You've already forked FrameTour-BE
feat(basic): 添加模板片段更新状态缓存支持
- 在FaceStatusManager中新增按模板ID区分的人脸片段更新状态缓存键 - 更新TaskTaskServiceImpl以设置模板渲染状态 - 在任务回调逻辑中增加对模板渲染状态的更新操作 - 修改任务删除逻辑为更新状态加10的临时解决方案 - 移除旧有的切割任务状态更新逻辑,统一使用模板渲染状态管理
This commit is contained in:
@@ -2,6 +2,11 @@ package com.ycwl.basic.service.mobile.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.ycwl.basic.biz.FaceStatusManager;
|
||||
import com.ycwl.basic.enums.FaceCutStatus;
|
||||
import com.ycwl.basic.enums.FacePieceUpdateStatus;
|
||||
import com.ycwl.basic.enums.TemplateRenderStatus;
|
||||
import com.ycwl.basic.enums.VideoTaskStatus;
|
||||
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
||||
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
|
||||
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
|
||||
@@ -10,7 +15,6 @@ import com.ycwl.basic.repository.OrderRepository;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import com.ycwl.basic.biz.CouponBiz;
|
||||
import com.ycwl.basic.biz.OrderBiz;
|
||||
import com.ycwl.basic.biz.TaskStatusBiz;
|
||||
import com.ycwl.basic.constant.StorageConstant;
|
||||
import com.ycwl.basic.image.watermark.ImageWatermarkFactory;
|
||||
import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
|
||||
@@ -31,7 +35,6 @@ import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
||||
import com.ycwl.basic.model.pc.source.entity.SourceWatermarkEntity;
|
||||
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
|
||||
import com.ycwl.basic.model.pc.source.resp.SourceRespVO;
|
||||
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
|
||||
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
|
||||
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
|
||||
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
|
||||
@@ -65,6 +68,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -93,8 +97,6 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
@Autowired
|
||||
private FaceRepository faceRepository;
|
||||
@Autowired
|
||||
private TaskStatusBiz taskStatusBiz;
|
||||
@Autowired
|
||||
private DeviceRepository deviceRepository;
|
||||
@Autowired
|
||||
private CouponBiz couponBiz;
|
||||
@@ -106,6 +108,8 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
private PrinterMapper printerMapper;
|
||||
@Autowired
|
||||
private OrderRepository orderRepository;
|
||||
@Autowired
|
||||
private FaceStatusManager faceStatusManager;
|
||||
|
||||
@Override
|
||||
public List<GoodsDetailVO> sourceGoodsList(GoodsReqQuery query) {
|
||||
@@ -258,83 +262,113 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户当前景区的视频合成任务状态
|
||||
* 查询用户人脸对应的视频合成任务状态
|
||||
*
|
||||
* @param faceId 景区id
|
||||
* @return 0没有任务 1 合成中 2 合成成功
|
||||
* <p>业务流程:
|
||||
* <ol>
|
||||
* <li>验证人脸是否存在</li>
|
||||
* <li>检查视频切片状态(CUTTING → 返回处理中)</li>
|
||||
* <li>遍历景区模板,检查渲染状态(RENDERING → 返回处理中)</li>
|
||||
* <li>统计已渲染完成的模板数量</li>
|
||||
* <li>根据切片状态返回最终结果:
|
||||
* <ul>
|
||||
* <li>WAITING_USER_SELECT → 处理中(等待用户选择模板)</li>
|
||||
* <li>COMPLETED → 成功(查询已完成的视频信息)</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @param faceId 人脸ID
|
||||
* @return 视频任务状态VO,包含状态码、已完成数量、视频信息等
|
||||
* <ul>
|
||||
* <li>status = -1: 人脸不存在</li>
|
||||
* <li>status = 2: 处理中(切片中/渲染中/等待选择)</li>
|
||||
* <li>status = 1: 成功(已有完成的视频)</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public VideoTaskStatusVO getTaskStatusByFaceId(Long faceId) {
|
||||
VideoTaskStatusVO response = new VideoTaskStatusVO();
|
||||
|
||||
// ==================== 第一步:验证人脸是否存在 ====================
|
||||
FaceEntity face = faceRepository.getFace(faceId);
|
||||
if (face == null) {
|
||||
response.setStatus(-1);
|
||||
// 人脸不存在,返回无效人脸状态
|
||||
response.setStatus(VideoTaskStatus.INVALID_FACE.getCode());
|
||||
return response;
|
||||
}
|
||||
Long userId = face.getMemberId();
|
||||
|
||||
// 设置基本信息
|
||||
response.setFaceId(faceId);
|
||||
response.setScenicId(face.getScenicId());
|
||||
int faceCutStatus = taskStatusBiz.getFaceCutStatus(faceId);
|
||||
response.setCutStatus(faceCutStatus);
|
||||
if (faceCutStatus == 0) {
|
||||
// 切视频中,也显示正在处理
|
||||
response.setStatus(2);
|
||||
return response;
|
||||
}
|
||||
List<MemberVideoEntity> taskList = videoMapper.listRelationByFace(faceId);
|
||||
if (faceCutStatus != 1 && taskList.isEmpty()) {
|
||||
// 视频切成了能够获取视频的状态,但是没有任务,还是显示正在处理
|
||||
response.setStatus(0);
|
||||
return response;
|
||||
}
|
||||
if (taskList.isEmpty()) {
|
||||
response.setStatus(0);
|
||||
|
||||
// ==================== 第二步:检查视频切片状态 ====================
|
||||
// 从缓存中获取切片状态(CUTTING/COMPLETED/WAITING_USER_SELECT)
|
||||
FaceCutStatus status = faceStatusManager.getFaceCutStatus(faceId);
|
||||
response.setCutStatus(status.getCode());
|
||||
|
||||
if (status == FaceCutStatus.CUTTING) {
|
||||
// 视频片段正在切割中,用户需要等待切片完成
|
||||
// 前端展示:「正在检索新的视频片段」
|
||||
response.setStatus(VideoTaskStatus.PROCESSING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
// ==================== 第三步:检查模板渲染状态 ====================
|
||||
// 获取该景区的所有视频模板
|
||||
List<TemplateRespVO> templateList = templateRepository.getTemplateListByScenicId(response.getScenicId());
|
||||
List<Long> templateIds = templateList.stream().map(TemplateRespVO::getId).collect(Collectors.toList());
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
|
||||
// 遍历所有模板,检查每个模板的渲染状态
|
||||
for (TemplateRespVO template : templateList) {
|
||||
// 从缓存中获取该人脸在该模板下的渲染状态
|
||||
TemplateRenderStatus renderStatus = faceStatusManager.getTemplateRenderStatus(faceId, template.getId());
|
||||
|
||||
if (renderStatus == TemplateRenderStatus.RENDERING) {
|
||||
// 发现有模板正在渲染中,立即返回处理中状态
|
||||
// 前端展示:「专属视频合成中」
|
||||
response.setTemplateId(template.getId());
|
||||
response.setCount(0);
|
||||
response.setStatus(VideoTaskStatus.PROCESSING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
if (renderStatus == TemplateRenderStatus.RENDERED) {
|
||||
// 统计已渲染完成的模板数量
|
||||
count.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
// 设置已完成数量和总模板数
|
||||
response.setCount(count.get());
|
||||
response.setMaxCount(templateList.size());
|
||||
List<MemberVideoEntity> notFinishedTasks = taskList.stream()
|
||||
.filter(task -> templateIds.contains(task.getTemplateId()))
|
||||
.filter(task -> {
|
||||
TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
|
||||
if (taskById == null) {
|
||||
return true;
|
||||
}
|
||||
return taskById.getStatus() == 0 || taskById.getStatus() == 2;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
long finishedTask = taskList.stream()
|
||||
.filter(task -> {
|
||||
TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
|
||||
if (taskById == null) {
|
||||
return false;
|
||||
}
|
||||
return taskById.getStatus() == 1;
|
||||
})
|
||||
.map(MemberVideoEntity::getTemplateId)
|
||||
.distinct()
|
||||
.count();
|
||||
response.setCount(finishedTask);
|
||||
if (!notFinishedTasks.isEmpty()) {
|
||||
response.setTemplateId(notFinishedTasks.getFirst().getTemplateId());
|
||||
response.setTaskId(notFinishedTasks.getFirst().getTaskId());
|
||||
response.setStatus(2);
|
||||
|
||||
// ==================== 第四步:根据切片完成状态返回结果 ====================
|
||||
|
||||
if (status == FaceCutStatus.WAITING_USER_SELECT) {
|
||||
// 切片已完成,但景区配置了 face_select_first=true
|
||||
// 需要等待用户手动选择模板后才开始渲染
|
||||
// 前端展示:「专属视频合成中」
|
||||
response.setStatus(VideoTaskStatus.PROCESSING.getCode());
|
||||
return response;
|
||||
}
|
||||
// 重查一下
|
||||
taskList = videoMapper.listRelationByFace(faceId);
|
||||
MemberVideoEntity lastVideo = taskList.getLast();
|
||||
if (null == lastVideo.getVideoId()) {
|
||||
response.setTemplateId(lastVideo.getTemplateId());
|
||||
response.setTaskId(lastVideo.getTaskId());
|
||||
response.setStatus(2);
|
||||
|
||||
if (status == FaceCutStatus.COMPLETED) {
|
||||
// 切片已完成,查询该人脸关联的视频信息
|
||||
List<MemberVideoEntity> taskList = videoMapper.listRelationByFace(faceId);
|
||||
|
||||
// 设置最新的视频信息(取最后一个)
|
||||
response.setTaskId(taskList.getLast().getTaskId());
|
||||
response.setTemplateId(taskList.getLast().getTemplateId());
|
||||
response.setVideoId(taskList.getLast().getVideoId());
|
||||
|
||||
// 返回成功状态
|
||||
// 前端展示:「AI已为您合成{count}个视频」
|
||||
response.setStatus(VideoTaskStatus.SUCCESS.getCode());
|
||||
return response;
|
||||
}
|
||||
response.setTaskId(lastVideo.getTaskId());
|
||||
response.setTemplateId(lastVideo.getTemplateId());
|
||||
response.setVideoId(lastVideo.getVideoId());
|
||||
response.setStatus(1);
|
||||
|
||||
// 兜底返回(理论上不应该走到这里)
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -344,72 +378,109 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
return getTaskStatusByFaceId(lastFaceByUserId.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定人脸和模板的视频合成任务状态
|
||||
*
|
||||
* <p>业务流程:
|
||||
* <ol>
|
||||
* <li>验证人脸是否存在</li>
|
||||
* <li>检查视频切片状态(CUTTING → 返回处理中)</li>
|
||||
* <li>检查指定模板的渲染状态(RENDERING → 返回处理中)</li>
|
||||
* <li>检查是否等待用户选择(WAITING_USER_SELECT → 返回处理中)</li>
|
||||
* <li>查询该模板对应的视频信息并返回成功状态</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param faceId 人脸ID
|
||||
* @param templateId 模板ID
|
||||
* @return 视频任务状态VO,包含该模板的状态信息
|
||||
* <ul>
|
||||
* <li>status = -1: 人脸不存在</li>
|
||||
* <li>status = 0: 待制作(无任务记录)</li>
|
||||
* <li>status = 2: 处理中(切片中/渲染中/等待选择)</li>
|
||||
* <li>status = 1: 成功(该模板视频已完成)</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public VideoTaskStatusVO getTaskStatusByTemplateId(Long faceId, Long templateId) {
|
||||
List<MemberVideoEntity> taskList = videoMapper.listRelationByFaceAndTemplate(faceId, templateId);
|
||||
VideoTaskStatusVO response = new VideoTaskStatusVO();
|
||||
response.setFaceId(faceId);
|
||||
response.setTemplateId(templateId);
|
||||
if (taskList.isEmpty()) {
|
||||
response.setStatus(0);
|
||||
|
||||
// ==================== 第一步:验证人脸是否存在 ====================
|
||||
FaceEntity face = faceRepository.getFace(faceId);
|
||||
if (face == null) {
|
||||
// 人脸不存在,返回无效人脸状态
|
||||
response.setStatus(VideoTaskStatus.INVALID_FACE.getCode());
|
||||
return response;
|
||||
}
|
||||
response.setScenicId(taskList.getFirst().getScenicId());
|
||||
response.setMaxCount(templateRepository.getTemplateListByScenicId(response.getScenicId()).size());
|
||||
List<MemberVideoEntity> notFinishedTasks = taskList.stream()
|
||||
.filter(task -> {
|
||||
TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
|
||||
if (taskById == null) {
|
||||
return true;
|
||||
}
|
||||
return taskById.getStatus() == 0 || taskById.getStatus() == 2;
|
||||
}).collect(Collectors.toList());
|
||||
long finishedTask = taskList.stream()
|
||||
.filter(task -> {
|
||||
TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
|
||||
if (taskById == null) {
|
||||
return false;
|
||||
}
|
||||
return taskById.getStatus() == 1;
|
||||
}).count();
|
||||
response.setCount(finishedTask);
|
||||
int faceCutStatus = taskStatusBiz.getFaceCutStatus(faceId);
|
||||
if (Integer.valueOf(0).equals(faceCutStatus)) {
|
||||
if (!notFinishedTasks.isEmpty()) {
|
||||
response.setTemplateId(notFinishedTasks.getFirst().getTemplateId());
|
||||
|
||||
// 设置景区信息
|
||||
response.setScenicId(face.getScenicId());
|
||||
|
||||
// ==================== 第二步:检查视频切片状态 ====================
|
||||
// 从缓存中获取切片状态
|
||||
FaceCutStatus cutStatus = faceStatusManager.getFaceCutStatus(faceId);
|
||||
response.setCutStatus(cutStatus.getCode());
|
||||
|
||||
if (cutStatus == FaceCutStatus.CUTTING) {
|
||||
// 视频片段正在切割中,无法生成任何视频
|
||||
// 前端展示:「正在检索新的视频片段」
|
||||
response.setStatus(VideoTaskStatus.PROCESSING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
// ==================== 第三步:检查指定模板的渲染状态 ====================
|
||||
// 从缓存中获取该人脸在该模板下的渲染状态
|
||||
TemplateRenderStatus renderStatus = faceStatusManager.getTemplateRenderStatus(faceId, templateId);
|
||||
|
||||
if (renderStatus == TemplateRenderStatus.RENDERING) {
|
||||
// 该模板正在渲染中
|
||||
// 前端展示:「专属视频合成中」
|
||||
response.setStatus(VideoTaskStatus.PROCESSING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
if (renderStatus == TemplateRenderStatus.NONE) {
|
||||
// 该模板从未开始渲染
|
||||
// 可能是用户还没选择该模板,或系统还未开始处理
|
||||
response.setStatus(VideoTaskStatus.PENDING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
// ==================== 第四步:检查是否等待用户选择 ====================
|
||||
if (cutStatus == FaceCutStatus.WAITING_USER_SELECT && renderStatus != TemplateRenderStatus.RENDERED) {
|
||||
// 切片已完成,但需要等待用户手动选择模板
|
||||
// 前端展示:「专属视频合成中」
|
||||
response.setStatus(VideoTaskStatus.PROCESSING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
// ==================== 第五步:查询已完成的视频信息 ====================
|
||||
if (renderStatus == TemplateRenderStatus.RENDERED) {
|
||||
// 该模板已渲染完成,查询对应的视频信息
|
||||
List<MemberVideoEntity> taskList = videoMapper.listRelationByFaceAndTemplate(faceId, templateId);
|
||||
|
||||
if (taskList.isEmpty()) {
|
||||
// 理论上不应该出现:渲染完成但无视频记录
|
||||
// 可能是数据不一致,返回待制作状态
|
||||
response.setStatus(VideoTaskStatus.PENDING.getCode());
|
||||
return response;
|
||||
}
|
||||
response.setStatus(2);
|
||||
return response;
|
||||
}
|
||||
if (!notFinishedTasks.isEmpty()) {
|
||||
response.setTemplateId(notFinishedTasks.getFirst().getTemplateId());
|
||||
response.setTaskId(notFinishedTasks.getFirst().getTaskId());
|
||||
response.setStatus(2);
|
||||
return response;
|
||||
}
|
||||
MemberVideoEntity lastVideo = taskList.getLast();
|
||||
response.setTaskId(lastVideo.getTaskId());
|
||||
response.setTemplateId(lastVideo.getTemplateId());
|
||||
response.setVideoId(lastVideo.getVideoId());
|
||||
if (null != lastVideo.getVideoId()) {
|
||||
response.setStatus(1);
|
||||
|
||||
// 获取最新的视频记录(取最后一个)
|
||||
MemberVideoEntity lastVideo = taskList.getLast();
|
||||
response.setTaskId(lastVideo.getTaskId());
|
||||
response.setVideoId(lastVideo.getVideoId());
|
||||
} else {
|
||||
TaskEntity taskById = videoTaskRepository.getTaskById(lastVideo.getTaskId());
|
||||
if (taskById == null) {
|
||||
response.setStatus(1);
|
||||
} else {
|
||||
videoTaskRepository.clearTaskCache(lastVideo.getTaskId());
|
||||
if (taskById.getStatus() == 1) {
|
||||
response.setStatus(1);
|
||||
response.setVideoId(lastVideo.getVideoId());
|
||||
} else if (taskById.getStatus() == 0 || taskById.getStatus() == 2) {
|
||||
response.setStatus(2);
|
||||
} else {
|
||||
response.setStatus(1);
|
||||
}
|
||||
}
|
||||
response.setCount(1); // 该模板已完成1个视频
|
||||
|
||||
// 返回成功状态
|
||||
// 前端展示:「AI已为您合成视频」
|
||||
response.setStatus(VideoTaskStatus.SUCCESS.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
// 兜底:默认返回待制作状态
|
||||
response.setStatus(VideoTaskStatus.PENDING.getCode());
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -718,6 +789,13 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
return result;
|
||||
}
|
||||
|
||||
FacePieceUpdateStatus updateStatus = faceStatusManager.getFacePieceUpdateStatus(video.getFaceId(), video.getTemplateId());
|
||||
if (updateStatus == FacePieceUpdateStatus.NO_NEW_PIECES) {
|
||||
log.info("无新片段: faceId={}, templateId={}", video.getFaceId(), video.getTemplateId());
|
||||
result.setCanUpdate(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
Long taskId = video.getTaskId();
|
||||
if (taskId == null) {
|
||||
log.error("视频没有关联任务: videoId={}", videoId);
|
||||
@@ -730,6 +808,9 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
result.setTemplateId(video.getTemplateId());
|
||||
|
||||
TaskUpdateResult taskResult = videoTaskRepository.checkTaskUpdate(taskId);
|
||||
if (!taskResult.isCanUpdate()) {
|
||||
faceStatusManager.markNoNewPieces(video.getFaceId(), video.getTemplateId());
|
||||
}
|
||||
result.setCanUpdate(taskResult.isCanUpdate());
|
||||
result.setNewSegmentCount(taskResult.getNewSegmentCount());
|
||||
result.setTotalSegmentCount(taskResult.getTotalSegmentCount());
|
||||
|
||||
@@ -466,7 +466,7 @@ public class FaceServiceImpl implements FaceService {
|
||||
contentPageVO.setLockType(0);
|
||||
} else if (taskById.getStatus() == 3) {
|
||||
contentPageVO.setLockType(2);
|
||||
} else {
|
||||
} else if (taskById.getStatus() == 0 || taskById.getStatus() == 2) {
|
||||
contentPageVO.setLockType(-9); // 正在生成
|
||||
}
|
||||
contentPageVO.setContentType(0);
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
package com.ycwl.basic.service.pc.orchestrator;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.ycwl.basic.biz.TaskStatusBiz;
|
||||
import com.ycwl.basic.biz.FaceStatusManager;
|
||||
import com.ycwl.basic.enums.FaceCutStatus;
|
||||
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
|
||||
import com.ycwl.basic.puzzle.dto.PuzzleGenerateRequest;
|
||||
import com.ycwl.basic.puzzle.dto.PuzzleGenerateResponse;
|
||||
import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO;
|
||||
import com.ycwl.basic.puzzle.entity.PuzzleGenerationRecordEntity;
|
||||
import com.ycwl.basic.puzzle.mapper.PuzzleGenerationRecordMapper;
|
||||
import com.ycwl.basic.puzzle.service.IPuzzleGenerateService;
|
||||
import com.ycwl.basic.puzzle.service.IPuzzleTemplateService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ycwl.basic.biz.OrderBiz;
|
||||
import com.ycwl.basic.exception.BaseException;
|
||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
||||
@@ -99,9 +97,9 @@ public class FaceMatchingOrchestrator {
|
||||
@Autowired
|
||||
private IPuzzleGenerateService puzzleGenerateService;
|
||||
@Autowired
|
||||
private TaskStatusBiz taskStatusBiz;
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
@Autowired
|
||||
private FaceStatusManager faceStatusManager;
|
||||
|
||||
/**
|
||||
* 编排人脸匹配的完整流程
|
||||
@@ -117,7 +115,7 @@ public class FaceMatchingOrchestrator {
|
||||
|
||||
if (isNew) {
|
||||
// 新用户,设置任务状态为待处理
|
||||
taskStatusBiz.setFaceCutStatus(faceId, 0);
|
||||
faceStatusManager.setFaceCutStatus(faceId, FaceCutStatus.CUTTING);
|
||||
}
|
||||
|
||||
// 步骤1: 数据准备
|
||||
@@ -349,7 +347,7 @@ public class FaceMatchingOrchestrator {
|
||||
taskService.autoCreateTaskByFaceId(faceId);
|
||||
} else {
|
||||
log.debug("景区配置 face_select_first=true,跳过自动创建任务:faceId={}", faceId);
|
||||
taskStatusBiz.setFaceCutStatus(faceId, 2);
|
||||
faceStatusManager.setFaceCutStatus(faceId, FaceCutStatus.WAITING_USER_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@ package com.ycwl.basic.service.task.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.ycwl.basic.biz.FaceStatusManager;
|
||||
import com.ycwl.basic.enums.FaceCutStatus;
|
||||
import com.ycwl.basic.enums.TemplateRenderStatus;
|
||||
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
|
||||
import com.ycwl.basic.integration.common.manager.RenderWorkerConfigManager;
|
||||
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
||||
@@ -11,7 +14,6 @@ import com.ycwl.basic.repository.MemberRelationRepository;
|
||||
import com.ycwl.basic.repository.SourceRepository;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import com.ycwl.basic.biz.OrderBiz;
|
||||
import com.ycwl.basic.biz.TaskStatusBiz;
|
||||
import com.ycwl.basic.biz.TemplateBiz;
|
||||
import com.ycwl.basic.constant.StorageConstant;
|
||||
import com.ycwl.basic.mapper.FaceMapper;
|
||||
@@ -116,8 +118,6 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
@Autowired
|
||||
private TaskStatusBiz taskStatusBiz;
|
||||
@Autowired
|
||||
private DeviceRepository deviceRepository;
|
||||
@Autowired
|
||||
private VideoReUploader videoReUploader;
|
||||
@@ -131,6 +131,8 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
private ZtMessageProducerService ztMessageProducerService;
|
||||
@Autowired
|
||||
private NotificationAuthUtils notificationAuthUtils;
|
||||
@Autowired
|
||||
private FaceStatusManager faceStatusManager;
|
||||
|
||||
private RenderWorkerEntity getWorker(@NonNull WorkerAuthReqVo req) {
|
||||
String accessKey = req.getAccessKey();
|
||||
@@ -295,7 +297,6 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
task.templateId = null;
|
||||
task.memberId = faceRespVO.getMemberId();
|
||||
task.callback = () -> {
|
||||
log.info("task callback: {}", task);
|
||||
};
|
||||
VideoPieceGetter.addTask(task);
|
||||
return;
|
||||
@@ -340,9 +341,9 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
if (!forceCreate) {
|
||||
if (templateBiz.determineTemplateCanGenerate(templateId, faceId, false)) {
|
||||
// 临时写死,当自动生成视频,切片也算合成中,并更新状态
|
||||
taskStatusBiz.setFaceCutStatus(face.getId(), 0);
|
||||
faceStatusManager.setFaceCutStatus(face.getId(), FaceCutStatus.CUTTING);
|
||||
} else {
|
||||
taskStatusBiz.setFaceCutStatus(face.getId(), 2);
|
||||
faceStatusManager.setFaceCutStatus(face.getId(), FaceCutStatus.WAITING_USER_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,19 +359,18 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
}).toList()
|
||||
.stream().map(FaceSampleEntity::getId).collect(Collectors.toList());
|
||||
log.info("视频切分任务: faceId={}, 原始数量={}, 筛选后数量={}", faceId, faceSampleList.size(), faceSampleIds.size());
|
||||
List<SourceEntity> sourceList = sourceMapper.listVideoByScenicFaceRelation(face.getScenicId(), faceId);
|
||||
VideoPieceGetter.Task task = new VideoPieceGetter.Task();
|
||||
task.faceId = faceId;
|
||||
task.faceSampleIds = faceSampleIds;
|
||||
task.templateId = templateId;
|
||||
task.memberId = face.getMemberId();
|
||||
task.callback = () -> {
|
||||
log.info("task callback: {}", task);
|
||||
|
||||
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERING);
|
||||
// 只有在非强制创建时才进行模板生成判断
|
||||
if (!forceCreate) {
|
||||
boolean canGenerate = templateBiz.determineTemplateCanGenerate(templateId, faceId);
|
||||
if (!canGenerate) {
|
||||
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
|
||||
log.info("task callback: 不能生成,templateId: {}", templateId);
|
||||
return;
|
||||
}
|
||||
@@ -378,11 +378,14 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
|
||||
Map<String, List<SourceEntity>> allTaskParams = sourceRepository.getTaskParams(faceId, templateId);
|
||||
if (allTaskParams.isEmpty()) {
|
||||
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
|
||||
log.info("task callback: 任务参数没有,templateId: {}", templateId);
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, List<SourceEntity>> sourcesMap = templateBiz.filterTaskParams(templateId, allTaskParams);
|
||||
if (sourcesMap.isEmpty()) {
|
||||
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
|
||||
log.info("task callback: 筛选后无有效源数据,templateId: {}", templateId);
|
||||
return;
|
||||
}
|
||||
@@ -415,7 +418,8 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
memberVideoEntity.setIsBuy(taskVideoRelation.getIsBuy());
|
||||
memberVideoEntity.setOrderId(taskVideoRelation.getOrderId());
|
||||
}
|
||||
taskMapper.deleteById(taskEntity.getId());
|
||||
// TODO: FIXME 临时解决
|
||||
taskMapper.updateStatus(taskEntity.getId(), taskEntity.getStatus() + 10);
|
||||
}
|
||||
}
|
||||
if (taskEntity == null) {
|
||||
@@ -449,12 +453,8 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
}
|
||||
videoMapper.addRelation(memberVideoEntity);
|
||||
memberRelationRepository.clearVCacheByFace(faceId);
|
||||
|
||||
// 只有在非强制创建时才更新切割任务状态
|
||||
if (!forceCreate) {
|
||||
// 任务生成了,需要更新切割任务状态
|
||||
taskStatusBiz.setFaceCutStatus(faceId, 2);
|
||||
}
|
||||
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED);
|
||||
faceStatusManager.markNoNewPieces(faceId, templateId);
|
||||
};
|
||||
VideoPieceGetter.addTask(task);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user