TASK:1. 通过定时任务,补偿获取第三方api的运行结果;

2. pose 生成,对使用万相模型的生成限流,最大支持5个并发
3. Slogan限流,一分钟内,最多接收3个请求
This commit is contained in:
2025-08-01 17:21:41 +08:00
parent 132f48eb60
commit 4ad2cd027c
9 changed files with 3511 additions and 3326 deletions

View File

@@ -293,7 +293,7 @@ public class GenerateConsumer {
} else { } else {
// 修改redis中的数据状态为exception // 修改redis中的数据状态为exception
String key = generateResultKey + ":" + generateResult.get("tasks_id"); String key = generateResultKey + ":" + generateResult.get("tasks_id");
generateService.updatePoseTransferStatus(generateResult.get("tasks_id"), "Fail"); generateService.updatePoseTransferStatus(generateResult.get("tasks_id"), "Fail", null);
redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.get("tasks_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.get("tasks_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中 // 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>(); HashMap<String, String> exceptionInfo = new HashMap<>();
@@ -529,7 +529,7 @@ public class GenerateConsumer {
} else { } else {
// 修改redis中的数据状态为exception // 修改redis中的数据状态为exception
String key = generateResultKey + ":" + generateResult.getString("task_id"); String key = generateResultKey + ":" + generateResult.getString("task_id");
generateService.updatePoseTransferStatus(generateResult.getString("task_id"), "Fail"); generateService.updatePoseTransferStatus(generateResult.getString("task_id"), "Fail", null);
redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.getString("task_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.getString("task_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中 // 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>(); HashMap<String, String> exceptionInfo = new HashMap<>();

View File

@@ -0,0 +1,134 @@
package com.ai.da.common.task;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.mapper.primary.PoseTransformationMapper;
import com.ai.da.mapper.primary.ToProductImageResultMapper;
import com.ai.da.mapper.primary.entity.*;
import com.ai.da.service.APIGenerateService;
import com.ai.da.service.CreditsService;
import com.ai.da.service.GenerateService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import static com.ai.da.common.enums.CreditsEventsEnum.TO_PRODUCT_IMAGE;
@Slf4j
@Component
public class GenerateTask {
@Resource
private APIGenerateService apiGenerateService;
@Resource
private CreditsService creditsService;
@Resource
private GenerateService generateService;
@Resource
private ToProductImageResultMapper toProductImageResultMapper;
@Resource
private PoseTransformationMapper poseTransformationMapper;
/*
* 对于使用了第三方api的允许异步获得结果的生成功能可能在第三方接口的结果Ready时没有及时存储结果导致第三方链接失效
* 万相 24h失效
* flux 10mins失效 使用了flux接口的功能 ToProductImage || Relight, Pattern这里不做补偿
* 故这里通过定时任务做补偿
* flux五分钟查询一次万相1小时查询一次
*/
@Scheduled(cron = "0 */4 * * * ?")
public void fluxCompensationMechanism(){
// 1、查所有 任务还没成功、还没失败正在等待或者执行中的任务id有哪些
// 由于获取结果的polling_url在redis中只存一天大部分结果超过一天之后就无法再找到任务小部分可以通过公共路径查到结果
List<APIGenerate> apiGenerates = apiGenerateService.getPendingTaskByStatus("flux");
if (apiGenerates != null && !apiGenerates.isEmpty()){
for (APIGenerate apiGenerate : apiGenerates){
String taskId = apiGenerate.getTaskId();
// 1. 根据taskId查toProductImageResult 判断当前任务状态与超时状态
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(new QueryWrapper<ToProductImageResult>().eq("task_id", taskId));
if (Objects.nonNull(toProductImageResult) && "Pending".equals(toProductImageResult.getStatus())){
// 判断当前任务的超时状态
if (!DateUtil.isMoreThanOneDayApart(toProductImageResult.getCreateTime())){
// 1. 未超时,获取当前任务结果
String fileName = toProductImageResult.getResultType().equals(TO_PRODUCT_IMAGE.getName()) ? "product_image" : "relight_image";
String objectName = apiGenerate.getAccountId() + "/" + fileName +"/" + taskId + ".png";
String fluxResult = generateService.getFluxResult(taskId, objectName);
// 2. 成功获取结果下载图片上传至minio,更新toProductImageResult表
if (StringUtil.isNullOrEmpty(fluxResult) || fluxResult.equals("Fail")){
toProductImageResult.setStatus("Fail");
toProductImageResultMapper.updateById(toProductImageResult);
apiGenerate.setStatus("Fail");
apiGenerate.setUpdateTime(LocalDateTime.now());
apiGenerateService.updateById(apiGenerate);
} else if (!fluxResult.equals("Pending")){
if (StringUtil.isNullOrEmpty(toProductImageResult.getUrl())){
toProductImageResult.setStatus("Success");
toProductImageResult.setUrl(fluxResult);
toProductImageResultMapper.updateById(toProductImageResult);
apiGenerate.setStatus("Success");
apiGenerate.setUpdateTime(LocalDateTime.now());
apiGenerateService.updateById(apiGenerate);
}
// 扣积分
Boolean flag = creditsService.taskCreditsDeduction(apiGenerate.getAccountId(), taskId);
if (flag) creditsService.updateChangedCredits(String.valueOf(apiGenerate.getAccountId()), taskId);
}
} else {
// 超时,设置状态为失败
toProductImageResult.setStatus("Fail");
toProductImageResultMapper.updateById(toProductImageResult);
apiGenerate.setStatus("Fail");
apiGenerate.setUpdateTime(LocalDateTime.now());
apiGenerateService.updateById(apiGenerate);
}
}
}
}
}
// 万相 -> pose transformation 补偿 一小时执行一次
@Scheduled(fixedDelay = 60 * 60 * 1000)
public void wxCompensationMechanism(){
List<APIGenerate> apiGenerates = apiGenerateService.getPendingTaskByStatus("wx");
if (apiGenerates != null && !apiGenerates.isEmpty()){
for (APIGenerate apiGenerate : apiGenerates){
String taskId = apiGenerate.getTaskId();
PoseTransformation poseTransformation = poseTransformationMapper.selectOne(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId));
if (Objects.nonNull(poseTransformation) && "Pending".equals(poseTransformation.getTaskStatus())){
// 判断当前任务的超时状态
if (!DateUtil.isMoreThanOneDayApart(poseTransformation.getCreateTime())){
try {
// 方法中已经完成了pose_transformation和api_generate表的更新不用额外做处理
generateService.getAnimateResult(taskId);
} catch (BusinessException e){
log.warn("万相 animation 生成失败,原因:{}", e.getMessage());
}
}
} else {
poseTransformation.setTaskStatus("Fail");
poseTransformation.setUpdateTime(LocalDateTime.now());
poseTransformationMapper.updateById(poseTransformation);
apiGenerate.setStatus("Fail");
apiGenerate.setUpdateTime(LocalDateTime.now());
apiGenerateService.updateById(apiGenerate);
}
}
}
}
}

View File

@@ -5,10 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Instant; import java.time.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@@ -101,4 +98,10 @@ public class DateUtil {
return localDate.format(DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE, Locale.US)); return localDate.format(DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE, Locale.US));
} }
public static boolean isMoreThanOneDayApart(LocalDateTime givenDateTime) {
LocalDateTime now = LocalDateTime.now();
Duration duration = Duration.between(givenDateTime, now);
return duration.toHours() >= 24;
}
} }

