feat: 系统功能更新 - 添加错误统计、数据初始化、订单调度等功能

This commit is contained in:
AIGC Developer
2025-12-20 15:24:58 +08:00
parent 0933031b59
commit 5344148a1c
70 changed files with 3649 additions and 688 deletions

View File

@@ -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);
}