You've already forked FrameTour-BE
feat(printer): 新增人脸绑定二维码生成功能
- 添加获取人脸绑定二维码接口,支持生成小程序二维码 - 实现二维码文件流输出及临时文件清理 - 修改人脸识别流程,保存人脸数据并返回faceId - 调整自动添加照片到打印列表逻辑,返回添加数量 - 更新响应模型,增加二维码URL字段 - 优化人脸匹配逻辑,使用memberRelationRepository查询关联照片 - 修复BCE适配器图片下载地址问题,去除内网地址替换逻辑
This commit is contained in:
@@ -3,7 +3,13 @@ package com.ycwl.basic.controller.printer;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||
import com.ycwl.basic.mapper.FaceMapper;
|
||||
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
||||
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
|
||||
import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
|
||||
import com.ycwl.basic.repository.MemberRelationRepository;
|
||||
import com.ycwl.basic.repository.SourceRepository;
|
||||
import com.ycwl.basic.service.printer.PrinterService;
|
||||
import com.ycwl.basic.service.task.TaskFaceService;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.annotation.IgnoreToken;
|
||||
@@ -23,6 +29,7 @@ import com.ycwl.basic.service.pc.FaceService;
|
||||
import com.ycwl.basic.service.pc.ScenicService;
|
||||
import com.ycwl.basic.storage.utils.StorageUtil;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import com.ycwl.basic.utils.WxMpUtil;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -55,8 +62,13 @@ public class PrinterTvController {
|
||||
private final ScenicRepository scenicRepository;
|
||||
private final FaceRepository faceRepository;
|
||||
private final TaskFaceService faceService;
|
||||
private final FaceService pcFaceService;
|
||||
private final ScenicService scenicService;
|
||||
private final SourceMapper sourceMapper;
|
||||
private final FaceMapper faceMapper;
|
||||
private final MemberRelationRepository memberRelationRepository;
|
||||
private final SourceRepository sourceRepository;
|
||||
private final PrinterService printerService;
|
||||
|
||||
/**
|
||||
* 获取景区列表
|
||||
@@ -118,6 +130,57 @@ public class PrinterTvController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取人脸绑定二维码
|
||||
* 生成小程序二维码,用于绑定人脸到用户账号
|
||||
*
|
||||
* @param faceId 人脸ID
|
||||
* @param response HTTP响应
|
||||
*/
|
||||
@GetMapping("/face/{faceId}/qrcode")
|
||||
public void getFaceQrcode(@PathVariable("faceId") Long faceId, HttpServletResponse response) throws Exception {
|
||||
File qrcode = new File("qrcode_face_" + faceId + ".jpg");
|
||||
try {
|
||||
FaceEntity face = faceRepository.getFace(faceId);
|
||||
if (face == null) {
|
||||
response.setStatus(404);
|
||||
return;
|
||||
}
|
||||
MpConfigEntity scenicMpConfig = scenicRepository.getScenicMpConfig(face.getScenicId());
|
||||
if (scenicMpConfig == null) {
|
||||
response.setStatus(500);
|
||||
return;
|
||||
}
|
||||
WxMpUtil.generateUnlimitedWXAQRCode(
|
||||
scenicMpConfig.getAppId(),
|
||||
scenicMpConfig.getAppSecret(),
|
||||
"pages/videoSynthesis/bind_face",
|
||||
faceId.toString(),
|
||||
qrcode
|
||||
);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("image/jpeg");
|
||||
response.setHeader("Content-Disposition", "inline; filename=\"" + qrcode.getName() + "\"");
|
||||
|
||||
// 将二维码文件写入响应输出流
|
||||
try (FileInputStream fis = new FileInputStream(qrcode);
|
||||
OutputStream os = response.getOutputStream()) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, bytesRead);
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
} finally {
|
||||
// 删除临时文件
|
||||
if (qrcode.exists()) {
|
||||
qrcode.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据人脸样本ID查询图像素材
|
||||
*
|
||||
@@ -154,35 +217,44 @@ public class PrinterTvController {
|
||||
String fileName = UUID.randomUUID() + "." + suffix;
|
||||
String faceUrl = adapter.uploadFile(file, filePath, fileName);
|
||||
|
||||
// 2. 获取景区人脸识别适配器
|
||||
IFaceBodyAdapter faceBodyAdapter = scenicService.getScenicFaceBodyAdapter(scenicId);
|
||||
// 2. 保存人脸数据到数据库
|
||||
Long faceId = SnowFlakeUtil.getLongId();
|
||||
FaceEntity faceEntity = new FaceEntity();
|
||||
faceEntity.setId(faceId);
|
||||
faceEntity.setScenicId(scenicId);
|
||||
faceEntity.setFaceUrl(faceUrl);
|
||||
faceEntity.setCreateAt(new Date());
|
||||
faceEntity.setMemberId(0L); // 打印机大屏端没有用户ID
|
||||
faceMapper.add(faceEntity);
|
||||
|
||||
// 3. 在景区人脸库中搜索(注意:这里使用scenicId作为数据库名,搜索的是景区内的人脸样本)
|
||||
SearchFaceRespVo searchResult = faceService.searchFace(
|
||||
faceBodyAdapter,
|
||||
String.valueOf(scenicId),
|
||||
faceUrl,
|
||||
"大屏端人脸识别"
|
||||
);
|
||||
pcFaceService.matchFaceId(faceId);
|
||||
|
||||
// 4. 查询匹配到的图像素材(type=2)
|
||||
// 4. 自动添加照片到打印列表
|
||||
int addedCount = printerService.autoAddPhotosToPreferPrint(faceId);
|
||||
|
||||
// 5. 查询匹配到的图像素材(type=2)
|
||||
List<SourceEntity> sources = new ArrayList<>();
|
||||
if (searchResult != null && searchResult.getSampleListIds() != null && !searchResult.getSampleListIds().isEmpty()) {
|
||||
// 遍历匹配到的人脸样本ID,查询对应的图像素材
|
||||
for (Long sampleId : searchResult.getSampleListIds()) {
|
||||
SourceEntity source = sourceMapper.getBySampleIdAndType(sampleId, 2);
|
||||
if (source != null) {
|
||||
sources.add(source);
|
||||
}
|
||||
List<MemberSourceEntity> memberSourceEntities = memberRelationRepository.listSourceByFaceRelation(faceId, 2);
|
||||
for (MemberSourceEntity memberSourceEntity : memberSourceEntities) {
|
||||
SourceEntity source = sourceRepository.getSource(memberSourceEntity.getSourceId());
|
||||
if (source != null) {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 构造响应
|
||||
// 6. 构造响应
|
||||
FaceRecognizeWithSourcesResp resp = new FaceRecognizeWithSourcesResp();
|
||||
resp.setUrl(faceUrl);
|
||||
resp.setFaceId(null); // 不保存人脸,所以没有faceId
|
||||
resp.setFaceId(faceId);
|
||||
resp.setScenicId(scenicId);
|
||||
resp.setSources(sources);
|
||||
// 只有当添加了照片时才返回二维码URL
|
||||
if (addedCount > 0) {
|
||||
resp.setQrcodeUrl("https://zhentuai.com/printer/v1/tv/face/" + faceId + "/qrcode");
|
||||
} else {
|
||||
resp.setQrcodeUrl(null);
|
||||
}
|
||||
|
||||
return ApiResponse.success(resp);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user