Browse Source

托盘重新移库

master
常熟吴彦祖 15 hours ago
parent
commit
c166c87282
  1. 2
      src/main/java/com/gaotao/modules/autoWareHourceHaian/HAIAN_AI_CONTEXT.md
  2. 2
      src/main/java/com/gaotao/modules/autoWareHourceHaian/entity/vo/HaiAnPallet.java
  3. 43
      src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnAutoIssueServiceImpl.java

2
src/main/java/com/gaotao/modules/autoWareHourceHaian/HAIAN_AI_CONTEXT.md

@ -107,7 +107,7 @@
- 海安同步RFID复核每次调用(首次通过、不通过、在线幂等返回及异常)都通过 `haiAnLogCompleteCall` 独立写 `haian_interface_call_log`,`interface_name=HaiAnWmsMessageService/method_name=verifyInboundPalletRfid/business_key=taskNo`。业务由事务模板完成后记录完整请求、响应(含null字段)、状态及毫秒耗时;正常复核无论通过与否均为 `SUCCESS`,业务或提交异常为 `ERROR` 并保存原错误信息,日志故障不覆盖业务结果。- rqrq
- 海安 RFID复核消费(`action_type=RFID复核`)只用明细 `site/task_no/pallet_id/comment`,不要求运输主表。`comment` 去空格后不等于 `通过`:先把明细改 `已完成` 并保留首次复核 `error_code/error_msg`,再调 `notifyOutboundPortRfidPalletAction(type=2)` 去异常位,成功后把 `haian_pallet.error_message` 写成 `Rfid校验失败 多盘标签… 少盘标签…`(多盘=门扫到但组盘没有,少盘=组盘有但门没扫到),按 VARCHAR(500) 字节截断,不改调用标记和位置;等于 `通过`:先查 `haian_pallet_detail`;无标签则明细改 `已完成` 后再调 `type=1`;有标签且 `scheduler.haianAutoTask.autoIssue.enabled=true` 时,收集全部 `reserve_flag=Y` 且 `reserve_order_ref1` 能关联 `haian_SOIssueNotifyHeader(site+notify_no)` 且 `order_type=shoporder` 的预定标签:只要有一张命中,就写自动发料任务并调用现有海安移库入队,RFID 明细改 `待自动发料`(不进 AGV 定时扫描、不调立库);开关关闭或未命中则明细改 `已完成` 后再调 `type=1`。立库接口返回仅供记录,托盘移动由定时消费后下发 `POST /api/wms/outbound/rfid-action`;WCS调用失败由明细事务回滚后重试。- rqrq
- 海安自动发料移库目标区域写死 `HaiAnAreaStaticData.AUTO_ISSUE_TRANSFER_AREA = "A99"`,实际仓库/库位按显式site+A99查询haian_area配置,缺少映射中断建单。`HaiAnPalletTransferService.doWareHouseForPalletForAuto` 回参改为实体 `HaiAnPalletTransferEnqueueResult`(`queueIds`+`message`),无需搬库时 `queueIds` 为空列表并视为 IFS 已完成;三个原调用方仍忽略回参,禁止改 `haian_ifs_pallet_move_queue` 表结构,禁止改老模块 `WmsMessageService.doWareHouseForPalletForAuto` - rqrq
- 海安自动发料定时任务只读 IFS 队列表:关联 `queueId` 存在 N/P 则继续等;全部关联队列均为Y后,任一条 `result_flag=F` 则不发料,任务与 RFID 明细都改 `已完成`,`error_code=移库失败`,覆盖写 `haian_pallet.remark` 与 RFID `error_msg`,再调立库 `type=2`。全部 `Y` 且全 `S`(或无队列)后:实时查 `handling_unit`,用 `haian_SOIssueNotifyOrderMaterialList_detail` 关联 `haian_SOIssueNotifyOrderList` 按 `site+soorder_no+release+sequence` 分组,经 `HaiAnProductionAutoIssueAdapter` 调用同事 `AutoIssueService.autoIssue`(不改同事方法,`labelCode` 空、`workOrderNo` 空、release/sequence 空填 `*`、`lineItemNo` 由 `BOM_item_no` 转 Integer 失败为 0、`issueQty=qty` 全发)。回参只有 failures,成功标签用送出清单减去失败 handlingUnitId 反推;全成功则解绑、`type=1`、不写失败码;只要有一张失败则成功的解绑、失败的不解绑、`type=2`、`error_code=发料失败`。不论成败先改本地再调立库。已 `issue_flag=S` 的标签禁止再送同事 - rqrq
- 海安自动发料定时任务只读 IFS 队列表:关联 `queueId` 存在 N/P 则继续等;全部关联队列均为Y后,任一条 `result_flag=F` 则不发料,任务与 RFID 明细都改 `已完成`,`error_code=移库失败`,覆盖写 `haian_pallet.remark`、`error_message` 与 RFID `error_msg`,再调立库 `type=2`。`error_message` 保存“移库失败:说明”或“发料失败:标签说明”,按 VARCHAR(500) 字节截断,不改调用标记和位置。全部 `Y` 且全 `S`(或无队列)后:实时查 `handling_unit`,用 `haian_SOIssueNotifyOrderMaterialList_detail` 关联 `haian_SOIssueNotifyOrderList` 按 `site+soorder_no+release+sequence` 分组,经 `HaiAnProductionAutoIssueAdapter` 调用同事 `AutoIssueService.autoIssue`(不改同事方法,`labelCode` 空、`workOrderNo` 空、release/sequence 空填 `*`、`lineItemNo` 由 `BOM_item_no` 转 Integer 失败为 0、`issueQty=qty` 全发)。回参只有 failures,成功标签用送出清单减去失败 handlingUnitId 反推;全成功则解绑、`type=1`、不写失败码;只要有一张失败则成功的解绑、失败的不解绑、`type=2`、`error_code=发料失败`。不论成败先改本地再调立库。已 `issue_flag=S` 的标签禁止再送同事 - rqrq
- 海安自动发料 PC 查看页:`wms-vue/src/views/modules/haianWarehouse/automatedWarehouse/autoIssueTask54.vue`,接口 `/autoWareHourceHaian/haiAnAutoIssueTask/getAutoIssueTaskPage|getAutoIssueTaskLabelList|getAutoIssueMoveRefList`,只读不提供重试/解绑。菜单脚本 `sql/20260918_haian_pc_auto_issue_task_menu.sql`(menu_id=690150,父级立库功能海安 690) - rqrq
- 自动发料标签新增落库快照 `order_no/release_no/sequence_no`:定时RFID建单按site+标签号+预定领料单号,经领料明细item_no关联`haian_SOIssueNotifyOrderList`取soorder_no/release_no/sequence_no;无来源留空,不同工单多匹配拒绝建单。PC申请单号后三列展示快照,移库失败也可看工单;存量升级执行`sql/20260920_haian_auto_issue_label_order_snapshot.sql`,仅补54工厂全空且唯一匹配的历史快照,不覆盖发料状态。- rqrq
- 海安 `wcsWareHouse` 回调同样采用“两段式”:第一段接口只写 `haian_wcs_callback_task(status=已录入)`;第二段由 `HaianWcsSchedule.scheduleHaianWcsTaskProcessing(2.6秒)` 乐观锁消费,并按 `入货架(原入库)/出货架(原出库)/离开入库口(原取走栈板)/到达异常位(原异常位处理)/到达出库口(原取货通知)/到达手工分拣区` 分流处理(到达出库口不再依赖transportTask分支,且不执行 `palletAutoGoToWCS.goToWCS` 回库逻辑;离开入库口释放calling_flag并把托盘落到A01+立库输送线、不改wcs_location;到达手工分拣区仅把 `haian_pallet.location_code` 改成回传点位,不改 calling_flag、不做移库) - rqrq

