|
|
|
@ -715,45 +715,48 @@ public class ReportLabelListServiceImpl extends ServiceImpl<ReportLabelListMappe |
|
|
|
customerId: "CUST123",// customerId是可选的,如果传了,系统会优先根据customerId解析标签编号 |
|
|
|
addressNo: "ADDR001", // addressNo是可选的,传了会优先按customerId+addressNo精确匹配 |
|
|
|
"customFields": { |
|
|
|
"QTY": 120, |
|
|
|
"QTY": ["100","200","300"], |
|
|
|
"grossWeight": 15.6, |
|
|
|
"netWeight": 14.9 |
|
|
|
} |
|
|
|
}*/ |
|
|
|
// 则系统会替换customFields里的qty字段到ZPL代码里对应的位置 |
|
|
|
Map<String, Object> customFields = printRequest.getCustomFields(); |
|
|
|
if (customFields != null && !customFields.isEmpty()) { |
|
|
|
queryParams.put("customFields", customFields); |
|
|
|
} |
|
|
|
// 可以根据需要添加更多参数 |
|
|
|
// 2. 生成外箱标签:带真实数据的ZPL代码和对应数据 |
|
|
|
List<String> zplCodeList = previewLabelWithRealData(outerLabelSetting.getLabelNo(), true, queryParams); |
|
|
|
// 同时获取原始数据用于保存WMS标签记录 |
|
|
|
List<Map<String, Object>> labelDataList = getLabelDataForPrint(outerLabelSetting.getLabelNo(), queryParams); |
|
|
|
// 3. 验证ZPL代码 |
|
|
|
if (zplCodeList == null || zplCodeList.isEmpty()) { |
|
|
|
throw new RuntimeException("ZPL代码获取失败"); |
|
|
|
} |
|
|
|
log.info("生成了 {} 个外箱标签ZPL代码,准备打印", zplCodeList.size()); |
|
|
|
List<String> outerQtyList = extractRequiredOuterQtyList(customFields); |
|
|
|
|
|
|
|
// 4. 获取外箱标签打印机配置 |
|
|
|
// 2. 获取外箱标签打印机配置 |
|
|
|
UserLabelPrinterData outerPrinter = getRequiredLabelPrinter(printRequest.getUserId(), outerLabelSetting.getLabelNo()); |
|
|
|
|
|
|
|
// 5. 将外箱打印任务加入队列(不直接打印) |
|
|
|
int totalLabels = zplCodeList.size(); |
|
|
|
// 3. 按QTY数组逐项生成外箱任务(复用同一个queryParams,确保IFS数据只查询一次) |
|
|
|
List<Long> taskIds = new ArrayList<>(); |
|
|
|
for (int i = 0; i < totalLabels; i++) { |
|
|
|
String zplCode = zplCodeList.get(i); |
|
|
|
Map<String, Object> labelData = i < labelDataList.size() ? labelDataList.get(i) : new HashMap<>(); |
|
|
|
Long taskId = enqueueSingleTask(outerPrinter.getIpAddress(), zplCode, outerRfidFlag, labelData, printRequest); |
|
|
|
taskIds.add(taskId); |
|
|
|
log.info("打印任务已加入队列 {} / {}, taskId={}", i + 1, totalLabels, taskId); |
|
|
|
int outerBatchIndex = 1; |
|
|
|
for (String outerQty : outerQtyList) { |
|
|
|
Map<String, Object> outerCustomFields = buildOuterCustomFields(customFields, outerQty); |
|
|
|
queryParams.put("customFields", outerCustomFields); |
|
|
|
|
|
|
|
// 生成当前QTY对应的外箱标签(同一queryParams会复用IFS缓存) |
|
|
|
List<String> zplCodeList = previewLabelWithRealData(outerLabelSetting.getLabelNo(), true, queryParams); |
|
|
|
List<Map<String, Object>> labelDataList = getLabelDataForPrint(outerLabelSetting.getLabelNo(), queryParams); |
|
|
|
if (zplCodeList == null || zplCodeList.isEmpty()) { |
|
|
|
throw new RuntimeException("外箱标签ZPL代码获取失败,qty=" + outerQty); |
|
|
|
} |
|
|
|
|
|
|
|
int totalLabels = zplCodeList.size(); |
|
|
|
for (int i = 0; i < totalLabels; i++) { |
|
|
|
String zplCode = zplCodeList.get(i); |
|
|
|
Map<String, Object> labelData = i < labelDataList.size() ? labelDataList.get(i) : new HashMap<>(); |
|
|
|
Long taskId = enqueueSingleTask(outerPrinter.getIpAddress(), zplCode, outerRfidFlag, labelData, printRequest); |
|
|
|
taskIds.add(taskId); |
|
|
|
log.info("外箱标签任务已加入队列,batch={} / {}, index={} / {}, qty={}, taskId={}", |
|
|
|
outerBatchIndex, outerQtyList.size(), i + 1, totalLabels, outerQty, taskId); |
|
|
|
} |
|
|
|
outerBatchIndex++; |
|
|
|
} |
|
|
|
|
|
|
|
// 6. customerId + innerBox 场景:在外箱任务后自动补打对应内箱子标签 |
|
|
|
// 4. 外箱全部完成后仅补打一套内箱(若存在内箱配置) |
|
|
|
enqueueInnerBoxTasksIfNeeded(printRequest, resolvedReportId, queryParams, outerPrinter, taskIds); |
|
|
|
|
|
|
|
// 7. 记录日志 |
|
|
|
// 5. 记录日志 |
|
|
|
log.info("✓ 所有打印任务已加入队列,共 {} 个任务,任务ID: {}", taskIds.size(), taskIds); |
|
|
|
} catch (Exception e) { |
|
|
|
System.err.println("RFID标签打印失败: " + e.getMessage()); |
|
|
|
@ -850,13 +853,16 @@ public class ReportLabelListServiceImpl extends ServiceImpl<ReportLabelListMappe |
|
|
|
|
|
|
|
String innerLabelNo = resolveInnerLabelByCustomer(printRequest, outerLabelNo); |
|
|
|
if (StringUtils.isBlank(innerLabelNo)) { |
|
|
|
throw new RuntimeException("未找到外箱标签对应的内箱标签配置,outerLabelNo=" + outerLabelNo); |
|
|
|
// 内箱配置为可选,未配置时仅打印外箱,不中断主流程 |
|
|
|
log.info("外箱标签未维护内箱子标签映射,跳过内箱补打。outerLabelNo={}", outerLabelNo); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
LabelSettingData innerLabelSetting = getRequiredLabelSetting(innerLabelNo, null); |
|
|
|
UserLabelPrinterData innerPrinter = resolveInnerPrinter(printRequest.getUserId(), innerLabelNo, outerPrinter); |
|
|
|
|
|
|
|
Map<String, Object> innerQueryParams = new HashMap<>(baseQueryParams); |
|
|
|
// 复用同一个queryParams,确保IFS缓存可跨外箱/内箱复用,避免重复调用getIfsDataFromApi |
|
|
|
Map<String, Object> innerQueryParams = baseQueryParams; |
|
|
|
int innerIndex = 1; |
|
|
|
for (String innerQty : innerBoxList) { |
|
|
|
if (StringUtils.isBlank(innerQty)) { |
|
|
|
@ -924,6 +930,57 @@ public class ReportLabelListServiceImpl extends ServiceImpl<ReportLabelListMappe |
|
|
|
return innerCustomFields; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 构建外箱标签 customFields:保留原字段并覆盖 qty |
|
|
|
*/ |
|
|
|
private Map<String, Object> buildOuterCustomFields(Map<String, Object> sourceCustomFields, String outerQty) { |
|
|
|
Map<String, Object> outerCustomFields = new HashMap<>(); |
|
|
|
if (sourceCustomFields != null && !sourceCustomFields.isEmpty()) { |
|
|
|
outerCustomFields.putAll(sourceCustomFields); |
|
|
|
} |
|
|
|
boolean qtyUpdated = false; |
|
|
|
for (String key : new ArrayList<>(outerCustomFields.keySet())) { |
|
|
|
if (StringUtils.equalsIgnoreCase(StringUtils.trimToEmpty(key), "qty")) { |
|
|
|
outerCustomFields.put(key, outerQty); |
|
|
|
qtyUpdated = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!qtyUpdated) { |
|
|
|
outerCustomFields.put("qty", outerQty); |
|
|
|
} |
|
|
|
return outerCustomFields; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 提取外箱QTY数组(仅支持数组,不兼容单值) |
|
|
|
*/ |
|
|
|
private List<String> extractRequiredOuterQtyList(Map<String, Object> customFields) { |
|
|
|
if (customFields == null || customFields.isEmpty()) { |
|
|
|
throw new RuntimeException("外箱标签打印必须传入customFields.QTY数组"); |
|
|
|
} |
|
|
|
Object qtyValue = null; |
|
|
|
for (Map.Entry<String, Object> entry : customFields.entrySet()) { |
|
|
|
if (StringUtils.equalsIgnoreCase(StringUtils.trimToEmpty(entry.getKey()), "qty")) { |
|
|
|
qtyValue = entry.getValue(); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!(qtyValue instanceof List<?> qtyList) || qtyList.isEmpty()) { |
|
|
|
throw new RuntimeException("customFields.QTY必须为非空数组,例如 [\"100\",\"200\",\"300\"]"); |
|
|
|
} |
|
|
|
List<String> outerQtyList = new ArrayList<>(); |
|
|
|
int qtyIndex = 1; |
|
|
|
for (Object qtyObj : qtyList) { |
|
|
|
String qty = qtyObj == null ? "" : qtyObj.toString().trim(); |
|
|
|
if (StringUtils.isBlank(qty)) { |
|
|
|
throw new RuntimeException("customFields.QTY第" + qtyIndex + "项不能为空"); |
|
|
|
} |
|
|
|
outerQtyList.add(qty); |
|
|
|
qtyIndex++; |
|
|
|
} |
|
|
|
return outerQtyList; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 根据外箱标签解析对应内箱标签 |
|
|
|
*/ |
|
|
|
|