|
|
|
|
@ -111,11 +111,20 @@
|
|
|
|
|
<text class="form-label">{{ t('productInbound.palletCode') }}<text class="required-star">*</text></text>
|
|
|
|
|
<text v-if="selectedPallets.length" class="label-tip">{{ t('productInbound.selectedPalletCount', { count: selectedPallets.length }) }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view :class="['select-field', selectedPallets.length ? 'selected' : '']" @click="goSelectPallet" >
|
|
|
|
|
<view class="select-content">
|
|
|
|
|
<text :class="selectedPallets.length ? 'select-value' : 'select-placeholder'">{{ palletCode || t('productInbound.selectPallet') }}</text>
|
|
|
|
|
<view class="task-product-search-row">
|
|
|
|
|
<input
|
|
|
|
|
id="product-inbound-pallet-scan-input"
|
|
|
|
|
v-model="palletScanInput"
|
|
|
|
|
class="task-product-scan-input"
|
|
|
|
|
type="text"
|
|
|
|
|
:placeholder="palletCode || t('productInbound.selectPallet')"
|
|
|
|
|
confirm-type="done"
|
|
|
|
|
@input="onPalletScanInput"
|
|
|
|
|
@confirm="onPalletScanConfirm"
|
|
|
|
|
/>
|
|
|
|
|
<view class="task-product-select-field" @click="goSelectPallet">
|
|
|
|
|
<text class="task-product-select-text">{{ t('productInbound.selectPalletTitle') }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
<uni-icons type="right" size="18" color="#9ca3af"></uni-icons>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
@ -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
|
|
|
|
|
|