35 Commits

Author SHA1 Message Date
3c2b4ffc48 TASK: 画布数据 回参添加返回crossOrigin 2025-07-22 11:31:26 +08:00
b90df7468e TASK:管理员权限变更 2025-07-18 17:32:03 +08:00
370d9402f2 TASK: 试用邮件通知权限变更 2025-07-02 10:08:54 +08:00
4d518d05b9 TASK: 管理员页面访问权限变动 2025-07-02 09:18:22 +08:00
13514b277b BUGFIX:用户注册后重发验证码,验证不通过 2025-06-24 19:30:20 +08:00
d6c5d0e95d TASK:查询交易记录 添加显示总金额和付款者邮箱 2025-06-23 10:53:30 +08:00
301a62a563 TASK:添加管理员访问人员 2025-06-19 17:39:18 +08:00
22e5a97143 BUGFIX: 优惠券的佣金计算,统计时间边界问题优化 2025-06-13 11:18:55 +08:00
765d404845 TASK: 将generate,用户输入中的中文字符转换为英文字符 2025-06-11 15:34:00 +08:00
d5cf4e9d3f TASK: 添加“新增试用用户”通知对象chelseayu@code-create.com.hk 2025-06-08 09:19:36 +08:00
4b7fd649a3 TASK: 推广码 添加开始生效时间;优化数据计算类型,使用BigDecimal替换float;更新paidCommission后自动计算unpaidCommission 2025-06-06 19:37:38 +08:00
6249d53b7b BUGFIX: modifySketch 除library以外的地方修改,originalIdSource允许不传 2025-06-04 22:04:09 +08:00
b445f1f11e BUGFIX: modifySketch 在library中修改后需要保存到library 2025-06-04 15:49:55 +08:00
5c66ece467 1.关闭续订前七天邮件提醒
2.优化订阅邮件提醒,向redis存储已发送的邮件类型
2025-05-23 17:16:19 +08:00
3b6b0c7e2c TASK: prom code 开启佣金计费定时器和商家邮件通知 2025-05-22 16:37:41 +08:00
9a81fb7ee4 TASK:将PromotionCode合并到生产-test 2025-05-20 16:53:48 +08:00
31bb29f2fd Affiliate 允许为不同的用户设置不同的affiliate
Stripe 添加优惠券删除接口;限制优惠券只能在订阅时使用

(cherry picked from commit 200c0adfba)
2025-05-20 11:30:42 +08:00
c7b46229b5 删除优惠券
(cherry picked from commit 58af5c5570)
2025-05-19 17:29:06 +08:00
1482bb6ab2 Stripe推广码 部分功能完善
(cherry picked from commit 218d828e0d)
2025-05-19 17:28:52 +08:00
eae4087b3e Stripe支付--添加推广码功能及相应佣金计算
(cherry picked from commit 0ba28588da)
2025-05-19 17:13:28 +08:00
faf98607c4 优惠券查询DTO
(cherry picked from commit 1ce6c74f2c)
2025-05-19 17:04:51 +08:00
c19e9094d1 BUGFIX: generate mode字段传递不准确导致生成结果与图片没有关联 2025-05-09 17:03:42 +08:00
db55c5597f undividedLayers数据保存失败原因查找 2025-05-09 00:18:00 +08:00
0c79739867 BUGFIX: design之后,未分割图片的保存问题 2025-05-08 15:26:06 +08:00
e484f22788 BUGFIX : design 未分割图层保存问题 2025-05-08 14:54:12 +08:00
6a694cee18 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-05-08 14:19:41 +08:00
1a077edf0c designSingle 取消颜色限制 2025-05-08 14:19:26 +08:00
shahaibo
68926757dc Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-05-07 22:04:21 +08:00
shahaibo
eea57435e5 TASK:minio地址修改; 2025-05-07 22:04:10 +08:00
1f0e8f9cf2 BUGFIX: designSingle时,添加相同类型的服装导致未分割图层获取混乱 2025-05-07 14:10:42 +08:00
shahaibo
63ee41e3b8 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-03-31 17:47:33 +08:00
shahaibo
08072001a7 BUGFIX:dislike合并逻辑去除; 2025-03-31 17:47:25 +08:00
6b4d82a67d AiDA 8折优惠活动恢复 2025-03-31 17:45:16 +08:00
5612b5b1d4 AiDA 8折优惠活动 2025-03-31 09:48:09 +08:00
1d46a3b6d4 修改本地缓存的过期时间 2025-03-27 15:38:25 +08:00
387 changed files with 6706 additions and 28145 deletions

93
pom.xml
View File

@@ -29,10 +29,6 @@
<activation>1.1.1</activation>
<easy-captcha>1.6.2</easy-captcha>
<aws.java.sdk.version>2.20.43</aws.java.sdk.version>
<javacv.version>1.5.5</javacv.version>
<system.windowsx64>windows-x86_64</system.windowsx64>
<javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64>
</properties>
<dependencyManagement>
<dependencies>
@@ -163,7 +159,7 @@
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java-ses</artifactId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.572</version>
</dependency>
@@ -320,93 +316,6 @@
<version>1.41.5</version>
</dependency>
<!-- 邮件发送 -->
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
<!-- JSON 转义恢复 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.10.0</version> <!-- 使用最新版本 -->
</dependency>
<!-- 最新版本号https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java -->
<!-- 万象SDK -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>2.20.1</version>
</dependency>
<!-- FFmpeg封装JavaCV 视频转gif 全部依赖-->
<!--<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.9</version>
</dependency>-->
<!-- javacv+javacpp核心库-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>${javacv.version}</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp-platform</artifactId>
<version>${javacv.version}</version>
</dependency>
<!-- 最小opencv依赖包 必须包含上面的javacv+javacpp -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>opencv</artifactId>
<version>4.5.1-${javacv.version}</version>
<!--<classifier>${system.windowsx64}</classifier>-->
<classifier>${javacpp.platform.linux-x86_64}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas</artifactId>
<version>0.3.13-${javacv.version}</version>
<!--<classifier>${system.windowsx64}</classifier>-->
<classifier>${javacpp.platform.linux-x86_64}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>flycapture</artifactId>
<version>2.13.3.31-${javacv.version}</version>
<!--<classifier>${system.windowsx64}</classifier>-->
<classifier>${javacpp.platform.linux-x86_64}</classifier>
</dependency>
<!-- FFmpeg视频处理解决你的报错 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.4-1.5.6</version>
<!--<classifier>${system.windowsx64}</classifier>-->
<classifier>${javacpp.platform.linux-x86_64}</classifier>
</dependency>
<!-- GIFEncoder 视频转gif-->
<dependency>
<groupId>com.madgag</groupId>
<artifactId>animated-gif-lib</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>

View File

