2026-05-13 19:48:21 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 功能说明:定义扫码明细的最小结构,统一扫码页里的重复合并计算输入。
|
|
|
|
|
|
* 适用场景:扫码其它入库、扫码其它出库的条码累计逻辑。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ScanItem {
|
|
|
|
|
|
warehouseId: number
|
|
|
|
|
|
productId: number
|
|
|
|
|
|
count: number
|
|
|
|
|
|
orderItemId?: number
|
2026-05-14 16:48:09 +08:00
|
|
|
|
batchNo?: string
|
|
|
|
|
|
locationCode?: string
|
2026-05-13 19:48:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 功能说明:清洗扫码枪输入的条码文本,去掉回车、换行和前后空白。
|
|
|
|
|
|
* 适用场景:扫码枪通过键盘模拟输入后,页面提交前统一清洗条码值。
|
|
|
|
|
|
* @param raw 原始扫码内容
|
|
|
|
|
|
* @return 清洗后的条码字符串
|
|
|
|
|
|
* 注意事项:扫码枪通常会追加回车,不先清洗会导致条码查产品接口无法命中。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function normalizeScanCode(raw: string): string {
|
|
|
|
|
|
return (raw || '').replace(/[\r\n]/g, '').trim()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 功能说明:把相机扫码结果统一转换成业务可用条码。
|
|
|
|
|
|
* 适用场景:`uni.scanCode` 返回对象后,与扫码枪输入共用同一套处理流程。
|
|
|
|
|
|
* @param result uni-app 扫码返回结果
|
|
|
|
|
|
* @return 清洗后的条码字符串
|
|
|
|
|
|
* 注意事项:扫码取消、空返回或结构变化时,需要安全降级为空字符串,避免页面直接抛错。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function normalizeCameraScanResult(result?: { result?: string } | null): string {
|
|
|
|
|
|
return normalizeScanCode(result?.result || '')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 功能说明:生成扫码明细的合并键,决定重复扫码时应该累加到哪一行。
|
|
|
|
|
|
* 适用场景:自由扫码模式按“仓库 + 产品”合并,订单约束模式再附加订单行编号。
|
|
|
|
|
|
* @param item 当前明细
|
|
|
|
|
|
* @param withOrderConstraint 是否启用订单约束模式
|
|
|
|
|
|
* @return 合并键字符串
|
|
|
|
|
|
* 注意事项:订单约束场景若不带订单行编号,会把不同订单行的同一产品错误合并。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function buildScanMergeKey(item: ScanItem, withOrderConstraint = false): string {
|
2026-05-14 16:48:09 +08:00
|
|
|
|
const segments = [String(item.warehouseId), String(item.productId)]
|
2026-05-13 19:48:21 +08:00
|
|
|
|
|
|
|
|
|
|
// 订单约束扫码时需要把订单明细编号带入合并键,避免不同订单行误合并。
|
|
|
|
|
|
if (withOrderConstraint) {
|
2026-05-14 16:48:09 +08:00
|
|
|
|
segments.push(String(item.orderItemId || 0))
|
|
|
|
|
|
segments.push(item.batchNo || '')
|
|
|
|
|
|
segments.push(item.locationCode || '')
|
2026-05-13 19:48:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return segments.join(':')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 功能说明:将一次新的扫码结果合并到现有明细列表中。
|
|
|
|
|
|
* 适用场景:连续扫到同一产品时自动累计数量,减少仓库人员手工修改次数。
|
|
|
|
|
|
* @param items 当前明细列表
|
|
|
|
|
|
* @param scannedItem 新扫码得到的明细
|
|
|
|
|
|
* @param withOrderConstraint 是否启用订单约束模式
|
|
|
|
|
|
* @return 合并后的新明细列表
|
|
|
|
|
|
* 注意事项:这里返回新数组而不是原地修改,避免页面状态更新不稳定。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function mergeScannedItem(
|
|
|
|
|
|
items: ScanItem[],
|
|
|
|
|
|
scannedItem: ScanItem,
|
|
|
|
|
|
withOrderConstraint = false,
|
|
|
|
|
|
): ScanItem[] {
|
|
|
|
|
|
const targetKey = buildScanMergeKey(scannedItem, withOrderConstraint)
|
|
|
|
|
|
const existedIndex = items.findIndex(item => buildScanMergeKey(item, withOrderConstraint) === targetKey)
|
|
|
|
|
|
|
|
|
|
|
|
if (existedIndex === -1) {
|
|
|
|
|
|
return [...items, scannedItem]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return items.map((item, index) => {
|
|
|
|
|
|
if (index !== existedIndex) {
|
|
|
|
|
|
return item
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 命中同一合并键时只累计数量,避免把已录入明细拆成多行,影响 PDA 连续扫码效率。
|
|
|
|
|
|
return {
|
|
|
|
|
|
...item,
|
|
|
|
|
|
count: Number(item.count || 0) + Number(scannedItem.count || 0),
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|