From ebf071b225f2357bd118791c12cc49484c4c66ee Mon Sep 17 00:00:00 2001 From: ziin Date: Wed, 19 Nov 2025 22:10:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(tenant-balance):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=E7=BB=99=E7=A7=9F=E6=88=B7=E5=85=85=E5=80=BC?= =?UTF-8?q?=E4=BD=99=E9=A2=9D=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TenantBalanceController.java | 8 +++ .../vo/TenantBalanceAddReqVO.java | 23 +++++++ .../tenantbalance/TenantBalanceDO.java | 3 +- .../tenantpoints/TenantPointsDO.java | 6 +- .../tenantbalance/TenantBalanceMapper.java | 5 ++ .../system/enums/balance/BalanceEnum.java | 27 ++++++++ .../tenantbalance/TenantBalanceService.java | 1 + .../TenantBalanceServiceImpl.java | 69 +++++++++++++++---- .../module/system/util/BizNoGenerator.java | 34 +++++++++ .../src/main/resources/application.yaml | 2 + 10 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/vo/TenantBalanceAddReqVO.java create mode 100644 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/balance/BalanceEnum.java create mode 100644 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/util/BizNoGenerator.java diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/TenantBalanceController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/TenantBalanceController.java index a4d8c8a..f92b5e5 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/TenantBalanceController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/TenantBalanceController.java @@ -101,4 +101,12 @@ public class TenantBalanceController { BeanUtils.toBean(list, TenantBalanceRespVO.class)); } + + @PostMapping("/addAmount") + @Operation(summary = "添加租户余额") + @PreAuthorize("@ss.hasPermission('system:tenant-balance:add')") + public CommonResult addTenantBalance(@Valid @RequestBody TenantBalanceAddReqVO addReqVO) { + tenantBalanceService.addTenantBalance(addReqVO); + return success(true); + } } \ No newline at end of file diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/vo/TenantBalanceAddReqVO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/vo/TenantBalanceAddReqVO.java new file mode 100644 index 0000000..1a99a4f --- /dev/null +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenantbalance/vo/TenantBalanceAddReqVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/* + * @author: ziin + * @date: 2025/11/19 21:05 + */ +@Schema(description = "管理后台 - 租户余额添加VO") +@Data +public class TenantBalanceAddReqVO { + @Schema(description = "租户 Id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19954") + @NotNull(message = "租户 Id 不能为空") + private Long id; + + @Schema(description = "增加的余额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000000") + @NotNull(message = "增加的余额不能为空") + private Integer amount; +} diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantbalance/TenantBalanceDO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantbalance/TenantBalanceDO.java index 5f85cff..3c6a707 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantbalance/TenantBalanceDO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantbalance/TenantBalanceDO.java @@ -14,12 +14,11 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @TableName("system_tenant_balance") @KeySequence("system_tenant_balance_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Builder @NoArgsConstructor @AllArgsConstructor -public class TenantBalanceDO extends BaseDO { +public class TenantBalanceDO{ private Long id; /** diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantpoints/TenantPointsDO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantpoints/TenantPointsDO.java index 68e4abd..25f7d66 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantpoints/TenantPointsDO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenantpoints/TenantPointsDO.java @@ -14,17 +14,16 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @TableName("system_tenant_points") @KeySequence("system_tenant_points_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Builder @NoArgsConstructor @AllArgsConstructor -public class TenantPointsDO extends BaseDO { +public class TenantPointsDO { /** * 主键 */ - @TableId + @TableId(type = IdType.AUTO) private Long id; /** * 本次变动点数,正加负减 @@ -63,5 +62,6 @@ public class TenantPointsDO extends BaseDO { */ private LocalDateTime createdAt; + private Long tenantId; } \ No newline at end of file diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenantbalance/TenantBalanceMapper.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenantbalance/TenantBalanceMapper.java index 8cfcfa2..e0feea7 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenantbalance/TenantBalanceMapper.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenantbalance/TenantBalanceMapper.java @@ -25,4 +25,9 @@ public interface TenantBalanceMapper extends BaseMapperX { .orderByDesc(TenantBalanceDO::getId)); } + default Integer updateBalanceWithVersion(TenantBalanceDO updateObj){ + return update(updateObj, new LambdaQueryWrapperX() + .eq(TenantBalanceDO::getId, updateObj.getId()) + .eq(TenantBalanceDO::getVersion, updateObj.getVersion())); + } } \ No newline at end of file diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/balance/BalanceEnum.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/balance/BalanceEnum.java new file mode 100644 index 0000000..6d11b12 --- /dev/null +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/balance/BalanceEnum.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.system.enums.balance; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/* + * @author: ziin + * @date: 2025/11/19 21:30 + */ +@Getter +@AllArgsConstructor +@NoArgsConstructor +public enum BalanceEnum { + + + RECHARGE("充值"), + TRANSFER("转账"), + CONSUMPTION("消费"); + + + private String desc; + + + + +} diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceService.java index 581682a..7582a02 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceService.java @@ -59,4 +59,5 @@ public interface TenantBalanceService { */ PageResult getTenantBalancePage(TenantBalancePageReqVO pageReqVO); + void addTenantBalance(@Valid TenantBalanceAddReqVO updateReqVO); } \ No newline at end of file diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceServiceImpl.java index 7f4958b..2cbc6a9 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenantbalance/TenantBalanceServiceImpl.java @@ -1,24 +1,27 @@ package cn.iocoder.yudao.module.system.service.tenantbalance; import cn.hutool.core.collection.CollUtil; -import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; -import cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo.*; -import cn.iocoder.yudao.module.system.dal.dataobject.tenantbalance.TenantBalanceDO; +import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; - +import cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo.TenantBalanceAddReqVO; +import cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo.TenantBalancePageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo.TenantBalanceSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.tenantbalance.TenantBalanceDO; +import cn.iocoder.yudao.module.system.dal.dataobject.tenantpoints.TenantPointsDO; import cn.iocoder.yudao.module.system.dal.mysql.tenantbalance.TenantBalanceMapper; +import cn.iocoder.yudao.module.system.dal.mysql.tenantpoints.TenantPointsMapper; +import cn.iocoder.yudao.module.system.util.BizNoGenerator; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TENANT_BALANCE_NOT_EXISTS; +import static cn.iocoder.yudao.module.system.enums.balance.BalanceEnum.RECHARGE; /** * 租户余额 Service 实现类 @@ -32,6 +35,9 @@ public class TenantBalanceServiceImpl implements TenantBalanceService { @Resource private TenantBalanceMapper tenantBalanceMapper; + @Resource + private TenantPointsMapper tenantPointsMapper; + @Override public Long createTenantBalance(TenantBalanceSaveReqVO createReqVO) { // 插入 @@ -89,4 +95,41 @@ public class TenantBalanceServiceImpl implements TenantBalanceService { return tenantBalanceMapper.selectPage(pageReqVO); } + @Override + @Transactional(rollbackFor = Exception.class) + public void addTenantBalance(TenantBalanceAddReqVO addReqVO) { + // 校验存在 + if (tenantBalanceMapper.selectById(addReqVO.getId()) == null) { + // 初始化余额为 0 + TenantBalanceDO tenantBalance = new TenantBalanceDO(); + tenantBalance.setId(addReqVO.getId()); + tenantBalance.setBalance(0); + tenantBalance.setVersion(0); + tenantBalanceMapper.insert(tenantBalance); + } + String recharge = BizNoGenerator.generate("RECHARGE"); + // 获取初始化查询结果 + + TenantBalanceDO tenantBalance = tenantBalanceMapper.selectById(addReqVO.getId()); + Integer newBalance = tenantBalance.getBalance()+addReqVO.getAmount(); + Integer oldVersion = tenantBalance.getVersion(); + + TenantBalanceDO updateObj = BeanUtils.toBean(addReqVO, TenantBalanceDO.class); + + updateObj.setVersion(oldVersion); + updateObj.setBalance(newBalance); + Integer updateCount = tenantBalanceMapper.updateBalanceWithVersion(updateObj); + if (updateCount == 0) { + throw exception(TENANT_BALANCE_NOT_EXISTS); + } + TenantPointsDO tenantPointsDO = new TenantPointsDO(); + tenantPointsDO.setTenantId(addReqVO.getId()); + tenantPointsDO.setPoints(addReqVO.getAmount()); + tenantPointsDO.setBalance(newBalance); + tenantPointsDO.setType(RECHARGE.getDesc()); // RECHARGE / BONUS / ... + tenantPointsDO.setDescription("后台加积分"); + tenantPointsDO.setBizNo(recharge); + tenantPointsMapper.insert(tenantPointsDO); + } + } \ No newline at end of file diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/util/BizNoGenerator.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/util/BizNoGenerator.java new file mode 100644 index 0000000..3e79919 --- /dev/null +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/util/BizNoGenerator.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.system.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.atomic.AtomicInteger; + +public class BizNoGenerator { + + private static final AtomicInteger SEQUENCE = new AtomicInteger(0); + private static final int MAX_SEQUENCE = 999999; + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd"); + + /** + * 生成通用业务流水号 + * 格式:PREFIX-yyyyMMdd-000001 + */ + public static String generate(String prefix) { + String date = DATE_FORMAT.format(new Date()); + + // 自增序列(每天重置) + int seq = SEQUENCE.incrementAndGet(); + if (seq > MAX_SEQUENCE) { + synchronized (BizNoGenerator.class) { + if (SEQUENCE.get() > MAX_SEQUENCE) { + SEQUENCE.set(1); + seq = 1; + } + } + } + + return prefix + "-" + date + "-" + String.format("%06d", seq); + } +} diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 2a97a81..842c034 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -193,6 +193,8 @@ yudao: - server_country_info - ai_comment - ai_language + - system_tenant_balance + - system_tenant_points ignore-caches: - user_role_ids - permission_menu_ids