@@ -5,14 +5,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils ;
import cn.iocoder.yudao.framework.security.core.LoginUser ;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils ;
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.TenantBalanceRespVO ;
import cn.iocoder.yudao.module.system.controller.admin.tenantbalance.vo.TenantBalanceSaveReqVO ;
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.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.tenantbalance.TenantBalanceMapper ;
import cn.iocoder.yudao.module.system.dal.mysql.tenantpoints.TenantPointsMapper ;
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum ;
import cn.iocoder.yudao.module.system.service.user.AdminUserService ;
import cn.iocoder.yudao.module.system.util.BizNoGenerator ;
import com.baomidou.mybatisplus.core.metadata.IPage ;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page ;
@@ -26,6 +27,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception ;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.* ;
import static cn.iocoder.yudao.module.system.enums.balance.BalanceEnum.RECHARGE ;
import static cn.iocoder.yudao.module.system.enums.balance.BalanceEnum.TRANSFER ;
/**
* 租户余额 Service 实现类
@@ -42,6 +44,9 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
@Resource
private TenantPointsMapper tenantPointsMapper ;
@Resource
private AdminUserService userService ;
@Override
public Long createTenantBalance ( TenantBalanceSaveReqVO createReqVO ) {
// 插入
@@ -121,10 +126,6 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
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 ( addReqVO . getId ( ) , addReqVO . getAmount ( ) , oldVersion ) ;
if ( updateCount = = 0 ) {
throw exception ( TENANT_BALANCE_RECHARGE_ERROR ) ;
@@ -145,4 +146,117 @@ public class TenantBalanceServiceImpl implements TenantBalanceService {
tenantPointsMapper . insert ( tenantPointsDO ) ;
}
@Override
@Transactional ( rollbackFor = Exception . class )
public void transferToTenant ( TenantBalanceTransferReqVO transferReqVO ) {
/**
* 执行租户余额转账操作
* 注:这部分代码应该位于某个转账相关的方法中
*/
// 获取当前登录用户ID, 用于操作记录和权限验证
Long loginUserId = SecurityFrameworkUtils . getLoginUserId ( ) ;
// 生成转账业务流水号,用于唯一标识这笔转账交易
String transfer = BizNoGenerator . generate ( " TRANSFER " ) ;
// 验证转账密码是否为空
if ( transferReqVO . getPassword ( ) . isEmpty ( ) ) {
throw exception ( TENANT_BALANCE_TRANSFER_PASSWORD_ERROR_IS_NULL ) ;
}
// 获取当前登录用户信息
AdminUserDO user = userService . getUser ( loginUserId ) ;
// 验证转账密码是否正确
if ( ! userService . isPasswordMatch ( transferReqVO . getPassword ( ) , user . getPassword ( ) ) ) {
throw exception ( TENANT_BALANCE_TRANSFER_PASSWORD_ERROR ) ;
}
// 获取当前租户ID( 转出方)
Long tenantId = TenantContextHolder . getTenantId ( ) ;
// 校验当前租户钱包是否存在
TenantBalanceDO tenantBalanceDO = tenantBalanceMapper . selectById ( tenantId ) ;
if ( tenantBalanceDO = = null ) {
throw exception ( TENANT_WALLET_NOT_EXISTS ) ;
}
// 获取目标租户(转入方)的余额信息
TenantBalanceDO targetTenantBalance = tenantBalanceMapper . selectById ( transferReqVO . getTargetTenantId ( ) ) ;
// 校验目标租户钱包是否存在
if ( targetTenantBalance = = null ) {
throw exception ( TENANT_BALANCE_TRANSFER_TARGET_NOT_EXISTS ) ;
}
// 校验当前租户余额是否足够支付转账金额
if ( tenantBalanceDO . getBalance ( ) < transferReqVO . getTransferAmount ( ) ) {
throw exception ( TENANT_BALANCE_NOT_ENOUGH ) ;
}
// 校验转账金额是否有效( 必须大于0)
if ( transferReqVO . getTransferAmount ( ) < = 0 ) {
throw exception ( TENANT_BALANCE_TRANSFER_ERROR ) ;
}
// 计算转账后转出方的新余额
Integer tenantNewBalance = tenantBalanceDO . getBalance ( ) - transferReqVO . getTransferAmount ( ) ;
// 计算转账后转入方的新余额
Integer targetTenantNewBalance = targetTenantBalance . getBalance ( ) + transferReqVO . getTransferAmount ( ) ;
// 获取转出方当前的版本号(用于乐观锁控制)
Integer tenantBalanceDOVersion = tenantBalanceDO . getVersion ( ) ;
// 获取转入方当前的版本号(用于乐观锁控制)
Integer targetTenantBalanceVersion = targetTenantBalance . getVersion ( ) ;
// 先更新转入方的余额(使用乐观锁)
Integer updateTargetBalanceCount = tenantBalanceMapper
. updateBalanceWithVersion ( transferReqVO . getTargetTenantId ( ) , transferReqVO . getTransferAmount ( ) , targetTenantBalanceVersion ) ;
// 如果更新转入方失败,抛出异常
if ( updateTargetBalanceCount = = 0 ) {
throw exception ( TENANT_BALANCE_TRANSFER_OPERATION_ERROR ) ;
}
// 再更新转出方的余额(使用乐观锁,金额为负数表示减少)
Integer updateCount = tenantBalanceMapper
. updateBalanceWithVersion ( tenantId , - transferReqVO . getTransferAmount ( ) , tenantBalanceDOVersion ) ;
// 如果更新转出方失败,抛出异常
if ( updateCount = = 0 ) {
throw exception ( TENANT_BALANCE_TRANSFER_OPERATION_ERROR ) ;
}
// 创建转出方的积分变动记录
TenantPointsDO tenantPointsDO = new TenantPointsDO ( ) ;
tenantPointsDO . setTenantId ( tenantId ) ; // 设置租户ID
tenantPointsDO . setPoints ( - transferReqVO . getTransferAmount ( ) ) ; // 设置变动积分(负数表示减少)
tenantPointsDO . setBalance ( tenantNewBalance ) ; // 设置变动后的余额
tenantPointsDO . setOperatorId ( loginUserId ) ; // 设置操作人ID
tenantPointsDO . setType ( TRANSFER . getDesc ( ) ) ; // 设置交易类型为转账
tenantPointsDO . setDescription ( transferReqVO . getDescription ( ) ) ; // 设置交易描述
tenantPointsDO . setBizNo ( transfer ) ; // 设置业务流水号
int tenantInsert = tenantPointsMapper . insert ( tenantPointsDO ) ; // 插入记录
// 创建转入方的积分变动记录
TenantPointsDO targetPointsDO = new TenantPointsDO ( ) ;
targetPointsDO . setTenantId ( transferReqVO . getTargetTenantId ( ) ) ; // 设置目标租户ID
targetPointsDO . setPoints ( transferReqVO . getTransferAmount ( ) ) ; // 设置变动积分(正数表示增加)
targetPointsDO . setBalance ( targetTenantNewBalance ) ; // 设置变动后的余额
targetPointsDO . setOperatorId ( loginUserId ) ; // 设置操作人ID
targetPointsDO . setType ( TRANSFER . getDesc ( ) ) ; // 设置交易类型为转账
targetPointsDO . setDescription ( transferReqVO . getDescription ( ) ) ; // 设置交易描述
targetPointsDO . setBizNo ( transfer ) ; // 设置业务流水号(与转出方使用同一个流水号)
int targetInsert = tenantPointsMapper . insert ( targetPointsDO ) ; // 插入记录
// 验证交易记录是否都插入成功
if ( tenantInsert = = 0 | | targetInsert = = 0 ) {
throw exception ( TENANT_BALANCE_TRANSFER_OPERATION_ERROR ) ;
}
}
}