Compare commits
14 Commits
6e98f295c5
...
temp_Promo
| Author | SHA1 | Date | |
|---|---|---|---|
| a8c1261c89 | |||
| c35e60dcde | |||
| ad3bc69e5c | |||
| bb682e56fa | |||
| 9a4a5d5504 | |||
| b4354d5975 | |||
| 635d913084 | |||
| 61e8901bb1 | |||
| 1680debd4b | |||
| bd6ba95a25 | |||
| 75efc341be | |||
| 921de43b08 | |||
| c558ebb3d0 | |||
| d20bb27244 |
@@ -13,8 +13,9 @@ public class CommonConstant {
|
|||||||
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60;
|
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60;
|
||||||
// 单位 秒 一天过期 in redis
|
// 单位 秒 一天过期 in redis
|
||||||
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
|
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
|
||||||
// 单位 秒 7天过期
|
// 单位 秒 7天过期 (todo 测试状态下 3小时过期)
|
||||||
public static final Long REDIS_SET_EXPIRE_TIME = 24 * 60 * 60 * 7L;
|
// public static final Long REDIS_SET_EXPIRE_TIME = 24 * 60 * 60 * 7L;
|
||||||
|
public static final Long REDIS_SET_EXPIRE_TIME = 3 * 60 * 60L;
|
||||||
|
|
||||||
public static class Numbers{
|
public static class Numbers{
|
||||||
public static final Integer NUMBER_10 = 10;
|
public static final Integer NUMBER_10 = 10;
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ public class ModelConstants {
|
|||||||
|
|
||||||
// 模型名称常量
|
// 模型名称常量
|
||||||
public static final String PRINTBOARD_ADVANCED_T2I = "qwen-image";
|
public static final String PRINTBOARD_ADVANCED_T2I = "qwen-image";
|
||||||
public static final String MOODBOARD_ADVANCED = "doubao-seedream-3-0-t2i-250415";
|
public static final String MOODBOARD_ADVANCED = "doubao-seedream-4-5-251128";
|
||||||
public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-3-0-t2i-250415";
|
public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-4-0-250828-high";
|
||||||
public static final String PRINTBOARD_HIGH_I2I = "doubao-seedream-4-0-250828-fast";
|
public static final String PRINTBOARD_HIGH_I2I = "doubao-seedream-4-0-250828-fast";
|
||||||
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
||||||
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
||||||
|
|||||||
@@ -17,17 +17,38 @@ import com.tencentcloudapi.ses.v20201002.models.SendEmailRequest;
|
|||||||
import com.tencentcloudapi.ses.v20201002.models.SendEmailResponse;
|
import com.tencentcloudapi.ses.v20201002.models.SendEmailResponse;
|
||||||
import com.tencentcloudapi.ses.v20201002.models.Template;
|
import com.tencentcloudapi.ses.v20201002.models.Template;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮件发送类
|
* 邮件发送类
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class SendEmailUtil {
|
public class SendEmailUtil {
|
||||||
|
@Value("${merchant.email:}")
|
||||||
|
private String merchantEmailInstance;
|
||||||
|
@Value("${developer.email: xupei@code-create.com.hk}")
|
||||||
|
private String developerEmailInstance;
|
||||||
|
|
||||||
|
private static String merchantEmail;
|
||||||
|
private static String developerEmail;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
merchantEmail = merchantEmailInstance;
|
||||||
|
developerEmail = developerEmailInstance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 秘钥id
|
* 秘钥id
|
||||||
*/
|
*/
|
||||||
@@ -765,9 +786,7 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
public static boolean subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
|
public static boolean subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
|
||||||
try {
|
try {
|
||||||
String merchantEmail = "kimwong@code-create.com.hk";
|
String[] receiverEmail = buildMerchantReceiverEmail();
|
||||||
String developer = "xupei3360@163.com";
|
|
||||||
String[] receiverEmail = {/*merchantEmail,*/ developer};
|
|
||||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||||
HttpProfile httpProfile = new HttpProfile();
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
@@ -966,9 +985,7 @@ public class SendEmailUtil {
|
|||||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||||
SendEmailRequest req = new SendEmailRequest();
|
SendEmailRequest req = new SendEmailRequest();
|
||||||
req.setFromEmailAddress(SEND_ADDRESS);
|
req.setFromEmailAddress(SEND_ADDRESS);
|
||||||
String merchantEmail = "kimwong@code-create.com.hk";
|
req.setDestination(buildMerchantReceiverEmail());
|
||||||
String developerEmail = "xupei@code-create.com.hk";
|
|
||||||
req.setDestination(new String[]{/*merchantEmail,*/ developerEmail});
|
|
||||||
Template template = new Template();
|
Template template = new Template();
|
||||||
req.setSubject("New Credit Purchase Order");
|
req.setSubject("New Credit Purchase Order");
|
||||||
template.setTemplateID(CREDITS_PURCHASE_MERCHANT);
|
template.setTemplateID(CREDITS_PURCHASE_MERCHANT);
|
||||||
@@ -1076,4 +1093,25 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String[] buildMerchantReceiverEmail() {
|
||||||
|
List<String> emails = new ArrayList<>();
|
||||||
|
if (!StringUtils.isEmpty(merchantEmail)) {
|
||||||
|
for (String e : merchantEmail.split(",")) {
|
||||||
|
String trimmed = e.trim();
|
||||||
|
if (!trimmed.isEmpty()) {
|
||||||
|
emails.add(trimmed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(developerEmail)) {
|
||||||
|
for (String e : developerEmail.split(",")) {
|
||||||
|
String trimmed = e.trim();
|
||||||
|
if (!trimmed.isEmpty()) {
|
||||||
|
emails.add(trimmed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emails.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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.model.vo.ContestantCountVO;
|
||||||
|
import com.ai.da.model.vo.PageVisitCountVO;
|
||||||
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;
|
||||||
@@ -198,6 +199,19 @@ public class GlobalAwardController {
|
|||||||
return Response.success(globalAwardService.getContestantCount());
|
return Response.success(globalAwardService.getContestantCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/page/visit")
|
||||||
|
@ApiOperation(value = "记录比赛页面访问量", notes = "记录比赛页面的访问量,包含两种统计方式:每次访问/刷新计一次,以及5秒内刷新只计一次")
|
||||||
|
public Response<Void> recordPageVisit(@ApiParam(value = "会话ID,用于5秒内去重判断", required = false) @RequestParam(value = "sessionId", required = false) String sessionId) {
|
||||||
|
globalAwardService.recordPageVisit(sessionId);
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page/visit/count")
|
||||||
|
@ApiOperation(value = "获取比赛页面访问量", notes = "获取比赛页面的两种访问量:rawVisitCount(每次访问/刷新计一次)和 uniqueVisitCount(5秒内刷新只计一次)")
|
||||||
|
public Response<PageVisitCountVO> getPageVisitCount() {
|
||||||
|
return Response.success(globalAwardService.getPageVisitCount());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
23
src/main/java/com/ai/da/model/vo/PageVisitCountVO.java
Normal file
23
src/main/java/com/ai/da/model/vo/PageVisitCountVO.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ai.da.model.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PageVisitCountVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每次访问或刷新都计一次(不去重)
|
||||||
|
*/
|
||||||
|
private Long rawVisitCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5秒内刷新只算一次(去重后的真实访客数)
|
||||||
|
*/
|
||||||
|
private Long uniqueVisitCount;
|
||||||
|
}
|
||||||
@@ -2912,72 +2912,71 @@ public class PythonService {
|
|||||||
|
|
||||||
private PrintToPython resolveDesignSinglePrint(List<DesignSinglePrint> printObject, String partialDesign) {
|
private PrintToPython resolveDesignSinglePrint(List<DesignSinglePrint> printObject, String partialDesign) {
|
||||||
PrintToPython printToPython = new PrintToPython();
|
PrintToPython printToPython = new PrintToPython();
|
||||||
// DesignPythonItemPrint printSingle = new DesignPythonItemPrint();
|
|
||||||
DesignPythonItemPrint printOverall = new DesignPythonItemPrint();
|
DesignPythonItemPrint printOverall = new DesignPythonItemPrint();
|
||||||
// printToPython.setSingle(printSingle);
|
|
||||||
printToPython.setOverall(printOverall);
|
printToPython.setOverall(printOverall);
|
||||||
printToPython.setPartial(StringUtil.isNullOrEmpty(partialDesign) ? null : partialDesign);
|
printToPython.setPartial(StringUtil.isNullOrEmpty(partialDesign) ? null : partialDesign);
|
||||||
if (Objects.isNull(printObject) || printObject.isEmpty()) {
|
if (Objects.isNull(printObject) || printObject.isEmpty()) {
|
||||||
return printToPython;
|
return printToPython;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 没有印花时的参数设置
|
// 1. 先对 printObject 按 priority 排序(升序)
|
||||||
// if (printObject.getIfSingle().equals(Boolean.FALSE) && CollectionUtil.isEmpty(printObject.getPrints())) {
|
List<DesignSinglePrint> sortedPrints = printObject.stream()
|
||||||
// return new DesignPythonItemPrint(new ArrayList<>(), false);
|
.sorted(Comparator.comparingInt(DesignSinglePrint::getPriority))
|
||||||
// }
|
.toList();
|
||||||
// DesignPythonItemPrint print = CopyUtil.copyObject(printObject, DesignPythonItemPrint.class);
|
|
||||||
|
|
||||||
int size = printObject.size();
|
// 2. 分别收集单印和非单印的数据
|
||||||
// 占位符填充数组
|
List<DesignSinglePrint> singlePrints = sortedPrints.stream()
|
||||||
List<List<Float>> locationS = new ArrayList<>(Collections.nCopies(size, null));
|
.filter(DesignSinglePrint::getIfSingle)
|
||||||
List<List<Float>> scaleS = new ArrayList<>(Collections.nCopies(size, null));
|
.toList();
|
||||||
List<Double> angleS = new ArrayList<>(Collections.nCopies(size, null));
|
|
||||||
ArrayList<String> pathsS = new ArrayList<>(Collections.nCopies(size, null));
|
|
||||||
|
|
||||||
List<List<Float>> locationO = new ArrayList<>(Collections.nCopies(size, null));
|
List<DesignSinglePrint> overallPrints = sortedPrints.stream()
|
||||||
List<List<Float>> scaleO = new ArrayList<>(Collections.nCopies(size, null));
|
.filter(p -> !p.getIfSingle())
|
||||||
List<Double> angleO = new ArrayList<>(Collections.nCopies(size, null));
|
.toList();
|
||||||
ArrayList<String> pathsO = new ArrayList<>(Collections.nCopies(size, null));
|
|
||||||
|
|
||||||
// 设置印花的位置、大小、旋转角度
|
// 3. 处理单印数据
|
||||||
// 优先级越大,越靠近顶层,在传输给python的数组中,越靠前
|
if (!singlePrints.isEmpty()) {
|
||||||
// List<DesignSinglePrint> prints = printObject.getPrints();
|
List<List<Float>> locationS = new ArrayList<>();
|
||||||
printObject.forEach(p -> {
|
List<List<Float>> scaleS = new ArrayList<>();
|
||||||
p.getLocation().set(0, p.getLocation().get(0));
|
List<Double> angleS = new ArrayList<>();
|
||||||
p.getLocation().set(1, p.getLocation().get(1));
|
List<String> pathsS = new ArrayList<>();
|
||||||
Integer priority = p.getPriority();
|
|
||||||
setUriToMinioPath(p);
|
for (DesignSinglePrint p : singlePrints) {
|
||||||
// todo 下标越界问题
|
setUriToMinioPath(p);
|
||||||
if (p.getIfSingle()) {
|
locationS.add(p.getLocation());
|
||||||
locationS.set(priority - 1, p.getLocation());
|
scaleS.add(p.getScale());
|
||||||
scaleS.set(priority - 1, p.getScale());
|
angleS.add(p.getAngle());
|
||||||
angleS.set(priority - 1, p.getAngle());
|
pathsS.add(p.getMinIOPath());
|
||||||
pathsS.set(priority - 1, p.getMinIOPath());
|
|
||||||
} else {
|
|
||||||
locationO.set(priority - 1, p.getLocation());
|
|
||||||
scaleO.set(priority - 1, p.getScale());
|
|
||||||
angleO.set(priority - 1, p.getAngle());
|
|
||||||
pathsO.set(priority - 1, p.getMinIOPath());
|
|
||||||
}
|
}
|
||||||
// log.info("本次print打点locations###{}###fileVO{}", p.getLocation(), JSON.toJSONString(fileVO));
|
|
||||||
});
|
|
||||||
/*locationS.removeAll(Collections.singleton(null));
|
|
||||||
scaleS.removeAll(Collections.singleton(null));
|
|
||||||
angleS.removeAll(Collections.singleton(null));
|
|
||||||
pathsS.removeAll(Collections.singleton(null));
|
|
||||||
printSingle.setLocation(locationS);
|
|
||||||
printSingle.setPrint_scale_list(scaleS);
|
|
||||||
printSingle.setPrint_angle_list(angleS);
|
|
||||||
printSingle.setPrint_path_list(pathsS);*/
|
|
||||||
|
|
||||||
locationO.removeAll(Collections.singleton(null));
|
// 注意:如果 printOverall 中需要设置单印数据,请在这里添加相应的 setter
|
||||||
scaleO.removeAll(Collections.singleton(null));
|
// 根据您的原始代码,似乎只设置了 overall(非单印)的数据
|
||||||
angleO.removeAll(Collections.singleton(null));
|
// 如果需要设置单印,请取消下面的注释并添加对应的字段
|
||||||
pathsO.removeAll(Collections.singleton(null));
|
// printOverall.setSingleLocation(locationS);
|
||||||
printOverall.setLocation(locationO);
|
// printOverall.setSingleScale(scaleS);
|
||||||
printOverall.setPrint_scale_list(scaleO);
|
// printOverall.setSingleAngle(angleS);
|
||||||
printOverall.setPrint_angle_list(angleO);
|
// printOverall.setSinglePath(pathsS);
|
||||||
printOverall.setPrint_path_list(pathsO);
|
}
|
||||||
|
|
||||||
|
// 4. 处理非单印数据(整体印花)
|
||||||
|
if (!overallPrints.isEmpty()) {
|
||||||
|
List<List<Float>> locationO = new ArrayList<>();
|
||||||
|
List<List<Float>> scaleO = new ArrayList<>();
|
||||||
|
List<Double> angleO = new ArrayList<>();
|
||||||
|
List<String> pathsO = new ArrayList<>();
|
||||||
|
|
||||||
|
for (DesignSinglePrint p : overallPrints) {
|
||||||
|
setUriToMinioPath(p);
|
||||||
|
locationO.add(p.getLocation());
|
||||||
|
scaleO.add(p.getScale());
|
||||||
|
angleO.add(p.getAngle());
|
||||||
|
pathsO.add(p.getMinIOPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
printOverall.setLocation(locationO);
|
||||||
|
printOverall.setPrint_scale_list(scaleO);
|
||||||
|
printOverall.setPrint_angle_list(angleO);
|
||||||
|
printOverall.setPrint_path_list(pathsO);
|
||||||
|
}
|
||||||
|
|
||||||
return printToPython;
|
return printToPython;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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 com.ai.da.model.vo.ContestantCountVO;
|
||||||
|
import com.ai.da.model.vo.PageVisitCountVO;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -46,6 +47,22 @@ public interface GlobalAwardService {
|
|||||||
* @return 参赛者数量和最大参赛者编号
|
* @return 参赛者数量和最大参赛者编号
|
||||||
*/
|
*/
|
||||||
ContestantCountVO getContestantCount();
|
ContestantCountVO getContestantCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录比赛页面的访问量
|
||||||
|
* <ul>
|
||||||
|
* <li>rawVisitCount: 每次访问或刷新都计一次(不去重)</li>
|
||||||
|
* <li>uniqueVisitCount: 5秒内刷新只算一次(基于会话去重)</li>
|
||||||
|
* </ul>
|
||||||
|
* @param sessionId 会话ID(用于5秒去重判断)
|
||||||
|
*/
|
||||||
|
void recordPageVisit(String sessionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取比赛页面的两种访问量
|
||||||
|
* @return 原始访问量和去重访问量
|
||||||
|
*/
|
||||||
|
PageVisitCountVO getPageVisitCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3383,12 +3383,14 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
Account account = accountMapper.selectById(accountId);
|
Account account = accountMapper.selectById(accountId);
|
||||||
if (!Objects.isNull(account.getValidEndTime())
|
if (!Objects.isNull(account.getValidEndTime())
|
||||||
&& account.getValidEndTime().equals(currentPeriodEnd * 1000)) {
|
&& account.getValidEndTime().equals(currentPeriodEnd * 1000)) {
|
||||||
|
log.info("accountId:{}未更新账号有效期。current validEnd:{}, new validEnd:{}", accountId, account.getValidEndTime(), currentPeriodEnd);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
account.setValidEndTime(currentPeriodEnd * 1000);
|
account.setValidEndTime(currentPeriodEnd * 1000);
|
||||||
accountMapper.updateById(account);
|
accountMapper.updateById(account);
|
||||||
|
log.info("accountId:{} 将账号有效期更新到 {}", accountId, currentPeriodEnd);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -3416,13 +3418,14 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
}
|
}
|
||||||
account.setCredits(BigDecimal.valueOf(productCredits));
|
account.setCredits(BigDecimal.valueOf(productCredits));
|
||||||
accountMapper.updateById(account);
|
accountMapper.updateById(account);
|
||||||
|
log.info("accountId:{},更新用户角色为{},总积分为{}", accountId, account.getSystemUser(), productCredits);
|
||||||
|
|
||||||
CreditsService creditsService = SpringUtils.getBean(CreditsService.class);
|
CreditsService creditsService = SpringUtils.getBean(CreditsService.class);
|
||||||
// 添加积分变更记录(订单续订时的积分变更也需要记录) todo 重置的记录不太准确
|
// 添加积分变更记录(订单续订时的积分变更也需要记录)
|
||||||
creditsService.insertToCreditsDetail(accountId,
|
creditsService.insertToCreditsDetail(accountId,
|
||||||
description + "--Stripe",
|
description + "--Stripe",
|
||||||
String.valueOf(productCredits),
|
String.valueOf(productCredits),
|
||||||
"positive", orderNo);
|
"set", orderNo);
|
||||||
/*CreditsDetail creditsDetail = creditsService.queryDetailByTaskId(orderNo);
|
/*CreditsDetail creditsDetail = creditsService.queryDetailByTaskId(orderNo);
|
||||||
if (Objects.isNull(creditsDetail)) {
|
if (Objects.isNull(creditsDetail)) {
|
||||||
creditsService.insertToCreditsDetail(accountId,
|
creditsService.insertToCreditsDetail(accountId,
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import jakarta.annotation.Resource;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -80,9 +79,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
affiliate.setPromotionMethod(promotionMethod);
|
affiliate.setPromotionMethod(promotionMethod);
|
||||||
baseMapper.insert(affiliate);
|
baseMapper.insert(affiliate);
|
||||||
// 邮件通知审批者
|
// 邮件通知审批者
|
||||||
String merchantEmail = "kimwong@code-create.com.hk";
|
String[] receiverEmail = buildMerchantReceiverEmail();
|
||||||
String developer = "xupei3360@163.com";
|
|
||||||
String[] receiverEmail = {/*merchantEmail,*/ developer};
|
|
||||||
SendEmailUtil.affiliateEmailReminder(receiverEmail, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
SendEmailUtil.affiliateEmailReminder(receiverEmail, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
||||||
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
||||||
}else {
|
}else {
|
||||||
@@ -440,9 +437,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
affiliateEmailParamsDTO.setUnpaidEarnings(String.valueOf(unpaidCommission));
|
affiliateEmailParamsDTO.setUnpaidEarnings(String.valueOf(unpaidCommission));
|
||||||
affiliateEmailParamsDTO.setPaidEarnings(String.valueOf(paidCommission));
|
affiliateEmailParamsDTO.setPaidEarnings(String.valueOf(paidCommission));
|
||||||
|
|
||||||
String merchantEmail = "kimwong@code-create.com.hk";
|
String[] receiverEmail = buildMerchantReceiverEmail();
|
||||||
String developer = "xupei3360@163.com";
|
|
||||||
String[] receiverEmail = {/*merchantEmail,*/ developer};
|
|
||||||
// 邮件通知
|
// 邮件通知
|
||||||
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
|
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
|
||||||
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), affiliateEmailParamsDTO, "summary");
|
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), affiliateEmailParamsDTO, "summary");
|
||||||
@@ -607,4 +602,8 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
coupon.setUnpaidCommission(unpaidCommission);
|
coupon.setUnpaidCommission(unpaidCommission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String[] buildMerchantReceiverEmail() {
|
||||||
|
return SendEmailUtil.buildMerchantReceiverEmail();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
*
|
*
|
||||||
* @param changeEvent 导致积分变更的事件
|
* @param changeEvent 导致积分变更的事件
|
||||||
* @param credits 变更的积分
|
* @param credits 变更的积分
|
||||||
* @param changeType 变更类型 : positive->增 negative->减
|
* @param changeType 变更类型 : positive->增 negative->减 set->重置
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType, String orderNo) {
|
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType, String orderNo) {
|
||||||
@@ -94,9 +94,11 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
if ("positive".equals(changeType)) {
|
if ("positive".equals(changeType)) {
|
||||||
// finalCredits = account.getCredits().add(new BigDecimal(credits));
|
// finalCredits = account.getCredits().add(new BigDecimal(credits));
|
||||||
changeCredits = "+" + credits;
|
changeCredits = "+" + credits;
|
||||||
} else {
|
} else if ("negative".equals(changeType)) {
|
||||||
// finalCredits = account.getCredits().subtract(new BigDecimal(credits));
|
// finalCredits = account.getCredits().subtract(new BigDecimal(credits));
|
||||||
changeCredits = "-" + credits;
|
changeCredits = "-" + credits;
|
||||||
|
} else {
|
||||||
|
changeCredits = credits;
|
||||||
}
|
}
|
||||||
creditsDetail.setAccountId(accountId);
|
creditsDetail.setAccountId(accountId);
|
||||||
creditsDetail.setChangeEvent(changeEvent);
|
creditsDetail.setChangeEvent(changeEvent);
|
||||||
@@ -107,6 +109,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
creditsDetail.setCreateTime(LocalDateTime.now());
|
creditsDetail.setCreateTime(LocalDateTime.now());
|
||||||
|
|
||||||
baseMapper.insert(creditsDetail);
|
baseMapper.insert(creditsDetail);
|
||||||
|
log.info("creditsDetail inserted");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.ai.da.common.response.ResultEnum;
|
|||||||
import com.ai.da.common.utils.DateUtil;
|
import com.ai.da.common.utils.DateUtil;
|
||||||
import com.ai.da.common.utils.MailUtil;
|
import com.ai.da.common.utils.MailUtil;
|
||||||
import com.ai.da.common.utils.RedisUtil;
|
import com.ai.da.common.utils.RedisUtil;
|
||||||
|
import com.ai.da.common.utils.SendEmailUtil;
|
||||||
import com.ai.da.mapper.primary.AccountMapper;
|
import com.ai.da.mapper.primary.AccountMapper;
|
||||||
import com.ai.da.mapper.primary.EmailLogMapper;
|
import com.ai.da.mapper.primary.EmailLogMapper;
|
||||||
import com.ai.da.mapper.primary.EmailTemplateMapper;
|
import com.ai.da.mapper.primary.EmailTemplateMapper;
|
||||||
@@ -585,9 +586,7 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
|
|
||||||
public boolean subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
|
public boolean subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
|
||||||
try {
|
try {
|
||||||
String merchantEmail = "kimwong@code-create.com.hk";
|
List<String> merchantReceiver = buildMerchantReceiverList();
|
||||||
String developer = "xupei3360@163.com";
|
|
||||||
List<String> merchantReceiver = Arrays.asList(/*merchantEmail,*/ developer);
|
|
||||||
|
|
||||||
String merchantSubject = null;
|
String merchantSubject = null;
|
||||||
String merchantTemplate = null;
|
String merchantTemplate = null;
|
||||||
@@ -723,15 +722,13 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
|
|
||||||
private final static String CREDITS_PURCHASE_MERCHANT = "133275_AiDA 积分购买通知-merchant.html";
|
private final static String CREDITS_PURCHASE_MERCHANT = "133275_AiDA 积分购买通知-merchant.html";
|
||||||
public void creditsPurchaseReminder(String username, String quantity, String amount) {
|
public void creditsPurchaseReminder(String username, String quantity, String amount) {
|
||||||
String merchantEmail = "kimwong@code-create.com.hk";
|
|
||||||
String developerEmail = "xupei@code-create.com.hk";
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
// 设置试用订单相关数据
|
// 设置试用订单相关数据
|
||||||
jsonObject.put("username", username);
|
jsonObject.put("username", username);
|
||||||
jsonObject.put("quantity", quantity);
|
jsonObject.put("quantity", quantity);
|
||||||
jsonObject.put("totalFee", amount);
|
jsonObject.put("totalFee", amount);
|
||||||
|
|
||||||
sendEmail(Arrays.asList(/*merchantEmail,*/ developerEmail), jsonObject, CREDITS_PURCHASE_MERCHANT, "New Credit Purchase Order", null, null);
|
sendEmail(buildMerchantReceiverList(), jsonObject, CREDITS_PURCHASE_MERCHANT, "New Credit Purchase Order", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String COMMON_EXCEPTION_REMINDER = "135279_common-exception-reminder.html";
|
private final static String COMMON_EXCEPTION_REMINDER = "135279_common-exception-reminder.html";
|
||||||
@@ -742,6 +739,10 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
|
|
||||||
sendEmail(destination, param, COMMON_EXCEPTION_REMINDER, "AiDA发生异常,请及时处理", null, null);
|
sendEmail(destination, param, COMMON_EXCEPTION_REMINDER, "AiDA发生异常,请及时处理", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> buildMerchantReceiverList() {
|
||||||
|
return Arrays.asList(SendEmailUtil.buildMerchantReceiverEmail());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1553,11 +1553,11 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
if (imagePath != null) {
|
if (imagePath != null) {
|
||||||
requestBuilder.image(finalImagePath1);
|
requestBuilder.image(finalImagePath1);
|
||||||
}
|
}
|
||||||
if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)) {
|
if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)|| useModel.equals(ModelConstants.PRINTBOARD_HIGH_T2I)) {
|
||||||
GenerateImagesRequest.OptimizePromptOptions optimizePromptOptions = new GenerateImagesRequest.OptimizePromptOptions();
|
GenerateImagesRequest.OptimizePromptOptions optimizePromptOptions = new GenerateImagesRequest.OptimizePromptOptions();
|
||||||
optimizePromptOptions.setMode("fast");
|
optimizePromptOptions.setMode("fast");
|
||||||
requestBuilder.optimizePromptOptions(optimizePromptOptions);
|
requestBuilder.optimizePromptOptions(optimizePromptOptions);
|
||||||
//由于PRINTBOARD_HIGH_I2I与PRINTBOARD_ADVANCED_I2I使用模型一致,为了区别积分扣除,PRINTBOARD_HIGH_I2I加入了-fast,但传入模型时需要去掉-fast,用PRINTBOARD_ADVANCED_I2I的常量做替代
|
//由于PRINTBOARD_HIGH_T2I,PRINTBOARD_HIGH_I2I与PRINTBOARD_ADVANCED_I2I使用模型一致,为了区别积分扣除,PRINTBOARD_HIGH_I2I加入了-fast或者-high,但传入模型时需要去掉-fast或者-high,用PRINTBOARD_ADVANCED_I2I的常量做替代
|
||||||
requestBuilder.model(ModelConstants.PRINTBOARD_ADVANCED_I2I);
|
requestBuilder.model(ModelConstants.PRINTBOARD_ADVANCED_I2I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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.model.vo.ContestantCountVO;
|
||||||
|
import com.ai.da.model.vo.PageVisitCountVO;
|
||||||
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;
|
||||||
@@ -619,6 +620,37 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
private String nullSafe(String value) {
|
private String nullSafe(String value) {
|
||||||
return value != null ? value : "N/A";
|
return value != null ? value : "N/A";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String RAW_VISIT_COUNT_KEY = "GLOBAL_AWARD:visit:raw";
|
||||||
|
private static final String UNIQUE_VISIT_SET_KEY = "GLOBAL_AWARD:visit:unique";
|
||||||
|
private static final String SESSION_VISIT_KEY_PREFIX = "GLOBAL_AWARD:visit:session:";
|
||||||
|
private static final long SESSION_DEDUP_SECONDS = 5L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recordPageVisit(String sessionId) {
|
||||||
|
redisUtil.increaseCount(RAW_VISIT_COUNT_KEY);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(sessionId)) {
|
||||||
|
String sessionKey = SESSION_VISIT_KEY_PREFIX + sessionId;
|
||||||
|
if (!redisUtil.hasKey(sessionKey)) {
|
||||||
|
redisUtil.increaseCount(UNIQUE_VISIT_SET_KEY);
|
||||||
|
redisUtil.addToString(sessionKey, "1", SESSION_DEDUP_SECONDS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
redisUtil.increaseCount(UNIQUE_VISIT_SET_KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageVisitCountVO getPageVisitCount() {
|
||||||
|
Long raw = redisUtil.getIncrementCount(RAW_VISIT_COUNT_KEY);
|
||||||
|
Long unique = redisUtil.getIncrementCount(UNIQUE_VISIT_SET_KEY);
|
||||||
|
return PageVisitCountVO.builder()
|
||||||
|
.rawVisitCount(raw != null ? raw : 0L)
|
||||||
|
.uniqueVisitCount(unique != null ? unique : 0L)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -486,7 +486,8 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
emailParamsDTO.setEmail(account.getUserEmail());
|
emailParamsDTO.setEmail(account.getUserEmail());
|
||||||
emailParamsDTO.setCountry(paymentInfo.getCountry());
|
emailParamsDTO.setCountry(paymentInfo.getCountry());
|
||||||
emailParamsDTO.setOrderId(paymentInfo.getId().toString());
|
emailParamsDTO.setOrderId(paymentInfo.getId().toString());
|
||||||
emailParamsDTO.setOrderRef("\"" + orderListLink + paymentInfo.getId().toString() + "\"");
|
// emailParamsDTO.setOrderRef("\"" + orderListLink + paymentInfo.getId().toString() + "\"");
|
||||||
|
emailParamsDTO.setOrderRef("\"" + paymentInfo.getHostedInvoiceUrl() + "\"");
|
||||||
emailParamsDTO.setCreateDate(String.valueOf(paymentInfo.getCreateTime()).replace("T", " "));
|
emailParamsDTO.setCreateDate(String.valueOf(paymentInfo.getCreateTime()).replace("T", " "));
|
||||||
emailParamsDTO.setQuantity(String.valueOf(1));
|
emailParamsDTO.setQuantity(String.valueOf(1));
|
||||||
emailParamsDTO.setTotalFee(paymentInfo.getPayerTotal().toString());
|
emailParamsDTO.setTotalFee(paymentInfo.getPayerTotal().toString());
|
||||||
|
|||||||
@@ -84,24 +84,29 @@ public class StripeSubscriptionServiceImpl implements StripeSubscriptionService
|
|||||||
SubscriptionInfo passedSubscriptionInfo) {
|
SubscriptionInfo passedSubscriptionInfo) {
|
||||||
SubscriptionInfo subscriptionInfo = resolveSubscriptionInfo(subscription, type, orderNo, passedSubscriptionInfo);
|
SubscriptionInfo subscriptionInfo = resolveSubscriptionInfo(subscription, type, orderNo, passedSubscriptionInfo);
|
||||||
if (subscriptionInfo == null) {
|
if (subscriptionInfo == null) {
|
||||||
|
log.info("subscriptionInfo为null,不发送邮件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(subscriptionInfo.getOrderNo());
|
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(subscriptionInfo.getOrderNo());
|
||||||
if (orderByOrderNo == null) {
|
if (orderByOrderNo == null) {
|
||||||
|
log.info("orderByOrderNo为null,不发送邮件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Account account = accountMapper.selectById(subscriptionInfo.getAccountId());
|
Account account = accountMapper.selectById(subscriptionInfo.getAccountId());
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
|
log.info("account为null,不发送邮件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentInfo paymentInfo = resolvePaymentInfo(subscriptionInfo, orderNo, type);
|
PaymentInfo paymentInfo = resolvePaymentInfo(subscriptionInfo, orderNo, type);
|
||||||
if (paymentInfo == null) {
|
if (paymentInfo == null) {
|
||||||
|
log.info("paymentInfo为null,不发送邮件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String resolvedType = resolveEmailType(type, paymentInfo);
|
String resolvedType = resolveEmailType(type, paymentInfo);
|
||||||
if (isEmailAlreadySent(subscriptionInfo, resolvedType, paymentInfo)) {
|
if (isEmailAlreadySent(subscriptionInfo, resolvedType, paymentInfo)) {
|
||||||
|
log.info("邮件已发送,取消重复发送");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,13 +135,15 @@ public class StripeSubscriptionServiceImpl implements StripeSubscriptionService
|
|||||||
// renewal 场景:从 InvoicePaidHandler 直接传入已更新的 SubscriptionInfo,避免事务未提交导致查询不到
|
// renewal 场景:从 InvoicePaidHandler 直接传入已更新的 SubscriptionInfo,避免事务未提交导致查询不到
|
||||||
if (passedInfo != null) {
|
if (passedInfo != null) {
|
||||||
long now = Instant.now().getEpochSecond();
|
long now = Instant.now().getEpochSecond();
|
||||||
// 限制当前时间在订阅区间内,避免处理上个周期内的回调而重复发送邮件
|
boolean inPeriod = now > passedInfo.getCurrentPeriodStart() && now < passedInfo.getCurrentPeriodEnd();
|
||||||
if (now > passedInfo.getCurrentPeriodStart() && now < passedInfo.getCurrentPeriodEnd()
|
// 续订失败的场景,可能订单状态已被更新为past_due
|
||||||
&& "active".equals(passedInfo.getStatus())) {
|
boolean validStatus = "past_due".equals(passedInfo.getStatus()) || "active".equals(passedInfo.getStatus());
|
||||||
|
if (inPeriod && validStatus) {
|
||||||
return passedInfo;
|
return passedInfo;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StringUtil.isNullOrEmpty(orderNo)) {
|
if (!StringUtil.isNullOrEmpty(orderNo)) {
|
||||||
long now = Instant.now().getEpochSecond();
|
long now = Instant.now().getEpochSecond();
|
||||||
List<SubscriptionInfo> infos = subscriptionInfoMapper.selectList(
|
List<SubscriptionInfo> infos = subscriptionInfoMapper.selectList(
|
||||||
@@ -175,7 +182,7 @@ public class StripeSubscriptionServiceImpl implements StripeSubscriptionService
|
|||||||
.orderByDesc("id")
|
.orderByDesc("id")
|
||||||
.last("LIMIT 1");
|
.last("LIMIT 1");
|
||||||
if (!type.contains("fail")) {
|
if (!type.contains("fail")) {
|
||||||
last.in("trade_state", "paid", "COMPLETED");
|
last.in("trade_state", "paid", "COMPLETED", "Refunded");
|
||||||
}
|
}
|
||||||
List<PaymentInfo> infos = paymentInfoMapper.selectList(last);
|
List<PaymentInfo> infos = paymentInfoMapper.selectList(last);
|
||||||
return infos.isEmpty() ? null : infos.getFirst();
|
return infos.isEmpty() ? null : infos.getFirst();
|
||||||
@@ -348,7 +355,9 @@ public class StripeSubscriptionServiceImpl implements StripeSubscriptionService
|
|||||||
params.setEmail(account.getUserEmail());
|
params.setEmail(account.getUserEmail());
|
||||||
params.setCountry(paymentInfo.getCountry());
|
params.setCountry(paymentInfo.getCountry());
|
||||||
params.setOrderId(paymentInfo.getId().toString());
|
params.setOrderId(paymentInfo.getId().toString());
|
||||||
params.setOrderRef("\"" + orderListLink + paymentInfo.getId().toString() + "\"");
|
// params.setOrderRef("\"" + orderListLink + paymentInfo.getId().toString() + "\"");
|
||||||
|
params.setOrderRef("\"" + paymentInfo.getHostedInvoiceUrl() + "\"");
|
||||||
|
|
||||||
params.setCreateDate(String.valueOf(paymentInfo.getCreateTime()).replace("T", " "));
|
params.setCreateDate(String.valueOf(paymentInfo.getCreateTime()).replace("T", " "));
|
||||||
params.setQuantity("1");
|
params.setQuantity("1");
|
||||||
params.setTotalFee(paymentInfo.getPayerTotal() != null ? paymentInfo.getPayerTotal().toString() : "0");
|
params.setTotalFee(paymentInfo.getPayerTotal() != null ? paymentInfo.getPayerTotal().toString() : "0");
|
||||||
|
|||||||
@@ -187,10 +187,13 @@ public class CheckoutSessionCompletedHandler implements StripeEventHandler {
|
|||||||
log.info("[checkout.session.completed] 订阅记录创建完成,orderNo={},subscriptionId={},periodEnd={}",
|
log.info("[checkout.session.completed] 订阅记录创建完成,orderNo={},subscriptionId={},periodEnd={}",
|
||||||
orderNo, subscriptionId, periodEnd);
|
orderNo, subscriptionId, periodEnd);
|
||||||
|
|
||||||
stripeSubscriptionService.sendSubscriptionEmail(null, "new", orderNo, null);
|
boolean sent = stripeSubscriptionService.sendSubscriptionEmail(null, "new", orderNo, subscriptionInfo);
|
||||||
|
|
||||||
log.info("[checkout.session.completed] 邮件通知完成 类型:new");
|
|
||||||
|
|
||||||
|
if (sent) {
|
||||||
|
log.info("[checkout.session.completed] 邮件通知完成 类型:new");
|
||||||
|
} else {
|
||||||
|
log.info("[checkout.session.completed] 邮件通知未完成");
|
||||||
|
}
|
||||||
} catch (StripeException e) {
|
} catch (StripeException e) {
|
||||||
log.error("[checkout.session.completed] 处理订阅记录失败,orderNo={},error={}", orderNo, e.getMessage());
|
log.error("[checkout.session.completed] 处理订阅记录失败,orderNo={},error={}", orderNo, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,10 +96,6 @@ public class CheckoutSessionExpiredHandler implements StripeEventHandler {
|
|||||||
// 首次订阅失败
|
// 首次订阅失败
|
||||||
stripeSubscriptionService.sendFailedNewOrderEmail(orderNo);
|
stripeSubscriptionService.sendFailedNewOrderEmail(orderNo);
|
||||||
log.info("[checkout.session.expired] 首次订阅失败邮件已发送,orderNo={}", orderNo);
|
log.info("[checkout.session.expired] 首次订阅失败邮件已发送,orderNo={}", orderNo);
|
||||||
} else {
|
|
||||||
// 续费失败 todo 续费不走这里吧?
|
|
||||||
stripeSubscriptionService.sendSubscriptionEmail(null, "fail_renewal", subInfoList.getFirst().getOrderNo(), null);
|
|
||||||
log.info("[checkout.session.expired] 续费失败邮件已发送,orderNo={}", orderNo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class InvoicePaidHandler implements StripeEventHandler {
|
|||||||
updateSubscriptionPeriod(invoice, subscriptionInfo);
|
updateSubscriptionPeriod(invoice, subscriptionInfo);
|
||||||
|
|
||||||
// 更新用户积分、账号到期时间,添加积分详细记录
|
// 更新用户积分、账号到期时间,添加积分详细记录
|
||||||
accountService.updateAccountValidity(subscriptionInfo.getAccountId(), invoice.getPeriodEnd());
|
accountService.updateAccountValidity(subscriptionInfo.getAccountId(), subscriptionInfo.getCurrentPeriodEnd());
|
||||||
accountService.updateUserRoleAndCredits(subscriptionInfo.getAccountId(), subscriptionInfo.getOrderNo());
|
accountService.updateUserRoleAndCredits(subscriptionInfo.getAccountId(), subscriptionInfo.getOrderNo());
|
||||||
|
|
||||||
// 发送通知邮件
|
// 发送通知邮件
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class SubscriptionDeletedHandler implements StripeEventHandler {
|
|||||||
|
|
||||||
// 发送取消订阅通知邮件
|
// 发送取消订阅通知邮件
|
||||||
if (subscriptionInfo.getCancelNotified() == 0) {
|
if (subscriptionInfo.getCancelNotified() == 0) {
|
||||||
boolean sent = stripeSubscriptionService.sendSubscriptionEmail(null, "cancel", subscriptionInfo.getOrderNo(), null);
|
boolean sent = stripeSubscriptionService.sendSubscriptionEmail(null, "cancel", subscriptionInfo.getOrderNo(), subscriptionInfo);
|
||||||
if (sent) {
|
if (sent) {
|
||||||
subscriptionInfo.setCancelNotified((byte) 1);
|
subscriptionInfo.setCancelNotified((byte) 1);
|
||||||
|
|
||||||
|
|||||||
@@ -181,4 +181,10 @@ file.upload.max.size.video=104857600
|
|||||||
# 上传任务过期时间(小时)
|
# 上传任务过期时间(小时)
|
||||||
file.upload.task.expiry.hours=24
|
file.upload.task.expiry.hours=24
|
||||||
|
|
||||||
global.award.link=https://aida-global-design-awards.com.hk/contestants?id=
|
global.award.link=https://aida-global-design-awards.com.hk/contestants?id=
|
||||||
|
|
||||||
|
# merchant email receivers (comma-separated, multiple supported)
|
||||||
|
# dev/local: developer.email 不配置,使用默认值 xupei3360@163.com
|
||||||
|
# prod: 两个都配置
|
||||||
|
merchant.email=
|
||||||
|
developer.email=xupei@code-create.com.hk,yizhang@aidlab.hk
|
||||||
@@ -179,4 +179,9 @@ file.upload.max.size.video=104857600
|
|||||||
# 上传任务过期时间(小时)
|
# 上传任务过期时间(小时)
|
||||||
file.upload.task.expiry.hours=24
|
file.upload.task.expiry.hours=24
|
||||||
|
|
||||||
global.award.link=https://aida-global-design-awards.com.hk/contestants?id=
|
global.award.link=https://aida-global-design-awards.com.hk/contestants?id=
|
||||||
|
|
||||||
|
# merchant email receivers (comma-separated, multiple supported)
|
||||||
|
# prod: includes merchant email
|
||||||
|
merchant.email=kimwong@code-create.com.hk
|
||||||
|
developer.email=xupei3360@163.com
|
||||||
@@ -51,47 +51,41 @@
|
|||||||
a.user_email email,
|
a.user_email email,
|
||||||
p.payment_type platform,
|
p.payment_type platform,
|
||||||
p.payer_total,
|
p.payer_total,
|
||||||
p.type,
|
CASE
|
||||||
|
WHEN o.title LIKE '%Subscription' THEN 'Subscription'
|
||||||
|
ELSE 'Credits'
|
||||||
|
END AS type,
|
||||||
p.payment_method,
|
p.payment_method,
|
||||||
p.last4,
|
p.last4,
|
||||||
p.country,
|
p.country,
|
||||||
p.city,
|
p.city,
|
||||||
p.create_time,
|
p.create_time,
|
||||||
CASE
|
CASE
|
||||||
|
WHEN p.trade_state IN ('paid', 'COMPLETED', 'complete', 'liquidated') THEN 'Success'
|
||||||
WHEN p.trade_state IN ( 'paid', 'COMPLETED', 'complete', 'liquidated' ) THEN
|
WHEN p.trade_state IN ('failed', 'expired', 'VOIDED', 'void', 'uncollectible') THEN 'Fail'
|
||||||
'Success'
|
WHEN p.trade_state IN ('Refunded') THEN 'Refunded'
|
||||||
WHEN p.trade_state IN ( 'failed', 'expired', 'VOIDED', 'void', 'uncollectible' ) THEN
|
|
||||||
'Fail'
|
|
||||||
WHEN p.trade_state IN ( 'Refunded' ) THEN
|
|
||||||
'Refunded'
|
|
||||||
ELSE 'Pending'
|
ELSE 'Pending'
|
||||||
END AS status
|
END AS status
|
||||||
FROM
|
FROM t_payment_info p
|
||||||
t_payment_info p
|
LEFT JOIN t_order_info o ON p.order_no = o.order_no
|
||||||
LEFT JOIN
|
LEFT JOIN t_account a ON a.id = o.account_id
|
||||||
t_order_info o ON p.order_no = o.order_no
|
WHERE 1 = 1
|
||||||
LEFT JOIN
|
|
||||||
t_account a ON a.id = o.account_id
|
|
||||||
WHERE
|
|
||||||
1 = 1
|
|
||||||
<if test="paymentType != null and paymentType != ''">
|
<if test="paymentType != null and paymentType != ''">
|
||||||
AND p.payment_type = #{paymentType}
|
AND p.payment_type = #{paymentType}
|
||||||
</if>
|
</if>
|
||||||
<if test="payerTotal != null and payerTotal != ''">
|
<if test="payerTotal != null and payerTotal != ''">
|
||||||
AND p.payer_total = #{payerTotal}
|
AND p.payer_total = #{payerTotal}
|
||||||
</if>
|
</if>
|
||||||
<if test="type != null and type != ''">
|
<!-- 修复1:删除 type 过滤条件,因为 type 是计算字段 -->
|
||||||
AND p.type = #{type}
|
|
||||||
</if>
|
|
||||||
<if test="status != null and status != ''">
|
<if test="status != null and status != ''">
|
||||||
AND
|
AND (
|
||||||
CASE
|
(p.trade_state IN ('paid', 'COMPLETED', 'complete', 'liquidated') AND #{status} = 'Success')
|
||||||
WHEN p.trade_state IN ('paid', 'COMPLETED', 'complete', 'liquidated') THEN 'Success'
|
OR (p.trade_state IN ('failed', 'expired', 'VOIDED', 'void', 'uncollectible') AND #{status} = 'Fail')
|
||||||
WHEN p.trade_state IN ('failed', 'expired', 'VOIDED', 'void', 'uncollectible') THEN 'Fail'
|
OR (p.trade_state IN ('Refunded') AND #{status} = 'Refunded')
|
||||||
WHEN p.trade_state IN ('Refunded') THEN 'Refunded'
|
OR (p.trade_state NOT IN ('paid', 'COMPLETED', 'complete', 'liquidated',
|
||||||
ELSE 'Pending'
|
'failed', 'expired', 'VOIDED', 'void', 'uncollectible', 'Refunded')
|
||||||
END = #{status}
|
AND #{status} = 'Pending')
|
||||||
|
)
|
||||||
</if>
|
</if>
|
||||||
<if test="country != null and country != ''">
|
<if test="country != null and country != ''">
|
||||||
AND p.country = #{country}
|
AND p.country = #{country}
|
||||||
@@ -106,9 +100,8 @@
|
|||||||
AND a.user_name = #{payer}
|
AND a.user_name = #{payer}
|
||||||
</if>
|
</if>
|
||||||
AND p.transaction_id NOT LIKE 'cs_test%'
|
AND p.transaction_id NOT LIKE 'cs_test%'
|
||||||
ORDER BY
|
ORDER BY p.id ${order} <!-- 建议使用白名单校验 -->
|
||||||
p.id ${order}
|
LIMIT #{limit} OFFSET #{offset} <!-- 修复:改为 #{} -->
|
||||||
LIMIT ${limit} OFFSET ${offset}
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="queryPaymentInfoCount" resultType="java.lang.Long">
|
<select id="queryPaymentInfoCount" resultType="java.lang.Long">
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.ai.da.mapper.primary.SubscriptionInfoMapper">
|
<mapper namespace="com.ai.da.mapper.primary.SubscriptionInfoMapper">
|
||||||
<insert id="insertIgnore" parameterType="com.ai.da.mapper.primary.entity.SubscriptionInfo">
|
<insert id="insertIgnore" parameterType="com.ai.da.mapper.primary.entity.SubscriptionInfo"
|
||||||
|
useGeneratedKeys="true" keyProperty="id">
|
||||||
INSERT IGNORE INTO
|
INSERT IGNORE INTO
|
||||||
t_subscription_info (account_id, order_no, subscription_id, type, status, cancel_notified,
|
t_subscription_info (account_id, order_no, subscription_id, type, status, cancel_notified,
|
||||||
next_pay_date, current_period_start, current_period_end, create_time)
|
next_pay_date, current_period_start, current_period_end, create_time)
|
||||||
|
|||||||
Reference in New Issue
Block a user