diff --git a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java index 8e38d1e4..aebb9e10 100644 --- a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java @@ -518,29 +518,92 @@ public class TaskFaceServiceImpl implements TaskFaceService { if (limitPhoto == null || limitPhoto <= 0) { List deviceSampleIds = deviceSamples.stream() .map(FaceSampleEntity::getId) - .collect(Collectors.toList()); + .toList(); resultIds.addAll(deviceSampleIds); log.debug("设备照片限制:设备ID={}, 无限制,保留{}张照片", deviceId, deviceSampleIds.size()); } else { - // 取前N张 - List limitedSamples = deviceSamples.stream() - .limit(limitPhoto) - .collect(Collectors.toList()); - - List limitedIds = limitedSamples.stream() - .map(FaceSampleEntity::getId) - .collect(Collectors.toList()); - - resultIds.addAll(limitedIds); - log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,最终{}张", - deviceId, limitPhoto, deviceSamples.size(), limitedIds.size()); + // 根据样本数量与限制的关系进行不同处理 + if (deviceSamples.size() > (limitPhoto + 2)) { + // 样本数大于(limit_photo+2)时,去掉首尾 + List limitedIds = processDeviceSamples(deviceSamples, limitPhoto, true); + resultIds.addAll(limitedIds); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,去首尾后最终{}张", + deviceId, limitPhoto, deviceSamples.size(), limitedIds.size()); + } else if (deviceSamples.size() > (limitPhoto + 1)) { + // 样本数大于(limit_photo+1)时,去掉尾部 + List limitedIds = processDeviceSamples(deviceSamples, limitPhoto, false); + resultIds.addAll(limitedIds); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,去尾部后最终{}张", + deviceId, limitPhoto, deviceSamples.size(), limitedIds.size()); + } else if (deviceSamples.size() > limitPhoto) { + // 样本数大于limit_photo但小于等于(limit_photo+1),取前N张 + List limitedIds = deviceSamples.stream() + .limit(limitPhoto) + .map(FaceSampleEntity::getId) + .toList(); + resultIds.addAll(limitedIds); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,取前{}张", + deviceId, limitPhoto, deviceSamples.size(), limitedIds.size()); + } else { + // 样本数小于等于limit_photo,不做操作 + List limitedIds = deviceSamples.stream() + .map(FaceSampleEntity::getId) + .toList(); + resultIds.addAll(limitedIds); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,无需筛选,保留全部", + deviceId, limitPhoto, deviceSamples.size()); + } } } - log.info("设备照片数量限制筛选:原始样本数量={}, 筛选后数量={}", + log.info("设备照片数量限制筛选:原始样本数量={}, 筛选后数量={}", acceptedSampleIds.size(), resultIds.size()); - + return resultIds; } + + /** + * 处理设备样本,根据参数决定是否去掉首尾 + * + * @param deviceSamples 设备样本列表 + * @param limitPhoto 限制数量 + * @param removeBoth 是否去掉首尾,true去掉首尾,false只去掉尾部 + * @return 处理后的样本ID列表 + */ + private List processDeviceSamples(List deviceSamples, int limitPhoto, boolean removeBoth) { + // 创建原始排序的索引映射,用于后续恢复排序 + Map originalIndexMap = new HashMap<>(); + for (int i = 0; i < deviceSamples.size(); i++) { + originalIndexMap.put(deviceSamples.get(i).getId(), i); + } + + // 按创建时间排序 + List sortedByCreateTime = deviceSamples.stream() + .sorted(Comparator.comparing(FaceSampleEntity::getCreateAt)) + .toList(); + + // 根据参数决定去掉首尾还是只去掉尾部 + List filteredSamples; + if (removeBoth && sortedByCreateTime.size() > 2) { + // 去掉首尾 + filteredSamples = sortedByCreateTime.subList(1, sortedByCreateTime.size() - 1); + } else if (!removeBoth && sortedByCreateTime.size() > 1) { + // 只去掉尾部(最新的) + filteredSamples = sortedByCreateTime.subList(0, sortedByCreateTime.size() - 1); + } else { + // 样本数量不足,无法去掉 + filteredSamples = sortedByCreateTime; + } + + // 恢复原排序并取限制数量 + List finalSamples = filteredSamples.stream() + .sorted(Comparator.comparing(sample -> originalIndexMap.get(sample.getId()))) + .limit(limitPhoto) + .toList(); + + return finalSamples.stream() + .map(FaceSampleEntity::getId) + .toList(); + } }