View File

@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -594,4 +595,19 @@ public class RedisUtil {
return count; return count;
} }
public boolean allowRequest(String apiKey) {
String key = "rate_limit:" + apiKey;
ValueOperations<String, String> ops = redisTemplate.opsForValue();
// 使用Redis的INCR命令
Long count = ops.increment(key, 1);
if (count == 1) {
// 第一次调用,设置过期时间
redisTemplate.expire(key, 1, TimeUnit.MINUTES);
}
return count <= 3;
}
} }

View File

@@ -10,6 +10,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@@ -58,8 +59,14 @@ public class GenerateController {
@ApiOperation(value = "发起生成请求,异步获取结果") @ApiOperation(value = "发起生成请求,异步获取结果")
@PostMapping("/prepare") @PostMapping("/prepare")
public Response<PrepareForGenerateVO> prepareForGenerate(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) { public ResponseEntity<Response<PrepareForGenerateVO>> prepareForGenerate(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) {
return Response.success(generateService.prepareForGenerate(generateThroughImageTextDTO)); PrepareForGenerateVO prepareForGenerateVO = generateService.prepareForGenerate(generateThroughImageTextDTO);
if (prepareForGenerateVO.getStatus().equals(200)){
prepareForGenerateVO.setStatus(0);
return ResponseEntity.ok(Response.success(prepareForGenerateVO));
} else {
return ResponseEntity.status(prepareForGenerateVO.getStatus()).body(Response.fail("The rate limit has been exceeded. Please wait 1 minute before retrying."));
}
} }
@ApiOperation(value = "取消继续生成") @ApiOperation(value = "取消继续生成")

View File

@@ -14,14 +14,14 @@ public class PrepareForGenerateVO {
private List<String> uniqueId; private List<String> uniqueId;
@ApiModelProperty("剩余使用次数") @ApiModelProperty("剩余使用次数")
private Integer leftUsageCount; private Integer status;
public PrepareForGenerateVO(List<String> uniqueId, Integer leftUsageCount) { public PrepareForGenerateVO(List<String> uniqueId, Integer status) {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
this.leftUsageCount = leftUsageCount; this.status = status;
} }
public PrepareForGenerateVO(Integer leftUsageCount) { public PrepareForGenerateVO(Integer status) {
this.leftUsageCount = leftUsageCount; this.status = status;
} }
} }

