diff --git a/src/main/java/com/ycwl/basic/controller/printer/PrinterTvController.java b/src/main/java/com/ycwl/basic/controller/printer/PrinterTvController.java index 575fe967..98747bea 100644 --- a/src/main/java/com/ycwl/basic/controller/printer/PrinterTvController.java +++ b/src/main/java/com/ycwl/basic/controller/printer/PrinterTvController.java @@ -198,7 +198,7 @@ public class PrinterTvController { @RequestParam("file") MultipartFile file, @PathVariable Long scenicId) { // 复用 faceUpload 方法的去重逻辑 - // memberId=0L 表示打印机大屏用户,scene="print" 会触发自动添加打印逻辑并等待完成 + // memberId=0L 表示打印机大屏用户,scene="tv" 为试点场景:仅执行识别/补救/落库/建关系 FaceRecognizeResp resp = pcFaceService.faceUpload(file, scenicId, 0L, "tv"); return ApiResponse.success(resp); } diff --git a/src/main/java/com/ycwl/basic/face/pipeline/enums/FaceMatchingScene.java b/src/main/java/com/ycwl/basic/face/pipeline/enums/FaceMatchingScene.java index 78cea793..584ecf94 100644 --- a/src/main/java/com/ycwl/basic/face/pipeline/enums/FaceMatchingScene.java +++ b/src/main/java/com/ycwl/basic/face/pipeline/enums/FaceMatchingScene.java @@ -21,5 +21,11 @@ public enum FaceMatchingScene { * 仅识别 * 只执行人脸识别,不处理后续业务逻辑(源文件关联、任务创建等) */ - RECOGNITION_ONLY + RECOGNITION_ONLY, + + /** + * 打印机大屏识别试点 + * 仅执行:识别、补救、落库、建关系 + */ + PRINTER_TV_RECOGNIZE } diff --git a/src/main/java/com/ycwl/basic/face/pipeline/factory/FaceMatchingPipelineFactory.java b/src/main/java/com/ycwl/basic/face/pipeline/factory/FaceMatchingPipelineFactory.java index b1af037d..33c10927 100644 --- a/src/main/java/com/ycwl/basic/face/pipeline/factory/FaceMatchingPipelineFactory.java +++ b/src/main/java/com/ycwl/basic/face/pipeline/factory/FaceMatchingPipelineFactory.java @@ -71,6 +71,40 @@ public class FaceMatchingPipelineFactory { @Autowired private ScenicConfigFacade scenicConfigFacade; + /** + * 创建打印机大屏识别试点Pipeline + * 仅执行:识别、补救、落库、建关系 + * + * 说明: + * - “准备上下文”属于基础能力,默认包含 + * - “建关系”包含构建关联与持久化两步 + */ + public Pipeline createPrinterTvRecognizePipeline() { + PipelineBuilder builder = new PipelineBuilder<>("PrinterTvRecognize"); + + // 1. 准备上下文 + builder.addStage(prepareContextStage); + + // 2. 执行人脸识别 + builder.addStage(faceRecognitionStage); + + // 3. 人脸识别补救 + builder.addStage(faceRecoveryStage); + + // 4. 更新人脸结果(落库) + builder.addStage(updateFaceResultStage); + + // 5. 构建源文件关联(建关系) + builder.addStage(buildSourceRelationStage); + + // 6. 持久化关联关系(建关系) + builder.addStage(persistRelationsStage); + + log.debug("创建打印机大屏识别试点Pipeline: stageCount={}", builder.build().getStageCount()); + + return builder.build(); + } + /** * 创建自动人脸匹配Pipeline * @@ -219,6 +253,7 @@ public class FaceMatchingPipelineFactory { case AUTO_MATCHING -> createAutoMatchingPipeline(isNew); case CUSTOM_MATCHING -> createCustomMatchingPipeline(); case RECOGNITION_ONLY -> createRecognitionOnlyPipeline(); + case PRINTER_TV_RECOGNIZE -> createPrinterTvRecognizePipeline(); }; } diff --git a/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java index 624ba92e..99e17a78 100644 --- a/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java @@ -7,6 +7,9 @@ import com.ycwl.basic.biz.OrderBiz; import com.ycwl.basic.biz.TemplateBiz; import com.ycwl.basic.constant.BaseContextHandler; import com.ycwl.basic.exception.BaseException; +import com.ycwl.basic.face.pipeline.core.FaceMatchingContext; +import com.ycwl.basic.face.pipeline.enums.FaceMatchingScene; +import com.ycwl.basic.face.pipeline.factory.FaceMatchingPipelineFactory; import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter; import com.ycwl.basic.facebody.entity.SearchFaceResultItem; import com.ycwl.basic.mapper.FaceSampleMapper; @@ -85,6 +88,8 @@ import com.ycwl.basic.storage.adapters.IStorageAdapter; import com.ycwl.basic.storage.enums.StorageAcl; import com.ycwl.basic.storage.utils.StorageUtil; import com.ycwl.basic.utils.*; +import com.ycwl.basic.pipeline.core.Pipeline; +import com.ycwl.basic.pipeline.exception.PipelineException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Strings; @@ -119,6 +124,8 @@ import static com.ycwl.basic.constant.StorageConstant.USER_FACE; @Slf4j @Service public class FaceServiceImpl implements FaceService { + private static final String FACE_UPLOAD_SCENE_PRINTER_TV = "tv"; + @Autowired private FaceMapper faceMapper; @Autowired @@ -176,6 +183,8 @@ public class FaceServiceImpl implements FaceService { // 编排器 @Autowired private FaceMatchingOrchestrator faceMatchingOrchestrator; + @Autowired + private FaceMatchingPipelineFactory faceMatchingPipelineFactory; // 防重复服务 @Autowired @@ -311,7 +320,7 @@ public class FaceServiceImpl implements FaceService { resp.setUrl(faceUrl); resp.setFaceId(newFaceId); resp.setScenicId(scenicId); - matchFaceId(newFaceId, oldFaceId == null); + matchFaceId(newFaceId, oldFaceId == null, scene); // 异步执行自动添加打印 Long finalFaceId = newFaceId; @@ -368,9 +377,35 @@ public class FaceServiceImpl implements FaceService { } @Override public SearchFaceRespVo matchFaceId(Long faceId, boolean isNew, String scene) { + if (Strings.CI.equals(FACE_UPLOAD_SCENE_PRINTER_TV, scene)) { + return matchFaceIdForPrinterTv(faceId, isNew); + } return faceMatchingOrchestrator.orchestrateMatching(faceId, isNew, scene); } + private SearchFaceRespVo matchFaceIdForPrinterTv(Long faceId, boolean isNew) { + FaceMatchingContext context = FaceMatchingContext.builder() + .faceId(faceId) + .isNew(isNew) + .scene(FaceMatchingScene.PRINTER_TV_RECOGNIZE) + .build(); + + Pipeline pipeline = faceMatchingPipelineFactory.createPrinterTvRecognizePipeline(); + try { + boolean success = pipeline.execute(context); + if (!success) { + throw new BaseException("打印机大屏人脸识别失败"); + } + return context.getSearchResult(); + } catch (PipelineException e) { + Throwable rootCause = e.getCause(); + if (rootCause instanceof BaseException baseException) { + throw baseException; + } + throw new BaseException("打印机大屏人脸识别失败"); + } + } + /** * 更新人脸实体结果信息 * 仅用于 handleCustomFaceMatching 方法