Bläddra i källkod

手持-新增收货初始化

zhaohuanhuan 10 månader sedan
förälder
incheckning
e8b3bb085c

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

@@ -0,0 +1,102 @@
+// @ts-ignore
+import request from '@/utils/request'
+// @ts-ignore
+import { calculateShelfLifeType, getCommodityRuleType, getIReceivingTaskType, getProductAttributeType, getReceivingAsnDetailsType, setProductAttributeDataType, setProductAttributeParamsType, setReceivingType} from '@/types/takeDelivery'
+/**
+ * 获取收货任务详情以及当前员工收货信息
+ * @param data
+ */
+export function getIReceivingTask(data:getIReceivingTaskType) {
+  return request({
+    url: '/api/device/check/receiving/getTask',
+    method: 'post',
+    data:JSON.stringify(data),
+  })
+}
+
+/**
+ * 待收货ASN详情
+ * @param params
+ */
+export function getReceivingAsnDetails(params:getReceivingAsnDetailsType) {
+  return request({
+    url: '/api/wms/receiving/get-asn-details',
+    method: 'get',
+    params
+  })
+}
+
+/**
+ * 获取商品物理属性
+ * @param params
+ */
+export function getProductAttribute(params:getProductAttributeType) {
+  return request({
+    url: '/api/basic/product/attribute',
+    method: 'get',
+    params
+  })
+}
+
+/**
+ * 获取商品物理属性
+ * @param params
+ */
+export function setProductAttribute(params:setProductAttributeParamsType,data:setProductAttributeDataType) {
+  return request({
+    url: '/api/basic/product/update-attribute',
+    method: 'post',
+    params,
+    data
+  })
+}
+
+/**
+ * 获取商品批次属性
+ * @param params
+ */
+export function getProductLot(params:getProductAttributeType) {
+  return request({
+    url: '/api/basic/product/lot',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 获取商品批次属性
+ * @param params
+ */
+export function calculateShelfLife(params:calculateShelfLifeType) {
+  return request({
+    url: '/api/basic/product/calculateShelfLife',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 查询商品规则
+ * @param params
+ */
+export function getCommodityRule(params:getCommodityRuleType) {
+  return request({
+    url: '/api/base/commodity/rule/list',
+    method: 'get',
+    params
+  })
+}
+
+
+/**
+ * 完成收货
+ * @param params
+ */
+export function setReceiving(data:setReceivingType) {
+  return request({
+    url: '/api/wms/receiving',
+    method: 'post',
+    data
+  })
+}
+
+
+

+ 7 - 0
src/router/index.ts

@@ -55,6 +55,13 @@ const routes: RouteRecordRaw[] = [
     meta:{title:'计件面板'},
     component: () => import('@/views/piece/dashboard/index.vue')
   },
+  {
+    path: '/take-delivery',
+    name: 'TakeDelivery',
+    meta:{title:'宝时丰收'},
+    component: () => import('@/views/inbound/TakeDelivery/task/index.vue')
+  },
+
 ];
 
 // 创建路由实例

+ 129 - 0
src/types/takeDelivery.ts

@@ -0,0 +1,129 @@
+
+/**
+ * 获取收货任务详情以及当前员工收货信息
+ * @param taskNo 任务号
+ * @param staff  操作人账号
+ * @param version  系统版本
+ */
+export interface getIReceivingTaskType {
+  taskNo: string;
+  version:string
+}
+
+/**
+ * 获取收货任务详情以及当前员工收货信息
+ * @param warehouse 仓库
+ * @param barcode  条码
+ * @param asnNos  ASN单号
+ */
+export interface getReceivingAsnDetailsType {
+  warehouse: string;
+  barcode:string,
+  asnNos?: string[];
+
+}
+/**
+ * 获取商品物理属性
+ * @param warehouse 仓库
+ * @param barcode  条码
+ * @param owner  货主
+ */
+export interface getProductAttributeType {
+  warehouse: string;
+  owner:string;
+  barcode:string,
+
+}
+/**
+ * 修改商品物理属性路径参数
+ * @param warehouse 仓库
+ * @param sku  sku
+ * @param owner  货主
+ */
+export interface setProductAttributeParamsType {
+  warehouse?: string;
+  owner?:string;
+  sku?:string,
+}
+
+/**
+ * 修改商品物理属性
+ @param packCarton 每箱件数
+ @param length 长
+ @param width 宽
+ @param height 高
+ @param weight 重量(千克)
+ @param packId 箱规
+ @param sku 商品编码
+ @param size 是否需要维护长宽高
+ @param metering 是否需要维护体积重量
+ @param carton 是否需要维护箱规
+ */
+export interface setProductAttributeDataType {
+  packCarton?: string;
+  length?:string;
+  width?:string,
+  height?:string,
+  weight?:string,
+  packId?:string,
+  sku?:string,
+  size?:boolean,
+  metering?:boolean,
+  carton?:boolean,
+}
+
+/**
+ * 计算效期
+ */
+export interface calculateShelfLifeType {
+  barcode?: string;
+  customer?: string;
+  /**
+   * 生产日期或失效日期
+   */
+  date?: string;
+  /**
+   * true:计算失效日期, false:计算生产日期
+   */
+  isExpiryDate?: string;
+  [property: string]: any;
+}
+/**
+ * 收货
+ */
+export interface setReceivingType {
+  asnLineNo?: string;
+  asnNo?: string;
+  containerId?: string;
+  lotAtt05?: string;
+  lotAtt08?: string;
+  quantity?: number;
+  /**
+   * 序列号(商品唯一码)
+   */
+  serialNos?: string[];
+  warehouse?: string;
+  [property: string]: any;
+}
+
+/**
+ * 获取商品规则
+ */
+export interface getCommodityRuleType {
+  /**
+   * 货主编码
+   */
+  customer?: string;
+  /**
+   * RECEIVING-收货, REVIEW-复核
+   */
+  input?: string;
+  /**
+   * 商品编码
+   */
+  sku?: string;
+  [property: string]: any;
+}
+
+
+

+ 11 - 0
src/utils/date.ts

@@ -20,3 +20,14 @@ export function getTimeHours(date: Date | string): number | undefined {
   const timeDiff = currentTime.getTime() - targetTime.getTime(); // 获取毫秒差
   return Math.floor(timeDiff / (1000 * 60 * 60)); // 转换为小时
 }
+
+/*
+ *获取当前时间时分秒
+ */
+export function getCurrentTime() {
+  const now = new Date();
+  const hours = String(now.getHours()).padStart(2, '0');
+  const minutes = String(now.getMinutes()).padStart(2, '0');
+  const seconds = String(now.getSeconds()).padStart(2, '0');
+  return `${hours}:${minutes}:${seconds}`;
+};

+ 133 - 0
src/views/inbound/TakeDelivery/components/Attribute.vue

@@ -0,0 +1,133 @@
+<template>
+  <div class="attribute">
+    <van-dialog v-model:show="attributeTrueFalseBy"
+                title="维护货品属性"
+                show-cancel-button
+                :beforeClose="beforeClose"
+                :keyboardEnabled="false"
+    >
+      <div>
+        <van-form>
+          <van-cell-group inset>
+            <van-field v-if="attribute.includes('size')"
+                       v-model="length"
+                       name="length"
+                       type="number"
+                       label="长/厘米:"
+                       placeholder="请输入长/厘米"
+                       :label-width="70"
+                       clearable
+                       autocomplete="off"
+            />
+            <van-field v-if="attribute.includes('size')"
+                       v-model="width"
+                       name="width"
+                       type="number"
+                       label="宽/厘米:"
+                       placeholder="请输入宽/厘米"
+                       :label-width="70"
+                       clearable
+                       autocomplete="off"
+            />
+            <van-field v-if="attribute.includes('size')"
+                       v-model="height"
+                       name="height"
+                       type="number"
+                       label="高/厘米:"
+                       placeholder="请输入高/厘米"
+                       :label-width="70"
+                       clearable
+                       autocomplete="off"
+            />
+            <van-field v-if="attribute.includes('metering')"
+                       v-model="weight"
+                       name="weight"
+                       type="number"
+                       label="重量/千克:"
+                       placeholder="请输入重量/千克"
+                       :label-width="70"
+                       clearable
+                       autocomplete="off"
+            />
+            <van-field v-if="attribute.includes('carton')"
+                       v-model="packCarton"
+                       name="packCarton"
+                       type="number"
+                       label="每箱件数:"
+                       placeholder="请输入每箱件数"
+                       :label-width="70"
+                       clearable
+                       autocomplete="off"
+            />
+          </van-cell-group>
+        </van-form>
+      </div>
+    </van-dialog>
+  </div>
+</template>
+<script setup>
+import { ref } from 'vue'
+import { showToast } from 'vant'
+
+const attributeTrueFalseBy = ref(false)
+//长/厘米
+const length = ref('')
+//宽/厘米
+const width = ref('')
+//高/厘米
+const height = ref('')
+//每箱件数
+const packCarton = ref('')
+//重量/千克
+const weight = ref('')
+const attribute = ref([])
+const show = (item, attributeMap) => {
+  length.value = ''
+  width.value = ''
+  height.value = ''
+  packCarton.value = ''
+  weight.value = ''
+  attribute.value = item
+  attributeTrueFalseBy.value = true
+}
+
+const emit = defineEmits()
+const beforeClose = (action) =>
+  new Promise(async (resolve) => {
+    if (action === 'confirm') {
+      if (['size', 'metering'].some(val => attribute.value.includes(val))) {
+        if (!length.value || !width.value || !height.value || !height.value) {
+          showToast('请输入长宽高')
+          return resolve(false)
+        }
+      }
+      if (['metering'].some(val => attribute.value.includes(val))) {
+        if (!weight.value) {
+          showToast('请输入重量')
+          return resolve(false)
+        }
+      }
+      if (['carton'].some(val => attribute.value.includes(val))) {
+        if (!packCarton.value) {
+          showToast('请输入每箱件数')
+          return resolve(false)
+        }
+      }
+      const data = {
+        height: height.value ? height.value / 100 : undefined,
+        length: length.value ? length.value / 100 : undefined,
+        width: width.value ? width.value / 100 : undefined,
+        packCarton: packCarton.value,
+        packId: packCarton.value ? '1/' + packCarton.value : 'STANDARD',
+        weight: weight.value,
+        cube: (height.value / 100) * (length.value / 100) * (width.value / 100),
+      }
+      emit('setAttribute', data)
+    }
+    resolve(true)
+  })
+defineExpose({ show })
+
+</script>
+<style lang="scss" scoped>
+</style>

+ 56 - 0
src/views/inbound/TakeDelivery/components/LotDate.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="lot-date">
+    <van-popup v-model:show="lotDateTrueFalseBy" destroy-on-close round position="bottom">
+          <van-date-picker
+            v-model="currentDate"
+            :title="title"
+            :min-date="minDate"
+            @cancel="lotDateTrueFalseBy = false"
+            @confirm="onConfirm"
+            format="yyyy-MM-dd"
+          />
+    </van-popup>
+
+  </div>
+</template>
+<script setup>
+import { ref, computed } from 'vue'
+const lotDateTrueFalseBy=ref(false)
+const title=ref('选择日期')
+// 获取当前日期
+const today = new Date()
+const currentDate = ref([today.getFullYear(), today.getMonth() + 1, today.getDate()])
+// 最小日期为当前日期前三年
+const minDate = computed(() => {
+  const date = new Date(today)
+  date.setFullYear(today.getFullYear() - 3) // 当前日期减去3年
+  return date
+})
+// // 最大日期为当前日期后8年
+// const maxDate = computed(() => {
+//   const date = new Date(today)
+//   date.setFullYear(today.getFullYear() + 10) // 当前日期加上8年
+//   return date
+// })
+
+const show = (label,date) => {
+  title.value = label
+  let day  = ''
+  if(date){
+    day= new Date(date)
+  }else {
+    day= new Date()
+  }
+  currentDate.value = [day.getFullYear(), day.getMonth() + 1, day.getDate()]
+  lotDateTrueFalseBy.value = true
+}
+const emit = defineEmits(['selectLotDate'])
+const onConfirm=({ selectedValues })=>{
+  const formattedDate = `${selectedValues[0]}-${selectedValues[1]}-${selectedValues[2]}`;
+  lotDateTrueFalseBy.value = false
+  emit('selectLotDate', formattedDate)
+}
+defineExpose({show})
+</script>
+<style scoped lang="sass">
+</style>

+ 268 - 0
src/views/inbound/TakeDelivery/components/UniqueCodeInput.vue

@@ -0,0 +1,268 @@
+<template>
+  <div class="unique-code">
+    <van-dialog v-model:show="uniqueCodeTrueFalseBy"
+                :keyboardEnabled="false"
+                :beforeClose="beforeClose"
+                title="唯一码录入"
+                show-cancel-button>
+      <div>
+        <div class="unique-code-type">
+          <div class="tips">{{ tag }}</div>
+          <div>
+            <div :class="newCheckAllType?'unique-v-active':'unique-v-no-active'"  @click="onCheckAllType"> <van-icon name="exchange" /> 条码校验</div>
+<!--            <van-button type="primary" size="mini" :plain="!newCheckAllType" @click="onCheckAllType" icon="exchange"  >条码校验</van-button>-->
+          </div>
+        </div>
+        <div class="unique-input-list" v-if="newCheckAllType">
+          <div class="unique-input-list-left">商品条码:</div>
+          <div class="unique-input-list-right">
+            <van-field class="code-input"
+                       v-model="uniqueBarcode"
+                       ref="uniqueBarcodeRef"
+                       clearable
+                       autocomplete="off"
+                       placeholder="请扫描商品条码"
+                       type="text"
+                       @keydown.enter="uniqueBarcodeChange"
+                       :style="uniqueCodeScanType == 'barcode' ? { 'border-bottom': '2px solid #1989fa' } : {}"
+                       @focus="uniqueCodeScanType = 'barcode'"
+
+            />
+          </div>
+        </div>
+        <div class="unique-input-list">
+          <div class="unique-input-list-left">唯&nbsp;&nbsp;一&nbsp;&nbsp;码:</div>
+          <div class="unique-input-list-right">
+            <van-field class="code-input"
+                       v-model="uniqueCode"
+                       ref="uniqueCodeRef"
+                       clearable
+                       autocomplete="off"
+                       placeholder="请扫描唯一码"
+                       type="text"
+                       @keydown.enter="onKeydown"
+                       :style="uniqueCodeScanType == 'unique' ? { 'border-bottom': '2px solid #1989fa' } : {}"
+                       @focus="uniqueCodeScanType = 'unique'"
+            />
+          </div>
+        </div>
+      </div>
+      <div class="container-list">
+        <div v-for="(item,i) in containerList" class="container-item" :key="i">
+          <div style="display: flex;justify-content: space-between;align-items: center;">
+            <div style="margin-right: 3px;">{{ containerList.length - i }}</div>
+            <div class="container-item-line"></div>
+          </div>
+          <div class="container-item-no">
+            <van-notice-bar :background="'none'" color="#000" :speed="10" :text="item" />
+          </div>
+          <div class="container-item-clear" @click="containerList.splice(i,1)">
+            <van-icon name="delete-o" color="#ee0a24" size="15" />
+          </div>
+        </div>
+      </div>
+    </van-dialog>
+  </div>
+</template>
+<script setup>
+import { computed, ref } from 'vue'
+import { showNotify } from 'vant'
+import { scanError, scanSuccess } from '@/utils/android'
+import { barcodeToUpperCase } from '@/utils/dataType.js'
+const uniqueCodeTrueFalseBy = ref(false)
+//商品条码
+const uniqueBarcode=ref('')
+const uniqueBarcodeRef=ref(null)
+
+//唯一码
+const uniqueCode = ref('')
+const uniqueCodeRef = ref(null)
+
+const tag = ref('')
+// 定义传入的 props
+const props = defineProps({
+  uniqueCodeList: Array,
+  scanType: Number,
+  searchCount: [String, Number],
+  asnInfo:Object,
+  checkAllType:Boolean
+})
+const scanInputType=props.checkAllType?'barcode':'unique'
+const uniqueCodeScanType=ref(scanInputType)
+// 定义自定义的 emit
+const emit = defineEmits(['update:scanType', 'update:uniqueCodeList', 'setUniqueCode','update:checkAllType'])
+const containerList = computed(() => {
+  return props.uniqueCodeList
+})
+const uniqueRuleMap = ref({})
+const show = async (code, desc, tips, uniqueRule) => {
+  if (tips !== undefined) {
+    tag.value = tips
+  }
+  uniqueRuleMap.value = uniqueRule
+  uniqueCodeTrueFalseBy.value = true
+}
+const newCheckAllType=ref(props.checkAllType)
+// 切换校验类型
+const onCheckAllType=()=>{
+  newCheckAllType.value = !newCheckAllType.value
+  uniqueCodeScanType.value = newCheckAllType.value ? 'barcode' : 'unique';
+  localStorage.setItem('checkAllType',newCheckAllType.value)
+  emit('update:checkAllType',newCheckAllType.value)
+}
+//商品条码验证
+const uniqueBarcodeChange=()=>{
+  if(newCheckAllType.value){
+    if(!uniqueBarcode.value){
+      showNotify({ type: 'danger', duration: 3000, message: `请先扫描商品条码` })
+      scanError()
+      return false
+    }
+    const barcode = Array.from(new Set([props.asnInfo.barcode, props.asnInfo.barcode2, props.asnInfo.sku].filter(Boolean)))
+    if (barcode.some(item => barcodeToUpperCase(item) ===  barcodeToUpperCase(uniqueBarcode.value))) {
+      scanSuccess()
+      uniqueCodeRef.value?.focus()
+      return true
+    }else {
+      showNotify({ type: 'danger', duration: 3000, message: `${uniqueBarcode.value}-商品条码不匹配、请重新扫描` })
+      uniqueBarcode.value=''
+      scanError()
+      return false
+    }
+  }
+  return true
+}
+const onKeydown = () => {
+  if(!uniqueBarcodeChange()) return
+  if (uniqueCode.value) {
+    const uniqueRegExp = uniqueRuleMap.value['sku'] ? uniqueRuleMap.value['sku'] : uniqueRuleMap.value['all']
+    const isValidCode = new RegExp(uniqueRegExp).test(uniqueCode.value)
+    if (!isValidCode) {
+      scanError()
+      showNotify({ type: 'danger', duration: 3000, message: `唯一码《${uniqueCode.value}》不符合规则、请重新扫描` })
+      uniqueCode.value = ''
+      return
+    }
+    if (containerList.value.includes(uniqueCode.value)) {
+      scanError()
+      showNotify({ type: 'danger', duration: 3000, message: `唯一码《${uniqueCode.value}》已存在列表内请重新扫描` })
+      uniqueCode.value = ''
+      return
+    }
+    scanSuccess()
+    containerList.value.unshift(uniqueCode.value)
+    uniqueBarcode.value=''
+    uniqueCode.value = ''
+    if(newCheckAllType.value){
+      uniqueBarcodeRef.value?.focus()
+    }else {
+      uniqueCodeRef.value?.focus()
+    }
+  }
+  emit('update:uniqueCodeList', containerList.value)
+}
+const beforeClose = (action) =>
+  new Promise(async (resolve) => {
+    if (action === 'confirm') {
+      if (containerList.value.length != props.searchCount) {
+        scanError()
+        showNotify({
+          type: 'danger',
+          duration: 3000,
+          message: `当前扫描唯一码数量:${containerList.value.length}、收货数量:${props.searchCount},请扫描相同数量唯一码`,
+        })
+        return resolve(false)
+      }
+      resolve(true)
+      emit('update:scanType', 2)
+      emit('setUniqueCode')
+    } else {
+      resolve(true)
+      emit('update:scanType', 2)
+    }
+  })
+
+defineExpose({ show ,uniqueBarcode,uniqueCodeScanType })
+</script>
+<style scoped lang="sass">
+.unique-code
+  .unique-code-type
+    display: flex
+    justify-content: space-between
+    align-items: center
+    padding: 0 15px
+    .unique-v-active
+      background: #1989fa
+      font-size: 10px
+      color: #FFFFFF
+      border-radius: 5px
+      padding:  5px
+    .unique-v-no-active
+      background: #6e6c6c
+      color: #FFFFFF
+      font-size: 10px
+      border-radius: 5px
+      padding:  5px
+  .unique-input-list
+    display: flex
+    padding: 0 10px
+    .unique-input-list-left
+      display: flex
+      justify-content: center
+      align-items: center
+      gap: 10px
+    .unique-input-list-right
+      flex: 1
+      .code-input
+        font-size: 22px
+        font-weight: bold
+        border-bottom: 2px solid #efefef
+        margin-top: 10px
+
+      .completion
+        text-align: right
+        font-size: 12px
+        padding: 5px 20px
+        cursor: pointer
+        text-decoration: underline
+  .container-list
+    max-height: 100px
+    font-size: 13px
+    font-weight: bold
+    display: flex
+    margin: 10px 15px
+    justify-content: space-between
+    flex-wrap: wrap
+    overflow: auto
+
+    .container-item
+      width: 99%
+      display: flex
+      justify-items: center
+      align-items: center
+      padding: 2px
+      cursor: pointer
+      border-bottom: 1px solid #efefef
+      .container-item-line
+        width: 5px
+        height: 5px
+        background: #0077ff
+        border-radius: 50%
+        margin-right: 5px
+
+      .container-item-no
+        flex: 1
+        text-align: left
+        text-decoration: underline
+
+      .container-item-clear
+        padding: 0 15px
+    .container-item:last-child
+      border-bottom: none
+
+  .tips
+    font-size: 14px
+    color: #ff4141
+    line-height: 20px
+
+</style>

+ 23 - 0
src/views/inbound/TakeDelivery/task/hooks/attribute.js

@@ -0,0 +1,23 @@
+export function isAttribute(item) {
+  const list = [];
+  // 检查 item.size 是否存在,若存在则验证长宽高是否完整
+  if (item.size && (!item.length || !item.width || !item.height)) {
+    console.log('补全长宽高');
+    list.push('size');
+  }
+  // 检查 item.carton 是否存在,若存在则验证箱规是否完整
+  if (item.carton && (!item.packCarton)) {
+    console.log('补全箱规');
+    list.push('carton');
+  }
+  // 检查 item.metering 是否存在,若存在则验证体积重量是否完整
+  if (item.metering && (!item.cube)) {
+    console.log('补全体积');
+    list.push('size');
+  }
+  if (item.metering && (!item.weight)) {
+    console.log('补全重量');
+    list.push('metering');
+  }
+  return list;
+}

+ 813 - 0
src/views/inbound/TakeDelivery/task/index.vue

@@ -0,0 +1,813 @@
+<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>
+    </van-nav-bar>
+    <div class="take-delivery">
+      <div class="take-info">
+        <div class="take-info-no">
+          <div class="info-no-title">
+            <div>任务号:{{ taskInfo.taskNo || '--' }}</div>
+            <div>
+              <van-button type="primary" size="mini" plain @click="switchTask">切换任务</van-button>
+            </div>
+          </div>
+          <div class="info-no-tips">
+            <div>货主:<span style="color: #333;font-weight: bold;">{{ taskInfo.customerName || '--' }}</span></div>
+            <div>任务数:<span style="color: #0077ff;font-weight: bold;">{{ taskInfo.receivedQty || 0 }}/{{ taskInfo.expectedQty || 0}}</span></div>
+          </div>
+        </div>
+        <div class="take-info-number">
+          <div class="info-number-left">
+            <div class="number-left-box">
+              <div>开始时间</div>
+              <div class="left-box-title">{{ currentTime }}</div>
+            </div>
+            <div class="number-left-box">
+              <div>已用时</div>
+              <div class="left-box-title">{{ formattedTime }}</div>
+            </div>
+          </div>
+          <div class="info-number-right">
+            <div>容器号</div>
+            <div>
+              <van-search
+                ref="containerNoRef"
+                v-model="containerNo"
+                left-icon=""
+                placeholder="请扫描容器号"
+                autocomplete="off"
+                @search="onConfirm"
+                @focus="scanType=5"
+                @blur="scanType=2"
+              ></van-search>
+            </div>
+          </div>
+        </div>
+      </div>
+      <van-progress v-if="taskInfo.receivedQty/taskInfo.expectedQty>=0" :percentage="((taskInfo.receivedQty/taskInfo.expectedQty)*100).toFixed(2)" stroke-width="4" />
+      <div class="take-barcode">
+        <div class="barcode-input">
+          <van-search
+            ref="searchRef"
+            v-model="searchBarcode"
+            placeholder="请扫描商品条码"
+            @search="_handlerScan(searchBarcode)"
+            label="商品条码:"
+            left-icon=""
+            :class="[scanType===2?'search-input-barcode':'','van-hairline--bottom']"
+            @focus="scanType=2"
+            autocomplete="off"
+            @input="onAsnCancel"
+            @clear="reset"
+          >
+          </van-search>
+        </div>
+        <div class="barcode-input">
+          <van-search
+            ref="numberRef"
+            v-model="searchCount"
+            placeholder="请输入收货数量"
+            type="number"
+            label="收货数量:"
+            left-icon=""
+            autocomplete="off"
+            show-action
+            :min="1"
+            :max="asnInfo.asnNo?asnInfo.expectedQuantity-asnInfo.receivedQuantity:10000"
+            @search="onConfirm"
+            :class="[scanType===4?'search-input-barcode':'','van-hairline--bottom']"
+            @focus="scanType=4"
+            @blur="scanType=2"
+          >
+            <template #action>
+              <div style="display: flex; align-items: center;flex-direction: column;margin-left: 20px"
+                   v-if="asnInfo.asnNo">
+                <div style="height: 20px;font-size: 12px">已收/预计</div>
+                <div style="font-size: 16px;font-weight: bold">{{ asnInfo.receivedQuantity}}/{{ asnInfo.expectedQuantity }}
+                </div>
+              </div>
+            </template>
+          </van-search>
+        </div>
+      </div>
+      <div class="take-lot" v-if="lotData.length>0">
+        <van-cell-group>
+          <div class="take-lot-title">批次信息</div>
+          <van-cell v-for="(item,i) in lotData" :key="i" :is-link="item.field!=='lotAtt05' && item.field!=='lotAtt08'"
+                    @click="onLot(item)">
+            <template #title>
+              <van-icon v-if="item.require" name="warning-o" color="#ed6a0c" />
+              <span class="custom-title">{{ item.label }}</span>
+            </template>
+            <template #value>
+              <div>{{ item.mapping }}</div>
+            </template>
+          </van-cell>
+        </van-cell-group>
+      </div>
+      <div class="take-button">
+        <van-button type="primary" size="large" round style="height: 36px" @click="onConfirm">完成收货</van-button>
+      </div>
+    </div>
+  </div>
+
+  <!-- 条码输入组件 -->
+  <input-barcode :back="back" @setBarcode="setBarcode" ref="inputBarcodeRef"  />
+  <!--  单据选择-->
+  <van-action-sheet v-model:show="asnDetailsTrueFalseBy" cancel-text="取消" description="请选择具体单据" close-on-click-action>
+    <van-cell-group>
+      <van-cell v-for="item in asnDetailsList" @click="onDetailActive(item)">
+        <template #title>
+          {{ item.asnNo }}({{ item.customerId }}-{{ item.expectedQuantity }}件)
+        </template>
+      </van-cell>
+    </van-cell-group>
+  </van-action-sheet>
+  <!--  商品物理属性-->
+  <attribute ref="attributeRef" @set-attribute="setAttribute" />
+  <!--  商品批次属性-->
+  <lot-date ref="lotDateRef" @select-lot-date="selectLotDate" />
+  <!--  唯一码-->
+  <unique-code-input ref="uniqueCodeRef"
+                     v-model:uniqueCodeList="uniqueCodeList"
+                     v-model:scanType="scanType"
+                     v-model:checkAllType="checkAllType"
+                     :searchCount="searchCount"
+                     :asnInfo="asnInfo"
+                     @setUniqueCode="onConfirm"
+
+  />
+</template>
+
+<script setup>
+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 { closeListener, openListener, scanInit } from '@/utils/keydownListener.js'
+import { useRouter } from 'vue-router'
+import {
+  calculateShelfLife, getCommodityRule,
+  getIReceivingTask,
+  getProductAttribute, getProductLot,
+  getReceivingAsnDetails,
+  setProductAttribute, setReceiving,
+} from '@/api/takeDelivery/index'
+import { closeLoading, showLoading } from '@/utils/loading'
+import { useStore } from '@/store/modules/user'
+import { showNotify, showToast } from 'vant'
+import { isAttribute } from '@/views/inbound/TakeDelivery/task/hooks/attribute'
+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 { barcodeToUpperCase, toMap } from '@/utils/dataType.js'
+import { getCurrentTime } from '@/utils/date'
+
+const router = useRouter()
+const store = useStore()
+try {
+  getHeader()
+  androidFocus()
+} catch (error) {
+  router.push('/login')
+}
+const warehouse = store.warehouse
+//开单任务号
+const taskNo = ref('')
+//容器号
+const containerNo = ref('')
+//商品条码
+const searchBarcode = ref('')
+//收货数量
+const searchCount = ref('')
+//收货详情
+const taskInfo = ref({ receivedQty: 0, expectedQty: 0 })
+//开始时间
+const currentTime = ref('--')
+const scanType = ref(2)
+
+const type=localStorage.getItem('checkAllType')?JSON.parse(localStorage.getItem('checkAllType')):true
+const checkAllType=ref(type)
+// 页面初始化
+onMounted(() => {
+  openListener()
+  scanInit(_handlerScan)
+  loadData()
+
+})
+/**
+ * 计算时分秒
+ */
+// 时器的总秒数
+let totalSeconds = ref(0)
+//时分秒
+const formattedTime = ref('00:00:00')
+let windowTimer = null // 计时器的引用
+const updateFormattedTime = () => {
+  let hours = Math.floor(totalSeconds.value / 3600)
+  let minutes = Math.floor((totalSeconds.value % 3600) / 60)
+  let seconds = totalSeconds.value % 60
+  formattedTime.value = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
+}
+// 启动计时器
+const startTimer = () => {
+  if (!windowTimer) {
+    windowTimer = setInterval(() => {
+      totalSeconds.value++
+      updateFormattedTime()
+    }, 1000)
+  }
+}
+
+// 停止计时器
+const stopTimer = () => {
+  if (windowTimer) {
+    clearInterval(windowTimer)
+    windowTimer = null
+  }
+}
+
+const back = ref(true)
+const inputBarcodeType = ref('task')
+//输入框组件
+const inputBarcodeRef = ref(null)
+const oldSearchBarcode = ref('')
+// 设置容器号
+const setBarcode = (code, type) => {
+  if (inputBarcodeType.value === 'lot') {
+    lotData.value.forEach((lot) => {
+      if (lot.field == lotField.value) {
+        lot.mapping = code
+      }
+    })
+    return
+  }
+  showLoading()
+  if(!type){ //切换任务时初始化计时器
+    stopTimer()
+    formattedTime.value="00:00:00"
+    totalSeconds.value=0
+  }
+  getIReceivingTask({ taskNo:code,version:'V6' }).then(res=>{
+    back.value = true
+    if(res.data.receivedQty==res.data.expectedQty && res.data.expectedQty>0 ){
+      if(type){
+        reset()
+        taskNo.value=''
+        taskInfo.value={}
+        switchTask()
+      }else {
+        taskInfo.value=res.data
+        taskNo.value=code
+      }
+      containerNo.value=''
+      stopTimer()
+
+    }else {
+      if(!type){//切换任务成功重启计时器
+        currentTime.value=getCurrentTime()
+        startTimer()
+        containerNo.value=''
+      }
+      taskInfo.value=res.data
+      taskNo.value=code
+    }
+    uniqueCodeList.value=[]
+    scanSuccess()
+  }).catch(err=>{
+    inputBarcodeRef.value?.show('', '请扫描开单任务号',err.message)
+    scanError()
+  }).finally(()=>{
+    reset()
+    closeLoading()
+  })
+}
+// setBarcode('BSSH20250605000006')
+
+//切换任务
+const switchTask = () => {
+  inputBarcodeType.value = 'switchTask'
+  back.value = false
+  inputBarcodeRef.value?.show('', `请扫描开单任务号`,'')
+}
+
+//asn单多条明细展示
+const asnDetailsTrueFalseBy = ref(false)
+const asnDetailsList = ref([])
+const asnInfo = ref({})
+const reset = () => {
+  asnInfo.value = {}
+  lotData.value = []
+  searchCount.value = ''
+  searchBarcode.value = ''
+  oldSearchBarcode.value = ''
+  uniqueCodeList.value = []
+}
+// 选择单据
+const onDetailActive = (item) => {
+  asnInfo.value = item
+  asnDetailsTrueFalseBy.value = false
+  searchCount.value=1
+  // searchCount.value = asnInfo.value.expectedQuantity - asnInfo.value.receivedQuantity
+  _getProductAttribute(item)
+  _getProductLot(item)
+  _getCommodityRule(item)
+}
+const onAsnCancel = () => {
+  if (searchBarcode.value === '' || (oldSearchBarcode.value.length != searchBarcode.value.length && oldSearchBarcode.value != '')) {
+    asnInfo.value = {}
+    lotData.value = []
+    searchCount.value = ''
+  }
+}
+const uniqueCodeList = ref([])
+
+// 扫描条码监听
+const _handlerScan = (code) => {
+  if (scanType.value == 2) {
+    searchBarcode.value = code
+    oldSearchBarcode.value = code
+    const params = { warehouse, barcode: code, asnNos: taskInfo.value?.asnNos.join(',') }
+    showLoading()
+    getReceivingAsnDetails(params).then(res => {
+      uniqueCodeList.value=[]
+      asnDetailsList.value = res.data
+      if (res.data.length > 0) {
+        scanSuccess()
+        closeLoading()
+        if (res.data.length == 1) {
+          const item = res.data[0]
+          asnInfo.value = item
+          // searchCount.value = item.expectedQuantity - item.receivedQuantity
+          searchCount.value=1
+          _getProductAttribute(item)
+          _getProductLot(item)
+          _getCommodityRule(item)
+        }
+        if (res.data.length > 1) {
+          asnInfo.value = {}
+          lotData.value = []
+          searchCount.value = ''
+          uniqueCodeList.value = []
+          asnDetailsTrueFalseBy.value = true
+        }
+      } else {
+        scanError()
+        showNotify({ type: 'danger', duration: 3000, message: `暂未查询到条码《${code}》信息请重试` })
+        reset()
+        closeLoading()
+      }
+    }).catch(() => {
+      scanError()
+      closeLoading()
+    })
+  } else if (scanType.value == 3) {
+    if (code) {
+      const uniqueCodeScanType = uniqueCodeRef.value?.uniqueCodeScanType
+      if (checkAllType.value && uniqueCodeScanType === 'barcode') {
+        const barcode = Array.from(new Set([asnInfo.value.barcode, asnInfo.value.barcode2, asnInfo.value.sku].filter(Boolean)));
+        if (barcode.some(item => barcodeToUpperCase(item) === barcodeToUpperCase(code))) {
+          scanSuccess();
+          uniqueCodeRef.value.uniqueCodeScanType = 'unique'
+          uniqueCodeRef.value.uniqueBarcode = code
+          return;
+        } else {
+          showNotify({ type: 'danger', duration: 3000, message: `${code}-商品条码不匹配,请重新扫描` })
+          uniqueCodeRef.value.uniqueBarcode = ''
+          scanError();
+          return;
+        }
+      }
+      // 如果是通过唯一码扫描,并且没有扫描条码
+      if (uniqueCodeScanType === 'unique' && ( uniqueCodeRef.value.uniqueBarcode == '' && checkAllType.value)) {
+        showNotify({ type: 'danger', duration: 3000, message: '请先扫描商品条码' });
+        uniqueCodeRef.value.uniqueCodeScanType = 'barcode';
+        scanError();
+        return;
+      }
+      const uniqueRegExp = uniqueRuleMap.value['sku'] ? uniqueRuleMap.value['sku'] : uniqueRuleMap.value['all']
+      const isValidCode = new RegExp(uniqueRegExp).test(code)
+      if (!isValidCode) {
+        scanError()
+        showNotify({ type: 'danger', duration: 3000, message: `唯一码《${code}》不符合规则、请重新扫描` })
+        return
+      }
+      if (uniqueCodeList.value.includes(code)) {
+        scanError()
+        showNotify({ type: 'danger', duration: 3000, message: `唯一码《${code}》已存在列表内请重新扫描` })
+        return
+      }
+      scanSuccess()
+      uniqueCodeList.value.unshift(code)
+      uniqueCodeRef.value.uniqueBarcode=''
+      if(checkAllType.value){
+        uniqueCodeRef.value.uniqueCodeScanType='barcode'
+      }else {
+        uniqueCodeRef.value.uniqueCodeScanType='unique'
+      }
+
+    }
+  }else if(scanType.value==5){
+    containerNo.value=code
+    scanType.value=2
+  }
+}
+/**
+ * 物理属性
+ */
+const attributeRef = ref(null)
+const attributeMap = ref({})
+const attributeTrueFalseBy = ref(true)
+// 获取商品物理属性
+const _getProductAttribute = (item) => {
+  const params = { warehouse: item.warehouse, owner: item.customerId, barcode: item.sku }
+  getProductAttribute(params).then(res => {
+    attributeMap.value = res.data
+    const isAttributeInfo = isAttribute(res.data)
+    if (isAttributeInfo.length > 0) {
+      attributeTrueFalseBy.value = false
+      attributeRef.value?.show(isAttributeInfo, res.data)
+    } else {
+      attributeTrueFalseBy.value = true
+    }
+  })
+}
+// 设置商品物理属性
+const setAttribute = (data) => {
+  const params = { warehouse, owner: taskInfo.value.customerId, sku: attributeMap.value.sku }
+  showLoading()
+  setProductAttribute(params, { ...attributeMap.value, ...data }).then(res => {
+    showToast({ duration: 3000, message: '商品物理属性设置成功' })
+    attributeTrueFalseBy.value = true
+    scanSuccess()
+  }).catch(err => {
+    closeLoading()
+    scanError()
+  })
+}
+/**
+ * 物理属性 end
+ */
+
+/**
+ * 商品批次属性
+ */
+// 获取商品批次属性
+const lotData = ref([])
+const _getProductLot = (item) => {
+  const params = { warehouse: item.warehouse, owner: item.customerId, barcode: item.sku }
+  getProductLot(params).then(res => {
+    res.data.forEach((lot) => {
+      const lotField = lot.field
+      if (lotField.startsWith('lotAtt') && lotField.length === 8) {
+        lot.mapping = item[lotField]
+      }
+    })
+    lotData.value = res.data
+    _calculateShelfLife(item, lotData.value)
+  })
+}
+// 计算效期
+const _calculateShelfLife = (item, lotData) => {
+  if ((item.lotAtt01 && item.lotAtt02) || (!item.lotAtt01 && !item.lotAtt02)) return
+  const params = {
+    customer: item.customerId,
+    barcode: item.sku,
+    date: item.lotAtt01 || item.lotAtt02,
+    isExpiryDate: item.lotAtt01 ? true : false,
+  }
+  calculateShelfLife(params).then(date => {
+    lotData.forEach((lot) => {
+      if ((lot.field === 'lotAtt01' && !params.isExpiryDate) ||
+        (lot.field === 'lotAtt02' && params.isExpiryDate)) {
+        lot.mapping = date.data
+      }
+    })
+  })
+}
+//日期选择
+const lotField = ref('')
+const lotDateRef = ref(null)
+const onLot = (item) => {
+  lotField.value = item.field
+  if (item.field == 'lotAtt05' || item.field == 'lotAtt08') return
+  if (item.type == 'Date') {
+    lotDateRef.value?.show(item.label, item.mapping)
+    return
+  }
+  if (item.type == 'String') {
+    inputBarcodeType.value = 'lot'
+    back.value = false
+    inputBarcodeRef.value?.show('', `请扫描${item.label}`,'')
+    return
+  }
+}
+
+
+// 设置日期
+const selectLotDate = (date) => {
+  const lotMap = toMap(lotData.value, 'field', 'mapping')
+  if ((lotField.value === 'lotAtt01' || lotField.value === 'lotAtt02') &&
+    lotMap['lotAtt01'] == '' || lotMap['lotAtt01'] == null && lotMap['lotAtt02'] == '' || lotMap['lotAtt02'] == null) {
+    const params = {
+      customer: asnInfo.value.customerId,
+      barcode: asnInfo.value.sku,
+      date,
+      isExpiryDate: lotField.value === 'lotAtt01' ? true : false,
+    }
+    calculateShelfLife(params).then(res => {
+      if(res.data){
+        lotData.value.forEach((lot) => {
+          if (lot.field === 'lotAtt01') {
+            lot.mapping = (lotField.value === 'lotAtt01') ? date : res.data
+          } else if (lot.field === 'lotAtt02') {
+            lot.mapping = (lotField.value === 'lotAtt02') ? date : res.data
+          }
+        })
+      }else {
+        lotData.value.forEach((lot) => {
+          if (lot.field === lotField.value) {
+            lot.mapping = date
+          }
+        })
+      }
+
+    })
+  }
+  lotData.value.forEach((lot) => {
+    if (lot.field === lotField.value) {
+      lot.mapping = date
+    }
+  })
+  inputBarcodeType.value = 'task'
+}
+
+/**
+ * 商品批次属性end
+ */
+/**
+ * 唯一码
+ */
+const uniqueCodeRef = ref(null)
+//规则列表
+const uniqueRuleList = ref([])
+const uniqueRuleMap = ref({})
+// 获取商品规则
+const _getCommodityRule = (item) => {
+  const params = { customer: item.customerId, sku: item.sku, input: 'RECEIVING' }
+  getCommodityRule(params).then(res => {
+    uniqueRuleList.value = res.data
+    res.data.forEach((item, index) => {
+      if (item.sku == '') {
+        item.type = 'all'
+      } else {
+        item.type = 'sku'
+      }
+    })
+    uniqueRuleMap.value = toMap(res.data, 'type', 'uniqueRegExp')
+  })
+}
+/**
+ * 唯一码end
+ */
+const containerNoRef = ref(null)
+const numberRef = ref(null)
+// 完成收货
+const onConfirm = () => {
+
+  if (!asnInfo.value.asnNo) {
+    scanError()
+    showToast({ duration: 3000, message: '请先查询商品收货信息' })
+    return
+  }
+  //商品物理属性判断
+  if (!attributeTrueFalseBy.value) {
+    const isAttributeInfo = isAttribute(attributeMap.value)
+    if (isAttributeInfo.length > 0) {
+      attributeTrueFalseBy.value = false
+      attributeRef.value?.show(isAttributeInfo, attributeMap.value)
+    }
+    return
+  }
+  // //商品批次属性判断
+  const incompleteLot = lotData.value.find(lot => lot.require && !lot.mapping)
+  if (incompleteLot) {
+    scanError()
+    showToast({ duration: 3000, message: `请先补充${incompleteLot.label}` })
+    return
+  }
+  const lotMap = toMap(lotData.value, 'field', 'mapping')
+  const productionDate = lotMap['lotAtt01'] ? new Date(lotMap['lotAtt01']) : null
+  const expirationDate = lotMap['lotAtt02'] ? new Date(lotMap['lotAtt02']) : null
+  const currentDate = new Date()
+// 如果存在失效日期
+  if (expirationDate) {
+    // 如果有生产日期,进行有效性检查
+    if (productionDate && expirationDate <= productionDate) {
+      scanError()
+      showToast({ duration: 3000, message: `失效日期不能小于等于生产日期` })
+      return
+    }
+    // 检查失效日期是否小于当前日期
+    if (expirationDate <= currentDate) {
+      scanError()
+      showToast({ duration: 3000, message: `失效日期不能小于等于当前日期` })
+      return
+    }
+  }
+  if(productionDate){
+    // 如果有生产日期,进行有效性检查
+    if (expirationDate && productionDate >= expirationDate) {
+      scanError()
+      showToast({ duration: 3000, message: `生产日期不能大于失效日期` })
+      return
+    }
+    // 检查生产日期是否小于当前日期
+    if (productionDate >= currentDate) {
+      scanError()
+      showToast({ duration: 3000, message: `生产日期不能大于等于当前日期` })
+      return
+    }
+  }
+  if (searchCount.value == '') {
+    numberRef.value?.focus()
+    scanError()
+    showToast({ duration: 3000, message: '请先输入收货数量' })
+    return
+  }
+  if (containerNo.value == '') {
+    scanError()
+    containerNoRef.value?.focus()
+    showToast({ duration: 3000, message: '请先输入容器号' })
+    return
+  }
+  // 唯一码收集
+  if (uniqueRuleList.value.length > 0) {
+    if (uniqueCodeList.value.length != searchCount.value) {
+      scanType.value = 3
+      uniqueCodeRef.value?.show('', '请扫描唯一码', `收货数量:${searchCount.value}`, uniqueRuleMap.value)
+      return
+    }
+  }
+  receiving()
+}
+// 收货
+const receiving = () => {
+  const lotMap = toMap(lotData.value, 'field', 'mapping')
+  const { asnLineNo, asnNo, warehouse } = asnInfo.value
+  const data = {
+    asnLineNo,
+    asnNo,
+    containerId: containerNo.value,
+    quantity: searchCount.value,
+    warehouse,
+    serialNos: uniqueCodeList.value.length > 0 ? uniqueCodeList.value : undefined,
+    ...lotMap,
+  }
+  showLoading()
+  inputBarcodeType.value='task'
+  setReceiving(data).then(res => {
+    scanSuccess()
+    showNotify({ type: 'success', duration: 3000, message: `${searchBarcode.value}收货完成,请继续收货!`})
+    setBarcode(taskNo.value, '2')
+    closeLoading()
+  }).catch(err => {
+    if(err.message.includes('序列号已存在')){
+      scanType.value = 3
+      uniqueCodeRef.value?.show('', '请扫描唯一码', `收货数量:${searchCount.value},${err.message}`, uniqueRuleMap.value)
+    }
+    scanError()
+    closeLoading()
+  })
+}
+
+// 数据刷新
+const loadData = () => {
+  if (!taskNo.value) {
+    inputBarcodeRef.value?.show('', '请扫描开单任务号','')
+    return
+  } else {
+    // currentTime.value=getCurrentTime()
+    // startTimer()
+  }
+}
+onUnmounted(() => {
+  closeListener()
+  stopTimer()
+})
+window.onRefresh = loadData
+
+</script>
+<style scoped lang="sass">
+.take-delivery
+  .take-info
+    padding: 6px 10px
+    background: linear-gradient(160deg, #cfe1ff 20%, white 50%, white 100%)
+    display: flex
+    flex-direction: column
+    text-align: left
+
+    .take-info-no
+      flex: 1
+
+      .info-no-title
+        font-size: 19px
+        font-width: 500
+        display: flex
+        justify-content: space-between
+        align-items: center
+
+      .info-no-tips
+        font-size: 14px
+        color: #666666
+        display: flex
+        justify-content: space-between
+        padding: 6px 0
+
+    .take-info-number
+      flex: 1
+      border-top: 1.5px solid #efefef
+      display: flex
+      justify-content: space-between
+      gap: 10px
+      color: #666
+      font-size: 14px
+      padding-top: 10px
+
+      .info-number-left
+        flex: 1
+        display: flex
+        justify-content: space-evenly
+        align-items: center
+
+        .number-left-box
+          flex: 1
+          display: flex
+          flex-direction: column
+          align-items: center
+
+          .left-box-title
+            font-size: 14px
+            font-weight: bold
+            color: #000
+            line-height: 34px
+
+      .info-number-right
+        width: 40%
+        text-align: center
+
+        .van-search
+          padding: 0
+
+  .take-barcode
+    margin-top: 10px
+    text-align: left
+    background: #FFFFFF
+
+    .barcode-input
+      ::v-deep(.van-search)
+        padding: 0
+
+      ::v-deep(.van-search__field)
+        border-bottom: 2px solid #ffffff
+
+      ::v-deep(.van-search__content)
+        background: #fff
+
+      ::v-deep(.van-field__control)
+        font-size: 15px
+        font-weight: bold
+
+      ::v-deep(.van-search__label)
+        font-size: 15px
+        font-weight: bold
+
+      .search-input-barcode
+        ::v-deep(.van-search__field)
+          border-bottom: 2px solid #0077ff
+          z-index: 2
+
+  .take-lot
+    text-align: left
+    margin-top: 5px
+
+    ::v-deep(.van-cell)
+      padding: 5px 8px
+
+    .take-lot-title
+      font-size: 15px
+      font-weight: bold
+      padding: 0 5px
+      border-left: 3px solid #1989fa
+      color: #333
+      margin-bottom: 3px
+
+
+  .take-button
+    padding: 20px
+
+
+</style>

+ 1 - 0
src/views/index.vue

@@ -7,6 +7,7 @@
     <div class="home" @click="onRouter('blind-receiving')">进入盲扫</div>
     <div class="home" @click="onRouter('check-move-stock')">进入反拣还库</div>
     <div class="home" @click="onRouter('piece-dashboard')">进入计件面板</div>
+    <div class="home" @click="onRouter('take-delivery')">进入收货</div>
   </div>
 </template>
 <script setup>

+ 2 - 6
src/views/outbound/picking/components/InputBarcode.vue

@@ -21,14 +21,14 @@ import { showToast } from 'vant'
   const store = useStore()
   const warehouse = store.warehouse
   import { useStore } from '@/store/modules/user'
-import { goBack } from '@/utils/android'
+  import { goBack } from '@/utils/android'
   const barcodeTrueFalseBy=ref(false)
   const barcodeRef=ref(null)
   const barcode=ref('');
   const title=ref('请扫描条码')
   const props=defineProps(['back'])
   const tag=ref('')
-const show = async (code,desc,tips) => {
+  const show = async (code,desc,tips) => {
     if(desc!==undefined){
       title.value=desc
     }
@@ -112,8 +112,4 @@ const show = async (code,desc,tips) => {
     color: #ff4141
     line-height: 20px
 
-
-
-
-
 </style>