diff --git a/src/main/java/com/ai/da/mapper/primary/entity/SysFile.java b/src/main/java/com/ai/da/mapper/primary/entity/SysFile.java index 24466611..a8c36e4e 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/SysFile.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/SysFile.java @@ -67,6 +67,11 @@ public class SysFile implements Serializable { */ private Date updateDate; + /** + * 风格样式 + */ + private String style; + public SysFile() { } 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 78d2093d..1a4a1413 100644 --- a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java @@ -294,10 +294,10 @@ 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,16 +305,12 @@ 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信息 @@ -388,10 +384,10 @@ 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(); // 3、保存新的designItemDetail(使用 saveOrUpdate 方式) @@ -400,16 +396,12 @@ 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); @@ -476,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"); @@ -493,16 +485,12 @@ 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); @@ -575,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);