Merge branch 'dev' into integ/loading-admission-sync

This commit is contained in:
2026-10-18 16:55:49 +08:00
3 changed files with 44 additions and 14 deletions
@@ -1326,7 +1326,8 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
Set<String> unfinished = WaybillProcessSupport.unfinishedPrerequisiteKeys(
processJson, punched, WaybillProcessSupport.nodeKey(nodeCfg));
if (!unfinished.isEmpty()) {
throw new ServiceException("请先完成「" + prerequisiteNames(processJson, unfinished) + "」打卡");
throw new ServiceException("请先完成「"
+ WaybillProcessSupport.firstUnfinishedPrerequisiteName(processJson, unfinished) + "」打卡");
}
}
@@ -1598,7 +1599,8 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
}
vo.setBlockedByOrder(true);
vo.setActionable(false);
vo.setOrderLockReason("请先完成「" + prerequisiteNames(processJson, unfinished) + "」打卡");
vo.setOrderLockReason("请先完成「"
+ WaybillProcessSupport.firstUnfinishedPrerequisiteName(processJson, unfinished) + "」打卡");
}
// 是否允许展开:顺序门禁不允许展开(还没轮到,展开也没用);
@@ -1647,18 +1649,6 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
return nodes;
}
/** 把前置节点 key 拼成给人看的名称列表,如「装货、发货」 */
private String prerequisiteNames(String processJson, Set<String> nodeKeys) {
List<String> names = new ArrayList<>();
for (Map<String, Object> node : WaybillProcessSupport.listDriverPunchNodes(processJson)) {
String key = WaybillProcessSupport.nodeKey(node);
if (nodeKeys.contains(key)) {
names.add(WaybillProcessSupport.nodeName(node));
}
}
return names.isEmpty() ? "" : String.join("、", names);
}
private Map<String, Object> findPunchNodeConfig(String processJson, String nodeCode) {
List<Map<String, Object>> punchConfigs = WaybillProcessSupport.listDriverPunchNodes(processJson);
for (Map<String, Object> cfg : punchConfigs) {
@@ -420,6 +420,28 @@ public final class WaybillProcessSupport {
return Collections.emptySet();
}
/**
* 顺序门禁点名的那一个前置节点名称:取**最先未完成**的。
* <p>
* 它才是司机现在能去打卡的那一步——后面那些未完成的前置节点自己也还打不了,
* 一起列出来既长,又不是一个可执行的下一步。
*
* @param processJson 过程配置
* @param nodeKeys 未完成的前置节点 key,即 {@link #unfinishedPrerequisiteKeys} 的返回
*/
public static String firstUnfinishedPrerequisiteName(String processJson, Collection<String> nodeKeys) {
if (nodeKeys == null || nodeKeys.isEmpty()) {
return "";
}
for (Map<String, Object> node : listDriverPunchNodes(processJson)) {
String key = nodeKey(node);
if (nodeKeys.contains(key)) {
return nodeName(node);
}
}
return "";
}
/**
* 两个节点编码是否指同一个节点:两侧去空白、忽略大小写。
* <p>
@@ -123,6 +123,24 @@ class WaybillProcessSupportTest {
"「到货」还没打,所以卸货的前置是到货;在途不是前置(它没有完成含义)");
}
@Test
@DisplayName("顺序门禁只点名最先未完成的那一个前置节点,不把没打的前置全列出来")
void namesOnlyTheEarliestUnfinishedPrerequisite() {
Set<String> unfinished = WaybillProcessSupport.unfinishedPrerequisiteKeys(
TRANSPORT_JSON, Collections.emptySet(), "arrival");
assertEquals(keys("arrive_scene", "load", "dispatch"), unfinished, "到货前面三个打卡节点都没打");
assertEquals("到场", WaybillProcessSupport.firstUnfinishedPrerequisiteName(TRANSPORT_JSON, unfinished),
"只报司机现在能去打卡的那一个:装货、发货自己也还打不了,列出来不是可执行的下一步");
}
@Test
@DisplayName("没有未完成的前置节点时不点名")
void namesNothingWhenNothingIsUnfinished() {
assertEquals("",
WaybillProcessSupport.firstUnfinishedPrerequisiteName(TRANSPORT_JSON, Collections.emptySet()));
}
@Test
@DisplayName("顺序门禁:在途豁免,前置一个都没打也返回空集")
void transitIsExemptFromOrderGate() {