You've already forked FrameTour-BE
refactor(face):优化人脸识别更新接口及样本展示逻辑
- 修改 updateRecognition 接口返回类型为 void,简化响应内容 - 移除 FaceRecognitionSampleVO 中冗余的字段(sourceType、faceUrl 等)- 删除与过滤原因相关的属性和处理逻辑 - 简化 buildSampleVO 方法参数及内部实现- 调整 resolveSourceUrl 方法中 URL 获取优先级 - 优化样本列表构建逻辑,提升性能与可读性
This commit is contained in:
@@ -111,10 +111,11 @@ public class AppFaceController {
|
||||
}
|
||||
|
||||
@PutMapping("/{faceId}/recognition")
|
||||
public ApiResponse<FaceRecognitionDetailVO> updateRecognition(@PathVariable Long faceId,
|
||||
public ApiResponse<?> updateRecognition(@PathVariable Long faceId,
|
||||
@RequestBody FaceRecognitionUpdateReq req) {
|
||||
req.setFaceId(faceId);
|
||||
return ApiResponse.success(faceService.updateRecognition(req));
|
||||
faceService.updateRecognition(req);
|
||||
return ApiResponse.success("OK");
|
||||
}
|
||||
|
||||
@GetMapping("/{faceId}/recognition/detail")
|
||||
|
||||
@@ -17,9 +17,7 @@ public class FaceRecognitionSampleVO {
|
||||
private Boolean accepted;
|
||||
|
||||
private Long sourceId;
|
||||
private Integer sourceType;
|
||||
private String sourceUrl;
|
||||
private String faceUrl;
|
||||
|
||||
private Long deviceId;
|
||||
private String deviceName;
|
||||
@@ -27,16 +25,4 @@ public class FaceRecognitionSampleVO {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date shotAt;
|
||||
|
||||
private Integer isFree;
|
||||
private Integer isBuy;
|
||||
|
||||
/**
|
||||
* 过滤原因列表,用于提示用户样本被过滤的原因。
|
||||
*/
|
||||
private List<FaceRecognitionFilterReason> filterReasons;
|
||||
|
||||
/**
|
||||
* 过滤原因的描述集合,方便前端直接展示。
|
||||
*/
|
||||
private List<String> filterReasonTexts;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public interface FaceService {
|
||||
|
||||
void matchCustomFaceId(Long faceId, List<Long> faceSampleIds);
|
||||
|
||||
FaceRecognitionDetailVO updateRecognition(FaceRecognitionUpdateReq req);
|
||||
void updateRecognition(FaceRecognitionUpdateReq req);
|
||||
|
||||
FaceRecognitionDetailVO getRecognitionDetail(Long faceId);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO;
|
||||
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
||||
import com.ycwl.basic.model.pc.face.enums.FaceRecognitionFilterReason;
|
||||
import com.ycwl.basic.model.mobile.face.FaceRecognitionUpdateReq;
|
||||
import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
|
||||
import com.ycwl.basic.model.mobile.face.FaceRecognitionDetailVO;
|
||||
@@ -80,7 +79,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -1264,7 +1262,7 @@ public class FaceServiceImpl implements FaceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaceRecognitionDetailVO updateRecognition(FaceRecognitionUpdateReq req) {
|
||||
public void updateRecognition(FaceRecognitionUpdateReq req) {
|
||||
if (req == null || req.getFaceId() == null) {
|
||||
throw new IllegalArgumentException("faceId 不能为空");
|
||||
}
|
||||
@@ -1308,8 +1306,6 @@ public class FaceServiceImpl implements FaceService {
|
||||
if (Strings.isNotBlank(req.getRemark())) {
|
||||
log.info("人脸识别人工调整备注:faceId={}, remark={}", faceId, req.getRemark());
|
||||
}
|
||||
|
||||
return getRecognitionDetail(faceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1363,52 +1359,12 @@ public class FaceServiceImpl implements FaceService {
|
||||
return detail;
|
||||
}
|
||||
|
||||
List<FaceSampleEntity> allSamples = faceSampleMapper.listByIds(allSampleIds);
|
||||
Map<Long, FaceSampleEntity> sampleEntityMap = allSamples.stream()
|
||||
.collect(Collectors.toMap(FaceSampleEntity::getId, Function.identity(), (a, b) -> a, LinkedHashMap::new));
|
||||
|
||||
List<SourceEntity> sourceEntities = sourceMapper.listBySampleIds(allSampleIds);
|
||||
Map<Long, SourceEntity> sourceBySampleId = sourceEntities.stream()
|
||||
.collect(Collectors.toMap(SourceEntity::getFaceSampleId, Function.identity(), (a, b) -> a, LinkedHashMap::new));
|
||||
Map<Long, SourceEntity> sourceById = sourceEntities.stream()
|
||||
.collect(Collectors.toMap(SourceEntity::getId, Function.identity(), (a, b) -> a));
|
||||
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(face.getScenicId());
|
||||
Float thresholdConfig = scenicConfig != null ? scenicConfig.getFloat("face_score_threshold") : null;
|
||||
float threshold = thresholdConfig != null ? thresholdConfig / 100F : 0F;
|
||||
|
||||
List<Long> initialAcceptedIds = allSampleIds.stream()
|
||||
.filter(id -> {
|
||||
SearchFaceResultItem item = itemBySampleId.get(id);
|
||||
return item != null && item.getScore() != null && item.getScore() > threshold;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<FaceSampleEntity> orderedSampleList = allSampleIds.stream()
|
||||
.map(sampleEntityMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
SampleFilterTrace filterTrace = faceService.applySampleFiltersWithTrace(initialAcceptedIds, orderedSampleList, scenicConfig);
|
||||
List<Long> systemAcceptedIds = filterTrace.getAcceptedSampleIds() == null
|
||||
? Collections.emptyList()
|
||||
: filterTrace.getAcceptedSampleIds();
|
||||
|
||||
Set<Long> initialAcceptedSet = new HashSet<>(initialAcceptedIds);
|
||||
for (Long sampleId : allSampleIds) {
|
||||
if (!initialAcceptedSet.contains(sampleId) && !systemAcceptedIds.contains(sampleId)) {
|
||||
filterTrace.addReason(sampleId, FaceRecognitionFilterReason.SCORE_BELOW_THRESHOLD);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Long> systemAcceptedSet = new HashSet<>(systemAcceptedIds);
|
||||
Set<Long> persistedAcceptedSet = new HashSet<>(persistedAcceptedIds);
|
||||
for (Long sampleId : systemAcceptedSet) {
|
||||
if (!persistedAcceptedSet.contains(sampleId)) {
|
||||
filterTrace.addReason(sampleId, FaceRecognitionFilterReason.MANUAL_REJECTED);
|
||||
}
|
||||
}
|
||||
|
||||
List<MemberSourceEntity> relations = new ArrayList<>();
|
||||
List<MemberSourceEntity> videoRelations = memberRelationRepository.listSourceByFaceRelation(faceId, 1);
|
||||
if (videoRelations != null) {
|
||||
@@ -1426,9 +1382,9 @@ public class FaceServiceImpl implements FaceService {
|
||||
}
|
||||
}
|
||||
|
||||
Map<Long, EnumSet<FaceRecognitionFilterReason>> reasonMap = filterTrace.getFilteredReasonMap();
|
||||
Map<Long, DeviceEntity> deviceCache = new HashMap<>();
|
||||
|
||||
Set<Long> persistedAcceptedSet = new LinkedHashSet<>(persistedAcceptedIds);
|
||||
List<Long> acceptedOrdered = new ArrayList<>();
|
||||
for (Long sampleId : allSampleIds) {
|
||||
if (persistedAcceptedSet.contains(sampleId)) {
|
||||
@@ -1446,32 +1402,25 @@ public class FaceServiceImpl implements FaceService {
|
||||
sampleId,
|
||||
true,
|
||||
itemBySampleId.get(sampleId),
|
||||
sampleEntityMap.get(sampleId),
|
||||
sourceBySampleId.get(sampleId),
|
||||
relationBySampleId.get(sampleId),
|
||||
deviceCache,
|
||||
Collections.emptyList()))
|
||||
deviceCache))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Set<Long> acceptedSet = new HashSet<>(acceptedOrdered);
|
||||
Set<Long> acceptedSet = new LinkedHashSet<>(acceptedOrdered);
|
||||
List<FaceRecognitionSampleVO> filteredSamples = new ArrayList<>();
|
||||
for (Long sampleId : allSampleIds) {
|
||||
if (acceptedSet.contains(sampleId)) {
|
||||
continue;
|
||||
}
|
||||
EnumSet<FaceRecognitionFilterReason> reasons = reasonMap.get(sampleId);
|
||||
List<FaceRecognitionFilterReason> reasonList = reasons == null
|
||||
? Collections.emptyList()
|
||||
: new ArrayList<>(reasons);
|
||||
filteredSamples.add(buildSampleVO(
|
||||
FaceRecognitionSampleVO sampleVO = buildSampleVO(
|
||||
sampleId,
|
||||
false,
|
||||
itemBySampleId.get(sampleId),
|
||||
sampleEntityMap.get(sampleId),
|
||||
sourceBySampleId.get(sampleId),
|
||||
relationBySampleId.get(sampleId),
|
||||
deviceCache,
|
||||
reasonList));
|
||||
deviceCache);
|
||||
if (sampleVO.getSourceId() != null) {
|
||||
filteredSamples.add(sampleVO);
|
||||
}
|
||||
}
|
||||
|
||||
detail.setAcceptedSamples(acceptedSamples);
|
||||
@@ -1508,44 +1457,26 @@ public class FaceServiceImpl implements FaceService {
|
||||
private FaceRecognitionSampleVO buildSampleVO(Long sampleId,
|
||||
boolean accepted,
|
||||
SearchFaceResultItem resultItem,
|
||||
FaceSampleEntity sampleEntity,
|
||||
SourceEntity sourceEntity,
|
||||
MemberSourceEntity relation,
|
||||
Map<Long, DeviceEntity> deviceCache,
|
||||
List<FaceRecognitionFilterReason> reasons) {
|
||||
Map<Long, DeviceEntity> deviceCache) {
|
||||
FaceRecognitionSampleVO vo = new FaceRecognitionSampleVO();
|
||||
vo.setSampleId(sampleId);
|
||||
vo.setAccepted(accepted);
|
||||
if (resultItem != null) {
|
||||
vo.setScore(resultItem.getScore());
|
||||
}
|
||||
if (sampleEntity != null) {
|
||||
vo.setFaceUrl(sampleEntity.getFaceUrl());
|
||||
vo.setDeviceId(sampleEntity.getDeviceId());
|
||||
vo.setShotAt(sampleEntity.getCreateAt());
|
||||
DeviceEntity device = getDeviceCached(sampleEntity.getDeviceId(), deviceCache);
|
||||
if (sourceEntity != null) {
|
||||
if (sourceEntity.getDeviceId() != null) {
|
||||
vo.setDeviceId(sourceEntity.getDeviceId());
|
||||
vo.setShotAt(sourceEntity.getCreateTime());
|
||||
DeviceEntity device = getDeviceCached(sourceEntity.getDeviceId(), deviceCache);
|
||||
if (device != null) {
|
||||
vo.setDeviceName(device.getName());
|
||||
}
|
||||
}
|
||||
if (sourceEntity != null) {
|
||||
vo.setSourceId(sourceEntity.getId());
|
||||
vo.setSourceType(sourceEntity.getType());
|
||||
vo.setSourceUrl(resolveSourceUrl(sourceEntity));
|
||||
}
|
||||
if (relation != null) {
|
||||
vo.setIsFree(relation.getIsFree());
|
||||
vo.setIsBuy(relation.getIsBuy());
|
||||
}
|
||||
if (reasons != null && !reasons.isEmpty()) {
|
||||
vo.setFilterReasons(new ArrayList<>(reasons));
|
||||
vo.setFilterReasonTexts(reasons.stream()
|
||||
.map(FaceRecognitionFilterReason::getDescription)
|
||||
.collect(Collectors.toList()));
|
||||
} else {
|
||||
vo.setFilterReasons(Collections.emptyList());
|
||||
vo.setFilterReasonTexts(Collections.emptyList());
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
@@ -1565,15 +1496,12 @@ public class FaceServiceImpl implements FaceService {
|
||||
if (sourceEntity == null) {
|
||||
return null;
|
||||
}
|
||||
if (!Strings.isBlank(sourceEntity.getUrl())) {
|
||||
return sourceEntity.getUrl();
|
||||
}
|
||||
if (!Strings.isBlank(sourceEntity.getVideoUrl())) {
|
||||
return sourceEntity.getVideoUrl();
|
||||
}
|
||||
if (!Strings.isBlank(sourceEntity.getThumbUrl())) {
|
||||
return sourceEntity.getThumbUrl();
|
||||
}
|
||||
if (!Strings.isBlank(sourceEntity.getUrl())) {
|
||||
return sourceEntity.getUrl();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user