feat(system): 新增套餐消费与余额校验逻辑
- 为 TenantAgencyPackage 增加 validTenantPackage 校验方法 - 在 TenantBalanceService 中实现基于套餐的消费接口 - 新增租户余额消费失败错误码 TENANT_BALANCE_CONSUMPTION_OPERATION_ERROR - 将积分记录 orderId 类型由 Long 改为 String 以兼容业务流水号 - 消费时自动生成 CONSUMPTION/ORDER 业务编号并记录积分变动
This commit is contained in:
@@ -34,7 +34,7 @@ public class TenantPointsPageRespVO {
|
||||
|
||||
@Schema(description = "订单 Id/业务单号", example = "84")
|
||||
@ExcelProperty("订单 Id/业务单号")
|
||||
private Long orderId;
|
||||
private String orderId;
|
||||
|
||||
@Schema(description = "业务流水号(转账、订单等唯一标识)")
|
||||
@ExcelProperty("业务流水号(转账、订单等唯一标识)")
|
||||
|
||||
@@ -34,7 +34,7 @@ public class TenantPointsRespVO {
|
||||
|
||||
@Schema(description = "订单 Id/业务单号", example = "84")
|
||||
@ExcelProperty("订单 Id/业务单号")
|
||||
private Long orderId;
|
||||
private String orderId;
|
||||
|
||||
@Schema(description = "业务流水号(转账、订单等唯一标识)")
|
||||
@ExcelProperty("业务流水号(转账、订单等唯一标识)")
|
||||
|
||||
@@ -28,7 +28,7 @@ public class TenantPointsSaveReqVO {
|
||||
private String description;
|
||||
|
||||
@Schema(description = "订单 Id/业务单号", example = "84")
|
||||
private Long orderId;
|
||||
private String orderId;
|
||||
|
||||
@Schema(description = "业务流水号(转账、订单等唯一标识)")
|
||||
private String bizNo;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.dal.dataobject.tenantagencypackage;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -42,7 +43,8 @@ public class TenantAgencyPackageDO extends BaseDO {
|
||||
/**
|
||||
* 关联的菜单编号
|
||||
*/
|
||||
private String menuIds;
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Set<Long> menuIds;
|
||||
/**
|
||||
* 套餐天数
|
||||
*/
|
||||
|
||||
@@ -44,7 +44,7 @@ public class TenantPointsDO {
|
||||
/**
|
||||
* 订单 Id/业务单号
|
||||
*/
|
||||
private Long orderId;
|
||||
private String orderId;
|
||||
/**
|
||||
* 业务流水号(转账、订单等唯一标识)
|
||||
*/
|
||||
|
||||
@@ -134,7 +134,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode TENANT_BALANCE_TRANSFER_PASSWORD_ERROR = new ErrorCode(1_003_017_010, "转账密码错误");
|
||||
ErrorCode TENANT_BALANCE_TRANSFER_PASSWORD_ERROR_IS_NULL = new ErrorCode(1_003_017_011, "转账密码不能为空");
|
||||
ErrorCode TENANT_BALANCE_TRANSFER_ERROR_TARGET_NOT_SUBORDINATE = new ErrorCode(1_003_017_012, "转账目标租户不是当前租户的下级");
|
||||
|
||||
ErrorCode TENANT_BALANCE_CONSUMPTION_OPERATION_ERROR = new ErrorCode(1_003_017_013, "租户余额消费操作失败");
|
||||
|
||||
// ================= 租户套餐 1-003-018-000 ==================
|
||||
ErrorCode TENANT_AGENCY_PACKAGE_NOT_EXISTS = new ErrorCode(1_003_018_000, "代理租户套餐不存在");
|
||||
|
||||
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.service.tenantagencypackage;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.admin.tenantagencypackage.vo.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenantagencypackage.TenantAgencyPackageDO;
|
||||
@@ -58,4 +60,5 @@ public interface TenantAgencyPackageService {
|
||||
*/
|
||||
PageResult<TenantAgencyPackageDO> getTenantAgencyPackagePage(TenantAgencyPackagePageReqVO pageReqVO);
|
||||
|
||||
TenantAgencyPackageDO validTenantPackage(@NotNull(message = "租户套餐编号不能为空") Long packageId);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package cn.iocoder.yudao.module.system.service.tenantagencypackage;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenantagencypackage.TenantAgencyPackageDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
@@ -85,4 +87,17 @@ public class TenantAgencyPackageServiceImpl implements TenantAgencyPackageServic
|
||||
return tenantAgencyPackageMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantAgencyPackageDO validTenantPackage(Long packageId) {
|
||||
|
||||
TenantAgencyPackageDO tenantPackage = tenantAgencyPackageMapper.selectById(packageId);
|
||||
if (tenantPackage == null) {
|
||||
throw exception(TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
if (tenantPackage.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
|
||||
throw exception(TENANT_PACKAGE_DISABLE, tenantPackage.getName());
|
||||
}
|
||||
return tenantPackage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,5 +67,5 @@ public interface TenantBalanceService {
|
||||
|
||||
PageResult<TenantBalanceRespVO> getSelfSubordinateTenantBalancePage(@Valid TenantBalancePageReqVO pageReqVO);
|
||||
|
||||
Boolean consumption(@Valid TenantBalanceConsumptionReqVO consumptionReqVO);
|
||||
Boolean consumption(Long PackageId, Long targetTenantId,String remark);
|
||||
}
|
||||
@@ -8,10 +8,12 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo.*;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenantagencypackage.TenantAgencyPackageDO;
|
||||
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.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.tenantagencypackage.TenantAgencyPackageMapper;
|
||||
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.enums.logger.LoginResultEnum;
|
||||
@@ -54,6 +56,9 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
|
||||
@Resource
|
||||
private TenantMapper tenantMapper;
|
||||
|
||||
@Resource
|
||||
private TenantAgencyPackageMapper tenantAgencyPackageMapper;
|
||||
|
||||
@Override
|
||||
public Long createTenantBalance(TenantBalanceSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
@@ -295,20 +300,56 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean consumption(TenantBalanceConsumptionReqVO consumptionReqVO) {
|
||||
public Boolean consumption(Long PackageId, Long targetTenantId,String remark) {
|
||||
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
// TenantBalanceDO tenantBalance = tenantBalanceMapper.selectById(tenantId);
|
||||
// if (tenantBalance == null) {
|
||||
// throw exception(TENANT_WALLET_NOT_EXISTS);
|
||||
// }
|
||||
// if (tenantBalance.getBalance() < consumptionReqVO.getAmount()) {
|
||||
// throw exception(TENANT_WALLET_NOT_ENOUGH);
|
||||
// }
|
||||
// Integer updateCount = tenantBalanceMapper.updateBalanceWithVersion(tenantId, -consumptionReqVO.getAmount(), tenantBalance.getVersion());
|
||||
// if (updateCount == 0) {
|
||||
// throw exception(TENANT_BALANCE_CONSUMPTION_OPERATION_ERROR);
|
||||
// }
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
|
||||
String consumption = BizNoGenerator.generate("CONSUMPTION");
|
||||
String order = BizNoGenerator.generate("ORDER");
|
||||
|
||||
// 从数据库中查询租户余额
|
||||
TenantBalanceDO tenantBalance = tenantBalanceMapper.selectById(tenantId);
|
||||
if (tenantBalance == null) {
|
||||
throw exception(TENANT_WALLET_NOT_EXISTS);
|
||||
}
|
||||
// 从数据库中查询套餐信息
|
||||
TenantAgencyPackageDO tenantAgencyPackageDO = tenantAgencyPackageMapper.selectById(PackageId);
|
||||
if (tenantAgencyPackageDO == null) {
|
||||
throw exception(TENANT_AGENCY_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
// 检查租户余额是否足够
|
||||
if (tenantBalance.getBalance() < tenantAgencyPackageDO.getPrice()) {
|
||||
throw exception(TENANT_BALANCE_BALANCE_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
Integer tenantBalanceDOVersion = tenantBalance.getVersion();
|
||||
|
||||
Integer oldBalance = tenantBalance.getBalance();
|
||||
// 更新租户余额
|
||||
Integer updateCount = tenantBalanceMapper.updateBalanceWithVersion(tenantId, -tenantAgencyPackageDO.getPrice(), tenantBalanceDOVersion);
|
||||
|
||||
if (updateCount == 0) {
|
||||
throw exception(TENANT_BALANCE_CONSUMPTION_OPERATION_ERROR);
|
||||
}
|
||||
|
||||
// 消费积分变动记录
|
||||
TenantPointsDO tenantPointsDO = new TenantPointsDO();
|
||||
tenantPointsDO.setTenantId(tenantId); // 设置租户ID
|
||||
tenantPointsDO.setPoints(-tenantAgencyPackageDO.getPrice()); // 设置变动积分(负数表示减少)
|
||||
tenantPointsDO.setBalance(oldBalance - tenantAgencyPackageDO.getPrice()); // 设置变动后的余额
|
||||
tenantPointsDO.setOperatorId(loginUserId); // 设置操作人ID
|
||||
tenantPointsDO.setType(CONSUMPTION.getDesc()); // 设置交易类型为转账
|
||||
tenantPointsDO.setDescription("给租户" + targetTenantId + "开通套餐" + tenantAgencyPackageDO.getName() + ",金额:" + tenantAgencyPackageDO.getPrice()); // 设置交易描述
|
||||
tenantPointsDO.setTargetTenantId(targetTenantId); // 设置目标租户ID
|
||||
tenantPointsDO.setBizNo(consumption); // 设置业务流水号
|
||||
tenantPointsDO.setRemark(remark);
|
||||
tenantPointsDO.setOrderId(order);
|
||||
int tenantInsert = tenantPointsMapper.insert(tenantPointsDO); // 插入记录
|
||||
if (tenantInsert == 0) {
|
||||
throw exception(TENANT_BALANCE_CONSUMPTION_OPERATION_ERROR);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user