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

宝时快上-新增组合商品

zhaohuanhuan 4 недель назад
Родитель
Сommit
0dffb684cc

+ 99 - 0
src/views/inbound/putaway/components/BarcodeCombine.vue

@@ -0,0 +1,99 @@
+<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 matchedSkuList" :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.expectedQuantity || 0) - (item.receivedQuantity || 0) }}件</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" placeholder="上架套数" />
+    </van-dialog>
+  </div>
+</template>
+<script setup>
+/** 组合商品上架弹框 */
+import { computed, ref } from 'vue'
+import { showToast } from 'vant'
+const goodsTrueFalseBy = ref(false)
+const countRef = ref(null)
+const count = ref('')
+const props = defineProps({
+  matchedSku: { type: Array, default: () => [] },
+})
+const matchedSkuList = computed(() => props.matchedSku)
+const maxCount = computed(() => {
+  const min = Math.min(
+    ...props.matchedSku.map((item) => ((item.expectedQuantity || 0) - (item.receivedQuantity || 0)) / (item.matchedJson?.quantity || 1))
+  )
+  return Number.isFinite(min) ? Math.floor(min) : 0
+})
+const show = () => {
+  count.value = ''
+  goodsTrueFalseBy.value = true
+  setTimeout(() => {
+    countRef.value?.focus()
+  }, 200)
+}
+const dataResult = (data) =>
+  data.map((item) => {
+    const { matchedJson, ...rest } = item
+    return { ...rest, quantity: matchedJson.quantity * Number(count.value) }
+  })
+const emit = defineEmits(['setCombine', 'cancel'])
+const beforeClose = (action) =>
+  new Promise((resolve) => {
+    if (action === 'confirm') {
+      if (count.value == '') {
+        showToast('请输入上架套数')
+        return resolve(false)
+      }
+      if (Number(count.value) <= 0) {
+        showToast('请输入有效上架套数')
+        return resolve(false)
+      }
+      if (Number(count.value) > maxCount.value) {
+        showToast({ duration: 3000, message: '上架套数不能大于可上架套数' })
+        return resolve(false)
+      }
+      const dataList = dataResult(matchedSkuList.value)
+      emit('setCombine', { dataList, count: Number(count.value) })
+    } else {
+      emit('cancel')
+    }
+    resolve(true)
+  })
+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
+  .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>

+ 84 - 5
src/views/inbound/putaway/task/index.vue

@@ -148,6 +148,8 @@
       <location-list :locationList="locationList" />
     </div>
   </van-action-sheet>
+  <!--  组合商品上架数量-->
+  <barcode-combine ref="barcodeCombineRef" @setCombine="setPutawayCombine" @cancel="onCombineCancel" :matched-sku="combineMatchedSku" />
 </template>
 
 <script setup>
@@ -155,6 +157,7 @@ import { onMounted, onUnmounted, ref, computed } from 'vue'
 import { androidFocus, getHeader, goBack, scanError, scanSuccess } from '@/utils/android'
 import InputBarcode from '@/views/outbound/picking/components/InputBarcode.vue'
 import LocationList from '@/views/inbound/putaway/components/LocationList.vue'
+import BarcodeCombine from '@/views/inbound/putaway/components/BarcodeCombine.vue'
 import { openListener,closeListener,scanInit } from '@/utils/keydownListener.js'
 import { useRouter } from 'vue-router'
 import { closeLoading, showLoading } from '@/utils/loading'
@@ -162,6 +165,7 @@ import { useStore } from '@/store/modules/user'
 import { showNotify, showToast } from 'vant'
 import { getCurrentTime } from '@/utils/date'
 import { getWaitPutawayListNew, setPutawayNew } from '@/api/putaway/index'
+import { getListCombineSku } from '@/api/picking'
 import { barcodeToUpperCase } from '@/utils/dataType.js'
 import { getRecommendedLocation } from '@/api/haikang/index'
 import { getOwnerList } from '@/hooks/basic/index'
@@ -182,7 +186,7 @@ onMounted(() => {
 })
 const warehouse = store.warehouse
 //容器号
-const containerNo = ref('')
+const containerNo = ref('zhh-c')
 //数据列表
 const dataList = ref([])
 //
