✨ 节点异常上报增加打卡与重复上报校验
This commit is contained in:
+7
@@ -108,4 +108,11 @@ public interface IDriverWaybillService {
|
||||
*/
|
||||
Map<String, Object> findPunchNode(Long waybillId, String nodeCode);
|
||||
|
||||
/**
|
||||
* 该运单的指定节点当前是否存在打卡流水;节点编码忽略大小写。
|
||||
* <p>
|
||||
* 以打卡流水为准而非运单当前节点:管理端取消打卡后这里要立刻回到未打卡。
|
||||
*/
|
||||
boolean isNodePunched(Long waybillId, String nodeCode);
|
||||
|
||||
}
|
||||
|
||||
+14
@@ -805,6 +805,20 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
||||
return findPunchNodeConfig(resolveProcessJson(waybill), nodeCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNodePunched(Long waybillId, String nodeCode) {
|
||||
if (waybillId == null || Func.isEmpty(nodeCode)) {
|
||||
return false;
|
||||
}
|
||||
// 不复用 latestNodePunchMap:它的 key 被 toLowerCase 过,与过程配置 key 比不出来
|
||||
String key = nodeCode.trim();
|
||||
return nodePunchMapper.selectList(Wrappers.<WaybillNodePunch>lambdaQuery()
|
||||
.eq(WaybillNodePunch::getWaybillId, waybillId))
|
||||
.stream()
|
||||
.map(punch -> Func.toStr(punch.getNodeCode(), "").trim())
|
||||
.anyMatch(key::equalsIgnoreCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该运单「未处理完成的异常」所属节点 key(未达终态:已完成 / 已撤销)。
|
||||
* <p>
|
||||
|
||||
+29
-1
@@ -147,7 +147,19 @@ public class ExceptionDisposalServiceImpl
|
||||
if (nodeCfg == null) {
|
||||
throw new ServiceException("异常节点不存在");
|
||||
}
|
||||
disposal.setNodeCode(WaybillProcessSupport.nodeKey(nodeCfg));
|
||||
String nodeKey = WaybillProcessSupport.nodeKey(nodeCfg);
|
||||
// 上报门禁之一:已打卡说明这个环节已经过去,事后才发现的问题走整单异常。
|
||||
// 在途例外——它可重复打卡、没有完成含义,打卡与否不说明环节是否已经过去。
|
||||
if (!WaybillProcessSupport.isTransitNodePublic(nodeCfg)
|
||||
&& driverWaybillService.isNodePunched(disposal.getWaybillId(), nodeKey)) {
|
||||
throw new ServiceException("该节点已打卡,不能上报异常");
|
||||
}
|
||||
// 上报门禁之二:同一节点同时至多一条未了结异常,处理中也占位。
|
||||
// 约束是同时性的:异常了结后该节点重新可以上报。
|
||||
if (hasUnresolvedNodeException(disposal.getWaybillId(), nodeKey)) {
|
||||
throw new ServiceException("该节点已有未处理异常,处理完成后才能再次上报");
|
||||
}
|
||||
disposal.setNodeCode(nodeKey);
|
||||
disposal.setNodeName(WaybillProcessSupport.nodeName(nodeCfg));
|
||||
}
|
||||
|
||||
@@ -157,6 +169,22 @@ public class ExceptionDisposalServiceImpl
|
||||
return toVO(disposal);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该运单的指定节点是否已有未了结(未达终态)的异常。
|
||||
* <p>
|
||||
* 未了结的判据与打卡门禁同一份:已完成、已撤销之外的状态都算,
|
||||
* 「处理中」同样占位——它只是有人跟进过,问题可能仍在。
|
||||
* 节点编码忽略大小写:历史数据里的写法不一定与过程配置的 key 完全一致。
|
||||
*/
|
||||
private boolean hasUnresolvedNodeException(Long waybillId, String nodeCode) {
|
||||
List<ExceptionDisposal> existing = baseMapper.selectList(Wrappers.<ExceptionDisposal>lambdaQuery()
|
||||
.eq(ExceptionDisposal::getWaybillId, waybillId)
|
||||
.eq(ExceptionDisposal::getIsDeleted, 0));
|
||||
return existing.stream().anyMatch(item ->
|
||||
nodeCode.equalsIgnoreCase(Func.toStr(item.getNodeCode(), "").trim())
|
||||
&& !WaybillProcessSupport.isSettledDisposal(item.getDisposalStatus()));
|
||||
}
|
||||
|
||||
/** 按运单补齐运单号 / 车牌 / 项目 / 承运商等展示字段 */
|
||||
private void fillFromWaybill(ExceptionDisposal disposal, Long waybillId, String waybillNo) {
|
||||
Waybill waybill = null;
|
||||
|
||||
Reference in New Issue
Block a user