2
src/main/java/com/gaotao/modules/autoWareHourceHaian/entity/vo/HaiAnPallet.java

@ -105,7 +105,7 @@ public class HaiAnPallet {
private String remark;
/**
* 立库异常错误原因(error_message)。到达异常位写入回调 remark 前 200 个字符。RFID复核不通过另写“Rfid校验失败 多盘标签… 少盘标签…”,按 VARCHAR(500) 字节截断。列可空。不改 location_code。现场用本字段看这次为什么去异常位。 - rqrq
* 立库异常错误原因(error_message)。到达异常位写入回调 remark 前 200 个字符。RFID复核不通过写“Rfid校验失败 多盘标签… 少盘标签…”。自动发料移库失败或发料失败写“失败码:标签说明”。都按 VARCHAR(500) 字节截断。列可空。不改 location_code。 - rqrq
*/
@TableField("error_message")
private String errorMessage;

43
src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnAutoIssueServiceImpl.java

@ -488,11 +488,14 @@ public class HaiAnAutoIssueServiceImpl implements HaiAnAutoIssueService {
Date now = new Date();
String errorMsg = truncate(failMessage, ERROR_MSG_MAX_LENGTH);
markTaskDone(task.getId(), HaiAnAutoIssueStaticData.ERROR_TRANSFER_FAIL, errorMsg, now);
// 覆盖托盘remark,与calling共用haian_pallet.remark;失败必须留下可现场看见的原因 - rqrq
// 占用备注仍写短原因,现场看托盘调用备注;失败回滚则立库去异常位也不会发出。- rqrq
haiAnPdaAutoWarehouseMapper.updatePalletRemark(
task.getSite(), task.getPalletId(),
truncate(HaiAnAutoIssueStaticData.ERROR_TRANSFER_FAIL + ":" + nvl(errorMsg), PALLET_REMARK_MAX_LENGTH),
HaiAnOperatorStaticData.SYS_WMS);
// 错误原因另写 error_message,可保留比备注更长的移库失败说明。0 行回滚本轮收口。- rqrq
writeAutoIssuePalletError(task.getSite(), task.getPalletId(),
HaiAnAutoIssueStaticData.ERROR_TRANSFER_FAIL, errorMsg);
markRfidDetailFinished(task.getTransportDetailId(), now,
HaiAnAutoIssueStaticData.ERROR_TRANSFER_FAIL, errorMsg);
notifyOutboundRfidAction(task.getSite(), task.getPalletId(),
@ -630,11 +633,13 @@ public class HaiAnAutoIssueServiceImpl implements HaiAnAutoIssueService {
: HaiAnAutoIssueStaticData.ERROR_TRANSFER_FAIL;
// 按完整任务结果收尾并写托盘可见原因;任一阶段失败均通知type=2,失败摘要包含各阶段标签。- rqrq
markTaskDone(task.getId(), errorCode, errorMsg, now);
// 将失败摘要写入本工厂托盘,失败回滚主任务收尾;已经提交的发料事实和留盘标记保留。- rqrq
// 短原因继续写占用备注,给正在看调用备注的页面用。- rqrq
haiAnPdaAutoWarehouseMapper.updatePalletRemark(
task.getSite(), task.getPalletId(),
truncate(errorCode + ":" + nvl(errorMsg), PALLET_REMARK_MAX_LENGTH),
HaiAnOperatorStaticData.SYS_WMS);
// 标签级失败明细写入 error_message。写入失败回滚收尾,已独立提交的发料状态不重发。- rqrq
writeAutoIssuePalletError(task.getSite(), task.getPalletId(), errorCode, errorMsg);
// 完成本任务对应RFID明细并保留错误,避免重复消费回调;失败回滚收尾。- rqrq
markRfidDetailFinished(task.getTransportDetailId(), now, errorCode, errorMsg);
// 本任务任一标签未全部成功时通知立库异常位;调用失败由原有事务恢复流程接管。- rqrq
@ -1158,6 +1163,40 @@ public class HaiAnAutoIssueServiceImpl implements HaiAnAutoIssueService {
return value.trim();
}
/**
* 自动发料失败只覆盖 error_message,不改调用标记和位置。内容是失败码加标签说明,按 VARCHAR(500) 字节截断。- rqrq
*/
private void writeAutoIssuePalletError(String site, String palletId, String errorCode, String errorMsg) {
String errorMessage = limitVarchar500(nvl(errorCode) + ":" + nvl(errorMsg));
// 入参 site+palletId 定位本盘。0 行说明托盘已删,抛错让本轮收口回滚,避免只通知立库却没有错误原因。- rqrq
int rows = haiAnPdaAutoWarehouseMapper.updateHaiAnPalletErrorMessage(
site, palletId, errorMessage, HaiAnOperatorStaticData.SYS_WMS);
if (rows <= 0) {
throw new RuntimeException("自动发料写入托盘错误原因失败,未命中托盘:" + palletId);
}
}
/**
* haian_pallet.error_message 是 VARCHAR(500)。中文按 2 字节计,截断后不补省略号。- rqrq
*/
private String limitVarchar500(String text) {
if (!StringUtils.hasText(text)) {
return "";
}
int usedBytes = 0;
int end = 0;
while (end < text.length()) {
char current = text.charAt(end);
int charBytes = current <= 0x7F ? 1 : 2;
if (usedBytes + charBytes > 500) {
break;
}
usedBytes += charBytes;
end++;
}
return text.substring(0, end);
}
/**
* @author rqrq
* @Description 按 nvarchar 的 UTF-16 容量截取错误摘要:null保留,首尾空白移除,纯空白返回空串;边界不拆代理对,避免超长或破损文本阻断收尾。 - rqrq

Loading…
Cancel
Save