@@ -376,6 +380,10 @@ const switchTask = () => {
 const lotBarcodeList = ref([])
 const lotBarcodeTrueFalseBy = ref(false)
 const barcodeActiveList = ref([])
+// 组合商品
+const barcodeCombineRef = ref(null)
+const putawayCombineData = ref(null)
+const combineMatchedSku = ref([])
 const reset = () => {
   searchCount.value = ''
   searchBarcode.value = ''
@@ -383,11 +391,42 @@ const reset = () => {
   oldSearchBarcode.value = ''
   locationList.value = []
   barcodeActiveList.value = []
+  putawayCombineData.value = null
+  combineMatchedSku.value = []
+}
+// 组合商品上架数量弹框
+const _showPutawayCombineDialog = (batchItem) => {
+  if (!putawayCombineData.value || !batchItem?.length) return
+  const total = batchItem.reduce((sum, i) => sum + Number(i.quantity || 0), 0)
+  combineMatchedSku.value = [{
+    matchedJson: putawayCombineData.value,
+    expectedQuantity: total,
+    receivedQuantity: 0,
+  }]
+  barcodeCombineRef.value?.show()
+}
+// 组合商品确认上架数量
+const setPutawayCombine = ({ dataList }) => {
+  if (dataList?.[0]?.quantity != null) {
+    searchCount.value = String(dataList[0].quantity)
+  }
+  showNotify({ type: 'success', duration: 2000, message: `已填入上架数量:${searchCount.value},请扫描库位并确认上架` })
+}
+// 组合商品取消
+const onCombineCancel = () => {
+  const qtyPerSet = putawayCombineData.value?.quantity ?? 1
+  searchCount.value = String(qtyPerSet)
 }
 // 选择单据
 const onDetailActive = (item) => {
   barcodeActiveList.value = item
   lotBarcodeTrueFalseBy.value = false
+  if (putawayCombineData.value) {
+    _showPutawayCombineDialog(item)
+    _getRecommendedLocation(item[0].lotNumber, item[0].owner)
+    scanType.value = 3
+    return
+  }
   searchCount.value = 1
   scanType.value = 3
   _getRecommendedLocation(item[0].lotNumber, item[0].owner)
@@ -400,6 +439,46 @@ const onAsnCancel = () => {
     locationList.value = []
   }
 }
+// 商品条码不匹配时,查询组合条码
+const _handlePutawayCombineProduct = (code) => {
+  showLoading()
+  getListCombineSku({ combineSku: barcodeToUpperCase(code), workEnvironment: 'inbound' })
+    .then((res) => {
+      const _err = (msg) => {
+        closeLoading()
+        scanError()
+        showNotify({ type: 'danger', duration: 3000, message: msg })
+        reset()
+      }
+      if (!res.data?.length) return _err(`${code}-商品条码不匹配,请重新扫描`)
+      if (res.data.length > 1) return _err('不支持多商品组合商品')
+      const combineBarcode = res.data[0].barcode
+      lotBarcodeList.value = matchingBarcodeItem(dataMap.value, combineBarcode)
+      if (lotBarcodeList.value.length === 0) return _err('组合商品与待上架数据不匹配,请检查组合商品配置!')
+      putawayCombineData.value = res.data[0]
+      closeLoading()
+      scanSuccess()
+      if (lotBarcodeList.value.length === 1) {
+        barcodeActiveList.value = lotBarcodeList.value[0]
+        _showPutawayCombineDialog(lotBarcodeList.value[0])
+        _getRecommendedLocation(barcodeActiveList.value[0].lotNumber, barcodeActiveList.value[0].owner)
+        scanType.value = 3
+      } else {
+        locationList.value = []
+        barcodeActiveList.value = []
+        searchCount.value = ''
+        searchLocation.value = ''
+        lotBarcodeTrueFalseBy.value = true
+      }
+    })
+    .catch(() => {
+      closeLoading()
+      scanError()
+      showNotify({ type: 'danger', duration: 3000, message: `${code}-商品条码不匹配,请重新扫描` })
+      reset()
+    })
+}
+
 // 扫描条码监听
 const _handlerScan = (code) => {
   if (scanType.value == 2) {
@@ -407,6 +486,8 @@ const _handlerScan = (code) => {
     oldSearchBarcode.value = code
     lotBarcodeList.value = matchingBarcodeItem(dataMap.value, code)
     if (lotBarcodeList.value.length > 0) {
+      putawayCombineData.value = null
+      combineMatchedSku.value = []
       if (lotBarcodeList.value.length == 1) {
         barcodeActiveList.value = lotBarcodeList.value[0]
         _getRecommendedLocation(barcodeActiveList.value[0].lotNumber, barcodeActiveList.value[0].owner)
@@ -420,14 +501,12 @@ const _handlerScan = (code) => {
         lotBarcodeTrueFalseBy.value = true
       }
     } else {
-      scanError()
-      showNotify({ type: 'danger', duration: 3000, message: `${code}-商品条码不匹配,请重新扫描` })
-      reset()
+      _handlePutawayCombineProduct(code)
     }
   } else if (scanType.value == 3) {
     searchLocation.value = barcodeToUpperCase(code)
     scanType.value = 4
-    searchCount.value = 1
+    if (!searchCount.value) searchCount.value = 1
     scanSuccess()
   }
 }