feat(theme): 支持购买记录查询并调整积分类型为BigDecimal

- 新增 /themes/purchase/list 接口,支持用户查询主题购买记录
- 将 KeyboardThemePurchase 中的积分字段由 Integer 改为 BigDecimal,确保金额精度
- 对应 Mapper XML 中 jdbcType 由 INTEGER 调整为 NUMERIC
- 补充 getUserPurchaseList 服务及返回 VO ThemePurchaseListRespVO
- 开放接口权限并完善跨域配置
This commit is contained in:
2025-12-10 19:58:48 +08:00
parent 22b97b99aa
commit 1a6fb944b2
8 changed files with 107 additions and 10 deletions

0
mvnw vendored Normal file → Executable file
View File

View File

@@ -88,7 +88,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
"/chat/save_embed", "/chat/save_embed",
"/themes/listByStyle", "/themes/listByStyle",
"/wallet/balance", "/wallet/balance",
"/themes/purchase" "/themes/purchase",
"/themes/purchase/list"
}; };
} }
@Bean @Bean

View File

@@ -4,6 +4,7 @@ import cn.dev33.satoken.stp.StpUtil;
import com.yolo.keyborad.common.BaseResponse; import com.yolo.keyborad.common.BaseResponse;
import com.yolo.keyborad.common.ResultUtils; import com.yolo.keyborad.common.ResultUtils;
import com.yolo.keyborad.model.dto.purchase.ThemePurchaseReq; import com.yolo.keyborad.model.dto.purchase.ThemePurchaseReq;
import com.yolo.keyborad.model.vo.purchase.ThemePurchaseListRespVO;
import com.yolo.keyborad.model.vo.purchase.ThemePurchaseRespVO; import com.yolo.keyborad.model.vo.purchase.ThemePurchaseRespVO;
import com.yolo.keyborad.model.vo.themes.KeyboardThemeStylesRespVO; import com.yolo.keyborad.model.vo.themes.KeyboardThemeStylesRespVO;
import com.yolo.keyborad.model.vo.themes.KeyboardThemesRespVO; import com.yolo.keyborad.model.vo.themes.KeyboardThemesRespVO;
@@ -58,4 +59,12 @@ public class ThemesController {
return ResultUtils.success(result); return ResultUtils.success(result);
} }
@GetMapping("/purchase/list")
@Operation(summary = "查询购买记录", description = "查询当前用户的主题购买记录")
public BaseResponse<List<ThemePurchaseListRespVO>> getPurchaseList() {
Long userId = StpUtil.getLoginIdAsLong();
List<ThemePurchaseListRespVO> result = themePurchaseService.getUserPurchaseList(userId);
return ResultUtils.success(result);
}
} }

View File

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import lombok.Data; import lombok.Data;
@@ -50,14 +52,14 @@ public class KeyboardThemePurchase {
*/ */
@TableField(value = "cost_points") @TableField(value = "cost_points")
@Schema(description="皮肤原始所需积分") @Schema(description="皮肤原始所需积分")
private Integer costPoints; private BigDecimal costPoints;
/** /**
* 实际扣除积分 * 实际扣除积分
*/ */
@TableField(value = "paid_points") @TableField(value = "paid_points")
@Schema(description="实际扣除积分") @Schema(description="实际扣除积分")
private Integer paidPoints; private BigDecimal paidPoints;
/** /**
* 支付状态0待支付 1已支付 2已关闭 3已退款 * 支付状态0待支付 1已支付 2已关闭 3已退款

View File

@@ -0,0 +1,36 @@
package com.yolo.keyborad.model.vo.purchase;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 主题购买记录响应
*/
@Schema(description = "主题购买记录响应")
@Data
public class ThemePurchaseListRespVO {
@Schema(description = "订单号")
private String orderNo;
@Schema(description = "主题ID")
private Long themeId;
@Schema(description = "主题名称")
private String themeName;
@Schema(description = "支付金额")
private BigDecimal paidAmount;
@Schema(description = "支付状态0待支付 1已支付 2已关闭 3已退款")
private Short payStatus;
@Schema(description = "购买时间")
private Date createdAt;
@Schema(description = "支付时间")
private Date paidAt;
}

View File

@@ -2,7 +2,11 @@ package com.yolo.keyborad.service;
import com.yolo.keyborad.model.entity.KeyboardThemePurchase; import com.yolo.keyborad.model.entity.KeyboardThemePurchase;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.yolo.keyborad.model.vo.purchase.ThemePurchaseListRespVO;
import com.yolo.keyborad.model.vo.purchase.ThemePurchaseRespVO; import com.yolo.keyborad.model.vo.purchase.ThemePurchaseRespVO;
import java.util.List;
/* /*
* @author: ziin * @author: ziin
* @date: 2025/12/10 19:17 * @date: 2025/12/10 19:17
@@ -14,4 +18,9 @@ public interface KeyboardThemePurchaseService extends IService<KeyboardThemePurc
* 购买主题 * 购买主题
*/ */
ThemePurchaseRespVO purchaseTheme(Long userId, Long themeId); ThemePurchaseRespVO purchaseTheme(Long userId, Long themeId);
/**
* 查询用户购买记录
*/
List<ThemePurchaseListRespVO> getUserPurchaseList(Long userId);
} }

View File

