Initial commit: AIGC项目完整代码
This commit is contained in:
465
demo/src/main/java/com/example/demo/service/PaymentService.java
Normal file
465
demo/src/main/java/com/example/demo/service/PaymentService.java
Normal file
@@ -0,0 +1,465 @@
|
||||
package com.example.demo.service;
|
||||
|
||||
import com.example.demo.model.*;
|
||||
import com.example.demo.repository.PaymentRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 保存支付记录
|
||||
*/
|
||||
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查找支付记录
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Optional<Payment> findById(Long id) {
|
||||
return paymentRepository.findById(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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认支付成功
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认支付失败
|
||||
*/
|
||||
public Payment confirmPaymentFailure(Long paymentId, String failureReason) {
|
||||
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;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("确认支付失败失败:", e);
|
||||
throw new RuntimeException("确认支付失败失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建订单支付
|
||||
*/
|
||||
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;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("创建订单支付失败:", e);
|
||||
throw new RuntimeException("创建订单支付失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计支付记录数量
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户名查找支付记录
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付
|
||||
*/
|
||||
public Payment createPayment(String username, String orderId, String amountStr, String method) {
|
||||
try {
|
||||
logger.info("创建支付 - 用户名: {}, 订单ID: {}, 金额: {}, 支付方式: {}", username, orderId, amountStr, method);
|
||||
|
||||
User user = userService.findByUsername(username);
|
||||
if (user == null) {
|
||||
logger.error("用户不存在: {}", username);
|
||||
// 如果是匿名用户,创建一个临时用户记录
|
||||
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.setPaymentMethod(paymentMethod);
|
||||
payment.setStatus(PaymentStatus.PENDING);
|
||||
payment.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
Payment savedPayment = save(payment);
|
||||
logger.info("支付记录创建成功: {}", savedPayment.getId());
|
||||
|
||||
// 根据支付方式调用相应的支付服务
|
||||
if (paymentMethod == PaymentMethod.ALIPAY) {
|
||||
try {
|
||||
String paymentUrl = alipayService.createPayment(savedPayment);
|
||||
savedPayment.setPaymentUrl(paymentUrl);
|
||||
save(savedPayment);
|
||||
logger.info("支付宝支付URL生成成功: {}", paymentUrl);
|
||||
} catch (Exception e) {
|
||||
logger.error("调用支付宝支付接口失败:", e);
|
||||
// 不抛出异常,让前端处理
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
Integer pointsToAdd = 0;
|
||||
|
||||
// 根据支付金额确定积分奖励
|
||||
if (amount.compareTo(new BigDecimal("59.00")) >= 0 && amount.compareTo(new BigDecimal("259.00")) < 0) {
|
||||
// 标准版订阅 (59-258元) - 200积分
|
||||
pointsToAdd = 200;
|
||||
} else if (amount.compareTo(new BigDecimal("259.00")) >= 0) {
|
||||
// 专业版订阅 (259元以上) - 1000积分
|
||||
pointsToAdd = 1000;
|
||||
}
|
||||
|
||||
if (pointsToAdd > 0) {
|
||||
userService.addPoints(payment.getUser().getId(), pointsToAdd);
|
||||
logger.info("用户 {} 支付 {} 元,获得 {} 积分",
|
||||
payment.getUser().getUsername(), amount, pointsToAdd);
|
||||
}
|
||||
|
||||
} 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.setTotalAmount(payment.getAmount());
|
||||
order.setCurrency("CNY");
|
||||
order.setStatus(OrderStatus.PAID); // 支付成功,订单状态为已支付
|
||||
order.setOrderType(OrderType.PAYMENT); // 订单类型为支付订单
|
||||
order.setCreatedAt(LocalDateTime.now());
|
||||
order.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
// 保存订单
|
||||
Order savedOrder = orderService.save(order);
|
||||
|
||||
// 创建订单项
|
||||
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());
|
||||
|
||||
// 保存订单项
|
||||
orderService.saveOrderItem(orderItem);
|
||||
|
||||
// 更新支付记录,关联到新创建的订单
|
||||
payment.setOrder(savedOrder);
|
||||
paymentRepository.save(payment);
|
||||
|
||||
logger.info("从支付记录自动创建订单成功,支付ID:{},订单ID:{},订单号:{}",
|
||||
payment.getId(), savedOrder.getId(), orderNumber);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("从支付记录创建订单失败:", e);
|
||||
throw new RuntimeException("创建订单失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user