订阅
This commit is contained in:
@@ -1,12 +1,23 @@
|
|||||||
package com.ruoyi.system.util;
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.core.domain.entity.OrderInfo;
|
||||||
|
import com.ruoyi.common.core.domain.entity.ShopUser;
|
||||||
|
import com.ruoyi.system.mapper.OrderInfoMapper;
|
||||||
|
import com.ruoyi.system.service.IOrderInfoService;
|
||||||
import com.ruoyi.system.service.ShopUserService;
|
import com.ruoyi.system.service.ShopUserService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AppleNotificationProcessor {
|
public class AppleNotificationProcessor {
|
||||||
@@ -15,6 +26,10 @@ public class AppleNotificationProcessor {
|
|||||||
private AppleSignedPayloadDecoder payloadDecoder;
|
private AppleSignedPayloadDecoder payloadDecoder;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ShopUserService shopUserService;
|
private ShopUserService shopUserService;
|
||||||
|
@Autowired
|
||||||
|
private OrderInfoMapper orderInfoMapper;
|
||||||
|
@Autowired
|
||||||
|
private IOrderInfoService orderInfoService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 完整的通知处理流程
|
* 完整的通知处理流程
|
||||||
@@ -149,10 +164,159 @@ public class AppleNotificationProcessor {
|
|||||||
RenewalInfo renewalInfo) {
|
RenewalInfo renewalInfo) {
|
||||||
log.info("处理续订事件 - 子类型: {}", notificationInfo.getSubtype());
|
log.info("处理续订事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
if (transactionInfo != null) {
|
if (transactionInfo == null) {
|
||||||
// 找到最近的原始订单数据做校验 ,防止重复校验问题,创建新的订单数据,并调用 shopUserService.updateShopUserVipTime(transactionInfo.getUserId(), "1")
|
log.warn("续订事件中交易信息为空");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String transactionId = transactionInfo.getTransactionId();
|
||||||
|
String originalTransactionId = transactionInfo.getOriginalTransactionId();
|
||||||
|
String productId = transactionInfo.getProductId();
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(transactionId) || StringUtils.isEmpty(originalTransactionId)) {
|
||||||
|
log.error("续订事件中交易ID或原始交易ID为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 检查当前交易ID是否已处理(防止重复处理)
|
||||||
|
OrderInfo existingOrder = orderInfoMapper.selectByTradeNo(transactionId);
|
||||||
|
if (existingOrder != null) {
|
||||||
|
log.warn("交易ID {} 已存在,可能重复处理。订单ID: {}", transactionId, existingOrder.getOrderId());
|
||||||
|
// 如果订单已存在且已支付,直接返回(幂等性处理)
|
||||||
|
if (existingOrder.getPayStatus() != null && existingOrder.getPayStatus() >= 2) {
|
||||||
|
log.info("订单已处理,跳过。订单ID: {}, 交易ID: {}", existingOrder.getOrderId(), transactionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据原始交易ID查找最近的原始订单,获取用户ID
|
||||||
|
OrderInfo queryOrder = new OrderInfo();
|
||||||
|
queryOrder.setCallbackContent(originalTransactionId);
|
||||||
|
queryOrder.setPayType("applePay");
|
||||||
|
List<OrderInfo> originalOrders = orderInfoService.selectOrderInfoList(queryOrder);
|
||||||
|
|
||||||
|
Long userId = null;
|
||||||
|
if (originalOrders != null && !originalOrders.isEmpty()) {
|
||||||
|
// 找到最近的原始订单(按创建时间倒序,取第一个)
|
||||||
|
OrderInfo originalOrder = originalOrders.stream()
|
||||||
|
.filter(order -> order.getUserId() != null)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (originalOrder != null) {
|
||||||
|
userId = originalOrder.getUserId();
|
||||||
|
log.info("从原始订单获取用户ID: {}, 原始交易ID: {}", userId, originalTransactionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
log.error("无法从原始交易ID {} 找到用户ID,无法处理续订", originalTransactionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 根据产品ID确定套餐类型和订单信息
|
||||||
|
String packageType = null;
|
||||||
|
String orderName = null;
|
||||||
|
BigDecimal amount = null;
|
||||||
|
|
||||||
|
if ("com.mingyue.product.month".equals(productId)) {
|
||||||
|
packageType = "1";
|
||||||
|
orderName = "VIP会员包月";
|
||||||
|
amount = new BigDecimal("268.00");
|
||||||
|
} else if ("com.mingyue.product.quarterly".equals(productId)) {
|
||||||
|
packageType = "2";
|
||||||
|
orderName = "VIP会员包季度";
|
||||||
|
amount = new BigDecimal("70.00");
|
||||||
|
} else if ("com.mingyue.product.semiAnnual".equals(productId)) {
|
||||||
|
packageType = "3";
|
||||||
|
orderName = "VIP会员包半年";
|
||||||
|
amount = new BigDecimal("135.00");
|
||||||
|
} else if ("com.mingyue.product.annual".equals(productId)) {
|
||||||
|
packageType = "4";
|
||||||
|
orderName = "VIP会员包年";
|
||||||
|
amount = new BigDecimal("18.00");
|
||||||
|
} else {
|
||||||
|
log.error("未知的产品ID: {}, 用户ID: {}", productId, userId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 创建新的订单记录
|
||||||
|
Date startTime = new Date();
|
||||||
|
Date endTime = calculateEndTime(startTime, packageType);
|
||||||
|
|
||||||
|
OrderInfo newOrder = new OrderInfo();
|
||||||
|
newOrder.setId(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
newOrder.setOrderId(System.currentTimeMillis());
|
||||||
|
newOrder.setUserId(userId);
|
||||||
|
newOrder.setPayType("applePay");
|
||||||
|
newOrder.setPayStatus(2L); // 2-待出货
|
||||||
|
newOrder.setPayTime(DateUtils.getNowDate());
|
||||||
|
newOrder.setStartTime(startTime);
|
||||||
|
newOrder.setEndTime(endTime);
|
||||||
|
newOrder.setTradeNo(transactionId);
|
||||||
|
newOrder.setCallbackContent(transactionId);
|
||||||
|
newOrder.setCallTime(DateUtils.getNowDate());
|
||||||
|
newOrder.setOrderName(orderName);
|
||||||
|
newOrder.setAmount(amount);
|
||||||
|
newOrder.setPackageType(packageType);
|
||||||
|
newOrder.setIdDel(0L);
|
||||||
|
newOrder.setVersion(1L);
|
||||||
|
newOrder.setCreateTime(DateUtils.getNowDate());
|
||||||
|
newOrder.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
|
||||||
|
// 5. 保存订单并更新用户VIP时间
|
||||||
|
try {
|
||||||
|
int insertResult = orderInfoService.insertOrderInfo(newOrder);
|
||||||
|
if (insertResult > 0) {
|
||||||
|
log.info("续订订单创建成功,订单ID: {}, 交易ID: {}, 用户ID: {}",
|
||||||
|
newOrder.getOrderId(), transactionId, userId);
|
||||||
|
|
||||||
|
// 更新用户VIP时间
|
||||||
|
ShopUser updatedUser = shopUserService.updateShopUserVipTime(userId, packageType);
|
||||||
|
if (updatedUser != null && updatedUser.getMsg() == null) {
|
||||||
|
log.info("用户VIP时间更新成功,用户ID: {}, 套餐类型: {}", userId, packageType);
|
||||||
|
} else {
|
||||||
|
String errorMsg = updatedUser != null ? updatedUser.getMsg() : "未知错误";
|
||||||
|
log.error("用户VIP时间更新失败,用户ID: {}, 错误信息: {}", userId, errorMsg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("续订订单创建失败,交易ID: {}, 用户ID: {}", transactionId, userId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理续订事件异常,交易ID: {}, 用户ID: {}, 错误: {}",
|
||||||
|
transactionId, userId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据套餐类型计算结束时间
|
||||||
|
*
|
||||||
|
* @param startTime 开始时间
|
||||||
|
* @param packageType 套餐类型:1-月付, 2-季付, 3-半年付, 4-年付
|
||||||
|
* @return 结束时间
|
||||||
|
*/
|
||||||
|
private Date calculateEndTime(Date startTime, String packageType) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(startTime);
|
||||||
|
|
||||||
|
switch (packageType) {
|
||||||
|
case "1": // 月付
|
||||||
|
calendar.add(Calendar.MONTH, 1);
|
||||||
|
break;
|
||||||
|
case "2": // 季付
|
||||||
|
calendar.add(Calendar.MONTH, 3);
|
||||||
|
break;
|
||||||
|
case "3": // 半年付
|
||||||
|
calendar.add(Calendar.MONTH, 6);
|
||||||
|
break;
|
||||||
|
case "4": // 年付
|
||||||
|
calendar.add(Calendar.YEAR, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
calendar.add(Calendar.MONTH, 1); // 默认1个月
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return calendar.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRenewalFailureEvent(NotificationInfo notificationInfo,
|
private void handleRenewalFailureEvent(NotificationInfo notificationInfo,
|
||||||
|
|||||||
Reference in New Issue
Block a user