/** * 功能说明:定义扫码明细的最小结构,统一扫码页里的重复合并计算输入。 * 适用场景:扫码其它入库、扫码其它出库的条码累计逻辑。 */ export interface ScanItem { warehouseId: number productId: number count: number orderItemId?: number batchNo?: string locationCode?: string } /** * 功能说明:清洗扫码枪输入的条码文本,去掉回车、换行和前后空白。 * 适用场景:扫码枪通过键盘模拟输入后,页面提交前统一清洗条码值。 * @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 { const segments = [String(item.warehouseId), String(item.productId)] // 订单约束扫码时需要把订单明细编号带入合并键,避免不同订单行误合并。 if (withOrderConstraint) { segments.push(String(item.orderItemId || 0)) segments.push(item.batchNo || '') segments.push(item.locationCode || '') } 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), } }) }