diff --git a/src/api/mes/productInbound.js b/src/api/mes/productInbound.js index c20ffbe..190ff33 100644 --- a/src/api/mes/productInbound.js +++ b/src/api/mes/productInbound.js @@ -64,6 +64,14 @@ export function getPalletPage(params = {}) { }) } +export function getPallet(id) { + return request({ + url: '/admin-api/erp/pallet/get', + method: 'get', + params: { id } + }) +} + export function createPallet(data) { return request({ url: '/admin-api/erp/pallet/create', diff --git a/src/pages_function/pages/productInbound/productConfirm.vue b/src/pages_function/pages/productInbound/productConfirm.vue index 5019eaa..51bb2be 100644 --- a/src/pages_function/pages/productInbound/productConfirm.vue +++ b/src/pages_function/pages/productInbound/productConfirm.vue @@ -111,11 +111,20 @@ {{ t('productInbound.palletCode') }}* {{ t('productInbound.selectedPalletCount', { count: selectedPallets.length }) }} - - - {{ palletCode || t('productInbound.selectPallet') }} + + + + {{ t('productInbound.selectPalletTitle') }} - @@ -188,8 +197,8 @@ import { computed, ref } from 'vue' import { onLoad, onShow } from '@dcloudio/uni-app' import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' -import { getTaskDefaultPackagingSchemes } from '@/api/mes/productInbound' -import { getProduct, getProductPage } from '@/api/erp/productInfo' +import { getPallet, getTaskDefaultPackagingSchemes } from '@/api/mes/productInbound' +import { getProduct } from '@/api/erp/productInfo' import { getWarehouseAreaSimpleList, getWarehouseSimpleList } from '@/api/mes/moldget' const { t } = useI18n() @@ -203,16 +212,17 @@ const selectedPallets = ref([]) const editingIndex = ref(null) const taskProductScanInput = ref('') const productScanInput = ref('') +const palletScanInput = ref('') const warehouseOptions = ref([]) const warehouseAreaMap = ref({}) const taskProductList = ref([]) const PRODUCT_CATEGORY_TYPE = 1 -const PRODUCT_PAGE_SIZE = 10 const SCAN_AUTO_SEARCH_DELAY = 300 let taskProductScanTimer = null let productScanTimer = null +let palletScanTimer = null const productName = computed(() => selectedTaskProduct.value?.productName || product.value.name || '') const productId = computed(() => selectedTaskProduct.value?.productId || product.value.id) @@ -364,6 +374,7 @@ function setRelateTask(value) { selectedTaskProduct.value = null taskProductScanInput.value = '' productScanInput.value = '' + palletScanInput.value = '' taskId.value = null taskCode.value = '' selectedTaskData.value = null @@ -393,6 +404,11 @@ function getProductMaterialScanCode(value) { const match = text.match(/^PRODUCTMATERIAL[-:]?\s*(.+)$/i) return match ? match[1].trim() : '' } +function getPalletScanCode(value) { + const text = String(value || '').trim() + const match = text.match(/^PALLET[-:]?\s*(.+)$/i) + return match ? match[1].trim() : '' +} function getProductIdValue(item) { return item?.id || item?.productId } @@ -413,49 +429,14 @@ function getTaskProductScanValues(item) { item?.name ].map(normalizeScanValue).filter(Boolean) } -function normalizeProductPageList(res) { - const root = res && res.data !== undefined ? res.data : res - return Array.isArray(root) ? root : (root?.list || root?.rows || root?.records || []) -} -function pickMatchedProduct(list, keyword) { - const normalized = normalizeScanValue(keyword) - return list.find((item) => { - const values = [getProductIdValue(item), getProductCodeValue(item), getProductNameValue(item)].map(normalizeScanValue).filter(Boolean) - return values.includes(normalized) - }) || list[0] -} -async function getProductDetailOrSelf(item) { - const id = getProductIdValue(item) - if (!id) return item - try { - const res = await getProduct(id) - return { ...item, ...(res?.data || res || {}) } - } catch (e) { - return item - } -} async function findProductByScanCode(scanCode) { - const keyword = String(scanCode || '').trim() - if (!keyword) return null - const codeRes = await getProductPage({ pageNo: 1, pageSize: PRODUCT_PAGE_SIZE, categoryType: PRODUCT_CATEGORY_TYPE, barCode: keyword }) - const codeList = normalizeProductPageList(codeRes) - let matched = pickMatchedProduct(codeList, keyword) - - if (!matched) { - const nameRes = await getProductPage({ pageNo: 1, pageSize: PRODUCT_PAGE_SIZE, categoryType: PRODUCT_CATEGORY_TYPE, name: keyword }) - const nameList = normalizeProductPageList(nameRes) - matched = pickMatchedProduct(nameList, keyword) - } - - if (!matched && /^\d+$/.test(keyword)) { - try { - const res = await getProduct(keyword) - const detail = res?.data || res - if (detail?.id && (!detail.categoryType || Number(detail.categoryType) === PRODUCT_CATEGORY_TYPE)) matched = detail - } catch (e) {} - } - - return matched ? getProductDetailOrSelf(matched) : null + const id = String(scanCode || '').trim() + if (!/^\d+$/.test(id)) return null + const res = await getProduct(id) + const detail = res?.data || res + if (!detail?.id) return null + if (detail.categoryType && Number(detail.categoryType) !== PRODUCT_CATEGORY_TYPE) return null + return detail } function getTaskProductByProduct(productItem) { const productValues = [getProductIdValue(productItem), getProductCodeValue(productItem), getProductNameValue(productItem)].map(normalizeScanValue).filter(Boolean) @@ -518,6 +499,7 @@ async function onTaskProductScanConfirm() { } selectedTaskProduct.value = buildTaskProductSelection(matched) selectedPallets.value = [] + palletScanInput.value = '' taskProductScanInput.value = '' } catch (e) { uni.hideLoading() @@ -542,12 +524,70 @@ async function onProductScanConfirm() { product.value = matched selectedTaskProduct.value = null selectedPallets.value = [] + palletScanInput.value = '' productScanInput.value = '' } catch (e) { uni.hideLoading() uni.showToast({ title: t('productInbound.loadFailed'), icon: 'none' }) } } +function schedulePalletScanSearch(value) { + if (!getPalletScanCode(value)) return + if (palletScanTimer) clearTimeout(palletScanTimer) + palletScanTimer = setTimeout(() => { + palletScanTimer = null + onPalletScanConfirm() + }, SCAN_AUTO_SEARCH_DELAY) +} +function onPalletScanInput(e) { + schedulePalletScanSearch(e?.detail?.value ?? palletScanInput.value) +} + +function addScannedPallet(pallet) { + if (!pallet?.id) return + const exists = selectedPallets.value.some((item) => String(item.id) === String(pallet.id)) + if (exists) return + selectedPallets.value.push({ + ...pallet, + packageCount: pallet.productCount || pallet.packageCount || palletPackageQuantity.value || 1 + }) +} +async function findPalletByScanCode(scanCode) { + const id = String(scanCode || '').trim() + if (!/^\d+$/.test(id)) return null + const res = await getPallet(id) + const detail = res?.data || res + if (!detail?.id) return null + if (detail.productId && productId.value && String(detail.productId) !== String(productId.value)) return null + return detail +} +async function onPalletScanConfirm() { + if (palletScanTimer) { + clearTimeout(palletScanTimer) + palletScanTimer = null + } + const scanCode = getPalletScanCode(palletScanInput.value) + if (!scanCode) return + if (!productId.value) { + uni.showToast({ title: t('productInbound.selectProductFirst'), icon: 'none' }) + return + } + try { + uni.showLoading({ title: t('productInbound.loading'), mask: true }) + const matched = await findPalletByScanCode(scanCode) + uni.hideLoading() + if (!matched?.id) { + uni.showToast({ title: '\u6ca1\u6709\u8fd9\u4e2a\u6258\u76d8', icon: 'none' }) + return + } + addScannedPallet(matched) + await loadAreasForPallets([matched]) + palletScanInput.value = '' + } catch (e) { + uni.hideLoading() + uni.showToast({ title: t('productInbound.loadFailed'), icon: 'none' }) + } +} function goSelectPallet() { if (!productId.value) { uni.showToast({ title: t('productInbound.selectProductFirst'), icon: 'none' }) @@ -683,6 +723,7 @@ onShow(async () => { selectedTaskProduct.value = null taskProductScanInput.value = '' selectedPallets.value = [] + palletScanInput.value = '' gd._productInboundTaskSelectResult = null try { uni.showLoading({ title: t('productInbound.loading'), mask: true }) @@ -706,6 +747,7 @@ onShow(async () => { productScanInput.value = '' } selectedPallets.value = [] + palletScanInput.value = '' gd._productInboundProductSelectResult = null } const palletResult = gd?._productInboundPalletSelectResult