Просмотр исходного кода

复核-活动单复核增加组合商品复核

zhaohuanhuan 7 месяцев назад
Родитель
Сommit
a7c4d41ce9

+ 1 - 0
src/utils/dataType.js

@@ -31,6 +31,7 @@ export function toArray(code) {
 }
 
  export function barcodeToUpperCase(code){
+   if(!code) return code
    if (/[a-zA-Z]/.test(code)) {
      return  code.toUpperCase();  // 强制转换为大写字母
     }

+ 70 - 25
src/views/outbound/check/activity/index.vue

@@ -6,9 +6,6 @@
         <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="activity">
       <div class="wave-title">
@@ -27,7 +24,6 @@
             <div>KG</div>
           </template>
         </van-field>
-<!--        :class="[totalWeight>0?'success-input-barcode':'error-input-barcode']"-->
       </div>
       <div class="order-detail">
         <div class="picking-no">
@@ -105,14 +101,16 @@
     </div>
     <!-- 条码输入组件 -->
     <input-barcode :back="back" @setBarcode="setBarcode" ref="inputBarcodeRef" />
-    <!--    打印面单-->
+    <!-- 打印面单-->
     <printer ref="printerRef" @onPrint="onPrint"  />
-    <!--    订单列表-->
+    <!-- 订单列表-->
     <order-list-table ref="orderListRef" />
-    <!--    返拣-->
+    <!-- 返拣-->
     <reverse-picking ref="reversePickingRef" :warehouse="warehouse" :reversePickingContainerNo="reversePickingContainerNo" @load-data="loadData" @reversePickingReset="reversePickingReset" />
-    <!--    耗材-->
+    <!-- 耗材-->
     <related-materia ref="relatedMateriaRef" @cut-barcode="cutBarcode" />
+    <!-- 复核组合商品-->
+    <check-barcode-combine ref="checkBarcodeCombineRef"  @cutBarcode="cutBarcode" />
   </div>
 </template>
 <script setup>
@@ -121,15 +119,16 @@ import { androidFocus, getHeader, goBack, scanError, scanSuccess } from '@/utils
 import { useStore } from '@/store/modules/user'
 import { closeListener, openListener, scanInit } from '@/utils/keydownListener'
 import { getPendingReviewTask, packingReview } from '@/api/check/index'
-import { barcodeToUpperCase } from '@/utils/dataType.js'
-import { closeToast, showConfirmDialog, showLoadingToast, showNotify } from 'vant'
+import { barcodeToUpperCase, toMap } from '@/utils/dataType.js'
+import { closeToast, showConfirmDialog, showDialog, showLoadingToast, showNotify, showToast } from 'vant'
 import { closeLoading, showLoading } from '@/utils/loading'
-import { fluxPrint } from '@/api/picking/index'
+import { fluxPrint, getListCombineSku } from '@/api/picking/index'
 import InputBarcode from '@/views/outbound/picking/components/InputBarcode.vue'
 import Printer from '@/components/Printer.vue'
 import orderListTable from '@/views/outbound/check/components/OrderListTable.vue'
 import ReversePicking from '@/views/outbound/check/components/ReversePicking.vue'
 import RelatedMateria from '@/views/outbound/check/components/RelatedMateria.vue'
+import CheckBarcodeCombine from '@/views/outbound/check/components/CheckBarcodeCombine.vue'
 const store = useStore()
 try {
   getHeader()
@@ -169,15 +168,22 @@ const orderList=ref([])
 const matchBarcodeList=ref([])
 const actions = [
   { text: '重新开始',value:'reset' },
-  // { text: '波次清单',value:'goods' },
   { text: '装箱清单',value:'packing' },
   { text: '取消单列表',value:'cancel' },
   { text: '冻结单列表',value: 'freeze' },
 ];
 // 扫描条码监听
 const relatedMateriaRef=ref(null)
+const matchedSku=ref([])
+const checkBarcodeCombineRef=ref(null)
 const _handlerScan = (code) => {
   if (code) {
+    if (isUniqueCode.value) {
+      scanError()
+      scanBarcode.value = ''
+      showNotify({ type: 'warning', duration: 3000, message: `此单包含唯一码/IMEI码,请到PC复核` })
+      return
+    }
     const barcode = [...new Set(
       orderList.value
         .flatMap(item => [item.barcode, item.barcode2, item.sku, item.universalCode])
@@ -188,16 +194,6 @@ const _handlerScan = (code) => {
       matchBarcodeList.value=orderList.value.filter(item=>((item.barcode===checkBarcode || item.sku===checkBarcode || item.barcode2===checkBarcode || item.universalCode==checkBarcode) && item.qty>0) )
       if(matchBarcodeList.value.length>0){
         const itemActive = matchBarcodeList.value[0]
-        if(itemActive.uniqueRegExp){
-          scanBarcode.value=''
-          showNotify({ type: 'warning', duration: 3000, message: `此活动单包含唯一码,请到PC复核`})
-          return
-        }
-        if(itemActive.imeiRegExp){
-          scanBarcode.value=''
-          showNotify({ type: 'warning', duration: 3000, message: `此活动单包含IMEI码,请到PC复核`})
-          return
-        }
         scanBarcode.value=code
         if(itemActive.relatedMaterial && itemActive.relatedMaterial.length>0){
           relatedMateriaRef.value.show(itemActive)
@@ -210,12 +206,59 @@ const _handlerScan = (code) => {
        showNotify({ type: 'warning', duration: 3000, message: `商品条码${code},已全部扫描完成`})
      }
     }else {
-      scanBarcode.value=''
-      showNotify({ type: 'warning', duration: 3000, message: `商品条码${code},不匹配请重新扫描!`})
-      scanError()
+      //查询组合条码
+      matchedSku.value=[]
+      getListCombineSku({combineSku:code, workEnvironment:'check'}).then(res=>{
+        if(res.data.length>0){
+          const combineSkuMap=toMap(res.data,'barcode')
+          const matchedSkuList=getBarcodeCombine(orderList.value,combineSkuMap)
+          if(matchedSkuList.length>0){
+            if(matchedSkuList.length==res.data.length){
+              matchedSku.value=matchedSkuList
+              checkBarcodeCombineRef.value.show(matchedSku.value,orderList.value)
+            }else{
+              scanError()
+              showDialog({
+                title:'温馨提示',
+                message:'组合商品与拣货任务不匹配,请检查组合商品配置!'
+              })
+            }
+          }else {
+            scanError()
+            showDialog({
+              title:'温馨提示',
+              message:'组合商品与拣货任务不匹配,请检查组合商品配置!'
+            })
+          }
+        }else {
+          scanError()
+          scanBarcode.value=''
+          showNotify({ type: 'warning', duration: 3000, message: `商品条码${code},不匹配请重新扫描!`})
+        }
+      })
+
     }
   }
 }
+
+//组合商品匹配到的商品
+const getBarcodeCombine=(goodsList, combineSkuMap)=>{
+  const result = goodsList.map(item => {
+    const barcode = item.barcode || item.barcodeAs;
+    // 如果有匹配数据添加到 item 中
+    if (combineSkuMap[barcode] && item.qty >= combineSkuMap[barcode].quantity ) {
+      return {
+        ...item,
+        matchedJson: combineSkuMap[barcode]
+      };
+    }
+    return null
+  })
+    .filter(item => item !== null) // 过滤掉 null 元素,保留匹配到的项
+  return result.length > 0 ? result : []
+}
+
+
 //扣除商品数量
 const weightRef=ref(null)
 const cutBarcode = (itemActive, count) => {
@@ -236,7 +279,9 @@ const cutBarcode = (itemActive, count) => {
     if (!totalWeight.value) {
       tips.value = '请输入重量';
       weightRef.value?.focus()
+      showNotify({ type: 'success', duration: 3000, message: '商品扫描完成,请输入重量' });
     } else {
+      showNotify({ type: 'success', duration: 3000, message: '商品扫描完成,请点击结束复核' });
       tips.value = '商品扫描完成,请点击结束复核';
     }
   }

+ 118 - 0
src/views/outbound/check/components/CheckBarcodeCombine.vue

@@ -0,0 +1,118 @@
+<template>
+  <div class="goods">
+    <van-dialog v-model:show="goodsTrueFalseBy"
+                :beforeClose="beforeClose"
+                title="组合商品包含"
+                show-cancel-button>
+        <div style="width:100%;max-height:150px;overflow:auto">
+          <div   v-for="(item,index) in matchedSku" :key="index" >
+            <van-cell center :title="item.matchedJson.barcode"  :label="item.matchedJson.skuName" >
+              <template #value>
+                <div>{{ item.matchedJson.quantity }}件</div>
+                <div class="goods-tips">预期数量:{{item.qty}}件</div>
+              </template>
+            </van-cell>
+          </div>
+        </div>
+        <div class="goods-number">应复核数量:{{maxCount}}</div>
+        <van-field label="实复核数" type="number" class="code-input" v-model="count" ref="countRef"  autocomplete="off" placeholder="实复核数" />
+    </van-dialog>
+  </div>
+</template>
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { showToast } from 'vant'
+import { formatDateTime } from '@/utils/date'
+const goodsTrueFalseBy=ref(false)
+const countRef=ref(null)
+const count=ref('');
+
+const matchedSku=ref([])
+const orderList=ref([])
+const maxCount = ref(0);
+const matchedSkuList =()=> {
+  let minNumber = Infinity;
+  matchedSku.value.forEach((item) => {
+    // 计算每个 item 的 number 值
+    const number = item.qty / item.matchedJson.quantity;
+    if (number < minNumber) {
+      minNumber = number;
+    }
+  });
+  maxCount.value = Math.floor(minNumber);
+}
+const show = async (list,order) => {
+  matchedSku.value=list
+  orderList.value=order
+  matchedSkuList()
+  count.value=''
+  goodsTrueFalseBy.value = true
+  setTimeout(()=>{
+    countRef.value?.focus()
+  },200)
+}
+//输入拣货容器号
+const emit = defineEmits(['cutBarcode'])
+const  beforeClose = (action) =>
+  new Promise(async (resolve) => {
+    if (action === 'confirm') {
+      if (count.value == '') {
+        showToast('请输入复核数量')
+        return resolve(false)
+      }
+      if (count.value<=0) {
+        showToast('请输入正确复核数量')
+        return resolve(false)
+      }
+      if (count.value >maxCount.value) {
+        showToast({duration:3000,message:'复核数量不能大于应复核数量'})
+        return resolve(false)
+      }
+      const data= dataResult(matchedSku.value)
+      data.forEach((item,index) => {
+        orderList.value.forEach((items,index) => {
+          if(item.lotNum==items.lotNum){
+            emit('cutBarcode', items,item.checkNumber)
+          }
+        })
+
+      })
+    }
+    resolve(true)
+  });
+const dataResult=(data)=>{
+  const list=JSON.parse(JSON.stringify(data))
+  list.forEach((item,index)=>{
+    item.checkNumber=item.matchedJson.quantity * count.value
+    delete item.matchedJson
+  })
+  return list
+}
+defineExpose({show})
+</script>
+<style scoped lang="sass">
+.goods
+  .code-input
+    font-size: 16px
+    font-weight: bold
+    border-bottom: 2px solid #0077ff
+  :deep(.van-cell--center)
+    padding: 5px 20px
+  :deep(.van-cell__title)
+    text-align: left !important
+  :deep(.van-cell__value)
+    width: 40% !important
+    flex: 0 0 40% !important
+    color: #000
+  :deep(.van-field__control)
+    font-size: 18spx
+  .goods-number
+    text-align: left
+    font-size: 16px
+    padding-left: 20px
+    margin-top: 5px
+  .goods-tips
+    font-size: 12px
+    text-align: right
+    color: #333
+</style>