feat(render): 优化模板渲染状态管理逻辑

- 引入 TaskRenderJobMappingMapper 和 TaskRenderJobMappingEntity 处理渲染作业映射关系
- 重构 FaceStatusManager 中的模板渲染状态查询逻辑,基于任务渲染作业映射确定准确状态
- 在 TaskTaskServiceImpl 中完善视频复用场景下的状态标记机制
- 新增 RenderJobPollingService 中的模板渲染状态更新功能,在预览就绪时同步更新缓存状态
- 添加渲染失败时的状态重置机制,确保状态一致性
- 实现基于任务ID查询关联信息并更新模板渲染状态的通用方法
This commit is contained in:
2026-02-06 21:07:55 +08:00
parent 092c99d25d
commit a79cbe4f84
3 changed files with 49 additions and 8 deletions

View File

@@ -6,7 +6,9 @@ import com.ycwl.basic.enums.FaceCutStatus;
import com.ycwl.basic.enums.FacePieceUpdateStatus;
import com.ycwl.basic.enums.TemplateRenderStatus;
import com.ycwl.basic.mapper.TaskMapper;
import com.ycwl.basic.mapper.task.TaskRenderJobMappingMapper;
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.task.entity.TaskRenderJobMappingEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -51,6 +53,8 @@ public class FaceStatusManager {
@Autowired
private TaskMapper taskMapper;
@Autowired
private TaskRenderJobMappingMapper taskRenderJobMappingMapper;
public FaceStatusManager() {
// 初始化三个独立的缓存实例
@@ -257,20 +261,27 @@ public class FaceStatusManager {
Integer code = templateRenderCache.getIfPresent(faceId + ":" + templateId);
if (code == null) {
log.debug("模板渲染状态缓存不存在: faceId={}, templateId={}", faceId, templateId);
// 查询数据库
// 查询数据库:通过 task_render_job_mapping 确定渲染状态
TaskEntity task = taskMapper.listLastFaceTemplateTask(faceId, templateId);
if (task == null) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
return TemplateRenderStatus.NONE;
}
if (Integer.valueOf(2).equals(task.getStatus())) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERING);
}
if (Integer.valueOf(1).equals(task.getStatus())) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED);
}
TaskRenderJobMappingEntity mapping = taskRenderJobMappingMapper.selectByTaskId(task.getId());
if (mapping == null) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
return TemplateRenderStatus.NONE;
}
TemplateRenderStatus status = switch (mapping.getRenderStatus()) {
case TaskRenderJobMappingEntity.STATUS_PENDING -> TemplateRenderStatus.RENDERING;
case TaskRenderJobMappingEntity.STATUS_PREVIEW_READY,
TaskRenderJobMappingEntity.STATUS_MP4_COMPOSING,
TaskRenderJobMappingEntity.STATUS_COMPLETED -> TemplateRenderStatus.RENDERED;
default -> TemplateRenderStatus.NONE; // FAILED 等异常状态
};
setTemplateRenderStatus(faceId, templateId, status);
return status;
}
return TemplateRenderStatus.fromCode(code);
}

View File

@@ -1,5 +1,7 @@
package com.ycwl.basic.service.task;
import com.ycwl.basic.biz.FaceStatusManager;
import com.ycwl.basic.enums.TemplateRenderStatus;
import com.ycwl.basic.integration.render.dto.job.FinalizeMP4Response;
import com.ycwl.basic.integration.render.dto.job.JobStatusResponse;
import com.ycwl.basic.integration.render.service.RenderJobIntegrationService;
@@ -49,6 +51,7 @@ public class RenderJobPollingService {
private final VideoTaskRepository videoTaskRepository;
private final VideoRepository videoRepository;
private final MemberRelationRepository memberRelationRepository;
private final FaceStatusManager faceStatusManager;
/**
* 定时轮询间隔:2秒
@@ -179,6 +182,9 @@ public class RenderJobPollingService {
updateMappingStatus(mapping.getId(), TaskRenderJobMappingEntity.STATUS_PREVIEW_READY,
publishedCount, segmentCount, playUrl, null);
// 更新模板渲染状态缓存为已渲染(预览就绪即视为渲染成功)
updateTemplateRenderStatus(taskId, TemplateRenderStatus.RENDERED);
// 更新task的videoUrl为预览地址
if (StringUtils.isNotBlank(playUrl)) {
TaskEntity task = new TaskEntity();
@@ -307,6 +313,26 @@ public class RenderJobPollingService {
errorMessage,
new Date()
);
// 渲染失败,重置模板渲染状态
updateTemplateRenderStatus(mapping.getTaskId(), TemplateRenderStatus.NONE);
}
/**
* 更新模板渲染状态缓存
* 根据 taskId 查询关联的 faceId 和 templateId,更新 FaceStatusManager 中的渲染状态
*/
private void updateTemplateRenderStatus(Long taskId, TemplateRenderStatus status) {
try {
var taskInfo = taskMapper.getById(taskId);
if (taskInfo != null && taskInfo.getFaceId() != null && taskInfo.getTemplateId() != null) {
faceStatusManager.setTemplateRenderStatus(taskInfo.getFaceId(), taskInfo.getTemplateId(), status);
log.info("[渲染轮询] 已更新模板渲染状态: taskId={}, faceId={}, templateId={}, status={}",
taskId, taskInfo.getFaceId(), taskInfo.getTemplateId(), status.getDescription());
}
} catch (Exception e) {
log.warn("[渲染轮询] 更新模板渲染状态缓存失败: taskId={}, error={}", taskId, e.getMessage());
}
}
/**

View File

@@ -436,6 +436,7 @@ public class TaskTaskServiceImpl implements TaskService {
if (video != null) {
log.info("自动创建任务:跳过(auto_replace_vlog=false), faceId:{}, templateId:{}, existingTaskId:{}, videoId:{}",
faceId, templateId, taskEntity.getId(), video.getId());
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED);
return;
}
}
@@ -492,7 +493,10 @@ public class TaskTaskServiceImpl implements TaskService {
}
videoMapper.addRelation(memberVideoEntity);
memberRelationRepository.clearVCacheByFace(faceId);
// 仅当复用已有视频时立即标记为已渲染,新任务由 RenderJobPollingService 在 PREVIEW_READY 时更新
if (memberVideoEntity.getVideoId() != null) {
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED);
}
faceStatusManager.markNoNewPieces(faceId, templateId);
};
VideoPieceGetter.addTask(task);