Merge branch 'dev/dev_xp' into dev/dev

# Conflicts:
#	src/main/java/com/ai/da/python/PythonService.java
This commit is contained in:
2025-03-25 11:25:22 +08:00
30 changed files with 1847 additions and 19 deletions

View File

@@ -1,24 +1,22 @@
package com.ai.da.common.RabbitMQ;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.model.dto.GenerateThroughImageTextDTO;
import com.ai.da.model.vo.GenerateResultVO;
import com.ai.da.model.vo.PoseTransformationVO;
import com.ai.da.service.GenerateService;
import com.ai.da.service.UserLikeGroupService;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.Time;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.io.IOException;
@@ -258,6 +256,55 @@ public class GenerateConsumer {
log.info("============ProcessRelightResult End listening==========");
}
public void processPoseTransformResult(Message msg, Channel channel) {
log.info("============ProcessPoseTransformResult listening==========");
long start = System.currentTimeMillis();
Map<String, String> generateResult = JSONObject.parseObject(msg.getBody(), Map.class);
log.info("PoseTransformation response : {}", generateResult);
try {
log.info("tasks_id : {} start ", generateResult.get("tasks_id"));
if (generateResult.get("status").equals("SUCCESS")) {
String gifUrl = generateResult.get("gif_url");
String taskId = generateResult.get("tasks_id");
String videoUrl = generateResult.get("video_url");
String imageUrl = generateResult.get("image_url");
generateService.processPoseTransformResult(taskId, gifUrl, videoUrl, imageUrl);
} else {
// 修改redis中的数据状态为exception
String key = generateResultKey + ":" + generateResult.get("tasks_id");
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中
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(generateResult.get("tasks_id"), generateResult.get("message"));
// 存redis
redisUtil.addToMap(exceptionMapKey, exceptionInfo);
}
} catch (Exception e) {
log.error(e.getMessage());
try {
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
// 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
redisUtil.removeFromZSet(consumptionOrderKey, generateResult.get("tasks_id"));
} catch (IOException exception) {
log.error("手动确认,取消返回队列,不再重新消费");
}
// 将入参和错误信息存入数据库
String exceptionMessage = JSONObject.toJSONString(generateResult) +
" Exception message " + e.getMessage();
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(String.valueOf(generateResult.get("tasks_id")), exceptionMessage);
// 存redis
redisUtil.addToMap(exceptionMapKey, exceptionInfo);
}
long end = System.currentTimeMillis();
log.info("tasks_id : {}, end , message : {}, 执行时长: {} 毫秒", generateResult.get("tasks_id"), generateResult.get("message"), (end - start));
log.info("============ProcessPoseTransformResult End listening==========");
}
@RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
@RabbitHandler
public void generateConsumer1(Message msg, Channel channel) {
@@ -329,4 +376,10 @@ public class GenerateConsumer {
public void getRelightResult(Message msg, Channel channel) {
processRelightResult(msg, channel);
}
@RabbitListener(queues = "#{rabbitMQProperties.queues.poseTransform}")
@RabbitHandler
public void getPoseTransformationResult(Message msg, Channel channel) {
processPoseTransformResult(msg, channel);
}
}

View File

@@ -20,6 +20,7 @@ public class RabbitMQProperties {
private String generateResult;
private String toProductImageResult;
private String relightResult;
private String poseTransform;
}
@Data

View File

@@ -30,6 +30,8 @@ public class CommonConstant {
public static final String GENERATE_LOGO_SINGLE_CANCEL = "/api/generate_single_logo_cancel/";
public static final String POSE_TRANSFORMATION_CANCEL = "/api/pose_transform_cancel/";
public static final String PYTHON_PORT_9996 = "9996";
public static final String PYTHON_PORT_9997 = "9997";

View File

@@ -35,6 +35,7 @@ public enum CreditsEventsEnum {
RELIGHT("Relight","5"),
QUESTIONNAIRE("Questionnaire","100"),
IMAGE_TO_SKETCH("ImageToSketch","5"),
POSE_TRANSFORMATION("PoseTransformation","10"),
OTHER("Other","5");

View File

@@ -174,7 +174,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
URL url = new URL(path);
return url.openStream();
} catch (IOException ioException) {
log.error("获取文件尺寸异常###{}###path##{}", ExceptionUtil.stacktraceToString(ioException), path);
log.error("获取文件异常###{}###path##{}", ExceptionUtil.stacktraceToString(ioException), path);
throw new BusinessException("get.file.failed");
}
}

View File

@@ -0,0 +1,168 @@
package com.ai.da.common.utils;
import com.ai.da.model.dto.BasicEmailParamDTO;
import com.alibaba.fastjson.JSONObject;
import com.sun.mail.smtp.SMTPTransport;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.*;
import java.util.List;
import java.util.Objects;
@Slf4j
@Component
public class MailUtil {
@Resource
private JavaMailSender javaMailSender;
@Resource
private TemplateEngine templateEngine;
/**
* 发送邮件 - 默认发件人
*
* @param basicEmailParamDTO 发送邮件所需参数
* @param inputStreamSource 附件(如果有)
*/
public int sendMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
MimeMessage mimeMessage = createSimpleMail(basicEmailParamDTO, fileName, inputStreamSource);
// 提取配置
String host;
String username;
String password;
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
host = ((JavaMailSenderImpl) javaMailSender).getHost();
} else {
host = basicEmailParamDTO.getServiceAddress();
}
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getSenderUser())) {
username = ((JavaMailSenderImpl) javaMailSender).getUsername();
} else {
username = basicEmailParamDTO.getSenderUser();
}
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
password = ((JavaMailSenderImpl) javaMailSender).getPassword();
} else {
password = basicEmailParamDTO.getPassword();
}
return sendMail(mimeMessage, host, username, password);
}
private int sendMail(MimeMessage mimeMessage, String host, String username, String password) throws MessagingException {
SMTPTransport transport = null;
try {
// 获取 SMTPTransport
transport = (SMTPTransport) mimeMessage.getSession().getTransport("smtp");
// 连接到 SMTP 服务器
transport.connect(host, username, password);
// 发送邮件
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
// 获取 SMTP 服务器的响应
String lastServerResponse = transport.getLastServerResponse();
int lastReturnCode = transport.getLastReturnCode();
log.info("SMTP 状态码: {}, SMTP 服务器响应: {}", lastReturnCode, lastServerResponse);
return lastReturnCode;
} catch (MailException | MessagingException e) {
// 记录日志或执行其他补偿逻辑
log.info("邮件发送失败:{}", e.getMessage());
} finally {
// 关闭连接
assert transport != null;
transport.close();
}
return 0;
}
/**
* 创建一封邮件
*
* @param basicEmailParamDTO 创建邮件需要的参数
* @param inputStreamSource 附件(如果有)
* @return 一封邮件
*/
private MimeMessage createSimpleMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
// 创建邮件对象
MimeMessage message = javaMailSender.createMimeMessage();
// 使用 MimeMessageHelper 简化邮件内容和附件的设置
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true);
// 设置发件人
mimeMessageHelper.setFrom(new InternetAddress(basicEmailParamDTO.getSenderUserMail()));
// 设置收件人
mimeMessageHelper.setTo(basicEmailParamDTO.getMailTo());
// 设置抄送人
if (basicEmailParamDTO.getCc() != null && basicEmailParamDTO.getCc().length > 0) {
mimeMessageHelper.setCc(basicEmailParamDTO.getCc());
}
// 设置暗送人
if (basicEmailParamDTO.getBcc() != null && basicEmailParamDTO.getBcc().length > 0) {
mimeMessageHelper.setBcc(basicEmailParamDTO.getBcc());
}
// 设置邮件主题
mimeMessageHelper.setSubject(basicEmailParamDTO.getSubject());
// 设置邮件内容HTML 格式)
mimeMessageHelper.setText(basicEmailParamDTO.getContent(), true);
// 设置附件
if (inputStreamSource != null) {
mimeMessageHelper.addAttachment(fileName, inputStreamSource);
}
return message;
}
/**
* 设置实体参数
*
* @param mailTo 接收邮件的邮箱地址
* @param jsonObject 模板中变量的值
* @return 返回一个MailEntity
* @throws AddressException 邮箱地址值异常
*/
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, JSONObject jsonObject, String templatePath, String title) throws AddressException {
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
basicEmailParamDTO.setSubject(title);
// todo 邮件模板不存在的报错与重试机制
basicEmailParamDTO.setContent(setContent(jsonObject, templatePath));
return basicEmailParamDTO;
}
/**
* 将地址转换为InternetAddress类型
*
* @param addressList 普通的地址字符串列表
* @return InternetAddress类型的地址列表
* @throws AddressException 地址异常
*/
public InternetAddress[] getInternetAddressList(List<String> addressList) throws AddressException {
InternetAddress[] toAddress = new InternetAddress[addressList.size()];
for (String address : addressList) {
toAddress[addressList.indexOf(address)] = new InternetAddress(address);
}
return toAddress;
}
public String setContent(JSONObject jsonObject, String templatePath) {
Context context = new Context();
if (Objects.nonNull(jsonObject)) {
for (String key : jsonObject.keySet()) {
context.setVariable(key, jsonObject.get(key));
}
}
return templateEngine.process(templatePath, context);
}
}