From d411b428f87368218e872a0507677cdf73d550b4 Mon Sep 17 00:00:00 2001 From: xupei Date: Tue, 26 Mar 2024 14:58:43 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=AE=8C=E5=96=84=E8=B6=85=E5=88=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=202=E3=80=81=E5=AE=8C=E5=96=84=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E7=B3=BB=E7=BB=9F=203=E3=80=81=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ai/da/common/RabbitMQ/MQConfig.java | 17 +- .../com/ai/da/common/RabbitMQ/SRConsumer.java | 164 +++++++++++--- .../constant/PayPalCheckoutConstant.java | 9 +- .../ai/da/common/enums/CreditsEventsEnum.java | 9 +- .../ai/da/common/utils/AsyncCallerUtil.java | 49 ---- .../com/ai/da/common/utils/RedisUtil.java | 20 +- .../ai/da/controller/CreditsController.java | 7 +- .../ai/da/controller/PythonController.java | 2 +- .../ai/da/controller/TaskListController.java | 40 ++++ .../ai/da/mapper/primary/TaskListMapper.java | 7 + .../primary/entity/SuperResolution.java | 20 -- .../ai/da/mapper/primary/entity/TaskList.java | 27 +++ .../ai/da/model/dto/QueryTaskHistoryDTO.java | 18 ++ .../ai/da/model/dto/SuperResolutionDTO.java | 4 +- .../java/com/ai/da/model/dto/TaskDTO.java | 46 ++++ src/main/java/com/ai/da/model/vo/TaskVO.java | 22 ++ .../java/com/ai/da/python/PythonService.java | 73 +++--- .../com/ai/da/service/CreditsService.java | 5 +- .../ai/da/service/SuperResolutionService.java | 18 +- .../com/ai/da/service/TaskListService.java | 22 ++ .../da/service/impl/CreditsServiceImpl.java | 75 ++++--- .../impl/PayPalCheckoutServiceImpl.java | 110 ++++----- .../impl/SuperResolutionServiceImpl.java | 212 ++++++++++++------ .../da/service/impl/TaskListServiceImpl.java | 123 ++++++++++ src/main/resources/application-dev.properties | 15 +- src/main/resources/paypal-sandbox.properties | 21 +- 26 files changed, 807 insertions(+), 328 deletions(-) create mode 100644 src/main/java/com/ai/da/controller/TaskListController.java create mode 100644 src/main/java/com/ai/da/mapper/primary/TaskListMapper.java delete mode 100644 src/main/java/com/ai/da/mapper/primary/entity/SuperResolution.java create mode 100644 src/main/java/com/ai/da/mapper/primary/entity/TaskList.java create mode 100644 src/main/java/com/ai/da/model/dto/QueryTaskHistoryDTO.java create mode 100644 src/main/java/com/ai/da/model/dto/TaskDTO.java create mode 100644 src/main/java/com/ai/da/model/vo/TaskVO.java create mode 100644 src/main/java/com/ai/da/service/TaskListService.java create mode 100644 src/main/java/com/ai/da/service/impl/TaskListServiceImpl.java diff --git a/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java b/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java index 7b5b2e8c..79ecda25 100644 --- a/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java +++ b/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java @@ -8,12 +8,16 @@ import org.springframework.context.annotation.Configuration; public class MQConfig { public static final String GENERATE_EXCHANGE_FANOUT = "generate-exchange"; -// public static final String GENERATE_QUEUE = "generate-queue-prod"; + // public static final String GENERATE_QUEUE = "generate-queue-prod"; // public static final String GENERATE_QUEUE = "generate-queue-test"; -// public static final String GENERATE_QUEUE = "generate-queue-dev"; - public static final String GENERATE_QUEUE = "generate-queue"; + public static final String GENERATE_QUEUE = "generate-queue-dev"; +// public static final String GENERATE_QUEUE = "generate-queue"; - public static final String SR_QUEUE = "SR-queue-dev"; + public static final String SR_QUEUE = "SR-queue-dev"; +// public static final String SR_QUEUE = "SR-queue-local"; + + // public static final String SR_RESULT_QUEUE = "SuperResolution-local"; + public static final String SR_RESULT_QUEUE = "SuperResolution-dev"; public MQConfig() { } @@ -36,6 +40,11 @@ public class MQConfig { return new Queue(SR_QUEUE); } + @Bean + public Queue SRResultQueue() { + return new Queue(SR_RESULT_QUEUE); + } + /** * 将队列绑定到交换机上【队列订阅交换机】 */ diff --git a/src/main/java/com/ai/da/common/RabbitMQ/SRConsumer.java b/src/main/java/com/ai/da/common/RabbitMQ/SRConsumer.java index 9e014274..059b4f81 100644 --- a/src/main/java/com/ai/da/common/RabbitMQ/SRConsumer.java +++ b/src/main/java/com/ai/da/common/RabbitMQ/SRConsumer.java @@ -2,13 +2,15 @@ package com.ai.da.common.RabbitMQ; import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.utils.RedisUtil; -import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.dto.SuperResolutionDTO; -import com.ai.da.model.vo.GenerateCollectionVO; +import com.ai.da.model.dto.TaskDTO; import com.ai.da.service.SuperResolutionService; +import com.ai.da.service.TaskListService; +import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import com.rabbitmq.client.Channel; -import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitHandler; @@ -18,6 +20,7 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.IOException; +import java.lang.reflect.Type; import java.util.HashMap; @Slf4j @@ -27,6 +30,9 @@ public class SRConsumer { @Resource private RedisUtil redisUtil; + @Resource + private TaskListService taskListService; + @Value("${redis.key.orderForSR}") private String consumptionOrderKey; @@ -36,21 +42,33 @@ public class SRConsumer { @Value("${redis.key.SRExceptionMap}") private String exceptionMapKey; - @Value("${redis.key.resultMap}") - private String resultMapKey; + @Value("${redis.key.taskList}") + private String taskListKey; @Resource private SuperResolutionService superResolutionService; - public void superResolution(Message msg, Channel channel, String consumerName){ - log.info("============start listening=========="); + /** + * 请求超分处理 + */ + public void superResolution(Message msg, Channel channel, String consumerName) { + log.info("============SR start listening=========="); long start = System.currentTimeMillis(); - SuperResolutionDTO superResolutionDTO = JSONObject.parseObject(msg.getBody(), SuperResolutionDTO.class); - String uniqueId = superResolutionDTO.getUniqueId(); - log.info("From " + consumerName + " : " + uniqueId); + SuperResolutionDTO superResolutionDTO; + String uniqueId = null; try { + superResolutionDTO = JSONObject.parseObject(msg.getBody(), SuperResolutionDTO.class); + uniqueId = superResolutionDTO.getUniqueId(); + log.info("From " + consumerName + " : " + uniqueId); + superResolutionService.updateSROutput(uniqueId, "Executing", null); + taskListService.updateTaskStatusOrOutputRedis(uniqueId, "Executing", null); + /*try { + Thread.sleep(2 * 60 * 1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + }*/ // 2、判断当前消息是否在取消列表中 Boolean isMember = redisUtil.isElementExistsInSet(cancelSetKey, uniqueId); if (isMember) { @@ -61,45 +79,112 @@ public class SRConsumer { log.error("手动确认,不返回队列重新消费"); } } else { - /*try { - Thread.sleep(15000); - } catch (InterruptedException e) { - throw new RuntimeException(e); - }*/ - String srOutput = superResolutionService.SR(superResolutionDTO); - // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除 - redisUtil.removeFromZSet(consumptionOrderKey, uniqueId); - if (!StringUtil.isNullOrEmpty(srOutput)) { - HashMap generateResult = new HashMap<>(); - generateResult.put(uniqueId, srOutput); - // 将结果存在redis中 ,为空时不要存 - redisUtil.addToMap(resultMapKey, generateResult); - } - + // 请求python端进行超分 + superResolutionService.SR(superResolutionDTO); } } catch (BusinessException e) { log.error(e.getMsg()); + superResolutionDTO = JSONObject.parseObject(msg.getBody(), SuperResolutionDTO.class); + // channel.basicNack() 为不确认deliveryTag对应的消息,第二个参数是否应用于多消息,第三个参数是否requeue + setErrorMessage(msg, channel, e.getMsg(), superResolutionDTO); + } catch (JSONException e) { + log.error(e.getMessage()); + setErrorMessage(msg, channel, e.getMessage(), null); + } catch (Exception e) { + log.error(e.getMessage()); + superResolutionDTO = JSONObject.parseObject(msg.getBody(), SuperResolutionDTO.class); + setErrorMessage(msg, channel, e.getMessage(), superResolutionDTO); + + } + + long end = System.currentTimeMillis(); + + log.info(" task_id: " + uniqueId + "----------" + consumerName + " 执行时长:" + (end - start) + "毫秒"); + log.info("=============SR end listening==========="); + } + + /** + * 获取超分结果 + */ + public void getSRResult(Message msg, Channel channel, String consumerName) { + log.info("============SRResult start listening=========="); + long start = System.currentTimeMillis(); + + JSONObject result = null; + String taskId = null; + + try { + result = JSONObject.parseObject(msg.getBody(), JSONObject.class); + taskId = result.get("tasks_id").toString(); + } catch (JSONException e) { + log.error("SRResult 返回数据格式不合规范"); + log.error(e.getMessage()); + setErrorMessage(msg, channel, e.getMessage(), null); + } + + + try { +// channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false); + + // 2、判断状态是否成功 + if ("SUCCESS".equals(result.get("status").toString())) { + String output = result.get("data").toString(); + superResolutionService.setSRResult(taskId, output, "success"); + taskListService.updateTaskStatusOrOutputRedis(taskId, "success", output); + } else { + superResolutionService.setSRResult(taskId, null, "fail"); + taskListService.updateTaskStatusOrOutputRedis(taskId, "fail", null); + HashMap exceptionInfo = new HashMap<>(); + // 获取输入信息 + String task = redisUtil.getFromString(taskListKey + taskId + taskId.substring(taskId.lastIndexOf("-") + 1)); + Gson gson = new Gson(); + Type type = new TypeToken>() { + }.getType(); + TaskDTO taskDTO = gson.fromJson(task, type); + // 将输入信息和报错信息均存入redis todo 加判空 + exceptionInfo.put(taskId, "Input ==> " + taskDTO.getInputParam() + "Fail Message ==> " + result.get("message").toString()); + // 将报错信息存入redis + redisUtil.addToMap(exceptionMapKey, exceptionInfo); + } + } catch (Exception e) { + log.error(e.getMessage()); // channel.basicNack() 为不确认deliveryTag对应的消息,第二个参数是否应用于多消息,第三个参数是否requeue try { // 第二个参数,是否批量确认消息,当传false时,只确认当前 deliveryTag对应的消息;当传true时,会确认当前及之前所有未确认的消息。 channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false); - // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除 - redisUtil.removeFromZSet(consumptionOrderKey, uniqueId); } catch (IOException exception) { log.error("手动确认,取消返回队列,不再重新消费"); } - // 将入参和错误信息存入数据库 - String exceptionMessage = JSONObject.toJSONString(superResolutionDTO) + - " Exception message : " + e.getMsg(); - HashMap exceptionInfo = new HashMap<>(); - exceptionInfo.put(String.valueOf(uniqueId), exceptionMessage); - // 存redis - redisUtil.addToMap(exceptionMapKey, exceptionInfo); } + long end = System.currentTimeMillis(); - log.info(" task_id: " + uniqueId + "----------" + consumerName + " 执行时长:" + (end - start) + "毫秒"); - log.info("=============end listening==========="); + log.info(" task_id: " + taskId + "----------" + consumerName + " 执行时长:" + (end - start) + "毫秒"); + log.info("=============SRResult end listening==========="); + } + + private void setErrorMessage(Message msg, Channel channel, String message, SuperResolutionDTO superResolutionDTO) { + String uniqueId; + try { + // 第二个参数,是否批量确认消息,当传false时,只确认当前 deliveryTag对应的消息;当传true时,会确认当前及之前所有未确认的消息。 + channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false); + uniqueId = superResolutionDTO.getUniqueId(); + // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除 + redisUtil.removeFromZSet(consumptionOrderKey, uniqueId); + } catch (Exception exception) { + log.error("手动确认,取消返回队列,不再重新消费"); + throw new BusinessException("发生错误,手动确认消息"); + } + // 将入参和错误信息存入redis + String exceptionMessage = JSONObject.toJSONString(superResolutionDTO) + + " Exception message : " + message; +// " Exception message : " + e.getMessage(); + HashMap exceptionInfo = new HashMap<>(); + uniqueId = superResolutionDTO.getUniqueId(); + exceptionInfo.put(String.valueOf(uniqueId), exceptionMessage); + // 存redis + redisUtil.addToMap(exceptionMapKey, exceptionInfo); + taskListService.updateTaskStatusOrOutputRedis(uniqueId, "fail", null); } @RabbitListener(queues = MQConfig.SR_QUEUE) @@ -108,4 +193,11 @@ public class SRConsumer { superResolution(msg, channel, "consumer 1"); } + + @RabbitListener(queues = MQConfig.SR_RESULT_QUEUE) + @RabbitHandler + public void SRResultConsumer1(Message msg, Channel channel) { + getSRResult(msg, channel, "consumer 1"); + } + } diff --git a/src/main/java/com/ai/da/common/constant/PayPalCheckoutConstant.java b/src/main/java/com/ai/da/common/constant/PayPalCheckoutConstant.java index 2a7726f2..31cc4adf 100644 --- a/src/main/java/com/ai/da/common/constant/PayPalCheckoutConstant.java +++ b/src/main/java/com/ai/da/common/constant/PayPalCheckoutConstant.java @@ -2,7 +2,8 @@ package com.ai.da.common.constant; public class PayPalCheckoutConstant { - public static String MODE = "sandbox"; +// public static String MODE = "sandbox"; + public static String MODE = "live"; public static final String CAPTURE = "CAPTURE"; /** @@ -167,7 +168,11 @@ public class PayPalCheckoutConstant { public final static String CMD_NOTIFY_VALIDATE = "_notify-validate"; - public final static String WEBHOOK_ID = "31797347YC028794L"; +// public final static String WEBHOOK_ID = "31797347YC028794L"; + // kim-sandbox +// public final static String WEBHOOK_ID = "1WH327112B602422N"; + // kim-live + public final static String WEBHOOK_ID = "41L14847MC833625B"; public final static String PAYPAL_TOKEN_KEY = "PayPalAccessToken"; diff --git a/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java b/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java index 7e3eeb40..23566466 100644 --- a/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java +++ b/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java @@ -7,17 +7,18 @@ import lombok.Getter; @Getter public enum CreditsEventsEnum { - PRICE("price","2"), + PRICE("price","1"), + // 6USD -> 1000 points ==> 10HKD -> 215 points ==> 2HKD -> 43points + BUY_CREDITS("Buy Credits","43"), INIT("init", "1000"), DAILY_CHECKIN("Daily Check-In", "50"), SOCIAL_MEDIA_SHARING("Social Media Sharing","50"), - // 6USD -> 1000 points ==> 10HKD -> 215 points ==> 2HKD -> 43points - BUY_CREDITS("Buy Credits","43"), - SUPER_RESOLUTION("Super Resolution","300"), +// SUPER_RESOLUTION("Super Resolution","300"), + SUPER_RESOLUTION("Super Resolution","30"), OTHER("Other","10"); diff --git a/src/main/java/com/ai/da/common/utils/AsyncCallerUtil.java b/src/main/java/com/ai/da/common/utils/AsyncCallerUtil.java index 01bcd9bc..29801a6b 100644 --- a/src/main/java/com/ai/da/common/utils/AsyncCallerUtil.java +++ b/src/main/java/com/ai/da/common/utils/AsyncCallerUtil.java @@ -2,7 +2,6 @@ package com.ai.da.common.utils; import com.ai.da.common.config.exception.BusinessException; import com.ai.da.model.dto.GenerateToPythonDTO; -import com.ai.da.model.dto.SuperResolutionDTO; import com.ai.da.python.PythonService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -72,52 +71,4 @@ public class AsyncCallerUtil { } } - public CompletableFuture callSRAsync(SuperResolutionDTO superResolutionDTO) { - return CompletableFuture.supplyAsync(() -> pythonService.superResolution(superResolutionDTO)); - } - - public String SR(SuperResolutionDTO superResolutionDTO) { - ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); - String taskId = superResolutionDTO.getUniqueId(); - ScheduledFuture timeoutTask = null; - if (!waitingStatus.containsKey(taskId)) waitingStatus.put(taskId, true); - - try { - CompletableFuture generateResult = callSRAsync(superResolutionDTO); - // 5秒后第一次确认,之后每隔10秒确认一次用户选择结果 - timeoutTask = scheduledExecutorService.scheduleAtFixedRate(() -> { - // 调用另一个接口获取用户的选择 - if (!waitingStatus.get(taskId)) { - // 如果用户选择取消,则取消对generate的调用 - generateResult.cancel(true); - waitingStatus.remove(taskId); - } else log.info("===============持续等待==============="); - }, 5, 10, TimeUnit.SECONDS); - - log.info("阻塞等待结果..."); - // 阻塞,等待结果 - String result = generateResult.get(); - // 取消定时任务 - timeoutTask.cancel(true); - waitingStatus.remove(taskId); - return result; - } catch (CancellationException e) { - // generateResult.cancel(true);通过抛出异常取消该任务 - log.info("==========成功取消generate任务=========="); - return null; - } catch (InterruptedException | ExecutionException | BusinessException e) { - // 处理异常 - log.error("发生错误 : " + e, e); - // 取消定时任务 - assert timeoutTask != null; - timeoutTask.cancel(true); - throw new BusinessException(e.getMessage()); - } finally { - // 关闭线程池 -// executorService.shutdown(); -// scheduledExecutorService.shutdown(); - } - } - - } diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index 92bc06aa..9fa37738 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -7,6 +7,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -69,10 +70,15 @@ public class RedisUtil { /** * 获取当前ZSet中数据量的总和 */ - public Long getZSetTotal(String key) { + public Long getZSetTotalCount(String key) { return redisTemplate.opsForZSet().zCard(key); } + + public Set getZSetTotalData(String key){ + return redisTemplate.opsForZSet().range(key, 0, -1); + } + //- - - - - - - - - - - - - - - - - - - - - set类型 - - - - - - - - - - - - - - - - - - - - /** @@ -138,4 +144,16 @@ public class RedisUtil { return redisTemplate.opsForValue().get(key); } + public Set getKeysFromString(String key){ + return redisTemplate.keys(key); + } + + public List getMultiValue(Set keys){ + return redisTemplate.opsForValue().multiGet(keys); + } + + public Long getExpire(String key){ + return redisTemplate.getExpire(key); + } + } diff --git a/src/main/java/com/ai/da/controller/CreditsController.java b/src/main/java/com/ai/da/controller/CreditsController.java index f578a45c..ab02e57f 100644 --- a/src/main/java/com/ai/da/controller/CreditsController.java +++ b/src/main/java/com/ai/da/controller/CreditsController.java @@ -1,5 +1,6 @@ package com.ai.da.controller; +import com.ai.da.common.context.UserContext; import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.Response; import com.ai.da.mapper.primary.entity.CreditsDetail; @@ -25,14 +26,14 @@ public class CreditsController { @ApiOperation("获取当前积分") @GetMapping("/getCredits") - public Response getCredits(){ - String credits = creditsService.getCredits(); + public Response getCredits() { + String credits = creditsService.getCredits(UserContext.getUserHolder().getId()); return Response.success(credits); } @ApiOperation("获取积分详细") @PostMapping("/getCreditsDetail") - public Response> getCreditsDetail(@Valid @RequestBody QueryIncomeOrExpenditureDTO queryPageByTimeDTO){ + public Response> getCreditsDetail(@Valid @RequestBody QueryIncomeOrExpenditureDTO queryPageByTimeDTO) { PageBaseResponse credits = creditsService.queryCreditsDetailsPage(queryPageByTimeDTO); return Response.success(credits); } diff --git a/src/main/java/com/ai/da/controller/PythonController.java b/src/main/java/com/ai/da/controller/PythonController.java index 5bb0f931..895d311a 100644 --- a/src/main/java/com/ai/da/controller/PythonController.java +++ b/src/main/java/com/ai/da/controller/PythonController.java @@ -115,7 +115,7 @@ public class PythonController { @ApiOperation(value = "超分辨率") @PostMapping("/prepareForSR") - public Response superResolution(@RequestBody SuperResolutionDTO superResolutionDTO){ + public Response> superResolution(@RequestBody List superResolutionDTO) { return Response.success(superResolutionService.prepareForSR(superResolutionDTO)); } diff --git a/src/main/java/com/ai/da/controller/TaskListController.java b/src/main/java/com/ai/da/controller/TaskListController.java new file mode 100644 index 00000000..85485d50 --- /dev/null +++ b/src/main/java/com/ai/da/controller/TaskListController.java @@ -0,0 +1,40 @@ +package com.ai.da.controller; + +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.common.response.Response; +import com.ai.da.model.dto.QueryTaskHistoryDTO; +import com.ai.da.model.dto.SuperResolutionDTO; +import com.ai.da.model.dto.TaskDTO; +import com.ai.da.model.vo.TaskVO; +import com.ai.da.service.TaskListService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +@Api(tags = "任务列表模块") +@Slf4j +@RestController +@RequestMapping("/api/tasks") +public class TaskListController { + + @Resource + private TaskListService taskListService; + + @PostMapping("/getList") + @ApiOperation("获取未执行完的任务") + public Response>> getTaskList(@Valid @RequestBody List taskIdList) { + return Response.success(taskListService.getExecTask(taskIdList)); + } + + @PostMapping("/getAllTask") + @ApiOperation("获取所有任务") + public Response> getAllTask(@Valid @RequestBody QueryTaskHistoryDTO queryTaskHistoryDTO) { + return Response.success(taskListService.getAllTask(queryTaskHistoryDTO)); + } + +} diff --git a/src/main/java/com/ai/da/mapper/primary/TaskListMapper.java b/src/main/java/com/ai/da/mapper/primary/TaskListMapper.java new file mode 100644 index 00000000..cbda70e9 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/TaskListMapper.java @@ -0,0 +1,7 @@ +package com.ai.da.mapper.primary; + +import com.ai.da.mapper.primary.entity.TaskList; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface TaskListMapper extends BaseMapper { +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/SuperResolution.java b/src/main/java/com/ai/da/mapper/primary/entity/SuperResolution.java deleted file mode 100644 index 31e32e58..00000000 --- a/src/main/java/com/ai/da/mapper/primary/entity/SuperResolution.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ai.da.mapper.primary.entity; - -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.List; - -@EqualsAndHashCode(callSuper = true) -@Data -@TableName("t_super_resolution") -public class SuperResolution extends BaseEntity{ - - private String input_url; - - private Integer scale; - - private String output_url; - -} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/TaskList.java b/src/main/java/com/ai/da/mapper/primary/entity/TaskList.java new file mode 100644 index 00000000..81797448 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/TaskList.java @@ -0,0 +1,27 @@ +package com.ai.da.mapper.primary.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("t_task_list") +public class TaskList extends BaseEntity{ + + private Long accountId; + + private String taskType; + + private String inputUrl; + + private Integer scale; + + /* 可选状态 : 成功:success 失败:fail */ + private String status; + + private String outputUrl; + + private String taskId; + +} diff --git a/src/main/java/com/ai/da/model/dto/QueryTaskHistoryDTO.java b/src/main/java/com/ai/da/model/dto/QueryTaskHistoryDTO.java new file mode 100644 index 00000000..db8dbc69 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/QueryTaskHistoryDTO.java @@ -0,0 +1,18 @@ +package com.ai.da.model.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotEmpty; + +@EqualsAndHashCode(callSuper = true) +@Data +@ApiModel("按分类分页查询历史任务") +public class QueryTaskHistoryDTO extends QueryPageByTimeDTO { + + @NotEmpty(message = "type cannot be empty") + @ApiModelProperty("可选类型 : SR") + private String type; +} diff --git a/src/main/java/com/ai/da/model/dto/SuperResolutionDTO.java b/src/main/java/com/ai/da/model/dto/SuperResolutionDTO.java index 95eb0745..36b15ce6 100644 --- a/src/main/java/com/ai/da/model/dto/SuperResolutionDTO.java +++ b/src/main/java/com/ai/da/model/dto/SuperResolutionDTO.java @@ -6,7 +6,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; -import java.util.List; @Data @NoArgsConstructor @@ -22,6 +21,5 @@ public class SuperResolutionDTO { private Integer scale; @ApiModelProperty("唯一id,用于保持消息唯一性") - String uniqueId; - + private String uniqueId; } diff --git a/src/main/java/com/ai/da/model/dto/TaskDTO.java b/src/main/java/com/ai/da/model/dto/TaskDTO.java new file mode 100644 index 00000000..83b3c7fa --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/TaskDTO.java @@ -0,0 +1,46 @@ +package com.ai.da.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TaskDTO { + + private String taskId; + + // 可选type : SR GENERATE + private String type; + + // 输入的图片名 + private String imageName; + + private T inputParam; + + private String outputImage; + + // 任务状态,暂定状态:排队中、执行中、成功/失败 + private String status; + + // 当前任务的创建时间 + private String createDate; + + public TaskDTO(String taskId, String type, String imageName, T inputParam, String status, String createDate) { + this.taskId = taskId; + this.type = type; + this.imageName = imageName; + this.inputParam = inputParam; + this.status = status; + this.createDate = createDate; + } + + public TaskDTO(String taskId, String type, T inputParam, String status, String createDate) { + this.taskId = taskId; + this.type = type; + this.inputParam = inputParam; + this.status = status; + this.createDate = createDate; + } +} diff --git a/src/main/java/com/ai/da/model/vo/TaskVO.java b/src/main/java/com/ai/da/model/vo/TaskVO.java new file mode 100644 index 00000000..1c0a3f63 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/TaskVO.java @@ -0,0 +1,22 @@ +package com.ai.da.model.vo; + +import lombok.Data; + +@Data +public class TaskVO { + + // 图片名 + private String imageName; + + private String inputImage; + + private String outputImage; + + private String otherInput; + + private String status; + + private String taskId; + + private String createDate; +} diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 7019e724..507dd69f 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -65,6 +65,8 @@ public class PythonService { private String accessPythonIp; @Value("${access.python.port:''}") private String accessPythonPort; + @Value("${access.python.sr}") + private String srPythonPort; @Resource private PythonTAllInfoService pythonTAllInfoService; @@ -290,7 +292,7 @@ public class PythonService { List pinData = getPinData(elementVO); if (CollectionUtil.isNotEmpty(pinData)) { return CurrentDesignPictureTypeEnum.PIN; - }else { + } else { if (sysSketchNum == 0 && noPinSketchNum == 0) { sysSketchNum = systemScale.multiply(BigDecimal.valueOf(8 - pinSketchNum)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(); noPinSketchNum = 8 - pinSketchNum - sysSketchNum; @@ -605,6 +607,7 @@ public class PythonService { @Resource private AttributeRetrievalMapper attributeRetrievalMapper; + private List getSystemSketchPool(JSONObject attributeRecognition, String styleCategory, String modelSex, int poolNum) { /** * female trousers->female_pants @@ -837,6 +840,7 @@ public class PythonService { private CollocationMapper collocationMapper; @Resource private DressingMapper dressingMapper; + private List getOtherSketchCategoryList(String modelSex, DesignPythonItem designPythonItem) { List collocationList = collocationMapper.getCollocationListBySketch(modelSex, designPythonItem.getType()); if (CollectionUtil.isNotEmpty(collocationList)) { @@ -1993,10 +1997,10 @@ public class PythonService { if (elementVO.getSingleOverall().equals(SingleOverallEnum.SINGLE.getRealName())) { if (!CollectionUtils.isEmpty(pinData)) { return pinData.stream().filter(o -> o.getLevel2Type().equals(elementVO.getSwitchCategory())).collect(Collectors.toList()); - }else { + } else { return pinData; } - }else { + } else { return pinData; } } @@ -2006,10 +2010,10 @@ public class PythonService { if (elementVO.getSingleOverall().equals(SingleOverallEnum.SINGLE.getRealName())) { if (!CollectionUtils.isEmpty(pinData)) { return pinData.stream().filter(o -> o.getLevel2Type().equals(elementVO.getSwitchCategory())).collect(Collectors.toList()); - }else { + } else { return pinData; } - }else { + } else { return pinData; } } @@ -2032,8 +2036,8 @@ public class PythonService { return sketchBoardPins; } - public final static List FEMALE_CATEGORY = Arrays.asList("Dress","Blouse","Skirt","Trousers","Outwear"); - public final static List MALE_CATEGORY = Arrays.asList("Tops","Bottoms","Outwear"); + public final static List FEMALE_CATEGORY = Arrays.asList("Dress", "Blouse", "Skirt", "Trousers", "Outwear"); + public final static List MALE_CATEGORY = Arrays.asList("Tops", "Bottoms", "Outwear"); private List getPinData(List sketchBoardElements, List hasUseMd5List, String modelSex) { if (CollectionUtils.isEmpty(sketchBoardElements)) { @@ -2060,7 +2064,7 @@ public class PythonService { return null; } return noPinData.stream().filter(o -> o.getLevel2Type().equals(elementVO.getSwitchCategory())).collect(Collectors.toList()); - }else { + } else { return getNoPinData(elementVO.getSketchBoardElements(), elementVO.getModelSex()); } } @@ -3065,7 +3069,7 @@ public class PythonService { // .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") // .addHeader("Content-Type", "application/json") .build(); - Response response; + Response response = null; try { log.info("cancelGenerateTask请求入参content###{}", taskId); response = client.newCall(request).execute(); @@ -3073,8 +3077,10 @@ public class PythonService { log.error("PythonService##cancelGenerateTask异常###{}", ExceptionUtil.getThrowableList(ioException)); return null; } + int responseCode = response.code(); + response.close(); - if (response.code() != HttpURLConnection.HTTP_OK) { + if (responseCode != HttpURLConnection.HTTP_OK) { log.info("generate-python 取消请求失败"); return Boolean.FALSE; } @@ -3082,7 +3088,7 @@ public class PythonService { return Boolean.TRUE; } - public String superResolution(SuperResolutionDTO superResolutionDTO){ + public Boolean superResolution(SuperResolutionDTO superResolutionDTO) throws BusinessException { OkHttpClient client = new OkHttpClient().newBuilder() .connectTimeout(30, TimeUnit.SECONDS) .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) @@ -3092,54 +3098,35 @@ public class PythonService { MediaType mediaType = MediaType.parse("application/json"); HashMap content = new HashMap<>(); - content.put("image_url", superResolutionDTO.getImages()); + content.put("sr_image_url", superResolutionDTO.getImages()); content.put("sr_xn", superResolutionDTO.getScale().toString()); - content.put("task_id", superResolutionDTO.getUniqueId()); + content.put("sr_tasks_id", superResolutionDTO.getUniqueId()); String jsonString = JSON.toJSONString(content, SerializerFeature.WriteNullStringAsEmpty); RequestBody body = RequestBody.create(mediaType, jsonString); Request request = new Request.Builder() - .url(accessPythonIp + ":" + 9991 + "/super-resolution/") + .url(srPythonPort + "/api/super_resolution") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = null; - String bodyString; try { - log.info("superResolution请求入参content###{}", JSON.toJSONString(superResolutionDTO, SerializerFeature.WriteMapNullValue)); + log.info("superResolution请求入参content###{}", jsonString); response = client.newCall(request).execute(); } catch (IOException ioException) { log.error("PythonService##superResolution异常###{}", ExceptionUtil.getThrowableList(ioException)); - throw new BusinessException(ioException.getMessage()); + return null; } + int responseCode = response.code(); + response.close(); - // 判断是否生成失败 - if (Objects.isNull(response.body())) { - log.error("PythonService##superResolution异常###{}", "response or body is empty!"); - throw new BusinessException("PythonService##superResolution异常###: response or body is empty!"); - } else if (response.code() != HttpURLConnection.HTTP_OK) { - log.error("PythonService##superResolution异常###{}", "Response error!Response code ## " + response.code() + " ##"); - throw new BusinessException("PythonService##superResolution异常### Response error!Response code ## " + response.code() + " ##"); - } else { - try { - bodyString = response.body().string(); - } catch (IOException e) { - log.error(e.getMessage()); - throw new BusinessException(e.getMessage()); - } + if (responseCode != HttpURLConnection.HTTP_OK) { + // 基本不会有除200以外的code + log.info("superResolution 请求超分操作失败。 Response code " + response.code()); + throw new BusinessException("superResolution 请求超分操作失败。 Response code " + response.code()); } - JSONObject jsonObject = JSON.parseObject(bodyString); - Boolean result = JSON.parseObject(JSON.toJSONString(response)).getBoolean("successful"); - - // todo 返回数据的结构没对接好 - if (result && jsonObject.get("code").equals(200)) { - log.info("superResolution##responseObject###{}", jsonObject); - return jsonObject.getJSONObject("data").get("image").toString(); - } - log.info("superResolution失败###{}", jsonObject); - log.info("superResolution Exception! Code : " + jsonObject.get("code")); - //生成失败 - throw new BusinessException("sr.interface.error"); + log.info("superResolution 请求超分操作成功"); + return Boolean.TRUE; } } diff --git a/src/main/java/com/ai/da/service/CreditsService.java b/src/main/java/com/ai/da/service/CreditsService.java index c8e6f6ea..a2947b5b 100644 --- a/src/main/java/com/ai/da/service/CreditsService.java +++ b/src/main/java/com/ai/da/service/CreditsService.java @@ -1,6 +1,7 @@ package com.ai.da.service; +import com.ai.da.common.enums.CreditsEventsEnum; import com.ai.da.common.response.PageBaseResponse; import com.ai.da.mapper.primary.entity.CreditsDetail; import com.ai.da.model.dto.QueryIncomeOrExpenditureDTO; @@ -16,11 +17,13 @@ public interface CreditsService extends IService { void creditsDecrease(Long accountId, String event); - String getCredits(); + String getCredits(Long accountId); void creditsRefund(Long accountId, Integer quantity); void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType); PageBaseResponse queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO); + + Boolean checkCredits(Long accountId, CreditsEventsEnum event, Integer num); } diff --git a/src/main/java/com/ai/da/service/SuperResolutionService.java b/src/main/java/com/ai/da/service/SuperResolutionService.java index 6d01bb2e..8f989e15 100644 --- a/src/main/java/com/ai/da/service/SuperResolutionService.java +++ b/src/main/java/com/ai/da/service/SuperResolutionService.java @@ -1,12 +1,22 @@ package com.ai.da.service; -import com.ai.da.mapper.primary.entity.SuperResolution; +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.mapper.primary.entity.TaskList; +import com.ai.da.model.dto.QueryTaskHistoryDTO; import com.ai.da.model.dto.SuperResolutionDTO; import com.baomidou.mybatisplus.extension.service.IService; -public interface SuperResolutionService extends IService { +import java.util.List; - String prepareForSR(SuperResolutionDTO superResolutionDTO); +public interface SuperResolutionService extends IService { - String SR(SuperResolutionDTO superResolutionDTO); + List prepareForSR(List superResolutionDTO); + + void SR(SuperResolutionDTO superResolutionDTO) throws Exception; + + void setSRResult(String taskId, String output, String status); + + void updateSROutput(String taskId, String status, String output); + + PageBaseResponse getTaskHistoryPage(QueryTaskHistoryDTO queryTaskHistoryDTO); } diff --git a/src/main/java/com/ai/da/service/TaskListService.java b/src/main/java/com/ai/da/service/TaskListService.java new file mode 100644 index 00000000..9f43deb6 --- /dev/null +++ b/src/main/java/com/ai/da/service/TaskListService.java @@ -0,0 +1,22 @@ +package com.ai.da.service; + +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.mapper.primary.entity.TaskList; +import com.ai.da.model.dto.QueryTaskHistoryDTO; +import com.ai.da.model.dto.SuperResolutionDTO; +import com.ai.da.model.dto.TaskDTO; +import com.ai.da.model.vo.TaskVO; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +public interface TaskListService extends IService { + + List> getExecTask(List taskIdList); + + void addToTaskListRedis(TaskDTO taskDTO); + + void updateTaskStatusOrOutputRedis(String taskId, String status, String output); + + PageBaseResponse getAllTask(QueryTaskHistoryDTO queryTaskHistoryDTO); +} diff --git a/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java b/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java index 707ad786..10342ad0 100644 --- a/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java @@ -51,7 +51,7 @@ public class CreditsServiceImpl extends ServiceImpl增 negative->减 + * @param credits 变更的积分 + * @param changeType 变更类型 : positive->增 negative->减 */ @Override - public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType){ + public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType) { CreditsDetail creditsDetail = new CreditsDetail(); Account account = accountMapper.selectById(accountId); - BigDecimal finalCredits; +// BigDecimal finalCredits; String changeCredits; - if ("positive".equals(changeType)){ - finalCredits = account.getCredits().add(new BigDecimal(credits)); + if ("positive".equals(changeType)) { +// finalCredits = account.getCredits().add(new BigDecimal(credits)); changeCredits = "+" + credits; - }else { - finalCredits = account.getCredits().subtract(new BigDecimal(credits)); + } else { +// finalCredits = account.getCredits().subtract(new BigDecimal(credits)); changeCredits = "-" + credits; } creditsDetail.setAccountId(accountId); creditsDetail.setChangeEvent(changeEvent); creditsDetail.setChangedCredits(changeCredits); - creditsDetail.setCredits(finalCredits); +// creditsDetail.setCredits(finalCredits); + creditsDetail.setCredits(account.getCredits()); creditsDetail.setCreateTime(LocalDateTime.now()); baseMapper.insert(creditsDetail); } @Override - public PageBaseResponse queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO){ + public PageBaseResponse queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO) { QueryWrapper qw = new QueryWrapper<>(); - qw.eq("account_id",UserContext.getUserHolder().getId()); + qw.eq("account_id", UserContext.getUserHolder().getId()); String startTime = queryPageByTimeDTO.getStartTime(); String endTime = queryPageByTimeDTO.getEndTime(); - if (StringUtil.isNullOrEmpty(startTime)){ + if (StringUtil.isNullOrEmpty(startTime)) { startTime = "2024-03-01 00:00:00"; } - if (StringUtil.isNullOrEmpty(endTime)){ + if (StringUtil.isNullOrEmpty(endTime)) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); endTime = now.format(dateTimeFormatter); } - if (!Objects.isNull(queryPageByTimeDTO.getIsIncome())){ - if (queryPageByTimeDTO.getIsIncome()){ - qw.likeRight("changed_credits","+"); - }else { - qw.likeRight("changed_credits","-"); + if (!Objects.isNull(queryPageByTimeDTO.getIsIncome())) { + if (queryPageByTimeDTO.getIsIncome()) { + qw.likeRight("changed_credits", "+"); + } else { + qw.likeRight("changed_credits", "-"); } } @@ -162,4 +168,15 @@ public class CreditsServiceImpl extends ServiceImpl response = null; try { response = payPalClient.client(MODE, clientId, clientSecret).execute(request); @@ -102,13 +102,13 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { log.info("Status Code = {}, Status = {}, OrderID = {}, Intent = {}", response.statusCode(), response.result().status(), response.result().id(), response.result().checkoutPaymentIntent()); for (LinkDescription link : response.result().links()) { log.info("Links-{}: {} \tCall Type: {}", link.rel(), link.href(), link.method()); - if(link.rel().equals("approve")) { + if (link.rel().equals("approve")) { approve = link.href(); } } String totalAmount = response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode() + ":" + response.result().purchaseUnits().get(0).amountWithBreakdown().value(); log.info("Total Amount: {}", totalAmount); - String json= new JSONObject(new Json().serialize(response.result())).toString(4); + String json = new JSONObject(new Json().serialize(response.result())).toString(4); log.info("createOrder response body: {}", json); } @@ -116,8 +116,8 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { orderInfoService.updateOrderNoById(orderInfo.getId(), orderId); HashMap returnData = new HashMap<>(); - returnData.put("approve",approve); - returnData.put("orderNo",orderId); + returnData.put("approve", approve); + returnData.put("orderNo", orderId); // 需要返回地址和订单id return returnData; @@ -132,12 +132,12 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { HashMap webhookRequest = new HashMap<>(); webhookRequest.put("auth_algo", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-AUTH-ALGO")); - webhookRequest.put("cert_url",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-CERT-URL")); - webhookRequest.put("transmission_id",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-ID")); - webhookRequest.put("transmission_sig",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-SIG")); - webhookRequest.put("transmission_time",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-TIME")); - webhookRequest.put("webhook_id",PayPalCheckoutConstant.WEBHOOK_ID); - webhookRequest.put("webhook_event",webhookEvent); + webhookRequest.put("cert_url", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-CERT-URL")); + webhookRequest.put("transmission_id", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-ID")); + webhookRequest.put("transmission_sig", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-SIG")); + webhookRequest.put("transmission_time", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-TIME")); + webhookRequest.put("webhook_id", PayPalCheckoutConstant.WEBHOOK_ID); + webhookRequest.put("webhook_event", webhookEvent); WebhookVerifyRequest webhookVerifyRequest = new WebhookVerifyRequest(); webhookVerifyRequest.authorization(getOAuth()); @@ -145,7 +145,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { // 验签 HttpResponse verified = payPalClient.client(MODE, clientId, clientSecret).execute(webhookVerifyRequest); boolean verifyResult = verified.result().get("verification_status").toString().equals("SUCCESS"); - if (verifyResult){ + if (verifyResult) { // ### Api Context APIContext apiContext = new APIContext(clientId, clientSecret, PayPalCheckoutConstant.MODE); @@ -155,14 +155,15 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { req), body); log.info("Webhook Validated: " + result); - if (result){ + if (result) { // 处理订单数据 - LinkedHashMap> webhookEventMap = (LinkedHashMap>) webhookEvent; + LinkedHashMap> webhookEventMap = (LinkedHashMap>) webhookEvent; String orderId = webhookEventMap.get("resource").get("id"); processOrder(orderId); return Boolean.TRUE; } - + } else { + log.error("Paypal 验签失败"); } } catch (PayPalRESTException | InvalidKeyException | NoSuchAlgorithmException | SignatureException e) { log.error(e.getMessage()); @@ -226,7 +227,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { ApplicationContext applicationContext = new ApplicationContext() .brandName(BRANDNAME) .landingPage(LANDINGPAGE) - .cancelUrl("https://www.example.com").returnUrl(returnUrl) + .cancelUrl(returnUrl).returnUrl(returnUrl) .userAction(USERACTION) .shippingPreference(SHIPPINGPREFERENCE); orderRequest.applicationContext(applicationContext); @@ -250,12 +251,12 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { log.info("通知参数 ===> {}", map); // log.info(map.toString()); - String outTradeNo = (String)map.get("invoice"); - String paymentStatus = (String)map.get("payment_status"); - String amount = (String)map.get("mc_gross"); - String currency = (String)map.get("mc_currency"); - String paymentId = (String)map.get("txn_id"); - String parentPaymentId = (String)map.get("parent_txn_id"); + String outTradeNo = (String) map.get("invoice"); + String paymentStatus = (String) map.get("payment_status"); + String amount = (String) map.get("mc_gross"); + String currency = (String) map.get("mc_currency"); + String paymentId = (String) map.get("txn_id"); + String parentPaymentId = (String) map.get("parent_txn_id"); log.info("商家订单号 = {}", outTradeNo); log.info("订单状态 = {}", paymentStatus); log.info("金额 = {}", amount); @@ -267,30 +268,30 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { log.info("FAIL = 商户id错误, outTradeNo = {}", outTradeNo); return "failure"; } - if("Completed".equals(paymentStatus)) { + if ("Completed".equals(paymentStatus)) { //进行数据库操作 // // log.info("支付成功,状态为=COMPLETED"); return "success"; } - if("Refunded".equals(paymentStatus)) { + if ("Refunded".equals(paymentStatus)) { //进行数据库操作 // // log.info("退款成功"); return "success"; } - if("Pending".equals(paymentStatus) && StringUtils.isEmpty(parentPaymentId)) { + if ("Pending".equals(paymentStatus) && StringUtils.isEmpty(parentPaymentId)) { String pendingReason = String.valueOf(map.get("pending_reason")); //进行数据库操作 // // - log.info("订单支付成功,状态为=PENDING,产生此状态的原因是 {}", pendingReason ); + log.info("订单支付成功,状态为=PENDING,产生此状态的原因是 {}", pendingReason); return "success"; } - if(StringUtils.isEmpty(parentPaymentId)) { - if(PayPalCheckoutConstant.PAYMENT_STATUS_REVERSED.equals(paymentStatus) + if (StringUtils.isEmpty(parentPaymentId)) { + if (PayPalCheckoutConstant.PAYMENT_STATUS_REVERSED.equals(paymentStatus) || PayPalCheckoutConstant.PAYMENT_STATUS_CANCELED_REVERSAL.equals(paymentStatus) || PayPalCheckoutConstant.PAYMENT_STATUS_DENIED.equals(paymentStatus)) { String reasonCode = String.valueOf(map.get("reason_code")); @@ -300,7 +301,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { log.info("订单异常,请尽快查看处理,状态为={},产生此状态的原因是 {} ", paymentStatus, reasonCode); return PayPalCheckoutConstant.SUCCESS; } - if(PayPalCheckoutConstant.PAYMENT_STATUS_EXPIRED.equals(paymentStatus) + if (PayPalCheckoutConstant.PAYMENT_STATUS_EXPIRED.equals(paymentStatus) || PayPalCheckoutConstant.PAYMENT_STATUS_CREATED.equals(paymentStatus) || PayPalCheckoutConstant.PAYMENT_STATUS_FAILED.equals(paymentStatus) || PayPalCheckoutConstant.PAYMENT_STATUS_PROCESSED.equals(paymentStatus) @@ -317,6 +318,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { /** * 查询订单信息 + * * @param orderNo * @return * @throws SerializeException @@ -328,20 +330,20 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { try { response = payPalClient.client(MODE, clientId, clientSecret).execute(request); } catch (Exception e) { - log.error("paypal订单查询失败,失败原因 ===> {}",e.getMessage()); + log.error("paypal订单查询失败,失败原因 ===> {}", e.getMessage()); } System.out.println("Status Code: " + response.statusCode()); System.out.println("Status: " + response.result().status()); System.out.println("Order id: " + response.result().id()); - if(response.result().purchaseUnits().get(0).payments() != null) { + if (response.result().purchaseUnits().get(0).payments() != null) { List captures = response.result().purchaseUnits().get(0).payments().captures(); - if(captures != null) { + if (captures != null) { for (Capture capture : captures) { System.out.println("\t订单编号= " + capture.invoiceId() + "\tCapture Id= " + capture.id() + "\tCapture status= " + capture.status() + "\tCapture amount= " + capture.amount().currencyCode() + ":" + capture.amount().value()); } } List refunds = response.result().purchaseUnits().get(0).payments().refunds(); - if(refunds != null) { + if (refunds != null) { for (Refund refund : refunds) { System.out.println("\t售后编号= " + refund.invoiceId() + "\tRefund Id= " + refund.id() + "\tRefund status= " + refund.status() + "\tRefund amount= " + refund.amount().currencyCode() + ":" + refund.amount().value()); } @@ -366,12 +368,12 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { OrdersCaptureRequest request = new OrdersCaptureRequest(orderId); request.requestBody(new OrderRequest()); PayPalClient payPalClient = new PayPalClient(); - HttpResponse response ; + HttpResponse response; try { response = payPalClient.client(MODE, clientId, clientSecret).execute(request); } catch (Exception e) { - log.error("调用paypal扣款失败,失败原因 ===> {}", e.getMessage() ); + log.error("调用paypal扣款失败,失败原因 ===> {}", e.getMessage()); throw new BusinessException("Order deduction failed."); } log.info("Status Code = {}, Status = {}, OrderID = {}", response.statusCode(), response.result().status(), response.result().id()); @@ -383,14 +385,14 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { log.info("Capture id: {}", capture.id()); log.info("status: {}", capture.status()); log.info("invoice_id: {}", capture.invoiceId()); - if("COMPLETED".equals(capture.status())) { + if ("COMPLETED".equals(capture.status())) { //进行数据库操作,修改订单状态为已支付成功,尽快发货(配合回调和CapturesGet查询确定成功) log.info("支付成功,状态为=COMPLETED"); } - if("PENDING".equals(capture.status())) { + if ("PENDING".equals(capture.status())) { log.info("status_details: {}", capture.captureStatusDetails().reason()); String reason = "PENDING"; - if(capture.captureStatusDetails() != null && capture.captureStatusDetails().reason() != null) { + if (capture.captureStatusDetails() != null && capture.captureStatusDetails().reason() != null) { reason = capture.captureStatusDetails().reason(); } //进行数据库操作,修改订单状态为已支付成功,但触发了人工审核,请审核通过后再发货(配合回调和CapturesGet查询确定成功) @@ -406,7 +408,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { try { json = new JSONObject(new Json().serialize(response.result())).toString(4); } catch (SerializeException e) { - log.warn("response序列化出错,具体信息 ===> {}",e.getMessage()); + log.warn("response序列化出错,具体信息 ===> {}", e.getMessage()); } log.info("captureOrder response body: {}", json); // return Convert.toStr(new Json().serialize(response.result())); @@ -437,7 +439,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { * 申请退款 */ @Transactional(rollbackFor = Exception.class) - public Boolean refundOrder(String orderId,String reason) throws IOException { + public Boolean refundOrder(String orderId, String reason) throws IOException { RefundInfo refundByOrderNo = refundsInfoService.createRefundByOrderNo(orderId, reason); @@ -445,7 +447,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { PayPalClient payPalClient = new PayPalClient(); HttpResponse ordersGetResponse = null; ordersGetRequest.authorization("Bearer " + getOAuth()); - boolean result ; + boolean result; try { ordersGetResponse = payPalClient.client(MODE, clientId, clientSecret).execute(ordersGetRequest); } catch (Exception e) { @@ -458,7 +460,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { request.prefer("return=representation"); OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId); - request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()),reason)); + request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()), reason)); HttpResponse response = null; try { response = payPalClient.client(MODE, clientId, clientSecret).execute(request); @@ -468,7 +470,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { } log.info("Status Code = {}, Status = {}, RefundID = {}", response.statusCode(), response.result().status(), response.result().id()); - if("COMPLETED".equals(response.result().status())) { + if ("COMPLETED".equals(response.result().status())) { //进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功) //更新订单状态 @@ -485,7 +487,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue())); log.info("退款成功"); result = Boolean.TRUE; - }else { + } else { //更新订单状态 orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_ABNORMAL); @@ -540,24 +542,24 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { return null; } - public String getOAuth(){ + public String getOAuth() { // 1、判断缓存区是否有该token Boolean hasKey = redisUtil.hasKey(PAYPAL_TOKEN_KEY); - if (hasKey){ + if (hasKey) { return redisUtil.getFromString(PAYPAL_TOKEN_KEY); // return "A21AAKnpozur9r9omqQ2ge5aXHBBdEERi5F8FIgNYOjhhO2N7rjmkz2irh2lScpBO3s3Cqukw3eZkpYZ4YWE7rIacjv7MHmow"; } // 2、无或者过期,重新获取token,返回 AuthenticationRequest authenticationRequest = new AuthenticationRequest(); - authenticationRequest.authorization(clientId,clientSecret); + authenticationRequest.authorization(clientId, clientSecret); try { HttpResponse authResult = payPalClient.client(MODE, clientId, clientSecret).execute(authenticationRequest); String accessToken = authResult.result().get("access_token").toString(); long expiresIn = Long.parseLong(authResult.result().get("expires_in").toString()); // 3、存redis - redisUtil.addToString(PAYPAL_TOKEN_KEY,accessToken,expiresIn); - return accessToken; + redisUtil.addToString(PAYPAL_TOKEN_KEY, accessToken, expiresIn); + return accessToken; } catch (IOException e) { log.error("获取paypal token失败,失败原因 ===> {}", e.getMessage()); throw new BusinessException(e); @@ -566,17 +568,17 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { // 处理当前订单 @Transactional(rollbackFor = Exception.class) - public void processOrder(String orderId){ + public void processOrder(String orderId) { // 1、确定当前订单是否已经被扣款 OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId); - if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())){ + if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())) { // 直接返回 - return ; + return; } // 发起扣款请求 Order capturedOrder = captureOrder(orderId); // 业务处理 - if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())){ + if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())) { //更新订单状态 orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS); //记录支付日志 diff --git a/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java b/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java index 0b634b82..8863c254 100644 --- a/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java @@ -1,29 +1,42 @@ package com.ai.da.service.impl; +import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.context.UserContext; import com.ai.da.common.enums.CreditsEventsEnum; -import com.ai.da.common.utils.AsyncCallerUtil; +import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.utils.RedisUtil; -import com.ai.da.mapper.primary.SuperResolutionMapper; -import com.ai.da.mapper.primary.entity.SuperResolution; +import com.ai.da.mapper.primary.TaskListMapper; +import com.ai.da.mapper.primary.entity.TaskList; +import com.ai.da.model.dto.QueryTaskHistoryDTO; import com.ai.da.model.dto.SuperResolutionDTO; +import com.ai.da.model.dto.TaskDTO; import com.ai.da.python.PythonService; import com.ai.da.service.CreditsService; import com.ai.da.service.RabbitMQService; import com.ai.da.service.SuperResolutionService; +import com.ai.da.service.TaskListService; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.netty.util.internal.StringUtil; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; import javax.annotation.Resource; -import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; +@Slf4j @Service -public class SuperResolutionServiceImpl extends ServiceImpl implements SuperResolutionService { +public class SuperResolutionServiceImpl extends ServiceImpl implements SuperResolutionService { public static final Integer creditsConsumption = 100; @@ -32,10 +45,11 @@ public class SuperResolutionServiceImpl extends ServiceImpl prepareForSR(List superResolutionDTOList) { - // 异步处理 - // 判断用户当前积分是否够本次超分消耗 - String credits = creditsService.getCredits(); - if (new BigDecimal(credits).subtract(new BigDecimal(creditsConsumption)).compareTo(BigDecimal.ZERO) < 0){ - return "Not enough Credits"; + Long accountId = UserContext.getUserHolder().getId(); + // 1、判断用户当前积分是否够本次超分消耗 + + Boolean credits = creditsService.checkCredits(accountId, CreditsEventsEnum.SUPER_RESOLUTION, superResolutionDTOList.size()); + // todo 积分扣除待升级 + if (credits) { + // 先扣除积分,后失败后再加上 + creditsService.creditsDecrease(accountId, CreditsEventsEnum.SUPER_RESOLUTION.getName()); + } else { + throw new BusinessException("Not enough Credits"); } - // 2、生成唯一id 使用uuid - String uuid = UUID.randomUUID().toString(); - int num = 1; - // 判断已经正常生成结果的uuid或正在排队的uuid中是否有相同的id - while ((redisUtil.isElementExistsInMap(resultMapKey, uuid) || - redisUtil.isElementExistsInZSet(orderForSR, uuid)) - && num < 10) { - uuid = UUID.randomUUID().toString(); - num++; - } - // 无依据确定的数字 - if (num > 10) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - throw new RuntimeException(e); + ArrayList uuidList = new ArrayList<>(); + + for (SuperResolutionDTO superResolutionDTO : superResolutionDTOList) { + // 2、生成唯一id 使用uuid + String uuid = UUID.randomUUID().toString(); + int num = 1; + // 判断已经正常生成结果的uuid或正在排队的uuid中是否有相同的id + while ((redisUtil.isElementExistsInMap(resultMapKey, uuid) || + redisUtil.isElementExistsInZSet(orderForSR, uuid)) + && num < 10) { + uuid = UUID.randomUUID().toString(); + num++; } - uuid = UUID.randomUUID().toString(); + uuid += "-" + accountId; + uuidList.add(uuid); + + // 3、截取minio地址 (前提是该url是由minio地址转换来的) + String inputString = superResolutionDTO.getImages(); + String replace = inputString.replace(endpoint + "/", ""); + String minioPath = replace.substring(0, replace.indexOf("?")); +// log.info(minioPath); + superResolutionDTO.setImages(minioPath); + + superResolutionDTO.setUniqueId(uuid); + String jsonString = JSON.toJSONString(superResolutionDTO); + + // 4、将数据存到数据库 + TaskList taskList = new TaskList(); + taskList.setAccountId(accountId); + taskList.setTaskType("SR"); + taskList.setInputUrl(superResolutionDTO.getImages()); + taskList.setScale(superResolutionDTO.getScale()); + taskList.setStatus("Waiting"); + taskList.setTaskId(superResolutionDTO.getUniqueId()); + taskList.setCreateTime(LocalDateTime.now()); + + baseMapper.insert(taskList); + + // 5、加入任务列表 设置状态为 等待中 + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String name = superResolutionDTO.getImages(); + taskListService.addToTaskListRedis(new TaskDTO<>(uuid, "SR", name.substring(name.lastIndexOf("/") + 1), superResolutionDTO, "Waiting", LocalDateTime.now().format(dateTimeFormatter))); + + // 6、将消息发布到MQ消息队列 + log.info("发送消息到SR_QUEUE,参数 :{}", jsonString); + rabbitMQService.publishMessageToSR(jsonString); } - superResolutionDTO.setUniqueId(uuid); - String jsonString = JSON.toJSONString(superResolutionDTO); - // 3、加入redis排队,便于获取实时排队信息 - Double maxScore = redisUtil.getMaxScore(orderForSR); - redisUtil.addToZSet(orderForSR, uuid, maxScore); - - // 4、将消息发布到MQ消息队列 - rabbitMQService.publishMessageToSR(jsonString); - - // 5、返回唯一id - return uuid; + // 6、返回唯一id列表 + return uuidList; } @Transactional(rollbackFor = Exception.class) @Override - public String SR(SuperResolutionDTO superResolutionDTO){ - + public void SR(SuperResolutionDTO superResolutionDTO) throws Exception { // 1、向模型发起请求 -// String srResult = asyncCallerUtil.SR(superResolutionDTO); - String srResult = pythonService.superResolution(superResolutionDTO); + pythonService.superResolution(superResolutionDTO); - // 2、向数据库插入数据 - SuperResolution superResolution = new SuperResolution(); - superResolution.setInput_url(superResolutionDTO.getImages()); - superResolution.setScale(superResolutionDTO.getScale()); - superResolution.setOutput_url(srResult); - superResolution.setCreateTime(LocalDateTime.now()); - - baseMapper.insert(superResolution); - - // 3、记录积分变更 - creditsService.insertToCreditsDetail(UserContext.getUserHolder().getId(), - CreditsEventsEnum.SUPER_RESOLUTION.getName(), - CreditsEventsEnum.SUPER_RESOLUTION.getValue(), - "negative"); - - // 4、扣除积分 - creditsService.creditsDecrease(UserContext.getUserHolder().getId(), CreditsEventsEnum.SUPER_RESOLUTION.getValue()); - - // 4、将数据存在数据库 - - return srResult; + // 2、更新状态 + updateSROutput(superResolutionDTO.getUniqueId(), "Executing", null); } + @Transactional(rollbackFor = Exception.class) + @Override + public void setSRResult(String taskId, String output, String status) { + Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); + // 获取结果后更新 + updateSROutput(taskId, status, output); + + if ("success".equals(status)) { + // 3、记录积分变更 + creditsService.insertToCreditsDetail(accountId, + CreditsEventsEnum.SUPER_RESOLUTION.getName(), + CreditsEventsEnum.SUPER_RESOLUTION.getValue(), + "negative"); + } else { + // 将之前扣除的积分返还 + creditsService.creditsIncrease(accountId, CreditsEventsEnum.SUPER_RESOLUTION.getName()); + } + } + + @Override + public void updateSROutput(String taskId, String status, String output) { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("task_id", taskId); + + uw.set("output_url", output); + uw.set("status", status); + baseMapper.update(null, uw); + + } + + // 分页查询 + @Override + public PageBaseResponse getTaskHistoryPage(QueryTaskHistoryDTO queryTaskHistoryDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("account_id", UserContext.getUserHolder().getId()); + + String startTime = queryTaskHistoryDTO.getStartTime(); + String endTime = queryTaskHistoryDTO.getEndTime(); + if (StringUtil.isNullOrEmpty(startTime)) { + startTime = "2024-03-01 00:00:00"; + } + if (StringUtil.isNullOrEmpty(endTime)) { + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + endTime = now.format(dateTimeFormatter); + } + + qw.between("create_time", startTime, endTime); + qw.orderByDesc("create_time"); + Page pageInfo = new Page<>(queryTaskHistoryDTO.getPage(), queryTaskHistoryDTO.getSize()); + Page orderInfo = baseMapper.selectPage(pageInfo, qw); + if (CollectionUtils.isEmpty(orderInfo.getRecords())) { + return PageBaseResponse.success(new Page<>()); + } + + return PageBaseResponse.success(orderInfo); + } } diff --git a/src/main/java/com/ai/da/service/impl/TaskListServiceImpl.java b/src/main/java/com/ai/da/service/impl/TaskListServiceImpl.java new file mode 100644 index 00000000..d8e02623 --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/TaskListServiceImpl.java @@ -0,0 +1,123 @@ +package com.ai.da.service.impl; + +import com.ai.da.common.context.UserContext; +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.common.utils.MinioUtil; +import com.ai.da.common.utils.RedisUtil; +import com.ai.da.mapper.primary.TaskListMapper; +import com.ai.da.mapper.primary.entity.TaskList; +import com.ai.da.model.dto.QueryTaskHistoryDTO; +import com.ai.da.model.dto.SuperResolutionDTO; +import com.ai.da.model.dto.TaskDTO; +import com.ai.da.model.vo.TaskVO; +import com.ai.da.service.SuperResolutionService; +import com.ai.da.service.TaskListService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import io.netty.util.internal.StringUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.lang.reflect.Type; +import java.time.format.DateTimeFormatter; +import java.util.*; + +@Service +@Slf4j +public class TaskListServiceImpl extends ServiceImpl implements TaskListService { + + @Resource + private RedisUtil redisUtil; + + @Value("${redis.key.taskList}") + private String taskListKey; + + @Resource + private MinioUtil minioUtil; + + @Resource + private SuperResolutionService superResolutionService; + + @Override + @Transactional(rollbackFor = Exception.class) + public List> getExecTask(List taskIdList) { + Long id = UserContext.getUserHolder().getId(); +// Set keys = redisUtil.getKeysFromString(taskListKey + ":" + id + ":*"); + ArrayList> taskDTOS = new ArrayList<>(); + taskIdList.forEach(taskId -> { + String taskDetail = redisUtil.getFromString(taskListKey + ":" + id + ":" + taskId); + Gson gson = new Gson(); + Type type = new TypeToken>() { + }.getType(); + TaskDTO taskDTO = gson.fromJson(taskDetail, type); + if (Objects.isNull(taskDTO)) { + // 未执行成功的taskId在redis被删除,将该条数据在db中的状态改为失败 + superResolutionService.updateSROutput(taskId, "fail", null); + taskDTOS.add(new TaskDTO<>()); + } else { + SuperResolutionDTO inputParam = taskDTO.getInputParam(); + inputParam.setImages(minioUtil.getPresignedUrl(inputParam.getImages(), 24 * 60)); + taskDTO.setOutputImage(StringUtil.isNullOrEmpty(taskDTO.getOutputImage()) ? null : minioUtil.getPresignedUrl(taskDTO.getOutputImage(), 24 * 60)); + taskDTOS.add(taskDTO); + } + }); + return taskDTOS; + } + + public void addToTaskListRedis(TaskDTO taskDTO) { + String key = taskListKey + ":" + UserContext.getUserHolder().getId() + ":" + taskDTO.getTaskId(); + redisUtil.addToString(key, new Gson().toJson(taskDTO), 24L * 60 * 60 * 3); + } + + // 3、更新任务状态 + @Override + public void updateTaskStatusOrOutputRedis(String taskId, String status, String output) { + String key = taskListKey + ":" + taskId.substring(taskId.lastIndexOf("-") + 1) + ":" + taskId; + String taskDetail = redisUtil.getFromString(key); + Gson gson = new Gson(); + Type type = new TypeToken>() { + }.getType(); + TaskDTO taskDTO = gson.fromJson(taskDetail, type); + taskDTO.setStatus(status); + if (!StringUtil.isNullOrEmpty(output)) { + taskDTO.setOutputImage(output); + } + Long expire = redisUtil.getExpire(key); + redisUtil.addToString(key, new Gson().toJson(taskDTO), expire); + } + + @Override + public PageBaseResponse getAllTask(QueryTaskHistoryDTO queryTaskHistoryDTO) { + PageBaseResponse response = new PageBaseResponse<>(); + ArrayList taskLists = new ArrayList<>(); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + switch (queryTaskHistoryDTO.getType()) { + case "SR": + PageBaseResponse taskHistoryPage = superResolutionService.getTaskHistoryPage(queryTaskHistoryDTO); + List srHistory = taskHistoryPage.getContent(); + srHistory.forEach(s -> { + // 成功失败的都返回 + TaskVO task = new TaskVO(); + task.setImageName(s.getInputUrl().substring(s.getInputUrl().lastIndexOf("/") + 1)); + task.setInputImage(minioUtil.getPresignedUrl(s.getInputUrl(), 24 * 60)); + task.setOutputImage(StringUtil.isNullOrEmpty(s.getOutputUrl()) ? null : minioUtil.getPresignedUrl(s.getOutputUrl(), 24 * 60)); + task.setStatus(s.getStatus()); + task.setTaskId(s.getTaskId()); + task.setCreateDate(s.getCreateTime().format(dateTimeFormatter)); + task.setOtherInput("×" + s.getScale()); + taskLists.add(task); + }); + BeanUtils.copyProperties(taskHistoryPage, response); + response.setContent(taskLists); + break; + case "GENERATE": + log.info("未知任务类型--GENERATE"); + } + return response; + } +} diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index ccb406c6..3b2cb2da 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -21,7 +21,7 @@ spring.security.jwtExpiration=8640000000 #spring security权限设置 认证了token还要认证权限 不然报错Full authentication is required to access this resource spring.security.ignorePaths=/,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs,\ /api/account/**,/api/element/**,/api/python/**,/api/design/**,/api/history/**,/api/library/**,/api/third/party/**,/api/generate/**,/api/workspace/**,/api/classification/**,\ - /api/product/**,/api/ali-pay/**,/api/order-info/**,/api/paypal/**,/api/credits/** + /api/product/**,/api/ali-pay/**,/api/order-info/**,/api/paypal/**,/api/credits/**,/api/inquiry/**,/api/tasks/**,/api/python/prepareForSR spring.security.authApi=/auth/login @@ -46,6 +46,7 @@ spring.servlet.multipart.max-request-size= 10MB #访问python服务的ip(对应环境) access.python.ip=http://18.167.251.121 access.python.port=9992 +access.python.sr=http://18.167.251.121:9994 minio.endpoint=https://www.minio.aida.com.hk:9000 minio.accessKey=admin @@ -74,7 +75,11 @@ spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0 spring.redis.lettuce.pool.max-wait=5 -redis.key.consumptionOrder=ConsumptionOrder -redis.key.cancelSet=CancelSet -redis.key.exceptionMap=ExceptionMap -redis.key.resultMap=ResultMap \ No newline at end of file +redis.key.orderForGenerate=OrderForGenerate +redis.key.generateCancelSet=GenerateCancelSet +redis.key.generateExceptionMap=GenerateExceptionMap +redis.key.resultMap=ResultMap +redis.key.orderForSR=OrderForSR +redis.key.SRCancelSet=SRCancelSet +redis.key.SRExceptionMap=SRExceptionMap +redis.key.taskList=TaskList \ No newline at end of file diff --git a/src/main/resources/paypal-sandbox.properties b/src/main/resources/paypal-sandbox.properties index e839eebf..aea3ac83 100644 --- a/src/main/resources/paypal-sandbox.properties +++ b/src/main/resources/paypal-sandbox.properties @@ -1,5 +1,20 @@ -paypal.client-id=ATbaebYi7-GXWRWJqwRLYMzKEbwjh4BFRqD4Y13i4lZq0rplWIM_IpPrtPKpdkAt_KrPXd6IJTwsDqa5 +# developer-sandbox +#paypal.client-id=ATbaebYi7-GXWRWJqwRLYMzKEbwjh4BFRqD4Y13i4lZq0rplWIM_IpPrtPKpdkAt_KrPXd6IJTwsDqa5 +#paypal.client-secret=EHWWJqGmmbfjLXqCUpGrvxRYBPPtWvA3hR5ZaAyHlGSVJiHoQPS8skbNaJ9h39VObnchUbgiY2pPu__s +#paypal.receiver.email=sb-ukxfk29608925@business.example.com +#paypal.mode=sandbox +#paypal.webhook_id=31797347YC028794L -paypal.client-secret=EHWWJqGmmbfjLXqCUpGrvxRYBPPtWvA3hR5ZaAyHlGSVJiHoQPS8skbNaJ9h39VObnchUbgiY2pPu__s +# aida-sandbox +#paypal.client-id=AbDDH8jnTrKqjnWLFgEu6LogYzVz2ZLuirE4W54t1M4lrofrP5OzXfhbxqktLLFB-rAO9KeYQVYFJ_tO +#paypal.client-secret=EOOoiIAe_dyR2YhY7qCIqWipZvYXCDrmBlFYchphuvkPFms1spsBGTlStlrx580y4hN-EukWwF9m_LAs +#paypal.receiver.email=sb-4xe8i29784722@business.example.com +#paypal.mode=sandbox +#paypal.webhook_id=1WH327112B602422N -paypal.receiver.email=sb-ukxfk29608925@business.example.com \ No newline at end of file +# aida-live +paypal.client-id=ASWSIZ3MXJU5w5VOeOHeigWcSw6iinl30ZCipruziKpHclxP0ryf8-7VKG1Ba2VwZwa2DMvGEzTfCTgz +paypal.client-secret=EHQg_K5PSqmp4FJlzEcOEH_kFkmq4aBzaI7jridw53L6cOQRULBAnfv2KakRfrsqaU1PDSkO4Co9Vyxc +paypal.receiver.email=kimwong@code-create.com.hk +paypal.mode=live +paypal.webhook_id=41L14847MC833625B \ No newline at end of file