You've already forked FrameTour-BE
1
This commit is contained in:
@@ -173,9 +173,6 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
private BuyStatusProcessor buyStatusProcessor;
|
private BuyStatusProcessor buyStatusProcessor;
|
||||||
@Autowired
|
@Autowired
|
||||||
private VideoRecreationHandler videoRecreationHandler;
|
private VideoRecreationHandler videoRecreationHandler;
|
||||||
@Autowired
|
|
||||||
private FaceRecoveryStrategy faceRecoveryStrategy;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<PageInfo<FaceRespVO>> pageQuery(FaceReqQuery faceReqQuery) {
|
public ApiResponse<PageInfo<FaceRespVO>> pageQuery(FaceReqQuery faceReqQuery) {
|
||||||
PageHelper.startPage(faceReqQuery.getPageNum(),faceReqQuery.getPageSize());
|
PageHelper.startPage(faceReqQuery.getPageNum(),faceReqQuery.getPageSize());
|
||||||
@@ -287,11 +284,12 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
FaceRecognizeResp resp = new FaceRecognizeResp();
|
FaceRecognizeResp resp = new FaceRecognizeResp();
|
||||||
resp.setUrl(faceUrl);
|
resp.setUrl(faceUrl);
|
||||||
resp.setFaceId(newFaceId);
|
resp.setFaceId(newFaceId);
|
||||||
|
resp.setScenicId(scenicId);
|
||||||
matchFaceId(newFaceId, oldFaceId == null);
|
matchFaceId(newFaceId, oldFaceId == null);
|
||||||
|
|
||||||
// 异步执行自动添加打印
|
// 异步执行自动添加打印
|
||||||
Long finalFaceId = newFaceId;
|
Long finalFaceId = newFaceId;
|
||||||
Thread thread = new Thread(() -> autoAddPhotosToPreferPrint(finalFaceId), "auto-add-print-" + newFaceId);
|
Thread thread = new Thread(() -> printerService.autoAddPhotosToPreferPrint(finalFaceId), "auto-add-print-" + newFaceId);
|
||||||
thread.start();
|
thread.start();
|
||||||
if (org.apache.commons.lang3.Strings.CI.equals("print", scene)) {
|
if (org.apache.commons.lang3.Strings.CI.equals("print", scene)) {
|
||||||
try {
|
try {
|
||||||
@@ -1149,114 +1147,4 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 自动将人脸关联的照片添加到优先打印列表
|
|
||||||
* 根据景区和设备配置自动添加type=2的照片到用户打印列表
|
|
||||||
*
|
|
||||||
* @param faceId 人脸ID
|
|
||||||
*/
|
|
||||||
private void autoAddPhotosToPreferPrint(Long faceId) {
|
|
||||||
try {
|
|
||||||
// 1. 获取人脸信息
|
|
||||||
FaceEntity face = faceRepository.getFace(faceId);
|
|
||||||
if (face == null) {
|
|
||||||
log.warn("人脸不存在,无法自动添加打印: faceId={}", faceId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Long scenicId = face.getScenicId();
|
|
||||||
Long memberId = face.getMemberId();
|
|
||||||
|
|
||||||
// 2. 获取景区配置
|
|
||||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
|
||||||
if (scenicConfig == null) {
|
|
||||||
log.warn("景区配置不存在,跳过自动添加打印: scenicId={}", scenicId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 检查景区是否启用打印功能
|
|
||||||
Boolean printEnable = scenicConfig.getBoolean("print_enable");
|
|
||||||
if (printEnable == null || !printEnable) {
|
|
||||||
log.debug("景区未启用打印功能,跳过自动添加: scenicId={}", scenicId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 查询该faceId关联的所有type=2的照片
|
|
||||||
List<SourceEntity> imageSources = sourceMapper.listImageSourcesByFaceId(faceId);
|
|
||||||
if (imageSources == null || imageSources.isEmpty()) {
|
|
||||||
log.debug("该人脸没有关联的照片,跳过自动添加: faceId={}", faceId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 按照deviceId分组处理
|
|
||||||
Map<Long, List<SourceEntity>> sourcesByDevice = imageSources.stream()
|
|
||||||
.filter(source -> source.getDeviceId() != null)
|
|
||||||
.collect(Collectors.groupingBy(SourceEntity::getDeviceId));
|
|
||||||
|
|
||||||
int totalAdded = 0;
|
|
||||||
for (Map.Entry<Long, List<SourceEntity>> entry : sourcesByDevice.entrySet()) {
|
|
||||||
Long deviceId = entry.getKey();
|
|
||||||
List<SourceEntity> deviceSources = entry.getValue();
|
|
||||||
|
|
||||||
// 6. 获取设备配置
|
|
||||||
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(deviceId);
|
|
||||||
if (deviceConfig == null) {
|
|
||||||
log.debug("设备配置不存在,跳过该设备: deviceId={}", deviceId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. 检查是否启用优先打印
|
|
||||||
Boolean preferPrintEnable = deviceConfig.getBoolean("prefer_print_enable");
|
|
||||||
if (preferPrintEnable == null || !preferPrintEnable) {
|
|
||||||
log.debug("设备未启用优先打印,跳过: deviceId={}", deviceId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 获取优先打印数量配置
|
|
||||||
Integer preferPrintCount = deviceConfig.getInteger("prefer_print_count");
|
|
||||||
if (preferPrintCount == null) {
|
|
||||||
log.debug("设备未配置优先打印数量,跳过: deviceId={}", deviceId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 9. 根据配置添加照片到打印列表
|
|
||||||
List<SourceEntity> sourcesToAdd;
|
|
||||||
if (preferPrintCount > 0) {
|
|
||||||
// 如果大于0,按照数量限制添加
|
|
||||||
sourcesToAdd = deviceSources.stream()
|
|
||||||
.limit(preferPrintCount)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
log.info("设备{}配置优先打印{}张,实际添加{}张",
|
|
||||||
deviceId, preferPrintCount, sourcesToAdd.size());
|
|
||||||
} else {
|
|
||||||
// 如果小于等于0,添加该设备的所有照片
|
|
||||||
sourcesToAdd = deviceSources;
|
|
||||||
log.info("设备{}配置优先打印所有照片,实际添加{}张",
|
|
||||||
deviceId, sourcesToAdd.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10. 批量添加到打印列表
|
|
||||||
for (SourceEntity source : sourcesToAdd) {
|
|
||||||
try {
|
|
||||||
printerService.addUserPhoto(memberId, scenicId, source.getUrl(), faceId);
|
|
||||||
totalAdded++;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("添加照片到打印列表失败: sourceId={}, url={}, error={}",
|
|
||||||
source.getId(), source.getUrl(), e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalAdded > 0) {
|
|
||||||
log.info("自动添加打印完成: faceId={}, 成功添加{}张照片", faceId, totalAdded);
|
|
||||||
} else {
|
|
||||||
log.debug("自动添加打印完成: faceId={}, 无符合条件的照片", faceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 出现异常则放弃,不影响主流程
|
|
||||||
log.error("自动添加打印失败,已忽略: faceId={}", faceId, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,4 +57,6 @@ public interface PrinterService {
|
|||||||
void setUserIsBuyItem(Long memberId, Long id, Long orderId);
|
void setUserIsBuyItem(Long memberId, Long id, Long orderId);
|
||||||
|
|
||||||
Object useSample(Long userId, Long sampleId);
|
Object useSample(Long userId, Long sampleId);
|
||||||
|
|
||||||
|
void autoAddPhotosToPreferPrint(Long faceId);
|
||||||
}
|
}
|
||||||
@@ -2,12 +2,10 @@ package com.ycwl.basic.service.printer.impl;
|
|||||||
|
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import com.ycwl.basic.biz.OrderBiz;
|
import com.ycwl.basic.biz.OrderBiz;
|
||||||
import com.ycwl.basic.constant.FaceConstant;
|
|
||||||
import com.ycwl.basic.constant.NumberConstant;
|
import com.ycwl.basic.constant.NumberConstant;
|
||||||
import com.ycwl.basic.constant.StorageConstant;
|
import com.ycwl.basic.constant.StorageConstant;
|
||||||
import com.ycwl.basic.enums.OrderStateEnum;
|
import com.ycwl.basic.enums.OrderStateEnum;
|
||||||
import com.ycwl.basic.exception.BaseException;
|
import com.ycwl.basic.exception.BaseException;
|
||||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
|
||||||
import com.ycwl.basic.image.watermark.ImageWatermarkFactory;
|
import com.ycwl.basic.image.watermark.ImageWatermarkFactory;
|
||||||
import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
|
import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
|
||||||
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
||||||
@@ -46,7 +44,6 @@ import com.ycwl.basic.model.printer.req.FromSourceReq;
|
|||||||
import com.ycwl.basic.model.printer.req.PrinterSyncReq;
|
import com.ycwl.basic.model.printer.req.PrinterSyncReq;
|
||||||
import com.ycwl.basic.model.printer.req.WorkerAuthReqVo;
|
import com.ycwl.basic.model.printer.req.WorkerAuthReqVo;
|
||||||
import com.ycwl.basic.model.printer.resp.PrintTaskResp;
|
import com.ycwl.basic.model.printer.resp.PrintTaskResp;
|
||||||
import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
|
|
||||||
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
|
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
|
||||||
import com.ycwl.basic.repository.DeviceRepository;
|
import com.ycwl.basic.repository.DeviceRepository;
|
||||||
import com.ycwl.basic.repository.FaceRepository;
|
import com.ycwl.basic.repository.FaceRepository;
|
||||||
@@ -54,9 +51,7 @@ import com.ycwl.basic.repository.OrderRepository;
|
|||||||
import com.ycwl.basic.repository.ScenicRepository;
|
import com.ycwl.basic.repository.ScenicRepository;
|
||||||
import com.ycwl.basic.service.mobile.WxPayService;
|
import com.ycwl.basic.service.mobile.WxPayService;
|
||||||
import com.ycwl.basic.service.pc.FaceService;
|
import com.ycwl.basic.service.pc.FaceService;
|
||||||
import com.ycwl.basic.service.pc.ScenicService;
|
|
||||||
import com.ycwl.basic.service.printer.PrinterService;
|
import com.ycwl.basic.service.printer.PrinterService;
|
||||||
import com.ycwl.basic.service.task.TaskFaceService;
|
|
||||||
import com.ycwl.basic.storage.StorageFactory;
|
import com.ycwl.basic.storage.StorageFactory;
|
||||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||||
import com.ycwl.basic.storage.enums.StorageAcl;
|
import com.ycwl.basic.storage.enums.StorageAcl;
|
||||||
@@ -83,15 +78,16 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class PrinterServiceImpl implements PrinterService {
|
public class PrinterServiceImpl implements PrinterService {
|
||||||
@@ -128,6 +124,11 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DeviceRepository deviceRepository;
|
private DeviceRepository deviceRepository;
|
||||||
|
|
||||||
|
// 用于优先打印的线程池,核心线程数根据实际情况调整
|
||||||
|
private final ExecutorService preferPrintExecutor = Executors.newFixedThreadPool(
|
||||||
|
Runtime.getRuntime().availableProcessors() * 2
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PrinterResp> listByScenicId(Long scenicId) {
|
public List<PrinterResp> listByScenicId(Long scenicId) {
|
||||||
return printerMapper.listByScenicId(scenicId);
|
return printerMapper.listByScenicId(scenicId);
|
||||||
@@ -813,7 +814,8 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
*
|
*
|
||||||
* @param faceId 人脸ID
|
* @param faceId 人脸ID
|
||||||
*/
|
*/
|
||||||
private void autoAddPhotosToPreferPrint(Long faceId) {
|
@Override
|
||||||
|
public void autoAddPhotosToPreferPrint(Long faceId) {
|
||||||
try {
|
try {
|
||||||
// 1. 获取人脸信息
|
// 1. 获取人脸信息
|
||||||
FaceEntity face = faceRepository.getFace(faceId);
|
FaceEntity face = faceRepository.getFace(faceId);
|
||||||
@@ -851,30 +853,38 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
.filter(source -> source.getDeviceId() != null)
|
.filter(source -> source.getDeviceId() != null)
|
||||||
.collect(Collectors.groupingBy(SourceEntity::getDeviceId));
|
.collect(Collectors.groupingBy(SourceEntity::getDeviceId));
|
||||||
|
|
||||||
int totalAdded = 0;
|
// 使用原子计数器统计成功添加的数量
|
||||||
|
AtomicInteger totalAdded = new AtomicInteger(0);
|
||||||
|
|
||||||
|
// 创建异步任务列表
|
||||||
|
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<Long, List<SourceEntity>> entry : sourcesByDevice.entrySet()) {
|
for (Map.Entry<Long, List<SourceEntity>> entry : sourcesByDevice.entrySet()) {
|
||||||
Long deviceId = entry.getKey();
|
Long deviceId = entry.getKey();
|
||||||
List<SourceEntity> deviceSources = entry.getValue();
|
List<SourceEntity> deviceSources = entry.getValue();
|
||||||
|
|
||||||
|
// 为每个设备创建一个异步任务
|
||||||
|
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
// 6. 获取设备配置
|
// 6. 获取设备配置
|
||||||
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(deviceId);
|
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(deviceId);
|
||||||
if (deviceConfig == null) {
|
if (deviceConfig == null) {
|
||||||
log.debug("设备配置不存在,跳过该设备: deviceId={}", deviceId);
|
log.debug("设备配置不存在,跳过该设备: deviceId={}", deviceId);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 检查是否启用优先打印
|
// 7. 检查是否启用优先打印
|
||||||
Boolean preferPrintEnable = deviceConfig.getBoolean("prefer_print_enable");
|
Boolean preferPrintEnable = deviceConfig.getBoolean("prefer_print_enable");
|
||||||
if (preferPrintEnable == null || !preferPrintEnable) {
|
if (preferPrintEnable == null || !preferPrintEnable) {
|
||||||
log.debug("设备未启用优先打印,跳过: deviceId={}", deviceId);
|
log.debug("设备未启用优先打印,跳过: deviceId={}", deviceId);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. 获取优先打印数量配置
|
// 8. 获取优先打印数量配置
|
||||||
Integer preferPrintCount = deviceConfig.getInteger("prefer_print_count");
|
Integer preferPrintCount = deviceConfig.getInteger("prefer_print_count");
|
||||||
if (preferPrintCount == null) {
|
if (preferPrintCount == null) {
|
||||||
log.debug("设备未配置优先打印数量,跳过: deviceId={}", deviceId);
|
log.debug("设备未配置优先打印数量,跳过: deviceId={}", deviceId);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. 根据配置添加照片到打印列表
|
// 9. 根据配置添加照片到打印列表
|
||||||
@@ -894,19 +904,37 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 10. 批量添加到打印列表
|
// 10. 批量添加到打印列表
|
||||||
|
int deviceAdded = 0;
|
||||||
for (SourceEntity source : sourcesToAdd) {
|
for (SourceEntity source : sourcesToAdd) {
|
||||||
try {
|
try {
|
||||||
addUserPhoto(memberId, scenicId, source.getUrl(), faceId);
|
addUserPhoto(memberId, scenicId, source.getUrl(), faceId);
|
||||||
totalAdded++;
|
deviceAdded++;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("添加照片到打印列表失败: sourceId={}, url={}, error={}",
|
log.warn("添加照片到打印列表失败: sourceId={}, url={}, error={}",
|
||||||
source.getId(), source.getUrl(), e.getMessage());
|
source.getId(), source.getUrl(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 累加成功添加的数量
|
||||||
|
totalAdded.addAndGet(deviceAdded);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理设备{}的照片添加任务失败: deviceId={}", deviceId, deviceId, e);
|
||||||
|
}
|
||||||
|
}, preferPrintExecutor);
|
||||||
|
|
||||||
|
futures.add(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalAdded > 0) {
|
// 等待所有任务完成
|
||||||
log.info("自动添加打印完成: faceId={}, 成功添加{}张照片", faceId, totalAdded);
|
try {
|
||||||
|
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("等待照片添加任务完成时发生异常: faceId={}", faceId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalAdded.get() > 0) {
|
||||||
|
log.info("自动添加打印完成: faceId={}, 成功添加{}张照片", faceId, totalAdded.get());
|
||||||
} else {
|
} else {
|
||||||
log.debug("自动添加打印完成: faceId={}, 无符合条件的照片", faceId);
|
log.debug("自动添加打印完成: faceId={}, 无符合条件的照片", faceId);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user