10 Commits

Author SHA1 Message Date
3273a61066 BUGFIX:印花优先级不从1开始传导致数组越界 2026-05-13 23:57:07 +08:00
ltx
d055331690 豆包模型更新 2026-05-13 20:56:22 +08:00
ltx
0073f910a7 豆包模型更新 2026-05-13 20:55:24 +08:00
6dcbfa025a TASK:Global Award记录访客量 2026-05-13 17:29:16 +08:00
65cde0b8f5 TASK:admin-organization plan优化 2026-04-28 13:11:57 +08:00
b66877425e BUGFIX:为下载flux图片添加重试机制 2026-04-21 17:33:39 +08:00
litianxiang
f53fca9a09 Merge remote-tracking branch 'origin/dev/3.1_release_merge' into release/3.1 2026-04-15 15:07:04 +08:00
litianxiang
d73442d1dd Merge remote-tracking branch 'origin/release/3.1' into release/3.1 2026-04-13 22:05:59 +08:00
litianxiang
c8164cb997 TO PROD 2026-04-13 22:05:31 +08:00
981fc35be4 BUGFIX:design 没有使用printboard中的元素 2026-04-13 18:04:30 +08:00
18 changed files with 216 additions and 82 deletions

View File

@@ -202,7 +202,7 @@ public class MyTaskScheduler {
}
}
// @Scheduled(cron = "0 0 9 * * ?")
@Scheduled(cron = "0 0 9 * * ?")
public void sendTrialOrderExcelToManagements() {
// 获取前一天日期
LocalDate yesterday = LocalDate.now().minusDays(1);

View File

@@ -18,8 +18,8 @@ public class ModelConstants {
// 模型名称常量
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 PRINTBOARD_HIGH_T2I = "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-4-0-250828-high";
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 IMAGEN_MODEL = "imagen-4.0-generate-001";

View File

@@ -34,7 +34,7 @@ public class AccountTask {
accountService.refreshCreditsMonthly();
}
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void getPaidUser() {
// 获取code-create 表中 指定日期之后 订单状态为wc-processing的订单
accountService.extendValidityForCC();

View File

@@ -45,7 +45,7 @@ public class PaymentTask {
@Resource
private PayPalCheckoutService payPalCheckoutService;
// @Scheduled(cron = "0/30 * * * * ?")
@Scheduled(cron = "0/30 * * * * ?")
public void orderConfirmForPaypal() throws SerializeException {
// log.info("PayPal orderConfirm 被执行......");
@@ -97,7 +97,7 @@ public class PaymentTask {
//
}
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void updateAffiliateInfoWithPayment(){
// log.info("佣金计算定时器");
affiliateService.updateAffiliateInfoWithPayment();
@@ -109,7 +109,7 @@ public class PaymentTask {
affiliateService.syncLinkViewCountToDB();
}
// @Scheduled(cron = "0 0 8 28-31 * ?")
@Scheduled(cron = "0 0 8 28-31 * ?")
public void commissionSummaryReminder(){
// 每个月末的最后一天的早上八点执行
LocalDate today = LocalDate.now();

View File

@@ -40,7 +40,7 @@ public class SubscriptionReminderTask {
REMINDER_DAYS_CONFIG.put("year", 14);
}
// @Scheduled(cron = "0 0 9 * * ?")
@Scheduled(cron = "0 0 9 * * ?")
public void subscriptionReminder() {
// 获取所有需要通知的订阅
List<SubscriptionInfo> subscriptionInfos = getDueSubscriptions();
@@ -97,7 +97,7 @@ public class SubscriptionReminderTask {
return subscriptionInfoMapper.selectList(qw);
}
// @Scheduled(cron = "0 0 9 * * ?")
@Scheduled(cron = "0 0 9 * * ?")
public void trialReminder() {
// 今天的 00:00:00 和 23:59:59
LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();

View File

@@ -767,7 +767,7 @@ public class SendEmailUtil {
try {
String merchantEmail = "kimwong@code-create.com.hk";
String developer = "xupei3360@163.com";
String[] receiverEmail = {/*merchantEmail,*/ developer};
String[] receiverEmail = {merchantEmail, developer};
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
@@ -968,7 +968,7 @@ public class SendEmailUtil {
req.setFromEmailAddress(SEND_ADDRESS);
String merchantEmail = "kimwong@code-create.com.hk";
String developerEmail = "xupei@code-create.com.hk";
req.setDestination(new String[]{/*merchantEmail,*/ developerEmail});
req.setDestination(new String[]{merchantEmail, developerEmail});
Template template = new Template();
req.setSubject("New Credit Purchase Order");
template.setTemplateID(CREDITS_PURCHASE_MERCHANT);

View File

@@ -5,6 +5,7 @@ import com.ai.da.model.dto.*;
import com.ai.da.model.dto.ContestantDTO;
import com.ai.da.model.vo.CheckOTPVO;
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.upload.UploadService;
import com.ai.da.service.upload.UploadTask;
@@ -198,6 +199,19 @@ public class GlobalAwardController {
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每次访问/刷新计一次)和 uniqueVisitCount5秒内刷新只计一次")
public Response<PageVisitCountVO> getPageVisitCount() {
return Response.success(globalAwardService.getPageVisitCount());
}
}

View 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;
}

View File

@@ -34,4 +34,8 @@ public class QueryUserConditionsVO extends PageQueryBaseVo {
private Integer systemUser;
private Long subscriptionPlanId;
private Long organizationId;
}

View File

@@ -2912,72 +2912,71 @@ public class PythonService {
private PrintToPython resolveDesignSinglePrint(List<DesignSinglePrint> printObject, String partialDesign) {
PrintToPython printToPython = new PrintToPython();
// DesignPythonItemPrint printSingle = new DesignPythonItemPrint();
DesignPythonItemPrint printOverall = new DesignPythonItemPrint();
// printToPython.setSingle(printSingle);
printToPython.setOverall(printOverall);
printToPython.setPartial(StringUtil.isNullOrEmpty(partialDesign) ? null : partialDesign);
if (Objects.isNull(printObject) || printObject.isEmpty()) {
return printToPython;
}
// 没有印花时的参数设置
// if (printObject.getIfSingle().equals(Boolean.FALSE) && CollectionUtil.isEmpty(printObject.getPrints())) {
// return new DesignPythonItemPrint(new ArrayList<>(), false);
// }
// DesignPythonItemPrint print = CopyUtil.copyObject(printObject, DesignPythonItemPrint.class);
// 1. 先对 printObject 按 priority 排序(升序)
List<DesignSinglePrint> sortedPrints = printObject.stream()
.sorted(Comparator.comparingInt(DesignSinglePrint::getPriority))
.toList();
int size = printObject.size();
// 占位符填充数组
List<List<Float>> locationS = new ArrayList<>(Collections.nCopies(size, null));
List<List<Float>> scaleS = new ArrayList<>(Collections.nCopies(size, null));
List<Double> angleS = new ArrayList<>(Collections.nCopies(size, null));
ArrayList<String> pathsS = new ArrayList<>(Collections.nCopies(size, null));
// 2. 分别收集单印和非单印的数据
List<DesignSinglePrint> singlePrints = sortedPrints.stream()
.filter(DesignSinglePrint::getIfSingle)
.toList();
List<List<Float>> locationO = new ArrayList<>(Collections.nCopies(size, null));
List<List<Float>> scaleO = new ArrayList<>(Collections.nCopies(size, null));
List<Double> angleO = new ArrayList<>(Collections.nCopies(size, null));
ArrayList<String> pathsO = new ArrayList<>(Collections.nCopies(size, null));
List<DesignSinglePrint> overallPrints = sortedPrints.stream()
.filter(p -> !p.getIfSingle())
.toList();
// 设置印花的位置、大小、旋转角度
// 优先级越大越靠近顶层在传输给python的数组中越靠前
// List<DesignSinglePrint> prints = printObject.getPrints();
printObject.forEach(p -> {
p.getLocation().set(0, p.getLocation().get(0));
p.getLocation().set(1, p.getLocation().get(1));
Integer priority = p.getPriority();
setUriToMinioPath(p);
// todo 下标越界问题
if (p.getIfSingle()) {
locationS.set(priority - 1, p.getLocation());
scaleS.set(priority - 1, p.getScale());
angleS.set(priority - 1, p.getAngle());
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());
// 3. 处理单印数据
if (!singlePrints.isEmpty()) {
List<List<Float>> locationS = new ArrayList<>();
List<List<Float>> scaleS = new ArrayList<>();
List<Double> angleS = new ArrayList<>();
List<String> pathsS = new ArrayList<>();
for (DesignSinglePrint p : singlePrints) {
setUriToMinioPath(p);
locationS.add(p.getLocation());
scaleS.add(p.getScale());
angleS.add(p.getAngle());
pathsS.add(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));
scaleO.removeAll(Collections.singleton(null));
angleO.removeAll(Collections.singleton(null));
pathsO.removeAll(Collections.singleton(null));
printOverall.setLocation(locationO);
printOverall.setPrint_scale_list(scaleO);
printOverall.setPrint_angle_list(angleO);
printOverall.setPrint_path_list(pathsO);
// 注意:如果 printOverall 中需要设置单印数据,请在这里添加相应的 setter
// 根据您的原始代码,似乎只设置了 overall非单印的数据
// 如果需要设置单印,请取消下面的注释并添加对应的字段
// printOverall.setSingleLocation(locationS);
// printOverall.setSingleScale(scaleS);
// printOverall.setSingleAngle(angleS);
// printOverall.setSinglePath(pathsS);
}
// 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;
}

View File

@@ -3,6 +3,7 @@ package com.ai.da.service;
import com.ai.da.model.dto.ContestantDTO;
import com.ai.da.model.vo.CheckOTPVO;
import com.ai.da.model.vo.ContestantCountVO;
import com.ai.da.model.vo.PageVisitCountVO;
import org.springframework.web.multipart.MultipartFile;
import java.util.Map;
@@ -46,6 +47,22 @@ public interface GlobalAwardService {
* @return 参赛者数量和最大参赛者编号
*/
ContestantCountVO getContestantCount();
/**
* 记录比赛页面的访问量
* <ul>
* <li>rawVisitCount: 每次访问或刷新都计一次(不去重)</li>
* <li>uniqueVisitCount: 5秒内刷新只算一次基于会话去重</li>
* </ul>
* @param sessionId 会话ID用于5秒去重判断
*/
void recordPageVisit(String sessionId);
/**
* 获取比赛页面的两种访问量
* @return 原始访问量和去重访问量
*/
PageVisitCountVO getPageVisitCount();
}

View File

@@ -82,7 +82,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
// 邮件通知审批者
String merchantEmail = "kimwong@code-create.com.hk";
String developer = "xupei3360@163.com";
String[] receiverEmail = {/*merchantEmail,*/ developer};
String[] receiverEmail = {merchantEmail, developer};
SendEmailUtil.affiliateEmailReminder(receiverEmail, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
}else {
@@ -442,7 +442,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
String merchantEmail = "kimwong@code-create.com.hk";
String developer = "xupei3360@163.com";
String[] receiverEmail = {/*merchantEmail,*/ developer};
String[] receiverEmail = {merchantEmail, developer};
// 邮件通知
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), affiliateEmailParamsDTO, "summary");

View File

@@ -787,6 +787,14 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl<QuestionnaireMappe
queryWrapper.lt("create_date", queryUserConditionsVO.getEndTime());
}
if (!Objects.isNull(queryUserConditionsVO.getSubscriptionPlanId())) {
queryWrapper.eq("subscription_plan_id", queryUserConditionsVO.getSubscriptionPlanId());
}
if (!Objects.isNull(queryUserConditionsVO.getOrganizationId())) {
queryWrapper.eq("organization_id", queryUserConditionsVO.getOrganizationId());
}
// 排序
if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getOrder()) && !StringUtils.isNullOrEmpty(queryUserConditionsVO.getOrderBy())) {
String orderBy = "id";

View File

@@ -587,7 +587,7 @@ public class EmailServiceImpl implements EmailService {
try {
String merchantEmail = "kimwong@code-create.com.hk";
String developer = "xupei3360@163.com";
List<String> merchantReceiver = Arrays.asList(/*merchantEmail,*/ developer);
List<String> merchantReceiver = Arrays.asList(merchantEmail, developer);
String merchantSubject = null;
String merchantTemplate = null;
@@ -731,7 +731,7 @@ public class EmailServiceImpl implements EmailService {
jsonObject.put("quantity", quantity);
jsonObject.put("totalFee", amount);
sendEmail(Arrays.asList(/*merchantEmail,*/ developerEmail), jsonObject, CREDITS_PURCHASE_MERCHANT, "New Credit Purchase Order", null, null);
sendEmail(Arrays.asList(merchantEmail, developerEmail), jsonObject, CREDITS_PURCHASE_MERCHANT, "New Credit Purchase Order", null, null);
}
private final static String COMMON_EXCEPTION_REMINDER = "135279_common-exception-reminder.html";

View File

@@ -1553,11 +1553,11 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
if (imagePath != null) {
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();
optimizePromptOptions.setMode("fast");
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);
}
@@ -3934,11 +3934,48 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
}
public byte[] downloadVideoOrImage(String url) {
try (CloseableHttpClient client = HttpClients.createDefault();
InputStream in = client.execute(new HttpGet(url)).getEntity().getContent()) {
return IOUtils.toByteArray(in);
} catch (IOException e) {
throw new RuntimeException(e);
int maxRetries = 3;
int retryDelayMs = 1000;
IOException lastException = null;
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
return downloadWithTimeout(url, 30000, 60000);
} catch (IOException e) {
lastException = e;
log.warn("下载失败 (尝试 {}/{}): {}", attempt, maxRetries, e.getMessage());
if (attempt < maxRetries) {
try {
Thread.sleep((long) retryDelayMs * attempt); // 递增延迟
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException(ie);
}
}
}
}
throw new RuntimeException("下载失败,已重试 " + maxRetries + "", lastException);
}
private byte[] downloadWithTimeout(String url, int connectTimeout, int socketTimeout) throws IOException {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout)
.setConnectionRequestTimeout(connectTimeout)
.build();
try (CloseableHttpClient client = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.build();
CloseableHttpResponse response = client.execute(new HttpGet(url))) {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
throw new IOException("HTTP Error: " + statusCode);
}
return IOUtils.toByteArray(response.getEntity().getContent());
}
}

View File

@@ -13,6 +13,7 @@ import com.ai.da.model.dto.ContestantDTO;
import com.ai.da.model.dto.PublishSysNotificationDTO;
import com.ai.da.model.vo.CheckOTPVO;
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.MessageCenterService;
import com.alibaba.fastjson.JSON;
@@ -619,6 +620,37 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
private String nullSafe(String value) {
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();
}
}

View File

@@ -2,7 +2,7 @@
#spring.profiles.active=test
#<23><><EFBFBD><EFBFBD>application-prod<6F>ļ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
#spring.profiles.active=prod
spring.profiles.active=prod
#<23><><EFBFBD><EFBFBD>application-dev<65>ļ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
spring.profiles.active=dev
#spring.profiles.active=dev

View File

@@ -27,9 +27,9 @@ paypal.webhook_id=1D107312EX592781K
##### Stripe
# developer
stripe.private-key=sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2
#stripe.private-key=sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2
# dev 端点
stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
#stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
# local 端点
#stripe.webhook-sign-secret=whsec_TJcMSnAkh4uktrNY1M6Iy8XaVze4Rzqm
@@ -43,8 +43,8 @@ stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
#stripe.webhook-sign-secret=whsec_pX0pPMQm85PaUSWnFMEzoccb3MGNkjoL
# kim - live
#stripe.private-key=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
stripe.private-key=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
# prod 端点
#stripe.webhook-sign-secret=whsec_hhGDgdelQRHSg4LmChtQe41crj41eb11
stripe.webhook-sign-secret=whsec_hhGDgdelQRHSg4LmChtQe41crj41eb11
# dev 端点
#stripe.webhook-sign-secret=whsec_cFUtjUOo8wnrIKZmt4GNvt7ZY1bOfrYr