feat(tenant-balance): 新增余额充值及自查询接口
This commit is contained in:
@@ -101,4 +101,28 @@ public class TenantBalanceController {
|
||||
BeanUtils.toBean(list, TenantBalanceRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/addAmount")
|
||||
@Operation(summary = "添加租户余额")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-balance:add')")
|
||||
public CommonResult<Boolean> addTenantBalance(@Valid @RequestBody TenantBalanceAddReqVO addReqVO) {
|
||||
tenantBalanceService.addTenantBalance(addReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get-self-amount")
|
||||
@Operation(summary = "获得自己的余额")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-balance:self-amount')")
|
||||
public CommonResult<TenantBalanceRespVO> getTenantBalance() {
|
||||
TenantBalanceDO tenantBalance = tenantBalanceService.getSelfBalance();
|
||||
return success(BeanUtils.toBean(tenantBalance, TenantBalanceRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-self-subordinate-amount-page")
|
||||
@Operation(summary = "获得自己下级余额的分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-balance:self-subordinate')")
|
||||
public CommonResult<PageResult<TenantBalanceRespVO>> getSelfSubordinate(@Valid TenantBalancePageReqVO pageReqVO) {
|
||||
PageResult<TenantBalanceRespVO> tenantBalancePage = tenantBalanceService.getSelfSubordinateTenantBalancePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(tenantBalancePage, TenantBalanceRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.yolo.keyboard.controller.admin.tenantbalance.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2025/11/19 21:05
|
||||
*/
|
||||
@Schema(description = "管理后台 - 租户余额添加VO")
|
||||
@Data
|
||||
public class TenantBalanceAddReqVO {
|
||||
@Schema(description = "租户 Id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19954")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "增加的余额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000000")
|
||||
private BigDecimal amount;
|
||||
|
||||
@Schema(description = "备注", example = "备注")
|
||||
private String remark;
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package com.yolo.keyboard.dal.dataobject.tenantbalance;
|
||||
|
||||
import com.yolo.keyboard.framework.tenant.core.aop.TenantIgnore;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
@@ -31,10 +33,11 @@ public class TenantBalanceDO extends BaseDO {
|
||||
/**
|
||||
* 当前积分余额
|
||||
*/
|
||||
private Integer balance;
|
||||
private BigDecimal balance;
|
||||
/**
|
||||
* 乐观锁版本号
|
||||
*/
|
||||
@Version
|
||||
private Integer version;
|
||||
/**
|
||||
* 更新时间
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.yolo.keyboard.dal.dataobject.tenantbalancetransaction;
|
||||
|
||||
import com.yolo.keyboard.framework.tenant.core.aop.TenantIgnore;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.yolo.keyboard.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 租户积分记录 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("system_tenant_balance_transaction")
|
||||
@KeySequence("system_tenant_balance_transaction_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TenantIgnore
|
||||
public class TenantBalanceTransactionDO {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 本次变动点数,正加负减
|
||||
*/
|
||||
private BigDecimal points;
|
||||
/**
|
||||
* 变动后余额快照(冗余)
|
||||
*/
|
||||
private BigDecimal balance;
|
||||
/**
|
||||
* 变动类型,如 TRANSFER_IN, WITHDRAW,REFUND_COMMISSION ,RECHARGE_COMMISSION
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 变动描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 订单 Id/业务单号
|
||||
*/
|
||||
private String orderId;
|
||||
/**
|
||||
* 业务流水号(转账、订单等唯一标识)
|
||||
*/
|
||||
private String bizNo;
|
||||
/**
|
||||
* 操作人 Id
|
||||
*/
|
||||
private Long operatorId;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createdAt;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
private Long tenantId;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.yolo.keyboard.dal.mysql.tenantbalancetransaction;
|
||||
|
||||
import com.yolo.keyboard.dal.dataobject.tenantbalancetransaction.TenantBalanceTransactionDO;
|
||||
import com.yolo.keyboard.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 租户积分记录 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface TenantBalanceTransactionMapper extends BaseMapperX<TenantBalanceTransactionDO> {
|
||||
}
|
||||
@@ -59,4 +59,26 @@ public interface TenantBalanceService {
|
||||
*/
|
||||
PageResult<TenantBalanceDO> getTenantBalancePage(TenantBalancePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 添加租户余额
|
||||
*
|
||||
* @param addReqVO 添加信息
|
||||
*/
|
||||
void addTenantBalance(@Valid TenantBalanceAddReqVO addReqVO);
|
||||
|
||||
/**
|
||||
* 获得自己的余额
|
||||
*
|
||||
* @return 租户余额
|
||||
*/
|
||||
TenantBalanceDO getSelfBalance();
|
||||
|
||||
/**
|
||||
* 获得自己下级余额的分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 租户余额分页
|
||||
*/
|
||||
PageResult<TenantBalanceRespVO> getSelfSubordinateTenantBalancePage(TenantBalancePageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.yolo.keyboard.service.tenantbalance;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.yolo.keyboard.dal.dataobject.tenantbalancetransaction.TenantBalanceTransactionDO;
|
||||
import com.yolo.keyboard.dal.mysql.tenantbalancetransaction.TenantBalanceTransactionMapper;
|
||||
import com.yolo.keyboard.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.yolo.keyboard.utils.BizNoGenerator;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import com.yolo.keyboard.controller.admin.tenantbalance.vo.*;
|
||||
import com.yolo.keyboard.dal.dataobject.tenantbalance.TenantBalanceDO;
|
||||
@@ -32,6 +37,9 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
|
||||
@Resource
|
||||
private TenantBalanceMapper tenantBalanceMapper;
|
||||
|
||||
@Resource
|
||||
private TenantBalanceTransactionMapper tenantBalanceTransactionMapper;
|
||||
|
||||
@Override
|
||||
public Long createTenantBalance(TenantBalanceSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
@@ -82,4 +90,47 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
|
||||
return tenantBalanceMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void addTenantBalance(TenantBalanceAddReqVO addReqVO) {
|
||||
// 1. 根据ID查询租户余额记录,校验是否存在
|
||||
TenantBalanceDO balance = tenantBalanceMapper.selectById(addReqVO.getId());
|
||||
if (balance == null) {
|
||||
throw exception(TENANT_BALANCE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 2. 计算新的余额(当前余额 + 充值金额)
|
||||
BigDecimal newBalance = balance.getBalance().add(new BigDecimal(String.valueOf(addReqVO.getAmount())));
|
||||
// 3. 更新租户余额(使用乐观锁)
|
||||
balance.setBalance(newBalance);
|
||||
int updateCount = tenantBalanceMapper.updateById(balance);
|
||||
if (updateCount == 0) {
|
||||
throw exception(TENANT_BALANCE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 4. 创建余额交易记录
|
||||
TenantBalanceTransactionDO transaction = TenantBalanceTransactionDO.builder()
|
||||
.bizNo(BizNoGenerator.generate("RECHARGE")) // 生成充值业务编号
|
||||
.points(new BigDecimal(String.valueOf(addReqVO.getAmount()))) // 充值金额
|
||||
.balance(newBalance) // 充值后余额
|
||||
.tenantId(addReqVO.getId())
|
||||
.type("RECHARGE") // 交易类型:充值
|
||||
.description("余额充值") // 交易描述
|
||||
.remark(addReqVO.getRemark()) // 备注信息
|
||||
.operatorId(TenantContextHolder.getTenantId()) // 操作人ID(当前租户ID)
|
||||
.build();
|
||||
// 5. 插入交易记录到数据库
|
||||
tenantBalanceTransactionMapper.insert(transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantBalanceDO getSelfBalance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<TenantBalanceRespVO> getSelfSubordinateTenantBalancePage(TenantBalancePageReqVO pageReqVO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.yolo.keyboard.utils;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
|
||||
public class BizNoGenerator {
|
||||
public static String generate(String prefix) {
|
||||
return prefix + "-" + IdUtil.getSnowflakeNextIdStr();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.baomidou.mybatisplus.extension.incrementer.*;
|
||||
import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal;
|
||||
import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
@@ -48,6 +49,7 @@ public class YoloMybatisAutoConfiguration {
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 分页插件
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁插件
|
||||
// ↓↓↓ 按需开启,可能会影响到 updateBatch 的地方:例如说文件配置管理 ↓↓↓
|
||||
// mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); // 拦截没有指定条件的 update 和 delete 语句
|
||||
return mybatisPlusInterceptor;
|
||||
|
||||
Reference in New Issue
Block a user