feat: 系统功能更新 - 添加错误统计、数据初始化、订单调度等功能
This commit is contained in:
@@ -15,6 +15,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.example.demo.model.*;
|
||||
import com.example.demo.repository.PaymentRepository;
|
||||
import com.example.demo.repository.MembershipLevelRepository;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
@@ -25,6 +26,8 @@ public class PaymentService {
|
||||
@Autowired private UserService userService;
|
||||
@Autowired private AlipayService alipayService;
|
||||
@Autowired(required = false) private PayPalService payPalService;
|
||||
@Autowired private SystemSettingsService systemSettingsService;
|
||||
@Autowired private MembershipLevelRepository membershipLevelRepository;
|
||||
|
||||
public Payment save(Payment payment) { return paymentRepository.save(payment); }
|
||||
@Transactional(readOnly = true) public Optional<Payment> findById(Long id) { return paymentRepository.findByIdWithUser(id); }
|
||||
@@ -58,11 +61,11 @@ public class PaymentService {
|
||||
payment.setExternalTransactionId(externalTransactionId);
|
||||
Payment savedPayment = paymentRepository.save(payment);
|
||||
|
||||
// 支付成功后创建订单
|
||||
// 支付成功后更新订单状态为已支付
|
||||
try {
|
||||
createOrderForPayment(savedPayment);
|
||||
updateOrderStatusForPayment(savedPayment);
|
||||
} catch (Exception e) {
|
||||
logger.error("支付成功但创建订单失败: paymentId={}, error={}", paymentId, e.getMessage(), e);
|
||||
logger.error("支付成功但更新订单状态失败: paymentId={}, error={}", paymentId, e.getMessage(), e);
|
||||
}
|
||||
|
||||
// 支付成功后增加用户积分
|
||||
@@ -76,61 +79,42 @@ public class PaymentService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 为支付成功的记录创建订单
|
||||
* 支付成功后更新关联订单状态为已支付
|
||||
*/
|
||||
private void createOrderForPayment(Payment payment) {
|
||||
if (payment == null || payment.getUser() == null) {
|
||||
logger.warn("无法创建订单: payment或user为空");
|
||||
private void updateOrderStatusForPayment(Payment payment) {
|
||||
if (payment == null) {
|
||||
logger.warn("无法更新订单状态: payment为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否已经关联了订单
|
||||
if (payment.getOrder() != null) {
|
||||
logger.info("支付记录已关联订单,跳过创建: paymentId={}, orderId={}", payment.getId(), payment.getOrder().getId());
|
||||
Order order = payment.getOrder();
|
||||
if (order == null) {
|
||||
logger.warn("支付记录未关联订单,无法更新状态: paymentId={}", payment.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建订单
|
||||
Order order = new Order();
|
||||
order.setUser(payment.getUser());
|
||||
order.setOrderNumber("ORD" + System.currentTimeMillis() + payment.getId());
|
||||
order.setTotalAmount(payment.getAmount());
|
||||
order.setCurrency(payment.getCurrency() != null ? payment.getCurrency() : "CNY");
|
||||
// 更新订单状态为已支付
|
||||
order.setStatus(OrderStatus.PAID);
|
||||
order.setPaidAt(LocalDateTime.now());
|
||||
order.setOrderType(OrderType.SUBSCRIPTION);
|
||||
order.setNotes(payment.getDescription() != null ? payment.getDescription() : "会员订阅");
|
||||
orderService.updateOrderStatus(order.getId(), OrderStatus.PAID);
|
||||
|
||||
// 根据金额设置订单描述
|
||||
BigDecimal amount = payment.getAmount();
|
||||
if (amount != null) {
|
||||
if (amount.compareTo(new BigDecimal("259.00")) >= 0) {
|
||||
order.setNotes("专业版会员订阅 - " + amount + "元");
|
||||
} else if (amount.compareTo(new BigDecimal("59.00")) >= 0) {
|
||||
order.setNotes("标准版会员订阅 - " + amount + "元");
|
||||
}
|
||||
}
|
||||
|
||||
Order savedOrder = orderService.createOrder(order);
|
||||
|
||||
// 关联支付记录和订单
|
||||
payment.setOrder(savedOrder);
|
||||
paymentRepository.save(payment);
|
||||
|
||||
logger.info("✅ 订单创建成功: orderId={}, orderNumber={}, paymentId={}",
|
||||
savedOrder.getId(), savedOrder.getOrderNumber(), payment.getId());
|
||||
logger.info("✅ 订单状态更新为已支付: orderId={}, orderNumber={}, paymentId={}",
|
||||
order.getId(), order.getOrderNumber(), payment.getId());
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("创建订单失败: paymentId={}, error={}", payment.getId(), e.getMessage(), e);
|
||||
logger.error("更新订单状态失败: paymentId={}, orderId={}, error={}",
|
||||
payment.getId(), order.getId(), e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据支付金额增加用户积分
|
||||
* 标准版(59元) -> 200积分
|
||||
* 专业版(259元) -> 1000积分
|
||||
* 从 system_settings 读取配置的价格来判断套餐类型
|
||||
* 标准版 -> 6000积分
|
||||
* 专业版 -> 12000积分
|
||||
*/
|
||||
private void addPointsForPayment(Payment payment) {
|
||||
if (payment == null || payment.getUser() == null) {
|
||||
@@ -144,29 +128,48 @@ public class PaymentService {
|
||||
return;
|
||||
}
|
||||
|
||||
// 从membership_levels表读取价格和积分(必须从数据库获取,禁止硬编码)
|
||||
MembershipLevel standardLevel = membershipLevelRepository.findByName("standard")
|
||||
.orElseThrow(() -> new IllegalStateException("数据库中缺少standard会员等级配置"));
|
||||
MembershipLevel proLevel = membershipLevelRepository.findByName("professional")
|
||||
.orElseThrow(() -> new IllegalStateException("数据库中缺少professional会员等级配置"));
|
||||
|
||||
int standardPrice = standardLevel.getPrice().intValue();
|
||||
int standardPoints = standardLevel.getPointsBonus();
|
||||
int proPrice = proLevel.getPrice().intValue();
|
||||
int proPoints = proLevel.getPointsBonus();
|
||||
|
||||
logger.info("会员等级价格: 标准版={}CNY/{}积分, 专业版={}CNY/{}积分", standardPrice, standardPoints, proPrice, proPoints);
|
||||
|
||||
// 根据金额计算积分
|
||||
int points = 0;
|
||||
String planName = "";
|
||||
int amountInt = amount.intValue();
|
||||
|
||||
// 专业版订阅 (259元以上) -> 1000积分
|
||||
if (amount.compareTo(new java.math.BigDecimal("259.00")) >= 0) {
|
||||
points = 1000;
|
||||
// 判断套餐类型:先检查专业版(价格更高),再检查标准版
|
||||
// 允许10%的价格浮动范围
|
||||
if (amountInt >= proPrice * 0.9 && amountInt <= proPrice * 1.1) {
|
||||
points = proPoints; // 专业版积分
|
||||
planName = "专业版";
|
||||
}
|
||||
// 标准版订阅 (59-258元) -> 200积分
|
||||
else if (amount.compareTo(new java.math.BigDecimal("59.00")) >= 0) {
|
||||
points = 200;
|
||||
} else if (amountInt >= standardPrice * 0.9 && amountInt <= standardPrice * 1.1) {
|
||||
points = standardPoints; // 标准版积分
|
||||
planName = "标准版";
|
||||
}
|
||||
// 其他金额不增加积分
|
||||
else {
|
||||
logger.info("支付金额不在套餐范围内,不增加积分: amount={}", amount);
|
||||
} else if (amountInt >= proPrice) {
|
||||
// 如果金额大于等于专业版价格,按专业版计算
|
||||
points = proPoints;
|
||||
planName = "专业版";
|
||||
} else if (amountInt >= standardPrice) {
|
||||
// 如果金额大于等于标准版价格,按标准版计算
|
||||
points = standardPoints;
|
||||
planName = "标准版";
|
||||
} else {
|
||||
logger.info("支付金额不在套餐范围内,不增加积分: amount={}, 标准版价格={}, 专业版价格={}", amountInt, standardPrice, proPrice);
|
||||
return;
|
||||
}
|
||||
|
||||
// 增加积分
|
||||
Long userId = payment.getUser().getId();
|
||||
logger.info("开始为用户增加积分: userId={}, points={}, plan={}, paymentId={}", userId, points, planName, payment.getId());
|
||||
logger.info("开始为用户增加积分: userId={}, points={}, plan={}, paymentId={}, amount={}", userId, points, planName, payment.getId(), amountInt);
|
||||
|
||||
userService.addPoints(userId, points);
|
||||
|
||||
@@ -222,14 +225,42 @@ public class PaymentService {
|
||||
User user = null;
|
||||
if (username != null) { try { user = userService.findByUsername(username); } catch (Exception e) {} }
|
||||
if (user == null) { user = userService.findByUsernameOrNull(username != null ? username : "anon"); if (user == null) user = createAnonymousUser(username != null ? username : "anon"); }
|
||||
|
||||
BigDecimal amount = new BigDecimal(amountStr);
|
||||
|
||||
// 先创建待支付订单
|
||||
Order order = new Order();
|
||||
order.setUser(user);
|
||||
order.setOrderNumber("ORD" + System.currentTimeMillis());
|
||||
order.setTotalAmount(amount);
|
||||
order.setCurrency("CNY");
|
||||
order.setStatus(OrderStatus.PENDING); // 待支付状态
|
||||
order.setOrderType(OrderType.SUBSCRIPTION);
|
||||
|
||||
// 根据金额设置订单描述
|
||||
if (amount.compareTo(new BigDecimal("259.00")) >= 0) {
|
||||
order.setDescription("专业版会员订阅 - " + amount + "元");
|
||||
} else if (amount.compareTo(new BigDecimal("59.00")) >= 0) {
|
||||
order.setDescription("标准版会员订阅 - " + amount + "元");
|
||||
} else {
|
||||
order.setDescription("会员订阅 - " + amount + "元");
|
||||
}
|
||||
|
||||
Order savedOrder = orderService.createOrder(order);
|
||||
logger.info("创建待支付订单: orderId={}, orderNumber={}, amount={}", savedOrder.getId(), savedOrder.getOrderNumber(), amount);
|
||||
|
||||
// 创建支付记录并关联订单
|
||||
Payment payment = new Payment();
|
||||
payment.setUser(user);
|
||||
payment.setOrderId(orderId);
|
||||
payment.setAmount(new BigDecimal(amountStr));
|
||||
payment.setAmount(amount);
|
||||
payment.setCurrency("CNY");
|
||||
payment.setPaymentMethod(PaymentMethod.valueOf(method));
|
||||
payment.setStatus(PaymentStatus.PENDING);
|
||||
payment.setCreatedAt(LocalDateTime.now());
|
||||
payment.setOrder(savedOrder); // 关联订单
|
||||
payment.setDescription(order.getDescription());
|
||||
|
||||
return paymentRepository.save(payment);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user