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 b25a4fd5..1ccc896d 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 @@ -52,6 +52,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.HashSet; @@ -501,67 +503,78 @@ public class TaskFaceServiceImpl implements TaskFaceService { return Collections.emptyList(); } - Map usedCount = new HashMap<>(); - Map limitCache = new HashMap<>(); - List result = new ArrayList<>(); - + Map> deviceSamplesMap = new LinkedHashMap<>(); + Set passthroughSampleIds = new LinkedHashSet<>(); for (Long sampleId : acceptedSampleIds) { FaceSampleEntity sample = sampleMap.get(sampleId); - if (sample == null) { - result.add(sampleId); - continue; - } - Long deviceId = sample.getDeviceId(); - if (deviceId == null) { - result.add(sampleId); + if (sample == null || sample.getDeviceId() == null) { + passthroughSampleIds.add(sampleId); continue; } + deviceSamplesMap + .computeIfAbsent(sample.getDeviceId(), key -> new ArrayList<>()) + .add(sample); + } + + Map limitCache = new HashMap<>(); + Set retainedSampleIds = new LinkedHashSet<>(passthroughSampleIds); + + for (Map.Entry> entry : deviceSamplesMap.entrySet()) { + Long deviceId = entry.getKey(); + List deviceSamples = entry.getValue(); + List deviceSampleIds = deviceSamples.stream() + .map(FaceSampleEntity::getId) + .toList(); + Integer limitPhoto = limitCache.computeIfAbsent(deviceId, id -> { DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(id); return deviceConfig != null ? deviceConfig.getInteger("limit_photo") : null; }); + + List retainedForDevice; if (limitPhoto == null || limitPhoto <= 0) { - List deviceSampleIds = deviceSamples.stream() + retainedForDevice = deviceSampleIds; + log.debug("设备照片限制:设备ID={}, 无限制,保留{}张照片", deviceId, deviceSampleIds.size()); + } else if (deviceSamples.size() > (limitPhoto + 2)) { + retainedForDevice = processDeviceSamples(deviceSamples, limitPhoto, true); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,去首尾后最终{}张", + deviceId, limitPhoto, deviceSamples.size(), retainedForDevice.size()); + } else if (deviceSamples.size() > (limitPhoto + 1)) { + retainedForDevice = processDeviceSamples(deviceSamples, limitPhoto, false); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,去尾部后最终{}张", + deviceId, limitPhoto, deviceSamples.size(), retainedForDevice.size()); + } else if (deviceSamples.size() > limitPhoto) { + retainedForDevice = deviceSamples.stream() + .limit(limitPhoto) .map(FaceSampleEntity::getId) .toList(); - resultIds.addAll(deviceSampleIds); - log.debug("设备照片限制:设备ID={}, 无限制,保留{}张照片", - deviceId, deviceSampleIds.size()); + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,取前{}张", + deviceId, limitPhoto, deviceSamples.size(), retainedForDevice.size()); } else { - // 根据样本数量与限制的关系进行不同处理 - 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()); + retainedForDevice = deviceSampleIds; + log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,无需筛选,保留全部", + deviceId, limitPhoto, deviceSamples.size()); + } + + retainedSampleIds.addAll(retainedForDevice); + + if (trace != null) { + Set retainedSet = new HashSet<>(retainedForDevice); + for (Long sampleId : deviceSampleIds) { + if (!retainedSet.contains(sampleId)) { + trace.addReason(sampleId, FaceRecognitionFilterReason.DEVICE_PHOTO_LIMIT); + } } } } + List resultIds = new ArrayList<>(acceptedSampleIds.size()); + for (Long sampleId : acceptedSampleIds) { + if (retainedSampleIds.contains(sampleId)) { + resultIds.add(sampleId); + } + } + log.info("设备照片数量限制筛选:原始样本数量={}, 筛选后数量={}", acceptedSampleIds.size(), resultIds.size());