Jelajahi Sumber

手持-超收优化

zhaohuanhuan 3 hari lalu
induk
melakukan
922db7b2aa

+ 8 - 0
src/api/takeDelivery/index.ts

@@ -115,6 +115,14 @@ export function setReceiving(data:setReceivingType) {
   })
 }
 
+/** 超收通知 */
+export function notifyOverReceive(businessNo: string) {
+  return request({
+    url: `/api/wms/admin/inbound-self/notifyOverReceive/${businessNo}`,
+    method: 'post',
+  })
+}
+
 
 /**
  * 完成收货

+ 129 - 0
src/views/inbound/takeDelivery/components/OverReceiveConfirmDialogs.vue

@@ -0,0 +1,129 @@
+<template>
+  <van-dialog
+    :show="visible"
+    :title="view.title"
+    show-cancel-button
+    :confirm-button-text="view.okText"
+    cancel-button-text="取消"
+    :before-close="onBeforeClose"
+    @update:show="onShow"
+  >
+    <div class="recv-over">
+      <template v-if="showStep2">
+        <van-notice-bar left-icon="volume-o" :text="view.tip" wrapable class="recv-over__bar" />
+        <van-cell-group inset class="recv-over__cells">
+          <van-cell title="已收数量" :value="cells.received" />
+          <van-cell title="预计数量" :value="cells.expected" />
+          <van-cell title="当前收货数量" :value="cells.current" />
+          <van-cell title="超收数量" :value="cells.thisOver" value-class="recv-over__val-warn" />
+        </van-cell-group>
+      </template>
+      <p v-else class="recv-over__ask">是否确认超收?</p>
+    </div>
+  </van-dialog>
+</template>
+
+<script setup>
+import { computed, nextTick } from 'vue'
+
+const props = defineProps({
+  panel: {
+    type: Object,
+    default: () => ({
+      receivedQty: 0,
+      expectedQtyDisplay: '—',
+      currentQty: 0,
+      thisOverReceiveQty: 0,
+      totalOverReceiveQty: 0,
+    }),
+  },
+  showStep1: Boolean,
+  showStep2: Boolean,
+})
+
+const emit = defineEmits(['update:showStep1', 'update:showStep2', 'confirm-submit'])
+
+const visible = computed(() => props.showStep1 || props.showStep2)
+
+const view = computed(() => {
+  if (props.showStep2) {
+    return {
+      title: '超收确认(2/2)',
+      tip: '请核对收货数量,按超收提交收货。',
+      okText: '确认超收',
+    }
+  }
+  return {
+    title: '超收确认(1/2)',
+    okText: '确认超收',
+  }
+})
+
+const cells = computed(() => {
+  const p = props.panel
+  return {
+    received: String(p?.receivedQty ?? 0),
+    expected: String(p?.expectedQtyDisplay ?? '—'),
+    current: String(p?.currentQty ?? 0),
+    thisOver: String(p?.thisOverReceiveQty ?? 0),
+  }
+})
+
+function closeBoth() {
+  emit('update:showStep1', false)
+  emit('update:showStep2', false)
+}
+
+function onShow(open) {
+  if (!open) closeBoth()
+}
+
+async function onBeforeClose(action) {
+  if (action === 'cancel') {
+    closeBoth()
+    return true
+  }
+  if (action !== 'confirm') return true
+
+  if (props.showStep2) {
+    emit('confirm-submit')
+    return true
+  }
+
+  emit('update:showStep1', false)
+  emit('update:showStep2', true)
+  await nextTick()
+  return false // 第一步不关窗,直接切第二步
+}
+</script>
+
+<style scoped lang="scss">
+.recv-over {
+  padding-bottom: 8px;
+  text-align: left;
+}
+
+.recv-over__ask {
+  margin: 0;
+  padding: 22px 20px 26px;
+  text-align: center;
+  font-size: 15px;
+  color: #323233;
+  line-height: 1.5;
+}
+
+.recv-over__bar {
+  margin: 0 12px 12px;
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.recv-over__cells {
+  margin: 0 12px;
+}
+
+:deep(.recv-over__val-warn) {
+  color: #ee0a24;
+  font-weight: 600;
+}
+</style>

+ 74 - 10
src/views/inbound/takeDelivery/task/index.vue

@@ -186,6 +186,13 @@
       </van-cell>
     </van-cell-group>
   </van-action-sheet>
+
+  <over-receive-confirm-dialogs
+    v-model:show-step1="overReceiveStep1Show"
+    v-model:show-step2="overReceiveStep2Show"
+    :panel="overReceivePanel"
+    @confirm-submit="onOverReceiveStep2Confirm"
+  />
 </template>
 
 <script setup>
@@ -201,6 +208,7 @@ import {
   getPanpassCodeRelation,
   getProductAttribute, getProductLot,
   getReceivingAsnDetails,
+  notifyOverReceive,
   setProductAttribute, setReceiving,
 } from '@/api/takeDelivery/index'
 import { getListCombineSku } from '@/api/picking'
@@ -212,6 +220,7 @@ import Attribute from '@/views/inbound/takeDelivery/components/Attribute.vue'
 import LotDate from '@/views/inbound/takeDelivery/components/LotDate.vue'
 import UniqueCodeInput from '@/views/inbound/takeDelivery/components/UniqueCodeInput.vue'
 import BarcodeCombine from '@/views/inbound/takeDelivery/components/BarcodeCombine.vue'
+import OverReceiveConfirmDialogs from '@/views/inbound/takeDelivery/components/OverReceiveConfirmDialogs.vue'
 import { receivingBarcodeCombine } from '@/views/inbound/takeDelivery/task/hooks/barcodeCombine'
 import { barcodeToUpperCase, toMap } from '@/utils/dataType'
 import { getCurrentTime } from '@/utils/date'
@@ -286,6 +295,22 @@ const back = ref(true)
 const inputBarcodeType = ref('task')
 const inputBarcodeRef = ref(null)
 const oldSearchBarcode = ref('')
+
+async function notifyOverReceiveForTask(task) {
+  const qty = Number(task?.overReceiveQuantity)
+  if (!qty || qty <= 0) return
+  let list =task?.asnNos
+  for (const asnNo of list) {
+    const businessNo =asnNo.replace(/^ASN/i, 'BSCS')
+    if (!businessNo) continue
+    try {
+      await notifyOverReceive(businessNo)
+    } catch {
+      /* 单条通知失败不影响其余 */
+    }
+  }
+}
+
 // 任务号/容器号:code 为任务号时拉取任务及ASN明细
 const setBarcode = (code, type) => {
   if (inputBarcodeType.value === 'lot') {
@@ -343,6 +368,7 @@ const setBarcode = (code, type) => {
       })
         .then(applyTaskAfterFetch)
         .catch(() => {
+          void notifyOverReceiveForTask(data)
           reset()
           taskNo.value = ''
           taskInfo.value = {}
@@ -414,6 +440,21 @@ const showOverReceiveTag = computed(
     || (overReceiveSheetActive.value && !!asnDetailsTrueFalseBy.value),
 )
 
+/** 超收确认 */
+const overReceiveStep1Show = ref(false)
+const overReceiveStep2Show = ref(false)
+const overReceivePanel = ref({
+  receivedQty: 0,
+  expectedQtyDisplay: '--',
+  currentQty: 0,
+  thisOverReceiveQty: 0,
+  totalOverReceiveQty: 0,
+})
+
+const onOverReceiveStep2Confirm = () => {
+  onConfirm(true)
+}
+
 const onAsnActionSheetClosed = () => {
   if (overReceiveSheetActive.value && !asnInfo.value?.asnNo) {
     overReceiveSheetActive.value = false
@@ -1090,17 +1131,40 @@ const onConfirm = (confirmOverReceive=false) => {
     }
     showLoading()
     inputBarcodeType.value='task'
-    setReceiving(data).then(res => {
-      console.log('res',res)
-      if(res.data.overReceive){
+    setReceiving(data).then((res) => {
+      if (res.data.overReceive) {
         scanError()
-        showConfirmDialog({
-          title: '温馨提示',
-          message: '是否确认超收?',
-        }).then(() => {
-          onConfirm(true)
-        }).catch(() => {
-        })
+        const currentReceiveQty = Math.max(0, Math.floor(Number(searchCount.value) || 0))
+        const expectedQty = Math.floor(Number(asnInfo.value.expectedQuantity) || 0)
+        const receivedQty = Math.floor(Number(asnInfo.value.receivedQuantity) || 0)
+        const overReceivedQty = Math.floor(Number(asnInfo.value.overReceiveQuantity) || 0)
+        const receivedTotal = receivedQty + overReceivedQty
+        const receiveData = res.data
+
+        let thisOverReceiveQty
+        if (expectedQty > 0) {
+          const overBefore = Math.max(0, receivedTotal - expectedQty)
+          const overAfter = Math.max(0, receivedTotal + currentReceiveQty - expectedQty)
+          thisOverReceiveQty = overAfter - overBefore
+        } else {
+          thisOverReceiveQty = currentReceiveQty
+        }
+        const apiThisOver = Number(
+          receiveData.thisOverReceiveQuantity ??
+            receiveData.currentOverReceiveQty ??
+            NaN,
+        )
+        if (Number.isFinite(apiThisOver) && apiThisOver >= 0) {
+          thisOverReceiveQty = Math.floor(apiThisOver)
+        }
+        overReceivePanel.value = {
+          receivedQty: receivedTotal,
+          expectedQtyDisplay: expectedQty > 0 ? String(expectedQty) : '—',
+          currentQty: searchCount.value,
+          thisOverReceiveQty
+        }
+        overReceiveStep2Show.value = false
+        overReceiveStep1Show.value = true
       }else{
         scanSuccess()
         showNotify({ type: 'success', duration: 3000, message: `${searchBarcode.value}收货完成,请继续收货!`})