小程序对接

This commit is contained in:
2026-09-11 15:30:22 +08:00
parent aa8b7ade99
commit 2da4d824fd
3 changed files with 30 additions and 12 deletions
@@ -109,7 +109,7 @@ public class DriverWaybillCardVO implements Serializable {
@Schema(description = "过程配置是否启用在途打卡(在途节点 punch=是)") @Schema(description = "过程配置是否启用在途打卡(在途节点 punch=是)")
private Boolean transitPunchEnabled; private Boolean transitPunchEnabled;
@Schema(description = "是否展示「今日在途打卡」面板(到期且在时段内,或今日已打") @Schema(description = "是否展示「今日在途打卡」面板(过程配置 punch=是即展示;频次/时段只影响 requireTransitCheckinToday")
private Boolean transitCheckinVisible; private Boolean transitCheckinVisible;
@Schema(description = "今日是否需要在途打卡(到期且未打且在时段内)") @Schema(description = "今日是否需要在途打卡(到期且未打且在时段内)")
@@ -716,12 +716,16 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
vo.setDefaultExpanded(false); vo.setDefaultExpanded(false);
if (isTransit) { if (isTransit) {
// 在途:今日已打则不可再打,回显最新一次信息 // 在途:过程配置 punch=是即下发可见卡;今日已打则不可再打,回显最新一次
boolean punchOn = transit != null && transit.punchEnabled(); // 在途不采集货量;货物照片仅当过程配置勾选上传凭证时下发
boolean punchOn = (transit != null && transit.punchEnabled())
|| WaybillProcessSupport.isTruthyPublic(cfg.get("punch"));
boolean done = transit != null && transit.doneToday(); boolean done = transit != null && transit.doneToday();
if (!punchOn) { if (!punchOn) {
continue; continue;
} }
vo.setNeedCargo(false);
vo.setCargoTypes(Collections.emptyList());
vo.setVisible(true); vo.setVisible(true);
vo.setDone(done); vo.setDone(done);
vo.setActionable(!done); vo.setActionable(!done);
@@ -164,9 +164,10 @@ public final class WaybillProcessSupport {
* 规则: * 规则:
* <ul> * <ul>
* <li>在途节点未启用或 punch≠是 → 不展示</li> * <li>在途节点未启用或 punch≠是 → 不展示</li>
* <li>运单非进行中(running)→ 不展示</li> * <li>过程配置 punch=是 → 始终展示折叠卡(与频次/时段解耦,对齐「所有打卡=是的节点都显示」)</li>
* <li>频次 / 时段仅影响 dueToday(今日是否仍需打),不隐藏卡片</li>
* <li>频次:每 N 天打卡 1 次;无历史 → 到期;上次打卡日 + N ≤ 今日 → 到期</li> * <li>频次:每 N 天打卡 1 次;无历史 → 到期;上次打卡日 + N ≤ 今日 → 到期</li>
* <li>时段:到期时须落在 timeStart~timeEnd(支持跨午夜);今日已打则仍展示(已打卡态)</li> * <li>时段:到期时须落在 timeStart~timeEnd(支持跨午夜)</li>
* </ul> * </ul>
*/ */
public static TransitCheckinDecision evaluateTransitCheckin( public static TransitCheckinDecision evaluateTransitCheckin(
@@ -182,24 +183,25 @@ public final class WaybillProcessSupport {
int frequencyDays = parsePositiveInt(transit.get("frequencyDays"), 1); int frequencyDays = parsePositiveInt(transit.get("frequencyDays"), 1);
String timeStart = normalizeHm(stringVal(transit.get("timeStart")), "00:00"); String timeStart = normalizeHm(stringVal(transit.get("timeStart")), "00:00");
String timeEnd = normalizeHm(stringVal(transit.get("timeEnd")), "23:59"); String timeEnd = normalizeHm(stringVal(transit.get("timeEnd")), "23:59");
// punch=是即展示卡片;非进行中仅不可作为「今日待打」
if (!STATUS_RUNNING.equals(businessStatus)) { if (!STATUS_RUNNING.equals(businessStatus)) {
return new TransitCheckinDecision(true, false, false, false, frequencyDays, timeStart, timeEnd); return new TransitCheckinDecision(true, true, false, false, frequencyDays, timeStart, timeEnd);
} }
LocalDateTime current = now == null ? LocalDateTime.now() : now; LocalDateTime current = now == null ? LocalDateTime.now() : now;
LocalDate today = current.toLocalDate(); LocalDate today = current.toLocalDate();
LocalDate lastDate = toLocalDate(lastPunchAt); LocalDate lastDate = toLocalDate(lastPunchAt);
boolean doneToday = lastDate != null && lastDate.equals(today); boolean doneToday = lastDate != null && lastDate.equals(today);
boolean dueToday; boolean dueByFrequency;
if (lastDate == null) { if (lastDate == null) {
dueToday = true; dueByFrequency = true;
} else { } else {
LocalDate nextDue = lastDate.plusDays(frequencyDays); LocalDate nextDue = lastDate.plusDays(frequencyDays);
dueToday = !today.isBefore(nextDue); dueByFrequency = !today.isBefore(nextDue);
} }
boolean inWindow = isWithinTimeWindow(current.toLocalTime(), timeStart, timeEnd); boolean inWindow = isWithinTimeWindow(current.toLocalTime(), timeStart, timeEnd);
boolean visible = doneToday || (dueToday && inWindow); boolean dueToday = dueByFrequency && inWindow && !doneToday;
return new TransitCheckinDecision(true, visible, dueToday && inWindow && !doneToday, doneToday, frequencyDays, timeStart, timeEnd); return new TransitCheckinDecision(true, true, dueToday, doneToday, frequencyDays, timeStart, timeEnd);
} }
public static Map<String, Object> findTransitNode(String processJson) { public static Map<String, Object> findTransitNode(String processJson) {
@@ -274,6 +276,11 @@ public final class WaybillProcessSupport {
return isTransitNode(node); return isTransitNode(node);
} }
/** 供业务层判断过程配置布尔字段(兼容 true/1/yes/是) */
public static boolean isTruthyPublic(Object value) {
return isTruthy(value);
}
public static boolean nodeNeedLocation(Map<String, Object> node) { public static boolean nodeNeedLocation(Map<String, Object> node) {
return isTruthy(node.get("location")); return isTruthy(node.get("location"));
} }
@@ -395,8 +402,15 @@ public final class WaybillProcessSupport {
if (value instanceof Boolean bool) { if (value instanceof Boolean bool) {
return bool; return bool;
} }
if (value instanceof Number number) {
return number.intValue() != 0;
}
String text = String.valueOf(value).trim(); String text = String.valueOf(value).trim();
return "true".equalsIgnoreCase(text) || "1".equals(text) || "yes".equalsIgnoreCase(text); return "true".equalsIgnoreCase(text)
|| "1".equals(text)
|| "yes".equalsIgnoreCase(text)
|| "y".equalsIgnoreCase(text)
|| "".equals(text);
} }
private static String stringVal(Object value) { private static String stringVal(Object value) {