Przeglądaj źródła

盲收第一版

zhaohuanhuan 1 rok temu
rodzic
commit
17af050748

+ 29 - 6
src/api/blind/index.ts

@@ -1,7 +1,7 @@
 // @ts-ignore
 import request from '@/utils/request'
 // @ts-ignore
-import { checkBlindBarcodeType, getBlindTaskType, getMovingTaskType, setBoxBarcodeCountType, setBoxCacheDataType, submitBoxCacheDataType, } from '@/types/blind'
+import { checkBlindBarcodeType, getBlindTaskType, getMovingTaskType, setBarcodeCountType, setBoxBarcodeCountType, setBoxCacheDataType, submitBoxCacheDataType, } from '@/types/blind'
 
 /**
  * 盲收任务获取
@@ -66,18 +66,18 @@ export function getBoxCacheData(params:{code:string}) {
     params
   })
 }
+
 /**
  * 盲收-添加缓存数据-按箱清点+分货多人
  */
-export function setBoxCacheData(data:setBoxCacheDataType) {
+export function setBoxCacheData(code:string,type:string,data:any) {
   return request({
-    url: 'api/entryOrder/app/blind/addCacheData',
+    url: `api/entryOrder/app/blind/addCacheData?code=${code}&type=${type}`,
     method: 'post',
-    data
+    data:JSON.stringify(data),
   })
 }
 
-
 /**
  * 盲收-根据sku+箱号修改缓存数据数量-按箱清点+分货多人
  */
@@ -88,18 +88,41 @@ export function setBoxBarcodeCount(data:setBoxBarcodeCountType) {
     data
   })
 }
+/**
+ * 盲收-根据sku修改缓存数据数量
+ */
+export function setNoBoxBarcodeCount(data:setBarcodeCountType) {
+  return request({
+    url: 'api/entryOrder/app/blind/updateCacheDataQtyByDistributionMode',
+    method: 'post',
+    params:data
+  })
+}
 
 /**
  * 盲收-根据格口清除缓存数据-按箱清点+分货多人
  */
 export function resetBoxCacheDataBin(params: { code:string ,latticeCode:string}) {
   return request({
-    url: '/api/entryOrder/app/blind/clearCacheDataByLatticeCode',
+    url: 'api/entryOrder/app/blind/clearCacheDataByLatticeCode',
     method: 'post',
     params
   })
 }
 
+/**
+ * 盲收-根据箱号清除缓存数据
+ */
+export function resetBoxCacheDataBox(params: { code:string ,cartonCode:string}) {
+  return request({
+    url: 'api/entryOrder/app/blind/clearCacheDataByCartonCode',
+    method: 'post',
+    params
+  })
+}
+
+
+
 /**
  * 盲收-重置缓存数据-按箱清点+分货多人
  */

+ 5 - 3
src/types/blind.ts

@@ -26,7 +26,6 @@ export interface checkBlindBarcodeType {
  */
 export interface setBoxCacheDataType {
   ownerCode: string;
-  code: string;
   cartonCode: string;
   barCode: string;
 }
@@ -43,16 +42,19 @@ export interface setBoxBarcodeCountType {
   sku: string;
   qty: string;
 }
+export interface setBarcodeCountType {
+  code: string;
+  sku: string;
+  qty: string;
+}
 
 /**
  * 盲收-添加缓存数据-按箱清点+分货多人
  * ownerCode 货主
- * type  任务模式:EntryBlindTaskTypeEnum(按箱清点+分货)
  */
 export interface submitBoxCacheDataType {
   code: string;
   ownerCode: string;
-  type: string;
 }
 
 

+ 24 - 0
src/utils/android.ts

@@ -57,6 +57,30 @@ export function playVoicePickNum(number: number) {
   }
 }
 
+/**
+ * 播报格口
+ * 播报:格口:number
+ * @param number
+ */
+export function playVoiceBin(number: number) {
+  try {
+    // @ts-ignore
+    window.android.playVoiceBin(number)
+  }catch (e){
+  }
+}
+
+/**
+ * 第一次进入页面获取焦点
+ */
+export function androidFocus(){
+  try {
+    // @ts-ignore
+    window.android.focus()
+  }catch (e){
+
+  }
+}
 /**
  * 扫描成功语音
  */

+ 3 - 3
src/views/inbound/blindCollection/components/LotAttQuality.vue

@@ -17,8 +17,8 @@ import { ref } from 'vue'
 const columns =[{ text: '正品', value: 'ZP' },
                 { text: '残次', value: 'CP' },
                 { text: '机损', value: 'JS' },
-                { text: '箱损', value: 'JS' },
-                { text: '在途库存', value: 'JS' },
+                { text: '箱损', value: 'XS' },
+                { text: '在途库存', value: 'ZT' },
                 ]
 const fieldValue = ref(' 正品');
 const lotAttQualityTrueFalseBy=ref(false)
@@ -29,7 +29,7 @@ const pickerValue = ref([{ text: '正品', value: 'ZP' }]);
 const emit = defineEmits()
 const onConfirm=({ selectedValues, selectedOptions })=>{
   pickerValue.value = selectedValues;
-  fieldValue.value = selectedOptions[0].value
+  fieldValue.value = selectedOptions[0].text
   lotAttQualityTrueFalseBy.value = false
   emit('selectLotAttQuality', fieldValue.value)
 }

