Compare commits
7 Commits
716d720782
...
dev/dev_xp
| Author | SHA1 | Date | |
|---|---|---|---|
| 55978ca410 | |||
| 60027ab17f | |||
| eba6fb512f | |||
| ca6d2dcb87 | |||
| 26d2d95acc | |||
| 379392c38d | |||
| 4757149214 |
@@ -64,7 +64,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
|||||||
"/api/global-award/uploads/pdf/init", "/api/global-award/uploads/pdf/chunk", "/api/global-award/uploads/pdf/complete", "/api/global-award/uploads/pdf/status",
|
"/api/global-award/uploads/pdf/init", "/api/global-award/uploads/pdf/chunk", "/api/global-award/uploads/pdf/complete", "/api/global-award/uploads/pdf/status",
|
||||||
"/api/global-award/uploads/video/init", "/api/global-award/uploads/video/chunk", "/api/global-award/uploads/video/complete", "/api/global-award/uploads/video/status",
|
"/api/global-award/uploads/video/init", "/api/global-award/uploads/video/chunk", "/api/global-award/uploads/video/complete", "/api/global-award/uploads/video/status",
|
||||||
"/api/global-award/contestants/save", "/api/global-award/contestants/by-email", "/api/global-award/checkEmail", "/api/global-award/checkCode","/api/global-award/contestants/export",
|
"/api/global-award/contestants/save", "/api/global-award/contestants/by-email", "/api/global-award/checkEmail", "/api/global-award/checkCode","/api/global-award/contestants/export",
|
||||||
"/api/global-award/contestants/export/files", "/api/global-award/contestants/count"
|
"/api/global-award/contestants/export/files"
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1030,15 +1030,25 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
private final static Long CN_2025_618 = 141425L;
|
private final static Long CN_2025_618 = 141425L;
|
||||||
private final static Long EN_2025_618 = 141424L;
|
private final static Long EN_2025_618 = 141424L;
|
||||||
|
|
||||||
|
private final static Long CN_GLOBAL_AWARDS = 166716L;
|
||||||
|
private final static Long EN_GLOBAL_AWARDS = 166715L;
|
||||||
|
private final static Long GLOBAL_AWARDS_2 = 173919L;
|
||||||
|
|
||||||
|
// 复用 SesClient,避免每次发送都创建新连接
|
||||||
|
private static SesClient getSesClient() {
|
||||||
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
return new SesClient(cred, "ap-hongkong", clientProfile);
|
||||||
|
}
|
||||||
|
|
||||||
public static void send618PromotionEmailTemp(String receiver, String language){
|
public static void send618PromotionEmailTemp(String receiver, String language){
|
||||||
|
SesClient client = null;
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
client = getSesClient();
|
||||||
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();
|
SendEmailRequest req = new SendEmailRequest();
|
||||||
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
|
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
|
||||||
req.setDestination(new String[]{receiver});
|
req.setDestination(new String[]{receiver});
|
||||||
@@ -1046,20 +1056,15 @@ public class SendEmailUtil {
|
|||||||
// 根据邮件类型设置不同的主题和模板
|
// 根据邮件类型设置不同的主题和模板
|
||||||
String subject = "";
|
String subject = "";
|
||||||
Template template = new Template();
|
Template template = new Template();
|
||||||
// if (type == 1) {
|
subject = "AiDA Global Design Awards 2026 | The Journey Starts Now ! \nAiDA 全球设计大奖 2026 | 从现在开始你的创作之旅 !";
|
||||||
// subject = "Upcoming System Upgrade for AiDA 3.0";
|
template.setTemplateID(GLOBAL_AWARDS_2);
|
||||||
// template.setTemplateID(UPGRADE_NOTIFICATION_ID);
|
/*if (language.equals("ENGLISH")) {
|
||||||
// }else {
|
subject = "From Idea to Wow. \uD83D\uDD25 | AiDA Demo & Global Awards";
|
||||||
// subject = "即将到来的AiDA 3.0系统升级";
|
template.setTemplateID(EN_GLOBAL_AWARDS);
|
||||||
// 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 {
|
}else {
|
||||||
subject = "设计时速狂飙!AiDA 618半价让灵感永不限流!";
|
subject = "灵感开挂,创作起飞 \uD83D\uDD25 | AiDA Demo & 全球设计大奖";
|
||||||
template.setTemplateID(CN_2025_618);
|
template.setTemplateID(CN_GLOBAL_AWARDS);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
req.setSubject(subject);
|
req.setSubject(subject);
|
||||||
req.setTemplate(template);
|
req.setTemplate(template);
|
||||||
@@ -1069,9 +1074,7 @@ public class SendEmailUtil {
|
|||||||
log.info("邮件发送成功,收件人地址:{}", receiver);
|
log.info("邮件发送成功,收件人地址:{}", receiver);
|
||||||
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
||||||
} catch (TencentCloudSDKException e) {
|
} catch (TencentCloudSDKException e) {
|
||||||
log.info(receiver);
|
log.error("邮件发送失败,收件人地址:{},错误信息:{}", receiver, e.toString());
|
||||||
log.error("邮件发送失败###{},收件人地址:{}", e.toString(), receiver);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,72 +20,92 @@ public class SendRequestUtil {
|
|||||||
@Value("${FREEPIK_API_KEY}")
|
@Value("${FREEPIK_API_KEY}")
|
||||||
private String FREEPIK_API_KEY;
|
private String FREEPIK_API_KEY;
|
||||||
|
|
||||||
public String sendAliYunPostAsync(String apiUrl, String requestBody){
|
public String sendAliYunPostAsync(String apiUrl, String requestBody) {
|
||||||
// 发送POST请求 todo 异常处理
|
// 发送POST请求
|
||||||
HttpResponse execute = HttpRequest.post(apiUrl)
|
try (HttpResponse execute = HttpRequest.post(apiUrl)
|
||||||
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
|
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
|
||||||
.header("X-DashScope-Async", "enable")
|
.header("X-DashScope-Async", "enable")
|
||||||
.header(Header.CONTENT_TYPE, "application/json")
|
.header(Header.CONTENT_TYPE, "application/json")
|
||||||
.body(requestBody)
|
.body(requestBody)
|
||||||
.timeout(20000) // 设置超时时间20秒
|
.timeout(20000) // 设置超时时间20秒
|
||||||
.execute();
|
.execute()) {
|
||||||
int status = execute.getStatus();
|
|
||||||
if (status == 200){
|
int status = execute.getStatus();
|
||||||
String body = execute.body();
|
if (status == 200) {
|
||||||
JSONObject bodyJson = JSONUtil.parseObj(body);
|
String body = execute.body();
|
||||||
return body;
|
JSONObject bodyJson = JSONUtil.parseObj(body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.warn("请求失败,状态码为:{},响应内容:{}", status, execute.body());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("请求阿里云API时发生异常,URL:{},请求体:{},异常信息:{}",
|
||||||
|
apiUrl, requestBody, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
log.warn("请求失败,状态码为 : {}", status);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String sendAliYunPost(String apiUrl, String requestBody){
|
public String sendAliYunPost(String apiUrl, String requestBody) {
|
||||||
// 发送POST请求 todo 异常处理
|
// 发送POST请求
|
||||||
HttpResponse execute = HttpRequest.post(apiUrl)
|
try (HttpResponse execute = HttpRequest.post(apiUrl)
|
||||||
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
|
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
|
||||||
.header(Header.CONTENT_TYPE, "application/json")
|
.header(Header.CONTENT_TYPE, "application/json")
|
||||||
.body(requestBody)
|
.body(requestBody)
|
||||||
.timeout(20000) // 设置超时时间20秒
|
.timeout(20000) // 设置超时时间20秒
|
||||||
.execute();
|
.execute()) {
|
||||||
int status = execute.getStatus();
|
|
||||||
if (status == 200){
|
int status = execute.getStatus();
|
||||||
String body = execute.body();
|
if (status == 200) {
|
||||||
JSONObject bodyJson = JSONUtil.parseObj(body);
|
String body = execute.body();
|
||||||
return body;
|
JSONObject bodyJson = JSONUtil.parseObj(body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.warn("请求失败,状态码为:{},响应内容:{}", status, execute.body());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("请求阿里云API时发生异常,URL:{},请求体:{},异常信息:{}",
|
||||||
|
apiUrl, requestBody, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
log.warn("请求失败,状态码为 : {}", status);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String FREE_PIK = "https://api.freepik.com/v1/ai/beta/text-to-image/reimagine-flux";
|
public static final String FREE_PIK = "https://api.freepik.com/v1/ai/beta/text-to-image/reimagine-flux";
|
||||||
public String sendFreepikPost( String requestBody){
|
public String sendFreepikPost(String requestBody) {
|
||||||
// 发送POST请求 todo 异常处理
|
// 发送POST请求
|
||||||
HttpResponse execute = HttpRequest.post(FREE_PIK)
|
try (HttpResponse execute = HttpRequest.post(FREE_PIK)
|
||||||
.header(Header.CONTENT_TYPE, "application/json")
|
.header(Header.CONTENT_TYPE, "application/json")
|
||||||
.header("x-freepik-api-key", FREEPIK_API_KEY)
|
.header("x-freepik-api-key", FREEPIK_API_KEY)
|
||||||
.body(requestBody)
|
.body(requestBody)
|
||||||
.timeout(20000) // 设置超时时间20秒
|
.timeout(20000) // 设置超时时间20秒
|
||||||
.execute();
|
.execute()) {
|
||||||
int status = execute.getStatus();
|
|
||||||
if (status == 200){
|
int status = execute.getStatus();
|
||||||
return execute.body();
|
if (status == 200) {
|
||||||
|
return execute.body();
|
||||||
|
}
|
||||||
|
log.warn("请求失败,状态码为:{},响应内容:{}", status, execute.body());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("请求Freepik API时发生异常,请求体:{},异常信息:{}",
|
||||||
|
requestBody, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
log.warn("请求失败,状态码为 : {}", status);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String sendAliYunGet(String fullUrl){
|
public String sendAliYunGet(String fullUrl) {
|
||||||
// 发送GET请求 todo 异常处理
|
// 发送GET请求
|
||||||
HttpResponse httpResponse = HttpRequest.get(fullUrl)
|
try (HttpResponse httpResponse = HttpRequest.get(fullUrl)
|
||||||
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
|
.header(Header.AUTHORIZATION, "Bearer " + ALIYUN_API_KEY)
|
||||||
.timeout(20000) // 设置超时时间20秒
|
.timeout(20000) // 设置超时时间20秒
|
||||||
.execute();
|
.execute()) {
|
||||||
int status = httpResponse.getStatus();
|
|
||||||
if (status == 200){
|
int status = httpResponse.getStatus();
|
||||||
return httpResponse.body();
|
if (status == 200) {
|
||||||
}else {
|
return httpResponse.body();
|
||||||
return null;
|
}
|
||||||
|
log.warn("请求失败,状态码为:{},响应内容:{}", status, httpResponse.body());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("请求阿里云API时发生异常,URL:{},异常信息:{}",
|
||||||
|
fullUrl, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public String sendFluxPost(String url, String requestBodyStr){
|
/*public String sendFluxPost(String url, String requestBodyStr){
|
||||||
|
|||||||
@@ -380,12 +380,12 @@ public class AccountController {
|
|||||||
return Response.success(accountService.subAccountImport(file));
|
return Response.success(accountService.subAccountImport(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@GetMapping("/send618Email")
|
@GetMapping("/send618Email")
|
||||||
@Operation(summary = "618邮件发送")
|
@Operation(summary = "618邮件发送")
|
||||||
public Response<String> send618PromotionEmailTemp() {
|
public Response<String> send618PromotionEmailTemp() {
|
||||||
accountService.send618PromotionEmailTemp();
|
accountService.send618PromotionEmailTemp();
|
||||||
return Response.success("success");
|
return Response.success("success");
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/*@GetMapping("/refreshCreditsMonthly")
|
/*@GetMapping("/refreshCreditsMonthly")
|
||||||
@Operation(summary = "刷新子账号积分")
|
@Operation(summary = "刷新子账号积分")
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.ai.da.common.response.Response;
|
|||||||
import com.ai.da.model.dto.*;
|
import com.ai.da.model.dto.*;
|
||||||
import com.ai.da.model.dto.ContestantDTO;
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
import com.ai.da.model.vo.CheckOTPVO;
|
import com.ai.da.model.vo.CheckOTPVO;
|
||||||
import com.ai.da.model.vo.ContestantCountVO;
|
|
||||||
import com.ai.da.service.GlobalAwardService;
|
import com.ai.da.service.GlobalAwardService;
|
||||||
import com.ai.da.service.upload.UploadService;
|
import com.ai.da.service.upload.UploadService;
|
||||||
import com.ai.da.service.upload.UploadTask;
|
import com.ai.da.service.upload.UploadTask;
|
||||||
@@ -177,25 +176,10 @@ public class GlobalAwardController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/contestants/export/files")
|
@PostMapping("/contestants/export/files")
|
||||||
@ApiOperation(value = "导出参赛者文件为ZIP", notes = "根据参赛者编号范围导出PDF、视频和信息文件为ZIP,直接响应给浏览器")
|
@ApiOperation(value = "导出参赛者文件到本地", notes = "根据参赛者编号范围导出PDF和视频文件到本地temp/uploads/contestants目录")
|
||||||
public void exportContestantFiles(@ApiParam(value = "参赛者文件导出请求", required = true) @RequestBody ContestantExportRequest request, HttpServletResponse response) throws Exception {
|
public Response<Integer> exportContestantFiles(@ApiParam(value = "参赛者文件导出请求", required = true) @RequestBody ContestantExportRequest request) throws Exception {
|
||||||
byte[] zipData = globalAwardService.exportContestantFilesAsZip(request.getMinContestantNumber(), request.getMaxContestantNumber());
|
int exportedCount = globalAwardService.exportContestantFiles(request.getMinContestantNumber(), request.getMaxContestantNumber());
|
||||||
if (zipData.length == 0) {
|
return Response.success(exportedCount);
|
||||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
|
||||||
response.getWriter().write("No contestants found in the specified range.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
response.setContentType("application/zip");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=\"contestants.zip\"");
|
|
||||||
response.setContentLength(zipData.length);
|
|
||||||
response.getOutputStream().write(zipData);
|
|
||||||
response.getOutputStream().flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/contestants/count")
|
|
||||||
@ApiOperation(value = "查询参赛者总数", notes = "查询数据库中参赛者的总数量和最大参赛者编号")
|
|
||||||
public Response<ContestantCountVO> getContestantCount() {
|
|
||||||
return Response.success(globalAwardService.getContestantCount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.ai.da.model.vo;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class ContestantCountVO {
|
|
||||||
|
|
||||||
private Long count;
|
|
||||||
|
|
||||||
private Integer maxContestantNumber;
|
|
||||||
}
|
|
||||||
@@ -239,7 +239,7 @@ public interface AccountService extends IService<Account> {
|
|||||||
|
|
||||||
Set<String> organizationNameSearch(String type, String name);
|
Set<String> organizationNameSearch(String type, String name);
|
||||||
|
|
||||||
/*void send618PromotionEmailTemp();*/
|
void send618PromotionEmailTemp();
|
||||||
|
|
||||||
void checkEduAdminExpireStatus();
|
void checkEduAdminExpireStatus();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.ai.da.service;
|
|||||||
|
|
||||||
import com.ai.da.model.dto.ContestantDTO;
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
import com.ai.da.model.vo.CheckOTPVO;
|
import com.ai.da.model.vo.CheckOTPVO;
|
||||||
import com.ai.da.model.vo.ContestantCountVO;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -34,18 +33,12 @@ public interface GlobalAwardService {
|
|||||||
void saveContestantsToLocal() throws Exception;
|
void saveContestantsToLocal() throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将参赛者文件打包为 ZIP 并返回字节数组(不落盘,直接响应给浏览器)
|
* 根据参赛者编号范围导出参赛者文件到本地目录
|
||||||
* @param minContestantNumber 最小参赛者编号
|
* @param minContestantNumber 最小参赛者编号
|
||||||
* @param maxContestantNumber 最大参赛者编号
|
* @param maxContestantNumber 最大参赛者编号
|
||||||
* @return ZIP 文件的字节数组
|
* @return 导出的参赛者数量
|
||||||
*/
|
*/
|
||||||
byte[] exportContestantFilesAsZip(Integer minContestantNumber, Integer maxContestantNumber) throws Exception;
|
int exportContestantFiles(Integer minContestantNumber, Integer maxContestantNumber) throws Exception;
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询参赛者总数和最大参赛者编号
|
|
||||||
* @return 参赛者数量和最大参赛者编号
|
|
||||||
*/
|
|
||||||
ContestantCountVO getContestantCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3670,33 +3670,66 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
return new HashSet<>();
|
return new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @Override
|
@Override
|
||||||
public void send618PromotionEmailTemp() {
|
public void send618PromotionEmailTemp() {
|
||||||
QueryWrapper<TrialOrder> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("is_deleted", 0);
|
|
||||||
|
|
||||||
List<TrialOrder> trialOrders = trialOrderMapper.selectList(queryWrapper);
|
queryWrapper.lambda()
|
||||||
|
.isNotNull(Account::getUserEmail)
|
||||||
|
.in(Account::getUserEmail, "xupei3360@163.com", "kimwong@code-create.com.hk", "kaicpang.pang@connect.polyu.hk", "chelseayu@code-create.com.hk")
|
||||||
|
.apply("LENGTH(TRIM(user_email)) > 0");
|
||||||
|
|
||||||
// List<Account> accountList = accountMapper.selectList(queryWrapper);
|
List<Account> accounts = baseMapper.selectList(queryWrapper);
|
||||||
System.out.println(trialOrders);
|
|
||||||
int total = trialOrders.size();
|
// 按邮箱去重,保留每个邮箱的第一条记录
|
||||||
log.info("试用用户总量:{}", total);
|
Map<String, Account> emailToAccountMap = new LinkedHashMap<>();
|
||||||
int current = 1;
|
for (Account account : accounts) {
|
||||||
for (TrialOrder trialOrder : trialOrders) {
|
String email = account.getUserEmail();
|
||||||
log.info("邮件发送进度 {}/{}", current, total);
|
if (!StringUtil.isNullOrEmpty(email)) {
|
||||||
try {
|
email = email.trim().toLowerCase();
|
||||||
if (!StringUtil.isNullOrEmpty(trialOrder.getCountry()) && trialOrder.getCountry().equals("China")) {
|
// 保留第一次出现的记录
|
||||||
SendEmailUtil.send618PromotionEmailTemp(trialOrder.getEmail(), "CHINESE_SIMPLIFIED");
|
emailToAccountMap.putIfAbsent(email, account);
|
||||||
} else {
|
|
||||||
// 英文
|
|
||||||
SendEmailUtil.send618PromotionEmailTemp(trialOrder.getEmail(), "ENGLISH");
|
|
||||||
}
|
|
||||||
}catch (Exception e) {
|
|
||||||
log.info(e.getMessage());
|
|
||||||
}
|
}
|
||||||
current ++;
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
List<String> uniqueEmails = new ArrayList<>(emailToAccountMap.keySet());
|
||||||
|
int total = uniqueEmails.size();
|
||||||
|
log.info("AiDA用户去重后邮件发送总量:{}", total);
|
||||||
|
|
||||||
|
// 控制发送速率:每发送20封后等待1秒,控制QPS在20以内
|
||||||
|
int batchSize = 20;
|
||||||
|
long sleepMillis = 1000;
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < uniqueEmails.size(); i++) {
|
||||||
|
String email = uniqueEmails.get(i);
|
||||||
|
log.info("邮件发送进度 {}/{}", i + 1, total);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 统一发送英文版本
|
||||||
|
// log.info("邮件地址 {}", email);
|
||||||
|
SendEmailUtil.send618PromotionEmailTemp(email, "ENGLISH");
|
||||||
|
successCount++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
failCount++;
|
||||||
|
log.error("邮件发送失败,收件人:{},错误信息:{}", email, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 控制发送速率,每发送 batchSize 封后等待
|
||||||
|
if ((i + 1) % batchSize == 0 && (i + 1) < uniqueEmails.size()) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepMillis);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
log.warn("邮件发送被中断");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("邮件发送完成,成功:{},失败:{}", successCount, failCount);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkEduAdminExpireStatus() {
|
public void checkEduAdminExpireStatus() {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import com.ai.da.mapper.primary.entity.Notification;
|
|||||||
import com.ai.da.model.dto.ContestantDTO;
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
import com.ai.da.model.dto.PublishSysNotificationDTO;
|
import com.ai.da.model.dto.PublishSysNotificationDTO;
|
||||||
import com.ai.da.model.vo.CheckOTPVO;
|
import com.ai.da.model.vo.CheckOTPVO;
|
||||||
import com.ai.da.model.vo.ContestantCountVO;
|
|
||||||
import com.ai.da.service.GlobalAwardService;
|
import com.ai.da.service.GlobalAwardService;
|
||||||
import com.ai.da.service.MessageCenterService;
|
import com.ai.da.service.MessageCenterService;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
@@ -27,22 +26,24 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.zip.ZipEntry;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -264,9 +265,11 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
r.createCell(ci++).setCellValue(cst.getPhoneNumber() == null ? "" : cst.getPhoneNumber());
|
r.createCell(ci++).setCellValue(cst.getPhoneNumber() == null ? "" : cst.getPhoneNumber());
|
||||||
r.createCell(ci++).setCellValue(cst.getDesignTitle() == null ? "" : cst.getDesignTitle());
|
r.createCell(ci++).setCellValue(cst.getDesignTitle() == null ? "" : cst.getDesignTitle());
|
||||||
r.createCell(ci++).setCellValue(cst.getDesignDescription() == null ? "" : cst.getDesignDescription());
|
r.createCell(ci++).setCellValue(cst.getDesignDescription() == null ? "" : cst.getDesignDescription());
|
||||||
r.createCell(ci++).setCellValue(cst.getPdfPath() == null ? "" : cst.getPdfPath());
|
// r.createCell(ci++).setCellValue(cst.getPdfPath() == null ? "" : cst.getPdfPath());
|
||||||
r.createCell(ci++).setCellValue(cst.getVideoPath() == null ? "" : cst.getVideoPath());
|
// r.createCell(ci++).setCellValue(cst.getVideoPath() == null ? "" : cst.getVideoPath());
|
||||||
|
// 视频时长(秒)
|
||||||
r.createCell(ci++).setCellValue(cst.getVideoDuration() == null ? "" : cst.getVideoDuration().toString());
|
r.createCell(ci++).setCellValue(cst.getVideoDuration() == null ? "" : cst.getVideoDuration().toString());
|
||||||
|
// 视频大小、PDF 大小:以 MB 导出,保留两位小数
|
||||||
if (cst.getVideoSize() == null) {
|
if (cst.getVideoSize() == null) {
|
||||||
r.createCell(ci++).setCellValue("");
|
r.createCell(ci++).setCellValue("");
|
||||||
} else {
|
} else {
|
||||||
@@ -329,9 +332,11 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
r.createCell(ci++).setCellValue(cst.getPhoneNumber() == null ? "" : cst.getPhoneNumber());
|
r.createCell(ci++).setCellValue(cst.getPhoneNumber() == null ? "" : cst.getPhoneNumber());
|
||||||
r.createCell(ci++).setCellValue(cst.getDesignTitle() == null ? "" : cst.getDesignTitle());
|
r.createCell(ci++).setCellValue(cst.getDesignTitle() == null ? "" : cst.getDesignTitle());
|
||||||
r.createCell(ci++).setCellValue(cst.getDesignDescription() == null ? "" : cst.getDesignDescription());
|
r.createCell(ci++).setCellValue(cst.getDesignDescription() == null ? "" : cst.getDesignDescription());
|
||||||
r.createCell(ci++).setCellValue(cst.getPdfPath() == null ? "" : cst.getPdfPath());
|
// r.createCell(ci++).setCellValue(cst.getPdfPath() == null ? "" : cst.getPdfPath());
|
||||||
r.createCell(ci++).setCellValue(cst.getVideoPath() == null ? "" : cst.getVideoPath());
|
// r.createCell(ci++).setCellValue(cst.getVideoPath() == null ? "" : cst.getVideoPath());
|
||||||
|
// 视频时长(秒)
|
||||||
r.createCell(ci++).setCellValue(cst.getVideoDuration() == null ? "" : cst.getVideoDuration().toString());
|
r.createCell(ci++).setCellValue(cst.getVideoDuration() == null ? "" : cst.getVideoDuration().toString());
|
||||||
|
// 视频大小、PDF 大小:以 MB 导出,保留两位小数
|
||||||
if (cst.getVideoSize() == null) {
|
if (cst.getVideoSize() == null) {
|
||||||
r.createCell(ci++).setCellValue("");
|
r.createCell(ci++).setCellValue("");
|
||||||
} else {
|
} else {
|
||||||
@@ -475,7 +480,7 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] exportContestantFilesAsZip(Integer minContestantNumber, Integer maxContestantNumber) throws Exception {
|
public int exportContestantFiles(Integer minContestantNumber, Integer maxContestantNumber) throws Exception {
|
||||||
if (minContestantNumber == null || maxContestantNumber == null) {
|
if (minContestantNumber == null || maxContestantNumber == null) {
|
||||||
throw new BusinessException("minContestantNumber and maxContestantNumber are required.");
|
throw new BusinessException("minContestantNumber and maxContestantNumber are required.");
|
||||||
}
|
}
|
||||||
@@ -483,7 +488,7 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
throw new BusinessException("minContestantNumber cannot be greater than maxContestantNumber.");
|
throw new BusinessException("minContestantNumber cannot be greater than maxContestantNumber.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. 根据 contestantNumber 范围查询参赛者
|
// 1. 根据contestantNumber范围查询参赛者
|
||||||
QueryWrapper<Contestant> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<Contestant> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.lambda()
|
queryWrapper.lambda()
|
||||||
.ge(Contestant::getContestantNumber, minContestantNumber)
|
.ge(Contestant::getContestantNumber, minContestantNumber)
|
||||||
@@ -493,125 +498,90 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
|
|
||||||
if (contestants.isEmpty()) {
|
if (contestants.isEmpty()) {
|
||||||
log.info("No contestants found in range [{}, {}]", minContestantNumber, maxContestantNumber);
|
log.info("No contestants found in range [{}, {}]", minContestantNumber, maxContestantNumber);
|
||||||
return new byte[0];
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 在内存中构建 ZIP
|
// 2. 创建基础目录
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
String baseDir = uploadDir + "/contestants";
|
||||||
java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(baos)) {
|
Path basePath = Paths.get(baseDir).toAbsolutePath();
|
||||||
|
Files.createDirectories(basePath);
|
||||||
|
log.info("Base directory created: {}", basePath);
|
||||||
|
|
||||||
for (Contestant contestant : contestants) {
|
int exportedCount = 0;
|
||||||
Integer contestantNumber = contestant.getContestantNumber();
|
|
||||||
if (contestantNumber == null) {
|
|
||||||
log.warn("Contestant {} has no contestantNumber, skipping", contestant.getId());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String dirPrefix = contestantNumber + "/";
|
// 3. 遍历每个参赛者,下载文件
|
||||||
|
for (Contestant contestant : contestants) {
|
||||||
// 添加 PDF 文件
|
Integer contestantNumber = contestant.getContestantNumber();
|
||||||
String pdfPath = contestant.getPdfPath();
|
if (contestantNumber == null) {
|
||||||
if (StringUtils.isNotBlank(pdfPath)) {
|
log.warn("Contestant {} has no contestantNumber, skipping", contestant.getId());
|
||||||
addMinioFileToZip(zos, pdfPath, dirPrefix + "design.pdf");
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// 添加视频文件
|
|
||||||
String videoPath = contestant.getVideoPath();
|
|
||||||
if (StringUtils.isNotBlank(videoPath)) {
|
|
||||||
String fileName = videoPath.contains("/") ?
|
|
||||||
videoPath.substring(videoPath.lastIndexOf("/") + 1) : "video.mp4";
|
|
||||||
addMinioFileToZip(zos, videoPath, dirPrefix + fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加参赛者信息 txt 文件
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("=== Contestant Information ===\n\n");
|
|
||||||
sb.append("ID: ").append(nullSafe(contestant.getId())).append("\n");
|
|
||||||
sb.append("Email: ").append(nullSafe(contestant.getEmail())).append("\n");
|
|
||||||
sb.append("Contestant Number: ").append(contestantNumber).append("\n");
|
|
||||||
sb.append("First Name: ").append(nullSafe(contestant.getFirstName())).append("\n");
|
|
||||||
sb.append("Last Name: ").append(nullSafe(contestant.getLastName())).append("\n");
|
|
||||||
sb.append("Gender: ").append(nullSafe(contestant.getGender())).append("\n");
|
|
||||||
sb.append("Occupation: ").append(nullSafe(contestant.getOccupation())).append("\n");
|
|
||||||
sb.append("Age: ").append(contestant.getAge() != null ? contestant.getAge() : "N/A").append("\n");
|
|
||||||
sb.append("Country/Region/City: ").append(nullSafe(contestant.getCountryRegionCity())).append("\n");
|
|
||||||
sb.append("Phone Number: ").append(nullSafe(contestant.getPhoneNumber())).append("\n");
|
|
||||||
sb.append("Design Title: ").append(nullSafe(contestant.getDesignTitle())).append("\n");
|
|
||||||
sb.append("Design Description: ").append(nullSafe(contestant.getDesignDescription())).append("\n");
|
|
||||||
sb.append("PDF Path: ").append(nullSafe(pdfPath)).append("\n");
|
|
||||||
sb.append("PDF Size (bytes): ").append(contestant.getPdfSize() != null ? contestant.getPdfSize() : "N/A").append("\n");
|
|
||||||
sb.append("Video Path: ").append(nullSafe(videoPath)).append("\n");
|
|
||||||
sb.append("Video Duration (seconds): ").append(contestant.getVideoDuration() != null ? contestant.getVideoDuration() : "N/A").append("\n");
|
|
||||||
sb.append("Video Size (bytes): ").append(contestant.getVideoSize() != null ? contestant.getVideoSize() : "N/A").append("\n");
|
|
||||||
sb.append("Created At: ").append(contestant.getCreatedAt() != null ? contestant.getCreatedAt() : "N/A").append("\n");
|
|
||||||
sb.append("Updated At: ").append(contestant.getUpdatedAt() != null ? contestant.getUpdatedAt() : "N/A").append("\n");
|
|
||||||
|
|
||||||
ZipEntry infoEntry = new ZipEntry(dirPrefix + "contestant_info.txt");
|
|
||||||
zos.putNextEntry(infoEntry);
|
|
||||||
zos.write(sb.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8));
|
|
||||||
zos.closeEntry();
|
|
||||||
log.info("Added contestant {} info to zip", contestantNumber);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zos.finish();
|
// 创建参赛者文件夹
|
||||||
log.info("ZIP built for {} contestants, size: {} bytes", contestants.size(), baos.size());
|
String contestantDir = baseDir + "/" + contestantNumber;
|
||||||
return baos.toByteArray();
|
Path contestantPath = Paths.get(contestantDir);
|
||||||
|
Files.createDirectories(contestantPath);
|
||||||
|
|
||||||
|
// 下载PDF文件
|
||||||
|
String pdfPath = contestant.getPdfPath();
|
||||||
|
if (StringUtils.isNotBlank(pdfPath)) {
|
||||||
|
try {
|
||||||
|
String fileName = pdfPath.contains("/") ?
|
||||||
|
pdfPath.substring(pdfPath.lastIndexOf("/") + 1) : "design.pdf";
|
||||||
|
downloadFileFromMinio(pdfPath, contestantPath.toString(), "design.pdf");
|
||||||
|
log.info("Downloaded PDF for contestant {}", fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to download PDF for contestant {}: {}", contestantNumber, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载视频文件
|
||||||
|
String videoPath = contestant.getVideoPath();
|
||||||
|
if (StringUtils.isNotBlank(videoPath)) {
|
||||||
|
try {
|
||||||
|
// 根据路径判断视频格式
|
||||||
|
String fileName = videoPath.contains("/") ?
|
||||||
|
videoPath.substring(videoPath.lastIndexOf("/") + 1) : "video.mp4";
|
||||||
|
downloadFileFromMinio(videoPath, contestantPath.toString(), fileName);
|
||||||
|
log.info("Downloaded video for contestant {}", contestantNumber);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to download video for contestant {}: {}", contestantNumber, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exportedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("Exported {} contestants' files to {}", exportedCount, basePath);
|
||||||
|
return exportedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 MinIO 文件流式写入 ZIP,不落盘
|
* 从MinIO下载文件到本地
|
||||||
* @param zos ZIP 输出流
|
* @param minioPath MinIO路径 (格式: bucketName/objectPath)
|
||||||
* @param minioPath MinIO 路径(格式: bucketName/objectPath)
|
* @param localDir 本地目录
|
||||||
* @param entryName ZIP 条目名称
|
* @param fileName 本地文件名
|
||||||
*/
|
*/
|
||||||
private void addMinioFileToZip(java.util.zip.ZipOutputStream zos, String minioPath, String entryName) {
|
private void downloadFileFromMinio(String minioPath, String localDir, String fileName) {
|
||||||
if (StringUtils.isBlank(minioPath)) {
|
if (StringUtils.isBlank(minioPath)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从路径中提取bucket名称和对象名称
|
||||||
int index = minioPath.indexOf("/");
|
int index = minioPath.indexOf("/");
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
log.warn("Invalid MinIO path: {}", minioPath);
|
log.warn("Invalid MinIO path: {}", minioPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String bucketName = minioPath.substring(0, index);
|
String bucketName = minioPath.substring(0, index);
|
||||||
String objectName = minioPath.substring(index + 1);
|
String objectName = minioPath.substring(index + 1);
|
||||||
|
|
||||||
try (InputStream in = minioUtil.download(bucketName, objectName)) {
|
// 构建本地文件完整路径
|
||||||
ZipEntry entry = new ZipEntry(entryName);
|
Path localFilePath = Paths.get(localDir, fileName);
|
||||||
zos.putNextEntry(entry);
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = in.read(buffer)) != -1) {
|
|
||||||
zos.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
zos.closeEntry();
|
|
||||||
log.info("Added {} to zip ({} bytes)", entryName, entry.getSize());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to add {} to zip: {}", entryName, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// 下载文件
|
||||||
public ContestantCountVO getContestantCount() {
|
minioUtil.downloadMinioObjectToLocal(bucketName, objectName, localFilePath.toString());
|
||||||
long count = contestantMapper.selectCount(null);
|
|
||||||
Integer maxContestantNumber = null;
|
|
||||||
QueryWrapper<Contestant> qMax = new QueryWrapper<>();
|
|
||||||
qMax.isNotNull("contestant_number");
|
|
||||||
qMax.orderByDesc("contestant_number");
|
|
||||||
qMax.last("LIMIT 1");
|
|
||||||
Contestant last = contestantMapper.selectOne(qMax);
|
|
||||||
if (last != null) {
|
|
||||||
maxContestantNumber = last.getContestantNumber();
|
|
||||||
}
|
|
||||||
return ContestantCountVO.builder()
|
|
||||||
.count(count)
|
|
||||||
.maxContestantNumber(maxContestantNumber)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String nullSafe(String value) {
|
|
||||||
return value != null ? value : "N/A";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1060,12 +1060,11 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
String periodEnd = DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_yyyy_MM_dd_HH_mm_ss);
|
String periodEnd = DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_yyyy_MM_dd_HH_mm_ss);
|
||||||
|
|
||||||
qwPI.lambda().eq(PaymentInfo::getOrderNo, subscriptionInfo.getOrderNo())
|
qwPI.lambda().eq(PaymentInfo::getOrderNo, subscriptionInfo.getOrderNo())
|
||||||
.eq(PaymentInfo::getTradeState, "paid")
|
|
||||||
.between(PaymentInfo::getCreateTime, periodStart, periodEnd)
|
.between(PaymentInfo::getCreateTime, periodStart, periodEnd)
|
||||||
.orderByDesc(PaymentInfo::getId);
|
.orderByDesc(PaymentInfo::getId);
|
||||||
List<PaymentInfo> paymentInfos = paymentInfoMapper.selectList(qwPI);
|
List<PaymentInfo> paymentInfos = paymentInfoMapper.selectList(qwPI);
|
||||||
if (paymentInfos.isEmpty()) {
|
if (paymentInfos.isEmpty()) {
|
||||||
log.info("不发送邮件,原因:【根据order_no:{},查询到的成功的paymentInfos为空】", orderNo);
|
log.info("不发送邮件,原因:【根据order_no:{},查询到的paymentInfos为空】", orderNo);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PaymentInfo paymentInfo = paymentInfos.get(0);
|
PaymentInfo paymentInfo = paymentInfos.get(0);
|
||||||
|
|||||||
@@ -905,15 +905,15 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 将构建好的结果对象添加到返回列表
|
// 将构建好的结果对象添加到返回列表
|
||||||
// results.add(magicToolResultVO);
|
results.add(magicToolResultVO);
|
||||||
} else if (Objects.isNull(magicToolResultVO)) {
|
} else if (Objects.isNull(magicToolResultVO)) {
|
||||||
// 如果Redis中没有结果对象,创建执行中状态的结果对象
|
// 如果Redis中没有结果对象,创建执行中状态的结果对象
|
||||||
magicToolResultVO = new MagicToolResultVO(taskId, "Executing");
|
magicToolResultVO = new MagicToolResultVO(taskId, "Executing");
|
||||||
// results.add(magicToolResultVO);
|
results.add(magicToolResultVO);
|
||||||
}/* else {
|
} else {
|
||||||
// 如果Redis中有结果对象但URL为空,直接添加到返回列表
|
// 如果Redis中有结果对象但URL为空,直接添加到返回列表
|
||||||
results.add(magicToolResultVO);
|
results.add(magicToolResultVO);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// 收集任务状态用于统计
|
// 收集任务状态用于统计
|
||||||
if (!StringUtil.isNullOrEmpty(magicToolResultVO.getStatus())) collect.add(magicToolResultVO.getStatus());
|
if (!StringUtil.isNullOrEmpty(magicToolResultVO.getStatus())) collect.add(magicToolResultVO.getStatus());
|
||||||
@@ -1461,16 +1461,12 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
if (StringUtil.isNullOrEmpty(fluxResult)) {
|
if (StringUtil.isNullOrEmpty(fluxResult)) {
|
||||||
toProductImageResult.setStatus("Fail");
|
toProductImageResult.setStatus("Fail");
|
||||||
toProductImageResultMapper.updateById(toProductImageResult);
|
toProductImageResultMapper.updateById(toProductImageResult);
|
||||||
if (toProductImageResult.getIsLike() != null && toProductImageResult.getIsLike() == 1) {
|
sortRank(toProductImageResult);
|
||||||
sortRank(toProductImageResult);
|
|
||||||
}
|
|
||||||
results.add(new MagicToolResultVO(taskId, "Fail"));
|
results.add(new MagicToolResultVO(taskId, "Fail"));
|
||||||
} else if (fluxResult.equals("Fail") || fluxResult.equals("Pending")) {
|
} else if (fluxResult.equals("Fail") || fluxResult.equals("Pending")) {
|
||||||
toProductImageResult.setStatus(fluxResult);
|
toProductImageResult.setStatus(fluxResult);
|
||||||
toProductImageResultMapper.updateById(toProductImageResult);
|
toProductImageResultMapper.updateById(toProductImageResult);
|
||||||
if (fluxResult.equals("Fail") && toProductImageResult.getIsLike() != null && toProductImageResult.getIsLike() == 1) {
|
sortRank(toProductImageResult);
|
||||||
sortRank(toProductImageResult);
|
|
||||||
}
|
|
||||||
results.add(new MagicToolResultVO(taskId, fluxResult));
|
results.add(new MagicToolResultVO(taskId, fluxResult));
|
||||||
} else {
|
} else {
|
||||||
results.add(processFluxResult(fluxResult, toProductImageResult, taskId, toProductImageRecord.getPrompt()));
|
results.add(processFluxResult(fluxResult, toProductImageResult, taskId, toProductImageRecord.getPrompt()));
|
||||||
@@ -2207,14 +2203,10 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
childCollectionQw.lambda().orderByAsc(CollectionSort::getSort);
|
childCollectionQw.lambda().orderByAsc(CollectionSort::getSort);
|
||||||
List<CollectionSort> childSortList = collectionSortMapper.selectList(childCollectionQw);
|
List<CollectionSort> childSortList = collectionSortMapper.selectList(childCollectionQw);
|
||||||
List<AllCollectionVO> childList = new ArrayList<>();
|
List<AllCollectionVO> childList = new ArrayList<>();
|
||||||
// 收集需要删除的失败记录ID,用于后续统一清理并重新排序
|
|
||||||
List<Long> failedSortIds = new ArrayList<>();
|
|
||||||
for (CollectionSort userLikeSort : childSortList) {
|
for (CollectionSort userLikeSort : childSortList) {
|
||||||
if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) {
|
if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) {
|
||||||
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId());
|
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId());
|
||||||
if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) {
|
if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) {
|
||||||
failedSortIds.add(userLikeSort.getId());
|
|
||||||
log.info("【获取内容】TO_PRODUCT_IMAGE结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl()));
|
toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl()));
|
||||||
@@ -2246,8 +2238,6 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
} else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) {
|
} else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) {
|
||||||
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId());
|
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId());
|
||||||
if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) {
|
if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) {
|
||||||
failedSortIds.add(userLikeSort.getId());
|
|
||||||
log.info("【获取内容】RELIGHT结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl()));
|
toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl()));
|
||||||
@@ -2279,8 +2269,6 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
} else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) {
|
} else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) {
|
||||||
PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId());
|
PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId());
|
||||||
if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) {
|
if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) {
|
||||||
failedSortIds.add(userLikeSort.getId());
|
|
||||||
log.info("【获取内容】POSE_TRANSFORM结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PoseTransformationVO poseTransformationVO = new PoseTransformationVO();
|
PoseTransformationVO poseTransformationVO = new PoseTransformationVO();
|
||||||
@@ -2305,114 +2293,6 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
childList.add(poseTransformationVO);
|
childList.add(poseTransformationVO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 统一处理失败的记录:从collection_sort表中删除失败的记录,并重新排序
|
|
||||||
if (CollectionUtil.isNotEmpty(failedSortIds)) {
|
|
||||||
Long parentId = collectionSort.getId();
|
|
||||||
Long projectId = projectDTO.getId();
|
|
||||||
log.info("【获取内容】检测到{}条失败记录需要清理,parentId={}, projectId={}", failedSortIds.size(), parentId, projectId);
|
|
||||||
for (Long failedSortId : failedSortIds) {
|
|
||||||
CollectionSort failedRecord = collectionSortMapper.selectById(failedSortId);
|
|
||||||
if (failedRecord != null) {
|
|
||||||
String relationType = failedRecord.getRelationType();
|
|
||||||
Long relationId = failedRecord.getRelationId();
|
|
||||||
collectionSortService.deleteCollectionSort(relationId, relationType, projectId, parentId);
|
|
||||||
log.info("【获取内容】已删除失败记录,relationId={}, relationType={}", relationId, relationType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 重新查询子列表,获取更新后的排序
|
|
||||||
childSortList = collectionSortMapper.selectList(childCollectionQw);
|
|
||||||
// 重新构建childList,使用更新后的sort值
|
|
||||||
childList = new ArrayList<>();
|
|
||||||
for (CollectionSort userLikeSort : childSortList) {
|
|
||||||
if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) {
|
|
||||||
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId());
|
|
||||||
if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl()));
|
|
||||||
ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class);
|
|
||||||
|
|
||||||
ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId());
|
|
||||||
if (Objects.isNull(toProductImageRecord)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt());
|
|
||||||
|
|
||||||
if (toProductImageResultVO.getElementType().equals("ProductElement")) {
|
|
||||||
ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId());
|
|
||||||
toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl()));
|
|
||||||
} else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) {
|
|
||||||
TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId());
|
|
||||||
toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl()));
|
|
||||||
} else {
|
|
||||||
ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId());
|
|
||||||
toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl()));
|
|
||||||
}
|
|
||||||
toProductImageResultVO.setCollectionType(CollectionType.TO_PRODUCT_IMAGE.getValue());
|
|
||||||
toProductImageResultVO.setSort(userLikeSort.getSort());
|
|
||||||
toProductImageResultVO.setUserLikeSortId(userLikeSort.getId());
|
|
||||||
toProductImageResultVO.setRelationType(userLikeSort.getRelationType());
|
|
||||||
toProductImageResultVO.setParentId(userLikeSort.getParentId());
|
|
||||||
childList.add(toProductImageResultVO);
|
|
||||||
} else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) {
|
|
||||||
ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId());
|
|
||||||
if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl()));
|
|
||||||
ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class);
|
|
||||||
|
|
||||||
ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId());
|
|
||||||
if (Objects.isNull(toProductImageRecord)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt());
|
|
||||||
|
|
||||||
if (toProductImageResultVO.getElementType().equals("ProductElement")) {
|
|
||||||
ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId());
|
|
||||||
toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl()));
|
|
||||||
} else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) {
|
|
||||||
TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId());
|
|
||||||
toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl()));
|
|
||||||
} else {
|
|
||||||
ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId());
|
|
||||||
toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl()));
|
|
||||||
}
|
|
||||||
toProductImageResultVO.setCollectionType(CollectionType.RELIGHT.getValue());
|
|
||||||
toProductImageResultVO.setSort(userLikeSort.getSort());
|
|
||||||
toProductImageResultVO.setUserLikeSortId(userLikeSort.getId());
|
|
||||||
toProductImageResultVO.setRelationType(userLikeSort.getRelationType());
|
|
||||||
toProductImageResultVO.setParentId(userLikeSort.getParentId());
|
|
||||||
childList.add(toProductImageResultVO);
|
|
||||||
} else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) {
|
|
||||||
PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId());
|
|
||||||
if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PoseTransformationVO poseTransformationVO = new PoseTransformationVO();
|
|
||||||
poseTransformationVO.setId(item.getId());
|
|
||||||
poseTransformationVO.setTaskId(item.getUniqueId());
|
|
||||||
poseTransformationVO.setProductImage(getMinioUrl(item.getProductImage()));
|
|
||||||
poseTransformationVO.setLastFrameProductImage(getMinioUrl(item.getLastFrameProductImage()));
|
|
||||||
poseTransformationVO.setPrompt(item.getPrompt());
|
|
||||||
poseTransformationVO.setGifUrl(getMinioUrl(item.getGifUrl()));
|
|
||||||
poseTransformationVO.setVideoUrl(getMinioUrl(item.getVideoUrl()));
|
|
||||||
poseTransformationVO.setFirstFrameUrl(getMinioUrl(item.getFirstFrameUrl()));
|
|
||||||
poseTransformationVO.setIsLiked(item.getIsLiked());
|
|
||||||
poseTransformationVO.setCollectionType(CollectionType.POSE_TRANSFORM.getValue());
|
|
||||||
poseTransformationVO.setSort(userLikeSort.getSort());
|
|
||||||
poseTransformationVO.setUserLikeSortId(userLikeSort.getId());
|
|
||||||
poseTransformationVO.setRelationType(userLikeSort.getRelationType());
|
|
||||||
poseTransformationVO.setResultType(CollectionType.POSE_TRANSFORM.getValue());
|
|
||||||
poseTransformationVO.setParentId(userLikeSort.getParentId());
|
|
||||||
poseTransformationVO.setModelName(item.getModelName());
|
|
||||||
poseTransformationVO.setPoseId(item.getPoseId());
|
|
||||||
poseTransformationVO.setStatus(item.getTaskStatus());
|
|
||||||
childList.add(poseTransformationVO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.info("【获取内容】失败记录清理完成,重新排序后childList.size={}", childList.size());
|
|
||||||
}
|
|
||||||
o.setChildList(childList);
|
o.setChildList(childList);
|
||||||
|
|
||||||
list.add(o);
|
list.add(o);
|
||||||
|
|||||||
Reference in New Issue
Block a user