From 5c66ece467b547f40c482c12c718f1eaf9ecede6 Mon Sep 17 00:00:00 2001 From: xupei Date: Fri, 23 May 2025 17:16:19 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=85=B3=E9=97=AD=E7=BB=AD=E8=AE=A2=E5=89=8D?= =?UTF-8?q?=E4=B8=83=E5=A4=A9=E9=82=AE=E4=BB=B6=E6=8F=90=E9=86=92=202.?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AE=A2=E9=98=85=E9=82=AE=E4=BB=B6=E6=8F=90?= =?UTF-8?q?=E9=86=92=EF=BC=8C=E5=90=91redis=E5=AD=98=E5=82=A8=E5=B7=B2?= =?UTF-8?q?=E5=8F=91=E9=80=81=E7=9A=84=E9=82=AE=E4=BB=B6=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/da/common/constant/CommonConstant.java | 2 + .../com/ai/da/common/task/PaymentTask.java | 5 +- .../com/ai/da/common/utils/RedisUtil.java | 5 +- .../da/service/impl/AffiliateServiceImpl.java | 10 ++-- .../da/service/impl/GenerateServiceImpl.java | 2 +- .../service/impl/PaymentInfoServiceImpl.java | 1 + .../ai/da/service/impl/StripeServiceImpl.java | 55 ++++++++++++------- 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/ai/da/common/constant/CommonConstant.java b/src/main/java/com/ai/da/common/constant/CommonConstant.java index 35ff4504..43c2c99b 100644 --- a/src/main/java/com/ai/da/common/constant/CommonConstant.java +++ b/src/main/java/com/ai/da/common/constant/CommonConstant.java @@ -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; diff --git a/src/main/java/com/ai/da/common/task/PaymentTask.java b/src/main/java/com/ai/da/common/task/PaymentTask.java index 3bf23fad..975e039d 100644 --- a/src/main/java/com/ai/da/common/task/PaymentTask.java +++ b/src/main/java/com/ai/da/common/task/PaymentTask.java @@ -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(); diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index f7b9ea1a..f8f1e6ec 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -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:"; } diff --git a/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java b/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java index ca3b87cc..141b3f54 100644 --- a/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java @@ -343,17 +343,19 @@ public class AffiliateServiceImpl extends ServiceImpl 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 paymentInfos = paymentInfoService.getBaseMapper().selectList(queryWrapper); + log.info("目前,新增使用优惠券的订单数:{}", paymentInfos.size()); // key:推广码, value:用户支付的金额 HashMap codeAmount = new HashMap<>(); diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index b96d04b0..65cab899 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -701,7 +701,7 @@ public class GenerateServiceImpl extends ServiceImpl 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); diff --git a/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java b/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java index d85d3725..fcc7eba5 100644 --- a/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java @@ -310,6 +310,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl qw = new QueryWrapper<>(); + // todo 首次支付失败,没有invoiceId,所以如果这个order之后成功支付后,会有多条paymentInfo 是否需要优化?? qw.eq("transaction_id", charge.getInvoice()); PaymentInfo paymentInfo = baseMapper.selectOne(qw); Charge.PaymentMethodDetails paymentMethodDetails = charge.getPaymentMethodDetails(); diff --git a/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java b/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java index 2c26914b..e9611ca7 100644 --- a/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java @@ -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 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 避免同一个订阅重复发送相同类型的邮件 subId:type + redisUtil.addToSet(key, type, CommonConstant.REDIS_SET_EXPIRE_TIME); return true; }