diff --git a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java index f3b798c9..96fb1a13 100644 --- a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java @@ -289,15 +289,15 @@ public class DesignItemServiceImpl extends ServiceImpl existingDetails = designItemDetailService.selectByDesignItemId(designItemId); // 创建 Map,以 priority 为 key,方便快速查找 Map existingDetailMap = existingDetails.stream() + .filter(detail -> Objects.nonNull(detail.getPriority())) .collect(Collectors.toMap(DesignItemDetail::getPriority, detail -> detail, (old, newVal) -> old)); - - // 收集新 detail 的 priority,用于后续删除不存在的旧记录 - Set newDetailPriorities = new HashSet<>(); + Map> detailBuckets = buildDetailTypeBuckets(existingDetails); + Set reusedDetailIds = new HashSet<>(); List designItemDetails = Lists.newArrayList(); pythonObjects.getObjects().get(0).getItems().forEach(detail -> { @@ -305,20 +305,16 @@ public class DesignItemServiceImpl extends ServiceImpl { - if (!newDetailPriorities.contains(existingDetail.getPriority())) { - // 该记录不在新列表中,需要逻辑删除 - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", existingDetail.getId()); - updateWrapper.set("is_deleted", (byte) 1); - updateWrapper.set("update_date", DateUtil.getByTimeZone(timeZone)); - designItemDetailService.update(null, updateWrapper); - } - }); - + + // 逻辑删除未复用的旧记录 + existingDetails.stream() + .filter(existingDetail -> Objects.nonNull(existingDetail.getId()) && !reusedDetailIds.contains(existingDetail.getId())) + .forEach(existingDetail -> { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", existingDetail.getId()); + updateWrapper.set("is_deleted", (byte) 1); + updateWrapper.set("update_date", DateUtil.getByTimeZone(timeZone)); + designItemDetailService.update(null, updateWrapper); + }); + designItemDetailService.saveOrUpdateBatch(designItemDetails); //封装item信息 List designCollectionItems = CopyUtil.copyList(getByDesignId(designId) @@ -383,16 +379,16 @@ public class DesignItemServiceImpl extends ServiceImpl existingDetails = designItemDetailService.selectByDesignItemId(designItemId); // 创建 Map,以 priority 为 key,方便快速查找 Map existingDetailMap = existingDetails.stream() + .filter(detail -> Objects.nonNull(detail.getPriority())) .collect(Collectors.toMap(DesignItemDetail::getPriority, detail -> detail, (old, newVal) -> old)); + Map> detailBuckets = buildDetailTypeBuckets(existingDetails); + Set reusedDetailIds = new HashSet<>(); - // 收集新 detail 的 priority,用于后续删除不存在的旧记录 - Set newDetailPriorities = new HashSet<>(); - List designItemDetails = Lists.newArrayList(); // 3、保存新的designItemDetail(使用 saveOrUpdate 方式) pythonObjects.getObjects().get(0).getItems().forEach(detail -> { @@ -400,20 +396,16 @@ public class DesignItemServiceImpl extends ServiceImpl { - if (!newDetailPriorities.contains(existingDetail.getPriority())) { - // 该记录不在新列表中,需要逻辑删除 - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", existingDetail.getId()); - updateWrapper.set("is_deleted", (byte) 1); - updateWrapper.set("update_date", DateUtil.getByTimeZone(timeZone)); - designItemDetailService.update(null, updateWrapper); - } - }); - + + // 逻辑删除未复用的旧记录 + existingDetails.stream() + .filter(existingDetail -> Objects.nonNull(existingDetail.getId()) && !reusedDetailIds.contains(existingDetail.getId())) + .forEach(existingDetail -> { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", existingDetail.getId()); + updateWrapper.set("is_deleted", (byte) 1); + updateWrapper.set("update_date", DateUtil.getByTimeZone(timeZone)); + designItemDetailService.update(null, updateWrapper); + }); + // businessId 来自t_sys_file或者t_library designItemDetailService.saveOrUpdateBatch(designItemDetails); @@ -470,10 +468,10 @@ public class DesignItemServiceImpl extends ServiceImpl existingLayers = designPythonOutfitDetailService.getDetailByDesignPythonOutfitId(designPythonOutfit.getId()); // 创建 Map,以 priority 为 key,方便快速查找 Map existingLayerMap = existingLayers.stream() - .collect(Collectors.toMap(TDesignPythonOutfitDetail::getPriority, layer -> layer, (old, newVal) -> old)); - - // 收集新 layer 的 priority,用于后续删除不存在的旧记录 - Set newLayerPriorities = new HashSet<>(); + .filter(layer -> Objects.nonNull(layer.getPriority())) + .collect(Collectors.toMap(layer -> Math.abs(layer.getPriority()), layer -> layer, (old, newVal) -> old)); + Map> layerBuckets = buildOutfitCategoryBuckets(existingLayers); + Set reusedLayerIds = new HashSet<>(); // 7、将新生成的图层信息存入designPythonOutfitDetail表(使用 saveOrUpdate 方式) JSONArray layers = outfit.getJSONArray("layers"); @@ -487,20 +485,16 @@ public class DesignItemServiceImpl extends ServiceImpl { - if (!newLayerPriorities.contains(Math.abs(existingLayer.getPriority()))) { - // 该记录不在新列表中,需要逻辑删除 - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", existingLayer.getId()); - updateWrapper.set("is_deleted", 1); - updateWrapper.set("update_date", LocalDateTime.now(ZoneId.of(timeZone))); - designPythonOutfitDetailService.update(null, updateWrapper); - } - }); + + // 逻辑删除未复用的旧记录 + existingLayers.stream() + .filter(existingLayer -> Objects.nonNull(existingLayer.getId()) && !reusedLayerIds.contains(existingLayer.getId())) + .forEach(existingLayer -> { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", existingLayer.getId()); + updateWrapper.set("is_deleted", 1); + updateWrapper.set("update_date", LocalDateTime.now(ZoneId.of(timeZone))); + designPythonOutfitDetailService.update(null, updateWrapper); + }); designPythonOutfitDetailService.saveOrUpdateBatch(list); @@ -569,6 +562,112 @@ public class DesignItemServiceImpl extends ServiceImpl> buildDetailTypeBuckets(List details) { + return details.stream() + .collect(Collectors.groupingBy(DesignItemDetail::getType, + Collectors.collectingAndThen(Collectors.toList(), list -> { + list.sort(Comparator + .comparingInt(this::extractDetailPriorityForSort) + .thenComparing(DesignItemDetail::getId, Comparator.nullsLast(Long::compareTo))); + return new ArrayDeque<>(list); + }))); + } + + private DesignItemDetail reuseDesignItemDetail(Integer priority, String type, + Map priorityMap, + Map> typeBuckets, + Set reusedIds) { + DesignItemDetail reused = null; + if (Objects.nonNull(priority)) { + reused = priorityMap.remove(priority); + } + if (Objects.nonNull(reused)) { + markReusedDetail(reused, reusedIds); + return reused; + } + Deque bucket = typeBuckets.get(type); + while (bucket != null && !bucket.isEmpty()) { + DesignItemDetail candidate = bucket.pollFirst(); + if (markReusedDetail(candidate, reusedIds)) { + Integer candidatePriority = candidate.getPriority(); + if (Objects.nonNull(candidatePriority)) { + priorityMap.remove(candidatePriority, candidate); + } + return candidate; + } + } + return null; + } + + private Map> buildOutfitCategoryBuckets(List details) { + return details.stream() + .collect(Collectors.groupingBy(TDesignPythonOutfitDetail::getImageCategory, + Collectors.collectingAndThen(Collectors.toList(), list -> { + list.sort(Comparator + .comparingInt(this::extractOutfitPriorityForSort) + .thenComparing(TDesignPythonOutfitDetail::getId, Comparator.nullsLast(Long::compareTo))); + return new ArrayDeque<>(list); + }))); + } + + private TDesignPythonOutfitDetail reuseOutfitDetail(Integer priority, String imageCategory, + Map priorityMap, + Map> categoryBuckets, + Set reusedIds) { + TDesignPythonOutfitDetail reused = null; + if (Objects.nonNull(priority)) { + reused = priorityMap.remove(Math.abs(priority)); + } + if (Objects.nonNull(reused)) { + markReusedLayer(reused, reusedIds); + return reused; + } + Deque bucket = categoryBuckets.get(imageCategory); + while (bucket != null && !bucket.isEmpty()) { + TDesignPythonOutfitDetail candidate = bucket.pollFirst(); + if (markReusedLayer(candidate, reusedIds)) { + Integer candidatePriority = candidate.getPriority(); + if (Objects.nonNull(candidatePriority)) { + priorityMap.remove(Math.abs(candidatePriority), candidate); + } + return candidate; + } + } + return null; + } + + private boolean markReusedDetail(DesignItemDetail detail, Set reusedIds) { + if (Objects.isNull(detail)) { + return false; + } + Long id = detail.getId(); + return Objects.isNull(id) || reusedIds.add(id); + } + + private boolean markReusedLayer(TDesignPythonOutfitDetail detail, Set reusedIds) { + if (Objects.isNull(detail)) { + return false; + } + Long id = detail.getId(); + return Objects.isNull(id) || reusedIds.add(id); + } + + private int safePriorityValue(Integer priority) { + return Objects.isNull(priority) ? Integer.MAX_VALUE : priority; + } + + private int safeAbsPriorityValue(Integer priority) { + return Objects.isNull(priority) ? Integer.MAX_VALUE : Math.abs(priority); + } + + private int extractDetailPriorityForSort(DesignItemDetail detail) { + return safePriorityValue(detail.getPriority()); + } + + private int extractOutfitPriorityForSort(TDesignPythonOutfitDetail detail) { + return safeAbsPriorityValue(detail.getPriority()); + } + private DesignItem selectById(Long id) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("id", id); @@ -1061,7 +1160,7 @@ public class DesignItemServiceImpl extends ServiceImpl existingPrints = designItemDetailPrintService.getByDesignItemDetailId(designItemDetailId, printType); // 创建 Map,以 priority 为 key,方便快速查找 @@ -1075,10 +1174,10 @@ public class DesignItemServiceImpl extends ServiceImpl { setUriToMinioPath(print); - + Integer priority = print.getPriority(); newPrintPriorities.add(priority); - + DesignItemDetailPrint designItemDetailPrint; // 如果存在相同 priority 的记录,则更新;否则创建新记录 if (existingPrintMap.containsKey(priority)) { @@ -1090,7 +1189,7 @@ public class DesignItemServiceImpl extends ServiceImpl