View File

@@ -4,6 +4,7 @@ import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.mapper.primary.entity.CollectionSort; import com.ai.da.mapper.primary.entity.CollectionSort;
import com.ai.da.mapper.primary.entity.Generate; import com.ai.da.mapper.primary.entity.Generate;
import com.ai.da.mapper.primary.entity.GenerateDetail; import com.ai.da.mapper.primary.entity.GenerateDetail;
import com.ai.da.mapper.primary.entity.PoseTransformation;
import com.ai.da.model.dto.*; import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*; import com.ai.da.model.vo.*;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
@@ -58,8 +59,7 @@ public interface GenerateService extends IService<Generate> {
List<PoseTransformationVO> getPoseTransformationResult(List<String> taskIdList, Long projectId, Boolean like); List<PoseTransformationVO> getPoseTransformationResult(List<String> taskIdList, Long projectId, Boolean like);
void updatePoseTransferStatus(String taskId, String status); void updatePoseTransferStatus(String taskId, String status, PoseTransformation poseTransformation);
CollectionSort disOrLikePose(Long transformedId, String likeOrDislike, Long projectId, Long sortLikeParentId); CollectionSort disOrLikePose(Long transformedId, String likeOrDislike, Long projectId, Long sortLikeParentId);

View File

@@ -53,7 +53,8 @@ public class APIGenerateServiceImpl extends ServiceImpl<APIGenerateMapper, APIGe
qw.lambda().eq(APIGenerate::getTaskId, taskId); qw.lambda().eq(APIGenerate::getTaskId, taskId);
APIGenerate apiGenerate = baseMapper.selectOne(qw); APIGenerate apiGenerate = baseMapper.selectOne(qw);
if (Objects.nonNull(apiGenerate)){ if (Objects.nonNull(apiGenerate)){
if (apiGenerate.getStatus().equals("Ready") || apiGenerate.getStatus().equals("SUCCEEDED")) { if (apiGenerate.getStatus().equals("Ready") || apiGenerate.getStatus().equals("SUCCEEDED")
|| apiGenerate.getStatus().equals("Success")) {
log.warn("当前任务 {} 状态已达Success, 不做修改", taskId); log.warn("当前任务 {} 状态已达Success, 不做修改", taskId);
} else { } else {
apiGenerate.setStatus(status); apiGenerate.setStatus(status);

View File

@@ -619,7 +619,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
private PrepareForGenerateVO handleWxModelGeneration(GenerateThroughImageTextDTO generateDTO) { private PrepareForGenerateVO handleWxModelGeneration(GenerateThroughImageTextDTO generateDTO) {
String taskId = createAsyncTask(generateDTO); String taskId = createAsyncTask(generateDTO);
processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.WX_TEXT2IMG); processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.WX_TEXT2IMG);
return new PrepareForGenerateVO(Collections.singletonList(taskId), 2); return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
} }
/** /**
@@ -647,7 +647,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
// 处理积分扣除 // 处理积分扣除
processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.FLUX_IMG2IMG); processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.FLUX_IMG2IMG);
return new PrepareForGenerateVO(Collections.singletonList(taskId), 2); return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
} }
/** /**
@@ -707,6 +707,14 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
// 确定积分事件和生成次数 // 确定积分事件和生成次数
GenerationConfig config = determineGenerationConfig(generateDTO); GenerationConfig config = determineGenerationConfig(generateDTO);
// 对Slogan功能限流
if (config.creditsEvent.equals(CreditsEventsEnum.SLOGAN)){
boolean b = redisUtil.allowRequest("Slogan");
if (!b){
return new PrepareForGenerateVO(429);
}
}
// 校验积分是否足够 // 校验积分是否足够
validateCredits(config.creditsEvent); validateCredits(config.creditsEvent);
@@ -716,7 +724,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
// 处理积分扣除使用第一个任务的UUID前缀 // 处理积分扣除使用第一个任务的UUID前缀
processCreditDeduction(generateDTO.getUserId(), taskIds.get(0).split("-")[0], config.creditsEvent); processCreditDeduction(generateDTO.getUserId(), taskIds.get(0).split("-")[0], config.creditsEvent);
return new PrepareForGenerateVO(taskIds, 2); return new PrepareForGenerateVO(taskIds, 200);
} }
/** /**
@@ -1714,8 +1722,10 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
return "Invalid".equals(status) || "Fail".equals(status); return "Invalid".equals(status) || "Fail".equals(status);
} }
public void updatePoseTransferStatus(String taskId, String status){ public void updatePoseTransferStatus(String taskId, String status, PoseTransformation poseTransformation){
PoseTransformation poseTransformation = poseTransformationMapper.selectOne(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId)); if (Objects.isNull(poseTransformation)){
poseTransformation = poseTransformationMapper.selectOne(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId));
}
if (StringUtil.isNullOrEmpty(poseTransformation.getTaskStatus()) || !status.equals(poseTransformation.getTaskStatus())){ if (StringUtil.isNullOrEmpty(poseTransformation.getTaskStatus()) || !status.equals(poseTransformation.getTaskStatus())){
poseTransformation.setTaskStatus(status); poseTransformation.setTaskStatus(status);
@@ -2253,6 +2263,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
private static final String ANIMATE = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis/"; private static final String ANIMATE = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis/";
public String animateAnyone(PoseTransformDTO poseTransformDTO, Long accountId) { public String animateAnyone(PoseTransformDTO poseTransformDTO, Long accountId) {
AccessLimitUtils.validate("animation", 5);
String inputImage = poseTransformDTO.getProductImage(); String inputImage = poseTransformDTO.getProductImage();
String inputImageUrl = minioUtil.getPreSignedUrl(inputImage, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); String inputImageUrl = minioUtil.getPreSignedUrl(inputImage, CommonConstant.MINIO_IMAGE_EXPIRE_TIME);
// 1、输入图片检测 // 1、输入图片检测
@@ -2443,6 +2454,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
public PoseTransformationVO getAnimateResult(String taskId) { public PoseTransformationVO getAnimateResult(String taskId) {
String fullUrl = GET_ASYNC_RESULT + taskId; String fullUrl = GET_ASYNC_RESULT + taskId;
// 从接口获取当前任务的结果
String respBody = sendRequestUtil.sendAliYunGet(fullUrl); String respBody = sendRequestUtil.sendAliYunGet(fullUrl);
log.info("获取wx pose transform 的结果: {}", respBody); log.info("获取wx pose transform 的结果: {}", respBody);
@@ -2450,44 +2462,54 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
JSONObject output = JSONUtil.parseObj(outputStr); JSONObject output = JSONUtil.parseObj(outputStr);
String videoUrl = output.getStr("video_url"); String videoUrl = output.getStr("video_url");
String status = output.getStr("task_status"); String status = output.getStr("task_status");
WangXiangTaskStatusEnum statusEnum = WangXiangTaskStatusEnum.fromName(status);
// 更新api_generate表
apiGenerateService.updateAPIGenerateStatusAsync(taskId, status); apiGenerateService.updateAPIGenerateStatusAsync(taskId, status);
List<PoseTransformation> poseTransformations = poseTransformationMapper.selectList(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId).orderByDesc("id"));
PoseTransformation poseTransformation;
if (!poseTransformations.isEmpty()) {
poseTransformation = poseTransformations.get(0);
} else {
throw new BusinessException("unknown motion task");
}
PoseTransformationVO poseTransformationVO = new PoseTransformationVO(); PoseTransformationVO poseTransformationVO = new PoseTransformationVO();
WangXiangTaskStatusEnum statusEnum = WangXiangTaskStatusEnum.fromName(status);
switch (statusEnum) { switch (statusEnum) {
case SUCCEEDED: case SUCCEEDED:
List<PoseTransformation> poseTransformations = poseTransformationMapper.selectList(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId).orderByDesc("id")); AccessLimitUtils.validateOut("animation");
if (!poseTransformations.isEmpty()) { poseTransformationVO = CopyUtil.copyObject(poseTransformation, PoseTransformationVO.class);
PoseTransformation poseTransformation = poseTransformations.get(0); poseTransformationVO.setStatus("Success");
poseTransformationVO = CopyUtil.copyObject(poseTransformation, PoseTransformationVO.class);
// 生成视频的gif和第一帧图片
poseTransformationVO.setStatus("Success");
processVideo(videoUrl, poseTransformation);
poseTransformationVO.setId(poseTransformation.getId());
if (!StringUtil.isNullOrEmpty(poseTransformation.getGifUrl())) {
poseTransformationVO.setGifUrl(minioUtil.getPreSignedUrl(poseTransformation.getGifUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
}
if (!StringUtil.isNullOrEmpty(poseTransformation.getVideoUrl())) {
poseTransformationVO.setVideoUrl(minioUtil.getPreSignedUrl(poseTransformation.getVideoUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
}
if (!StringUtil.isNullOrEmpty(poseTransformation.getFirstFrameUrl())) {
poseTransformationVO.setFirstFrameUrl(minioUtil.getPreSignedUrl(poseTransformation.getFirstFrameUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
}
// 执行积分扣除
Long accountId = poseTransformation.getAccountId();
Boolean flag = creditsService.taskCreditsDeduction(accountId, taskId);
if (flag) creditsService.updateChangedCredits(String.valueOf(accountId), taskId);
// 保存数据到redis // 生成视频的gif和第一帧图片并上传图片、视频、gif等数据更新pose transformation表
String key = generateResultKey + ":" + taskId; processVideo(videoUrl, poseTransformation);
redisUtil.addToString(key, new Gson().toJson(poseTransformationVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); poseTransformationVO.setId(poseTransformation.getId());
if (!StringUtil.isNullOrEmpty(poseTransformation.getGifUrl())) {
poseTransformationVO.setGifUrl(minioUtil.getPreSignedUrl(poseTransformation.getGifUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
} }
if (!StringUtil.isNullOrEmpty(poseTransformation.getVideoUrl())) {
poseTransformationVO.setVideoUrl(minioUtil.getPreSignedUrl(poseTransformation.getVideoUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
}
if (!StringUtil.isNullOrEmpty(poseTransformation.getFirstFrameUrl())) {
poseTransformationVO.setFirstFrameUrl(minioUtil.getPreSignedUrl(poseTransformation.getFirstFrameUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
}
// 执行积分扣除
Long accountId = poseTransformation.getAccountId();
Boolean flag = creditsService.taskCreditsDeduction(accountId, taskId);
if (flag) creditsService.updateChangedCredits(String.valueOf(accountId), taskId);
// 保存数据到redis
String key = generateResultKey + ":" + taskId;
redisUtil.addToString(key, new Gson().toJson(poseTransformationVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
break; break;
case FAILED: case FAILED:
AccessLimitUtils.validateOut("animation");
updatePoseTransferStatus(taskId, "Fail", poseTransformation);
throw new BusinessException(output.getStr("message"), ResultEnum.PROMPT.getCode()); throw new BusinessException(output.getStr("message"), ResultEnum.PROMPT.getCode());
case UNKNOWN_W: case UNKNOWN_W:
AccessLimitUtils.validateOut("animation");
poseTransformationVO.setStatus("Fail"); poseTransformationVO.setStatus("Fail");
updatePoseTransferStatus(taskId, "Fail", poseTransformation);
break; break;
case RUNNING: case RUNNING:
case PENDING_W: case PENDING_W:
@@ -2495,8 +2517,10 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
poseTransformationVO.setStatus("Executing"); poseTransformationVO.setStatus("Executing");
break; break;
default: default:
AccessLimitUtils.validateOut("animation");
log.info("未知状态: {}", status); log.info("未知状态: {}", status);
poseTransformationVO.setStatus("Fail"); poseTransformationVO.setStatus("Fail");
updatePoseTransferStatus(taskId, "Fail", poseTransformation);
} }
poseTransformationVO.setTaskId(taskId); poseTransformationVO.setTaskId(taskId);