TASK:订阅到期通知或续订通知(暂时关闭邮件发送)

This commit is contained in:
2025-12-03 13:55:52 +08:00
parent fc0867d9b1
commit bd69793a72
3 changed files with 34 additions and 20 deletions

View File

@@ -10,8 +10,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -19,6 +22,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
@Slf4j @Slf4j
@Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class SubscriptionReminderTask { public class SubscriptionReminderTask {
@@ -32,10 +36,11 @@ public class SubscriptionReminderTask {
private static final Map<String, Integer> REMINDER_DAYS_CONFIG = new HashMap<>(); private static final Map<String, Integer> REMINDER_DAYS_CONFIG = new HashMap<>();
static { static {
REMINDER_DAYS_CONFIG.put("monthly", 7); REMINDER_DAYS_CONFIG.put("month", 7);
REMINDER_DAYS_CONFIG.put("yearly", 14); REMINDER_DAYS_CONFIG.put("year", 14);
} }
@Scheduled(cron = "0 0 9 * * ?")
public void subscriptionReminder() { public void subscriptionReminder() {
// 获取所有需要通知的订阅 // 获取所有需要通知的订阅
List<SubscriptionInfo> subscriptionInfos = getDueSubscriptions(); List<SubscriptionInfo> subscriptionInfos = getDueSubscriptions();
@@ -52,7 +57,7 @@ public class SubscriptionReminderTask {
continue; continue;
} }
boolean success = stripeService.sendEmail(subscriptionInfo.getSubscriptionId(), "reminder_subscriber", null); boolean success = stripeService.sendEmail(subscriptionInfo.getSubscriptionId(), emailType, subscriptionInfo.getOrderNo());
if (success) { if (success) {
log.info("提前{}天向用户 {} 发送续订通知邮件,订阅类型: {}", log.info("提前{}天向用户 {} 发送续订通知邮件,订阅类型: {}",
daysBefore, subscriptionInfo.getAccountId(), subscriptionInfo.getType()); daysBefore, subscriptionInfo.getAccountId(), subscriptionInfo.getType());
@@ -78,26 +83,30 @@ public class SubscriptionReminderTask {
LocalDateTime startOfDay = targetDate.toLocalDate().atStartOfDay(); LocalDateTime startOfDay = targetDate.toLocalDate().atStartOfDay();
LocalDateTime endOfDay = targetDate.toLocalDate().atTime(23, 59, 59); LocalDateTime endOfDay = targetDate.toLocalDate().atTime(23, 59, 59);
long startTimestamp = startOfDay.toEpochSecond(ZoneOffset.UTC); // 使用系统默认时区
long endTimestamp = endOfDay.toEpochSecond(ZoneOffset.UTC); ZoneId zoneId = ZoneId.systemDefault();
long startTimestamp = startOfDay.atZone(zoneId).toEpochSecond();
long endTimestamp = endOfDay.atZone(zoneId).toEpochSecond();
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>(); QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
qw.ge("current_period_end", startTimestamp); qw.lambda().ge(SubscriptionInfo::getCurrentPeriodEnd, startTimestamp);
qw.lt("current_period_end", endTimestamp); qw.lambda().lt(SubscriptionInfo::getCurrentPeriodEnd, endTimestamp);
// qw.eq("status", "active"); // qw.eq("status", "active");
qw.eq("subscription_type", subscriptionType); qw.lambda().eq(SubscriptionInfo::getType, subscriptionType);
return subscriptionInfoMapper.selectList(qw); return subscriptionInfoMapper.selectList(qw);
} }
@Scheduled(cron = "0 0 9 * * ?")
public void trialReminder() { public void trialReminder() {
// 今天的 00:00:00 和 23:59:59 // 今天的 00:00:00 和 23:59:59
LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay(); LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
LocalDateTime endOfDay = LocalDateTime.now().toLocalDate().atTime(23, 59, 59); LocalDateTime endOfDay = LocalDateTime.now().toLocalDate().atTime(23, 59, 59);
// 转为时间戳 // 使用系统默认时区
long startTimestamp = startOfDay.toEpochSecond(ZoneOffset.UTC); ZoneId zoneId = ZoneId.systemDefault();
long endTimestamp = endOfDay.toEpochSecond(ZoneOffset.UTC); long startTimestamp = startOfDay.atZone(zoneId).toEpochSecond() * 1000;
long endTimestamp = endOfDay.atZone(zoneId).toEpochSecond() * 1000;
QueryWrapper<Account> queryWrapper = new QueryWrapper<>(); QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().gt(Account::getValidEndTime, startTimestamp) queryWrapper.lambda().gt(Account::getValidEndTime, startTimestamp)

View File

@@ -21,6 +21,7 @@ import org.springframework.util.StringUtils;
import java.util.Base64; import java.util.Base64;
import java.util.Date; import java.util.Date;
import java.util.Objects;
/** /**
* 邮件发送类 * 邮件发送类
@@ -832,7 +833,7 @@ public class SendEmailUtil {
if (language.equals("ENGLISH")) { if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] AiDA Subscription Renewal Reminder"); user.setSubject("[Code-Create] AiDA Subscription Renewal Reminder");
templateUser.setTemplateID(156072L); templateUser.setTemplateID(156072L);
} else if (language.equals("CHINESE")){ } else if (language.equals("CHINESE_SIMPLIFIED")){
user.setSubject("[Code-Create] AiDA续订提醒"); user.setSubject("[Code-Create] AiDA续订提醒");
templateUser.setTemplateID(156073L); templateUser.setTemplateID(156073L);
} else { } else {
@@ -844,7 +845,7 @@ public class SendEmailUtil {
if (language.equals("ENGLISH")) { if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] AiDA account is about to expire"); user.setSubject("[Code-Create] AiDA account is about to expire");
templateUser.setTemplateID(156749L); templateUser.setTemplateID(156749L);
} else if (language.equals("CHINESE")){ } else if (language.equals("CHINESE_SIMPLIFIED")){
user.setSubject("[Code-Create] 您的AiDA账号即将到期"); user.setSubject("[Code-Create] 您的AiDA账号即将到期");
templateUser.setTemplateID(156750L); templateUser.setTemplateID(156750L);
} else { } else {
@@ -856,7 +857,7 @@ public class SendEmailUtil {
if (language.equals("ENGLISH")) { if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] AiDA — Free Trial Ending"); user.setSubject("[Code-Create] AiDA — Free Trial Ending");
templateUser.setTemplateID(156075L); templateUser.setTemplateID(156075L);
} else if (language.equals("CHINESE")){ } else if (language.equals("CHINESE_SIMPLIFIED")){
user.setSubject("[Code-Create] AiDA — 免费试用结束提醒"); user.setSubject("[Code-Create] AiDA — 免费试用结束提醒");
templateUser.setTemplateID(156076L); templateUser.setTemplateID(156076L);
} else { } else {
@@ -874,14 +875,16 @@ public class SendEmailUtil {
templateUser.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO)); templateUser.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
user.setTemplate(templateUser); user.setTemplate(templateUser);
subscriptionEmailParamsDTO.setEndDate("When cancelled"); if (Objects.nonNull(subscriptionEmailParamsDTO)) {
subscriptionEmailParamsDTO.setEndDate("When cancelled");
}
templateMerchant.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO)); templateMerchant.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
merchant.setTemplate(templateMerchant); merchant.setTemplate(templateMerchant);
if (!type.equals("cancel") && !type.equals("fail_new")) { if (!type.equals("cancel") && !type.equals("fail_new")) {
// 返回的resp是一个SendEmailResponse的实例与请求对象对应 // 返回的resp是一个SendEmailResponse的实例与请求对象对应
SendEmailResponse respUser = client.SendEmail(user); // SendEmailResponse respUser = client.SendEmail(user);
log.info("邮件主题:{}发送结果toUser###{}", user.getSubject(), SendEmailResponse.toJsonString(respUser)); log.info("邮件主题:{}发送结果toUser###{}, email:{}", user.getSubject(), /*SendEmailResponse.toJsonString(respUser)*/null, receiverAddress);
} }
if (!type.startsWith("reminder")) { if (!type.startsWith("reminder")) {
SendEmailResponse respMerchant = client.SendEmail(merchant); SendEmailResponse respMerchant = client.SendEmail(merchant);

View File

@@ -20,6 +20,7 @@ import com.ai.da.model.enums.Language;
import com.ai.da.model.vo.CheckCouponsVO; import com.ai.da.model.vo.CheckCouponsVO;
import com.ai.da.service.*; import com.ai.da.service.*;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -1075,7 +1076,7 @@ public class StripeServiceImpl implements StripeService {
String key = RedisUtil.SUBSCRIPTION_SENT_EMAIL_TYPE + subscriptionInfo.getId(); String key = RedisUtil.SUBSCRIPTION_SENT_EMAIL_TYPE + subscriptionInfo.getId();
// 先判断当前订单 这个类型的邮件是否已发送过 // 先判断当前订单 这个类型的邮件是否已发送过
Boolean elementExistsInSet = redisUtil.isElementExistsInSet(key, type); Boolean elementExistsInSet = redisUtil.isElementExistsInSet(key, type);
if (!type.startsWith("reminder") && !type.equals("cancel") && paymentInfo.getNotified() == 1 && elementExistsInSet){ if (/*!type.startsWith("reminder") && */!type.equals("cancel") && paymentInfo.getNotified() == 1 && elementExistsInSet){
// 已经邮件通知过,直接返回 // 已经邮件通知过,直接返回
log.info("不发送邮件原因【type为{}order_no为{},已经进行邮件通知】", type, orderNo); log.info("不发送邮件原因【type为{}order_no为{},已经进行邮件通知】", type, orderNo);
return true; return true;
@@ -1099,9 +1100,10 @@ public class StripeServiceImpl implements StripeService {
emailParamsDTO.setEndOfPrepaidTerm(DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy)); emailParamsDTO.setEndOfPrepaidTerm(DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO, language); setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO, language);
boolean b = SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail()); log.info("SEND EMAIL: type={}, params={}, language={}, receiver={}", type, JSONObject.toJSON(emailParamsDTO), language, account.getUserEmail());
// boolean b = SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
// boolean b = emailService.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail()); // boolean b = emailService.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
if (!b) return false; // if (!b) return false;
// 邮件通知成功后,更新标志 // 邮件通知成功后,更新标志
if (!type.startsWith("reminder") && !type.equals("cancel")){ if (!type.startsWith("reminder") && !type.equals("cancel")){