feat: 添加任务状态级联触发器,优化支付和做同款功能

主要更新:
- 添加 MySQL 触发器实现 task_status 表到其他表的状态级联
- 移除控制器中的多表状态检查代码
- 完善做同款功能,支持参数传递
- 支付宝 USD 转 CNY 汇率转换
- 修复状态枚举映射问题

注意: 触发器仅在 task_status 更新时触发,部分代码仍直接更新业务表
This commit is contained in:
AIGC Developer
2025-12-08 13:54:02 +08:00
parent 624d560fb4
commit 3c37006ebd
84 changed files with 5325 additions and 1668 deletions

View File

@@ -13,518 +13,242 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.model.Order;
import com.example.demo.model.OrderItem;
import com.example.demo.model.OrderStatus;
import com.example.demo.model.OrderType;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.PaymentStatus;
import com.example.demo.model.User;
import com.example.demo.model.*;
import com.example.demo.repository.PaymentRepository;
@Service
@Transactional
public class PaymentService {
private static final Logger logger = LoggerFactory.getLogger(PaymentService.class);
@Autowired private PaymentRepository paymentRepository;
@Autowired private OrderService orderService;
@Autowired private UserService userService;
@Autowired private AlipayService alipayService;
@Autowired(required = false) private PayPalService payPalService;
@Autowired
private PaymentRepository paymentRepository;
public Payment save(Payment payment) { return paymentRepository.save(payment); }
@Transactional(readOnly = true) public Optional<Payment> findById(Long id) { return paymentRepository.findByIdWithUser(id); }
@Transactional(readOnly = true) public Optional<Payment> findByOrderId(String orderId) { return paymentRepository.findByOrderId(orderId); }
@Transactional(readOnly = true) public Optional<Payment> findByExternalTransactionId(String id) { return paymentRepository.findByExternalTransactionId(id); }
@Transactional(readOnly = true) public List<Payment> findByUserId(Long userId) { return paymentRepository.findByUserIdOrderByCreatedAtDesc(userId); }
@Transactional(readOnly = true) public List<Payment> findAll() { return paymentRepository.findAll(); }
@Transactional(readOnly = true) public List<Payment> findByStatus(PaymentStatus status) { return paymentRepository.findByStatus(status); }
@Transactional(readOnly = true) public long countByUserId(Long userId) { return paymentRepository.countByUserId(userId); }
@Transactional(readOnly = true) public long countByStatus(PaymentStatus status) { return paymentRepository.countByStatus(status); }
@Transactional(readOnly = true) public long countByUserIdAndStatus(Long userId, PaymentStatus status) { return paymentRepository.countByUserIdAndStatus(userId, status); }
@Autowired
private OrderService orderService;
@Autowired
private UserService userService;
@Autowired
private AlipayService alipayService;
@Autowired(required = false)
private PayPalService payPalService;
/**
* 保存支付记录
*/
public Payment save(Payment payment) {
try {
Payment savedPayment = paymentRepository.save(payment);
logger.info("支付记录保存成功支付ID{}", savedPayment.getId());
return savedPayment;
} catch (Exception e) {
logger.error("保存支付记录失败:", e);
throw new RuntimeException("保存支付记录失败:" + e.getMessage());
}
}
/**
* 根据ID查找支付记录包含User信息避免LazyInitializationException
*/
@Transactional(readOnly = true)
public Optional<Payment> findById(Long id) {
return paymentRepository.findByIdWithUser(id);
}
/**
* 根据订单ID查找支付记录
*/
@Transactional(readOnly = true)
public Optional<Payment> findByOrderId(String orderId) {
return paymentRepository.findByOrderId(orderId);
}
/**
* 根据外部交易ID查找支付记录
*/
@Transactional(readOnly = true)
public Optional<Payment> findByExternalTransactionId(String externalTransactionId) {
return paymentRepository.findByExternalTransactionId(externalTransactionId);
}
/**
* 根据用户ID查找支付记录
*/
@Transactional(readOnly = true)
public List<Payment> findByUserId(Long userId) {
return paymentRepository.findByUserIdOrderByCreatedAtDesc(userId);
}
/**
* 查找所有支付记录
*/
@Transactional(readOnly = true)
public List<Payment> findAll() {
return paymentRepository.findAll();
}
/**
* 根据状态查找支付记录
*/
@Transactional(readOnly = true)
public List<Payment> findByStatus(PaymentStatus status) {
return paymentRepository.findByStatus(status);
}
/**
* 更新支付状态
*/
public Payment updatePaymentStatus(Long paymentId, PaymentStatus newStatus) {
try {
Payment payment = paymentRepository.findById(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在:" + paymentId));
PaymentStatus oldStatus = payment.getStatus();
payment.setStatus(newStatus);
if (newStatus == PaymentStatus.SUCCESS) {
payment.setPaidAt(LocalDateTime.now());
// 更新关联订单状态
if (payment.getOrder() != null) {
orderService.confirmPayment(payment.getOrder().getId(), payment.getExternalTransactionId());
}
}
Payment updatedPayment = paymentRepository.save(payment);
logger.info("支付状态更新成功支付ID{},状态:{} -> {}",
paymentId, oldStatus, newStatus);
return updatedPayment;
} catch (Exception e) {
logger.error("更新支付状态失败:", e);
throw new RuntimeException("更新支付状态失败:" + e.getMessage());
}
Payment payment = paymentRepository.findById(paymentId).orElseThrow(() -> new RuntimeException("Not found"));
payment.setStatus(newStatus);
if (newStatus == PaymentStatus.SUCCESS) payment.setPaidAt(LocalDateTime.now());
return paymentRepository.save(payment);
}
/**
* 确认支付成功
*/
public Payment confirmPaymentSuccess(Long paymentId, String externalTransactionId) {
try {
Payment payment = paymentRepository.findById(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在:" + paymentId));
payment.setStatus(PaymentStatus.SUCCESS);
payment.setPaidAt(LocalDateTime.now());
payment.setExternalTransactionId(externalTransactionId);
Payment confirmedPayment = paymentRepository.save(payment);
// 更新关联订单状态
if (payment.getOrder() != null) {
orderService.confirmPayment(payment.getOrder().getId(), externalTransactionId);
} else {
// 如果没有关联订单,自动创建一个订单
createOrderFromPayment(confirmedPayment);
}
// 根据支付金额增加积分
addPointsForPayment(confirmedPayment);
logger.info("支付确认成功支付ID{}外部交易ID{}", paymentId, externalTransactionId);
return confirmedPayment;
} catch (Exception e) {
logger.error("确认支付成功失败:", e);
throw new RuntimeException("确认支付成功失败:" + e.getMessage());
Payment payment = paymentRepository.findById(paymentId).orElseThrow(() -> new RuntimeException("Not found"));
// 检查是否已经处理过(防止重复增加积分和重复创建订单)
if (payment.getStatus() == PaymentStatus.SUCCESS) {
logger.info("支付记录已经是成功状态,跳过重复处理: paymentId={}", paymentId);
return payment;
}
}
/**
* 确认支付失败
*/
public Payment confirmPaymentFailure(Long paymentId, String failureReason) {
payment.setStatus(PaymentStatus.SUCCESS);
payment.setPaidAt(LocalDateTime.now());
payment.setExternalTransactionId(externalTransactionId);
Payment savedPayment = paymentRepository.save(payment);
// 支付成功后创建订单
try {
Payment payment = paymentRepository.findById(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在:" + paymentId));
payment.setStatus(PaymentStatus.FAILED);
if (failureReason != null && !failureReason.isEmpty()) {
payment.setDescription((payment.getDescription() != null ? payment.getDescription() + "\n" : "") +
"失败原因:" + failureReason);
}
Payment failedPayment = paymentRepository.save(payment);
logger.info("支付确认失败支付ID{},失败原因:{}", paymentId, failureReason);
return failedPayment;
createOrderForPayment(savedPayment);
} catch (Exception e) {
logger.error("确认支付失败失败:", e);
throw new RuntimeException("确认支付失败失败:" + e.getMessage());
logger.error("支付成功但创建订单失败: paymentId={}, error={}", paymentId, e.getMessage(), e);
}
}
/**
* 创建订单支付
*/
public Payment createOrderPayment(Order order, PaymentMethod paymentMethod) {
// 支付成功后增加用户积分
try {
Payment payment = new Payment();
payment.setOrderId(order.getOrderNumber());
payment.setAmount(order.getTotalAmount());
payment.setCurrency(order.getCurrency());
payment.setPaymentMethod(paymentMethod);
payment.setDescription("订单支付 - " + order.getOrderNumber());
payment.setUser(order.getUser());
payment.setOrder(order);
payment.setStatus(PaymentStatus.PENDING);
Payment savedPayment = paymentRepository.save(payment);
logger.info("订单支付创建成功,订单号:{}支付ID{}", order.getOrderNumber(), savedPayment.getId());
return savedPayment;
addPointsForPayment(savedPayment);
} catch (Exception e) {
logger.error("创建订单支付失败:", e);
throw new RuntimeException("创建订单支付失败:" + e.getMessage());
logger.error("支付成功但增加积分失败: paymentId={}, error={}", paymentId, e.getMessage(), e);
}
return savedPayment;
}
/**
* 统计支付记录数量
* 为支付成功的记录创建订单
*/
@Transactional(readOnly = true)
public long countByUserId(Long userId) {
return paymentRepository.countByUserId(userId);
}
/**
* 统计指定状态的支付记录数量
*/
@Transactional(readOnly = true)
public long countByStatus(PaymentStatus status) {
return paymentRepository.countByStatus(status);
}
/**
* 统计用户指定状态的支付记录数量
*/
@Transactional(readOnly = true)
public long countByUserIdAndStatus(Long userId, PaymentStatus status) {
return paymentRepository.countByUserIdAndStatus(userId, status);
}
/**
* 删除支付记录
*/
public void deletePayment(Long paymentId) {
try {
Payment payment = paymentRepository.findById(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在:" + paymentId));
// 只有失败的支付记录才能删除
if (payment.getStatus() != PaymentStatus.FAILED) {
throw new RuntimeException("只有失败的支付记录才能删除");
}
paymentRepository.delete(payment);
logger.info("支付记录删除成功支付ID{}", paymentId);
} catch (Exception e) {
logger.error("删除支付记录失败:", e);
throw new RuntimeException("删除支付记录失败:" + e.getMessage());
private void createOrderForPayment(Payment payment) {
if (payment == null || payment.getUser() == null) {
logger.warn("无法创建订单: payment或user为空");
return;
}
}
/**
* 根据用户名查找支付记录
*/
@Transactional(readOnly = true)
public List<Payment> findByUsername(String username) {
try {
logger.info("PaymentService: 开始查找用户 {} 的支付记录", username);
// 先查找用户
User user = userService.findByUsername(username);
if (user == null) {
logger.error("PaymentService: 用户 {} 不存在", username);
throw new RuntimeException("用户不存在: " + username);
}
logger.info("PaymentService: 找到用户 {}, ID: {}", username, user.getId());
// 查找支付记录
List<Payment> payments = paymentRepository.findByUserIdOrderByCreatedAtDesc(user.getId());
logger.info("PaymentService: 用户 {} 的支付记录数量: {}", username, payments.size());
return payments;
} catch (Exception e) {
logger.error("PaymentService: 根据用户名查找支付记录失败,用户名: {}, 错误: {}", username, e.getMessage(), e);
throw new RuntimeException("查找支付记录失败:" + e.getMessage());
// 检查是否已经关联了订单
if (payment.getOrder() != null) {
logger.info("支付记录已关联订单,跳过创建: paymentId={}, orderId={}", payment.getId(), payment.getOrder().getId());
return;
}
}
/**
* 创建支付
*/
public Payment createPayment(String username, String orderId, String amountStr, String method) {
try {
logger.info("创建支付 - 用户名: '{}', 订单ID: {}, 金额: {}, 支付方式: {}", username, orderId, amountStr, method);
User user;
try {
logger.info("PaymentService - 尝试查找用户: '{}'", username);
user = userService.findByUsername(username);
logger.info("PaymentService - 用户查找结果: {}", user != null ? "找到用户 '" + user.getUsername() + "'" : "未找到用户");
} catch (Exception e) {
logger.error("PaymentService - 用户查找异常: {}", username, e);
// 如果是匿名用户,创建一个临时用户记录
if (username.startsWith("anonymous_")) {
user = createAnonymousUser(username);
} else {
throw new RuntimeException("用户不存在: " + username);
}
}
logger.info("找到用户: {}", user.getUsername());
BigDecimal amount = new BigDecimal(amountStr);
PaymentMethod paymentMethod = PaymentMethod.valueOf(method);
logger.info("金额: {}, 支付方式: {}", amount, paymentMethod);
Payment payment = new Payment();
payment.setUser(user);
payment.setOrderId(orderId);
payment.setAmount(amount);
payment.setCurrency("CNY"); // 设置默认货币为人民币
payment.setPaymentMethod(paymentMethod);
payment.setStatus(PaymentStatus.PENDING);
payment.setCreatedAt(LocalDateTime.now());
Payment savedPayment = save(payment);
logger.info("支付记录创建成功: {}", savedPayment.getId());
// 根据支付方式调用相应的支付服务
if (paymentMethod == PaymentMethod.ALIPAY) {
try {
Map<String, Object> paymentResult = alipayService.createPayment(savedPayment);
if (paymentResult.containsKey("qrCode")) {
savedPayment.setPaymentUrl(paymentResult.get("qrCode").toString());
}
save(savedPayment);
logger.info("支付宝二维码生成成功: {}", paymentResult.get("qrCode"));
} catch (Exception e) {
logger.error("调用支付宝支付接口失败:", e);
// 不抛出异常,让前端处理
}
} else if (paymentMethod == PaymentMethod.PAYPAL) {
try {
if (payPalService == null) {
throw new RuntimeException("PayPal服务未配置");
}
Map<String, Object> paymentResult = payPalService.createPayment(savedPayment);
if (paymentResult.containsKey("paymentUrl")) {
savedPayment.setPaymentUrl(paymentResult.get("paymentUrl").toString());
}
if (paymentResult.containsKey("paypalPaymentId")) {
savedPayment.setExternalTransactionId(paymentResult.get("paypalPaymentId").toString());
}
save(savedPayment);
logger.info("PayPal支付链接生成成功: {}", paymentResult.get("paymentUrl"));
} catch (Exception e) {
logger.error("调用PayPal支付接口失败", e);
throw new RuntimeException("创建PayPal支付失败: " + e.getMessage());
}
}
return savedPayment;
} catch (Exception e) {
logger.error("创建支付失败:", e);
throw new RuntimeException("创建支付失败:" + e.getMessage());
}
}
/**
* 创建匿名用户
*/
private User createAnonymousUser(String username) {
try {
User user = new User();
user.setUsername(username);
user.setEmail(username + "@anonymous.com");
user.setPasswordHash("anonymous");
user.setRole("ROLE_USER");
return userService.save(user);
} catch (Exception e) {
logger.error("创建匿名用户失败:", e);
throw new RuntimeException("创建匿名用户失败:" + e.getMessage());
}
}
/**
* 获取用户支付统计
*/
@Transactional(readOnly = true)
public Map<String, Object> getUserPaymentStats(String username) {
try {
User user = userService.findByUsername(username);
if (user == null) {
throw new RuntimeException("用户不存在");
}
Long userId = user.getId();
Map<String, Object> stats = new HashMap<>();
stats.put("totalPayments", paymentRepository.countByUserId(userId));
stats.put("successfulPayments", paymentRepository.countByUserIdAndStatus(userId, PaymentStatus.SUCCESS));
stats.put("pendingPayments", paymentRepository.countByUserIdAndStatus(userId, PaymentStatus.PENDING));
stats.put("failedPayments", paymentRepository.countByUserIdAndStatus(userId, PaymentStatus.FAILED));
stats.put("cancelledPayments", paymentRepository.countByUserIdAndStatus(userId, PaymentStatus.CANCELLED));
return stats;
} catch (Exception e) {
logger.error("获取用户支付统计失败:", e);
throw new RuntimeException("获取支付统计失败:" + e.getMessage());
}
}
/**
* 根据支付信息增加积分
*/
private void addPointsForPayment(Payment payment) {
try {
BigDecimal amount = payment.getAmount();
String description = payment.getDescription() != null ? payment.getDescription() : "";
Integer pointsToAdd = 0;
// 优先从描述中识别套餐类型
if (description.contains("标准版") || description.contains("standard")) {
// 标准版订阅 - 200积分
pointsToAdd = 200;
logger.info("识别到标准版订阅,奖励 200 积分");
} else if (description.contains("专业版") || description.contains("premium")) {
// 专业版订阅 - 1000积分
pointsToAdd = 1000;
logger.info("识别到专业版订阅,奖励 1000 积分");
} else {
// 如果描述中没有套餐信息,根据金额判断
// 标准版订阅 (59-258元) - 200积分
if (amount.compareTo(new BigDecimal("59.00")) >= 0 && amount.compareTo(new BigDecimal("259.00")) < 0) {
pointsToAdd = 200;
logger.info("根据金额 {} 判断为标准版订阅,奖励 200 积分", amount);
}
// 专业版订阅 (259元以上) - 1000积分
else if (amount.compareTo(new BigDecimal("259.00")) >= 0) {
pointsToAdd = 1000;
logger.info("根据金额 {} 判断为专业版订阅,奖励 1000 积分", amount);
} else {
logger.warn("支付金额 {} 不在已知套餐范围内,不增加积分", amount);
}
}
if (pointsToAdd > 0) {
userService.addPoints(payment.getUser().getId(), pointsToAdd);
logger.info("✅ 用户 {} 支付 {} 元,成功获得 {} 积分",
payment.getUser().getUsername(), amount, pointsToAdd);
} else {
// 如果金额不在套餐范围内给予基础积分1元=1积分
// 这样可以避免用户支付后没有任何积分的情况
int basePoints = amount.intValue(); // 1元=1积分
if (basePoints > 0) {
userService.addPoints(payment.getUser().getId(), basePoints);
logger.info("✅ 用户 {} 支付 {} 元(非套餐金额),获得基础积分 {} 积分按1元=1积分计算",
payment.getUser().getUsername(), amount, basePoints);
} else {
logger.warn("⚠️ 用户 {} 支付 {} 元,金额过小未获得积分(描述: {}",
payment.getUser().getUsername(), amount, description);
}
}
} catch (Exception e) {
logger.error("❌ 增加积分失败:", e);
// 不抛出异常,避免影响支付流程
}
}
/**
* 从支付记录自动创建订单
*/
private void createOrderFromPayment(Payment payment) {
try {
// 生成订单号
String orderNumber = "ORD" + System.currentTimeMillis();
// 创建订单
Order order = new Order();
order.setUser(payment.getUser());
order.setOrderNumber(orderNumber);
order.setOrderNumber("ORD" + System.currentTimeMillis() + payment.getId());
order.setTotalAmount(payment.getAmount());
order.setCurrency("CNY");
order.setStatus(OrderStatus.PAID); // 支付成功,订单状态为已支付
order.setOrderType(OrderType.PAYMENT); // 订单类型为支付订单
order.setCreatedAt(LocalDateTime.now());
order.setUpdatedAt(LocalDateTime.now());
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() : "会员订阅");
// 保存订单
Order savedOrder = orderService.save(order);
// 根据金额设置订单描述
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 + "");
}
}
// 创建订单项
OrderItem orderItem = new OrderItem();
orderItem.setOrder(savedOrder);
orderItem.setProductName("支付服务 - " + payment.getPaymentMethod().name());
orderItem.setProductDescription("通过" + payment.getPaymentMethod().name() + "完成的支付服务");
orderItem.setQuantity(1);
orderItem.setUnitPrice(payment.getAmount());
orderItem.setSubtotal(payment.getAmount());
Order savedOrder = orderService.createOrder(order);
// 保存订单
orderService.saveOrderItem(orderItem);
// 更新支付记录,关联到新创建的订单
// 关联支付记录和订单
payment.setOrder(savedOrder);
paymentRepository.save(payment);
logger.info("从支付记录自动创建订单成功支付ID{}订单ID{},订单号:{}",
payment.getId(), savedOrder.getId(), orderNumber);
logger.info("✅ 订单创建成功: orderId={}, orderNumber={}, paymentId={}",
savedOrder.getId(), savedOrder.getOrderNumber(), payment.getId());
} catch (Exception e) {
logger.error("从支付记录创建订单失败", e);
throw new RuntimeException("创建订单失败:" + e.getMessage());
logger.error("创建订单失败: paymentId={}, error={}", payment.getId(), e.getMessage(), e);
throw e;
}
}
/**
* 根据支付金额增加用户积分
* 标准版(59元) -> 200积分
* 专业版(259元) -> 1000积分
*/
private void addPointsForPayment(Payment payment) {
if (payment == null || payment.getUser() == null) {
logger.warn("无法增加积分: payment或user为空");
return;
}
java.math.BigDecimal amount = payment.getAmount();
if (amount == null) {
logger.warn("无法增加积分: 支付金额为空, paymentId={}", payment.getId());
return;
}
// 根据金额计算积分
int points = 0;
String planName = "";
// 专业版订阅 (259元以上) -> 1000积分
if (amount.compareTo(new java.math.BigDecimal("259.00")) >= 0) {
points = 1000;
planName = "专业版";
}
// 标准版订阅 (59-258元) -> 200积分
else if (amount.compareTo(new java.math.BigDecimal("59.00")) >= 0) {
points = 200;
planName = "标准版";
}
// 其他金额不增加积分
else {
logger.info("支付金额不在套餐范围内,不增加积分: amount={}", amount);
return;
}
// 增加积分
Long userId = payment.getUser().getId();
logger.info("开始为用户增加积分: userId={}, points={}, plan={}, paymentId={}", userId, points, planName, payment.getId());
userService.addPoints(userId, points);
logger.info("✅ 积分增加成功: userId={}, addedPoints={}, plan={}", userId, points, planName);
}
public Payment confirmPaymentFailure(Long paymentId, String failureReason) {
Payment payment = paymentRepository.findById(paymentId).orElseThrow(() -> new RuntimeException("Not found"));
payment.setStatus(PaymentStatus.FAILED);
return paymentRepository.save(payment);
}
public Payment createOrderPayment(Order order, PaymentMethod paymentMethod) {
Payment payment = new Payment();
payment.setOrderId(order.getOrderNumber());
payment.setAmount(order.getTotalAmount());
payment.setCurrency(order.getCurrency());
payment.setPaymentMethod(paymentMethod);
payment.setUser(order.getUser());
payment.setOrder(order);
payment.setStatus(PaymentStatus.PENDING);
return paymentRepository.save(payment);
}
public void deletePayment(Long paymentId) {
Payment payment = paymentRepository.findById(paymentId).orElseThrow(() -> new RuntimeException("Not found"));
paymentRepository.delete(payment);
}
@Transactional(readOnly = true)
public List<Payment> findByUsername(String username) {
User user = userService.findByUsername(username);
if (user == null) throw new RuntimeException("User not found");
return paymentRepository.findByUserIdOrderByCreatedAtDesc(user.getId());
}
@Transactional
public Payment createPayment(String username, String orderId, String amountStr, String method) {
// 检查是否已存在相同 orderId 的支付记录
Optional<Payment> existing = paymentRepository.findByOrderId(orderId);
if (existing.isPresent()) {
Payment existingPayment = existing.get();
// 如果已存在且状态是 PENDING直接返回
if (existingPayment.getStatus() == PaymentStatus.PENDING) {
logger.info("复用已存在的PENDING支付记录: orderId={}, paymentId={}", orderId, existingPayment.getId());
return existingPayment;
}
// 如果是其他状态,生成新的 orderId
orderId = orderId + "_" + System.currentTimeMillis();
logger.info("已存在相同orderId但状态为{}生成新orderId: {}", existingPayment.getStatus(), orderId);
}
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"); }
Payment payment = new Payment();
payment.setUser(user);
payment.setOrderId(orderId);
payment.setAmount(new BigDecimal(amountStr));
payment.setCurrency("CNY");
payment.setPaymentMethod(PaymentMethod.valueOf(method));
payment.setStatus(PaymentStatus.PENDING);
payment.setCreatedAt(LocalDateTime.now());
return paymentRepository.save(payment);
}
private User createAnonymousUser(String username) {
User user = new User();
user.setUsername(username);
user.setEmail(username + "@anon.com");
user.setPasswordHash("anon");
user.setRole("ROLE_USER");
return userService.save(user);
}
@Transactional(readOnly = true)
public Map<String, Object> getUserPaymentStats(String username) {
User user = userService.findByUsername(username);
if (user == null) throw new RuntimeException("User not found");
Map<String, Object> stats = new HashMap<>();
stats.put("totalPayments", paymentRepository.countByUserId(user.getId()));
stats.put("successfulPayments", paymentRepository.countByUserIdAndStatus(user.getId(), PaymentStatus.SUCCESS));
return stats;
}
}