|
@@ -2,9 +2,12 @@ package com.aitori.listener;
|
|
|
|
|
|
|
|
import com.aitori.entity.TAiAlbum;
|
|
import com.aitori.entity.TAiAlbum;
|
|
|
import com.aitori.entity.TAiOrderV2;
|
|
import com.aitori.entity.TAiOrderV2;
|
|
|
|
|
+import com.aitori.entity.TAiStyle;
|
|
|
import com.aitori.entity.message.WorkflowTaskMessage;
|
|
import com.aitori.entity.message.WorkflowTaskMessage;
|
|
|
import com.aitori.service.TAiAlbumService;
|
|
import com.aitori.service.TAiAlbumService;
|
|
|
import com.aitori.service.TAiOrderV2Service;
|
|
import com.aitori.service.TAiOrderV2Service;
|
|
|
|
|
+import com.aitori.service.TAiStyleService;
|
|
|
|
|
+import com.aitori.service.TUserMessageService;
|
|
|
import com.aitori.utils.VideoThumbnailUtil;
|
|
import com.aitori.utils.VideoThumbnailUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
@@ -12,6 +15,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.core.task.AsyncTaskExecutor;
|
|
|
import org.springframework.data.redis.connection.Message;
|
|
import org.springframework.data.redis.connection.Message;
|
|
|
import org.springframework.data.redis.connection.MessageListener;
|
|
import org.springframework.data.redis.connection.MessageListener;
|
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
@@ -28,10 +32,14 @@ import java.util.Map;
|
|
|
public class WorkflowTaskMessageListener implements MessageListener {
|
|
public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
|
|
|
|
|
private static final String STATUS_SUCCESS = "successes";
|
|
private static final String STATUS_SUCCESS = "successes";
|
|
|
|
|
+ private static final int MSG_TYPE_ORDER_V2_FINISH = 11;
|
|
|
|
|
|
|
|
private final TAiOrderV2Service aiOrderV2Service;
|
|
private final TAiOrderV2Service aiOrderV2Service;
|
|
|
private final TAiAlbumService aiAlbumService;
|
|
private final TAiAlbumService aiAlbumService;
|
|
|
|
|
+ private final TAiStyleService aiStyleService;
|
|
|
|
|
+ private final TUserMessageService userMessageService;
|
|
|
private final ObjectMapper objectMapper;
|
|
private final ObjectMapper objectMapper;
|
|
|
|
|
+ private final AsyncTaskExecutor asyncTaskExecutor;
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void onMessage(Message message, byte[] pattern) {
|
|
public void onMessage(Message message, byte[] pattern) {
|
|
@@ -39,14 +47,21 @@ public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
String body = new String(message.getBody());
|
|
String body = new String(message.getBody());
|
|
|
log.info("收到 Redis 订阅消息, channel: {}, body: {}", channel, body);
|
|
log.info("收到 Redis 订阅消息, channel: {}, body: {}", channel, body);
|
|
|
|
|
|
|
|
|
|
+ WorkflowTaskMessage taskMessage;
|
|
|
try {
|
|
try {
|
|
|
- WorkflowTaskMessage taskMessage = objectMapper.readValue(body, WorkflowTaskMessage.class);
|
|
|
|
|
- handleTaskMessage(taskMessage);
|
|
|
|
|
|
|
+ taskMessage = objectMapper.readValue(body, WorkflowTaskMessage.class);
|
|
|
} catch (JsonProcessingException e) {
|
|
} catch (JsonProcessingException e) {
|
|
|
log.error("解析 WorkflowTask 消息失败, body: {}", body, e);
|
|
log.error("解析 WorkflowTask 消息失败, body: {}", body, e);
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.error("处理 WorkflowTask 消息异常, body: {}", body, e);
|
|
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ asyncTaskExecutor.execute(() -> {
|
|
|
|
|
+ try {
|
|
|
|
|
+ handleTaskMessage(taskMessage);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理 WorkflowTask 消息异常, taskId: {}", taskMessage.getTaskId(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void handleTaskMessage(WorkflowTaskMessage taskMessage) {
|
|
private void handleTaskMessage(WorkflowTaskMessage taskMessage) {
|
|
@@ -64,52 +79,55 @@ public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- LambdaUpdateWrapper<TAiOrderV2> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
|
|
- updateWrapper.eq(TAiOrderV2::getTaskId, taskId);
|
|
|
|
|
|
|
+ if (order.getTaskStatus() != null && (order.getTaskStatus() == 2 || order.getTaskStatus() == 3)) {
|
|
|
|
|
+ log.info("订单已处理, taskId={}, orderId={}, taskStatus={}, 跳过重复处理",
|
|
|
|
|
+ taskId, order.getId(), order.getTaskStatus());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (STATUS_SUCCESS.equals(taskMessage.getStatus())) {
|
|
if (STATUS_SUCCESS.equals(taskMessage.getStatus())) {
|
|
|
- String resultJson = buildResultJson(taskMessage.getData());
|
|
|
|
|
- updateWrapper.set(TAiOrderV2::getTaskStatus, 2)
|
|
|
|
|
- .set(TAiOrderV2::getResult, resultJson)
|
|
|
|
|
- .set(TAiOrderV2::getErrorMessage, null);
|
|
|
|
|
- aiOrderV2Service.update(updateWrapper);
|
|
|
|
|
- log.info("任务完成, taskId={}, orderId={}", taskId, order.getId());
|
|
|
|
|
-
|
|
|
|
|
- updateAlbumIfExists(order.getId(), taskMessage.getData());
|
|
|
|
|
|
|
+ handleSuccess(taskId, order, taskMessage.getData());
|
|
|
} else {
|
|
} else {
|
|
|
- updateWrapper.set(TAiOrderV2::getTaskStatus, 3)
|
|
|
|
|
- .set(TAiOrderV2::getErrorMessage, taskMessage.getMessage());
|
|
|
|
|
- aiOrderV2Service.update(updateWrapper);
|
|
|
|
|
- log.info("任务失败, taskId={}, orderId={}, status={}, message={}",
|
|
|
|
|
|
|
+ aiOrderV2Service.refundOrder(order, taskMessage.getMessage());
|
|
|
|
|
+ failAlbumIfExists(order.getId());
|
|
|
|
|
+ log.info("任务失败已退款, taskId={}, orderId={}, status={}, message={}",
|
|
|
taskId, order.getId(), taskMessage.getStatus(), taskMessage.getMessage());
|
|
taskId, order.getId(), taskMessage.getStatus(), taskMessage.getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private void handleSuccess(String taskId, TAiOrderV2 order, WorkflowTaskMessage.TaskData data) {
|
|
|
|
|
+ String imagesArrayJson = buildImagesArrayJson(data != null ? data.getImages() : null);
|
|
|
|
|
+ String videosArrayJson = buildVideosArrayJson(data != null ? data.getVideos() : null);
|
|
|
|
|
+
|
|
|
|
|
+ String resultJson = assembleResultJson(imagesArrayJson, videosArrayJson);
|
|
|
|
|
+ LambdaUpdateWrapper<TAiOrderV2> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
|
|
+ updateWrapper.eq(TAiOrderV2::getTaskId, taskId)
|
|
|
|
|
+ .set(TAiOrderV2::getTaskStatus, 2)
|
|
|
|
|
+ .set(TAiOrderV2::getResult, resultJson)
|
|
|
|
|
+ .set(TAiOrderV2::getErrorMessage, null);
|
|
|
|
|
+ aiOrderV2Service.update(updateWrapper);
|
|
|
|
|
+ log.info("任务完成, taskId={}, orderId={}", taskId, order.getId());
|
|
|
|
|
+
|
|
|
|
|
+ TAiAlbum album = updateAlbumIfExists(order.getId(), imagesArrayJson, videosArrayJson);
|
|
|
|
|
+ notifyUser(order, album);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * 构建 result JSON,格式:
|
|
|
|
|
|
|
+ * 组装 result JSON,格式:
|
|
|
* images → {"images":"[\"url1\",\"url2\"]"}
|
|
* images → {"images":"[\"url1\",\"url2\"]"}
|
|
|
* video → {"videos":"[{\"url\":\"...\",\"thumbnailUrl\":\"...\"}]"}
|
|
* video → {"videos":"[{\"url\":\"...\",\"thumbnailUrl\":\"...\"}]"}
|
|
|
*/
|
|
*/
|
|
|
- private String buildResultJson(WorkflowTaskMessage.TaskData data) {
|
|
|
|
|
- if (data == null) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ private String assembleResultJson(String imagesArrayJson, String videosArrayJson) {
|
|
|
Map<String, String> result = new LinkedHashMap<>();
|
|
Map<String, String> result = new LinkedHashMap<>();
|
|
|
- String imagesArrayJson = buildImagesArrayJson(data.getImages());
|
|
|
|
|
- String videosArrayJson = buildVideosArrayJson(data.getVideos());
|
|
|
|
|
-
|
|
|
|
|
if (imagesArrayJson != null) {
|
|
if (imagesArrayJson != null) {
|
|
|
result.put("images", imagesArrayJson);
|
|
result.put("images", imagesArrayJson);
|
|
|
}
|
|
}
|
|
|
if (videosArrayJson != null) {
|
|
if (videosArrayJson != null) {
|
|
|
result.put("videos", videosArrayJson);
|
|
result.put("videos", videosArrayJson);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
if (result.isEmpty()) {
|
|
if (result.isEmpty()) {
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
try {
|
|
try {
|
|
|
return objectMapper.writeValueAsString(result);
|
|
return objectMapper.writeValueAsString(result);
|
|
|
} catch (JsonProcessingException e) {
|
|
} catch (JsonProcessingException e) {
|
|
@@ -159,11 +177,11 @@ public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 根据 orderId 查找相册,若存在则将 images/video 数据更新到相册的 pictures/videos 字段
|
|
|
|
|
|
|
+ * 根据 orderId 查找相册,若存在则将预计算好的 images/videos JSON 更新到相册的 pictures/videos 字段
|
|
|
*/
|
|
*/
|
|
|
- private void updateAlbumIfExists(String orderId, WorkflowTaskMessage.TaskData data) {
|
|
|
|
|
- if (orderId == null || data == null) {
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ private TAiAlbum updateAlbumIfExists(String orderId, String imagesArrayJson, String videosArrayJson) {
|
|
|
|
|
+ if (orderId == null) {
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TAiAlbum album = aiAlbumService.getOne(
|
|
TAiAlbum album = aiAlbumService.getOne(
|
|
@@ -171,7 +189,7 @@ public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
);
|
|
);
|
|
|
if (album == null) {
|
|
if (album == null) {
|
|
|
log.info("orderId={} 无关联相册, 跳过相册更新", orderId);
|
|
log.info("orderId={} 无关联相册, 跳过相册更新", orderId);
|
|
|
- return;
|
|
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
LambdaUpdateWrapper<TAiAlbum> albumUpdate = new LambdaUpdateWrapper<>();
|
|
LambdaUpdateWrapper<TAiAlbum> albumUpdate = new LambdaUpdateWrapper<>();
|
|
@@ -179,13 +197,10 @@ public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
|
|
|
|
|
boolean needUpdate = false;
|
|
boolean needUpdate = false;
|
|
|
|
|
|
|
|
- String imagesArrayJson = buildImagesArrayJson(data.getImages());
|
|
|
|
|
if (imagesArrayJson != null) {
|
|
if (imagesArrayJson != null) {
|
|
|
albumUpdate.set(TAiAlbum::getPictures, imagesArrayJson);
|
|
albumUpdate.set(TAiAlbum::getPictures, imagesArrayJson);
|
|
|
needUpdate = true;
|
|
needUpdate = true;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- String videosArrayJson = buildVideosArrayJson(data.getVideos());
|
|
|
|
|
if (videosArrayJson != null) {
|
|
if (videosArrayJson != null) {
|
|
|
albumUpdate.set(TAiAlbum::getVideos, videosArrayJson);
|
|
albumUpdate.set(TAiAlbum::getVideos, videosArrayJson);
|
|
|
needUpdate = true;
|
|
needUpdate = true;
|
|
@@ -196,5 +211,60 @@ public class WorkflowTaskMessageListener implements MessageListener {
|
|
|
aiAlbumService.update(albumUpdate);
|
|
aiAlbumService.update(albumUpdate);
|
|
|
log.info("相册更新成功, albumId={}, orderId={}", album.getId(), orderId);
|
|
log.info("相册更新成功, albumId={}, orderId={}", album.getId(), orderId);
|
|
|
}
|
|
}
|
|
|
|
|
+ return album;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void failAlbumIfExists(String orderId) {
|
|
|
|
|
+ if (orderId == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ TAiAlbum album = aiAlbumService.getOne(
|
|
|
|
|
+ new LambdaQueryWrapper<TAiAlbum>().eq(TAiAlbum::getOrderId, orderId)
|
|
|
|
|
+ );
|
|
|
|
|
+ if (album == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ LambdaUpdateWrapper<TAiAlbum> albumUpdate = new LambdaUpdateWrapper<>();
|
|
|
|
|
+ albumUpdate.eq(TAiAlbum::getId, album.getId())
|
|
|
|
|
+ .set(TAiAlbum::getStatus, 0);
|
|
|
|
|
+ aiAlbumService.update(albumUpdate);
|
|
|
|
|
+ log.info("相册标记失败, albumId={}, orderId={}", album.getId(), orderId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void notifyUser(TAiOrderV2 order, TAiAlbum album) {
|
|
|
|
|
+ if (order.getUserId() == null || order.getStyleId() == null) {
|
|
|
|
|
+ log.warn("订单缺少 userId 或 styleId, 跳过消息通知, orderId={}", order.getId());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ TAiStyle style = aiStyleService.getById(order.getStyleId());
|
|
|
|
|
+ if (style == null) {
|
|
|
|
|
+ log.warn("未找到 styleId={} 对应的风格, 跳过消息通知", order.getStyleId());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String styleName = style.getName();
|
|
|
|
|
+ log.info("styleName:{}", styleName);
|
|
|
|
|
+
|
|
|
|
|
+ String title;
|
|
|
|
|
+ String content = switch (order.getOrderLang() != null ? order.getOrderLang() : "") {
|
|
|
|
|
+ case "zh_CN" -> {
|
|
|
|
|
+ title = "图像生成已完成";
|
|
|
|
|
+ yield String.format("「%s」中所述修改相应参数的值。现在可以从生成的相册中查看和下载图像。", styleName);
|
|
|
|
|
+ }
|
|
|
|
|
+ case "en_US" -> {
|
|
|
|
|
+ title = "Image creation completed";
|
|
|
|
|
+ yield String.format("「%s」 An image was generated. You can view and download images from generated albums.", styleName);
|
|
|
|
|
+ }
|
|
|
|
|
+ default -> {
|
|
|
|
|
+ title = "画像生成は完了しました";
|
|
|
|
|
+ yield String.format("「%s」の画像が生成されました。生成されたアルバムから画像を表示およびダウンロードできるようになりました。", styleName);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ Integer albumId = album != null ? album.getId().intValue() : null;
|
|
|
|
|
+ log.info("发送消息给用户:{}, orderLang:{}", order.getUserId(), order.getOrderLang());
|
|
|
|
|
+ userMessageService.sendMessage(order.getUserId(), title, content, order.getId(),
|
|
|
|
|
+ MSG_TYPE_ORDER_V2_FINISH, albumId, style.getCoverImg());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|