fix(lastleg): repair dispatch cancellation and return execution contracts

This commit is contained in:
2026-10-18 16:34:14 +08:00
parent 66a0beb653
commit aa33514ec6
64 changed files with 2061 additions and 213 deletions
@@ -6,9 +6,9 @@ import java.util.Set;
public final class DeliveryStatusPolicy {
private static final Set<String> EDITABLE_TARGETS = Set.of(
"WAIT_DELIVERY", "DELIVERING", "REJECTED", "CANCELLED");
"WAIT_DELIVERY", "DELIVERING", "REJECTED");
private static final Map<String, Set<String>> TRANSITIONS = Map.of(
"WAIT_DELIVERY", Set.of("DELIVERING", "DELIVERED", "REJECTED", "CANCELLED"),
"WAIT_DELIVERY", Set.of("DELIVERING", "DELIVERED", "REJECTED"),
"DELIVERING", Set.of("DELIVERED", "REJECTED"),
"DELIVERED", Set.of(),
"REJECTED", Set.of(),
@@ -16,23 +16,32 @@ public final class DeliveryStatusPolicy {
"RETURNED", Set.of(),
"CANCELLED", Set.of());
/** 状态规则为纯策略,实际出库由命令及查询层提供。 */
private DeliveryStatusPolicy() { }
/** 人工只允许开始派送或拒签,取消必须由出库聚合命令处理。 */
public static boolean isEditableTarget(String status) {
return EDITABLE_TARGETS.contains(status);
}
/** 校验状态机,签收终态仍由签收资料命令触发。 */
public static boolean canTransition(String from, String target) {
return TRANSITIONS.getOrDefault(from, Set.of()).contains(target);
}
/** 返回状态本身允许的动作;执行动作还须满足实际出库事实。 */
public static List<String> allowedActions(String status) {
return switch (status == null ? "" : status) {
case "WAIT_DELIVERY" -> List.of(
"START_DELIVERY", "REJECT_DELIVERY", "CANCEL_DELIVERY");
"START_DELIVERY", "REJECT_DELIVERY");
case "DELIVERING" -> List.of("REJECT_DELIVERY", "MARK_RETURN");
case "DELIVERED", "REJECTED", "RETURN_PENDING" -> List.of("MARK_RETURN");
default -> List.of();
};
}
/** 未实际出库不得开始派送、拒签或创建运输退回。 */
public static List<String> allowedActions(String status, boolean outboundCompleted) {
return outboundCompleted ? allowedActions(status) : List.of();
}
}