- 新增可提现余额和不可提现余额字段,完善账户余额结构 - 添加充值接口支持微信和支付宝支付方式 - 实现token消费转换扣费功能,支持AI模型调用计费 - 增加管理员赠送金额接口,仅管理员可调用 - 完善交易记录查询功能,支持用户查看历史交易明细 - 集成模型价格服务,实现token费用自动计算 - 重构余额增加逻辑,区分可提现和不可提现金额 - 优化账户实体类初始化逻辑,确保余额字段正确设置 - 更新交易记录实体类,新增token相关和收支类型字段 - 修改支付配置,更新微信和支付宝回调地址为生产环境域名
341 lines
12 KiB
Java
341 lines
12 KiB
Java
package com.kexue.skills.service.impl;
|
||
|
||
import com.github.pagehelper.PageHelper;
|
||
import com.github.pagehelper.PageInfo;
|
||
import com.kexue.skills.entity.PaymentOrder;
|
||
import com.kexue.skills.entity.dto.PaymentOrderDto;
|
||
import com.kexue.skills.mapper.PaymentOrderMapper;
|
||
import com.kexue.skills.service.AccountService;
|
||
import com.kexue.skills.service.PaymentOrderService;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
import javax.annotation.Resource;
|
||
import java.util.Date;
|
||
import java.util.List;
|
||
import java.util.UUID;
|
||
|
||
/**
|
||
* (PaymentOrder)表服务实现类
|
||
*
|
||
* @author 王志维
|
||
* @since 2025-02-21 23:01:48
|
||
*/
|
||
@Service("paymentOrderService")
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public class PaymentOrderServiceImpl implements PaymentOrderService {
|
||
|
||
private static final Logger logger = LoggerFactory.getLogger(PaymentOrderServiceImpl.class);
|
||
@Resource
|
||
private PaymentOrderMapper paymentOrderMapper;
|
||
|
||
@Resource
|
||
private AccountService accountService;
|
||
|
||
@Resource
|
||
private com.kexue.skills.service.ContentPurchaseService contentPurchaseService;
|
||
|
||
@Resource
|
||
private com.kexue.skills.service.CmsContentService cmsContentService;
|
||
|
||
/**
|
||
* 分页查询
|
||
*
|
||
* @param queryDto 筛选条件
|
||
* @return 查询结果
|
||
*/
|
||
@Override
|
||
public PageInfo<PaymentOrder> getPageList(PaymentOrderDto queryDto) {
|
||
PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());
|
||
List<PaymentOrder> list = this.paymentOrderMapper.getPageList(queryDto);
|
||
return new PageInfo<>(list);
|
||
}
|
||
|
||
/**
|
||
* 查询列表
|
||
*
|
||
* @param queryDto 筛选条件
|
||
* @return 查询结果
|
||
*/
|
||
@Override
|
||
public List<PaymentOrder> getList(PaymentOrderDto queryDto) {
|
||
return this.paymentOrderMapper.getList(queryDto);
|
||
}
|
||
|
||
/**
|
||
* 通过主键查询单条数据
|
||
*
|
||
* @param orderId 主键
|
||
* @return 实例对象
|
||
*/
|
||
@Override
|
||
public PaymentOrder queryById(Long orderId) {
|
||
return this.paymentOrderMapper.queryById(orderId);
|
||
}
|
||
|
||
/**
|
||
* 通过订单号查询单条数据
|
||
*
|
||
* @param orderNo 订单号
|
||
* @return 实例对象
|
||
*/
|
||
@Override
|
||
public PaymentOrder queryByOrderNo(String orderNo) {
|
||
return this.paymentOrderMapper.queryByOrderNo(orderNo);
|
||
}
|
||
|
||
/**
|
||
* 新增数据
|
||
*
|
||
* @param paymentOrder 实例对象
|
||
* @return 实例对象
|
||
*/
|
||
@Override
|
||
public PaymentOrder insert(PaymentOrder paymentOrder) {
|
||
// 设置创建时间和更新时间
|
||
Date now = new Date();
|
||
paymentOrder.setCreateTime(now);
|
||
paymentOrder.setUpdateTime(now);
|
||
// 设置默认值
|
||
paymentOrder.setDeleteFlag(0);
|
||
// 保存数据
|
||
this.paymentOrderMapper.insert(paymentOrder);
|
||
return paymentOrder;
|
||
}
|
||
|
||
/**
|
||
* 更新数据
|
||
*
|
||
* @param paymentOrder 实例对象
|
||
* @return 实例对象
|
||
*/
|
||
@Override
|
||
public PaymentOrder update(PaymentOrder paymentOrder) {
|
||
// 设置更新时间
|
||
paymentOrder.setUpdateTime(new Date());
|
||
// 更新数据
|
||
this.paymentOrderMapper.update(paymentOrder);
|
||
return this.queryById(paymentOrder.getOrderId());
|
||
}
|
||
|
||
/**
|
||
* 更新订单状态
|
||
*
|
||
* @param orderId 订单ID
|
||
* @param status 状态
|
||
* @param channelOrderNo 渠道订单号
|
||
* @return 影响行数
|
||
*/
|
||
@Override
|
||
public int updateStatus(Long orderId, Integer status, String channelOrderNo) {
|
||
return this.paymentOrderMapper.updateStatus(orderId, status, channelOrderNo);
|
||
}
|
||
|
||
/**
|
||
* 通过主键逻辑删除
|
||
*
|
||
* @param orderId 主键
|
||
* @param updateBy 更新人
|
||
* @return 影响行数
|
||
*/
|
||
@Override
|
||
public int logicDeleteById(Long orderId, String updateBy) {
|
||
return this.paymentOrderMapper.logicDeleteById(orderId, updateBy);
|
||
}
|
||
|
||
/**
|
||
* 通过主键物理删除
|
||
*
|
||
* @param orderId 主键
|
||
* @return 影响行数
|
||
*/
|
||
@Override
|
||
public int deleteById(Long orderId) {
|
||
return this.paymentOrderMapper.deleteById(orderId);
|
||
}
|
||
|
||
/**
|
||
* 创建支付订单
|
||
*
|
||
* @param paymentOrder 订单信息
|
||
* @return 支付订单
|
||
*/
|
||
@Override
|
||
public PaymentOrder createPaymentOrder(PaymentOrder paymentOrder) {
|
||
// 生成订单号
|
||
String orderNo = generateOrderNo();
|
||
paymentOrder.setOrderNo(orderNo);
|
||
// 设置初始状态
|
||
paymentOrder.setStatus(1); // 1.待支付
|
||
// 设置支付类型默认值(防止null)
|
||
if (paymentOrder.getPayType() == null) {
|
||
paymentOrder.setPayType(1); // 默认微信支付
|
||
logger.info("设置默认支付类型为微信支付(1)");
|
||
} else {
|
||
logger.info("支付类型已设置为: {}", paymentOrder.getPayType());
|
||
}
|
||
// 设置创建时间和更新时间
|
||
Date now = new Date();
|
||
paymentOrder.setCreateTime(now);
|
||
paymentOrder.setUpdateTime(now);
|
||
// 设置默认值
|
||
paymentOrder.setDeleteFlag(0);
|
||
// 保存订单
|
||
logger.info("准备保存支付订单,payType: {}", paymentOrder.getPayType());
|
||
this.paymentOrderMapper.insert(paymentOrder);
|
||
logger.info("支付订单保存成功");
|
||
return paymentOrder;
|
||
}
|
||
|
||
/**
|
||
* 处理支付回调
|
||
*
|
||
* @param orderNo 订单号
|
||
* @param status 支付状态
|
||
* @param channelOrderNo 渠道订单号
|
||
* @return 处理结果
|
||
*/
|
||
@Override
|
||
public boolean handlePaymentCallback(String orderNo, Integer status, String channelOrderNo) {
|
||
// 查询订单
|
||
PaymentOrder order = this.queryByOrderNo(orderNo);
|
||
if (order == null) {
|
||
logger.warn("支付回调订单不存在:{}", orderNo);
|
||
return false;
|
||
}
|
||
|
||
// 更新订单状态
|
||
this.updateStatus(order.getOrderId(), status, channelOrderNo);
|
||
|
||
// 如果支付成功,处理相关业务逻辑
|
||
if (status == 2) { // 2.已支付
|
||
logger.info("支付订单回调成功,orderNo: {}, businessType: {}", orderNo, order.getBusinessType());
|
||
|
||
// 根据业务类型处理不同的业务逻辑
|
||
if ("recharge".equals(order.getBusinessType())) {
|
||
// 充值业务,增加用户余额
|
||
try {
|
||
this.accountService.addBalance(order.getUserId(), order.getAmount(), orderNo,
|
||
order.getBusinessId(), order.getBusinessType(), "充值成功");
|
||
logger.info("充值业务处理完成,userId: {}, amount: {}", order.getUserId(), order.getAmount());
|
||
} catch (Exception e) {
|
||
logger.error("充值业务处理失败:{}", e.getMessage(), e);
|
||
return false;
|
||
}
|
||
} else if ("purchase_content".equals(order.getBusinessType())) {
|
||
// 购买内容业务,创建或更新购买记录
|
||
try {
|
||
handleContentPurchaseCallback(order);
|
||
} catch (Exception e) {
|
||
logger.error("购买内容业务处理失败:{}", e.getMessage(), e);
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 处理内容购买回调逻辑
|
||
*
|
||
* @param order 支付订单
|
||
*/
|
||
private void handleContentPurchaseCallback(PaymentOrder order) {
|
||
Long userId = order.getUserId();
|
||
Long contentId = order.getBusinessId();
|
||
|
||
// 1. 先查询是否已存在购买记录
|
||
com.kexue.skills.entity.ContentPurchase existingPurchase =
|
||
contentPurchaseService.queryByUserIdAndContentId(userId, contentId);
|
||
|
||
if (existingPurchase != null) {
|
||
// 2. 如果已存在购买记录且状态为待支付,更新为已支付
|
||
if (existingPurchase.getStatus() == 1) { // 1.待支付
|
||
contentPurchaseService.updateStatus(existingPurchase.getPurchaseId(), 2); // 2.已支付
|
||
logger.info("更新购买记录状态为已支付,userId: {}, contentId: {}", userId, contentId);
|
||
} else {
|
||
logger.warn("购买记录已存在且状态为已支付,无需更新,userId: {}, contentId: {}", userId, contentId);
|
||
}
|
||
} else {
|
||
// 3. 如果不存在购买记录,创建新的购买记录
|
||
logger.info("购买记录不存在,创建新记录,userId: {}, contentId: {}", userId, contentId);
|
||
createContentPurchaseRecord(order);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 创建内容购买记录
|
||
*
|
||
* @param order 支付订单
|
||
*/
|
||
private void createContentPurchaseRecord(PaymentOrder order) {
|
||
try {
|
||
// 查询内容信息获取标题
|
||
String contentTitle = order.getProductName();
|
||
if (order.getBusinessId() != null) {
|
||
com.kexue.skills.entity.CmsContent content = cmsContentService.queryById(order.getBusinessId());
|
||
if (content != null) {
|
||
contentTitle = content.getTitle();
|
||
}
|
||
}
|
||
|
||
// 创建购买记录
|
||
com.kexue.skills.entity.ContentPurchase purchase = new com.kexue.skills.entity.ContentPurchase();
|
||
purchase.setUserId(order.getUserId());
|
||
purchase.setContentId(order.getBusinessId());
|
||
purchase.setContentTitle(contentTitle);
|
||
purchase.setPayType(mapPayType(order.getPayType())); // 转换支付方式类型
|
||
purchase.setAmount(order.getAmount());
|
||
purchase.setPoints(0); // 微信/支付宝支付不计积分
|
||
purchase.setStatus(2); // 2.已支付
|
||
purchase.setPurchaseTime(new Date());
|
||
purchase.setCreateTime(new Date());
|
||
purchase.setUpdateTime(new Date());
|
||
purchase.setDeleteFlag(0);
|
||
|
||
contentPurchaseService.insert(purchase);
|
||
logger.info("创建购买记录成功,userId: {}, contentId: {}, purchaseId: {}",
|
||
order.getUserId(), order.getBusinessId(), purchase.getPurchaseId());
|
||
} catch (Exception e) {
|
||
logger.error("创建购买记录失败:{}", e.getMessage(), e);
|
||
throw new RuntimeException("创建购买记录失败:" + e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 映射支付方式类型
|
||
* payment_order.pay_type: 1.微信 2.支付宝
|
||
* content_purchase.pay_type: 3.微信支付 4.支付宝支付
|
||
*
|
||
* @param payType 支付订单的支付方式
|
||
* @return 购买记录的支付方式
|
||
*/
|
||
private int mapPayType(Integer payType) {
|
||
if (payType == null) {
|
||
return 3; // 默认微信支付
|
||
}
|
||
switch (payType) {
|
||
case 1: // 微信
|
||
return 3;
|
||
case 2: // 支付宝
|
||
return 4;
|
||
default:
|
||
return 3; // 默认微信支付
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 生成订单号
|
||
*
|
||
* @return 订单号
|
||
*/
|
||
private String generateOrderNo() {
|
||
// 订单号生成规则:时间戳 + 6位随机数
|
||
String timestamp = String.valueOf(System.currentTimeMillis());
|
||
String random = UUID.randomUUID().toString().substring(0, 6).replaceAll("-", "");
|
||
return timestamp + random;
|
||
}
|
||
} |