refactor(wms): 优化卷材变更日志记录逻辑

- 重构加工变换日志记录,支持合并、分卷等不同场景
- 修改快照对比逻辑,合并新旧键值以避免遗漏空值字段
- 调整仓库层级排序算法,移除四级库位的序号修正
- 注释掉卷材合同关系中的日志记录代码
- 在撤回导出时清空操作人员信息
This commit is contained in:
2026-07-11 16:49:20 +08:00
parent 74827f696b
commit 2dbbb942ef
5 changed files with 96 additions and 70 deletions

View File

@@ -276,7 +276,7 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
// 1. 置顶优先 (is_top=1 排在前面) // 1. 置顶优先 (is_top=1 排在前面)
// 2. 合同号倒序KLPY+年月日+序号,降序最新在前) // 2. 合同号倒序KLPY+年月日+序号,降序最新在前)
qw.orderByDesc("co.is_top") qw.orderByDesc("co.is_top")
.orderByDesc("co.contract_code"); .orderByDesc("co.contract_code");
return qw; return qw;
} }
@@ -365,10 +365,11 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
// 计算变更字段差异 // 计算变更字段差异
Map<String, Map<String, Object>> diff = new LinkedHashMap<>(); Map<String, Map<String, Object>> diff = new LinkedHashMap<>();
for (Map.Entry<String, Object> fieldEntry : newSnapshot.entrySet()) { Set<String> allKeys = new LinkedHashSet<>(oldSnapshot.keySet());
String field = fieldEntry.getKey(); allKeys.addAll(newSnapshot.keySet());
for (String field : allKeys) {
Object oldVal = oldSnapshot.get(field); Object oldVal = oldSnapshot.get(field);
Object newVal = fieldEntry.getValue(); Object newVal = newSnapshot.get(field);
if (!Objects.equals(oldVal, newVal)) { if (!Objects.equals(oldVal, newVal)) {
Map<String, Object> change = new LinkedHashMap<>(); Map<String, Object> change = new LinkedHashMap<>();
change.put("old", oldVal); change.put("old", oldVal);

View File

@@ -107,10 +107,12 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
Map<String, Object> newSnapshot = newCoil != null ? BeanUtil.beanToMap(newCoil, false, true) : new LinkedHashMap<>(); Map<String, Object> newSnapshot = newCoil != null ? BeanUtil.beanToMap(newCoil, false, true) : new LinkedHashMap<>();
Map<String, Map<String, Object>> diff = new LinkedHashMap<>(); Map<String, Map<String, Object>> diff = new LinkedHashMap<>();
for (Map.Entry<String, Object> fieldEntry : newSnapshot.entrySet()) { // 合并新旧 key避免置空字段被 beanToMap 忽略而漏掉
String field = fieldEntry.getKey(); Set<String> allKeys = new LinkedHashSet<>(oldSnapshot.keySet());
allKeys.addAll(newSnapshot.keySet());
for (String field : allKeys) {
Object oldVal = oldSnapshot.get(field); Object oldVal = oldSnapshot.get(field);
Object newVal = fieldEntry.getValue(); Object newVal = newSnapshot.get(field);
if (!Objects.equals(oldVal, newVal)) { if (!Objects.equals(oldVal, newVal)) {
Map<String, Object> change = new LinkedHashMap<>(); Map<String, Object> change = new LinkedHashMap<>();
change.put("old", oldVal); change.put("old", oldVal);
@@ -872,9 +874,9 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
if (parent.getActualWarehouseType() != null && parent.getActualWarehouseType() == 1L) { if (parent.getActualWarehouseType() != null && parent.getActualWarehouseType() == 1L) {
List<WmsActualWarehouse> l2List = baseMapper.selectList( List<WmsActualWarehouse> l2List = baseMapper.selectList(
new LambdaQueryWrapper<WmsActualWarehouse>() new LambdaQueryWrapper<WmsActualWarehouse>()
.eq(WmsActualWarehouse::getParentId, parentId) .eq(WmsActualWarehouse::getParentId, parentId)
.eq(WmsActualWarehouse::getDelFlag, 0) .eq(WmsActualWarehouse::getDelFlag, 0)
); );
int totalCount = 0; int totalCount = 0;
@@ -895,16 +897,16 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
private int fixLevel(Long parentId, Long l1SortNo, Long l2SortNo, int[] counter) { private int fixLevel(Long parentId, Long l1SortNo, Long l2SortNo, int[] counter) {
List<WmsActualWarehouse> list = baseMapper.selectList( List<WmsActualWarehouse> list = baseMapper.selectList(
new LambdaQueryWrapper<WmsActualWarehouse>() new LambdaQueryWrapper<WmsActualWarehouse>()
.eq(WmsActualWarehouse::getParentId, parentId) .eq(WmsActualWarehouse::getParentId, parentId)
.eq(WmsActualWarehouse::getDelFlag, 0) .eq(WmsActualWarehouse::getDelFlag, 0)
); );
if (list.isEmpty()) return 0; if (list.isEmpty()) return 0;
// 需求调整:此处不再对四级(小库位)进行 sort_no 修正,只修正三级(大库位)即可 // 需求调整:此处不再对四级(小库位)进行 sort_no 修正,只修正三级(大库位)即可
boolean isFourthLevel = list.get(0).getActualWarehouseType() != null boolean isFourthLevel = list.get(0).getActualWarehouseType() != null
&& list.get(0).getActualWarehouseType() == 4L; && list.get(0).getActualWarehouseType() == 4L;
if (isFourthLevel) { if (isFourthLevel) {
return 0; return 0;
} }
@@ -919,25 +921,25 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
Matcher m3 = pattern3.matcher(code); Matcher m3 = pattern3.matcher(code);
if (m3.matches()) { if (m3.matches()) {
sortKeyMap.put(w, new int[]{ sortKeyMap.put(w, new int[]{
Integer.parseInt(m3.group(2)), Integer.parseInt(m3.group(2)),
Integer.parseInt(m3.group(3)), Integer.parseInt(m3.group(3)),
Integer.parseInt(m3.group(4)) Integer.parseInt(m3.group(4))
}); });
} }
} }
List<WmsActualWarehouse> sorted = sortKeyMap.entrySet().stream() List<WmsActualWarehouse> sorted = sortKeyMap.entrySet().stream()
.sorted((e1, e2) -> { .sorted((e1, e2) -> {
int[] k1 = e1.getValue(); int[] k1 = e1.getValue();
int[] k2 = e2.getValue(); int[] k2 = e2.getValue();
int c = Integer.compare(k1[0], k2[0]); int c = Integer.compare(k1[0], k2[0]);
if (c != 0) return c; if (c != 0) return c;
c = Integer.compare(k1[1], k2[1]); c = Integer.compare(k1[1], k2[1]);
if (c != 0) return c; if (c != 0) return c;
return Integer.compare(k1[2], k2[2]); return Integer.compare(k1[2], k2[2]);
}) })
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
.collect(Collectors.toList()); .collect(Collectors.toList());
List<WmsActualWarehouse> updates = new ArrayList<>(); List<WmsActualWarehouse> updates = new ArrayList<>();
int totalCount = 0; int totalCount = 0;

View File

@@ -118,44 +118,45 @@ public class WmsCoilContractRelServiceImpl implements IWmsCoilContractRelService
if (needUpdate) { if (needUpdate) {
updateWrapper.eq(WmsMaterialCoil::getCoilId, coilId); updateWrapper.eq(WmsMaterialCoil::getCoilId, coilId);
// 更新前抓快照 // // 更新前抓快照
WmsMaterialCoil oldCoil = coilMapper.selectById(coilId); // WmsMaterialCoil oldCoil = coilMapper.selectById(coilId);
Map<String, Object> oldSnapshot = oldCoil != null ? BeanUtil.beanToMap(oldCoil, false, true) : null; // Map<String, Object> oldSnapshot = oldCoil != null ? BeanUtil.beanToMap(oldCoil, false, true) : null;
coilMapper.update(null, updateWrapper); coilMapper.update(null, updateWrapper);
// 更新后抓快照,计算差异 // // 更新后抓快照,计算差异
try { // try {
WmsMaterialCoil newCoil = coilMapper.selectById(coilId); // WmsMaterialCoil newCoil = coilMapper.selectById(coilId);
Map<String, Object> newSnapshot = newCoil != null ? BeanUtil.beanToMap(newCoil, false, true) : new LinkedHashMap<>(); // Map<String, Object> newSnapshot = newCoil != null ? BeanUtil.beanToMap(newCoil, false, true) : new LinkedHashMap<>();
//
Map<String, Map<String, Object>> diff = new LinkedHashMap<>(); // Map<String, Map<String, Object>> diff = new LinkedHashMap<>();
if (oldSnapshot != null) { // if (oldSnapshot != null) {
for (Map.Entry<String, Object> entry : newSnapshot.entrySet()) { // Set<String> allKeys = new LinkedHashSet<>(oldSnapshot.keySet());
String field = entry.getKey(); // allKeys.addAll(newSnapshot.keySet());
Object oldVal = oldSnapshot.get(field); // for (String field : allKeys) {
Object newVal = entry.getValue(); // Object oldVal = oldSnapshot.get(field);
if (!Objects.equals(oldVal, newVal)) { // Object newVal = newSnapshot.get(field);
Map<String, Object> change = new LinkedHashMap<>(); // if (!Objects.equals(oldVal, newVal)) {
change.put("old", oldVal); // Map<String, Object> change = new LinkedHashMap<>();
change.put("new", newVal); // change.put("old", oldVal);
diff.put(field, change); // change.put("new", newVal);
} // diff.put(field, change);
} // }
} // }
// }
WmsCoilChangeLog log = new WmsCoilChangeLog(); //
log.setChangeType(CoilChangeType.UPDATE.name()); // WmsCoilChangeLog log = new WmsCoilChangeLog();
log.setOldCoilId(coilId); // log.setChangeType(CoilChangeType.UPDATE.name());
log.setNewCoilId(coilId); // log.setOldCoilId(coilId);
log.setOldCoilNo(oldSnapshot != null ? String.valueOf(oldSnapshot.get("currentCoilNo")) : null); // log.setNewCoilId(coilId);
log.setNewCoilNo(newSnapshot.get("currentCoilNo") != null ? String.valueOf(newSnapshot.get("currentCoilNo")) : null); // log.setOldCoilNo(oldSnapshot != null ? String.valueOf(oldSnapshot.get("currentCoilNo")) : null);
log.setChangedFields(diff.isEmpty() ? null : JSONUtil.toJsonStr(diff)); // log.setNewCoilNo(newSnapshot.get("currentCoilNo") != null ? String.valueOf(newSnapshot.get("currentCoilNo")) : null);
log.setOperationDesc("同步销售员/合同号"); // log.setChangedFields(diff.isEmpty() ? null : JSONUtil.toJsonStr(diff));
changeLogMapper.insert(log); // log.setOperationDesc("同步销售员/合同号");
} catch (Exception e) { // changeLogMapper.insert(log);
// 日志记录失败不影响主流程 // } catch (Exception e) {
} // // 日志记录失败不影响主流程
// }
} }
} }
} }

View File

@@ -81,13 +81,34 @@ public class CoilChangeLogAspect {
insertLog(changeType, null, newId, null, newSnapshot, coilChangeLog.value()); insertLog(changeType, null, newId, null, newSnapshot, coilChangeLog.value());
} }
} else if (changeType.isProcessing()) { } else if (changeType.isProcessing()) {
// 加工变换:旧卷 → 新卷,一一对应(或 多旧 → 一新) // 加工变换:旧卷 → 新卷
for (int i = 0; i < oldCoilIds.size(); i++) { Long commonNewId = newCoilIds.isEmpty() ? null : newCoilIds.get(0);
Long oldId = oldCoilIds.get(i); if (changeType == CoilChangeType.MERGE) {
Long newId = (i < newCoilIds.size()) ? newCoilIds.get(i) : null; // N旧→1新每个旧卷都指向同一个新卷
for (int i = 0; i < oldCoilIds.size(); i++) {
Long oldId = oldCoilIds.get(i);
Map<String, Object> oldSnapshot = oldSnapshots.get(oldId);
Map<String, Object> newSnapshot = commonNewId != null ? queryCoilSnapshot(commonNewId) : null;
insertLog(changeType, oldId, commonNewId, oldSnapshot, newSnapshot, coilChangeLog.value());
}
} else if (oldCoilIds.size() == 1 && newCoilIds.size() > 1) {
// 1旧→N新分卷每个新卷一条日志都指向同一个旧母卷
Long oldId = oldCoilIds.get(0);
Map<String, Object> oldSnapshot = oldSnapshots.get(oldId); Map<String, Object> oldSnapshot = oldSnapshots.get(oldId);
Map<String, Object> newSnapshot = (newId != null) ? queryCoilSnapshot(newId) : null; String label = coilChangeLog.value() + "-分卷";
insertLog(changeType, oldId, newId, oldSnapshot, newSnapshot, coilChangeLog.value()); for (Long newId : newCoilIds) {
Map<String, Object> newSnapshot = queryCoilSnapshot(newId);
insertLog(changeType, oldId, newId, oldSnapshot, newSnapshot, label);
}
} else {
// 一一对应:单步加工/回滚/单子卷等
for (int i = 0; i < oldCoilIds.size(); i++) {
Long oldId = oldCoilIds.get(i);
Long newId = (i < newCoilIds.size()) ? newCoilIds.get(i) : null;
Map<String, Object> oldSnapshot = oldSnapshots.get(oldId);
Map<String, Object> newSnapshot = (newId != null) ? queryCoilSnapshot(newId) : null;
insertLog(changeType, oldId, newId, oldSnapshot, newSnapshot, coilChangeLog.value());
}
} }
} else { } else {
// 原地修改:相同 ID // 原地修改:相同 ID
@@ -254,7 +275,7 @@ public class CoilChangeLogAspect {
* 对比新旧快照,返回变更字段差异 Map * 对比新旧快照,返回变更字段差异 Map
*/ */
private Map<String, Map<String, Object>> computeDiff(Map<String, Object> oldSnapshot, private Map<String, Map<String, Object>> computeDiff(Map<String, Object> oldSnapshot,
Map<String, Object> newSnapshot) { Map<String, Object> newSnapshot) {
Map<String, Map<String, Object>> diff = new LinkedHashMap<>(); Map<String, Map<String, Object>> diff = new LinkedHashMap<>();
// 检查旧值变更或新增 // 检查旧值变更或新增

View File

@@ -909,6 +909,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="updateForWithdrawExport"> <update id="updateForWithdrawExport">
UPDATE wms_material_coil UPDATE wms_material_coil
SET export_time = NULL, SET export_time = NULL,
export_by = NULL,
status = #{status} status = #{status}
WHERE coil_id = #{coilId} WHERE coil_id = #{coilId}
</update> </update>