1.关闭续订前七天邮件提醒

2.优化订阅邮件提醒,向redis存储已发送的邮件类型
This commit is contained in:
2025-05-23 17:16:19 +08:00
parent 3b6b0c7e2c
commit 5c66ece467
7 changed files with 51 additions and 29 deletions

View File

@@ -13,6 +13,8 @@ public class CommonConstant {
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60;
// 单位 秒 一天过期 in redis
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
// 单位 秒 7天过期
public static final Long REDIS_SET_EXPIRE_TIME = 24 * 60 * 60 * 7L;
public static class Numbers{
public static final Integer NUMBER_10 = 10;

View File

@@ -84,8 +84,9 @@ public class PaymentTask {
}*/
}
// !!关闭此定时器,改为提前三天站内信提醒!!
// 提前7天向用户发送提醒邮件,每天早上8点执行
@Scheduled(cron = "0 0 8 * * ?")
// @Scheduled(cron = "0 0 8 * * ?")
public void subscriptionReminder(){
stripeService.subscriptionReminder();
}
@@ -113,7 +114,7 @@ public class PaymentTask {
}
}
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void calcCouponsCommission(){
// log.info("优惠券佣金计算定时器");
affiliateService.calcCouponsCommission();

View File

@@ -84,8 +84,10 @@ public class RedisUtil {
/**
* 将数据放入set缓存
*/
public void addToSet(String key, String value) {
public void addToSet(String key, String value, Long expiresIn) {
redisTemplate.opsForSet().add(key, value);
// 设置过期时间
redisTemplate.expire(key, expiresIn, TimeUnit.SECONDS);
}
/**
@@ -302,4 +304,5 @@ public class RedisUtil {
}
public final static String STRIPE_EXCEPTION_LOG = "StripeException:";
public final static String SUBSCRIPTION_SENT_EMAIL_TYPE = "SubscriptionEmailSentType:";
}

View File

@@ -343,17 +343,19 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
}
public void calcCouponsCommission(){
// id存redis
String lastTime = redisUtil.getFromString(RedisUtil.PAYMENT_INFO_LAST_SCAN_TIME);
log.info("优惠券佣金计算,上次执行时间:{}", lastTime);
String currentTime = LocalDateTime.now().toString();
// 1、查上次更新之后有无使用了优惠券的新订单
QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("trade_state","paid")
.lt("create_time", currentTime)
.isNotNull("promotion_code");
if (!StringUtil.isNullOrEmpty(lastTime)){
queryWrapper.gt("create_time", lastTime)
.lt("create_time", currentTime)
.isNotNull("promotion_code");
queryWrapper.gt("create_time", lastTime);
}
List<PaymentInfo> paymentInfos = paymentInfoService.getBaseMapper().selectList(queryWrapper);
log.info("目前,新增使用优惠券的订单数:{}", paymentInfos.size());
// key:推广码, value:用户支付的金额
HashMap<String, Float> codeAmount = new HashMap<>();

View File

@@ -701,7 +701,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
// todo 取消待优化
uniqueIdList.forEach(uniqueId -> {
// 1、将需要取消的唯一id加入redis以便及时取消生成
redisUtil.addToSet(cancelSetKey, uniqueId);
redisUtil.addToSet(cancelSetKey, uniqueId, CommonConstant.REDIS_SET_EXPIRE_TIME);
/*// 1、确认当前消息是否还在排队中
Boolean exists = redisUtil.isElementExistsInZSet(consumptionOrderKey, uniqueId);

View File

@@ -310,6 +310,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
public PaymentInfo createOrUpdatePaymentInfoForStripe(Charge charge){
Stripe.apiKey = privateKey;
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
// todo 首次支付失败没有invoiceId所以如果这个order之后成功支付后会有多条paymentInfo 是否需要优化??
qw.eq("transaction_id", charge.getInvoice());
PaymentInfo paymentInfo = baseMapper.selectOne(qw);
Charge.PaymentMethodDetails paymentMethodDetails = charge.getPaymentMethodDetails();

View File

@@ -5,6 +5,7 @@ import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.*;
import com.ai.da.common.utils.DateUtil;
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.PaymentInfoMapper;
@@ -67,7 +68,6 @@ public class StripeServiceImpl implements StripeService {
private RefundInfoService refundInfoService;
@Resource
private AccountService accountService;
@Resource
private AccountMapper accountMapper;
@Resource
@@ -76,6 +76,8 @@ public class StripeServiceImpl implements StripeService {
private PaymentInfoMapper paymentInfoMapper;
@Resource
private ProductCouponsMapper productCouponsMapper;
@Resource
private RedisUtil redisUtil;
@Value("${stripe.private-key}")
private String privateKey;
@@ -368,28 +370,31 @@ public class StripeServiceImpl implements StripeService {
// 新增支付成功的信息,返回orderNo表示该回调第一次被记录
PaymentInfo paymentInfo = paymentInfoService.createOrUpdatePaymentInfoForStripe(invoice);
/* 在sendEmail方法中有做判断这里的判断取消
// 当前支付没有被通知时才需要发送通知邮件
if (paymentInfo.getNotified().equals(0)) {
// 更新t_order_info中的total_fee,记录该订单的累计付款金额
orderInfoService.updateTotalFeeByOrderNo(paymentInfo.getOrderNo());
// 邮件通知商家和用户
String billingReason = invoice.getBillingReason();
switch (billingReason) {
case "subscription_create":
response = sendEmail(invoice.getSubscription(), "new", null);
break;
case "subscription_cycle":
response = sendEmail(invoice.getSubscription(), "renewal", null);
break;
case "manual":
boolean b = invoice.getLines().getData().get(0).getDescription().endsWith("Subscription");
if (b) {
// 非自动续订式订阅Stripe不会创建Subscription,所以invoice中不会有subscriptionId
response = sendEmail(null, "new", paymentInfo.getOrderNo());
}
break;
}
}*/
// 更新t_order_info中的total_fee,记录该订单的累计付款金额
orderInfoService.updateTotalFeeByOrderNo(paymentInfo.getOrderNo());
// 邮件通知商家和用户
String billingReason = invoice.getBillingReason();
switch (billingReason) {
case "subscription_create":
response = sendEmail(invoice.getSubscription(), "new", null);
break;
case "subscription_cycle":
response = sendEmail(invoice.getSubscription(), "renewal", null);
break;
case "manual":
boolean b = invoice.getLines().getData().get(0).getDescription().endsWith("Subscription");
if (b) {
// 非自动续订式订阅Stripe不会创建Subscription,所以invoice中不会有subscriptionId
response = sendEmail(null, "new", paymentInfo.getOrderNo());
}
break;
}
} else if (event.getType().equals("invoice.payment_failed")) {
// 更新支付信息
QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
@@ -1011,7 +1016,12 @@ public class StripeServiceImpl implements StripeService {
// 其实这里也可以通过invoiceId查询stripe但是记录在自己的db中可以不用每次都查且方便查看
type = StringUtil.isNullOrEmpty(paymentInfo.getType()) ? "new" : paymentInfo.getType();
}
if (!type.equals("reminder") && !type.equals("cancel") && paymentInfo.getNotified() == 1){
// todo 之后这种改成通过email-log来判断
String key = RedisUtil.SUBSCRIPTION_SENT_EMAIL_TYPE + subscriptionInfo.getId();
// 先判断当前订单 这个类型的邮件是否已发送过
Boolean elementExistsInSet = redisUtil.isElementExistsInSet(key, type);
if (!type.equals("reminder") && !type.equals("cancel") && paymentInfo.getNotified() == 1 && elementExistsInSet){
// 已经邮件通知过,直接返回
log.info("不发送邮件原因【type为{}order_no为{},已经进行邮件通知】", type, orderNo);
return true;
@@ -1044,6 +1054,9 @@ public class StripeServiceImpl implements StripeService {
payment.setUpdateTime(LocalDateTime.now());
paymentInfoMapper.updateById(payment);
}
// 将发成功的邮件类型存入redis 避免同一个订阅重复发送相同类型的邮件 subIdtype
redisUtil.addToSet(key, type, CommonConstant.REDIS_SET_EXPIRE_TIME);
return true;
}