♻️ 收紧上报门禁查询、去掉平行列表接口并统一节点编码比较
This commit is contained in:
+11
-20
@@ -114,12 +114,6 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
||||
private static final DateTimeFormatter DATE_DOT_SHORT = DateTimeFormatter.ofPattern("MM.dd");
|
||||
private static final DateTimeFormatter TIME_HM = DateTimeFormatter.ofPattern("HH:mm");
|
||||
|
||||
/**
|
||||
* 异常处置终态:已完成 / 已撤销。只有终态解除打卡门禁——「处理中」只表示有人
|
||||
* 跟进过,问题可能仍在,不放行。
|
||||
*/
|
||||
private static final List<String> SETTLED_EXCEPTION_STATUSES = Arrays.asList("completed", "revoked");
|
||||
|
||||
/** 被异常阻断时的不可打卡原因(司机端展示) */
|
||||
private static final String LOCK_REASON_EXCEPTION = "该运单存在未处理异常,处理完成后才能打卡";
|
||||
|
||||
@@ -811,17 +805,15 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
||||
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);
|
||||
.anyMatch(punch -> WaybillProcessSupport.sameNodeCode(nodeCode, punch.getNodeCode()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertCurrentDriverOwnsWaybill(Long waybillId) {
|
||||
// 与司机打卡、司机接单共用同一套归属判定,不另立第二套规则
|
||||
// 归属口径与司机打卡、司机接单一致:都按司机档案自述绑定的车牌判定
|
||||
Driver driver = requireCurrentDriver();
|
||||
loadDriverWaybill(waybillId, currentBoundPlates(driver));
|
||||
}
|
||||
@@ -864,7 +856,7 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
||||
return exceptionDisposalMapper.selectList(Wrappers.<ExceptionDisposal>lambdaQuery()
|
||||
.eq(ExceptionDisposal::getWaybillId, waybillId)
|
||||
.eq(ExceptionDisposal::getIsDeleted, 0)
|
||||
.notIn(ExceptionDisposal::getDisposalStatus, SETTLED_EXCEPTION_STATUSES)
|
||||
.notIn(ExceptionDisposal::getDisposalStatus, WaybillProcessSupport.SETTLED_DISPOSAL_STATUSES)
|
||||
.orderByAsc(ExceptionDisposal::getReportTime)
|
||||
.orderByAsc(ExceptionDisposal::getId));
|
||||
}
|
||||
@@ -1107,18 +1099,17 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
||||
// 它作用于整张运单,所以每个可打卡节点——包括已打卡的与在途的——都挂标签、都算相关。
|
||||
// 相关只有两种来源:归属本节点的、以及整单的;被前序节点异常牵连阻断的节点
|
||||
// 只是不能打卡,那条异常并不归属它,故不进入它的相关列表。
|
||||
// 未了结异常已按上报时间升序取出,过滤后仍保持该顺序;id 转字符串是因为主键是 int64,
|
||||
// 前端直收数字会丢精度。
|
||||
List<ExceptionDisposal> unresolved = unresolvedExceptions(waybill.getId());
|
||||
List<String> unresolvedCodes = unresolved.stream()
|
||||
.map(item -> Func.toStr(item.getNodeCode(), "").trim())
|
||||
.collect(Collectors.toList());
|
||||
List<Long> unresolvedIds = unresolved.stream()
|
||||
.map(ExceptionDisposal::getId)
|
||||
.collect(Collectors.toList());
|
||||
boolean hasWaybillException = WaybillProcessSupport.hasWaybillLevelException(unresolvedCodes);
|
||||
boolean hasWaybillException = unresolved.stream()
|
||||
.anyMatch(item -> WaybillProcessSupport.isWaybillLevelException(item.getNodeCode()));
|
||||
for (DriverPunchNodeVO vo : nodes) {
|
||||
vo.setHasWaybillException(hasWaybillException);
|
||||
vo.setRelatedExceptionIds(
|
||||
WaybillProcessSupport.relatedExceptionIds(vo.getKey(), unresolvedCodes, unresolvedIds));
|
||||
vo.setRelatedExceptionIds(unresolved.stream()
|
||||
.filter(item -> WaybillProcessSupport.relatesToNode(vo.getKey(), item.getNodeCode()))
|
||||
.map(item -> String.valueOf(item.getId()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
for (DriverPunchNodeVO vo : nodes) {
|
||||
|
||||
+6
-5
@@ -54,6 +54,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -182,12 +183,12 @@ public class ExceptionDisposalServiceImpl
|
||||
* 节点编码忽略大小写:历史数据里的写法不一定与过程配置的 key 完全一致。
|
||||
*/
|
||||
private boolean hasUnresolvedNodeException(Long waybillId, String nodeCode) {
|
||||
List<ExceptionDisposal> existing = baseMapper.selectList(Wrappers.<ExceptionDisposal>lambdaQuery()
|
||||
Long count = baseMapper.selectCount(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()));
|
||||
.eq(ExceptionDisposal::getIsDeleted, 0)
|
||||
.notIn(ExceptionDisposal::getDisposalStatus, WaybillProcessSupport.SETTLED_DISPOSAL_STATUSES)
|
||||
.apply("LOWER(node_code) = {0}", nodeCode.toLowerCase(Locale.ROOT)));
|
||||
return count != null && count > 0;
|
||||
}
|
||||
|
||||
/** 按运单补齐运单号 / 车牌 / 项目 / 承运商等展示字段 */
|
||||
|
||||
+18
-27
@@ -58,6 +58,8 @@ public final class WaybillProcessSupport {
|
||||
/** 异常处置终态:completed=已完成,revoked=已撤销。只有终态解除打卡门禁 */
|
||||
private static final String DISPOSAL_COMPLETED = "completed";
|
||||
private static final String DISPOSAL_REVOKED = "revoked";
|
||||
/** 异常处置终态状态码集合:不在此集合内即未了结(processing 也在未了结之列) */
|
||||
public static final List<String> SETTLED_DISPOSAL_STATUSES = List.of(DISPOSAL_COMPLETED, DISPOSAL_REVOKED);
|
||||
private static final DateTimeFormatter HM = DateTimeFormatter.ofPattern("H:mm");
|
||||
private static final DateTimeFormatter HM_PADDED = DateTimeFormatter.ofPattern("HH:mm");
|
||||
|
||||
@@ -391,42 +393,31 @@ public final class WaybillProcessSupport {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在未了结的整单异常。
|
||||
* 两个节点编码是否指同一个节点:两侧去空白、忽略大小写。
|
||||
* <p>
|
||||
* 整单异常不归属任何过程节点,它的节点编码为空;它作用于整张运单,
|
||||
* 所以该运单每个可打卡节点都要挂上「整单异常」标记。
|
||||
* 空与空不算相等——节点编码为空表示整单,它不归属任何过程节点。
|
||||
*/
|
||||
public static boolean hasWaybillLevelException(List<String> unresolvedNodeCodes) {
|
||||
if (unresolvedNodeCodes == null) {
|
||||
return false;
|
||||
}
|
||||
return unresolvedNodeCodes.stream().anyMatch(code -> stringVal(code).isEmpty());
|
||||
public static boolean sameNodeCode(String left, String right) {
|
||||
String leftCode = stringVal(left);
|
||||
String rightCode = stringVal(right);
|
||||
return !leftCode.isEmpty() && leftCode.equalsIgnoreCase(rightCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 与某节点相关的未了结异常 id,一律以字符串返回。
|
||||
* 该异常是否为整单异常:异常不归属任何过程节点时,节点编码为空。
|
||||
*/
|
||||
public static boolean isWaybillLevelException(String exceptionNodeCode) {
|
||||
return stringVal(exceptionNodeCode).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 该异常是否与某节点相关。
|
||||
* <p>
|
||||
* 相关只有两种来源:归属该节点的异常,以及整单异常(节点编码为空,对每个节点都算相关)。
|
||||
* 被前序节点异常牵连阻断的节点不算相关——它自己并没有出过事。
|
||||
* <p>
|
||||
* 顺序保持入参顺序,调用方按上报时间升序取出未了结异常即可。
|
||||
* id 转成字符串是因为主键是 int64,前端直收数字会丢精度。
|
||||
*/
|
||||
public static List<String> relatedExceptionIds(String nodeKey, List<String> unresolvedNodeCodes,
|
||||
List<Long> unresolvedIds) {
|
||||
if (unresolvedNodeCodes == null || unresolvedIds == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String key = stringVal(nodeKey);
|
||||
List<String> related = new ArrayList<>();
|
||||
int size = Math.min(unresolvedNodeCodes.size(), unresolvedIds.size());
|
||||
for (int i = 0; i < size; i++) {
|
||||
String code = stringVal(unresolvedNodeCodes.get(i));
|
||||
if (code.isEmpty() || code.equalsIgnoreCase(key)) {
|
||||
related.add(String.valueOf(unresolvedIds.get(i)));
|
||||
}
|
||||
}
|
||||
return related;
|
||||
public static boolean relatesToNode(String nodeKey, String exceptionNodeCode) {
|
||||
return isWaybillLevelException(exceptionNodeCode) || sameNodeCode(nodeKey, exceptionNodeCode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user