@@ -3,13 +3,11 @@ package com.ai.da;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@Slf4j
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class AiDaApplication {
public static void main(String[] args) {

View File

@@ -1,96 +0,0 @@
package com.ai.da.common.RabbitMQ;
import com.ai.da.common.utils.MailUtil;
import com.ai.da.model.dto.BasicEmailParamDTO;
import com.ai.da.service.EmailService;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.core.io.InputStreamSource;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.core.exception.RetryableException;
import org.springframework.amqp.core.Message;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class EmailRetryConsumer {
@Resource
private MailUtil mailUtil;
@Resource
private MQPublisher mqPublisher;
@Resource
private EmailService emailService;
// @RabbitListener(queues = "#{rabbitMQProperties.deadLetter.queue}")
public void handleRetry(Map<String, String> mailParams, Message message, Channel channel) throws IOException {
long tag = message.getMessageProperties().getDeliveryTag();
try {
log.info("死信队列收到消息:{}", message);
// 处理邮件发送参数
BasicEmailParamDTO basicEmailParamDTO = JSONObject.parseObject(mailParams.get("dto"), BasicEmailParamDTO.class);
String fileName = mailParams.get("filename");
InputStreamSource inputStreamSource = Objects.isNull(mailParams.get("source")) ?
null : JSONObject.parseObject(mailParams.get("source"), InputStreamSource.class);
JSONObject templateParams = JSONObject.parseObject(mailParams.get("templateParams"), JSONObject.class);
String templateName = mailParams.get("templatePath");
long logId = Long.parseLong(mailParams.get("logId"));
basicEmailParamDTO.setContent(mailUtil.setContent(templateParams, templateName));
// 发邮件
int lastReturnCode = mailUtil.sendMail(basicEmailParamDTO, fileName, inputStreamSource);
if (lastReturnCode == 250) {
log.info("邮件发送成功Subject : {}", basicEmailParamDTO.getSubject());
emailService.updateStatus(logId, EmailService.DELIVERED);
} else if (lastReturnCode == 450) {
log.info("目标邮箱 {} 暂时不可用,请稍后重试", (Object) basicEmailParamDTO.getMailTo());
// 重试
retry(mailParams, message, channel, tag, logId);
} else if (lastReturnCode == 550) {
log.info("目标邮箱 {} 不可用,邮件发送失败", (Object) basicEmailParamDTO.getMailTo());
emailService.updateStatus(logId, EmailService.FAILED);
} else {
log.info("邮件发送失败Subject : {}, 状态码: {}", basicEmailParamDTO.getSubject(), lastReturnCode);
retry(mailParams, message, channel, tag, logId);
emailService.updateStatus(logId, EmailService.FAILED);
}
channel.basicAck(tag, false);
} catch (RetryableException e) {
log.info("邮件重试发生异常:RetryableException -> {}", e.getMessage());
channel.basicAck(tag, false); // 确认原消息
} catch (Exception e) {
log.info("邮件重试发生异常:Exception -> {}", e.getMessage());
channel.basicAck(tag, false); // 确认原消息
}
}
private int getRetryAttempt(Message message) {
Integer attempt = message.getMessageProperties()
.getHeader("x-retry-attempt");
return attempt != null ? attempt : 1;
}
private void retry(Map<String, String> mailParams, Message message, Channel channel, long tag, long logId) throws IOException{
int attempt = getRetryAttempt(message);
if (attempt >= 3) { // 最大重试次数
channel.basicReject(tag, false);
emailService.updateStatus(logId, EmailService.FAILED);
log.error("重试结束,邮件最终发送失败: {}", mailParams);
} else {
log.info("重新将邮件信息发送到重试队列");
mqPublisher.sendEmailMsg(mailParams, attempt);
channel.basicAck(tag, false); // 确认原消息
// 更新数据库
emailService.updateRetryCount(logId, attempt + 1);
}
}
}

View File

@@ -5,20 +5,13 @@ 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.CloudTaskService;
import com.ai.da.service.DesignService;
import com.ai.da.service.GenerateService;
import com.ai.da.service.UserLikeGroupService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;
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;
@@ -29,10 +22,8 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
@@ -45,12 +36,6 @@ public class GenerateConsumer {
@Resource
private UserLikeGroupService userLikeGroupService;
@Resource
private DesignService designService;
@Resource
private CloudTaskService cloudTaskService;
@Autowired
private RabbitMQProperties rabbitMQProperties;
@@ -76,9 +61,9 @@ public class GenerateConsumer {
public void generate(Message msg, Channel channel, String consumerName) {
log.info("============start listening==========");
long start = System.currentTimeMillis();
Map<String, String> resp = jsonBytesToMap(msg, channel);
String uniqueId = resp.get("tasks_id");
// String uniqueId = generateThroughImageTextDTO.getUniqueId();
GenerateThroughImageTextDTO generateThroughImageTextDTO = JSONObject.parseObject(msg.getBody(), GenerateThroughImageTextDTO.class);
String uniqueId = generateThroughImageTextDTO.getUniqueId();
log.info("From " + consumerName + " : " + uniqueId);
try {
@@ -92,7 +77,6 @@ public class GenerateConsumer {
log.error("手动确认,不返回队列重新消费");
}
} else {
GenerateThroughImageTextDTO generateThroughImageTextDTO = JSONObject.parseObject(msg.getBody(), GenerateThroughImageTextDTO.class);
generateService.generateThroughImageText(generateThroughImageTextDTO);
// 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
redisUtil.removeFromZSet(consumptionOrderKey, uniqueId);
@@ -107,13 +91,13 @@ public class GenerateConsumer {
// 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
redisUtil.removeFromZSet(consumptionOrderKey, uniqueId);
String key = generateResultKey + ":" + uniqueId;
GenerateResultVO generateResultVO = new GenerateResultVO(uniqueId, null, null, "Fail");
GenerateResultVO generateResultVO = new GenerateResultVO(generateThroughImageTextDTO.getUniqueId(), null, null, "Fail");
redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
} catch (IOException exception) {
log.error("手动确认,取消返回队列,不再重新消费");
}
// 将入参和错误信息存入数据库
String exceptionMessage = JSONObject.toJSONString(resp) +
String exceptionMessage = JSONObject.toJSONString(generateThroughImageTextDTO) +
" Exception message " + e.getMessage();
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(String.valueOf(uniqueId), exceptionMessage);
@@ -130,7 +114,7 @@ public class GenerateConsumer {
log.info("============ProcessGenerateResult listening==========");
long start = System.currentTimeMillis();
Map<String, String> generateResult = jsonBytesToMap(msg, channel);
Map<String, String> generateResult = JSONObject.parseObject(msg.getBody(), Map.class);
log.info("generate response : {}", generateResult);
try {
@@ -178,7 +162,7 @@ public class GenerateConsumer {
log.info("============processToProductImageResult listening==========");
long start = System.currentTimeMillis();
Map<String, String> generateResult = jsonBytesToMap(msg, channel);
Map<String, String> generateResult = JSONObject.parseObject(msg.getBody(), Map.class);
log.info("toProductImage response : {}", generateResult);
try {
@@ -194,7 +178,6 @@ public class GenerateConsumer {
} else {
// 修改redis中的数据状态为exception
String key = toProductImageResultKey + ":" + generateResult.get("tasks_id");
generateService.updateToProductTaskStatus(generateResult.get("tasks_id"), "Fail");
redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.get("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>();
@@ -229,7 +212,7 @@ public class GenerateConsumer {
log.info("============processRelightResult listening==========");
long start = System.currentTimeMillis();
Map<String, String> generateResult = jsonBytesToMap(msg, channel);
Map<String, String> generateResult = JSONObject.parseObject(msg.getBody(), Map.class);
log.info("toProductImage response : {}", generateResult);
try {
@@ -245,7 +228,6 @@ public class GenerateConsumer {
} else {
// 修改redis中的数据状态为exception
String key = relightResultKey + ":" + generateResult.get("tasks_id");
generateService.updateToProductTaskStatus(generateResult.get("tasks_id"), "Fail");
redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.get("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>();
@@ -276,291 +258,6 @@ 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 = jsonBytesToMap(msg, channel);
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");
generateService.updatePoseTransferStatus(generateResult.get("tasks_id"), "Fail", null);
redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.get("tasks_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到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==========");
}
public static Map<String, String> jsonBytesToMap(Message msg, Channel channel) {
try {
// 1. byte[] -> String
String jsonString = new String(msg.getBody(), StandardCharsets.UTF_8).trim();
// 2. 处理可能的双重转义
if (jsonString.startsWith("\"") && jsonString.endsWith("\"")) {
jsonString = jsonString.substring(1, jsonString.length() - 1);
// 使用 Apache Commons Text 将 JSON 字符串中的转义字符还原为原始字符
jsonString = StringEscapeUtils.unescapeJson(jsonString);
}
// 3. 验证 JSON 格式
if (!isValidJson(jsonString)) {
throw new IllegalArgumentException("Invalid JSON format");
}
// 4. 解析为 Map
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonString, new TypeReference<Map<String, String>>() {});
} catch (Exception e) {
log.error("消息解析失败: {}", e.getMessage(), e);
try {
// 仅对不可恢复错误(如非 JSON 数据)进行 ACK
if (e instanceof JsonParseException || e instanceof IllegalArgumentException) {
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
log.warn("因消息格式错误,已确认并丢弃消息。原始消息为:{}", msg);
}
} catch (IOException ex) {
log.error("消息确认失败: {}", ex.getMessage(), ex);
}
throw new RuntimeException("Failed to parse JSON to Map", e);
}
}
// 辅助方法:验证字符串是否为合法 JSON
private static boolean isValidJson(String json) {
try {
new ObjectMapper().readTree(json);
return true;
} catch (Exception e) {
return false;
}
}
private void processDesignBatchResult(Message msg, Channel channel) {
log.info("============processDesignBatchResult listening==========");
long start = System.currentTimeMillis();
Map<String, Object> generateResult = JSONObject.parseObject(msg.getBody(), Map.class);
log.info("designBatch response : {}", generateResult);
designService.processDesignBatch(generateResult);
}
private void processToProductImageBatchResult(Message msg, Channel channel) {
log.info("============processToProductImageResultBatch listening==========");
long start = System.currentTimeMillis();
JSONObject generateResult = JSONObject.parseObject(msg.getBody(), JSONObject.class);
log.info("toProductImageBatch response : {}", generateResult);
try {
log.info("task_id : {} start ", generateResult.get("task_id"));
if (!StringUtils.isEmpty(generateResult.getString("progress"))) {
String progress = generateResult.getString("progress");
String url = null;
if (!progress.startsWith("0") && !progress.equals("OK")) {
JSONObject result = generateResult.getJSONObject("result");
if (Objects.nonNull(result)) {
url = result.getString("product_img");
String taskId = generateResult.getString("task_id");
userLikeGroupService.toProductBatch(taskId, url, progress);
}
} else if (progress.startsWith("0/")) {
String batchTaskId = generateResult.getString("task_id");
if (!StringUtils.isEmpty(batchTaskId)) {
cloudTaskService.startTask(batchTaskId);
}
} else if (progress.equals("OK")) {
String batchTaskId = generateResult.getString("task_id");
if (!StringUtils.isEmpty(batchTaskId)) {
cloudTaskService.completeTask(batchTaskId);
}
}
} else {
// 修改redis中的数据状态为exception
String key = toProductImageResultKey + ":" + generateResult.get("task_id");
generateService.updateToProductTaskStatus(generateResult.getString("task_id"), "Fail");
redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.getString("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(generateResult.getString("task_id"), generateResult.getString("data"));
// 存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.getString("task_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("task_id")), exceptionMessage);
// 存redis
redisUtil.addToMap(exceptionMapKey, exceptionInfo);
}
long end = System.currentTimeMillis();
log.info("task_id : {}, end , message : {}, 执行时长: {} 毫秒", generateResult.get("task_id"), generateResult.get("message"), (end - start));
log.info("============ProcessToProductImageBatchResult End listening==========");
}
private void processRelightBatchResult(Message msg, Channel channel) {
log.info("============processRelightResult listening==========");
long start = System.currentTimeMillis();
JSONObject generateResult = JSONObject.parseObject(msg.getBody(), JSONObject.class);
log.info("relightBatch response : {}", generateResult);
try {
log.info("task_id : {} start ", generateResult.get("task_id"));
if (!StringUtils.isEmpty(generateResult.getString("progress"))) {
String progress = generateResult.getString("progress");
String url = null;
if (!progress.startsWith("0") && !progress.equals("OK")) {
JSONObject result = generateResult.getJSONObject("result");
if (Objects.nonNull(result)) {
url = result.getString("relight_img");
String taskId = generateResult.getString("task_id");
userLikeGroupService.relightBatch(taskId, url, progress);
}
} else if (progress.startsWith("0/")) {
String batchTaskId = generateResult.getString("task_id");
if (!StringUtils.isEmpty(batchTaskId)) {
cloudTaskService.startTask(batchTaskId);
}
} else if (progress.equals("OK")) {
String batchTaskId = generateResult.getString("task_id");
if (!StringUtils.isEmpty(batchTaskId)) {
cloudTaskService.completeTask(batchTaskId);
}
}
} else {
// 修改redis中的数据状态为exception
String key = relightResultKey + ":" + generateResult.get("task_id");
generateService.updateToProductTaskStatus(generateResult.getString("task_id"), "Fail");
redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.getString("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(generateResult.getString("task_id"), generateResult.getString("data"));
// 存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.getString("task_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("task_id")), exceptionMessage);
// 存redis
redisUtil.addToMap(exceptionMapKey, exceptionInfo);
}
long end = System.currentTimeMillis();
log.info("task_id : {}, end , message : {}, 执行时长: {} 毫秒", generateResult.get("task_id"), generateResult.get("message"), (end - start));
log.info("============ProcessRelightBatchResult End listening==========");
}
private void processPoseTransformBatchResult(Message msg, Channel channel) {
log.info("============ProcessPoseTransformBatchResult listening==========");
long start = System.currentTimeMillis();
JSONObject generateResult = JSONObject.parseObject(msg.getBody(), JSONObject.class);
log.info("PoseTransformationBatch response : {}", generateResult);
try {
log.info("task_id : {} start ", generateResult.get("task_id"));
if (!StringUtils.isEmpty(generateResult.getString("progress"))) {
String progress = generateResult.getString("progress");
String taskId = generateResult.getString("task_id");
generateService.processPoseTransformResultBatch(progress, taskId);
JSONArray result = generateResult.getJSONArray("result");
if (!StringUtils.isEmpty(result)) {
JSONObject jsonObject = result.getJSONObject(0);
String gifUrl = jsonObject.getString("gif_url");
String videoUrl = jsonObject.getString("video_url");
String imageUrl = jsonObject.getString("first_image_url");
generateService.processPoseTransformResultBatch(taskId, gifUrl, videoUrl, imageUrl, progress);
}
} else {
// 修改redis中的数据状态为exception
String key = generateResultKey + ":" + generateResult.getString("task_id");
generateService.updatePoseTransferStatus(generateResult.getString("task_id"), "Fail", null);
redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.getString("task_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 将异常信息存到exception中
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(generateResult.getString("task_id"), generateResult.getString("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.getString("task_id"));
} catch (IOException exception) {
log.error("手动确认,取消返回队列,不再重新消费");
}
// 将入参和错误信息存入数据库
String exceptionMessage = JSONObject.toJSONString(generateResult) +
" Exception message " + e.getMessage();
HashMap<String, String> exceptionInfo = new HashMap<>();
exceptionInfo.put(generateResult.getString("task_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) {
@@ -632,32 +329,4 @@ 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);
}
@RabbitListener(queues = "#{rabbitMQProperties.queues.designBatch}")
@RabbitHandler
public void getDesignBatchResult(Message msg, Channel channel) {
processDesignBatchResult(msg, channel);
}
@RabbitListener(queues = "#{rabbitMQProperties.queues.toProductImageBatch}")
@RabbitHandler
public void getToProductImageBatchResult(Message msg, Channel channel) {
processToProductImageBatchResult(msg, channel);
}
@RabbitListener(queues = "#{rabbitMQProperties.queues.relightBatch}")
@RabbitHandler
public void getRelightBatchResult(Message msg, Channel channel) {
processRelightBatchResult(msg, channel);
}
@RabbitListener(queues = "#{rabbitMQProperties.queues.poseTransformBatch}")
@RabbitHandler
public void getPoseTransformBatchResult(Message msg, Channel channel) {
processPoseTransformBatchResult(msg, channel);
}
}

View File

@@ -1,82 +1,43 @@
package com.ai.da.common.RabbitMQ;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MQConfig {
@Autowired
private RabbitMQProperties rabbitMQProperties;
@Bean
public Queue generateQueue() {
return new Queue(rabbitMQProperties.getQueues().getGenerate());
}
@Bean
public Queue SRQueue() {
return new Queue(rabbitMQProperties.getQueues().getSr());
}
@Bean
public Queue SRResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getSrResult());
}
@Bean
public Queue generateResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getGenerateResult());
}
@Bean
public Queue toProductImageResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getToProductImageResult());
}
@Bean
public Queue relightResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getRelightResult());
}
@Bean
public Queue poseTransformQueue() {
return new Queue(rabbitMQProperties.getQueues().getPoseTransform());
}
@Bean
public Queue mailRetryQueue() {
// 普通队列不绑定DLX首次失败后才进入MQ
// durable 持久化队列
return QueueBuilder.durable(rabbitMQProperties.getQueues().getEmailRetry())
// 关键参数:绑定死信交换机
.withArgument("x-dead-letter-exchange", rabbitMQProperties.getDeadLetter().getExchange())
// 可选:指定死信路由键(默认使用原消息的路由键)
.withArgument("x-dead-letter-routing-key", rabbitMQProperties.getDeadLetter().getRoutingKey())
.build();
}
// 新增死信交换机
@Bean
public DirectExchange deadLetterExchange() {
return new DirectExchange(rabbitMQProperties.getDeadLetter().getExchange());
}
// 新增死信队列
@Bean
public Queue deadLetterQueue() {
return QueueBuilder.durable(rabbitMQProperties.getDeadLetter().getQueue()).build();
}
// 绑定死信队列
@Bean
public Binding deadLetterBinding() {
return BindingBuilder.bind(deadLetterQueue())
.to(deadLetterExchange())
.with(rabbitMQProperties.getDeadLetter().getRoutingKey());
}
}
package com.ai.da.common.RabbitMQ;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MQConfig {
@Autowired
private RabbitMQProperties rabbitMQProperties;
@Bean
public Queue generateQueue() {
return new Queue(rabbitMQProperties.getQueues().getGenerate());
}
@Bean
public Queue SRQueue() {
return new Queue(rabbitMQProperties.getQueues().getSr());
}
@Bean
public Queue SRResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getSrResult());
}
@Bean
public Queue generateResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getGenerateResult());
}
@Bean
public Queue toProductImageResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getToProductImageResult());
}
@Bean
public Queue relightResultQueue() {
return new Queue(rabbitMQProperties.getQueues().getRelightResult());
}
}

View File

@@ -1,56 +1,29 @@
package com.ai.da.common.RabbitMQ;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
@Slf4j
@Component
public class MQPublisher {
@Autowired
private RabbitMQProperties rabbitMQProperties;
@Autowired
private AmqpTemplate amqpTemplate;
public void sendGenerateMessage(String mm) {
log.info("send generate message: {}", mm);
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getGenerate(), mm);
}
public void sendSRMessage(String mm) {
log.info("send message: {}", mm);
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getSr(), mm);
}
/**
*
* @param mailParams 含有的字段
* {"dto": basicEmailParamDTO, "filename": fileName, "source": inputStreamSource,
* "templateParams": jsonObject, "templatePath": path}
* 邮件发送参数,附件文件名,附件数据
* @param retryTimes 重试次数初始为0
*/
public void sendEmailMsg(Map<String, String> mailParams, int retryTimes){
log.info("send email MQ message: {} ", mailParams);
// // 重新入队(指数退避) 时间单位:毫秒
long newDelay = (long) (5000 * Math.pow(2, retryTimes + 1));
log.info("send email MQ delay: {} ms, retry attempt: {}", newDelay, retryTimes + 1);
amqpTemplate.convertAndSend(
rabbitMQProperties.getQueues().getEmailRetry(),
mailParams,
m -> {
m.getMessageProperties().setExpiration(String.valueOf(newDelay));
m.getMessageProperties().setHeader("x-retry-attempt", retryTimes + 1);
return m;
}
);
}
}
package com.ai.da.common.RabbitMQ;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Slf4j
@Component
public class MQPublisher {
@Autowired
private RabbitMQProperties rabbitMQProperties;
@Autowired
private AmqpTemplate amqpTemplate;
public void sendGenerateMessage(String mm) {
log.info("send message: " + mm);
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getGenerate(), mm);
}
public void sendSRMessage(String mm) {
log.info("send message: " + mm);
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getSr(), mm);
}
}

View File

@@ -1,45 +1,30 @@
package com.ai.da.common.RabbitMQ;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "rabbitmq")
@Data
public class RabbitMQProperties {
private Queues queues;
private Exchange exchange;
private DeadLetter deadLetter; // 新增死信配置
@Data
public static class Queues {
private String generate;
private String sr;
private String srResult;
private String generateResult;
private String toProductImageResult;
private String relightResult;
private String poseTransform;
private String emailRetry;
private String designBatch;
private String relightBatch;
private String toProductImageBatch;
private String poseTransformBatch;
}
@Data
public static class Exchange {
private String generate;
}
// 新增死信配置内部类
@Data
public static class DeadLetter {
private String exchange;
private String queue;
private String routingKey;
}
}
package com.ai.da.common.RabbitMQ;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "rabbitmq")
@Data
public class RabbitMQProperties {
private Queues queues;
private Exchange exchange;
@Data
public static class Queues {
private String generate;
private String sr;
private String srResult;
private String generateResult;
private String toProductImageResult;
private String relightResult;
}
@Data
public static class Exchange {
private String generate;
}
}

View File

@@ -1,21 +0,0 @@
package com.ai.da.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
public class AsyncConfig {
@Bean("asyncTaskExecutor")
public Executor asyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("Async-ImageToSketch-");
executor.initialize();
return executor;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,260 +0,0 @@
package com.ai.da.common.config;
import com.ai.da.common.utils.MinioUtil;
import com.ai.da.mapper.primary.ThreeDDetailMapper;
import com.ai.da.mapper.primary.ThreeDLayoutMapper;
import com.ai.da.mapper.primary.ThreeDPatternLayoutMapper;
import com.ai.da.mapper.primary.ThreeDSimpleMapper;
import com.ai.da.mapper.primary.entity.ThreeDDetail;
import com.ai.da.mapper.primary.entity.ThreeDLayout;
import com.ai.da.mapper.primary.entity.ThreeDPatternLayout;
import com.ai.da.mapper.primary.entity.ThreeDSimple;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Slf4j
@Component
public class ThreeDSave {
@Resource
private ThreeDDetailMapper threeDDetailMapper;
@Resource
private ThreeDSimpleMapper threeDSimpleMapper;
@Resource
private MinioUtil minioUtil;
@Resource
private ThreeDLayoutMapper threeDLayoutMapper;
@Resource
private ThreeDPatternLayoutMapper threeDPatternLayoutMapper;
@PostConstruct
public void test() {
// minioSave();
// frontBackDataCreate();
// patternDataCreate();
}
private void patternDataCreate() {
QueryWrapper<ThreeDSimple> qw = new QueryWrapper<>();
qw.lambda().eq(ThreeDSimple::getGender, "female");
qw.lambda().ne(ThreeDSimple::getId, 1);
List<ThreeDSimple> threeDSimpleList = threeDSimpleMapper.selectList(qw);
List<Integer> numbers = new ArrayList<>();
String patternPath = "C:\\workspace\\3D\\3D虚拟 1-7\\6.版文件、dxf文件\\女装系列(1)\\女装系列\\56款打版截图";
File directory = new File(patternPath);
if (directory.exists() && directory.isDirectory()) {
// 获取目录下的所有文件名,并建立编号 -> 文件名的映射
Map<Integer, String> fileMap = Arrays.stream(directory.listFiles())
.filter(File::isFile) // 只获取文件
.map(File::getName) // 获取文件名
.collect(Collectors.toMap(
name -> {
Matcher matcher = Pattern.compile("^\\d+").matcher(name);
return matcher.find() ? Integer.parseInt(matcher.group()) : -1;
},
name -> name,
(existing, replacement) -> existing // 处理重复情况,保留原有值
));
for (ThreeDSimple threeDSimple : threeDSimpleList) {
String name = threeDSimple.getName();
Pattern pattern = Pattern.compile("^\\d+"); // 匹配开头的数字
Matcher matcher = pattern.matcher(name);
if (matcher.find()) {
int number = Integer.parseInt(matcher.group());
numbers.add(number);
// 匹配对应文件夹,并获取文件
if (fileMap.containsKey(number)) {
String matchedFolder = fileMap.get(number);
File folder = new File(directory, matchedFolder);
ThreeDPatternLayout threeDPatternLayout = new ThreeDPatternLayout();
threeDPatternLayout.setThreeDSimpleId(threeDSimple.getId());
threeDPatternLayout.setName(matchedFolder);
String minioUrl = "aida-threed/female/pattern-layout/" + matchedFolder;
minioUtil.upload(minioUrl, folder);
threeDPatternLayout.setUrl(minioUrl);
// threeDPatternLayoutMapper.insert(threeDPatternLayout);
}
}
}
System.out.println("文件编号映射:" + fileMap);
}
}
private void frontBackDataCreate() {
QueryWrapper<ThreeDSimple> qw = new QueryWrapper<>();
qw.lambda().eq(ThreeDSimple::getGender, "female");
// qw.lambda().ne(ThreeDSimple::getId, 1);
List<ThreeDSimple> threeDSimpleList = threeDSimpleMapper.selectList(qw);
List<Integer> numbers = new ArrayList<>();
// 文件夹名列表
String path = "C:\\workspace\\3D\\3D虚拟 1-7\\3D服装真反面整理\\female"; // 目标路径
File directory = new File(path);
if (directory.exists() && directory.isDirectory()) {
// 获取文件夹名列表,并建立编号 -> 文件夹名的映射
Map<Integer, String> folderMap = Arrays.stream(directory.listFiles())
.filter(File::isDirectory)
.map(File::getName)
.collect(Collectors.toMap(
name -> {
Matcher matcher = Pattern.compile("^\\d+").matcher(name);
return matcher.find() ? Integer.parseInt(matcher.group()) : -1;
},
name -> name,
(existing, replacement) -> existing // 处理重复情况,保留原有值
));
System.out.println("文件夹编号映射:" + folderMap);
for (ThreeDSimple threeDSimple : threeDSimpleList) {
String name = threeDSimple.getName();
Pattern pattern = Pattern.compile("^\\d+"); // 匹配开头的数字
Matcher matcher = pattern.matcher(name);
if (matcher.find()) {
int number = Integer.parseInt(matcher.group());
numbers.add(number);
// 匹配对应文件夹,并获取文件
if (folderMap.containsKey(number)) {
String matchedFolder = folderMap.get(number);
File folder = new File(directory, matchedFolder);
if (folder.exists() && folder.isDirectory()) {
for (File file : folder.listFiles()) {
String fileName = file.getName(); // 去掉后缀
ThreeDLayout threeDLayout = new ThreeDLayout();
threeDLayout.setGender("female");
threeDLayout.setThreeDSimpleId(threeDSimple.getId());
threeDLayout.setName(file.getName());
if (fileName.startsWith("")) {
threeDLayout.setType("front");
}else if (fileName.startsWith("")) {
threeDLayout.setType("back");
}
String minioUrl = "aida-threed/female/layout/" + folderMap.get(number) + " " + file.getName();
minioUtil.upload(minioUrl, file);
threeDLayout.setUrl(minioUrl);
// threeDLayoutMapper.insert(threeDLayout);
}
}
}
}
}
System.out.println(numbers);
} else {
System.out.println("路径不存在或不是文件夹");
}
}
private void minioSave() {
// 指定目标文件夹路径
String folderPath = "C:\\workspace\\3D\\3D虚拟 1-7\\3D服装整理\\maleZip";
// 创建文件对象
File folder = new File(folderPath);
// 检查文件夹是否存在且是目录
if (folder.exists() && folder.isDirectory()) {
// 获取所有 .zip 文件
File[] zipFiles = folder.listFiles((dir, name) -> name.toLowerCase().endsWith(".zip"));
List<String> zipFileNameList = new ArrayList<>();
// 输出文件名
if (zipFiles != null) {
for (File file : zipFiles) {
String zipFileName = file.getName();
String[] split = zipFileName.split("_");
String zipName = split[0];
String sizeWithSuffix = split[1];
String[] sizeWithSuffixSplit = sizeWithSuffix.split("\\.");
String size = sizeWithSuffixSplit[0];
// 找到第一个字母的位置
int index = 0;
while (index < size.length() && Character.UnicodeBlock.of(size.charAt(index)) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) {
index++;
}
if (index > 0 && index < size.length()) {
String prefix = size.substring(0, index); // "亚码"
String suffix = size.substring(index); // "L"
ThreeDDetail threeDDetail = new ThreeDDetail();
threeDDetail.setName(zipFileName);
String url = "aida-threed/male/zip/" + zipFileName;
threeDDetail.setGender("male");
threeDDetail.setSizeType(prefix);
threeDDetail.setSize(suffix);
threeDDetail.setUrl(url);
// threeDDetailMapper.insert(threeDDetail);
minioUtil.upload(url, file);
QueryWrapper<ThreeDSimple> qw = new QueryWrapper<>();
qw.lambda().eq(ThreeDSimple::getName, zipName);
qw.lambda().eq(ThreeDSimple::getGender, "male");
List<ThreeDSimple> threeDSimples = threeDSimpleMapper.selectList(qw);
if (CollectionUtils.isEmpty(threeDSimples)) {
ThreeDSimple threeDSimple = new ThreeDSimple();
threeDSimple.setName(zipName);
threeDSimple.setGender("male");
String glbPath = "C:\\workspace\\3D\\3D虚拟 1-7\\3D服装整理\\male\\" + zipName + "\\" +"亚码L";
File glbFolder = new File(glbPath);
// 查找 .glb 文件
if (glbFolder.exists() && glbFolder.isDirectory()) {
File[] glbFiles = glbFolder.listFiles((dir, name) -> name.toLowerCase().endsWith(".glb"));
if (glbFiles != null && glbFiles.length > 0) {
for (File glbFile : glbFiles) {
String name = glbFile.getName();
String glbUrl = "aida-threed/male/glb/" + name;
threeDSimple.setUrl(glbUrl);
minioUtil.upload(glbUrl, glbFile);
}
} else {
System.out.println("未找到 GLB 文件。" + glbFolder);
}
} else {
System.out.println("GLB 文件夹不存在: " + glbPath);
}
// threeDSimpleMapper.insert(threeDSimple);
threeDDetail.setThreeDSimpleId(threeDSimple.getId());
threeDDetailMapper.updateById(threeDDetail);
}else {
Long id = threeDSimples.get(0).getId();
threeDDetail.setThreeDSimpleId(id);
threeDDetailMapper.updateById(threeDDetail);
}
} else {
}
}
} else {
System.out.println("未找到 ZIP 文件。");
}
log.info("aaa");
} else {
System.out.println("文件夹不存在或不是一个目录。");
}
}
}

View File

@@ -13,6 +13,8 @@ public class CommonConstant {
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60;
// 单位 秒 一天过期 in redis
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
// 单位 秒 7天过期
public static final Long REDIS_SET_EXPIRE_TIME = 24 * 60 * 60 * 7L;
public static class Numbers{
public static final Integer NUMBER_10 = 10;
@@ -30,8 +32,6 @@ 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";
@@ -81,11 +81,7 @@ public class CommonConstant {
public static final String TIME_FORMAT_MMM_dd_yyyy = "MMM. dd, yyyy";
public static final String TIME_FORMAT_yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
public static final String AFFILIATE_LINK = "https://www.aida.com.hk?ref=";
public static final String PARTIAL_DESIGN_FILENAME = "PartialDesign";
public static final String PARTIAL_DESIGN_PREVIEW_FILENAME = "Preview";
}

View File

@@ -31,7 +31,9 @@ public enum AuthenticationOperationTypeEnum {
/**
* 填写用户国家和职业
*/
UPDATE_USERINFO;
UPDATE_USERINFO,
REGISTER;
public static AuthenticationOperationTypeEnum of(String name) {
return Stream.of(AuthenticationOperationTypeEnum.values()).filter(v -> v.name().equals(name)).findFirst().orElse(null);

View File

@@ -27,9 +27,7 @@ public enum CollectionLevel1TypeEnum {
/**
* 市场
*/
MARKETING_SKETCH("MarketingSketch"),
MODEL("Models");
MARKETING_SKETCH("MarketingSketch");
private String realName;

View File

@@ -3,32 +3,23 @@ package com.ai.da.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@AllArgsConstructor
@Getter
public enum CreditsEventsEnum {
PRICE("price","10"),
PRICE("price","6"),
// PRICE("price","1"),// for test
// PRICE("price","0.1"),
BUY_CREDITS("Buy Credits","50"),
BUY_CREDITS("Buy Credits","60"),
// BUY_CREDITS("Buy Credits","10"),// for test
REFUND("Refund","50"),
REFUND("Refund","60"),
// BUY_CREDITS("Buy Credits","10"),
// 每月更新
INIT_YEARLY("init_yearly", "50000"),
INIT_MONTHLY("init_monthly", "3500"),
INIT_MONTHLY_ECO("init_monthly_eco", "500"),
INIT_QUARTERLY("init_quarterly", "12000"),
INIT_MONTHLY_EDU("init_monthly_edu", "3500"),
INIT_YEARLY("init_yearly", "6000"),
INIT_MONTHLY("init_monthly", "5000"),
INIT_TRIAL("init_trial", "100"),
INIT_WEEKLY("init_weekly","6000"),
RESET_YEAR_CREDITS("reset_year_credits","6000"),
@@ -41,45 +32,16 @@ public enum CreditsEventsEnum {
MOOD_BOARD("MoodBoard","5"),
SKETCH_BOARD("SketchBoard","5"),
TO_PRODUCT_IMAGE("ToProductImage","5"),
TO_PRODUCT_IMAGE_FLUX("ToProductImageFlux","10"),
RELIGHT("Relight","5"),
RELIGHT_FLUX("RelightFlux","10"),
QUESTIONNAIRE("Questionnaire","100"),
IMAGE_TO_SKETCH("ImageToSketch","5"),
IMAGE_TO_SKETCH_FLUX("ImageToSketchFlux","10"),
POSE_TRANSFORMATION("PoseTransformation","10"),
OTHER("Other","5"),
WX_TEXT2IMG("WX_Text2Image", "5"),
WX_ANIMATION("WX_Animation", "30"),
FREEPIK_IMG2IMG("Freepik_img2img", "20"),
FLUX_IMG2IMG("Flux_img2img","10"),
OTHER("Other","5");
LOCAL_TEXT2IMG("Local_text2img","1.25"),
LOCAL_IMG2IMG("Local_img2img","1.25"),
LOCAL_TEXT2IMG_HIGH("Local_text2img_high","5"),
LOCAL_IMG2IMG_HIGH("Local_img2img_high","5"),
LOCAL_ANIMATION("Local_Animation","15"),
LLM_CONVERSATION("LLM_Conversation", "0")
;
private final String name;
private String name;
/**
* 对应事件需要消耗or获得的积分
*/
private final String value;
public static List<String> generateFunctionNames() {
return Arrays.asList(SLOGAN.name, LOGO.name, PATTERN.name, MOOD_BOARD.name, SKETCH_BOARD.name,
TO_PRODUCT_IMAGE.name, RELIGHT.name, IMAGE_TO_SKETCH.name, POSE_TRANSFORMATION.name);
}
private static final Map<String, CreditsEventsEnum> BY_TASK_NAME = Arrays.stream(values())
.collect(Collectors.toMap(CreditsEventsEnum::getName, Function.identity()));
public static CreditsEventsEnum getByTaskName(String taskName){
return BY_TASK_NAME.get(taskName);
}
private String value;
}

View File

@@ -1,34 +0,0 @@
package com.ai.da.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum FluxTaskStatusEnum {
SUCCESS("Ready"),
TASK_NOT_FOUND("Task not found"),
REQUEST_MODERATED("Request Moderated"),
CONTENT_MODERATED("Content Moderated"),
ERROR("Error"),
PENDING_F("Pending");
private final String name;
public static FluxTaskStatusEnum fromName(String name) {
for (FluxTaskStatusEnum status : values()) {
if (status.name.equalsIgnoreCase(name)) {
return status;
}
}
// 或者返回默认值
return TASK_NOT_FOUND;
}
}

View File

@@ -28,9 +28,7 @@ public enum LibraryLevel1TypeEnum {
* 模特
*/
MODELS("Models"),
DESIGN_ELEMENTS("DesignElements"),
BRAND_DNA("BrandDNA");
DESIGN_ELEMENTS("DesignElements");
private String realName;

View File

@@ -1,80 +0,0 @@
package com.ai.da.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@AllArgsConstructor
@Getter
public enum PoseEnum {
// POSE_1(1, "aida-sys-image/pose/pose-1.mp4", "aida-sys-image/pose/pose-1.gif", "aida-sys-image/pose/pose-1-first_frame.jpeg", "AACT.8090e67b.-E3pujumEfCbDTI_rjSH-A.LwIlGT3j"),
POSE_1(1, "aida-sys-image/pose/pose-1-1.mp4", "aida-sys-image/pose/pose-1-1.gif", "aida-sys-image/pose/pose-1-first_frame.jpeg", "AACT.8090e67b.qNMWJlyKEfCuORaRJeW4dg.x3wUteVO"),
// POSE_2(2, "aida-sys-image/pose/pose-2.mp4", "aida-sys-image/pose/pose-2.gif", "aida-sys-image/pose/pose-2-first_frame.jpeg", "AACT.8090e67b.TwJLxEv3EfCbDTI_rjSH-A.IOQZCYhf"),
POSE_2(2, "aida-sys-image/pose/pose-2-1.mp4", "aida-sys-image/pose/pose-2-1.gif", "aida-sys-image/pose/pose-2-first_frame.jpeg", "AACT.8090e67b.QpaGOlyLEfCuuJo8eQGF2Q.62EiJj-6"),
// POSE_3(3, "aida-sys-image/pose/pose-3.mp4", "aida-sys-image/pose/pose-3.gif", "aida-sys-image/pose/pose-3-first_frame.jpeg", "AACT.8090e67b.gd3OCkv4EfCxyZo8eQGF2Q.qMm-a1XI"),
POSE_3(3, "aida-sys-image/pose/pose-3-1.mp4", "aida-sys-image/pose/pose-3-1.gif", "aida-sys-image/pose/pose-3-first_frame.jpeg", "AACT.8090e67b.2q5qjFyLEfCImjI_rjSH-A.5cFMwOvi"),
// POSE_4(4, "aida-sys-image/pose/pose-4.mp4", "aida-sys-image/pose/pose-4.gif", "aida-sys-image/pose/pose-4-first_frame.jpeg", "AACT.8090e67b.AUDnuEwDEfCEHBaRJeW4dg.rlx36xEY"),
POSE_4(4, "aida-sys-image/pose/pose-4-1.mp4", "aida-sys-image/pose/pose-4-1.gif", "aida-sys-image/pose/pose-4-first_frame.jpeg", "AACT.8090e67b.KoYMplyPEfCuORaRJeW4dg.MuuBTG78"),
// POSE_5(5, "aida-sys-image/pose/pose-5.mp4", "aida-sys-image/pose/pose-5.gif", "aida-sys-image/pose/pose-5-first_frame.jpeg", "AACT.8090e67b.G8BvkEwEEfCxyZo8eQGF2Q.fo4ryrgR"),
POSE_5(5, "aida-sys-image/pose/pose-5-1.mp4", "aida-sys-image/pose/pose-5-1.gif", "aida-sys-image/pose/pose-5-first_frame.jpeg", "AACT.8090e67b.x54FNFyPEfCuuJo8eQGF2Q.P1egmEZ_"),
// POSE_6(6, "aida-sys-image/pose/pose-6.mp4", "aida-sys-image/pose/pose-6.gif", "aida-sys-image/pose/pose-6-first_frame.jpeg", "AACT.8090e67b.yBIPnEwEEfCxyZo8eQGF2Q.boSFwTG9");
POSE_6(6, "aida-sys-image/pose/pose-6-1.mp4", "aida-sys-image/pose/pose-6-1.gif", "aida-sys-image/pose/pose-6-first_frame.jpeg", "AACT.8090e67b.QSCvBlyQEfCImjI_rjSH-A.G9-Z5ffW");
private final Integer id;
private final String videoPath;
private final String gifPath;
private final String firstFramePath;
private final String templateId;
private static final List<Map<String, String>> PROPERTY_LIST;
static {
PROPERTY_LIST = Arrays.stream(values())
.map(PoseEnum::toMap)
.collect(Collectors.toList());
}
private static final Map<Integer, PoseEnum> BY_ID = Arrays.stream(values())
.collect(Collectors.toMap(PoseEnum::getId, Function.identity()));
private static final Map<String, PoseEnum> BY_VIDEO_PATH = Arrays.stream(values())
.collect(Collectors.toMap(PoseEnum::getVideoPath, Function.identity()));
private static final List<String> VIDEO_PATH = Arrays.stream(values())
.map(PoseEnum::getVideoPath).collect(Collectors.toList());
public static PoseEnum getById(Integer id) {
return BY_ID.get(id);
}
public static PoseEnum getByVideoPath(String videoPath) {
return BY_VIDEO_PATH.get(videoPath);
}
private Map<String, String> toMap() {
Map<String, String> map = new HashMap<>();
map.put("id", String.valueOf(id));
map.put("gif", gifPath);
map.put("firstFrame", firstFramePath);
return map;
}
public static List<Map<String, String>> getPropertyList() {
return PROPERTY_LIST.stream()
.map(HashMap::new) // 深拷贝每个 Map
.collect(Collectors.toList());
}
public static List<String> getVideoList() {
return new ArrayList<>(VIDEO_PATH); // 返回副本以保证不可变性
}
}

View File

@@ -7,19 +7,13 @@ import lombok.Getter;
@AllArgsConstructor
public enum ProductEnum {
// 积分购买
CreditsProduct("AiDA credits purchase", 10L, 60L),
CreditsProduct("AiDA credits purchase", 6L),
// 年度订阅
AnnualSubscription("AiDA Annual Subscription", 5000L, 50000L),
// 月度订阅订阅费500每月3500 积分)
MonthlySubscription("AiDA Monthly Subscription", 500L, 3500L),
// 月度订阅 -- 经济实惠版 订阅费100每月500 积分)
Eco_MonthlySubscription("AiDA Eco Monthly Subscription", 100L, 500L),
// 季度订阅
QuarterlySubscription("AiDA Quarterly Subscription", 1500L, 12000L),
// 月度订阅 -- 教育版
EDUMonthlySubscription("AiDA Edu Monthly Subscription", 200L, 3500L),
AnnualSubscription("AiDA Annual Subscription", 5000L),
// 月度订阅
MonthlySubscription("AiDA Monthly Subscription", 500L),
// 测试
DailySubscription("AiDA Daily Subscription", 5L, 100L),
DailySubscription("AiDA Daily Subscription", 10L),
;
/**
@@ -28,6 +22,4 @@ public enum ProductEnum {
private final String name;
private final Long price;
private final Long credits;
}

View File

@@ -1,32 +0,0 @@
package com.ai.da.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum WangXiangTaskStatusEnum {
SUCCEEDED("SUCCEEDED"),
UNKNOWN_W("UNKNOWN"),
FAILED("FAILED"),
RUNNING("RUNNING"),
PENDING_W("PENDING");
private final String name;
// 通过name查找枚举的静态方法
public static WangXiangTaskStatusEnum fromName(String name) {
for (WangXiangTaskStatusEnum status : values()) {
if (status.name.equalsIgnoreCase(name)) {
return status;
}
}
// 或者返回默认值
return UNKNOWN_W;
}
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.common.response;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@NoArgsConstructor
@ApiModel("交易记录分页响应结果")
public class TransactionPageResponse<T> extends PageBaseResponse<T> {
private BigDecimal totalAmount;
}

View File

@@ -43,8 +43,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
private SecurityProperties properties;
private static final List<String> FILTER_URL =
Arrays.asList("/favicon.ico", "/doc.html", "/api/account/login", "/api/account/preLogin", "api/account/sendEmail","api/account/noLoginRequired",
"/webjars/", "/swagger-resources", "/v2/api-docs", "/api/account/resetPwd",
Arrays.asList("/favicon.ico", "/doc.html", "api/account/login", "api/account/preLogin", "api/account/sendEmail","api/account/noLoginRequired",
"/webjars/", "/swagger-resources", "/v2/api-docs", "api/account/resetPwd",
"/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId",
"/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile",
"/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew","/api/third/party/updateNoLoginRequiredNew",
@@ -52,16 +52,14 @@ public class AuthenticationFilter extends OncePerRequestFilter {
"/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back","/api/alipay-hk/trade/notify",
"/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease",
"/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify",
"/notification","/api/account/activateNewEmail","/api/third/party/auth/google_callback","/api/third/party/parseGoogleCredential","/api/third/party/receiveDesignResults","/api/third/party/parseWeChatCode","/api/third/party/receiveDesignParams"
, "/api/account/schoolLogin", "/api/account/enterpriseLogin", "/api/account/organizationNameSearch",
"/api/llm/stream"
"/notification","/api/account/activateNewEmail","/api/third/party/auth/google_callback","/api/third/party/parseGoogleCredential","/api/third/party/receiveDesignResults","/api/third/party/parseWeChatCode"
);
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, @NonNull HttpServletResponse httpServletResponse, @NonNull FilterChain filterChain) throws ServletException, IOException {
String requestURI = httpServletRequest.getRequestURI();
if (calculateUrl(requestURI)/* || hasAuthorizationToken(httpServletRequest)*/) {
if (calculateUrl(requestURI) || hasAuthorizationToken(httpServletRequest)) {
StopWatch stopWatch = new StopWatch();
HttpServletRequest wrappedRequest = httpServletRequest;
HttpServletResponse wrappedResponse = httpServletResponse;
@@ -74,12 +72,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
wrappedRequest = new MultiReadHttpServletRequest(httpServletRequest);
wrappedResponse = new MultiReadHttpServletResponse(httpServletResponse);
extracted(wrappedRequest);
// excel导出使用原始response,不对响应做包装
if (requestURI.equals("/api/account/exportAccountsToExcel")) {
filterChain.doFilter(httpServletRequest, httpServletResponse); // 不包装
} else {
filterChain.doFilter(wrappedRequest, wrappedResponse);
}
filterChain.doFilter(wrappedRequest, wrappedResponse);
}
} catch (Exception e) {
SecurityContextHolder.clearContext();

View File

@@ -25,20 +25,20 @@ public class AccountTask {
* 每个月月初只刷新年付用户的积分
*/
// @Scheduled(cron = "59 59 23 * * ?")
// @Scheduled(cron = "0 0 0 1 * ?")
@Scheduled(cron = "0 0 0 1 * ?")
public void refreshCreditsMonthly() {
log.info("每月1号0点 重置教育版子账号为默认积分");
accountService.refreshCreditsMonthly();
log.info("每月1号0点 将年费用户积分重置为 6000");
accountService.refreshCreditsWeekly();
}
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void getPaidUser() {
// 获取code-create 表中 指定日期之后 订单状态为wc-processing的订单
accountService.extendValidityForCC();
}
// 每天凌晨0点执行一次
// @Scheduled(cron = "0 0 0 * * ?")
@Scheduled(cron = "0 0 0 * * ?")
public void cancelActivityBenefits() {
// 1、查询当前所有参与了活动且过期的用户
List<Account> accountList = accountService.getExpiredUserBySystemUser(4);
@@ -51,7 +51,7 @@ public class AccountTask {
}
// 每天检测正式用户到期情况每天凌晨0点执行
// @Scheduled(cron = "0 0 0 * * ?")
@Scheduled(cron = "0 0 0 * * ?")
public void paidUserToVisitor() {
// 1、查询当前已过期正式用户或试用用户
List<Account> accountList = accountService.getExpiredUserBySystemUser(1);
@@ -74,7 +74,7 @@ public class AccountTask {
accountService.registerUserToVisitor();
}
// @Scheduled(cron = "0 0 0 1 * ?")
@Scheduled(cron = "0 0 0 1 * ?")
// 每月初刷新所有用户用户名剩余修改次数
public void resetUsernameModifyTimes(){
log.info("重置所有用户的用户名修改次数");

View File

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

View File

@@ -45,7 +45,7 @@ public class PaymentTask {
@Resource
private PayPalCheckoutService payPalCheckoutService;
// @Scheduled(cron = "0/30 * * * * ?")
@Scheduled(cron = "0/30 * * * * ?")
public void orderConfirmForPaypal() throws SerializeException {
// log.info("PayPal orderConfirm 被执行......");
@@ -84,6 +84,7 @@ public class PaymentTask {
}*/
}
// !!关闭此定时器,改为提前三天站内信提醒!!
// 提前7天向用户发送提醒邮件,每天早上8点执行
// @Scheduled(cron = "0 0 8 * * ?")
public void subscriptionReminder(){
@@ -102,13 +103,7 @@ public class PaymentTask {
affiliateService.updateAffiliateInfoWithPayment();
}
// 定时同步(每分钟一次)
@Scheduled(fixedRate = 60000)
public void syncLinkViewCountToDB(){
affiliateService.syncLinkViewCountToDB();
}
// @Scheduled(cron = "0 0 8 28-31 * ?")
@Scheduled(cron = "0 0 8 28-31 * ?")
public void commissionSummaryReminder(){
// 每个月末的最后一天的早上八点执行
LocalDate today = LocalDate.now();
@@ -119,9 +114,9 @@ public class PaymentTask {
}
}
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void calcCouponsCommission(){
log.info("优惠券佣金计算定时器");
// log.info("优惠券佣金计算定时器");
affiliateService.calcCouponsCommission();
}

View File

@@ -0,0 +1,88 @@
package com.ai.da.common.utils;
import java.util.HashMap;
import java.util.Map;
public class ComprehensivePunctuationConverter {
private static final Map<Character, Character> FULL_TO_HALF_MAP = new HashMap<>();
static {
// 中文标点到英文标点的映射(扩展版)
FULL_TO_HALF_MAP.put('', ',');
FULL_TO_HALF_MAP.put('。', '.');
FULL_TO_HALF_MAP.put('', ';');
FULL_TO_HALF_MAP.put('', ':');
FULL_TO_HALF_MAP.put('', '?');
FULL_TO_HALF_MAP.put('', '!');
FULL_TO_HALF_MAP.put('', '(');
FULL_TO_HALF_MAP.put('', ')');
FULL_TO_HALF_MAP.put('【', '[');
FULL_TO_HALF_MAP.put('】', ']');
FULL_TO_HALF_MAP.put('「', '\'');
FULL_TO_HALF_MAP.put('」', '\'');
FULL_TO_HALF_MAP.put('『', '"');
FULL_TO_HALF_MAP.put('』', '"');
FULL_TO_HALF_MAP.put('、', '\\');
FULL_TO_HALF_MAP.put('', '~');
FULL_TO_HALF_MAP.put('—', '-');
FULL_TO_HALF_MAP.put('', '.');
FULL_TO_HALF_MAP.put('〈', '<');
FULL_TO_HALF_MAP.put('〉', '>');
FULL_TO_HALF_MAP.put('《', '«');
FULL_TO_HALF_MAP.put('》', '»');
FULL_TO_HALF_MAP.put('〝', '"');
FULL_TO_HALF_MAP.put('〞', '"');
FULL_TO_HALF_MAP.put('﹁', '"');
FULL_TO_HALF_MAP.put('﹂', '"');
FULL_TO_HALF_MAP.put('…', '.');
FULL_TO_HALF_MAP.put('', '_');
// 全角字母和数字
for (char c = ''; c <= ''; c++) {
FULL_TO_HALF_MAP.put(c, (char)(c - '' + 'A'));
}
for (char c = ''; c <= ''; c++) {
FULL_TO_HALF_MAP.put(c, (char)(c - '' + 'a'));
}
for (char c = ''; c <= ''; c++) {
FULL_TO_HALF_MAP.put(c, (char)(c - '' + '0'));
}
}
/**
* 将字符串中的全角字符(包括标点、字母、数字)转换为半角字符
*/
public static String convertToHalfWidth(String input) {
if (input == null || input.isEmpty()) {
return input;
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
// 检查映射表
if (FULL_TO_HALF_MAP.containsKey(c)) {
result.append(FULL_TO_HALF_MAP.get(c));
}
// 处理全角空格Unicode 12288
else if (c == ' ') {
result.append(' ');
}
// 其他字符保持不变
else {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
// String text = "这是一个全角示例,包含:中文标点、全角字母(ABC)、全角数字(123) 还有全角空格!";
String text = "birdsyellow";
String converted = convertToHalfWidth(text);
System.out.println("原始文本: " + text);
System.out.println("转换后: " + converted);
}
}

View File

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

View File

@@ -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

@@ -28,7 +28,7 @@ public final class LocalCacheUtils {
private static LoadingCache<String, String> loadTokenCache() {
LoadingCache<String, String> tokenCache = CacheBuilder.newBuilder()
.concurrencyLevel(10)
.expireAfterWrite(24 * 7 - 1, TimeUnit.HOURS)
.expireAfterWrite(24 * (7 - 1), TimeUnit.HOURS)
.initialCapacity(100)
.maximumSize(10000)
.recordStats()

View File

@@ -1,176 +0,0 @@
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;
}
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, String title) throws AddressException {
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
basicEmailParamDTO.setSubject(title);
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);
}
}

View File

@@ -1,30 +1,25 @@
package com.ai.da.common.utils;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.mapper.primary.entity.ObjectItem;
import io.minio.*;
import io.minio.errors.*;
import io.minio.errors.MinioException;
import io.minio.http.Method;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -379,38 +374,16 @@ public class MinioUtil {
*/
public String getPreSignedUrl(String bucketName, String fileName, int expiry) {
try {
String lowerName = fileName.toLowerCase();
boolean isImage = lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg")
|| lowerName.endsWith(".png") || lowerName.endsWith(".gif");
GetPresignedObjectUrlArgs.Builder builder = GetPresignedObjectUrlArgs.builder()
.bucket(bucketName)
.object(fileName)
.expiry(expiry, TimeUnit.MINUTES)
.method(Method.GET);
if (isImage) {
// 根据后缀名设置正确的 content-type
String contentType = "image/jpeg";
if (lowerName.endsWith(".png")) {
contentType = "image/png";
} else if (lowerName.endsWith(".gif")) { // 新增 GIF
contentType = "image/gif";
}
Map<String, String> queryParams = new HashMap<>();
queryParams.put("response-content-type", contentType);
queryParams.put("response-content-disposition", "inline");
builder.extraQueryParams(queryParams);
}
return minioClient.getPresignedObjectUrl(builder.build());
} catch (MinioException | InvalidKeyException
| IOException | NoSuchAlgorithmException | IllegalArgumentException e) {
return minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.bucket(bucketName)
.object(fileName)
.expiry(expiry, TimeUnit.MINUTES)
.method(Method.GET)
.build()
);
} catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
e.printStackTrace();
log.error("bucket: {}, object:{}", bucketName, fileName);
throw new BusinessException(e.getMessage());
}
}
@@ -597,153 +570,6 @@ public class MinioUtil {
throw new BusinessException(e.getMessage());
}
}
public void upload(String url, File file) {
try {
// 分割桶名和对象路径
int firstSlashIndex = url.indexOf("/");
if (firstSlashIndex == -1) {
throw new IllegalArgumentException("URL 格式不正确,无法解析桶名和对象路径");
}
String bucketName = url.substring(0, firstSlashIndex);
String objectName = url.substring(firstSlashIndex + 1);
// 读取文件流
try (FileInputStream fileInputStream = new FileInputStream(file)) {
// 上传到 MinIO
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(fileInputStream, file.length(), -1)
.contentType("application/zip")
.build()
);
System.out.println("文件上传成功: " + url);
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("文件上传失败: " + e.getMessage());
}
}
public String getImageAsBase64(String path) throws IOException {
int index = path.indexOf("/");
String bucketName = path.substring(0, index);
String fileName = path.substring(index + 1);
// 检查桶是否存在
boolean found = doesObjectExist(bucketName, fileName);
if (!found) {
throw new IOException("Bucket " + bucketName + " does not exist");
}
try (InputStream stream = minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.build())) {
byte[] bytes = IOUtils.toByteArray(stream);
return Base64.getEncoder().encodeToString(bytes);
} catch (ServerException e) {
throw new RuntimeException(e);
} catch (InsufficientDataException e) {
throw new RuntimeException(e);
} catch (ErrorResponseException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
} catch (InvalidResponseException e) {
throw new RuntimeException(e);
} catch (XmlParserException e) {
throw new RuntimeException(e);
} catch (InternalException e) {
throw new RuntimeException(e);
}
}
public void uploadToMinio(byte[] data, String bucket, String objectName, String contentType) /*throws Exception*/ {
try {
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucket)
.object(objectName)
.stream(new ByteArrayInputStream(data), data.length, -1)
.contentType(contentType)
.build());
} catch (MinioException | IOException | NoSuchAlgorithmException | InvalidKeyException e){
log.error("图片上传到minio出错{}", e.getMessage());
throw new BusinessException("file upload exception");
}
}
public String changeToWhiteBackground(String minioPath){
try {
// 1. 使用URL读取远程图片
BufferedImage originalImage = ImageIO.read(new URL(getPreSignedUrl(minioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)));
// 2. 透明图检查(新增核心逻辑)
if (!hasTransparency(originalImage)) {
log.info("图片 {} 无透明通道,无需添加白底", minioPath);
return null; // 返回空
}
// 3. 处理图片(例如:转换为白底)
BufferedImage newImage = new BufferedImage(
originalImage.getWidth(),
originalImage.getHeight(),
BufferedImage.TYPE_INT_RGB
);
// 4. 填充白色背景
java.awt.Graphics2D g = newImage.createGraphics();
g.setColor(java.awt.Color.WHITE);
g.fillRect(0, 0, newImage.getWidth(), newImage.getHeight());
g.drawImage(originalImage, 0, 0, null);
g.dispose();
// 5. 输出为Base64
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(newImage, "PNG", baos);
String base64Image = java.util.Base64.getEncoder().encodeToString(baos.toByteArray());
log.info("为图片 {} 添加白色背景", minioPath);
// System.out.println("data:image/png;base64," + base64Image);
return "data:image/png;base64," + base64Image;
// return base64Image;
} catch (Exception e) {
log.error(e.getMessage());
throw new BusinessException("透明图添加白色背景失败");
}
}
/**
* 检测图片是否包含透明通道
*/
private boolean hasTransparency(BufferedImage image) {
// 情况1图像本身支持透明如TYPE_INT_ARGB
if (image.getTransparency() == Transparency.TRANSLUCENT) {
return true;
}
// 情况2检查像素级透明度适用于TYPE_INT_RGB等格式
if (image.getColorModel().hasAlpha()) {
// 抽样检查前100x100像素避免全图扫描的性能问题
int width = Math.min(image.getWidth(), 100);
int height = Math.min(image.getHeight(), 100);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if ((image.getRGB(x, y) >> 24) == 0x00) {
return true; // 发现透明像素
}
}
}
}
return false;
}
}

View File

@@ -1,614 +1,308 @@
package com.ai.da.common.utils;
import com.ai.da.model.dto.ProgressDTO;
import com.ai.da.python.vo.DesignPythonObject;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, String> redisTemplate;
public final static String FLUX_POLLING_URL = "Flux:";
public Boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
//- - - - - - - - - - - - - - - - - - - - - ZSet类型 - - - - - - - - - - - - - - - - - - - -
/**
* 向ZSet中添加元素
*/
public void addToZSet(String key, String value, Double score) {
redisTemplate.opsForZSet().add(key, value, score);
}
/**
* 从ZSet中删除元素
*/
public void removeFromZSet(String key, String value) {
redisTemplate.opsForZSet().remove(key, value);
}
/**
* 获取指定元素的当前排列顺序
*/
public Long getRank(String key, String value) {
return redisTemplate.opsForZSet().rank(key, value);
}
/**
* 获取当前ZSet中的最大score
*/
public Double getMaxScore(String key) {
Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 0);
if (!CollectionUtils.isEmpty(set)) {
Double score = set.iterator().next().getScore();
return score + 1.0;
} else {
return 1.0;
}
}
/**
* 判断元素是否存在
*/
public Boolean isElementExistsInZSet(String key, String value) {
return redisTemplate.opsForZSet().score(key, value) != null;
}
/**
* 获取当前ZSet中数据量的总和
*/
public Long getZSetTotalCount(String key) {
return redisTemplate.opsForZSet().zCard(key);
}
public Set<String> getZSetTotalData(String key){
return redisTemplate.opsForZSet().range(key, 0, -1);
}
//- - - - - - - - - - - - - - - - - - - - - set类型 - - - - - - - - - - - - - - - - - - - -
/**
* 将数据放入set缓存
*/
public void addToSet(String key, String value) {
redisTemplate.opsForSet().add(key, value);
}
/**
* 弹出变量中的元素
*/
public void removeFromSet(String key, String value) {
redisTemplate.opsForSet().remove(key, value);
}
/**
* 检查给定的元素是否在变量中。
*/
public Boolean isElementExistsInSet(String key, String obj) {
return redisTemplate.opsForSet().isMember(key, obj);
}
//- - - - - - - - - - - - - - - - - - - - - hash类型 - - - - - - - - - - - - - - - - - - - -
/**
* 加入缓存
*/
public void addToMap(String key, Map<String, String> map) {
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 验证指定 key 下 有没有指定hashkey
*/
public Boolean isElementExistsInMap(String key, String hashKey) {
return redisTemplate.opsForHash().hasKey(key, hashKey);
}
/**
* 获取指定key的值string
*/
public String getMapValue(String key1, String key2) {
return String.valueOf(redisTemplate.opsForHash().get(key1, key2));
}
/**
* 删除指定 hash 的 HashKey
*
* @return 删除成功的 数量
*/
public Long removeFromMap(String key, String hashKeys) {
return redisTemplate.opsForHash().delete(key, hashKeys);
}
//- - - - - - - - - - - - - - - - - - - - - String类型 - - - - - - - - - - - - - - - - - - - -
public void addToString(String key, String value){
redisTemplate.opsForValue().set(key,value);
}
public void addToString(String key, String value, Long expiresIn){
redisTemplate.opsForValue().set(key,value,expiresIn, TimeUnit.SECONDS);
}
public String getFromString(String key){
return redisTemplate.opsForValue().get(key);
}
public Set<String> getKeysFromString(String key){
return redisTemplate.keys(key);
}
public Long getSize(String key){return redisTemplate.opsForSet().size(key);}
public List<String> getMultiValue(Set<String> keys){
return redisTemplate.opsForValue().multiGet(keys);
}
public Long getExpire(String key){
return redisTemplate.getExpire(key);
}
public void removeFromString(String key){
redisTemplate.delete(key);
}
public final static String PORTFOLIO_LIKE_KEY = "portfolio:like:";
public void likePost(Long portfolioId, Long userId) {
redisTemplate.opsForSet().add(PORTFOLIO_LIKE_KEY + portfolioId, String.valueOf(userId));
}
public Long getLikeCount(Long portfolioId) {
String key = PORTFOLIO_LIKE_KEY + portfolioId;
return redisTemplate.opsForSet().size(key);
}
public List<Long> getLikedPortfolios(Long userId) {
// 获取所有包含PORTFOLIO_LIKE_KEY的键
Set<String> likedPortfolios = redisTemplate.keys(PORTFOLIO_LIKE_KEY + "*");
// 如果没有喜欢的,返回空列表
if (likedPortfolios == null || likedPortfolios.isEmpty()) {
return new ArrayList<>();
}
// 过滤出包含指定用户ID的键并提取投资组合ID
return likedPortfolios.stream()
.filter(key -> redisTemplate.opsForSet().isMember(key, String.valueOf(userId)))
.map(key -> Long.valueOf(key.replace(PORTFOLIO_LIKE_KEY, "")))
.collect(Collectors.toList());
}
public void unLikePost(Long portfolioId, Long userId) {
redisTemplate.opsForSet().remove(PORTFOLIO_LIKE_KEY + portfolioId, userId.toString());
}
// 检查用户是否喜欢某个作品
public boolean isPostLikedByUser(Long portfolioId, Long userId) {
String key = PORTFOLIO_LIKE_KEY + portfolioId;
Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());
return isMember != null && isMember;
}
public final static String PORTFOLIO_VIEW_KEY = "portfolio:view:";
public void increaseViewCount(Long portfolioId) {
String key = PORTFOLIO_VIEW_KEY + portfolioId;
redisTemplate.opsForValue().increment(key);
}
public Long getViewCount(Long portfolioId) {
String key = PORTFOLIO_VIEW_KEY + portfolioId;
return redisTemplate.opsForValue().increment(key, 0);
}
public Long getViewCount(String key) {
Object value = redisTemplate.opsForValue().get(key);
if (value instanceof Integer) {
return Long.valueOf((Integer) value);
} else if (value instanceof Long) {
return (Long) value;
} else if (value instanceof String) {
return Long.valueOf((String) value);
} else {
throw new IllegalArgumentException("Unexpected value type");
}
}
public final static String PERSONAL_HOMEPAGE_VIEW_KEY = "PersonalHomepage:view:";
public void increasePersonalHomepageViewCount(Long accountId) {
String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId;
redisTemplate.opsForValue().increment(key);
}
public Long getPersonalHomepageViewCount(Long accountId) {
String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId;
return redisTemplate.opsForValue().increment(key, 0);
}
public final static String MOODBOARD_POSITION_KEY = "moodboard:position:";
public void saveMoodboardPosition(Long id, String moodboardPosition) {
addToString(MOODBOARD_POSITION_KEY + id, moodboardPosition);
}
public String getMoodboardPosition(Long id) {
return getFromString(MOODBOARD_POSITION_KEY + id);
}
public final static String NICKNAME_MODIFY_TIMES = "NicknameModifyTimes:";
public void increaseCount(String key) {
redisTemplate.opsForValue().increment(key);
}
public Long getIncrementCount(String key) {
return redisTemplate.opsForValue().increment(key, 0);
}
public void setKeyExpire(String key, Long expire) {
redisTemplate.expire(key, expire, TimeUnit.DAYS);
}
public final static String CHANGE_MAILBOX = "ChangeMailbox:";
// 每天允许通知3次
public final static String UPLOAD_TIMEOUT_REMINDER_COUNTER = "UploadTimeoutReminderCounter";
public void addProcessId(String processId, int progress) {
// Redis 中的键,可以通过 processId 来唯一标识
String redisKey = "process:progress:" + processId;
// 将当前进度存储到 Redis
redisTemplate.opsForValue().set(redisKey, String.valueOf(progress));
// 设置过期时间为 5 分钟300 秒)
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
}
public void addPathToCache(Long collectionId, Long userId, String path) {
// Redis 中的键,唯一标识由 collectionId 和 userId 组成
String redisKey = "path:cache:" + collectionId + ":" + userId;
// 增加路径的计数
redisTemplate.opsForHash().increment(redisKey, path, 1);
// 设置过期时间为 2 小时7200 秒)
redisTemplate.expire(redisKey, 8, TimeUnit.HOURS);
}
public int getPathUsageCount(Long collectionId, Long userId, String path) {
String redisKey = "path:cache:" + collectionId + ":" + userId;
// 获取路径的使用次数
Object count = redisTemplate.opsForHash().get(redisKey, path);
return count != null ? Integer.parseInt(count.toString()) : 0;
}
public void addAssembledObjects(Long collectionId, Set<DesignPythonObject> assembledObjects) {
// Redis 中的键,使用 collectionId 来唯一标识
String redisKey = "collection:assembledObjects:" + collectionId;
// 将 assembledObjects 转换为 JSON 格式存储,避免直接存储对象
String assembledObjectsJson = convertToJson(assembledObjects);
// 使用 Redis 的 set 操作更新集合
redisTemplate.opsForValue().set(redisKey, assembledObjectsJson);
// 设置过期时间为 5 分钟300 秒)
redisTemplate.expire(redisKey, 30, TimeUnit.MINUTES);
}
// 将 Set<DesignPythonObject> 转换为 JSON 格式
private String convertToJson(Set<DesignPythonObject> assembledObjects) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(assembledObjects);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
public Set<DesignPythonObject> getAssembledObjects(Long collectionId) {
// Redis 中的键,使用 collectionId 来唯一标识
String redisKey = "collection:assembledObjects:" + collectionId;
// 从 Redis 获取存储的 JSON 字符串
String assembledObjectsJson = (String) redisTemplate.opsForValue().get(redisKey);
if (assembledObjectsJson == null) {
return new HashSet<>(); // 如果没有找到数据,返回一个空的 Set
}
// 将 JSON 字符串转换为 Set<DesignPythonObject>
return convertFromJson(assembledObjectsJson);
}
// 将 JSON 字符串转换为 Set<DesignPythonObject>
private Set<DesignPythonObject> convertFromJson(String json) {
try {
ObjectMapper objectMapper = new ObjectMapper();
// 使用 TypeReference 来指定目标类型是 Set<DesignPythonObject>
return objectMapper.readValue(json, new TypeReference<Set<DesignPythonObject>>() {});
} catch (JsonProcessingException e) {
e.printStackTrace();
return new HashSet<>(); // 如果转换失败,返回空的 Set
}
}
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime";
public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:";
public void increaseAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
redisTemplate.opsForValue().increment(key);
}
public Long getAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
return redisTemplate.opsForValue().increment(key, 0);
}
/**
* 记录任务的耗时到Redis
* @param taskKey 任务标识,如 "taskA"
* @param elapsedTime 本次耗时,单位为毫秒
*/
public void recordTaskElapsedTime(String taskKey, long elapsedTime) {
String hashKey = "task:stats";
// 累加总耗时
redisTemplate.opsForHash().increment(hashKey, taskKey + ":totalTime", elapsedTime);
// 增加计数器
redisTemplate.opsForHash().increment(hashKey, taskKey + ":count", 1);
}
/**
* 获取任务的平均耗时
* @param taskKey 任务标识,如 "taskA"
* @return 平均耗时(毫秒)
*/
public double getTaskAverageTime(String taskKey) {
String hashKey = "task:stats";
// 获取总耗时和计数
Object totalTime = redisTemplate.opsForHash().get(hashKey, taskKey + ":totalTime");
Object count = redisTemplate.opsForHash().get(hashKey, taskKey + ":count");
// 计算平均值
if (totalTime == null || count == null) {
return 0;
}
return Double.parseDouble(totalTime.toString()) / Long.parseLong(count.toString());
}
/**
* 清除指定任务的统计数据
* @param taskKey 任务标识,如 "taskA"
*/
public void clearTaskStats(String taskKey) {
String hashKey = "task:stats";
// 删除总耗时和计数器
redisTemplate.opsForHash().delete(hashKey, taskKey + ":totalTime", taskKey + ":count");
}
public void recordTaskElapsedTime(String taskKey, double elapsedTimeInSeconds) {
// 将耗时转换为 BigDecimal并四舍五入保留四位小数
BigDecimal elapsedTime = new BigDecimal(elapsedTimeInSeconds).setScale(4, RoundingMode.HALF_UP);
// 累加总耗时(以毫秒为单位)
redisTemplate.opsForHash().increment("task:stats", taskKey + ":totalTime", elapsedTime.doubleValue());
// 增加计数器
redisTemplate.opsForHash().increment("task:stats", taskKey + ":count", 1);
}
// 获取第一部分Sketch耗时
public double getFirstSketchTime() {
// 获取 "firstSketchTime:totalTime" 对应的值,并返回(单位为秒)
Object time = redisTemplate.opsForHash().get("task:stats", "firstSketchTime:totalTime");
return time != null ? (double) time : 0.0;
}
// 获取第二部分(获取特征值)耗时
public double getGetAttributeRecognitionTime() {
// 获取 "getAttributeRecognitionTime:totalTime" 对应的值,并返回(单位为秒)
Object time = redisTemplate.opsForHash().get("task:stats", "getAttributeRecognitionTime:totalTime");
return time != null ? (double) time : 0.0;
}
// 获取第三部分(搭配 Sketch耗时
public double getOtherSketchTime() {
// 获取 "otherSketchTime:totalTime" 对应的值,并返回(单位为秒)
Object time = redisTemplate.opsForHash().get("task:stats", "otherSketchTime:totalTime");
return time != null ? (double) time : 0.0;
}
// 清理三部分的缓存
public void clearTaskElapsedTimeCache() {
// 删除第一部分的缓存
redisTemplate.opsForHash().delete("task:stats", "firstSketchTime:totalTime");
redisTemplate.opsForHash().delete("task:stats", "firstSketchTime:count");
// 删除第二部分的缓存
redisTemplate.opsForHash().delete("task:stats", "getAttributeRecognitionTime:totalTime");
redisTemplate.opsForHash().delete("task:stats", "getAttributeRecognitionTime:count");
// 删除第三部分的缓存
redisTemplate.opsForHash().delete("task:stats", "otherSketchTime:totalTime");
redisTemplate.opsForHash().delete("task:stats", "otherSketchTime:count");
}
public boolean incrementLikeCount(Long userId, String sketchPath) {
String redisKey = "user_like_count:" + userId;
try {
redisTemplate.opsForHash().increment(redisKey, sketchPath, 1);
return true;
} catch (Exception e) {
log.error("Error incrementing like count for userId {} and sketchPath {}: {}", userId, sketchPath, e.getMessage());
return false;
}
}
public int getLikeCount(Long userId, String sketchPath) {
String redisKey = "user_like_count:" + userId;
Object count = redisTemplate.opsForHash().get(redisKey, sketchPath);
return count != null ? Integer.parseInt(count.toString()) : 0;
}
public void storeMaxLikeCount(Long userId, int maxLikeCount) {
String redisKey = "user_max_like_count:" + userId;
redisTemplate.opsForValue().set(redisKey, String.valueOf(maxLikeCount));
}
public int getMaxLikeCount(Long userId) {
String redisKey = "user_max_like_count:" + userId;
String maxLikeCount = redisTemplate.opsForValue().get(redisKey);
return maxLikeCount != null ? Integer.parseInt(maxLikeCount) : 0;
}
public final static String IMAGE_SEGMENTATION = "ImageSegmentation:";
public final static String STRIPE_EXCEPTION_LOG = "StripeException:";
public void batchDeleteKeysWithSamePrefix(String prefix){
Set<String> keys = redisTemplate.keys(prefix + "*");
assert keys != null;
if (!keys.isEmpty()){
redisTemplate.delete(keys);
}
}
public void setTaskProgressDTO(String taskId, ProgressDTO dto) {
String key = "task:progress:" + taskId;
redisTemplate.opsForValue().set(key, JSON.toJSONString(dto), Duration.ofDays(1));
}
public ProgressDTO getTaskProgressDTO(String taskId) {
String key = "task:progress:" + taskId;
String json = redisTemplate.opsForValue().get(key);
if (StringUtils.isBlank(json)) {
// return new ProgressDTO(0, 0, false);
return null;
}
try {
return JSON.parseObject(json, ProgressDTO.class);
} catch (Exception e) {
log.warn("任务进度解析失败 key={}, json={}", key, json);
return new ProgressDTO(0, 0, false, null);
}
}
// Lua脚本原子化操作
/*private static final String RATE_LIMIT_SCRIPT =
"local current = redis.call('INCR', KEYS[1])\n" +
"if tonumber(current) == 1 then\n" +
" redis.call('EXPIRE', KEYS[1], ARGV[1])\n" +
"end\n" +
"return tonumber(current) <= tonumber(ARGV[2])";*/
private static final String RATE_LIMIT_SCRIPT =
"local current = redis.call('INCR', KEYS[1])\n" +
"local ttl = redis.call('TTL', KEYS[1])\n" +
"if tonumber(current) == 1 or tonumber(ttl) == -1 then\n" +
" redis.call('EXPIRE', KEYS[1], ARGV[1])\n" +
"end\n" +
"return tonumber(current) <= tonumber(ARGV[2])";
/**
* 检查是否允许发送
* @param userId 用户ID
* @return true-允许发送false-已超限
*/
public boolean allowSend(Long userId) {
String hourKey = getCurrentHourKey(userId);
// 执行Lua脚本
List<String> keys = Collections.singletonList(hourKey);
List<Long> args = Arrays.asList(
3600L, // 1小时过期
10L // 限制数量 一小时只能向普通用户发10封
);
Boolean result = redisTemplate.execute(
new DefaultRedisScript<>(RATE_LIMIT_SCRIPT, Boolean.class),
keys,
args.toArray()
);
return Boolean.TRUE.equals(result);
}
/**
* 获取当前小时的Key
* 格式email_limit:{userId}:{yyyyMMddHH}
*/
private String getCurrentHourKey(Long userId) {
String hour = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
return String.format("email_limit:%s:%s", userId, hour);
}
/**
* 获取当前已发送数量
*/
public int getCurrentCount(Long userId) {
String key = getCurrentHourKey(userId);
String val = redisTemplate.opsForValue().get(key);
int count;
if (StringUtils.isBlank(val)){
count = 0;
}else {
count = Integer.parseInt(val);
}
return count;
}
public boolean allowRequest(String apiKey) {
String key = "rate_limit:" + apiKey;
ValueOperations<String, String> ops = redisTemplate.opsForValue();
// 使用Redis的INCR命令
Long count = ops.increment(key, 1);
if (count == 1) {
// 第一次调用,设置过期时间
redisTemplate.expire(key, 1, TimeUnit.MINUTES);
}
return count <= 3;
}
}
package com.ai.da.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, String> redisTemplate;
public Boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
//- - - - - - - - - - - - - - - - - - - - - ZSet类型 - - - - - - - - - - - - - - - - - - - -
/**
* 向ZSet中添加元素
*/
public void addToZSet(String key, String value, Double score) {
redisTemplate.opsForZSet().add(key, value, score);
}
/**
* 从ZSet中删除元素
*/
public void removeFromZSet(String key, String value) {
redisTemplate.opsForZSet().remove(key, value);
}
/**
* 获取指定元素的当前排列顺序
*/
public Long getRank(String key, String value) {
return redisTemplate.opsForZSet().rank(key, value);
}
/**
* 获取当前ZSet中的最大score
*/
public Double getMaxScore(String key) {
Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 0);
if (!CollectionUtils.isEmpty(set)) {
Double score = set.iterator().next().getScore();
return score + 1.0;
} else {
return 1.0;
}
}
/**
* 判断元素是否存在
*/
public Boolean isElementExistsInZSet(String key, String value) {
return redisTemplate.opsForZSet().score(key, value) != null;
}
/**
* 获取当前ZSet中数据量的总和
*/
public Long getZSetTotalCount(String key) {
return redisTemplate.opsForZSet().zCard(key);
}
public Set<String> getZSetTotalData(String key){
return redisTemplate.opsForZSet().range(key, 0, -1);
}
//- - - - - - - - - - - - - - - - - - - - - set类型 - - - - - - - - - - - - - - - - - - - -
/**
* 将数据放入set缓存
*/
public void addToSet(String key, String value, Long expiresIn) {
redisTemplate.opsForSet().add(key, value);
// 设置过期时间
redisTemplate.expire(key, expiresIn, TimeUnit.SECONDS);
}
/**
* 弹出变量中的元素
*/
public void removeFromSet(String key, String value) {
redisTemplate.opsForSet().remove(key, value);
}
/**
* 检查给定的元素是否在变量中。
*/
public Boolean isElementExistsInSet(String key, String obj) {
return redisTemplate.opsForSet().isMember(key, obj);
}
//- - - - - - - - - - - - - - - - - - - - - hash类型 - - - - - - - - - - - - - - - - - - - -
/**
* 加入缓存
*/
public void addToMap(String key, Map<String, String> map) {
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 验证指定 key 下 有没有指定的 hashkey
*/
public Boolean isElementExistsInMap(String key, String hashKey) {
return redisTemplate.opsForHash().hasKey(key, hashKey);
}
/**
* 获取指定key的值string
*/
public String getMapValue(String key1, String key2) {
return String.valueOf(redisTemplate.opsForHash().get(key1, key2));
}
/**
* 删除指定 hash HashKey
*
* @return 删除成功的 数量
*/
public Long removeFromMap(String key, String hashKeys) {
return redisTemplate.opsForHash().delete(key, hashKeys);
}
//- - - - - - - - - - - - - - - - - - - - - String类型 - - - - - - - - - - - - - - - - - - - -
public void addToString(String key, String value){
redisTemplate.opsForValue().set(key,value);
}
public void addToString(String key, String value, Long expiresIn){
redisTemplate.opsForValue().set(key,value,expiresIn, TimeUnit.SECONDS);
}
public String getFromString(String key){
return redisTemplate.opsForValue().get(key);
}
public Set<String> getKeysFromString(String key){
return redisTemplate.keys(key);
}
public Long getSize(String key){return redisTemplate.opsForSet().size(key);}
public List<String> getMultiValue(Set<String> keys){
return redisTemplate.opsForValue().multiGet(keys);
}
public Long getExpire(String key){
return redisTemplate.getExpire(key);
}
public void removeFromString(String key){
redisTemplate.delete(key);
}
public final static String PORTFOLIO_LIKE_KEY = "portfolio:like:";
public void likePost(Long portfolioId, Long userId) {
redisTemplate.opsForSet().add(PORTFOLIO_LIKE_KEY + portfolioId, String.valueOf(userId));
}
public Long getLikeCount(Long portfolioId) {
String key = PORTFOLIO_LIKE_KEY + portfolioId;
return redisTemplate.opsForSet().size(key);
}
public List<Long> getLikedPortfolios(Long userId) {
// 获取所有包含PORTFOLIO_LIKE_KEY的键
Set<String> likedPortfolios = redisTemplate.keys(PORTFOLIO_LIKE_KEY + "*");
// 如果没有喜欢的,返回空列表
if (likedPortfolios == null || likedPortfolios.isEmpty()) {
return new ArrayList<>();
}
// 过滤出包含指定用户ID的键并提取投资组合ID
return likedPortfolios.stream()
.filter(key -> redisTemplate.opsForSet().isMember(key, String.valueOf(userId)))
.map(key -> Long.valueOf(key.replace(PORTFOLIO_LIKE_KEY, "")))
.collect(Collectors.toList());
}
public void unLikePost(Long portfolioId, Long userId) {
redisTemplate.opsForSet().remove(PORTFOLIO_LIKE_KEY + portfolioId, userId.toString());
}
// 检查用户是否喜欢某个作品
public boolean isPostLikedByUser(Long portfolioId, Long userId) {
String key = PORTFOLIO_LIKE_KEY + portfolioId;
Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());
return isMember != null && isMember;
}
public final static String PORTFOLIO_VIEW_KEY = "portfolio:view:";
public void increaseViewCount(Long portfolioId) {
String key = PORTFOLIO_VIEW_KEY + portfolioId;
redisTemplate.opsForValue().increment(key);
}
public Long getViewCount(Long portfolioId) {
String key = PORTFOLIO_VIEW_KEY + portfolioId;
return redisTemplate.opsForValue().increment(key, 0);
}
public Long getViewCount(String key) {
Object value = redisTemplate.opsForValue().get(key);
if (value instanceof Integer) {
return Long.valueOf((Integer) value);
} else if (value instanceof Long) {
return (Long) value;
} else if (value instanceof String) {
return Long.valueOf((String) value);
} else {
throw new IllegalArgumentException("Unexpected value type");
}
}
public final static String PERSONAL_HOMEPAGE_VIEW_KEY = "PersonalHomepage:view:";
public void increasePersonalHomepageViewCount(Long accountId) {
String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId;
redisTemplate.opsForValue().increment(key);
}
public Long getPersonalHomepageViewCount(Long accountId) {
String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId;
return redisTemplate.opsForValue().increment(key, 0);
}
public final static String MOODBOARD_POSITION_KEY = "moodboard:position:";
public void saveMoodboardPosition(Long id, String moodboardPosition) {
addToString(MOODBOARD_POSITION_KEY + id, moodboardPosition);
}
public String getMoodboardPosition(Long id) {
return getFromString(MOODBOARD_POSITION_KEY + id);
}
public final static String NICKNAME_MODIFY_TIMES = "NicknameModifyTimes:";
public void increaseCount(String key) {
redisTemplate.opsForValue().increment(key);
}
public Long getIncrementCount(String key) {
return redisTemplate.opsForValue().increment(key, 0);
}
public void setKeyExpire(String key, Long expire) {
redisTemplate.expire(key, expire, TimeUnit.DAYS);
}
public final static String CHANGE_MAILBOX = "ChangeMailbox:";
// 每天允许通知3次
public final static String UPLOAD_TIMEOUT_REMINDER_COUNTER = "UploadTimeoutReminderCounter";
public void addProcessId(String processId, int progress) {
// Redis 中的键,可以通过 processId 来唯一标识
String redisKey = "process:progress:" + processId;
// 将当前进度存储到 Redis
redisTemplate.opsForValue().set(redisKey, String.valueOf(progress));
// 设置过期时间为 5 分钟300 秒)
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
}
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime";
public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:";
public void increaseAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
redisTemplate.opsForValue().increment(key);
}
public Long getAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
return redisTemplate.opsForValue().increment(key, 0);
}
public void batchDeleteKeysWithSamePrefix(String prefix){
Set<String> keys = redisTemplate.keys(prefix + "*");
assert keys != null;
if (!keys.isEmpty()){
redisTemplate.delete(keys);
}
}
public final static String STRIPE_EXCEPTION_LOG = "StripeException:";
public final static String SUBSCRIPTION_SENT_EMAIL_TYPE = "SubscriptionEmailSentType:";
}

View File

@@ -1,743 +0,0 @@
package com.ai.da.common.utils;
import com.ai.da.model.dto.ProgressDTO;
import com.ai.da.python.vo.DesignPythonObject;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Component
public class RedisUtilEnhance {
@Resource
private RedisTemplate<String, Object> redisTemplate;
private ValueOperations<String, Object> valueOperations;
private SetOperations<String, Object> setOperations;
private HashOperations<String, Object, Object> hashOperations;
private ZSetOperations<String, Object> zSetOperations;
@PostConstruct
public void init() {
this.valueOperations = redisTemplate.opsForValue();
this.setOperations = redisTemplate.opsForSet();
this.hashOperations = redisTemplate.opsForHash();
this.zSetOperations = redisTemplate.opsForZSet();
}
public final static String FLUX_POLLING_URL = "Flux:";
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
//- - - - - - - - - - - - - - - - - - - - - ZSet类型 - - - - - - - - - - - - - - - - - - - -
/**
* 向ZSet中添加元素
*/
public void addToZSet(String key, Object value, Double score) {
zSetOperations.add(key, value, score);
}
/**
* 从ZSet中删除元素
*/
public void removeFromZSet(String key, Object value) {
zSetOperations.remove(key, value);
}
/**
* 获取指定元素的当前排列顺序
*/
public Long getRank(String key, Object value) {
return zSetOperations.rank(key, value);
}
/**
* 获取当前ZSet中的最大score
*/
public Double getMaxScore(String key) {
Set<ZSetOperations.TypedTuple<Object>> set = zSetOperations.reverseRangeWithScores(key, 0, 0);
if (!CollectionUtils.isEmpty(set)) {
Iterator<ZSetOperations.TypedTuple<Object>> iterator = set.iterator();
if (iterator.hasNext()) {
Double score = iterator.next().getScore();
return score != null ? score + 1.0 : 1.0;
}
}
return 1.0;
}
/**
* 判断元素是否存在
*/
public Boolean isElementExistsInZSet(String key, Object value) {
return zSetOperations.score(key, value) != null;
}
/**
* 获取当前ZSet中数据量的总和
*/
public Long getZSetTotalCount(String key) {
return zSetOperations.zCard(key);
}
public Set<Object> getZSetTotalData(String key) {
return zSetOperations.range(key, 0, -1);
}
//- - - - - - - - - - - - - - - - - - - - - set类型 - - - - - - - - - - - - - - - - - - - -
/**
* 将数据放入set缓存
*/
public void addToSet(String key, Object value) {
setOperations.add(key, value);
}
/**
* 弹出变量中的元素
*/
public void removeFromSet(String key, Object value) {
setOperations.remove(key, value);
}
/**
* 检查给定的元素是否在变量中。
*/
public Boolean isElementExistsInSet(String key, Object obj) {
return setOperations.isMember(key, obj);
}
//- - - - - - - - - - - - - - - - - - - - - hash类型 - - - - - - - - - - - - - - - - - - - -
/**
* 加入缓存
*/
public void addToMap(String key, Map<String, String> map) {
hashOperations.putAll(key, map);
}
/**
* 验证指定 key 下 有没有指定的 hashkey
*/
public Boolean isElementExistsInMap(String key, Object hashKey) {
return hashOperations.hasKey(key, hashKey);
}
/**
* 获取指定key的值string
*/
public String getMapValue(String key1, Object key2) {
Object value = hashOperations.get(key1, key2);
return value != null ? value.toString() : null;
}
/**
* 删除指定 hash 的 HashKey
*
* @return 删除成功的 数量
*/
public Long removeFromMap(String key, Object hashKeys) {
return hashOperations.delete(key, hashKeys);
}
//- - - - - - - - - - - - - - - - - - - - - String/Long/Integer类型支持 - - - - - - - - - - - - - - - - - - - -
/**
* 设置字符串值
*/
public void setString(String key, String value) {
valueOperations.set(key, value);
}
/**
* 设置字符串值并设置过期时间
*/
public void setString(String key, String value, long timeout, TimeUnit unit) {
valueOperations.set(key, value, timeout, unit);
}
/**
* 设置Long值
*/
public void setLong(String key, Long value) {
valueOperations.set(key, value);
}
/**
* 设置Long值并设置过期时间
*/
public void setLong(String key, Long value, long timeout, TimeUnit unit) {
valueOperations.set(key, value, timeout, unit);
}
/**
* 设置Integer值
*/
public void setInteger(String key, Integer value) {
valueOperations.set(key, value);
}
/**
* 设置Integer值并设置过期时间
*/
public void setInteger(String key, Integer value, long timeout, TimeUnit unit) {
valueOperations.set(key, value, timeout, unit);
}
/**
* 设置对象值
*/
public void setObject(String key, Object value, long timeout, TimeUnit unit) {
valueOperations.set(key, value, timeout, unit);
}
/**
* 获取字符串值
*/
public String getString(String key) {
Object value = valueOperations.get(key);
return value != null ? value.toString() : null;
}
/**
* 获取Long值
*/
public Long getLong(String key) {
Object value = valueOperations.get(key);
if (value instanceof Long) {
return (Long) value;
} else if (value instanceof Integer) {
return ((Integer) value).longValue();
} else if (value instanceof String) {
try {
return Long.parseLong((String) value);
} catch (NumberFormatException e) {
log.warn("无法将字符串转换为Long: key={}, value={}", key, value);
return null;
}
} else if (value != null) {
log.warn("不支持的类型转换到Long: key={}, type={}", key, value.getClass().getName());
}
return null;
}
/**
* 获取Long值带默认值
*/
public Long getLong(String key, Long defaultValue) {
try {
Long value = getLong(key);
return value != null ? value : defaultValue;
} catch (Exception e) {
log.warn("获取Long值失败: key={}", key, e);
return defaultValue;
}
}
/**
* 获取Integer值
*/
public Integer getInteger(String key) {
Object value = valueOperations.get(key);
if (value instanceof Integer) {
return (Integer) value;
} else if (value instanceof Long) {
return ((Long) value).intValue();
} else if (value instanceof String) {
try {
return Integer.parseInt((String) value);
} catch (NumberFormatException e) {
log.warn("无法将字符串转换为Integer: key={}, value={}", key, value);
return null;
}
} else if (value != null) {
log.warn("不支持的类型转换到Integer: key={}, type={}", key, value.getClass().getName());
}
return null;
}
/**
* 获取Integer值带默认值
*/
public Integer getInteger(String key, Integer defaultValue) {
try {
Integer value = getInteger(key);
return value != null ? value : defaultValue;
} catch (Exception e) {
log.warn("获取Integer值失败: key={}", key, e);
return defaultValue;
}
}
/**
* 递增操作
*/
public Long increment(String key, long delta) {
return valueOperations.increment(key, delta);
}
/**
* 递增操作double
*/
public Double increment(String key, double delta) {
return valueOperations.increment(key, delta);
}
//- - - - - - - - - - - - - - - - - - - - - 原有方法适配 - - - - - - - - - - - - - - - - - - - -
public void addToString(String key, String value) {
setString(key, value);
}
public void addToString(String key, String value, Long expiresIn) {
setString(key, value, expiresIn, TimeUnit.SECONDS);
}
public String getFromString(String key) {
return getString(key);
}
public Set<String> getKeysFromString(String pattern) {
Set<String> keys = redisTemplate.keys(pattern);
return keys != null ? keys : Collections.emptySet();
}
public Long getSize(String key) {
return setOperations.size(key);
}
public List<Object> getMultiValue(Set<String> keys) {
return valueOperations.multiGet(keys);
}
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
public void removeFromString(String key) {
redisTemplate.delete(key);
}
public final static String PORTFOLIO_LIKE_KEY = "portfolio:like:";
public void likePost(Long portfolioId, Long userId) {
setOperations.add(PORTFOLIO_LIKE_KEY + portfolioId, userId.toString());
}
public Long getLikeCount(Long portfolioId) {
String key = PORTFOLIO_LIKE_KEY + portfolioId;
return setOperations.size(key);
}
public List<Long> getLikedPortfolios(Long userId) {
// 获取所有包含PORTFOLIO_LIKE_KEY的键
Set<String> likedPortfolios = redisTemplate.keys(PORTFOLIO_LIKE_KEY + "*");
// 如果没有喜欢的,返回空列表
if (likedPortfolios == null || likedPortfolios.isEmpty()) {
return new ArrayList<>();
}
// 过滤出包含指定用户ID的键并提取投资组合ID
return likedPortfolios.stream()
.filter(key -> setOperations.isMember(key, userId.toString()))
.map(key -> Long.valueOf(key.replace(PORTFOLIO_LIKE_KEY, "")))
.collect(Collectors.toList());
}
public void unLikePost(Long portfolioId, Long userId) {
setOperations.remove(PORTFOLIO_LIKE_KEY + portfolioId, userId.toString());
}
// 检查用户是否喜欢某个作品
public boolean isPostLikedByUser(Long portfolioId, Long userId) {
String key = PORTFOLIO_LIKE_KEY + portfolioId;
Boolean isMember = setOperations.isMember(key, userId.toString());
return isMember != null && isMember;
}
public final static String PORTFOLIO_VIEW_KEY = "portfolio:view:";
public void increaseViewCount(Long portfolioId) {
String key = PORTFOLIO_VIEW_KEY + portfolioId;
increment(key, 1);
}
public Long getViewCount(Long portfolioId) {
String key = PORTFOLIO_VIEW_KEY + portfolioId;
return getLong(key, 0L);
}
public Long getViewCount(String key) {
return getLong(key, 0L);
}
public final static String PERSONAL_HOMEPAGE_VIEW_KEY = "PersonalHomepage:view:";
public void increasePersonalHomepageViewCount(Long accountId) {
String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId;
increment(key, 1);
}
public Long getPersonalHomepageViewCount(Long accountId) {
String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId;
return getLong(key, 0L);
}
public final static String MOODBOARD_POSITION_KEY = "moodboard:position:";
public void saveMoodboardPosition(Long id, String moodboardPosition) {
setString(MOODBOARD_POSITION_KEY + id, moodboardPosition);
}
public String getMoodboardPosition(Long id) {
return getString(MOODBOARD_POSITION_KEY + id);
}
public final static String NICKNAME_MODIFY_TIMES = "NicknameModifyTimes:";
public void increaseCount(String key) {
increment(key, 1);
}
public Long getIncrementCount(String key) {
return getLong(key, 0L);
}
public void setKeyExpire(String key, Long expire) {
redisTemplate.expire(key, expire, TimeUnit.DAYS);
}
public final static String CHANGE_MAILBOX = "ChangeMailbox:";
// 每天允许通知3次
public final static String UPLOAD_TIMEOUT_REMINDER_COUNTER = "UploadTimeoutReminderCounter";
public void addProcessId(String processId, int progress) {
// Redis 中的键,可以通过 processId 来唯一标识
String redisKey = "process:progress:" + processId;
setInteger(redisKey, progress);
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
}
public void addPathToCache(Long collectionId, Long userId, String path) {
// Redis 中的键,唯一标识由 collectionId 和 userId 组成
String redisKey = "path:cache:" + collectionId + ":" + userId;
// 增加路径的计数
hashOperations.increment(redisKey, path, 1);
// 设置过期时间为 2 小时7200 秒)
redisTemplate.expire(redisKey, 2, TimeUnit.HOURS);
}
public int getPathUsageCount(Long collectionId, Long userId, String path) {
String redisKey = "path:cache:" + collectionId + ":" + userId;
// 获取路径的使用次数
Object count = hashOperations.get(redisKey, path);
return count != null ? ((Number) count).intValue() : 0;
}
public void addAssembledObjects(Long collectionId, Set<DesignPythonObject> assembledObjects) {
// Redis 中的键,使用 collectionId 来唯一标识
String redisKey = "collection:assembledObjects:" + collectionId;
// 将 assembledObjects 转换为 JSON 格式存储,避免直接存储对象
String assembledObjectsJson = convertToJson(assembledObjects);
if (assembledObjectsJson != null) {
// 使用 Redis 的 set 操作更新集合
setString(redisKey, assembledObjectsJson);
// 设置过期时间为 5 分钟300 秒)
redisTemplate.expire(redisKey, 30, TimeUnit.MINUTES);
}
}
private String convertToJson(Set<DesignPythonObject> assembledObjects) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(assembledObjects);
} catch (JsonProcessingException e) {
log.error("JSON转换失败", e);
return null;
}
}
public Set<DesignPythonObject> getAssembledObjects(Long collectionId) {
String redisKey = "collection:assembledObjects:" + collectionId;
String assembledObjectsJson = getString(redisKey);
if (assembledObjectsJson == null) {
return new HashSet<>();
}
return convertFromJson(assembledObjectsJson);
}
private Set<DesignPythonObject> convertFromJson(String json) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, new TypeReference<Set<DesignPythonObject>>() {});
} catch (JsonProcessingException e) {
log.error("JSON解析失败", e);
return new HashSet<>();
}
}
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime";
public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:";
public void increaseAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
increment(key, 1);
}
public Long getAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
return getLong(key, 0L);
}
public Long getAndSetKey(String key, Long count) {
Object oldValue = valueOperations.getAndSet(key, count);
if (oldValue instanceof Long) {
return (Long) oldValue;
} else if (oldValue instanceof Integer) {
return ((Integer) oldValue).longValue();
} else if (oldValue instanceof String) {
try {
return Long.parseLong((String) oldValue);
} catch (NumberFormatException e) {
log.warn("无法将字符串转换为Long: key={}, value={}", key, oldValue);
return 0L;
}
}
return 0L;
}
/**
* 记录任务的耗时到Redis
*/
public void recordTaskElapsedTime(String taskKey, long elapsedTime) {
String hashKey = "task:stats";
hashOperations.increment(hashKey, taskKey + ":totalTime", elapsedTime);
hashOperations.increment(hashKey, taskKey + ":count", 1);
}
/**
* 获取任务的平均耗时
*/
public double getTaskAverageTime(String taskKey) {
String hashKey = "task:stats";
Object totalTime = hashOperations.get(hashKey, taskKey + ":totalTime");
Object count = hashOperations.get(hashKey, taskKey + ":count");
if (totalTime == null || count == null) {
return 0;
}
try {
double total = ((Number) totalTime).doubleValue();
long cnt = ((Number) count).longValue();
return cnt > 0 ? total / cnt : 0;
} catch (Exception e) {
log.warn("计算平均耗时失败: taskKey={}", taskKey, e);
return 0;
}
}
/**
* 清除指定任务的统计数据
* @param taskKey 任务标识,如 "taskA"
*/
public void clearTaskStats(String taskKey) {
String hashKey = "task:stats";
// 删除总耗时和计数器
hashOperations.delete(hashKey, taskKey + ":totalTime", taskKey + ":count");
}
public void recordTaskElapsedTime(String taskKey, double elapsedTimeInSeconds) {
// 将耗时转换为 BigDecimal并四舍五入保留四位小数
BigDecimal elapsedTime = new BigDecimal(elapsedTimeInSeconds).setScale(4, RoundingMode.HALF_UP);
hashOperations.increment("task:stats", taskKey + ":totalTime", elapsedTime.doubleValue());
hashOperations.increment("task:stats", taskKey + ":count", 1);
}
// 获取第一部分Sketch耗时
public double getFirstSketchTime() {
Object time = hashOperations.get("task:stats", "firstSketchTime:totalTime");
return time != null ? ((Number) time).doubleValue() : 0.0;
}
// 获取第二部分(获取特征值)耗时
public double getGetAttributeRecognitionTime() {
Object time = hashOperations.get("task:stats", "getAttributeRecognitionTime:totalTime");
return time != null ? ((Number) time).doubleValue() : 0.0;
}
// 获取第三部分(搭配 Sketch耗时
public double getOtherSketchTime() {
Object time = hashOperations.get("task:stats", "otherSketchTime:totalTime");
return time != null ? ((Number) time).doubleValue() : 0.0;
}
// 清理三部分的缓存
public void clearTaskElapsedTimeCache() {
String hashKey = "task:stats";
Object[] keysToDelete = {
"firstSketchTime:totalTime", "firstSketchTime:count",
"getAttributeRecognitionTime:totalTime", "getAttributeRecognitionTime:count",
"otherSketchTime:totalTime", "otherSketchTime:count"
};
hashOperations.delete(hashKey, keysToDelete);
}
public boolean incrementLikeCount(Long userId, String sketchPath) {
String redisKey = "user_like_count:" + userId;
try {
hashOperations.increment(redisKey, sketchPath, 1);
return true;
} catch (Exception e) {
log.error("Error incrementing like count for userId {} and sketchPath {}: {}", userId, sketchPath, e.getMessage());
return false;
}
}
public int getLikeCount(Long userId, String sketchPath) {
String redisKey = "user_like_count:" + userId;
Object count = hashOperations.get(redisKey, sketchPath);
return count != null ? ((Number) count).intValue() : 0;
}
public void storeMaxLikeCount(Long userId, int maxLikeCount) {
String redisKey = "user_max_like_count:" + userId;
setInteger(redisKey, maxLikeCount);
}
public int getMaxLikeCount(Long userId) {
String redisKey = "user_max_like_count:" + userId;
return getInteger(redisKey, 0);
}
public final static String IMAGE_SEGMENTATION = "ImageSegmentation:";
public final static String STRIPE_EXCEPTION_LOG = "StripeException:";
public void batchDeleteKeysWithSamePrefix(String prefix) {
Set<String> keys = redisTemplate.keys(prefix + "*");
if (keys != null && !keys.isEmpty()) {
redisTemplate.delete(keys);
}
}
public void setTaskProgressDTO(String taskId, ProgressDTO dto) {
String key = "task:progress:" + taskId;
setString(key, JSON.toJSONString(dto));
redisTemplate.expire(key, 1, TimeUnit.DAYS);
}
public ProgressDTO getTaskProgressDTO(String taskId) {
String key = "task:progress:" + taskId;
String json = getString(key);
if (StringUtils.isBlank(json)) {
return null;
}
try {
return JSON.parseObject(json, ProgressDTO.class);
} catch (Exception e) {
log.warn("任务进度解析失败 key={}, json={}", key, json);
return new ProgressDTO(0, 0, false, null);
}
}
// Lua脚本
private static final String RATE_LIMIT_SCRIPT =
"local current = redis.call('INCR', KEYS[1])\n" +
"local ttl = redis.call('TTL', KEYS[1])\n" +
"if tonumber(current) == 1 or tonumber(ttl) == -1 then\n" +
" redis.call('EXPIRE', KEYS[1], ARGV[1])\n" +
"end\n" +
"return tonumber(current) <= tonumber(ARGV[2])";
/**
* 检查是否允许发送
* @param userId 用户ID
* @return true-允许发送false-已超限
*/
public boolean allowSend(Long userId) {
String hourKey = getCurrentHourKey(userId);
// 执行Lua脚本
List<String> keys = Collections.singletonList(hourKey);
// 1小时过期限制数量 一小时只能向普通用户发10封
String[] args = new String[]{"3600", "10"};
Boolean result = redisTemplate.execute(
new DefaultRedisScript<>(RATE_LIMIT_SCRIPT, Boolean.class),
keys,
args
);
return Boolean.TRUE.equals(result);
}
/**
* 获取当前小时的Key
*/
private String getCurrentHourKey(Long userId) {
String hour = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
return String.format("email_limit:%s:%s", userId, hour);
}
/**
* 获取当前已发送数量
*/
public int getCurrentCount(Long userId) {
String key = getCurrentHourKey(userId);
return getInteger(key, 0);
}
public boolean allowRequest(String apiKey) {
String key = "rate_limit:" + apiKey;
// 使用Redis的INCR命令
Long count = increment(key, 1);
if (count == 1) {
redisTemplate.expire(key, 1, TimeUnit.MINUTES);
}
return count <= 3;
}
// 新增方法安全删除key
public boolean safeDelete(String key) {
try {
return Boolean.TRUE.equals(redisTemplate.delete(key));
} catch (Exception e) {
log.error("删除Redis key失败: {}", key, e);
return false;
}
}
// 新增方法:批量设置过期时间
public void batchExpire(Set<String> keys, long timeout, TimeUnit unit) {
if (keys != null && !keys.isEmpty()) {
for (String key : keys) {
redisTemplate.expire(key, timeout, unit);
}
}
}
}

