| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904 |
- <template>
- <div class="container">
- <van-nav-bar
- title="复核-大件单" left-arrow fixed placeholder @click-left="goBack">
- <template #left>
- <van-icon name="arrow-left" size="25" />
- <div style="color: #fff">返回</div>
- </template>
- <!-- <template #right>-->
- <!-- <div class="nav-right" @click="onClickRight">提交任务</div>-->
- <!-- </template>-->
- </van-nav-bar>
- <div class="large">
- <div class="large-title">
- <!-- <div><span style="font-size: 12px">订单号:</span>{{ orderNo || '--' }}</div>-->
- <div class="large-tips">
- <van-notice-bar :background="'none'" :speed="50" :text="tips" />
- </div>
- <van-button plain size="mini" type="primary" @click="_setOrderNo()">更换订单/快递</van-button>
- </div>
- <div class="scan-barcode">
- <van-field v-model.lazy="scanBarcode" label-align="left" placeholder="请扫描商品条码/SKU" label="商品条码:"
- ref="barcodeNumberRef" class="input-barcode" autocomplete="off" @keydown.enter="_handlerScan(scanBarcode)" />
- </div>
- <div class="order-detail">
- <div class="picking-no">
- <div class="picking-code">
- <van-icon name="stop-circle-o" color="#419bff" />
- <span style="padding-left: 5px">单号:{{ orderDetail.orderNo }}</span></div>
- <div>{{ orderDetail.carrierName || '--' }}</div>
- </div>
- <div class="picking-container ">
- <div style="display: flex;padding-top: 5px" @click="setPrinter()">
- <div>打印机:</div>
- <div v-if="printer">{{printer.printer}}</div>
- <div style="text-decoration: underline;color: #0077ff">设置打印机<van-icon name="edit" color="#0077ff"/> </div>
- </div>
- <div class="picking-order-count ">
- <div>已复核/总复核:
- <span>{{packingCount}}/{{ orderBarcodeCount+packingCount+scanOrderBarcodeCount }}</span>
- </div>
- <div>耗材数:
- <span>{{ scanMaterialCount }}/{{ materialCount }}</span>
- </div>
- <div>已装箱数:
- <span v-if="orderDetail.orderPacking && orderDetail.orderPacking.length>0" style="text-decoration: underline;color: #0077ff" @click="resetPacking" >{{ orderDetail.orderPacking.length }}<van-icon name="arrow-double-right" color="#0077ff" /></span>
- <span v-else>0</span>
- </div>
- </div>
- </div>
- <div class="picking-button">
- <div class="picking-button-item" @click="reset()">重置</div>
- <div class="picking-button-item" @click="print('A3001_SO_PACKINGLIST',orderDetail.orderNo)">总清单</div>
- <div class="picking-button-item" @click="setPacking('batch')">批量分箱</div>
- <div class="picking-button-item" @click="setPacking('single')">装箱</div>
- </div>
- </div>
- <div class="order-list-box">
- <van-divider style="margin: 0;padding: 5px 15px">
- <template #default>
- <div style="display: flex;align-items: center">订单明细(<div style="background: #E6A23C;height: 10px;width: 10px;margin:0 5px"></div><div>待装箱商品)</div></div>
- </template>
- </van-divider>
- <div class="order-list">
- <table class="task-table">
- <thead>
- <tr>
- <th style="width: 20px">#</th>
- <th style="width: 40%">商品条码</th>
- <th>数量</th>
- <th>剩余</th>
- <th>状态</th>
- <th v-if="isUniqueCode || isQualityCheck">标记</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item, index) in orderList" :key="index" v-if="orderList.length>0" :style="rowStyle(item)" >
- <td>{{ index + 1 }}</td>
- <td>{{ item.barcode }} <van-tag type="success" v-if="item.universalCode">万用</van-tag></td>
- <td>
- <span v-if="item.qtyOrdered" :style="item.qty!=item.oldQuantity && item.oldQuantity!=0 && item.qty!=0?'color:#b40a1e':''">{{ item.qty }}/{{ item.qtyOrdered }}</span>
- <span v-else><van-tag type="warning">耗材</van-tag></span>
- </td>
- <td>{{ item.qty }}</td>
- <td>{{ statusMap[item.status] || '' }}</td>
- <td v-if="isUniqueCode || isQualityCheck">
- <van-tag v-if="item.uniqueRegExp" type="warning">唯一码</van-tag>
- <van-tag v-if="item.imeiRegExp" type="primary">IMEI码</van-tag>
- <van-tag v-if="item.qualityCheck" type="warning" >质检</van-tag>
- </td>
- </tr>
- <tr v-else>
- <td colspan="5">
- <div>暂无数据</div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- <!-- 条码输入组件 -->
- <input-barcode :back="back" @setBarcode="setBarcode" ref="inputBarcodeRef" />
- <!-- 打印面单-->
- <printer ref="printerRef" @onPrint="onPrint" />
- <!-- 批量扫描-->
- <van-dialog v-model:show="barcodeNumberTrueFalseBy" title="批量扫描" show-cancel-button :beforeClose="beforeClose" :keyboardEnabled="false" >
- <van-field v-model="barcodeNumber" autocomplete="off" center border label="数量:" placeholder="请输入数量"
- type="digit" name="pattern" ref="barcodeNumberRef" class="count-input" @keydown.enter="onSubmitCount"
- label-width="70px" label-align="center" :rules="[{ pattern, message: '请输入正确数量' }]">
- </van-field>
- <van-row :gutter="[5, 5]" style="margin: 10px 20px;font-size: 14px;text-align: left;color:#333" v-for="item in matchBarcodeList">
- <van-col span="12">条码:{{item.barcode}}</van-col>
- <van-col span="12">数量:{{item.qty}}</van-col>
- </van-row>
- </van-dialog>
- <!-- 装箱-->
- <check-packing ref="checkPackingRef" @cancelOrder="cancelOrder" @resetPackingStatus="resetPackingStatus" @getOrderPacking="_getOrderPacking" @print-picking-list="printPickingList" @print="print"/>
- <!-- 批量装箱-->
- <batch-packing ref="batchPackingRef" @print="print" @loadData="loadData" @print-picking-list="printPickingList" />
- <!-- 重置装箱-->
- <packing-list ref="packingListRef" @loadData="loadData" />
- </div>
- </template>
- <script setup >
- import { onMounted, onUnmounted, computed, ref } from 'vue'
- import { androidFocus, getHeader, goBack, scanError, scanSuccess } from '@/utils/android'
- import { closeListener, openListener, scanInit } from '@/utils/keydownListener'
- import InputBarcode from '@/views/outbound/picking/components/InputBarcode.vue'
- import { useStore } from '@/store/modules/user'
- import { closeLoading, showLoading } from '@/utils/loading'
- import { getOrderPacking, getPendingReviewTask, listEnableCheckDocumentPrint, reversePicking } from '@/api/check'
- import { barcodeToUpperCase } from '@/utils/dataType'
- import { showConfirmDialog, showDialog, showNotify, showToast } from 'vant'
- import { fluxPrint } from '@/api/picking'
- import Printer from '@/components/Printer.vue'
- import CheckPacking from '@/views/outbound/check/components/CheckPacking.vue'
- import BatchPacking from '@/views/outbound/check/components/BatchPacking.vue'
- import PackingList from '@/views/outbound/check/components/PackingList.vue'
- // 设置波次号
- const store = useStore()
- try {
- getHeader()
- androidFocus()
- } catch (error) {
- }
- // 页面初始化
- onMounted(() => {
- openListener()
- scanInit(_handlerScan)
- loadData()
- })
- const warehouse = store.warehouse
- const orderNo = ref('')
- // 错误提示
- const tips = ref('请扫描订单/快递单号')
- //强制返回
- const back = ref(true)
- const scanBarcode = ref('')
- const inputBarcodeRef = ref(null)
- // 订单明细
- const orderDetail = ref({})
- //装箱明细
- const packingDetailMap=ref({})
- const isUniqueCode = ref(false)
- const isQualityCheck=ref(false)
- const statusMap = {
- '00': '创建',
- '20': '预配',
- '30': '部分分配',
- '40': '已分配',
- '50': '待拣货',
- '60': '已拣货',
- '61': '分拣完成',
- '90': '订单取消',
- }
- //订单列表
- const dataList = ref([])
- const orderList = computed(() => {
- return dataList.value
- .filter(item => item.qty !== 0 || item.isPacking)
- .sort((a, b) => {
- const statusPriority = {
- '60': 0,
- '600': 1,
- '50': 2,
- '40': 3,
- '30': 4,
- '20': 5,
- '00': 6,
- }
- if (statusPriority[a.status] !== statusPriority[b.status]) {
- return statusPriority[a.status] - statusPriority[b.status]
- }
- return 0
- })
- })
- //订单产品总数
- const orderBarcodeCount = computed(() => {
- return dataList.value.reduce((sum, item) => {
- if (item.qtyOrdered != null) {
- return sum + Number(item.qty)
- }
- return sum
- }, 0)
- })
- //装箱总数
- const packingCount = computed(() => {
- return packingList.value.reduce((sum, item) => sum + (+item.qty || 0), 0);
- })
- //
- //扫描订单产品总数
- const scanOrderBarcodeCount = computed(() => {
- return dataList.value.reduce((sum, item) => {
- if (item.qtyOrdered != null) {
- return sum + Number(item.quantity)
- }
- return sum
- }, 0)
- })
- //耗材总数
- const materialCount = computed(() => {
- return dataList.value.reduce((sum, item) => {
- if (item.qtyOrdered == null) {
- return sum + Number(item.oldQty)
- }
- return sum
- }, 0)
- })
- const scanMaterialCount = computed(() => {
- return dataList.value.reduce((sum, item) => {
- if (item.qtyOrdered == null) {
- return sum + Number(item.quantity)
- }
- return sum
- }, 0)
- })
- // 查询打印策略
- const printConfig=ref([])
- const getListEnableCheckDocumentPrint=()=>{
- listEnableCheckDocumentPrint({ 'name': '', 'owner': '' }).then(res => {
- printConfig.value= res.data
- })
- }
- getListEnableCheckDocumentPrint()
- //匹配条码
- const matchBarcodeList = ref([])
- //扣除数量
- const barcodeNumberTrueFalseBy = ref(false)
- const barcodeNumberRef = ref(null)
- const barcodeNumber=ref('')
- const pattern=/^[0-9]\d*$/
- const _handlerScan = async (code) => {
- if (code) {
- if (isUniqueCode.value) {
- scanError()
- scanBarcode.value = ''
- showNotify({ type: 'warning', duration: 3000, message: `此单包含唯一码/IMEI码,请到PC复核` })
- return
- }
- const barcode = [...new Set(
- orderList.value
- .filter(item => (item.status == '60' || item.status == '600'))
- .flatMap(item => [item.barcode, item.barcode2, item.sku, item.universalCode])
- .filter(value => value !== null && value !== '' && value !== undefined),
- )]
- const checkBarcode = barcodeToUpperCase(code)
- if (barcode.some(item => barcodeToUpperCase(item) === checkBarcode)) {
- dataList.value = await barcodeMatching(checkBarcode)
- matchBarcodeList.value = dataList.value.filter(item => (item.barcode === checkBarcode || item.sku === checkBarcode || item.barcode2 === checkBarcode || item.universalCode == checkBarcode) && (item.status == '60' || item.status == '600') && item.qty > 0)
- if (matchBarcodeList.value.length > 0) {
- scanBarcode.value = code
- const allCount = matchBarcodeList.value.reduce((sum, item) => sum + Number(item.qty), 0)
- if (allCount > 1) {
- barcodeNumberTrueFalseBy.value = true
- setTimeout(() => {
- barcodeNumber.value=''
- barcodeNumberRef.value?.focus()
- },300)
- return
- }
- cutBarcode([matchBarcodeList.value[0]], 1)
- } else {
- scanBarcode.value = ''
- scanError()
- tips.value = `商品条码${code},已全部扫描完成`
- showNotify({ type: 'warning', duration: 3000, message: `商品条码${code},已全部扫描完成` })
- }
- } else {
- scanBarcode.value = ''
- tips.value = `商品条码${code},不匹配请重新扫描!`
- showNotify({ type: 'warning', duration: 3000, message: `商品条码${code},不匹配请重新扫描!` })
- scanError()
- }
- }
- }
- const onSubmitCount=()=>{
- if(!barcodeNumber.value){
- tips.value='请输入数量'
- showToast({duration:5000,message:'请输入数量'})
- return
- }
- const allCount = matchBarcodeList.value.reduce((sum, item) => sum + Number(item.qty), 0)
- if(Number(barcodeNumber.value)>allCount){
- const message='数量不能大于最大数量'+allCount
- tips.value=message
- showToast({duration:5000,message})
- return
- }
- barcodeNumberTrueFalseBy.value=false
- cutBarcode(matchBarcodeList.value, barcodeNumber.value)
- }
- const beforeClose= (action) =>
- new Promise((resolve) => {
- if(action==='confirm'){
- if(!barcodeNumber.value){
- tips.value='请输入数量'
- showToast({duration:5000,message:'请输入数量'})
- return resolve(false)
- }
- const allCount = matchBarcodeList.value.reduce((sum, item) => sum + Number(item.qty), 0)
- if(Number(barcodeNumber.value)>allCount){
- const message='数量不能大于最大数量'+allCount
- tips.value=message
- showToast({duration:5000,message})
- return resolve(false)
- }
- resolve(true)
- cutBarcode(matchBarcodeList.value, barcodeNumber.value)
- }else {
- tips.value='您已取消扣减扫描商品,请重新扫描'
- scanBarcode.value=''
- matchBarcodeList.value=[]
- resolve(true)
- }
- });
- const cutBarcode = (list, count) => { //扣减数量
- let remainingCount = count // 剩余的扣减数量
- // 更新扫描数据的逻辑
- const updateData = (item) => {
- const itemIndex = dataList.value.findIndex(data => data.lotNum === item.lotNum)
- const deductedAmount = item.originalDetailAmount - item.qty // 扣减的数量
- if (itemIndex !== -1) {
- dataList.value[itemIndex] = {
- ...dataList.value[itemIndex],
- quantity: dataList.value[itemIndex].quantity + deductedAmount, // 更新实际扣减的数量
- oldQuantity:dataList.value[itemIndex].oldQuantity + deductedAmount, // 更新实际扣减的数量
- }
- } else {
- item.quantity = deductedAmount
- item.oldQuantity=deductedAmount
- dataList.value.push(item)
- }
- }
- list.forEach(item => {
- if (remainingCount <= 0) return // 如果剩余数量为0,停止扣减
- item.originalDetailAmount = item.qty // 保存原始数量
- if (item.qty > 0) {
- // 如果剩余数量大于当前商品的数量,则直接扣除当前商品的数量
- if (remainingCount >= item.qty) {
- remainingCount -= item.qty
- item.qty = 0
- } else {
- item.qty -= remainingCount // 扣减剩余数量
- remainingCount = 0
- }
- item.isPacking=true
- }
- if (item.qty !== item.originalDetailAmount) {
- updateData(item) // 更新扫描数据
- scanBarcode.value = ''
- tips.value = '请继续扫描商品'
- scanSuccess()
- }
- })
- const materiaList=orderList.value.filter(item=>item.status=='600' && item.qty>0)
- const endOrder=orderList.value.filter(item=>item.status=='60' && item.qty>0)
- if(materiaList.length ==0 &&endOrder.length==0){
- setPacking('single')
- return
- }
- }
- // 进行装箱
- const checkPackingRef=ref(null)
- const currPackingList=ref([])
- const batchPackingRef=ref(null)
- const setPacking=(type)=>{
- if(!printer.value){
- scanError()
- showNotify({ type: 'warning', duration: 3000, message: '请先设置打印机' })
- return
- }
- // 获取装箱的商品列表
- currPackingList.value = orderList.value.filter(item => item.isPacking)
- if (currPackingList.value.length === 0) {
- scanError()
- showNotify({ type: 'warning', duration: 3000, message: '暂无未装箱数据' })
- return
- }
- const materiaList = orderList.value.filter(item => item.status == '600' && item.qty > 0)
- if (materiaList.length > 0) {
- const checkBarcode = new Set(currPackingList.value.flatMap(item => item.relatedMaterial.map(material => material.barCode)))
- const packingBarcodes = new Set(materiaList.map(item => item.barcode))
- // 判断是否有装箱商品条形码与需要扫描的物料条形码重复
- const hasCommonBarcode = [...packingBarcodes].some(barcode => checkBarcode.has(barcode))
- if (hasCommonBarcode) {
- scanError();
- showNotify({ type: 'warning', duration: 3000, message: `装箱商品包含耗材${[...checkBarcode].join(',')},请先扫描耗材` })
- return
- }
- }
- if (type === 'single') { // 普通装箱
- checkPackingRef.value?.show(currPackingList.value, orderDetail.value)
- } else { // 批量装箱
- const list =orderList.value.filter(item => item.isPacking && item.status=='60')
- if (list.length > 1) {
- scanError()
- showNotify({ type: 'warning', duration: 3000, message: '不支持多个商品装箱' })
- return
- }
- batchPackingRef.value?.show(currPackingList.value, orderDetail.value)
- }
- }
- //重置装箱状态
- const resetPackingStatus=()=>{
- currPackingList.value.forEach((item) => {
- item.quantity=0
- delete item.isPacking
- })
- }
- //重置装箱
- const packingListRef=ref(null)
- const resetPacking=()=>{
- _getOrderPacking(orderDetail.value.orderNo,1)
- }
- //重新开始
- const reset=()=>{
- showConfirmDialog({
- title: '温馨提示',
- message: '您正在进行重新开始操作,是否继续?',
- }).then(() => {
- _reset()
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号','')
- })
- }
- //打印清单
- const printerRef=ref(null)
- //设置打印机
- const setPrinter=()=>{
- printerRef.value?.show(warehouse)
- }
- const printer=ref(null)
- if(localStorage.getItem('check-print')){
- printer.value=JSON.parse(localStorage.getItem('check-print'))
- }
- const print=(templateCode,code)=>{
- if(!printer.value){
- scanError()
- showNotify({ type: 'warning', duration: 3000, message: '请先设置打印机' });
- return
- }
- const data = {warehouse,code,printServer: printer.value.server, printName:printer.value.printer,templateCode }
- showLoading()
- fluxPrint(data)
- .then(res => {
- if(res.code==200){
- scanSuccess()
- showNotify({ type: 'success', duration: 3000, message: '打印已发起,请检查打印情况' });
- printPickingList(code,currPackingList.value)
- }else {
- scanError()
- tips.value=res.message || '系统异常,请联系技术支持!'
- showNotify({ type: 'danger', duration: 3000, message: res.message || '系统异常,请联系技术支持!' });
- }
- })
- .catch(err => {
- scanError()
- tips.value=err.message || '系统异常,请联系技术支持!'
- showNotify({ type: 'danger', duration: 3000, message: err.message || '系统异常,请联系技术支持!' });
- }).finally(() => {
- closeLoading()
- })
- }
- // 打印装箱清单
- const printPickingList=(deliveryNo,curPackingList)=> {
- // 打印装箱清单
- let printData=[]
- const findIndex = printConfig.value.findIndex(item => item.ownerList.includes(orderDetail.value.customerId));
- // 检查质检数据并添加质检打印任务
- const hasQualityCheck = curPackingList.some(item => item.qualityCheck === true);
- if (hasQualityCheck) {
- const qcData = {
- warehouse: orderDetail.value.warehouseId,
- code: deliveryNo,
- printServer: printer.value.server,
- printName: printer.value.printer,
- templateCode: 'A3014_PACK_CARTON_QC'
- };
- printData.push(qcData);
- }
- if (findIndex === -1) {
- printRequests(0, printData);
- return;
- }
- printConfig.value.forEach((item,index) => {
- const isOwner = item.ownerList.includes(orderDetail.value.customerId);
- const printMap = item.printer && item.printer !== '' ? item.printer.split('+') : [printer.value.server,printer.value.printer];
- // 判断 店铺和承运商是否匹配
- const isShop = item.shop ? item.shop.includes(orderDetail.value.shop) : true;
- const isCarrier =item.carriers? item.carriers.includes(orderDetail.value.carrierId):true
- if (isOwner && isShop && isCarrier ) {
- const data = {
- warehouse: orderDetail.value.warehouseId,
- code: deliveryNo,
- printServer: printMap[0],
- printName: printMap[1],
- templateCode: item.templateCode,
- ignoreNoData:item.templateCode
- };
- const printCount = Math.max(item.printNum, 1)
- printData.push(...new Array(printCount).fill(data));
- }
- if(index==printConfig.value.length-1){
- printRequests(0,printData)
- }
- });
- }
- const printRequests = async(index, dataList)=> {
- if (index >= dataList.length) {
- // if (this.orderList.length == 0) {
- // this.getOrderList();
- // }
- return;
- }
- try {
- const res = await _printMode(dataList[index]);
- if (res) {
- if(res.code==200){
- showNotify({ type: 'success', duration: 3000, message: '打印已发起,请检查打印情况' });
- }else {
- if(dataList[index].ignoreNoData && dataList[index].ignoreNoData==true && (res.message.includes('打印数据为空') ||res.message.includes('ignoreNoData'))){
- return
- }
- showNotify({ type: 'danger', duration: 3000, message:res.message || '未知系统错误,请联系开发人员' });
- }
- }
- } catch (error) {
- console.error('打印请求发生错误:', error);
- showNotify({ type: 'danger', duration: 3000, message: error.message || '系统异常,请联系技术支持!' });
- } finally {
- closeLoading();
- await printRequests(index + 1, dataList);
- }
- }
- const _printMode=(data)=> {
- return new Promise((resolve, reject) => {
- fluxPrint(data)
- .then(res => resolve(res))
- .catch(err => reject(`打印失败: ${err}`));
- });
- }
- const onPrint=(code)=>{
- printer.value=code
- localStorage.setItem('check-print',JSON.stringify(code))
- }
- //设置订单号
- const setBarcode = (code) => {
- const data = { warehouse, code, activityOrderFlag: true }
- showLoading()
- packingDetailMap.value={}
- getPendingReviewTask(data).then(res => {
- if (res.data.details.length == 0) {
- scanError()
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', '暂未查询到待复核数据,请切换单号')
- } else {
- if(res.data.releaseStatus=='H' || res.data.status=='90' ||res.data.erpCancelFlag=='Y'){
- orderNo.value = code
- orderDetail.value = res.data
- scanError()
- cancelOrder(res.data)
- return
- }
- const orderNos = [...new Set(res.data.details.map(item => item.orderNo))];
- if(orderNos.length>1){
- scanError()
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', '仅支持单个订单复核','')
- return
- }
- orderNo.value = code
- orderDetail.value = res.data
- tips.value = '请扫描商品条码'
- _getOrderPacking(res.data.orderNo)
- scanSuccess()
- // 处理每个详情项
- res.data.details.forEach((item) => {
- item.quantity = 0
- item.oldQuantity = 0
- item.oldQty = item.qty
- if (item.relatedMaterial == null) {
- item.relatedMaterial = []
- }
- if (item.universalBarcode) {
- item.universalCode = '#@@@@@@#'
- }
- })
- const relatedMaterialList = getRelatedMaterial(res.data.details)
- res.data.details.push(...relatedMaterialList)
- dataList.value = res.data.details
- isUniqueCode.value = dataList.value.some(item => item.uniqueRegExp || item.imeiRegExp)
- isQualityCheck.value = dataList.value.some(item => item.qualityCheck === true);
- scanBarcode.value = ''
- }
- }).catch(err => {
- scanError()
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', err.message)
- }).finally(f => {
- closeLoading()
- })
- }
- const _reset=()=>{
- orderNo.value = ''
- orderDetail.value=[]
- dataList.value=[]
- tips.value = '请扫描订单/快递单号'
- }
- const containerNoMap={
- 'WH01':'FJ-WH01-20',
- 'WH02':'FJ-WH02-20',
- 'WH10':'FJ-WH10-1',
- 'WH99':'FJ-WH99-01',
- }
- //返拣容器
- const cancelOrder=(item,type)=>{
- const orderDetailStatus = orderList.value.find(item => (item.status != '60' && item.status != '600'));
- if(item.status=='90'){
- scanError()
- showDialog({ title: '温馨提示', message: '已取消, 暂停发货', }).then(() => {
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', '上一单为冻结单,请重新扫描单号')
- });
- }else if(item.releaseStatus=='H' || type=='release'){
- scanError()
- showDialog({ title: '温馨提示', message: `订单:${orderNo.value},已冻结, 暂停发货`, }).then(() => {
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', '上一单为冻结单,请重新扫描单号')
- });
- _reset()
- }else if(orderDetailStatus && item.erpCancelFlag=='Y' ){
- scanError()
- showDialog({ title: '温馨提示', message: '此取消单包含《待拣货》商品,请将所有商品拣货后返拣', }).then(() => {});
- } else if(item.erpCancelFlag=='Y' || type=='erp'){
- scanError()
- showConfirmDialog({ title: '温馨提示', message: `订单:${orderNo.value},取消单,请进入还库流程!!!`, })
- .then(() => {
- _reversePicking()
- })
- }
- }
- const _reversePicking = () => {
- showLoading()
- const data = {
- warehouse,
- reversePickingContainerNo: containerNoMap[warehouse],
- code: orderDetail.value.orderNo,
- }
- reversePicking(data).then(res => {
- showNotify({ type: 'success', duration: 5000, message: `${data.code},已进行返拣,请放置《${data.reversePickingContainerNo}》返拣容器中!` })
- loadData()
- }).finally(() => {
- closeLoading()
- })
- }
- const packingList=ref([])
- const _getOrderPacking=(orderNo,type)=>{
- showLoading()
- getOrderPacking({ warehouse, code:orderNo }).then(res => {
- packingList.value=res.data
- const mergedList = Object.values(
- res.data.reduce((acc, item) => {
- const { sku, traceId, qty } = item
- const compositeKey = `${sku}_${traceId}`
- if (!acc[compositeKey]) {
- acc[compositeKey] = { ...item }
- } else {
- acc[compositeKey].qty += qty
- }
- return acc;
- }, {})
- )
- packingDetailMap.value = mergedList.reduce((acc, item) => {
- const { traceId } = item
- acc[traceId] = acc[traceId] || []
- acc[traceId].push(item)
- return acc
- }, {});
- if(type && type==1){
- packingListRef.value?.show(packingDetailMap.value,orderDetail.value)
- }
- }).catch(err => {
- packingDetailMap.value = {}
- }).finally(f=>{
- closeLoading()
- })
- }
- const rowStyle=( row )=>{
- if(row.isPacking){
- return { background: '#E6A23C'}
- }
- if( row.status=='600'){
- return { background: '#fff8d9'}
- }
- if(row.status!='60' ){
- return { background: '#b3b3b3'}
- }
- return ''
- }
- //条码匹配放到前边
- const barcodeMatching = (checkBarcode) => {
- return dataList.value.reduce((list, item) => {
- if (item.status === '50') {
- list.push(item)
- return list
- }
- const itemBarcode = barcodeToUpperCase(item.barcode)
- const isMatchingBarcode = itemBarcode === checkBarcode || checkBarcode === item.sku || checkBarcode === item.barcodeOne
- if (isMatchingBarcode) {
- list.unshift(item) // 匹配条形码的项放到顶部
- } else {
- list.push(item) // 不匹配的项放到末尾
- }
- return list
- }, [])
- }
- // 格式化耗材
- const getRelatedMaterial = (data) => {
- const materialMap = {}
- let allocationIdCounter = 0
- data.forEach(item => {
- if (item.status == '60' && item.qty>0) {
- item.relatedMaterial.forEach((material, index) => {
- material.oldQty = material.qty * item.qty
- material.qty = material.qty * item.qty
- material.barcode = material.barCode
- material.barcode2 = material.barCode
- material.qtyOrdered = null
- material.skuName = material.skuDescr
- material.quantity = 0
- material.status = '600'
- material.lotNum = allocationIdCounter++
- material.relatedMaterial = []
- if (materialMap[material.barcode]) {
- materialMap[material.barcode].qty += material.qty
- } else {
- materialMap[material.barcode] = { ...material }
- }
- })
- }
- })
- return Object.values(materialMap)
- }
- //切换波次
- const _setOrderNo = () => {
- back.value = false
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', '')
- }
- // 数据刷新
- const loadData = () => {
- if (!orderNo.value) {
- inputBarcodeRef.value?.show('', '请扫描订单/快递单号', '')
- return
- } else {
- setBarcode(orderNo.value)
- }
- }
- onUnmounted(() => {
- closeListener()
- })
- window.onRefresh = loadData
- </script>
- <style scoped lang="sass">
- .container
- background: #e9f4ff
- .large
- .large-title
- display: flex
- justify-content: space-between
- padding: 8px 10px
- .large-tips
- color: #ed6a0c
- flex: 1
- .scan-barcode
- ::v-deep(.van-cell)
- padding: 0 15px
- height: 50px
- min-height: 50px
- display: flex
- align-items: center
- ::v-deep(.van-field__control)
- border-bottom: 2px solid #efefef
- font-size: 16px
- line-height: 46px
- ::v-deep(.van-field__label)
- width: unset
- font-size: 16px
- .input-barcode
- ::v-deep(.van-field__control)
- border-bottom: 2px solid #0077ff
- z-index: 2
- font-size: 16px
- line-height: 46px
- .order-detail
- margin-top: 2px
- background: #fff
- font-size: 14px
- .picking-no
- display: flex
- justify-content: space-between
- margin: 0 15px
- padding: 8px 0
- border-bottom: 1px solid #eaeaeb
- .picking-container
- padding: 0 15px
- text-align: left
- border-bottom: 1px solid #eaeaeb
- .container-item
- line-height: 30px
- display: flex
- align-items: center
- .picking-order-count
- display: flex
- justify-content: space-between
- line-height: 30px
- .picking-button
- display: flex
- justify-content: space-evenly
- align-items: center
- .picking-button-item
- flex: 1
- color: #419bff
- font-weight: bold
- line-height: 35px
- border-right: 1px solid #eaeaeb
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1)
- .picking-button-item:last-child
- border-right: none
- .order-list-box
- background: #fff
- margin-top: 2px
- .order-list
- width: 100%
- overflow-y: auto
- max-height: 60vh
- .task-table, .task-table-bin, .task-table-box
- width: 100%
- table-layout: fixed
- border-collapse: collapse
- font-size: 15px
- .task-table th, .task-table-bin th, .task-table td, .task-table-bin td, .task-table-box th, .task-table-box td
- text-align: center
- border: 1px solid #ccc
- word-wrap: break-word
- word-break: break-all
- .task-table thead, .task-table-bin thead, .task-table-box thead
- background-color: #3f8dff
- position: sticky
- top: 0
- color: white
- font-size: 15px
- .task-table-bin thead
- background-color: #3f8dff
- .task-table-bin tbody
- background: #cde7ff
- .count-input
- border-bottom: 2px solid #0077ff
- </style>
|