@@ -5,16 +5,19 @@ import com.yolo.keyborad.exception.BusinessException;
import com.yolo.keyborad.model.entity.KeyboardThemes; import com.yolo.keyborad.model.entity.KeyboardThemes;
import com.yolo.keyborad.model.entity.KeyboardUserWallet; import com.yolo.keyborad.model.entity.KeyboardUserWallet;
import com.yolo.keyborad.model.entity.KeyboardWalletTransaction; import com.yolo.keyborad.model.entity.KeyboardWalletTransaction;
import com.yolo.keyborad.model.vo.purchase.ThemePurchaseListRespVO;
import com.yolo.keyborad.model.vo.purchase.ThemePurchaseRespVO; import com.yolo.keyborad.model.vo.purchase.ThemePurchaseRespVO;
import com.yolo.keyborad.service.KeyboardThemesService; import com.yolo.keyborad.service.KeyboardThemesService;
import com.yolo.keyborad.service.KeyboardUserWalletService; import com.yolo.keyborad.service.KeyboardUserWalletService;
import com.yolo.keyborad.service.KeyboardWalletTransactionService; import com.yolo.keyborad.service.KeyboardWalletTransactionService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -29,13 +32,13 @@ import com.yolo.keyborad.service.KeyboardThemePurchaseService;
@Service @Service
public class KeyboardThemePurchaseServiceImpl extends ServiceImpl<KeyboardThemePurchaseMapper, KeyboardThemePurchase> implements KeyboardThemePurchaseService{ public class KeyboardThemePurchaseServiceImpl extends ServiceImpl<KeyboardThemePurchaseMapper, KeyboardThemePurchase> implements KeyboardThemePurchaseService{
@Autowired @Resource
private KeyboardThemesService themesService; private KeyboardThemesService themesService;
@Autowired @Resource
private KeyboardUserWalletService walletService; private KeyboardUserWalletService walletService;
@Autowired @Resource
private KeyboardWalletTransactionService transactionService; private KeyboardWalletTransactionService transactionService;
@Override @Override
@@ -105,8 +108,8 @@ public class KeyboardThemePurchaseServiceImpl extends ServiceImpl<KeyboardThemeP
purchase.setOrderNo(orderNo); // 订单号 purchase.setOrderNo(orderNo); // 订单号
purchase.setUserId(userId); // 用户ID purchase.setUserId(userId); // 用户ID
purchase.setThemeId(themeId); // 主题ID purchase.setThemeId(themeId); // 主题ID
purchase.setCostPoints(themePrice.intValue()); // 消费积分 purchase.setCostPoints(themePrice); // 消费积分
purchase.setPaidPoints(themePrice.intValue()); // 实付积分 purchase.setPaidPoints(themePrice); // 实付积分
purchase.setPayStatus((short) 1); // 支付状态1-已支付 purchase.setPayStatus((short) 1); // 支付状态1-已支付
purchase.setCreatedAt(new Date()); // 创建时间 purchase.setCreatedAt(new Date()); // 创建时间
purchase.setPaidAt(new Date()); // 支付时间 purchase.setPaidAt(new Date()); // 支付时间
@@ -141,4 +144,41 @@ public class KeyboardThemePurchaseServiceImpl extends ServiceImpl<KeyboardThemeP
return respVO; return respVO;
} }
@Override
/**
* 获取用户的主题购买记录列表
*
* @param userId 用户ID
* @return 购买记录列表
*/
public List<ThemePurchaseListRespVO> getUserPurchaseList(Long userId) {
// 1. 查询用户的所有购买记录,按创建时间倒序排列
List<KeyboardThemePurchase> purchases = this.lambdaQuery()
.eq(KeyboardThemePurchase::getUserId, userId) // 根据用户ID筛选
.orderByDesc(KeyboardThemePurchase::getCreatedAt) // 按创建时间倒序
.list();
// 2. 将购买记录转换为响应VO对象
return purchases.stream().map(purchase -> {
// 创建响应VO对象
ThemePurchaseListRespVO vo = new ThemePurchaseListRespVO();
// 设置订单基本信息
vo.setOrderNo(purchase.getOrderNo()); // 订单号
vo.setThemeId(purchase.getThemeId()); // 主题ID
vo.setPaidAmount(purchase.getPaidPoints()); // 支付金额
vo.setPayStatus(purchase.getPayStatus()); // 支付状态
vo.setCreatedAt(purchase.getCreatedAt()); // 创建时间
vo.setPaidAt(purchase.getPaidAt()); // 支付时间
// 3. 获取主题详情,填充主题名称
KeyboardThemes theme = themesService.getById(purchase.getThemeId());
if (theme != null) {
vo.setThemeName(theme.getThemeName()); // 主题名称
}
return vo;
}).collect(java.util.stream.Collectors.toList());
}
} }

View File

@@ -8,8 +8,8 @@
<result column="order_no" jdbcType="VARCHAR" property="orderNo" /> <result column="order_no" jdbcType="VARCHAR" property="orderNo" />
<result column="user_id" jdbcType="BIGINT" property="userId" /> <result column="user_id" jdbcType="BIGINT" property="userId" />
<result column="theme_id" jdbcType="BIGINT" property="themeId" /> <result column="theme_id" jdbcType="BIGINT" property="themeId" />
<result column="cost_points" jdbcType="INTEGER" property="costPoints" /> <result column="cost_points" jdbcType="NUMERIC" property="costPoints" />
<result column="paid_points" jdbcType="INTEGER" property="paidPoints" /> <result column="paid_points" jdbcType="NUMERIC" property="paidPoints" />
<result column="pay_status" jdbcType="SMALLINT" property="payStatus" /> <result column="pay_status" jdbcType="SMALLINT" property="payStatus" />
<result column="wallet_tx_id" jdbcType="BIGINT" property="walletTxId" /> <result column="wallet_tx_id" jdbcType="BIGINT" property="walletTxId" />
<result column="refund_points" jdbcType="INTEGER" property="refundPoints" /> <result column="refund_points" jdbcType="INTEGER" property="refundPoints" />