From 0426a6e77ad62134685d7541b2410198de3e716f Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期五, 08 五月 2026 16:51:17 +0800
Subject: [PATCH] Merge branch '2.0' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile into 2.0
---
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 225 insertions(+), 0 deletions(-)
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java
index 57d3b7d..21c7215 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java
@@ -73,6 +73,12 @@
@Resource
private TExchangeCodeUseRecordMapper useRecordMapper;
+ /**
+ * 分页查询兑换码卡包列表。
+ *
+ * @param query 查询条件
+ * @return 卡包分页结果
+ */
@Override
public PageInfo<TExchangeCodePackage> pageList(ExchangeCodePackageQuery query) {
PageInfo<TExchangeCodePackage> pageInfo = new PageInfo<>(query.getPageCurr(), query.getPageSize());
@@ -81,6 +87,11 @@
return pageInfo;
}
+ /**
+ * 新增兑换码卡包。
+ *
+ * @param dto 卡包保存参数
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public void savePackage(ExchangeCodePackageSaveDTO dto) {
@@ -91,6 +102,11 @@
refreshPackageStats(entity.getId());
}
+ /**
+ * 编辑兑换码卡包。
+ *
+ * @param dto 卡包保存参数
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePackage(ExchangeCodePackageSaveDTO dto) {
@@ -112,6 +128,12 @@
refreshPackageStats(dto.getId());
}
+ /**
+ * 更新兑换码卡包启用状态。
+ *
+ * @param id 卡包ID
+ * @param status 启用状态
+ */
@Override
public void updatePackageStatus(Long id, Integer status) {
if (id == null) {
@@ -130,6 +152,9 @@
this.updateById(entity);
}
+ /**
+ * 刷新所有已过领取截止日期的兑换码卡包未绑定兑换码状态。
+ */
@Override
public void refreshExpiredPackageCodes() {
List<TExchangeCodePackage> expiredPackages = this.list(new QueryWrapper<TExchangeCodePackage>()
@@ -141,6 +166,11 @@
}
}
+ /**
+ * 删除兑换码卡包。
+ *
+ * @param ids 卡包ID,多个ID用英文逗号分隔
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public void deletePackage(String ids) {
@@ -166,6 +196,12 @@
codeDetailMapper.delete(new QueryWrapper<TExchangeCodeDetail>().in("package_id", idList));
}
+ /**
+ * 查询兑换码卡包详情。
+ *
+ * @param id 卡包ID
+ * @return 卡包详情
+ */
@Override
public ExchangeCodePackageDetailVO getDetail(Long id) {
TExchangeCodePackage entity = this.getById(id);
@@ -200,6 +236,12 @@
return detailVO;
}
+ /**
+ * 分页查询兑换码明细。
+ *
+ * @param query 查询条件
+ * @return 兑换码明细分页结果
+ */
@Override
public PageInfo<ExchangeCodeDetailVO> codePage(ExchangeCodeDetailQuery query) {
refreshExpiredPackageCodes(query.getPackageId());
@@ -209,12 +251,24 @@
return pageInfo;
}
+ /**
+ * 导出兑换码明细。
+ *
+ * @param query 查询条件
+ * @return 兑换码明细导出数据
+ */
@Override
public List<ExchangeCodeDetailVO> exportCodes(ExchangeCodeDetailQuery query) {
refreshExpiredPackageCodes(query.getPackageId());
return codeDetailMapper.exportList(query);
}
+ /**
+ * 批量失效兑换码。
+ *
+ * @param dto 失效参数
+ * @return 失效结果
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public ExchangeCodeBatchInvalidResultVO batchInvalidate(ExchangeCodeBatchInvalidDTO dto) {
@@ -242,6 +296,13 @@
return new ExchangeCodeBatchInvalidResultVO(success, skip);
}
+ /**
+ * 查询可下载二维码的兑换码列表。
+ *
+ * @param packageId 卡包ID
+ * @param onlyUnbound 是否只查询未绑定兑换码
+ * @return 可下载二维码的兑换码列表
+ */
@Override
public List<ExchangeCodeDetailVO> listDownloadableCodes(Long packageId, boolean onlyUnbound) {
ExchangeCodeDetailQuery query = new ExchangeCodeDetailQuery();
@@ -252,6 +313,12 @@
return exportCodes(query);
}
+ /**
+ * 查询兑换码明细。
+ *
+ * @param id 兑换码明细ID
+ * @return 兑换码明细
+ */
@Override
public ExchangeCodeDetailVO getCodeDetail(Long id) {
TExchangeCodeDetail detail = codeDetailMapper.selectById(id);
@@ -270,6 +337,14 @@
return vo;
}
+ /**
+ * 绑定兑换码。
+ *
+ * @param dto 绑定参数
+ * @param userId 用户ID
+ * @param phone 手机号
+ * @return 绑定结果
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public ExchangeCodeBindResultVO bindExchangeCode(ExchangeCodeBindDTO dto, Long userId, String phone) {
@@ -334,6 +409,12 @@
return resultVO;
}
+ /**
+ * 分页查询兑换码余额流水。
+ *
+ * @param query 查询条件
+ * @return 流水分页结果
+ */
@Override
public Page<TExchangeCodeUseRecord> useRecordPage(ExchangeCodeUseRecordQuery query) {
Page<TExchangeCodeUseRecord> page = useRecordMapper.selectPage(Page.of(query.getPageCurr(), query.getPageSize()),
@@ -348,6 +429,13 @@
return page;
}
+ /**
+ * 查询兑换码余额流水详情。
+ *
+ * @param id 流水ID
+ * @param userId 用户ID
+ * @return 流水详情
+ */
@Override
public TExchangeCodeUseRecord useRecordDetail(Long id, Long userId) {
TExchangeCodeUseRecord record = useRecordMapper.selectOne(new QueryWrapper<TExchangeCodeUseRecord>()
@@ -359,6 +447,12 @@
return record;
}
+ /**
+ * 查询用户兑换码余额映射。
+ *
+ * @param userIds 用户ID集合
+ * @return 用户余额映射
+ */
@Override
public Map<Long, BigDecimal> getUserExchangeCodeBalanceMap(List<Long> userIds) {
Map<Long, BigDecimal> result = new HashMap<>();
@@ -378,6 +472,12 @@
return result;
}
+ /**
+ * 扣减用户兑换码余额。
+ *
+ * @param dto 扣减参数
+ * @return 扣减结果
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public ExchangeCodeConsumeResultVO consumeBalance(ExchangeCodeConsumeDTO dto) {
@@ -437,6 +537,12 @@
return resultVO;
}
+ /**
+ * 退款返还用户兑换码余额。
+ *
+ * @param dto 退款参数
+ * @return 退款结果
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public ExchangeCodeConsumeResultVO refundBalance(ExchangeCodeConsumeDTO dto) {
@@ -501,6 +607,13 @@
return resultVO;
}
+ /**
+ * 根据兑换码明细记录的赠送比例计算本次使用金额中的赠送金额。
+ *
+ * @param useAmount 本次使用金额
+ * @param detail 兑换码明细
+ * @return 本次使用金额对应的赠送金额
+ */
private BigDecimal calculateGiftUsedAmount(BigDecimal useAmount, TExchangeCodeDetail detail) {
if (useAmount == null || detail == null || detail.getGiftRatio() == null) {
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
@@ -508,6 +621,12 @@
return useAmount.multiply(detail.getGiftRatio()).setScale(2, RoundingMode.HALF_UP);
}
+ /**
+ * 查询兑换码明细当前剩余可用金额。
+ *
+ * @param detail 兑换码明细
+ * @return 剩余可用金额
+ */
private BigDecimal getDetailRemainAmount(TExchangeCodeDetail detail) {
if (detail == null || detail.getPackageSpecId() == null) {
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
@@ -522,6 +641,13 @@
: remainAmount.setScale(2, RoundingMode.HALF_UP);
}
+ /**
+ * 将保存参数转换为兑换码卡包实体。
+ *
+ * @param dto 卡包保存参数
+ * @param entity 待填充的卡包实体
+ * @return 填充后的卡包实体
+ */
private TExchangeCodePackage buildPackageEntity(ExchangeCodePackageSaveDTO dto, TExchangeCodePackage entity) {
entity.setPackageName(dto.getPackageName());
entity.setCoverPicture(dto.getCoverPicture());
@@ -539,6 +665,12 @@
return entity;
}
+ /**
+ * 校验兑换码卡包新增或编辑参数。
+ *
+ * @param dto 卡包保存参数
+ * @param editing 是否为编辑场景
+ */
private void validateSaveDTO(ExchangeCodePackageSaveDTO dto, boolean editing) {
if (!StringUtils.hasText(dto.getPackageName())) {
throw new ServiceException("请输入卡包名称");
@@ -589,6 +721,13 @@
allocateDiscount(dto.getSpecList(), gift, total);
}
+ /**
+ * 按规格小计占比分摊卡包赠送金额。
+ *
+ * @param specList 规格列表
+ * @param giftAmount 赠送金额
+ * @param totalAmount 卡包总金额
+ */
private void allocateDiscount(List<ExchangeCodePackageSpecDTO> specList, BigDecimal giftAmount, BigDecimal totalAmount) {
if (giftAmount.compareTo(BigDecimal.ZERO) == 0 || totalAmount.compareTo(BigDecimal.ZERO) == 0) {
for (ExchangeCodePackageSpecDTO spec : specList) {
@@ -611,6 +750,14 @@
}
}
+ /**
+ * 保存兑换码规格并按新增库存生成兑换码明细。
+ *
+ * @param packageId 卡包ID
+ * @param specList 规格列表
+ * @param inventory 当前库存
+ * @param oldInventory 编辑前库存,新增场景为空
+ */
private void saveSpecsAndCodes(Long packageId, List<ExchangeCodePackageSpecDTO> specList, Integer inventory, Integer oldInventory) {
List<TExchangeCodePackageSpec> specEntities = new ArrayList<>();
for (int i = 0; i < specList.size(); i++) {
@@ -656,6 +803,12 @@
}
}
+ /**
+ * 计算卡包赠送金额占总金额的比例。
+ *
+ * @param exchangePackage 兑换码卡包
+ * @return 赠送金额比例
+ */
private BigDecimal calculateGiftRatio(TExchangeCodePackage exchangePackage) {
if (exchangePackage == null || exchangePackage.getTotalAmount() == null
|| exchangePackage.getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -665,6 +818,13 @@
.divide(exchangePackage.getTotalAmount(), 6, RoundingMode.HALF_UP);
}
+ /**
+ * 计算单个兑换码对应的赠送金额。
+ *
+ * @param spec 兑换码规格
+ * @param giftRatio 赠送金额比例
+ * @return 单个兑换码赠送金额
+ */
private BigDecimal calculateDetailGiftAmount(TExchangeCodePackageSpec spec, BigDecimal giftRatio) {
if (spec == null || spec.getAmount() == null || giftRatio == null) {
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
@@ -672,6 +832,11 @@
return spec.getAmount().multiply(giftRatio).setScale(2, RoundingMode.HALF_UP);
}
+ /**
+ * 刷新兑换码卡包的已绑定、已失效和未绑定数量。
+ *
+ * @param packageId 卡包ID
+ */
private void refreshPackageStats(Long packageId) {
TExchangeCodePackage entity = this.getById(packageId);
if (entity == null) {
@@ -691,6 +856,11 @@
this.baseMapper.updateById(entity);
}
+ /**
+ * 将已过领取截止日期卡包下未绑定的兑换码刷新为已失效。
+ *
+ * @param packageId 卡包ID
+ */
private void refreshExpiredPackageCodes(Long packageId) {
if (packageId == null) {
return;
@@ -711,14 +881,32 @@
refreshPackageStats(packageId);
}
+ /**
+ * 生成兑换码卡号。
+ *
+ * @param packageId 卡包ID
+ * @param seq 当前批次序号
+ * @return 兑换码卡号
+ */
private String generateCode(Long packageId, int seq) {
return "CD" + packageId + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + String.format("%03d", seq);
}
+ /**
+ * 生成兑换码密码。
+ *
+ * @return 兑换码密码
+ */
private String generatePassword() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
}
+ /**
+ * 合并同一订单或同一兑换码维度的余额流水展示记录。
+ *
+ * @param records 原始流水列表
+ * @return 合并后的流水列表
+ */
private List<TExchangeCodeUseRecord> mergeUseRecords(List<TExchangeCodeUseRecord> records) {
if (records == null || records.isEmpty()) {
return records;
@@ -744,6 +932,12 @@
return new ArrayList<>(recordMap.values());
}
+ /**
+ * 构建余额流水合并键。
+ *
+ * @param record 余额流水记录
+ * @return 流水合并键
+ */
private String buildUseRecordMergeKey(TExchangeCodeUseRecord record) {
Long orderId = record.getOrderId() == null ? 0L : record.getOrderId();
Long detailId = record.getDetailId() == null ? 0L : record.getDetailId();
@@ -755,6 +949,12 @@
return detailId + "_" + changeType + "_" + refundNo;
}
+ /**
+ * 填充单条余额流水发生后的用户当前余额。
+ *
+ * @param record 余额流水记录
+ * @param userId 用户ID
+ */
private void fillUseRecordBalance(TExchangeCodeUseRecord record, Long userId) {
if (record == null || userId == null || record.getId() == null) {
return;
@@ -762,6 +962,12 @@
record.setCurrentBalance(calculateCurrentBalanceAfterRecord(userId, record.getId()));
}
+ /**
+ * 批量填充余额流水发生后的用户当前余额。
+ *
+ * @param records 余额流水列表
+ * @param userId 用户ID
+ */
private void fillUseRecordBalances(List<TExchangeCodeUseRecord> records, Long userId) {
if (records == null || records.isEmpty() || userId == null) {
return;
@@ -779,6 +985,7 @@
item.setCurrentBalance(balanceMap.getOrDefault(item.getId(), BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)));
}
}
+
private BigDecimal calculateCurrentBalanceAfterRecord(Long userId, Long recordId) {
BigDecimal balance = getCurrentExchangeCodeBalance(userId);
@@ -806,6 +1013,11 @@
return defaultMoney(balanceMap.get(userId));
}
+ /**
+ * 填充余额流水前端展示字段。
+ *
+ * @param record 余额流水记录
+ */
private void fillUseRecordView(TExchangeCodeUseRecord record) {
if (record == null) {
return;
@@ -831,6 +1043,13 @@
}
}
+ /**
+ * 根据使用金额和赠送比例填充流水的总使用金额与赠送使用金额。
+ *
+ * @param record 余额流水记录
+ * @param amount 使用金额
+ * @param giftRatio 赠送金额比例
+ */
private void fillUseRecordAmount(TExchangeCodeUseRecord record, BigDecimal amount, BigDecimal giftRatio) {
BigDecimal usedAmount = defaultMoney(amount);
BigDecimal ratio = giftRatio == null ? BigDecimal.ZERO : giftRatio;
@@ -847,6 +1066,12 @@
record.setGiftUsedAmount(giftUsedAmount);
}
+ /**
+ * 将金额空值归零并统一保留两位小数。
+ *
+ * @param amount 原始金额
+ * @return 标准金额
+ */
private BigDecimal defaultMoney(BigDecimal amount) {
return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
: amount.setScale(2, RoundingMode.HALF_UP);
--
Gitblit v1.7.1