+ 4 - 3
src/views/inbound/blindCollection/components/ResetData.vue

@@ -2,7 +2,7 @@
   <div class="container-no-container">
     <van-dialog v-model:show="resetDataTrueFalseBy"
                 :beforeClose="beforeClose"
-                title="若确定重新清点,请输入格口号!"
+                :title="'若确定重新清点,请输入'+props.modeTypeName+'!'"
                 show-cancel-button
                 >
       <van-field  :class="['code-input',bin>0?'success-border':'']"
@@ -10,7 +10,7 @@
                  ref="binRef"
                  type="digit"
                  clearable :max="1000"
-                 placeholder="请输入格口" />
+                 :placeholder="'请输入'+props.modeTypeName" />
       <van-row>
         <van-col span="16"></van-col>
         <van-col span="8"><div class="completion" @click="onConfirm" >清除全部</div></van-col>
@@ -25,7 +25,8 @@ const resetDataTrueFalseBy=ref(false)
 const binRef=ref(null)
 const bin=ref('');
 const props = defineProps({
-  binData: Array
+  binData: Array,
+  modeTypeName:String
 });
 const show = async () => {
     resetDataTrueFalseBy.value = true

+ 7 - 1
src/views/inbound/blindCollection/components/TaskList.vue

@@ -59,9 +59,15 @@ const show = async (list) => {
   taskTrueFalseBy.value = true
 }
 const router = useRouter()
+const emit = defineEmits()
 const onTaskDetail = (item) => {
   taskTrueFalseBy.value = false
-  router.push({name:'BlindTask',query: { code:item.code,type:item.type }})
+  if(item.type){
+    router.push({name:'BlindTask',query: { code:item.code,typeCode:item.typeCode }})
+  }else {
+    emit('selectMode',item.code)
+  }
+
 }
 defineExpose({show})
 </script>

+ 37 - 33
src/views/inbound/blindCollection/mode/index.vue

@@ -18,17 +18,17 @@
     </van-nav-bar>
     <div class="mode">
       <div class="mode-input-box">
-        <div class="mode-input-text">请扫描盲收/般仓任务号</div>
+        <div class="mode-input-text">请扫描盲收任务号</div>
         <van-field class="mode-input" ref="taskNoRef"
                    :style="taskNo!==''?'border: 2px solid #07c160':''" clearable v-model="taskNo"
-                   placeholder="请扫描盲收/般仓任务号"
+                   placeholder="请扫描盲收任务号"
                    @keydown.enter="_getBlindTask()"
         />
       </div>
       <div class="mode-select">
         <div class="select-list">
-          <div class="select-item" @click="onSelect(2)">
-            <i class="iconfont icon-zaixianqingdian select-item-icon" style="color: #7598ca"></i>
+          <div class="select-item" @click="onSelect(0)">
+            <i class="iconfont icon-shoudongluru select-item-icon" style="color: #ef9a00"></i>
             <div class="left">
               <div class="select-item-title">清点模式</div>
               <div class="select-item-tips">步骤:扫描条码->进行装箱</div>
@@ -47,16 +47,6 @@
               <van-button type="primary" round size="small"> 选择</van-button>
             </div>
           </div>
-          <div class="select-item"  @click="onSelect(3)">
-            <i class="iconfont icon-shoudongluru select-item-icon" style="color: #ef9a00"></i>
-            <div class="left">
-              <div class="select-item-title">录入模式</div>
-              <div class="select-item-tips">步骤:扫描条码->录入效期、批次信息->输入数量->进行装箱</div>
-            </div>
-            <div class="right">
-              <van-button type="primary" round size="small"> 选择</van-button>
-            </div>
-          </div>
           <div class="select-item"  @click="onSelect(5)">
             <i class="iconfont icon-zhuangxiangyanhuodan select-item-icon" style="color:#55d1c2;"></i>
             <div class="left">
@@ -70,11 +60,11 @@
         </div>
       </div>
     </div>
-    <task-list ref="taskListRef" />
+    <task-list ref="taskListRef" @selectMode="_selectMode" />
   </div>
 </template>
 <script setup>
-import { goBack } from '@/utils/android.ts'
+import { androidFocus, goBack, scanError, scanSuccess } from '@/utils/android.ts'
 import { useRoute, useRouter } from 'vue-router'
 import { onMounted, onUnmounted, ref } from 'vue'
 import { closeListener, openListener, scanInit } from '@/utils/keydownListener.js'
@@ -91,6 +81,7 @@ const taskNoRef=ref(null)
 onMounted(() => {
   openListener()
   setTimeout(() => {
+    androidFocus()
     taskNoRef.value?.focus()
     scanInit(_handlerScan)
   },300)
@@ -114,13 +105,17 @@ const onClickLeft = () => {
   }
 };
 const link=(code,type)=>{
-  router.push({name:'BlindTask',query: { code,type }})
+  router.push({name:'BlindTask',query: { code,typeCode:type }})
+}
+const _selectMode=(code)=>{
+  taskNo.value=code
+  _getBlindTask()
 }
 //查询盲收任务
 const taskModel=ref({})
 const _getBlindTask=()=>{
   if(taskNo.value===''){
-    showToast({duration:5000,message:'请先扫描盲收或般仓任务号'})
+    showToast({duration:5000,message:'请先扫描盲收任务号'})
     return
   }
   taskModel.value={}
@@ -130,12 +125,14 @@ const _getBlindTask=()=>{
     data={code:taskNo.value}
     type=1
   }
+  showLoading()
   url(data).then(res=>{
+    scanSuccess()
     taskModel.value=res.data
     //盲收任务
     if(type===0){
-      if(res.data && res.data.type){
-        link(res.data.code,res.data.type)
+      if(res.data && res.data.typeCode){
+        link(res.data.code,res.data.typeCode)
       }else {
         showToast({duration:5000,message:'该任务未绑定模式,请选择模式!'})
       }
@@ -145,15 +142,19 @@ const _getBlindTask=()=>{
       }
     }
   })
+    .catch((err)=>{
+      closeLoading()
+      scanError()
+    })
+}
+const modeMap={
+  0:'清点模式',
+  1:'分货模式',
+  5:'按箱清点+分货',
 }
 //设置盲收任务类型
 const onSelect=(type)=>{
-  const modeMap={
-    1:'分货模式',
-    2:'清点模式',
-    3:'录入模式',
-    5:'按箱清点+分货多人',
-  }
+  const {typeCode,code,warehouseCode,ownerCode}=taskModel.value
   if(taskNo.value===''){
     showToast({duration:5000,message:'请先扫描盲收或般仓任务号'})
     return
@@ -162,8 +163,8 @@ const onSelect=(type)=>{
     showToast({duration:5000,message:'未检测到任务,请检查任务号是否正确!'})
     return
   }
-  if(taskModel.value.type){
-    link(taskModel.value.code,taskModel.value.type)
+  if(typeCode){
+    link(code,typeCode)
     return
   }
   showConfirmDialog({
@@ -173,13 +174,16 @@ const onSelect=(type)=>{
   })
     .then(() => {
       const params={
-        type:modeMap[type],
-        warehouseCode:taskModel.value.warehouseCode,
-        ownerCode:taskModel.value.ownerCode,
-        code:taskModel.value.code,
+        typeCode:type,
+        warehouseCode,
+        ownerCode,
+        code,
       }
+      showLoading()
       setBlindTaskMode(params).then(res=>{
-        link(taskModel.value.code,modeMap[type])
+        link(code,type)
+      }).finally(()=>{
+        closeLoading()
       })
     })
 

+ 13 - 0
src/views/inbound/blindCollection/task/hooks/barcodeIsData.ts

@@ -0,0 +1,13 @@
+export function barcodeIsData (str:string, data1:any,data2:any){
+  for (let item of data1) {
+    if (item.barcode === str) {
+      return true;
+    }
+  }
+  for (let item of data2) {
+    if (item.barcode === str) {
+      return true;
+    }
+  }
+  return false;
+}

+ 31 - 0
src/views/inbound/blindCollection/task/hooks/binData.ts

@@ -0,0 +1,31 @@
+// 定义数据项的类型
+interface Item {
+  barcode: string;
+  barcodeTwo: string;
+  sku: string;
+  commodityName: string;
+  cartonCode: string;
+  latticeCode: number;
+  qty: number;
+  operatorList: string[];
+}
+
+// 合并相同格口数据
+export function binData(data: Item[]): Item[] {
+  const result: Item[] = [];
+  // 遍历原始数据并合并
+  data.forEach(item => {
+    // 查找 result 数组中是否有相同格口数据
+    const existingItem = result.find(r => r.latticeCode === item.latticeCode);
+
+    if (existingItem) {
+      // 如果找到了相同 latticeCode,累加 qty
+      existingItem.qty += item.qty;
+    } else {
+      // 如果没有找到,直接将该条数据添加到结果数组
+      result.push({ ...item });
+    }
+  });
+
+  return result;
+}

+ 280 - 175
src/views/inbound/blindCollection/task/index.vue

@@ -17,22 +17,22 @@
     </van-nav-bar>
     <div class="blind-task-list">
       <van-cell-group inset>
-        <van-field label-width="70" center class="select" v-model="taskInfo.ownerName" readonly :is-link="modeType===3" @click-right-icon="onLotAtt"	  >
+        <van-field label-width="70" center class="select" v-model="taskInfo.ownerName" readonly    >
           <template #label>
             <van-button size="small" plain type="danger" @click="_resetData" >重新清点</van-button>
           </template>
-          <template #right-icon v-if="modeType===3" >
-            <van-tag type="primary">正品</van-tag>
-          </template>
         </van-field>
         <table  border="0" style="border-collapse: collapse" v-if="modeType===5" >
           <tbody>
           <tr style="border-bottom: 1px solid #ebedf0">
             <td width="70px" style="border-right: 1px solid #ebedf0" >箱号</td>
-            <td width="120px" style="border-right: 1px solid #ebedf0;word-break: break-all" >{{ preBoxNo || '--' }}<van-icon v-if="preBoxNo" name="edit" color="#0077aa" /></td>
+            <td width="120px" style="border-right: 1px solid #ebedf0;word-break: break-all" >{{ preBoxNo || '--'}}
+<!--              <van-icon v-if="preBoxNo" name="edit" color="#0077aa" />-->
+            </td>
             <td>
               <van-field  label-width="70" :class="focusType===5?'box-input':'select'" ref="boxNoRef" v-model="boxNo"
-                         label="" @focus="onFocus(5)" @blur="onFocus(0)" placeholder="请扫描箱号" clearable  @keydown.enter="_scanBox"  >
+                         label="" @focus="onFocus(5)" @blur="onFocus(0)" placeholder="请扫描箱号" clearable
+                          @keydown.enter="scanBox" autocomplete="off"   >
               </van-field>
             </td>
           </tr>
@@ -42,35 +42,23 @@
             <td>
               <van-field  label-width="70" :class="focusType===1?'box-input':'select'" ref="barcodeRef" v-model="barcode"
                  @focus="onFocus(1)" @blur="onFocus(0)" placeholder="请扫描条码" clearable
-                 @keydown.enter="_checkBarcode" />
+                 @keydown.enter="_checkBarcode" autocomplete="off" />
             </td>
           </tr>
           </tbody>
         </table>
         <van-field v-if="modeType!==5" label-width="70" :class="focusType===1?'input':'select'" ref="barcodeRef" v-model="barcode"
                    label="条码" @focus="onFocus(1)" @blur="onFocus(0)" placeholder="请扫描条码" clearable
-                   @keydown.enter.native="_checkBarcode" />
-        <van-field label-width="70" class="select" v-model="manufactureDate" label="生产日期" v-if="modeType===3"
-                   placeholder="请选择生产日期" readonly is-link @click="onProduct(1)" />
-        <van-field label-width="70" class="select" v-model="expirationDate" label="失效日期" v-if="modeType===3"
-                   placeholder="请选择失效日期" readonly is-link @click="onProduct(2)" />
-        <van-field label-width="70" :class="focusType===2?'input':'select'" ref="lotNumberRef" v-model="lotNumber" v-if="modeType===3"
-                   label="批次号" @focus="onFocus(2)"  @blur="onFocus(0)"  placeholder="请扫描批次号" clearable />
-        <van-field label-width="70" :class="focusType===3?'input':'select'" ref="countRef" v-model="count" center v-if="modeType===3"
-                   label="数量" @focus="onFocus(3)"  @blur="onFocus(0)"  :min="1" :max="10000" type="digit" placeholder="请输入数量">
-          <template #button>
-            <van-button size="small" type="primary">装&nbsp;&nbsp;箱</van-button>
-          </template>
-        </van-field>
+                   @keydown.enter="_checkBarcode" autocomplete="off" />
         <van-grid clickable :column-num="2" v-if="modeType!==3">
           <van-grid-item icon="home-o" text="数量">
             <template #icon>
               <div class="number">{{newOneData.qty}}</div>
             </template>
           </van-grid-item>
-          <van-grid-item  v-if="modeType===2 ">
+          <van-grid-item  v-if="modeType===0 ">
             <template #default>
-              <van-button  type="primary">装&nbsp;&nbsp;箱</van-button>
+              <van-button  type="primary" @click="_setBoxBarcode" >装&nbsp;&nbsp;箱</van-button>
             </template>
           </van-grid-item>
           <van-grid-item text="格口" v-else>
@@ -79,11 +67,12 @@
             </template>
           </van-grid-item>
         </van-grid>
-        <van-field label-width="70"  class="select" v-model="newOneData.barCode" center  label="上一条:"  placeholder="上条数据" readonly>
-          <template #button v-if="modeType!==5 && newOneData.latticeCode">
+        <van-field label-width="70"  class="select" v-model="newOneData.barcode" center  label="上一条:"  placeholder="上条数据" readonly>
+          <template #button >
             <van-button size="mini" type="danger" plain @click="resetNewBin" >取 消</van-button>
           </template>
         </van-field>
+
       </van-cell-group>
     </div>
     <div class="blind-task-table" >
@@ -99,16 +88,16 @@
               </tr>
               </thead>
               <tbody>
-              <tr v-if="boxTypeData.cartonDataList" v-for="(item,index) in boxTypeData.cartonDataList" :key="index" @click="_setBarcodeCount(item)">
+              <tr v-if="dataList.length>0" v-for="(item,index) in dataList" :key="index" @click="_setBarcodeCount(item)">
                 <td>{{ item.cartonCode }}</td>
-                <td>{{ item.barCode }}</td>
-                <td>{{ item.qty }}</td>
+                <td>{{ item.barcode }}</td>
+                <td>{{ item.qty }}<van-icon name="edit" color="#0077aa" /></td>
               </tr>
               </tbody>
             </table>
           </div>
           <div style="flex: 1">
-            <table class="task-table-bin" v-if="modeType===5">
+            <table class="task-table-bin" >
               <thead>
               <tr>
                 <th style="min-width: 40px">格口</th>
@@ -117,29 +106,45 @@
               </tr>
               </thead>
               <tbody>
-              <tr v-if="boxTypeData.latticeDataList" v-for="(item,index) in boxTypeData.latticeDataList" :key="index">
+              <tr v-if="binList.length>0" v-for="(item,index) in binList" :key="index">
                 <td>{{ item.latticeCode }}</td>
-                <td>{{ item.barCode }}</td>
+                <td>{{ item.barcode }}</td>
                 <td>{{ item.qty }}</td>
               </tr>
               </tbody>
             </table>
           </div>
         </div>
-        </van-cell-group>
+      </van-cell-group>
         <van-cell-group inset v-else>
         <table class="task-table">
           <thead>
           <tr>
             <th width="120px" >商品条码</th>
-            <th>格口/箱号</th>
+            <th>{{modeTypeName}}</th>
             <th width="80px">数量({{allCount}})</th>
             <th>操作</th>
           </tr>
           </thead>
           <tbody>
-          <tr v-if="boxTypeData.latticeDataList" v-for="(item,index) in boxTypeData.latticeDataList" :key="index" :class="{'odd-row': index % 2 !=0}">
-            <td>{{ item.barCode }}</td>
+          <tr v-if="localData.length>0" v-for="(item,index) in localData" :key="index">
+            <td>{{ item.barcode }}</td>
+            <td>{{ item.latticeCode }}</td>
+            <td>{{ item.qty }}</td>
+            <td>
+              <van-button plain size="mini" type="primary" @click="_setBarcodeCount(item)" >修改数量</van-button>
+            </td>
+          </tr>
+          <tr  v-if=" modeType===0" v-for="(item,index) in dataList" :key="index" :class="{'odd-row': index % 2 !=0}">
+            <td>{{ item.barcode }}</td>
+            <td>{{ item.cartonCode }}</td>
+            <td>{{ item.qty }}</td>
+            <td>
+              <van-button plain size="mini" type="primary" @click="_setBarcodeCount(item)" >修改数量</van-button>
+            </td>
+          </tr>
+          <tr  v-if="modeType===1" v-for="(item,index) in dataList" :key="index" :class="{'odd-row': index % 2 !=0}">
+            <td>{{ item.barcode }}</td>
             <td>{{ item.latticeCode }}</td>
             <td>{{ item.qty }}</td>
             <td>
@@ -150,11 +155,9 @@
         </table>
       </van-cell-group>
     </div>
-    <lot-att-quality ref="lotAttQualityRef" @selectLotAttQuality="selectLotAttQuality" />
-    <product-date  ref="productDateRef" @productDate="onProductDate"  />
     <barcode-count ref="barcodeCountRef" @setBarcodeCount="setBarcodeCount" />
     <van-back-top right="15vw" bottom="10vh" />
-    <reset-data ref="resetDataRef" :binData="boxTypeData?boxTypeData.latticeDataList:[]" @resetData="onResetData" />
+    <reset-data ref="resetDataRef" :modeTypeName="modeTypeName" :binData="dataList" @resetData="onResetData" />
   </div>
 </template>
 <script setup>
@@ -162,18 +165,18 @@ import { useRoute } from 'vue-router'
 import {
   checkBlindBarcode,
   getBlindTask,
-  getBoxCacheData, resetBoxCacheData, resetBoxCacheDataBin, setBlindTaskMode,
+  getBoxCacheData, resetBoxCacheData, resetBoxCacheDataBin, resetBoxCacheDataBox, setBlindTaskMode,
   setBoxBarcodeCount,
-  setBoxCacheData, submitBoxCacheData,
+  setBoxCacheData, setNoBoxBarcodeCount, submitBoxCacheData,
 } from '@/api/blind/index.ts'
-import { computed, onMounted, ref } from 'vue'
-import LotAttQuality from '@/views/inbound/blindCollection/components/LotAttQuality.vue'
-import ProductDate from '@/views/inbound/blindCollection/components/ProductDate.vue'
-import { scanError, scanSuccess } from '@/utils/android'
+import { computed, nextTick, onMounted, ref } from 'vue'
+import { playVoiceBin, scanError, scanSuccess } from '@/utils/android'
 import BarcodeCount from '@/views/inbound/blindCollection/components/BarcodeCount.vue'
 import { showConfirmDialog, showToast } from 'vant'
 import ResetData from '@/views/inbound/blindCollection/components/ResetData.vue'
-import { reactive } from '@vue/runtime-dom'
+import { barcodeIsData } from '@/views/inbound/blindCollection/task/hooks/barcodeIsData'
+import { closeLoading, showLoading } from '@/utils/loading'
+import { binData } from '@/views/inbound/blindCollection/task/hooks/binData'
 const route = useRoute()
 //箱号
 const boxNo = ref('')
@@ -183,45 +186,57 @@ const preBoxNo = ref('')
 const barcode = ref('')
 //上一个条码
 const preBarcode=ref('')
-//生产日期
-const manufactureDate = ref('')
-//失效日期
-const expirationDate = ref('')
-//批次号
-const lotNumber = ref('')
-//数量
-const count = ref('')
 const focusType = ref(0)
-const modeMap = {
-  '分货模式': 1,
-  '清点模式': 2,
-  '录入模式': 3,
-  '按箱清点+分货多人': 5,
+const modeMap={
+  0:'清点模式',
+  1:'分货模式',
+  5:'按箱清点+分货',
 }
-const modeType = modeMap[route.query.type]
+const modeType = Number(route.query.typeCode)
+const modeTypeName=modeType===0?'箱号':'格口'
 const barcodeRef = ref(null)
 const boxNoRef = ref(null)
-const lotNumberRef = ref(null)
-const countRef = ref(null)
-
 //按箱清点+分货数据
-const boxTypeData=ref({})
-const newOneData = computed(() => boxTypeData.value.latticeDataList?.[0] ?? { barCode: '', qty: 0, latticeCode: 0 });
+const dataList=ref([])
+//上一条数据
+const newOneData = computed(() =>
+  localData.value.length > 0
+    ? localData.value[0]
+    : dataList.value?.[0] ?? { qty: 0, latticeCode: 0 }
+)
+
+//计算总数量,默认空数组处理,确保 data 是有效的数组
+const sumQty = (data = []) => data.reduce((sum, item) => sum + Number(item.qty), 0);
+// 计算所有数量
 const allCount = computed(() => {
-  return boxTypeData.value.latticeDataList?.reduce((sum, item) => sum + item.qty, 0) || 0
+  const localNumber = sumQty(localData.value);
+  const dataNumber = sumQty(dataList.value);
+  return localNumber + dataNumber
 });
+const binList=computed(() => {
+ return  binData(dataList.value)
+})
+// 焦点
 const onFocus = (type) => {
   focusType.value = type
 }
-
 //查询任务信息
 const taskInfo = ref({})
-const taskType = route.query.type
+const taskType = modeMap[route.query.typeCode]
+const localData=ref([])
 const getTaskInfo = async (taskNo) => {
   const taskResponse = await getBlindTask({ taskNo });
   taskInfo.value = taskResponse.data;
+  localData.value=loadLocalData(taskInfo.value.code)
+  const { warehouseCode,typeCode,code, ownerCode}=taskResponse.data
+  const params={typeCode,warehouseCode,ownerCode,code}
+  // 获取设置模式
+  setBlindTaskMode(params).then(res=>{})
+  //获取缓存数据
   const boxResponse = await getBoxCacheData({ code: taskNo });
-  boxTypeData.value = boxResponse.data;
+  if(boxResponse.data){
+    dataList.value = boxResponse.data;
+  }
 }
 onMounted(() => {
   getTaskInfo(route.query.code)
@@ -234,66 +249,121 @@ onMounted(() => {
 })
 
 // 验证箱号
-const _scanBox=()=>{
+const scanBox=()=>{
+  if (boxNo.value === '') return;
   preBoxNo.value=boxNo.value
   boxNo.value=''
-  barcode.value=''
   barcodeRef.value?.focus()
+
 }
-const localData=ref([])
+// 验证条码
 const _checkBarcode = () => {
-  const { warehouseCode, ownerCode,code } = taskInfo.value;  // 解构出taskInfo中的仓库和业主信息
-  const params = {
-    warehouse: warehouseCode,
-    ownerCode,
-    barcode: barcode.value,
-  };
-  if(barcode.value==='') return
-  checkBlindBarcode(params).then(res => {
-    scanSuccess()
-    preBarcode.value = barcode.value;
-    if (modeType === 3) {
-      lotNumberRef.value.focus();
-      focusType.value = 2;
-    } else if (modeType === 5) {
-      const data = {
-        ownerCode,
-        code,
-        cartonCode: preBoxNo.value,
-        barCode: barcode.value,
-      };
-      _setBoxCacheData(data);  // 添加缓存数据
-    }else if(modeType === 2) {
-      const data = {
-        barCode: barcode.value,
-        cartonCode: null,
-        qty: 1
-      };
-      // 查找是否已存在相同的 barCode
-      const existingItem = localData.value.find(item => item.barCode === barcode.value);
-      if (existingItem) {
-        // 如果存在相同的 barCode,数量增加 1
-        existingItem.qty += 1;
-      } else {
-        // 如果不存在相同的 barCode,新增数据
-        localData.value.push(data);
+  const { warehouseCode, ownerCode } = taskInfo.value;
+  preBarcode.value = barcode.value;
+  barcode.value=''
+  if (preBarcode.value === '') return
+  // 检查条码是否存在列表里
+  const isBarcodeEmpty = barcodeIsData(preBarcode.value, localData.value, dataList.value);
+  // 条码存在列表里设置数据
+  if (isBarcodeEmpty) {
+    setBarcode(preBarcode.value);
+  } else {
+    const params = {
+      warehouse: warehouseCode,
+      ownerCode,
+      barcode:preBarcode.value
+    };
+    checkBlindBarcode(params).then(res=>{
+      if(res.data){
+        setBarcode(preBarcode.value)
       }
-      localData.value.unshift(localData.value.pop());
-      boxTypeData.value.latticeDataList.unshift(...localData.value);
-    }
-    barcode.value = '';  // 清空条码
-  }).catch(() => {
-    scanError()
-  })
+    }).catch((err)=>{
+      scanError();
+    })
+  }
+
+};
+// 设置条码的处理
+const setBarcode = (curBarcode) => {
+  barcode.value = '';
+  const { code } = taskInfo.value;
+  console.log(modeType,"modeType")
+  switch (modeType) {
+    case 5:
+    case 1:
+      // 根据 类型设置箱号
+      const data = [{
+        cartonCode: modeType == 5 ? preBoxNo.value : '*',
+        barcode: curBarcode,
+        qty: 1,
+      }];
+      console.log(data)
+      _setBoxCacheData(code, data);  // 添加缓存数据
+      break;
+    case 0:
+      setLocalData(curBarcode, modeType);  // 设置本地数据
+      break;
+    default:
+      break;
+  }
 };
 
-// 盲收-添加缓存数据-按箱清点+分货多人
-const _setBoxCacheData = (data) => {
-  setBoxCacheData(data).then(res=>{
-    boxTypeData.value = res.data
-    scanSuccess()
-  }).catch(() => {
+/**
+ * 设置本地数据
+ */
+const loadLocalData = (taskCode) => {
+  const savedData = localStorage.getItem(`task_${taskCode}`);
+  return savedData ? JSON.parse(savedData) : []; // 如果缓存有数据,解析并返回,如果没有,则返回空数组
+};
+
+const setLocalData=(barCode,type)=>{
+  scanSuccess();
+  const data = {
+    barcode:barCode,
+    cartonCode: null,
+    index:localData.value.length,
+    qty:1
+  };
+  const existingItem = localData.value.find(item => item.barcode === barCode);
+  if (existingItem) {
+    existingItem.qty += 1;
+  } else {
+    localData.value.push(data);
+  }
+  // 将最新数据放到第一位
+  const index = localData.value.findIndex(item => item.barcode === barCode);
+  if (index > 0) {
+    const [itemToMove] = localData.value.splice(index, 1);
+    localData.value.unshift(itemToMove);
+  }
+  localStorage.setItem(`task_${taskInfo.value.code}`, JSON.stringify(localData.value));
+}
+
+//装箱
+const _setBoxBarcode=()=>{
+  const data=loadLocalData(taskInfo.value.code)
+  if(data.length===0) {
+    showToast({duration:5000,message:'当前无需要装箱数据'})
+    return
+  }
+  _setBoxCacheData(route.query.code,data.reverse())
+}
+// 盲收-添加缓存数据
+const _setBoxCacheData = (code,data) => {
+  showLoading()
+  setBoxCacheData(code,taskInfo.value.typeCode,data).then(res=>{
+    dataList.value = res.data
+    localData.value=[]
+    localStorage.removeItem(`task_${taskInfo.value.code}`);
+    if(res.data && modeType!==0){
+      playVoiceBin(Number(res.data[0].latticeCode))
+    }else {
+      scanSuccess()
+    }
+  }).catch((e) => {
     scanError()
+  }).finally(()=>{
+    closeLoading()
   })
 };
 //设置条码数量
@@ -301,22 +371,41 @@ const barcodeCountRef=ref(null)
 const activeItem=ref({})
 const _setBarcodeCount=(item)=>{
   activeItem.value=item
-  barcodeCountRef.value?.show(item.barCode)
+  barcodeCountRef.value?.show(item.barcode)
 }
 const setBarcodeCount=(count)=>{
   const {sku,cartonCode}=activeItem.value
-  const data={
-    code:route.query.code,
-    sku,
-    cartonCode,
-    qty:count,
+  if(activeItem.value.index>=0){
+    const item = localData.value.find(item => item.index === activeItem.value.index);
+    if (item) {
+      item.qty = count;
+    }
+    localStorage.setItem(`task_${taskInfo.value.code}`, JSON.stringify(localData.value));
+  }else {
+    let url=setBoxBarcodeCount
+    let data={
+      code:route.query.code,
+      sku,
+      cartonCode,
+      qty:count,
+    }
+    if(cartonCode==null){
+      url=setNoBoxBarcodeCount
+      data={
+        code:route.query.code,
+        sku,
+        qty:count,
+      }
+    }
+    url(data).then(res=>{
+      dataList.value = res.data
+      scanSuccess()
+      barcodeRef.value?.focus();
+    }).catch(() => {
+      scanError()
+    })
   }
-  setBoxBarcodeCount(data).then(res=>{
-    boxTypeData.value = res.data
-    scanSuccess()
-  }).catch(() => {
-    scanError()
-  })
+
 }
 // 重新清点数据
 const resetDataRef=ref(null)
@@ -328,53 +417,65 @@ const _resetData=()=>{
   }
 
 }
-const onResetData=(bin,type)=>{
-  const params={code:taskInfo.value.code,latticeCode:bin}
-    let url=resetBoxCacheDataBin
-    if(type==='all'){
-      url=resetBoxCacheData
-    }
-    url(params).then(res=>{
-      scanSuccess()
-      boxTypeData.value = res.data
-      barcodeRef.value?.focus()
-    }).catch(() => {
-      scanError()
+//重新清点数据
+const onResetData = (bin, type) => {
+  let url = resetBoxCacheDataBin;
+  let params = { code: taskInfo.value.code, latticeCode: bin };
+  if (type === 'all') {
+    localData.value = []
+    localStorage.removeItem(`task_${taskInfo.value.code}`);
+    if(dataList.value.length===0) return
+    url = resetBoxCacheData;
+  } else if (type === 'bin' && modeType === 0) {
+    url = resetBoxCacheDataBox;
+    params = { code: taskInfo.value.code, cartonCode: bin };
+  }
+  url(params)
+    .then(res => {
+      scanSuccess();
+      dataList.value = res.data;
+      if(modeType===5){
+        boxNoRef.value?.focus()
+      }else {
+        barcodeRef.value?.focus();
+      }
+
     })
-}
+    .catch(() => {
+      scanError();
+    });
+};
 
-const  resetNewBin=()=>{
-  showConfirmDialog({
+//清除上一条数据
+const showConfirmation = (message) => {
+  return showConfirmDialog({
     title: '温馨提示',
-    message:
-      `您正在清除格口:${newOneData.value.latticeCode}数据,是否继续?`,
-  })
+    message,
+  });
+};
+const resetNewBin = () => {
+  const { barcode, index, latticeCode, cartonCode } = newOneData.value;
+  const confirmMessage = index >= 0
+    ? `您正在清除条码:${barcode}数据,是否继续?`
+    : `您正在清除${modeTypeName}:${modeType === 0 ? cartonCode : latticeCode}数据,是否继续?`;
+
+  showConfirmation(confirmMessage)
     .then(() => {
-      onResetData(newOneData.value.latticeCode,'bin')
-    })
-}
-//质量状态选择
-const lotAttQualityRef=ref(null)
-const onLotAtt=()=>{
-  lotAttQualityRef.value.show()
-}
-const selectLotAttQuality=(lotAtt08)=>{
-  console.log(lotAtt08)
-}
-//选择生产日期、失效日期
-const productDateRef=ref(null)
-const dateType=ref(1)
-const onProduct=(type)=>{
-  dateType.value=type
-  productDateRef.value.show()
-}
-const onProductDate=(date)=>{
-  if(dateType.value===1){
-    manufactureDate.value=date
-  }else {
-    expirationDate.value=date
-  }
-}
+      if (index >= 0) {
+        localData.value.splice(0, 1)
+        if(localData.value.length>0){
+          localStorage.setItem(`task_${taskInfo.value.code}`, JSON.stringify(localData.value));
+        }else {
+          localStorage.removeItem(`task_${taskInfo.value.code}`);
+        }
+        barcodeRef.value?.focus()
+      } else {
+        const bin = modeType === 0 ? cartonCode : latticeCode;
+        onResetData(bin, 'bin');
+      }
+
+    });
+};
 const onClickLeft = () => {
   history.back()
 }
@@ -384,11 +485,15 @@ const onClickRight = () => {
     return
   }
   const {code,ownerCode}=taskInfo.value
-  let type='EntryBlindTaskTypeEnum'
-  const data={code,ownerCode,type}
+  if(loadLocalData(code).length>0){
+    showToast({duration:5000,message:'当前还有缓存数据未进行装箱,请先装箱!'})
+    return
+  }
+  const data={code,ownerCode}
   submitBoxCacheData(data).then(res=>{
     scanSuccess()
     showToast('数据提交成功,将进入盲收首页')
+    localStorage.removeItem(`task_${taskInfo.value.code}`);
     onClickLeft()
   }).catch(() => {
     scanError()

+ 0 - 1
src/views/index.vue

@@ -4,7 +4,6 @@
     <div class="name" >{{userInfo.username}}</div>
     <div class="home" @click="onRouter('picking')">进入拣货</div>
     <div class="home" @click="onRouter('mode')">进入盲收</div>
-
   </div>
 </template>
 <script setup>

+ 3 - 4
src/views/outbound/picking/list/index.vue

@@ -117,7 +117,7 @@ const route = useRoute()
 const store = useStore()
 const basic = basicStore()
 import { useStore } from '@/store/modules/user'
-import { goBack, getHeader, playVoicePickNum, scanError, scanSuccess } from '@/utils/android'
+import { goBack, getHeader, playVoicePickNum, scanError, scanSuccess, androidFocus } from '@/utils/android'
 import { closeListener, openListener, scanInit } from '@/utils/keydownListener'
 import BarcodeCombine from '@/views/outbound/picking/components/BarcodeCombine.vue'
 const PickingNoInput = defineAsyncComponent(() => import('@/views/outbound/picking/components/PickingNoInput.vue'))
@@ -234,9 +234,8 @@ const loadData =  async (pickingCode) => {
   }else {
     scanBarcode.value=''
     containerNo.value=''
-    // window.android.focus()
-    // onContainerNo(2)
-
+    androidFocus()
+    onContainerNo(2)
   }
 }
 // 设置拣货容器