TASK:1. 通过定时任务,补偿获取第三方api的运行结果;
2. pose 生成,对使用万相模型的生成限流,最大支持5个并发 3. Slogan限流,一分钟内,最多接收3个请求
This commit is contained in:
@@ -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<>();
|
||||||
|
|||||||
134
src/main/java/com/ai/da/common/task/GenerateTask.java
Normal file
134
src/main/java/com/ai/da/common/task/GenerateTask.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = "取消继续生成")
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user