View File

@@ -426,7 +426,45 @@ public class SendEmailUtil {
}
}
// todo ?需要保留吗
private final static Long GENERATE_EXCEPTION_WARNING_ID = 122589L;
public static void sendGenerateExceptionWarning(String message) {
try {
// 实例化一个认证对象
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
req.setDestination(new String[]{"xupei3360@163.com"});
// 根据邮件类型设置不同的主题和模板
String subject = "";
Template template = new Template();
subject = "Warning: AiDA 3.0 Generate Exception Warning";
template.setTemplateID(GENERATE_EXCEPTION_WARNING_ID);
JSONObject parameter = new JSONObject();
parameter.put("errorMessage", message);
parameter.put("time", DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
template.setTemplateData(parameter.toJSONString());
req.setSubject(subject);
req.setTemplate(template);
// 发送邮件
SendEmailResponse resp = client.SendEmail(req);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail");
}
}
private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L;
private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L;
@@ -568,7 +606,6 @@ public class SendEmailUtil {
}
}
// todo 目前该定时器已取消,是否需要保留该模板?
private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L;
public static void notificationForRegisterUser(String receiverAddress) {
@@ -607,11 +644,55 @@ public class SendEmailUtil {
}
}
private final static Long CHANGE_MAILBOX_CONFIRM_CN = 128278L;
private final static Long CHANGE_MAILBOX_CONFIRM_EN = 128277L;
public static void changeMailboxConfirm(String receiverAddress, String language, String name, String link) {
try {
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(SEND_ADDRESS);
req.setDestination(new String[]{receiverAddress});
Template template = new Template();
if (language.equals("ENGLISH")) {
req.setSubject("Change the email address bound to the AiDA account");
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_EN);
} else {
req.setSubject("更换AiDA账号绑定的邮箱地址");
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_CN);
}
JSONObject param = new JSONObject();
param.put("userName", name);
param.put("link", link);
template.setTemplateData(param.toJSONString());
req.setTemplate(template);
// 返回的resp是一个SendEmailResponse的实例与请求对象对应
SendEmailResponse resp = client.SendEmail(req);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail");
}
}
private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L;
public static void uploadTimeoutReminder(String userName, String time) {
String xp = "xupei3360@163.com";
String shb = "shahaibodd99@gmail.com";
String wxd = "X1627315083@163.com";
String pkc = "kaicpang.pang@connect.polyu.hk";
try {
@@ -630,7 +711,7 @@ public class SendEmailUtil {
// 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(SEND_ADDRESS);
req.setDestination(new String[]{shb, xp, wxd, pkc});
req.setDestination(new String[]{xp, wxd, pkc});
Template template = new Template();
req.setSubject("上传图片超时提醒");
template.setTemplateID(UPLOAD_TIMEOUT_REMINDER);
@@ -650,7 +731,7 @@ public class SendEmailUtil {
}
}
/*private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
private final static Long HALFPRICEPROMOTION_EN_ID = 128583L;
public static void halfPricePromotion(Account account, String senderAddress, int type) {
@@ -739,15 +820,18 @@ public class SendEmailUtil {
log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail");
}
}*/
}
private final static Long CANCEL_MERCHANT_EN = 130720L;
// private final static Long NEW_MERCHANT_EN = 130721L;
// private final static Long NEW_USER_EN = 130722L;
// private final static Long NEW_USER_CN = 130723L;
private final static Long NEW_MERCHANT_EN = 135190L;
private final static Long NEW_USER_EN = 135189L;
private final static Long NEW_USER_CN = 135186L;
private final static Long NEW_MERCHANT_EN = 140335L;
// private final static Long NEW_MERCHANT_EN = 135190L;
// private final static Long NEW_USER_EN = 135189L;
// private final static Long NEW_USER_CN = 135186L;
private final static Long NEW_USER_EN = 140316L;
private final static Long NEW_USER_CN = 140317L;
private final static Long RENEWAL_MERCHANT_EN = 130724L;
private final static Long RENEWAL_USER_EN = 130725L;
private final static Long RENEWAL_USER_CN = 130726L;
@@ -762,7 +846,7 @@ public class SendEmailUtil {
try {
String merchantEmail = "kimwong@code-create.com.hk";
String developer = "xupei3360@163.com";
String[] receiverEmail = {/*merchantEmail,*/ developer};
String[] receiverEmail = {merchantEmail, developer};
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
@@ -932,7 +1016,7 @@ public class SendEmailUtil {
req.setFromEmailAddress(SEND_ADDRESS);
String merchantEmail = "kimwong@code-create.com.hk";
String developerEmail = "xupei@code-create.com.hk";
req.setDestination(new String[]{/*merchantEmail,*/ developerEmail});
req.setDestination(new String[]{merchantEmail, developerEmail});
Template template = new Template();
req.setSubject("New Credit Purchase Order");
template.setTemplateID(CREDITS_PURCHASE_MERCHANT);
@@ -992,52 +1076,4 @@ public class SendEmailUtil {
}
}
private final static Long CN_2025_618 = 141425L;
private final static Long EN_2025_618 = 141424L;
public static void send618PromotionEmailTemp(String receiver, String language){
try {
// 实例化一个认证对象
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
req.setDestination(new String[]{receiver});
// 根据邮件类型设置不同的主题和模板
String subject = "";
Template template = new Template();
// if (type == 1) {
// subject = "Upcoming System Upgrade for AiDA 3.0";
// template.setTemplateID(UPGRADE_NOTIFICATION_ID);
// }else {
// subject = "即将到来的AiDA 3.0系统升级";
// template.setTemplateID(UPGRADE_NOTIFICATION_ID_CHINESE);
// }
if (language.equals("ENGLISH")) {
subject = "Welcome back Subscribe AiDA with the discount code to enjoy 50% OFF!";
template.setTemplateID(EN_2025_618);
}else {
subject = "设计时速狂飙AiDA 618半价让灵感永不限流";
template.setTemplateID(CN_2025_618);
}
req.setSubject(subject);
req.setTemplate(template);
// 发送邮件
SendEmailResponse resp = client.SendEmail(req);
log.info("邮件发送成功,收件人地址:{}", receiver);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
log.info(receiver);
log.error("邮件发送失败###{},收件人地址:{}", e.toString(), receiver);
}
}
}

View File

@@ -1,153 +0,0 @@
package com.ai.da.common.utils;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Map;
@Slf4j
@Component
public class SendRequestUtil {
@Value("${ALIYUN_API_KEY}")
private String ALIYUN_API_KEY;
@Value("${FREEPIK_API_KEY}")
private String FREEPIK_API_KEY;
public String sendAliYunPostAsync(String apiUrl, String requestBody){
// 发送POST请求 todo 异常处理
HttpResponse execute = HttpRequest.post(apiUrl)
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
.header("X-DashScope-Async", "enable")
.header(Header.CONTENT_TYPE, "application/json")
.body(requestBody)
.timeout(20000) // 设置超时时间20秒
.execute();
int status = execute.getStatus();
if (status == 200){
String body = execute.body();
JSONObject bodyJson = JSONUtil.parseObj(body);
return body;
}
log.warn("请求失败,状态码为 {}", status);
return null;
}
public String sendAliYunPost(String apiUrl, String requestBody){
// 发送POST请求 todo 异常处理
HttpResponse execute = HttpRequest.post(apiUrl)
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
.header(Header.CONTENT_TYPE, "application/json")
.body(requestBody)
.timeout(20000) // 设置超时时间20秒
.execute();
int status = execute.getStatus();
if (status == 200){
String body = execute.body();
JSONObject bodyJson = JSONUtil.parseObj(body);
return body;
}
log.warn("请求失败,状态码为 {}", status);
return null;
}
public static final String FREE_PIK = "https://api.freepik.com/v1/ai/beta/text-to-image/reimagine-flux";
public String sendFreepikPost( String requestBody){
// 发送POST请求 todo 异常处理
HttpResponse execute = HttpRequest.post(FREE_PIK)
.header(Header.CONTENT_TYPE, "application/json")
.header("x-freepik-api-key", FREEPIK_API_KEY)
.body(requestBody)
.timeout(20000) // 设置超时时间20秒
.execute();
int status = execute.getStatus();
if (status == 200){
return execute.body();
}
log.warn("请求失败,状态码为 {}", status);
return null;
}
public String sendAliYunGet(String fullUrl){
// 发送GET请求 todo 异常处理
HttpResponse httpResponse = HttpRequest.get(fullUrl)
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
.timeout(20000) // 设置超时时间20秒
.execute();
int status = httpResponse.getStatus();
if (status == 200){
return httpResponse.body();
}else {
return null;
}
}
public String sendFluxPost(String url, String requestBodyStr){
int status;
String body;
try (HttpResponse execute = HttpRequest.post(url)
.header(Header.CONTENT_TYPE, "application/json")
.header("x-key", "d447a0ac-2291-4f1c-9a36-f7614c385989")
.body(requestBodyStr) // Hutool 会自动处理 JSON 序列化
.timeout(180000) // 设置超时(毫秒)
.execute()) {
status = execute.getStatus();
body = execute.body();
if (status == 200) {
return body;
}
}
log.warn("请求失败,状态码为 {}", status);
return null;
}
public String sendPost(String url, String requestBodyStr){
int status;
String body;
try (HttpResponse execute = HttpRequest.post(url)
.header("Content-Type", "application/json") // 必须设置 Content-Type
.body(requestBodyStr) // Hutool 会自动处理 JSON 序列化
.timeout(180000) // 设置超时(毫秒)
.execute()) {
status = execute.getStatus();
body = execute.body();
if (status == 200) {
return body;
}
}
log.warn("请求失败,状态码为 {}, body: {}", status, body);
return null;
}
public String sendGet(String url, Map<String, Object> params) {
int status;
String body;
try (HttpResponse execute = HttpRequest.get(url)
.form(params) // 直接传入MapHutool会正确处理
.timeout(180000)
.execute()) {
status = execute.getStatus();
body = execute.body();
if (status == 200) {
return body;
}
} catch (Exception e) {
log.error("请求发生异常: {}", e.getMessage(), e);
return null;
}
log.warn("请求失败,状态码为: {}, body: {}", status, body);
return body;
}
}

View File

@@ -22,12 +22,10 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Api(tags = "Account模块")
@@ -173,30 +171,29 @@ public class AccountController {
@CrossOrigin
@ApiOperation(value = "广场用户注册")
@PostMapping("/designWorksRegisterCode")
public Response<AccountLoginVO> designWorksRegisterCode(@Valid @RequestBody AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO,
HttpServletRequest request) {
return Response.success(accountService.designWorksRegisterCode(accountDesignWorksRegisterDTO, request));
public Response<AccountLoginVO> designWorksRegisterCode(@Valid @RequestBody AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) {
return Response.success(accountService.designWorksRegisterCode(accountDesignWorksRegisterDTO));
}
/**
* 填写调查问卷
* @return
*/
/* @ApiOperation(value = "填写调查问卷")
@ApiOperation(value = "填写调查问卷")
@PostMapping("/questionnaire")
public Response<Boolean> questionnaire(@Valid @RequestBody String questionnaireInfo){
return Response.success(accountService.collectQuestionnaires(questionnaireInfo));
}*/
}
/**
* 参与活动 获取福利
* @return
*/
/* @ApiOperation(value = "参与活动 获取福利")
@ApiOperation(value = "参与活动 获取福利")
@GetMapping("/activity")
public Response<String> getActivityBenefits(){
return Response.success(accountService.getActivityBenefits());
}*/
}
@ApiOperation(value = "将用户账号过期时间设置为过期当天的235959")
@GetMapping("/setUserValidToDayEnd")
@@ -276,22 +273,16 @@ public class AccountController {
@PostMapping("enterpriseLogin")
@ApiOperation(value = "企业登录")
public Response<AccountPreLoginVO> enterpriseLogin(@Valid @RequestBody AccountLoginDTO accountDTO) {
public Response<AccountLoginVO> enterpriseLogin(@Valid @RequestBody AccountLoginDTO accountDTO) {
return Response.success(accountService.enterpriseLogin(accountDTO));
}
@PostMapping("schoolLogin")
@ApiOperation(value = "学校登录")
public Response<AccountPreLoginVO> schoolLogin(@Valid @RequestBody AccountLoginDTO accountDTO) {
public Response<AccountLoginVO> schoolLogin(@Valid @RequestBody AccountLoginDTO accountDTO) {
return Response.success(accountService.schoolLogin(accountDTO));
}
@PostMapping("organizationNameSearch")
@ApiOperation(value = "组织名模糊查询")
public Response<Set<String>> organizationNameSearch(@RequestParam("type") String type, @RequestParam("name") String name) {
return Response.success(accountService.organizationNameSearch(type, name));
}
@PostMapping("addOrUpdateSubAccount")
@ApiOperation(value = "子账号新增")
public Response<Boolean> addSubAccount(@Valid @RequestBody AddSubAccountDTO addSubAccountDTO) {
@@ -301,9 +292,7 @@ public class AccountController {
@PostMapping("deleteSubAccount")
@ApiOperation(value = "子账号删除")
public Response<Boolean> deleteSubAccount(@Valid @RequestBody AddSubAccountDTO addSubAccountDTO) {
// return Response.success(accountService.deleteSubAccount(addSubAccountDTO));
accountService.removeSubAccount(addSubAccountDTO);
return Response.success();
return Response.success(accountService.deleteSubAccount(addSubAccountDTO));
}
@PostMapping("subAccountList")
@@ -359,37 +348,4 @@ public class AccountController {
public Response<Boolean> updateUserInfo(@Valid @RequestBody UpdateUserInfoDTO updateUserInfoDTO) {
return Response.success(accountService.updateUserInfo(updateUserInfoDTO));
}
@GetMapping("/subAccountImportExcelDownload")
@ApiOperation(value = "模板下载")
public void subAccountImportExcelDownload(HttpServletResponse response) {
accountService.subAccountImportExcelDownload(response);
}
@GetMapping("/exportAccountsToExcel")
@ApiOperation(value = "下载子账号信息")
public void exportAccountsToExcel(HttpServletResponse response) {
accountService.exportAccountsToExcel(response);
}
@PostMapping("/subAccountImport")
@ApiOperation(value = "模板导入")
public Response<Boolean> subAccountImport(@RequestParam("file") MultipartFile file) {
return Response.success(accountService.subAccountImport(file));
}
/*@GetMapping("/send618Email")
@ApiOperation(value = "618邮件发送")
public Response<String> send618PromotionEmailTemp() {
accountService.send618PromotionEmailTemp();
return Response.success("success");
}*/
@GetMapping("/refreshCreditsMonthly")
@ApiOperation(value = "刷新子账号积分")
public void refreshCreditsMonthly() {
accountService.refreshCreditsMonthly();
}
}

View File

@@ -4,24 +4,17 @@ 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.AffiliateQueryDTO;
import com.ai.da.model.dto.EditReferralDTO;
import com.ai.da.model.dto.ReferralPageQueryDTO;
import com.ai.da.model.vo.AffiliateInvitationDetailsVO;
import com.ai.da.model.vo.AffiliateVO;
import com.ai.da.model.vo.ReferralPageQueryVO;
import com.ai.da.service.AffiliateService;
import com.ai.da.service.ReferralService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
@Slf4j
@RestController
@@ -32,9 +25,6 @@ public class AffiliateController {
@Resource
private AffiliateService affiliateService;
@Resource
private ReferralService referralService;
@ApiOperation(value = "注册成为affiliate")
@GetMapping("/registration")
public Response<Boolean> completeGuidance(@RequestParam(value = "promotionMethod", required = false) String promotionMethod) {
@@ -43,7 +33,7 @@ public class AffiliateController {
@ApiOperation(value = "获取affiliate列表")
@PostMapping("/list")
public Response<PageBaseResponse<AffiliateVO>> getAffiliateList(@Validated @RequestBody AffiliateQueryDTO affiliateQueryDTO) {
public Response<PageBaseResponse<AffiliateVO>> getAffiliateList(@Valid @RequestBody AffiliateQueryDTO affiliateQueryDTO) {
return Response.success(affiliateService.getAffiliateList(affiliateQueryDTO));
}
@@ -55,7 +45,7 @@ public class AffiliateController {
@ApiOperation(value = "获取个人佣金图表数据")
@GetMapping("/getPersonalMonthlyIncome")
public Response<BigDecimal[]> getPersonalMonthlyIncome(@RequestParam("year")int year) {
public Response<double[]> getPersonalMonthlyIncome(@RequestParam("year")int year) {
return Response.success(affiliateService.getPersonalMonthlyIncome(year));
}
@@ -63,7 +53,7 @@ public class AffiliateController {
@GetMapping("/approval")
public Response<Boolean> applicationApproval(@RequestParam("id") Long id,
@RequestParam("isApproved")Boolean isApproved,
@RequestParam(value = "commission", required = false) Float commission) {
@RequestParam("commission") Float commission) {
return Response.success(affiliateService.applicationApproval(id, isApproved, commission));
}
@@ -96,35 +86,9 @@ public class AffiliateController {
@ApiOperation(value = "获取每个affiliate产生的收入")
@PostMapping("/getEachAffiliateGeneratedRevenue")
public Response<IPage<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@Validated @RequestBody AffiliateQueryDTO affiliateQueryDTO) {
public Response<IPage<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@RequestBody AffiliateQueryDTO affiliateQueryDTO) {
return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(affiliateQueryDTO));
}
@ApiOperation(value = "分页获取所有的referral")
@PostMapping("/getReferrals")
public Response<IPage<ReferralPageQueryVO>> getReferrals(@RequestBody ReferralPageQueryDTO referralPageQueryDTO) {
return Response.success(referralService.queryByPage(referralPageQueryDTO));
}
@ApiOperation(value = "编辑单个referral")
@PostMapping("/editReferral")
public Response<String> editReferral(@Validated @RequestBody EditReferralDTO editReferralDTO) {
referralService.editReferral(editReferralDTO);
return Response.success();
}
@ApiOperation(value = "批量删除referral")
@PostMapping("/batchDeleteReferral")
public Response<String> batchDeleteReferral(@RequestBody List<Long> idList) {
referralService.deleteReferral(idList);
return Response.success();
}
@ApiOperation(value = "获取所有affiliate用户名")
@GetMapping("/getAllAffiliateUsername")
public Response<List<Map<String, Object>>> getAllAffiliateUsername() {
return Response.success(affiliateService.getAllAffiliateUsername());
}
}

View File

@@ -6,9 +6,10 @@ import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.DesignMapper;
import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.Organization;
import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.*;
import com.ai.da.model.dto.AccountAddDTO;
import com.ai.da.model.dto.QueryPaymentInfoDTO;
import com.ai.da.model.dto.UserDesignStatisticDTO;
import com.ai.da.model.vo.PaymentInfoVO;
import com.ai.da.model.vo.QuestionnaireFeedbackVO;
import com.ai.da.model.vo.QuestionnaireVO;
@@ -16,6 +17,7 @@ import com.ai.da.model.vo.QueryUserConditionsVO;
import com.ai.da.service.AccountService;
import com.ai.da.service.ConvenientInquiryService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@@ -49,7 +51,9 @@ public class ConvenientInquiryController {
String userEmail = accountService.getById(accountId).getUserEmail();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L)
|| accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)
|| userEmail.equals("joho8228@hotmail.com") || userEmail.equals("wanninghua160@gmail.com")
|| userEmail.equals("joho8228@hotmail.com")
|| userEmail.equals("chelseayu@code-create.com.hk")
|| userEmail.equals("cheungzt007@gmail.com")
) {
return Response.success(convenientInquiryService.getTrial(queryUserConditionsVO));
} else {
@@ -61,7 +65,28 @@ public class ConvenientInquiryController {
@GetMapping("/getDesignStatistic")
public Response<List<UserDesignStatisticDTO>> getDesignStatistic(@RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime,
@RequestParam(required = false) List<Long> ids, @RequestParam(required = false) String email) {
return Response.success(convenientInquiryService.getDesignStatistic(startTime, endTime, ids, email));
Long accountId = UserContext.getUserHolder().getId();
String userEmail = accountService.getById(accountId).getUserEmail();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L)
|| accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)
|| userEmail.equals("joho8228@hotmail.com")
|| userEmail.equals("chelseayu@code-create.com.hk")
|| userEmail.equals("cheungzt007@gmail.com")
) {
if (StringUtil.isNullOrEmpty(startTime)) startTime = "2024-02-01 00:00:00";
if (StringUtil.isNullOrEmpty(endTime)) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = new Date();
endTime = simpleDateFormat.format(date);
}
if (!StringUtil.isNullOrEmpty(email)){
email = email.trim();
}
List<UserDesignStatisticDTO> designStatistic = designMapper.getDesignStatistic(startTime, endTime, ids, email);
return Response.success(designStatistic);
} else {
return Response.fail("Sorry, you don't have permission");
}
}
@@ -163,7 +188,9 @@ public class ConvenientInquiryController {
String userEmail = accountService.getById(accountId).getUserEmail();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L)
|| accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)
|| userEmail.equals("joho8228@hotmail.com") || userEmail.equals("wanninghua160@gmail.com")
|| userEmail.equals("joho8228@hotmail.com")
|| userEmail.equals("chelseayu@code-create.com.hk")
|| userEmail.equals("cheungzt007@gmail.com")
) {
return Response.success(convenientInquiryService.getUserInfo(queryUserConditionsVO));
} else {
@@ -194,30 +221,4 @@ public class ConvenientInquiryController {
public Response<String> exportTransactionRecords(@Valid @RequestBody QueryPaymentInfoDTO queryPaymentInfoDTO, HttpServletResponse response){
return Response.success(convenientInquiryService.exportTransactionRecords(queryPaymentInfoDTO, response));
}
@ApiOperation("获取生成功能使用频次")
@PostMapping("/getGenerateFrequency")
public Response<PageBaseResponse<AccountCreditsUsageDTO>> getGenerateFrequency(@Valid @RequestBody AccountCreditsUsageQueryDTO queryDTO){
return Response.success(convenientInquiryService.getGenerateFrequency(queryDTO));
}
@ApiOperation("获取所有生成功能的名字")
@GetMapping("/getAllGenerateFuncName")
public Response<List<String>> getAllGenerateFuncName(){
return Response.success(convenientInquiryService.getAllGenerateFuncName());
}
@ApiOperation("添加组织机构")
@GetMapping("/addOrganization")
public Response<String> addOrganization(@ApiParam(value = "机构名") @RequestParam String name, @ApiParam(value = "Enterprise || Education") @RequestParam String type){
convenientInquiryService.addOrganization(name, type);
return Response.success();
}
@ApiOperation("查询所有企业或教育机构")
@GetMapping("/queryOrganization")
public Response<List<Organization>> queryOrganization(@ApiParam(value = "Enterprise || Education") @RequestParam String type){
return Response.success(convenientInquiryService.queryOrganization(type));
}
}

View File

@@ -1,14 +1,12 @@
package com.ai.da.controller;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.entity.CloudTask;
import com.ai.da.mapper.primary.entity.CollectionSort;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.model.vo.CollectionSketchVO;
import com.ai.da.model.vo.DesignCollectionVO;
import com.ai.da.model.vo.DesignLikeVO;
import com.ai.da.service.DesignService;
import com.ai.da.service.UserLikeGroupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@@ -29,8 +27,6 @@ import java.util.List;
public class DesignController {
@Resource
private DesignService designService;
@Resource
private UserLikeGroupService userLikeGroupService;
@ApiOperation(value = "设计 Conllection")
@PostMapping("/designCollection")
@@ -77,7 +73,7 @@ public class DesignController {
@ApiOperation(value = "Design sort")
@PostMapping("/sort")
public Response<Boolean> sort(@Valid @RequestBody CollectionSortDTO userLikeSortDTO) {
public Response<Boolean> sort(@Valid @RequestBody UserLikeSortDTO userLikeSortDTO) {
return Response.success(designService.sort(userLikeSortDTO));
}
@@ -101,31 +97,8 @@ public class DesignController {
@ApiOperation(value = "云生成")
@PostMapping("/designCloud")
public Response<String> designCloud(@Valid @RequestBody CloudTaskDTO cloudTaskDTO) {
return Response.success(designService.designCloud(cloudTaskDTO));
}
@ApiOperation(value = "云生成修改任务名")
@PostMapping("/cloudTaskNameUpdate")
public Response<Boolean> cloudTaskNameUpdate(@Valid @RequestBody CloudTaskDTO cloudTaskDTO) {
return Response.success(designService.cloudTaskNameUpdate(cloudTaskDTO));
}
@ApiOperation(value = "云生成删除任务")
@PostMapping("/cloudTaskDelete")
public Response<Boolean> cloudTaskDelete(@Valid @RequestBody CloudTaskDTO cloudTaskDTO) {
return Response.success(designService.cloudTaskDelete(cloudTaskDTO));
}
@ApiOperation(value = "云生成page")
@PostMapping("/cloudPage")
public Response<PageBaseResponse<CloudTaskVO>> cloudPage(@Valid @RequestBody CloudPageDTO cloudPageDTO) {
return Response.success(PageBaseResponse.success(designService.cloudPage(cloudPageDTO)));
}
@ApiOperation(value = "获取design云生成结果")
@PostMapping("/getDesignCloudResult")
public Response<CloudTaskResultVO> getDesignCloudResult(@Valid @RequestBody DesignCloudResultQuery designCloudResultQuery) {
return Response.success(designService.getDesignCloudResult(designCloudResultQuery));
@CrossOrigin
public Response<String> designCloud(@Valid @RequestBody DesignCollectionDTO designDTO) {
return Response.success(designService.designCloud(designDTO));
}
}

View File

@@ -18,10 +18,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Api(tags = "collection模块")
@@ -53,15 +50,13 @@ public class ElementController {
@ApiParam("一级类型 Moodboard Printboard Sketchboard MarketingSketch Colorboard")
@RequestParam(value = "level1Type") String level1Type,
@RequestParam(name = "gender", required = false) String gender,
@RequestParam(name = "level2Type", required = false) String level2Type,
@RequestParam(name = "projectId", required = false) Long projectId,
@ApiParam("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
@RequestParam(value = "timeZone") String timeZone) {
if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) {
throw new BusinessException("file.cannot.be.empty");
}
return Response.success(collectionElementService.upload(
new CollectionElementUploadDTO(file, projectId, level1Type, level2Type, gender, timeZone, MD5Utils.encryptFile(file))));
new CollectionElementUploadDTO(file, level1Type, gender, timeZone, MD5Utils.encryptFile(file))));
}
@ApiOperation(value = "element文件删除")
@@ -111,33 +106,4 @@ public class ElementController {
return Response.success();
}
@ApiOperation(value = "图片分割")
@PostMapping("/imageSegmentation")
public Response<List<CollectionElementVO>> selectedImageSeg(
@RequestPart(value = "file", required = false) MultipartFile[] file,
@RequestParam(value = "type", required = false) @Pattern(regexp = "sketch|product", message = "Please choose the image type") String type,
@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "sourceType", required = false) @Pattern(regexp = "Library|Upload", message = "Select an image from the library or upload one.") String sourceType) {
// 过滤空文件
List<MultipartFile> nonEmptyFiles = Arrays.stream(file)
.filter(item -> !item.isEmpty())
.collect(Collectors.toList());
// 参数校验
if ((nonEmptyFiles.isEmpty()) && id == null) {
throw new BusinessException("必须提供文件上传或ID");
}
if (!nonEmptyFiles.isEmpty() && id != null) {
throw new BusinessException("不能同时提供文件上传和ID");
}
return Response.success(collectionElementService.selectedImageSeg(nonEmptyFiles, id, type, sourceType));
}
@ApiOperation(value = "更新element level2type")
@GetMapping("/updateElementLevel2Type")
public Response<String> updateLibraryLevel2Type(@RequestParam(value = "elementId") Long elementId, @RequestParam(value = "level2Type") String level2Type) {
collectionElementService.updateElementLevel2Type(elementId, level2Type);
return Response.success("success");
}
}

View File

@@ -1,42 +0,0 @@
package com.ai.da.controller;
import com.ai.da.service.EmailService;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import java.util.Collections;
@Api(tags = "邮件模块")
@Slf4j
@RestController
@RequestMapping("/api/email")
public class EmailController {
@Resource
private EmailService emailService;
@GetMapping("/loadSingleTemplate")
public void loadSingleEmailTemplate(){
emailService.loadSingleEmailTemplate("templates\\upgrade\\122899_AiDA发版完成通知中文版.html");
}
@GetMapping("/loadTemplate")
public void loadTemplatesFromResources(){
emailService.loadTemplatesFromResources("templates");
}
@GetMapping("/sendEmailTest")
public void sendEmailTest(){
Context context = new Context();
context.setVariable("username", "小白");
JSONObject jsonObject = new JSONObject();
jsonObject.put("username", "小白");
emailService.sendEmail(Collections.singletonList("xupei3360@163.com"), jsonObject, "132124_affiliate_accepted_en.html", "测试邮件", null, null );
}
}

View File

@@ -1,240 +1,101 @@
package com.ai.da.controller;
import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.entity.CollectionSort;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.GenerateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
/**
* @author XP
*/
@Api(tags = "Generate模块")
@Slf4j
@RestController
@RequestMapping("/api/generate")
public class GenerateController {
@Resource
private GenerateService generateService;
/*@ApiOperation("自动识别sketch的caption 暂时未上")
@PostMapping("/caption")
public Response<GenerateCaptionVO> generateCaption(@RequestParam Long sketchElementId) {
return Response.success(generateService.generateCaption(sketchElementId));
}*/
/*@ApiOperation("通过文字、图片生成图片")
@PostMapping("/sketchAndPrint")
public void generateThroughImageText(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) {
// return Response.success(generateService.generateThroughImageText(generateThroughImageTextDTO));
generateService.generateThroughImageText(generateThroughImageTextDTO);
}*/
@ApiOperation("喜欢生成的图片")
@PostMapping("/like")
public Response<GenerateLikeVO> like(@Valid @RequestBody GenerateLikeDTO generateLikeDTO) {
return Response.success(generateService.generateLike(generateLikeDTO));
}
@ApiOperation(value = "取消喜欢")
@GetMapping("/dislike")
public Response<Boolean> dislike(@ApiParam("generateDetailId") @RequestParam Long generateDetailId,
@ApiParam("timeZone") @RequestParam String timeZone) {
return Response.success(generateService.generateDislike(generateDetailId, timeZone));
}
@ApiOperation(value = "发起生成请求,异步获取结果")
@PostMapping("/prepare")
public ResponseEntity<Response<PrepareForGenerateVO>> prepareForGenerate(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) {
PrepareForGenerateVO prepareForGenerateVO = generateService.prepareForGenerate(generateThroughImageTextDTO);
if (prepareForGenerateVO.getStatus().equals(200)){
prepareForGenerateVO.setStatus(0);
return ResponseEntity.ok(Response.success(prepareForGenerateVO));
} else {
return ResponseEntity.status(prepareForGenerateVO.getStatus()).body(Response.fail("The rate limit has been exceeded. Please wait 1 minute before retrying."));
}
}
@ApiOperation(value = "取消继续生成")
@GetMapping("/stopWaiting")
public Response<String> stopWaiting(@RequestParam("userId") Long userId,
@RequestParam("uniqueId") List<String> uniqueId,
@RequestParam("timeZone") String timeZone,
@RequestParam("type") String type) {
generateService.cancelGenerate(userId, uniqueId, timeZone, type);
return Response.success("stop waiting successfully");
}
/*@ApiOperation(value = "获取生成结果")
@GetMapping("/result")
public Response<GenerateCollectionVO> getGenerateResult(@RequestParam("uniqueId") String uniqueId) {
GenerateCollectionVO generateResult = generateService.getGenerateResult(uniqueId);
return Response.success(generateResult);
}*/
@ApiOperation(value = "获取生成结果")
@PostMapping("/result")
public Response<List<GenerateResultVO>> getGenerateResults(@Valid @RequestBody List<String> taskIdList) {
List<GenerateResultVO> generateResult = generateService.getGenerateResultList(taskIdList);
return Response.success(generateResult);
}
@ApiOperation(value = "imageToSketch")
@PostMapping("/imageToSketch")
public Response<String> imageToSketch(@Valid @RequestBody ImageToSketchDTO imageToSketchDTO) {
return Response.success(generateService.imageToSketchAsync(imageToSketchDTO, null, null));
// return Response.success(generateService.imageToSketch(imageToSketchDTO, null, null));
}
// modifySketch
@ApiOperation(value = "modifySketch")
@PostMapping("/modifySketch")
public Response<GenerateResultVO> modifySketch(@Valid @RequestBody GenerateModifyDTO generateModifyDTO) {
return Response.success(generateService.modifySketch(generateModifyDTO));
}
@ApiOperation(value = "请求进行姿势变换")
@PostMapping("/poseTransform")
public Response<ToProductImageResultVO> poseTransform(@Valid @RequestBody PoseTransformDTO poseTransformDTO) {
return Response.success(generateService.poseTransform(poseTransformDTO));
}
@ApiOperation(value = "获取姿势变换生成结果")
@PostMapping("/poseTransformResult")
public Response<List<PoseTransformationVO>> getPoseTransformationResults(@Valid @RequestBody List<String> taskIdList) {
List<PoseTransformationVO> generateResult = generateService.getPoseTransformationResult(taskIdList, null, null);
return Response.success(generateResult);
}
@ApiOperation("喜欢或取消喜欢姿势变换生成的图片")
@PostMapping("/likeOrDislike")
public Response<CollectionSort> likeOrDislike(@ApiParam("id") @RequestParam Long transformedId, @ApiParam("like || dislike") @RequestParam String likeOrDislike, @RequestParam("projectId") Long projectId, @RequestParam(value = "collectionSortParentId", required = false) Long collectionSortParentId) {
return Response.success(generateService.disOrLikePose(transformedId, likeOrDislike, projectId, collectionSortParentId));
}
@ApiOperation(value = "修改模特比例")
@PostMapping("/modifyProportion")
public Response<String> modifyModelProportion(@Valid @RequestBody ModifyModelProportionDTO proportionDTO){
String path = generateService.modifyModelProportion(proportionDTO);
return Response.success(path);
}
@ApiOperation(value = "拼贴图生成线稿")
@PostMapping("/genSketchRecon")
public Response<GenerateResultVO> sketchReconstructionGenerate(@Valid @RequestBody SketchReconstructionDTO sketchReconstructionDTO){
GenerateResultVO generateResultVO = generateService.sketchReconstructionGenerate(sketchReconstructionDTO);
return Response.success(generateResultVO);
}
@ApiOperation(value = "获取拼贴图最后一次生成结果")
@GetMapping("/getReconLastResult")
public Response<SketchReconstructionVO> getSketchReconstruction(@RequestParam("projectId") Long projectId){
SketchReconstructionVO sketchReconstruction = generateService.getSketchReconstruction(projectId);
return Response.success(sketchReconstruction);
}
@ApiOperation(value = "获取pose transfer的所有pose")
@GetMapping("/getAllPose")
public Response<List<Map<String, String>>> getAllPose(){
return Response.success(generateService.getAllPose());
}
@ApiOperation(value = "删除pose transfer的结果")
@GetMapping("/deleteResult")
public Response<String> deleteToProductRelightResult(@RequestParam("projectId") @NotNull Long projectId,
@RequestParam("id") @NotNull Long id){
try{
generateService.deleteGeneratedPose(projectId, id);
return Response.success();
}catch (Exception e){
return Response.fail(e.getMessage());
}
}
/*@ApiOperation(value = "万象 t2i 创建异步任务")
@GetMapping("/createAsyncTask")
public Response<String> createAsyncTask(@RequestParam("prompt") String prompt){
return Response.success(generateService.createAsyncTask(87L, prompt, ""));
}
@ApiOperation(value = "万象 t2i 获取异步任务结果")
@GetMapping("/waitAsyncTask")
public Response<GenerateResultVO> waitAsyncTask(@RequestParam("taskId") String taskId){
return Response.success(generateService.getAsyncTaskResult(taskId));
}
@ApiOperation(value = "万象 图生动图")
@GetMapping("/animateAnyone")
public Response<String> animateAnyone(@Valid @RequestBody PoseTransformDTO poseTransformDTO){
return Response.success(generateService.animateAnyone(poseTransformDTO, null));
}
@ApiOperation(value = "万象 获取动图模板id")
@GetMapping("/getVideoTemplateId")
public Response<String> getVideoTemplateId(@RequestParam("videoPath") String videoPath){
return Response.success(generateService.getVideoTemplateId(videoPath));
}
@ApiOperation(value = "万象 获取动图结果")
@GetMapping("/getAnimateResult")
public Response<PoseTransformationVO> getAnimateResult(@RequestParam("taskId") String taskId){
return Response.success(generateService.getAnimateResult(taskId));
}
@ApiOperation(value = "freepik toProductImage")
@GetMapping("/reimagineFreePik")
public Response<String> reimagineFreePik(@RequestParam("path") String path,
@RequestParam("prompt") String prompt,
@RequestParam("style") String style) throws IOException {
return Response.success(generateService.reimagineFreePik(path, prompt, style));
}
@ApiOperation(value = "获取图片描述")
@GetMapping("/getImageDescription")
public Response<String> getImageDescription(@RequestParam("path") String path) {
return Response.success(generateService.getImageDescription(path));
}*/
// @ApiOperation(value = "试用flux")
// @GetMapping("/flux")
public Response<String> flux(@RequestParam(value = "path", required = false) String path,
@RequestParam("type") int type,
@RequestParam(value = "prompt", required = false) String prompt){
CreditsEventsEnum typeEnum = CreditsEventsEnum.RELIGHT;
switch (type){
case 1:
typeEnum = CreditsEventsEnum.TO_PRODUCT_IMAGE;
break;
case 2:
typeEnum = CreditsEventsEnum.IMAGE_TO_SKETCH;
break;
case 3:
typeEnum = CreditsEventsEnum.PATTERN;
break;
}
return Response.success(generateService.flux(typeEnum, prompt, path, false));
}
// @ApiOperation(value = "获取flux结果")
// @GetMapping("/fluxResult")
public Response<String> fluxResult(@RequestParam("taskId") String taskId){
return Response.success(generateService.getFluxResult(taskId, "87/" + taskId + ".png"));
}
}
package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.model.dto.GenerateLikeDTO;
import com.ai.da.model.dto.GenerateModifyDTO;
import com.ai.da.model.dto.GenerateThroughImageTextDTO;
import com.ai.da.model.dto.ImageToSketchDTO;
import com.ai.da.model.vo.*;
import com.ai.da.service.GenerateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
* @author XP
*/
@Api(tags = "Generate模块")
@Slf4j
@RestController
@RequestMapping("/api/generate")
public class GenerateController {
@Resource
private GenerateService generateService;
/*@ApiOperation("自动识别sketch的caption 暂时未上")
@PostMapping("/caption")
public Response<GenerateCaptionVO> generateCaption(@RequestParam Long sketchElementId) {
return Response.success(generateService.generateCaption(sketchElementId));
}*/
/*@ApiOperation("通过文字、图片生成图片")
@PostMapping("/sketchAndPrint")
public void generateThroughImageText(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) {
// return Response.success(generateService.generateThroughImageText(generateThroughImageTextDTO));
generateService.generateThroughImageText(generateThroughImageTextDTO);
}*/
@ApiOperation("喜欢生成的图片")
@PostMapping("/like")
public Response<GenerateLikeVO> like(@Valid @RequestBody GenerateLikeDTO generateLikeDTO) {
return Response.success(generateService.generateLike(generateLikeDTO));
}
@ApiOperation(value = "取消喜欢")
@GetMapping("/dislike")
public Response<Boolean> dislike(@ApiParam("generateDetailId") @RequestParam Long generateDetailId,
@ApiParam("timeZone") @RequestParam String timeZone) {
return Response.success(generateService.generateDislike(generateDetailId, timeZone));
}
@ApiOperation(value = "发起生成请求,异步获取结果")
@PostMapping("/prepare")
public Response<PrepareForGenerateVO> prepareForGenerate(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) {
return Response.success(generateService.prepareForGenerate(generateThroughImageTextDTO));
}
@ApiOperation(value = "取消继续生成")
@GetMapping("/stopWaiting")
public Response<String> stopWaiting(@RequestParam("userId") Long userId,
@RequestParam("uniqueId") List<String> uniqueId,
@RequestParam("timeZone") String timeZone,
@RequestParam("type") String type) {
generateService.cancelGenerate(userId, uniqueId, timeZone, type);
return Response.success("stop waiting successfully");
}
/*@ApiOperation(value = "获取生成结果")
@GetMapping("/result")
public Response<GenerateCollectionVO> getGenerateResult(@RequestParam("uniqueId") String uniqueId) {
GenerateCollectionVO generateResult = generateService.getGenerateResult(uniqueId);
return Response.success(generateResult);
}*/
@ApiOperation(value = "获取生成结果")
@PostMapping("/result")
public Response<List<GenerateResultVO>> getGenerateResults(@Valid @RequestBody List<String> taskIdList) {
List<GenerateResultVO> generateResult = generateService.getGenerateResultList(taskIdList);
return Response.success(generateResult);
}
@ApiOperation(value = "imageToSketch")
@PostMapping("/imageToSketch")
public Response<GenerateResultVO> imageToSketch(@Valid @RequestBody ImageToSketchDTO imageToSketchDTO) {
return Response.success(generateService.imageToSketch(imageToSketchDTO));
}
// modifySketch
@ApiOperation(value = "modifySketch")
@PostMapping("/modifySketch")
public Response<GenerateResultVO> modifySketch(@Valid @RequestBody GenerateModifyDTO generateModifyDTO) {
return Response.success(generateService.modifySketch(generateModifyDTO));
}
}

View File

@@ -1,99 +0,0 @@
package com.ai.da.controller;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.AccountExtend;
import com.ai.da.mapper.primary.entity.ChatMessage;
import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.AccountLoginVO;
import com.ai.da.model.vo.AccountPreLoginVO;
import com.ai.da.model.vo.BindEmailVO;
import com.ai.da.model.vo.PersonalHomepageVO;
import com.ai.da.service.AccountService;
import com.ai.da.service.LLMService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Api(tags = "llm模块")
@Slf4j
@RestController
@RequestMapping("/api/llm")
public class LLMController {
@Resource
private LLMService llmService;
@ApiOperation(value = "对话")
@CrossOrigin
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamPrompt(@RequestParam String prompt,
@RequestParam(required = false) Long projectId,
@RequestParam(required = false) String fileUrl,
@RequestParam(required = false) List<String> imageUrlList,
@RequestParam(required = false) String process,
@RequestParam String token,
@RequestParam Boolean enableThinking) {
return llmService.stream(prompt, projectId, fileUrl, imageUrlList, token, enableThinking, process);
}
@ApiOperation(value = "对话")
@CrossOrigin
@GetMapping(value = "/streamNew", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamNew(@RequestParam String prompt,
@RequestParam(required = false) Long projectId,
@RequestParam(required = false) String fileUrl,
@RequestParam(required = false) List<String> imageUrlList,
@RequestParam(required = false) String process,
@RequestParam String token,
@RequestParam Boolean enableThinking) {
return llmService.streamNew(prompt, projectId, fileUrl, imageUrlList, token, enableThinking, process);
}
@ApiOperation(value = "对话创建项目")
@GetMapping(value = "/chatCreateProject")
public Response<Long> chatCreateProject(@RequestParam String prompt, @RequestParam String process,
@RequestParam(required = false) String fileUrl,
@RequestParam(required = false) List<String> imageUrlList) {
return Response.success(llmService.chatCreateProject(prompt, process, fileUrl, imageUrlList));
}
@ApiOperation(value = "上传文件")
@PostMapping(value = "/uploadFile")
public Response<List<String>> uploadFile(@RequestParam("file") MultipartFile file) {
return Response.success(llmService.uploadFile(file));
}
@ApiOperation(value = "获取历史聊天记录")
@PostMapping(value = "/getChatHistory")
public Response<PageBaseResponse<ChatMessage>> getChatHistory(@RequestBody ChatHistoryDTO chatHistoryDTO) {
return Response.success(llmService.getChatHistory(chatHistoryDTO));
}
}

View File

@@ -20,7 +20,6 @@ import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -28,7 +27,9 @@ import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.File;
import java.text.ParseException;
import java.util.*;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
@Api(tags = "library模块")
@@ -72,7 +73,6 @@ public class LibraryController {
@RequestParam(value = "timeZone") String timeZone,
@RequestParam(value = "modelType") String modelType,
@RequestParam(value = "sex") String sex,
@RequestParam(value = "ageGroup") String ageGroup,
@RequestParam(value = "checkMd5") Integer checkMd5) {
if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) {
throw new BusinessException("file.cannot.be.empty");
@@ -99,7 +99,7 @@ public class LibraryController {
}
}
return Response.success(libraryService.upload(new LibraryUploadDTO(file, level1Type, level2Type,
timeZone, md5, high, width, modelType, sex, ageGroup)));
timeZone, md5, high, width, modelType, sex)));
}
@ApiOperation(value = "保存或者编辑template打点")
@@ -169,7 +169,7 @@ public class LibraryController {
@ApiOperation(value = "更新sketchboard level2type")
@PostMapping("/updateLibraryLevel2Type")
public Response<Boolean> updateLibraryLevel2Type(@Validated @RequestBody LibraryLevel2TypeUpdateDTO libraryLevel2TypeUpdateDTO) {
public Response<Boolean> updateLibraryLevel2Type(@RequestBody LibraryLevel2TypeUpdateDTO libraryLevel2TypeUpdateDTO) {
return Response.success(libraryService.updateLibraryLevel2Type(libraryLevel2TypeUpdateDTO));
}
@@ -202,45 +202,4 @@ public class LibraryController {
return Response.success(true);
}
@ApiOperation(value = "将系统模特添加到个人library")
@GetMapping("addSysModelToLib")
public Response<Map<String, String>> addSysModelToLib(@ApiParam("系统模特id") @RequestParam("sysModelId")long sysModelId){
return Response.success(libraryService.addSysModelToLib(sysModelId));
}
@ApiOperation(value = "将个人library元素添加到公共库")
@GetMapping("addToPublicLibrary")
public Response<String> addToPublicLibrary(@ApiParam("元素的libraryId") @RequestParam("libraryId") Long libraryId){
boolean b = libraryService.saveToOrganizationLibrary(libraryId);
if (b){
return Response.success("success");
}else {
return Response.success("fail");
}
}
@ApiOperation(value = "将个人library元素从公共库中删除")
@GetMapping("deleteFromPublicLib")
public Response<String> deleteFromPublicLib(@ApiParam("元素的libraryId") @RequestParam("libraryId") Long libraryId){
libraryService.deleteFromPublicLib(libraryId);
return Response.success("success");
}
@ApiOperation(value = "获取公共库")
@GetMapping("getPublicLib")
public Response<PageBaseResponse<Library>> getPublicLib(@ApiParam("排序" ) @RequestParam(value = "order", defaultValue = "DESC", required = false) String order,
@ApiParam("page") @RequestParam(value = "page", defaultValue = "1", required = false) Long page,
@ApiParam("size") @RequestParam(value = "size", defaultValue = "20", required = false) Long size){
return Response.success(libraryService.getPublicLib(order, page, size));
}
@ApiOperation(value = "管理员获取所有子账号lib元素")
@GetMapping("getAllSubAccLib")
public Response<PageBaseResponse<Library>> getAllSubAccLib(@ApiParam("排序") @RequestParam(value = "order", defaultValue = "DESC", required = false) String order,
@ApiParam("page") @RequestParam(value = "page", defaultValue = "1", required = false) Long page,
@ApiParam("size") @RequestParam(value = "size", defaultValue = "20", required = false) Long size){
return Response.success(libraryService.getAllSubAccLib(order, page, size));
}
}

View File

@@ -31,7 +31,7 @@ public class PortfolioController {
@ApiOperation(value = "发布作品集")
@PostMapping("/publish")
public Response<Long> publish(@RequestParam("file") MultipartFile canvas, @RequestParam("data") String data) {
public Response<Long> preLogin(@RequestParam("file") MultipartFile canvas, @RequestParam("data") String data) {
return Response.success(portfolioService.publish(canvas, data));
}
@@ -57,7 +57,7 @@ public class PortfolioController {
@ApiOperation(value = "选择作品")
@PostMapping("/choose")
public Response<ProjectChooseVO> choose(@Valid @RequestBody PortfolioDTO portfolioDTO) {
public Response<UserLikeChooseVO> choose(@Valid @RequestBody PortfolioDTO portfolioDTO) {
return Response.success(portfolioService.choose(portfolioDTO));
}
@@ -154,11 +154,4 @@ public class PortfolioController {
@RequestParam(value = "tagId", required = false) Long tagId) {
return Response.success(portfolioService.queryPortfolioByTag(tagName, tagId));
}*/
@ApiOperation(value = "将企业或教育版中的作品发布到公共gallery")
@GetMapping("/toPublic")
public Response<String> setPortfolioToPublic(@RequestParam("portfolioId") Long portfolioId) {
portfolioService.setPortfolioToPublic(portfolioId);
return Response.success("success");
}
}

View File

@@ -1,153 +0,0 @@
package com.ai.da.controller;
import com.ai.da.common.config.MyTaskScheduler;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.ProjectService;
import com.ai.da.service.UserLikeGroupService;
import com.ai.da.service.WorkspaceService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.minio.errors.MinioException;
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.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
@Api(tags = "Project模块")
@Slf4j
@RestController
@RequestMapping("/api/project")
public class ProjectController {
@Resource
private WorkspaceService workspaceService;
@Resource
private UserLikeGroupService userLikeGroupService;
@Resource
private ProjectService projectService;
@PostMapping("/saveOrUpdate")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "新增或编辑", notes = "传入project")
public Response<SaveOrUpdateProjectVO> saveOrUpdateProject(@Valid @RequestBody ProjectDTO projectDTO) {
return Response.success(workspaceService.saveOrUpdateProject(projectDTO));
}
@PostMapping("/page")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "分页查询", notes = "传入project")
public Response<PageBaseResponse<ProjectVO>> page(@Valid @RequestBody ProjectQueryDTO projectQueryDTO) {
return Response.success(PageBaseResponse.success(userLikeGroupService.getPage(projectQueryDTO)));
}
// @PostMapping("/detail")
// @ApiOperationSupport(order = 3)
// @ApiOperation(value = "详情", notes = "传入project")
// public Response saveOrUpdateProject(@Valid @RequestBody ProjectDTO projectDTO) {
// return Response.success(workspaceService.saveOrUpdateProject(projectDTO));
// }
//
@PostMapping("/choose")
@ApiOperationSupport(order = 4)
@ApiOperation(value = "选择", notes = "传入project")
public Response<ProjectChooseVO> choose(@Valid @RequestBody ProjectDTO projectDTO) {
return Response.success(userLikeGroupService.choose(projectDTO));
}
@PostMapping("/getModuleContent")
@ApiOperationSupport(order = 5)
@ApiOperation(value = "获取模块内容", notes = "传入project")
public Response<ModuleChooseVO> getModuleContent(@Valid @RequestBody ProjectDTO projectDTO) {
return Response.success(userLikeGroupService.getModuleContent(projectDTO));
}
@PostMapping("/saveModuleContent")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "存储模块内容", notes = "传入project")
public Response<ModuleChooseVO> saveModuleContent(@Valid @RequestBody ModuleSaveDTO moduleSaveDTO) {
return Response.success(userLikeGroupService.saveModuleContent(moduleSaveDTO));
}
//
// @PostMapping("/delete")
// @ApiOperationSupport(order = 5)
// @ApiOperation(value = "删除", notes = "传入project")
// public Response saveOrUpdateProject(@Valid @RequestBody ProjectDTO projectDTO) {
// return Response.success(workspaceService.saveOrUpdateProject(projectDTO));
// }
@PostMapping("/getMannequinDetail")
@ApiOperationSupport(order = 7)
@ApiOperation(value = "获取模特详情", notes = "传入mannequinId")
public Response<QueryLibraryPageVO> getMannequinDetail(@Valid @RequestBody MannequinDTO mannequinDTO) {
return Response.success(userLikeGroupService.getMannequinDetail(mannequinDTO));
}
@PostMapping("/threeDPage")
@ApiOperationSupport(order = 8)
@ApiOperation(value = "获取3Dpage", notes = "传入ThreeDLayoutQueryDTO")
public Response<PageBaseResponse<ThreeDLayoutVO>> threeDPage(@Valid @RequestBody ThreeDLayoutQueryDTO threeDLayoutQueryDTO) {
return Response.success(PageBaseResponse.success(userLikeGroupService.getThreeDLayoutPage(threeDLayoutQueryDTO)));
}
@PostMapping("/getLayoutDetail")
@ApiOperationSupport(order = 9)
@ApiOperation(value = "获取3D详情", notes = "传入project")
public Response<ThreeDVO> getLayoutDetail(@RequestParam(value = "threeDSimpleId") Long threeDSimpleId) {
return Response.success(userLikeGroupService.getLayoutDetail(threeDSimpleId));
}
@PostMapping("/getThreeDSize")
@ApiOperationSupport(order = 10)
@ApiOperation(value = "获取尺码", notes = "传入project")
public Response<ThreeDSizeVO> getThreeDSize(@RequestParam(value = "threeDSimpleId") Long threeDSimpleId) {
return Response.success(userLikeGroupService.getThreeDSize(threeDSimpleId));
}
@GetMapping("/getThreeDGlb")
@ApiOperationSupport(order = 11)
@ApiOperation(value = "获取GLB", notes = "传入project")
public void getThreeDGlb(@RequestParam(value = "threeDSimpleId") Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException {
userLikeGroupService.getThreeDGlb(threeDSimpleId, response);
}
@GetMapping("/downloadZip")
@ApiOperationSupport(order = 11)
@ApiOperation(value = "下载", notes = "传入project")
public Response<String> downloadZip(@RequestParam(value = "threeDSimpleId") Long threeDSimpleId, @RequestParam(value = "sizeType") String sizeType, @RequestParam(value = "size") String size, HttpServletResponse response) throws MinioException, IOException {
return Response.success(userLikeGroupService.downloadZip(threeDSimpleId, sizeType, size, response));
}
@PostMapping("/delete")
@ApiOperationSupport(order = 12)
@ApiOperation(value = "删除", notes = "传入project")
public Response<Boolean> delete(@RequestParam("projectId") Long projectId) {
return Response.success(userLikeGroupService.delete(projectId));
}
/*@Resource
private MyTaskScheduler myTaskScheduler;
@GetMapping("/dataMigration")
public String dataMigration(){
myTaskScheduler.projectDataCreate();
return "success";
}*/
@GetMapping("/getNextSequence")
public Response<Integer> getNextSequence(){
return Response.success(projectService.getOrCreateSequence());
}
}

View File

@@ -23,14 +23,11 @@ import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@@ -38,7 +35,6 @@ import java.util.stream.Collectors;
@Api(tags = "History模块(saved Collection)")
@Slf4j
@RestController
@Validated
@RequestMapping("/api/history")
public class SavedCollectionController {
@Resource
@@ -178,46 +174,32 @@ public class SavedCollectionController {
@ApiOperation(value = "exportSave")
@PostMapping("/exportSave")
public Response<Long> exportSave(@RequestParam("file") MultipartFile file, @RequestParam(value = "projectId", required = false) Long projectId,
@RequestParam("module") String module, @RequestParam(value = "designItemDetailId", required = false) Long designItemDetailId) {
return Response.success(userLikeGroupService.exportSave(file, projectId, module, designItemDetailId));
public Response<Boolean> exportSave(@RequestParam("file") MultipartFile file, @RequestParam("userLikeGroupId") Long userLikeGroupId) {
return Response.success(userLikeGroupService.exportSave(file, userLikeGroupId));
}
@ApiOperation(value = "exportSearch")
@PostMapping("/exportSearch")
public Response<JSONObject> exportSearch(@Valid @RequestBody ExportSearchDTO exportSearchDTO) {
return Response.success(userLikeGroupService.exportSearch(exportSearchDTO));
return Response.success(userLikeGroupService.exportSearch(exportSearchDTO.getUserLikeGroupId()));
}
@ApiOperation(value = "toProduct")
@PostMapping("/toProduct")
public Response<List<ToProductImageResultVO>> toProduct(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
public Response<List<ToProductImageResult>> toProduct(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
return Response.success(userLikeGroupService.toProduct(toProductImageDTO));
}
@ApiOperation(value = "toProductImageElementUpload")
@PostMapping("/toProductImageElementUpload")
public Response<ToProductElementVO> toProductImageElementUpload(@RequestParam("file") MultipartFile file, @RequestParam(value = "projectId", required = false) Long projectId) {
return Response.success(userLikeGroupService.toProductImageElementUpload(file, projectId));
}
@ApiOperation(value = "toProductImageElementDelete")
@PostMapping("/toProductImageElementDelete")
public Response<Boolean> toProductImageElementDelete(@RequestParam(value = "id") Long id) {
return Response.success(userLikeGroupService.toProductImageElementDelete(id));
public Response<ToProductElementVO> toProductImageElementUpload(@RequestParam("file") MultipartFile file, @RequestParam(value = "userlikeGroupId") Long userLikeGroupId) {
return Response.success(userLikeGroupService.toProductImageElementUpload(file, userLikeGroupId));
}
@ApiOperation(value = "productImageLike")
@PostMapping("/productImageLike")
public Response<CollectionSort> productImageLike(@Valid @RequestBody ProductImageLikeDTO productImageLikeDTO) {
CollectionSort collectionSort = userLikeGroupService.productImageLike(productImageLikeDTO);
return Response.success(collectionSort);
}
@ApiOperation(value = "collectionLikeUpdate")
@PostMapping("/collectionLikeUpdate")
public Response<Boolean> collectionLikeUpdate(@Valid @RequestBody CollectionLikeUpdateDTO collectionLikeUpdateDTO) {
return Response.success(userLikeGroupService.collectionLikeUpdate(collectionLikeUpdateDTO));
public Response<Boolean> productImageLike(@Valid @RequestBody ProductImageLikeDTO productImageLikeDTO) {
return Response.success(userLikeGroupService.productImageLike(productImageLikeDTO));
}
@ApiOperation(value = "productImageUnLike")
@@ -247,16 +229,10 @@ public class SavedCollectionController {
@ApiOperation(value = "relight")
@PostMapping("/relight")
public Response<List<ToProductImageResultVO>> relight(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
public Response<List<ToProductImageResult>> relight(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
return Response.success(userLikeGroupService.relight(toProductImageDTO));
}
@ApiOperation(value = "转relight元素")
@PostMapping("/convertRelightElement")
public Response<ToProductElementVO> convertRelightElement(@RequestParam("id") Long id) {
return Response.success(userLikeGroupService.convertRelightElement(id));
}
@ApiOperation(value = "获取relight结果")
@PostMapping("/relightResult")
public Response<List<MagicToolResultVO>> getRelightResult(@Valid @RequestBody List<String> taskIdList) {
@@ -264,19 +240,6 @@ public class SavedCollectionController {
return Response.success(magicToolResultVOList);
}
@ApiOperation(value = "删除toProduct Relight的结果")
@GetMapping("/deleteResult")
public Response<String> deleteResult(@RequestParam("id") Long id,
@RequestParam("projectId") Long projectId,
@RequestParam("type") @Pattern(regexp = "^(Relight|ToProductImage)$", message = "Please choose type from 'Relight|ToProductImage'") String type){
try{
userLikeGroupService.deleteToProductRelightResult(id, projectId, type);
return Response.success();
}catch (Exception e){
return Response.fail(e.getMessage());
}
}
@ApiOperation(value = "likeHistoryRelSketch")
@PostMapping("/likeHistoryRelSketch")
public Response<String> likeHistoryRelSketch() {
@@ -294,46 +257,4 @@ public class SavedCollectionController {
public Response<Boolean> productImageUpload(@Valid @RequestBody ProductImageInitializeDTO productImageInitializeDTO) {
return Response.success(userLikeGroupService.productImageInitialize(productImageInitializeDTO));
}
@ApiOperation(value = "getInitializeProgress")
@PostMapping("/getInitializeProgress")
public Response<InitializeProgressVO> getInitializeProgress(@Valid @RequestBody ProductImageInitializeDTO productImageInitializeDTO) {
return Response.success(userLikeGroupService.getInitializeProgress(productImageInitializeDTO));
}
@ApiOperation(value = "brandDNASaveOrUpdate")
@PostMapping("/brandDNASaveOrUpdate")
public Response<Boolean> brandDNASaveOrUpdate(@Valid @RequestBody BrandDNADTO brandDNADTO) {
return Response.success(userLikeGroupService.brandDNASaveOrUpdate(brandDNADTO));
}
@ApiOperation(value = "brandDNADelete")
@PostMapping("/brandDNADelete")
public Response<Boolean> brandDNADelete(@Valid @RequestBody BrandDNADTO brandDNADTO) {
return Response.success(userLikeGroupService.brandDNADelete(brandDNADTO));
}
@ApiOperation(value = "brandDNAPage")
@PostMapping("/brandDNAPage")
public Response<PageBaseResponse<BrandDNAVO>> brandDNAPage(@Valid @RequestBody BrandDNAQueryDTO brandDNAQueryDTO) {
return Response.success(userLikeGroupService.brandDNAPage(brandDNAQueryDTO));
}
@ApiOperation(value = "brandLogoUpload")
@PostMapping("/brandLogoUpload")
public Response<BrandLogoUploadVO> brandDNASaveOrUpdate(@RequestParam("file") MultipartFile file) {
return Response.success(userLikeGroupService.brandLogoUpload(file));
}
@ApiOperation(value = "brandDNAUpload")
@PostMapping("/brandDNAUpload")
public Response<LibraryUpdateVo> brandDNAUpload(@RequestParam("file") MultipartFile file, @RequestParam("brandId") Long brandId) throws IOException {
return Response.success(userLikeGroupService.brandDNAUpload(file, brandId));
}
@ApiOperation(value = "brandDNAGenerate")
@PostMapping("/brandDNAGenerate")
public Response<BrandDNAGenerateVO> brandDNAGenerate(@RequestParam("prompt") String prompt) {
return Response.success(userLikeGroupService.brandDNAGenerate(prompt));
}
}

View File

@@ -137,9 +137,11 @@ public class StripeController {
@ApiOperation("更新推广码信息")
@GetMapping("/updatePromCodeInfo")
public Response<ProductCoupons> updateCouponsInfo(@RequestParam Long id, @RequestParam(required = false) Long paidCommission,
@RequestParam(required = false) String cooperator, @RequestParam(required = false) String remark){
return Response.success(stripeService.updateCouponsInfo(id, paidCommission, cooperator, remark));
public Response<ProductCoupons> updateCouponsInfo(@RequestParam Long id, @RequestParam(required = false) String paidCommission,
@RequestParam(required = false) String cooperator,
@RequestParam(required = false) String remark,
@RequestParam(required = false) Long startTime){
return Response.success(stripeService.updateCouponsInfo(id, paidCommission, cooperator, remark, startTime));
}
@ApiOperation("删除推广码")

View File

@@ -1,8 +1,6 @@
package com.ai.da.controller;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.MinioUtil;
import com.ai.da.mapper.primary.entity.GoogleUser;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.AccountLoginVO;
@@ -37,9 +35,6 @@ public class ThirdPartyController {
@Resource
private DesignService designService;
@Resource
private MinioUtil minioUtil;
/*@ApiOperation(value = "Add user information")
@PostMapping("/addUser")
public Response<Boolean> addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) {
@@ -151,17 +146,4 @@ public class ThirdPartyController {
public Response<Boolean> receiveDesignResults(@Valid @RequestBody JSONObject responseObject) {
return Response.success(designService.receiveDesignResults(responseObject));
}
@ApiOperation(value = "接收Design入参")
@PostMapping("/receiveDesignParams")
@CrossOrigin
public Response<Boolean> receiveDesignParams(@Valid @RequestBody ReceiveDesignParam receiveDesignParam) {
return Response.success(designService.receiveDesignParams(receiveDesignParam));
}
@ApiOperation(value = "刷新minio预签名地址")
@GetMapping("/refreshMinioUrl")
public Response<String> refreshMinioUrl(@RequestParam("path") String path){
return Response.success(minioUtil.getPreSignedUrl(path, CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
}
}

View File

@@ -3,7 +3,6 @@ package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.entity.Style;
import com.ai.da.mapper.primary.entity.Workspace;
import com.ai.da.model.dto.ProjectDTO;
import com.ai.da.model.dto.WorkspaceDTO;
import com.ai.da.model.dto.WorkspaceSaveDTO;
import com.ai.da.model.enums.BizJson;
@@ -96,8 +95,8 @@ public class WorkspaceController {
@GetMapping("/getMannequins")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "获取模特")
public Response<List<ModelsVO>> getMannequins(@RequestParam("sex") String sex, @RequestParam("style") String style, @RequestParam("ageGroup") String ageGroup) {
List<ModelsVO> modelsVO = workspaceService.getMannequins(sex, style, ageGroup);
public Response<List<ModelsVO>> getMannequins(@RequestParam("sex") String sex, @RequestParam("style") String style) {
List<ModelsVO> modelsVO = workspaceService.getMannequins(sex, style);
return Response.success(modelsVO);
}
@@ -132,11 +131,4 @@ public class WorkspaceController {
public Response<List<StyleVO>> styleList() {
return Response.success(workspaceService.styleList());
}
@PostMapping("/saveOrUpdateProject")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "新增或编辑", notes = "传入project")
public Response saveOrUpdateProject(@Valid @RequestBody ProjectDTO projectDTO) {
return Response.success(workspaceService.saveOrUpdateProject(projectDTO));
}
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.APIGenerate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface APIGenerateMapper extends BaseMapper<APIGenerate> {
}

View File

@@ -2,8 +2,8 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.model.dto.AccountCreditsUsageDTO;
import java.util.Date;
import java.util.List;
/**
@@ -32,10 +32,4 @@ public interface AccountMapper extends CommonMapper<Account> {
void toVisitor(Long id);
List<AccountCreditsUsageDTO> selectCreditUsage(boolean groupByEvent, String changeEvent, String role,
String userEmail, Long id, String startTime, String endTime,
Integer size, Integer offset, String organizationName);
int countCreditUsage(boolean groupByEvent, String changeEvent, String role, String userEmail, Long id, String startTime, String endTime, String organizationName);
}

View File

@@ -0,0 +1,14 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.AffiliateIncome;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import java.util.Map;
public interface AffiliateIncomeMapper extends BaseMapper<AffiliateIncome> {
List<Map<String, Object>> getPersonalMonthlyIncome(Long affiliateAccountId, int year);
List<Map<String, Object>> getMonthlyAffiliateIncome(int year, int month);
}

View File

@@ -12,10 +12,8 @@ public interface AffiliateMapper extends BaseMapper<Affiliate> {
Map<String, Long> getMonthlyApprovedAffiliate(int year, int month);
List<AffiliateVO> getAffiliateList(String status, String startTime, String endTime,
String order, Long affiliateId, String sortField, int size, int offset);
String order, Long affiliateId, int size, int offset);
int queryAffiliateTotalCount(String status, String startTime, String endTime, Long affiliateId);
List<Map<String, Object>> selectAllAffiliateUsername();
}

View File

@@ -1,16 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.BatchTaskSequence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
public interface BatchTaskSequenceMapper extends BaseMapper<BatchTaskSequence> {
@Update("UPDATE t_batch_task_sequence SET current_sequence = LAST_INSERT_ID(current_sequence + 1) WHERE account_id = #{userId}")
int incrementSequence(@Param("userId") Long userId);
@Select("SELECT LAST_INSERT_ID()")
Integer getLastInsertId();
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.BrandDNA;
public interface BrandDNAMapper extends CommonMapper<BrandDNA> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.BrandRelLibrary;
public interface BrandRelLibraryMapper extends CommonMapper<BrandRelLibrary> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ChatMessage;
public interface ChatMessageMapper extends CommonMapper<ChatMessage> {
}

View File

@@ -1,16 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.CloudTask;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
public interface CloudTaskMapper extends CommonMapper<CloudTask> {
@Update("UPDATE cloud_task SET completed_num = completed_num + 1, update_time = NOW() WHERE task_id = #{taskIdBatch}")
@Options(useGeneratedKeys = false, flushCache = Options.FlushCachePolicy.TRUE)
void increaseCompletedNum(@Param("taskIdBatch") String taskIdBatch);
@Select("SELECT * FROM cloud_task WHERE task_id = #{taskId} FOR UPDATE")
CloudTask selectForUpdate(String taskId);
}

View File

@@ -2,9 +2,6 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.CollectionElement;
import com.ai.da.mapper.primary.entity.CollectionElementRelModel;
import java.util.List;
/**
* Mapper 接口
@@ -14,7 +11,4 @@ import java.util.List;
*/
public interface CollectionElementMapper extends CommonMapper<CollectionElement> {
List<CollectionElement> selectDeleteList();
List<CollectionElementRelModel> selectByProject(Long projectId);
}

View File

@@ -1,10 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.CollectionElementRelModel;
import java.util.Set;
public interface CollectionElementRelModelMapper extends CommonMapper<CollectionElementRelModel> {
}

View File

@@ -3,8 +3,6 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.Collection;
import java.util.List;
/**
* Mapper 接口
*
@@ -14,6 +12,4 @@ import java.util.List;
public interface CollectionMapper extends CommonMapper<Collection> {
//返回插入数据后生成的主键
Long insertCollection(Collection collection);
List<Collection> selectDeleteList();
}

View File

@@ -1,18 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.CollectionSort;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
public interface CollectionSortMapper extends CommonMapper<CollectionSort> {
@Update("UPDATE collection_sort SET sort = sort + 1 " +
"WHERE parent_id = #{parentId} " +
"AND relation_type != 'Design' " +
"AND sort > #{originalSort}")
void increaseGenerateSortAbove(
@Param("parentId") Long parentId,
@Param("relationType") String relationType,
@Param("originalSort") int originalSort
);
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.DesignItemDetailCanvas;
public interface DesignItemDetailCanvasMapper extends CommonMapper<DesignItemDetailCanvas> {
}

View File

@@ -3,8 +3,6 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.DesignItem;
import java.util.List;
/**
* Mapper 接口
*
@@ -14,6 +12,4 @@ import java.util.List;
public interface DesignItemMapper extends CommonMapper<DesignItem> {
Long insertDesignItem(DesignItem designItem);
List<DesignItem> selectDeleteList();
}

View File

@@ -18,8 +18,5 @@ public interface DesignMapper extends CommonMapper<Design> {
//返回插入数据后生成的主键
Long insertDesign(Design design);
List<UserDesignStatisticDTO> getDesignStatistic(String startTime, String endTime, List<Long> ids, String email,
String role, String organizationName);
List<Design> selectDeleteList();
List<UserDesignStatisticDTO> getDesignStatistic(String startTime, String endTime, List<Long> ids, String email);
}

View File

@@ -1,8 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.EducationLibrary;
public interface EductionLibraryMapper extends CommonMapper<EducationLibrary> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.EmailLog;
public interface EmailLogMapper extends CommonMapper<EmailLog> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.EmailTemplate;
public interface EmailTemplateMapper extends CommonMapper<EmailTemplate> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.EnterpriseLibrary;
public interface EnterpriseLibraryMapper extends CommonMapper<EnterpriseLibrary> {
}

View File

@@ -3,8 +3,6 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.Library;
import java.util.List;
/**
* Mapper 接口
*
@@ -13,11 +11,4 @@ import java.util.List;
*/
public interface LibraryMapper extends CommonMapper<Library> {
List<Library> selectCommonLib(Long organizationId, String sort, long limit, long offset);
Long selectCommonLibCount(Long organizationId);
List<Library> selectAllSubAccLib(Long organizationId, String sort, long limit, long offset);
Long selectAllSubAccLibCount(Long organizationId);
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.Organization;
public interface OrganizationMapper extends CommonMapper<Organization> {
}

View File

@@ -6,6 +6,7 @@ import com.ai.da.model.vo.PaymentInfoVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@@ -24,6 +25,10 @@ public interface PaymentInfoMapper extends BaseMapper<PaymentInfo> {
String country, String city, String startTime, String endTime, String payer
);
BigDecimal queryTotalPaymentAmount(String paymentType,String payerTotal, String type, String status,
String country, String city, String startTime, String endTime, String payer
);
List<Map<String, String>> getCities();
List<Map<String, String>> getCountries();

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.PoseTransformation;
public interface PoseTransformationMapper extends CommonMapper<PoseTransformation> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.Project;
public interface ProjectMapper extends CommonMapper<Project> {
}

View File

@@ -1,32 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.Referral;
import com.ai.da.model.vo.ReferralPageQueryVO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
public interface ReferralMapper extends BaseMapper<Referral> {
// 使用自定义SQL进行分页查询
IPage<ReferralPageQueryVO> selectReferralWithAffiliate(Page<ReferralPageQueryVO> page, @Param("ew") Wrapper<ReferralPageQueryVO> wrapper);
void batchDeleteByIds(List<Long> ids);
BigDecimal sumAmount(
Long affiliateId,
List<String> statusList, // 改为 List 类型
LocalDateTime startTime, // 开始时间(可选)
LocalDateTime endTime // 结束时间(可选)
);
List<Map<String, Object>> getPersonalMonthlyIncome(Long affiliateAccountId, int year);
List<Map<String, Object>> getMonthlyAffiliateIncome(int year, int month);
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.SketchData;
public interface SketchDataMapper extends CommonMapper<SketchData> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.SketchReconstruction;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SketchReconstructionMapper extends BaseMapper<SketchReconstruction> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.SysFileExtra;
public interface SysFileExtraMapper extends CommonMapper<SysFileExtra> {
}

View File

@@ -29,5 +29,4 @@ public interface TDesignPythonOutfitDetailMapper extends CommonMapper<TDesignPyt
@Delete("DELETE FROM t_design_python_outfit_detail WHERE design_python_outfit_id = #{designPythonOutfitId}")
void deleteByDesignPythonOutfitIdPhysical(@Param("designPythonOutfitId") Long designPythonOutfitId);
List<TDesignPythonOutfitDetail> selectListDelete();
}

View File

@@ -25,5 +25,4 @@ public interface TDesignPythonOutfitMapper extends CommonMapper<TDesignPythonOut
*/
List<TDesignPythonOutfitVO> selectTDesignPythonOutfitPage(IPage page, TDesignPythonOutfitVO tDesignPythonOutfit);
List<TDesignPythonOutfit> selectListDelete();
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ThreeDDetail;
public interface ThreeDDetailMapper extends CommonMapper<ThreeDDetail> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ThreeDLayout;
public interface ThreeDLayoutMapper extends CommonMapper<ThreeDLayout> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ThreeDModule;
public interface ThreeDModuleMapper extends CommonMapper<ThreeDModule> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ThreeDPatternLayout;
public interface ThreeDPatternLayoutMapper extends CommonMapper<ThreeDPatternLayout> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ThreeDSimple;
public interface ThreeDSimpleMapper extends CommonMapper<ThreeDSimple> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserBehavior;
public interface UserBehaviorMapper extends CommonMapper<UserBehavior> {
}

View File

@@ -3,8 +3,6 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserLikeGroup;
import java.util.List;
/**
* Mapper 接口
*
@@ -14,6 +12,4 @@ import java.util.List;
public interface UserLikeGroupMapper extends CommonMapper<UserLikeGroup> {
//返回插入数据后生成的主键
Long insertUserLikeGroup(UserLikeGroup userLikeGroup);
List<UserLikeGroup> getMoreThan50UserLikeAccount();
}

View File

@@ -0,0 +1,7 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserLikeSort;
public interface UserLikeSortMapper extends CommonMapper<UserLikeSort> {
}

View File

@@ -1,7 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserPreferenceLogTest;
public interface UserPreferenceLogMapper extends CommonMapper<UserPreferenceLogTest> {
}

View File

@@ -1,8 +0,0 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserPreferenceLogPrediction;
import com.ai.da.mapper.primary.entity.UserPreferenceLogTest;
public interface UserPreferenceLogPredictionMapper extends CommonMapper<UserPreferenceLogPrediction> {
}

View File

@@ -1,27 +0,0 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("t_api_generate")
@ApiModel("调用第三方api的所有记录")
public class APIGenerate extends BaseEntity{
// 用户id
private Long accountId;
// 任务id 加唯一索引
private String taskId;
// 什么功能调用的api
private String func;
// 第三方api的服务商 目前只有ali-万相 和 flux
// private String service;
// 模型名
private String modelName;
// 任务状态
private String status;
// 获取结果的重试次数
private int retry_count;
}

View File

@@ -117,16 +117,11 @@ public class Account implements Serializable {
private String organizationName;
private Long organizationId;
private Long parentId;
private Integer isAdmin;
private BigDecimal creditsUsageLimit;
// 学校分配的积分使用情况
private BigDecimal creditsUsage = BigDecimal.ZERO;
private BigDecimal shareCredits;
private Integer subAccountNum;

View File

@@ -50,12 +50,4 @@ public class AccountLoginLog implements Serializable {
*/
private Date createDate;
public AccountLoginLog() {
}
public AccountLoginLog(Long accountId, String ip, Date createDate) {
this.accountId = accountId;
this.ip = ip;
this.createDate = createDate;
}
}

View File

@@ -22,8 +22,7 @@ public class Affiliate extends BaseEntity{
private Float unpaidEarnings = 0.00F;
// 邀请链接的访问人数每分钟从redis同步到数据库
private Long visits = 0L;
private Integer visits = 0;
private Boolean approved = false;

View File

@@ -1,18 +0,0 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@TableName("t_batch_task_sequence")
@Data
public class BatchTaskSequence extends BaseEntity{
private Long accountId;
private Integer nextSeq;
private Integer lockedSeq;
}

View File

@@ -1,37 +0,0 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("brand")
public class BrandDNA implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long accountId;
private String brandName;
private String brandSlogan;
private String brandLogo;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@@ -1,29 +0,0 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("brand_rel_library")
public class BrandRelLibrary implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long brandId;
private Long libraryId;
}

View File

@@ -1,61 +0,0 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("chat_message")
public class ChatMessage implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("项目ID")
private Long projectId;
@ApiModelProperty("角色system/user")
private String role;
@ApiModelProperty("排序")
private Integer seq;
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("用户ID")
private Long accountId;
@ApiModelProperty("0对话内容1颜色2图片")
private Integer isImage;
/**
* 输入
*/
private Long inputTokens;
/**
* 输出
*/
private Long outputTokens;
/**
* 思考
*/
private Long reasoningTokens;
/**
* 本次输出消耗的总金额
*/
private String totalCost;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@@ -1,70 +0,0 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.apache.poi.hpsf.Decimal;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("cloud_task")
public class CloudTask implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("任务名")
private String name;
@ApiModelProperty("项目ID")
private Long projectId;
@ApiModelProperty("collectionId")
private Long collectionId;
@ApiModelProperty("designId")
private Long designId;
@ApiModelProperty("任务类型")
private String buildType;
@ApiModelProperty("生成数量")
private Integer nums;
@ApiModelProperty("完成数量")
private Integer completedNum;
@ApiModelProperty("消耗积分")
private Integer costCredits;
@ApiModelProperty("状态1完成0未完成")
private Integer status;
@ApiModelProperty("批处理ID")
private String taskId;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("任务开始时间")
private LocalDateTime startTime;
@ApiModelProperty("任务更新时间")
private LocalDateTime updateTime;
@ApiModelProperty("用户ID")
private Long accountId;
@ApiModelProperty("任务序号")
private Long sequence;
}

View File

@@ -86,23 +86,4 @@ public class CollectionElement implements Serializable {
* 更新时间
*/
private Date updateDate;
private Long projectId;
private Integer isCompositeImage;
public CollectionElement() {
}
public CollectionElement(Long accountId, String level1Type, String level2Type, String name, String url, Byte hasPin, String md5, Date createDate, Long projectId) {
this.accountId = accountId;
this.level1Type = level1Type;
this.level2Type = level2Type;
this.name = name;
this.url = url;
this.hasPin = hasPin;
this.md5 = md5;
this.createDate = createDate;
this.projectId = projectId;
}
}

Some files were not shown because too many files have changed in this diff Show More