This commit is contained in:
张良(004796)
2024-01-05 18:18:21 +08:00
parent 4bc8850fad
commit 0fa2841213
25 changed files with 605 additions and 209 deletions

View File

@@ -30,6 +30,7 @@ public class AccountCash implements Serializable {
* *
*/ */
private Long userId; private Long userId;
private Long traceId;
/** /**
* 订单号 * 订单号
*/ */

View File

@@ -3,6 +3,7 @@ package com.ruoyi.cai.domain;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import org.springframework.web.bind.annotation.DeleteMapping;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -28,7 +29,7 @@ public class AccountChangeLog implements Serializable {
/** /**
* 用户ID * 用户ID
*/ */
private Integer userId; private Long userId;
/** /**
* 蜜瓜号 * 蜜瓜号
*/ */
@@ -44,15 +45,12 @@ public class AccountChangeLog implements Serializable {
/** /**
* 名称 * 名称
*/ */
private Integer cateName; private String cateName;
/** private Long traceId;
* 业务码
*/
private Long businessCode;
/** /**
* 变化值,为正 或者为负 * 变化值,为正 或者为负
*/ */
private BigDecimal changeValue; private Long changeValue;
/** /**
* 备注 * 备注
*/ */
@@ -60,6 +58,7 @@ public class AccountChangeLog implements Serializable {
/** /**
* 操作IP * 操作IP
*/ */
@Deprecated
private String operateIp; private String operateIp;
/** /**
* 是否为后台用户手动调整 * 是否为后台用户手动调整

View File

@@ -30,10 +30,15 @@ public class ConsumeLog implements Serializable {
* 类型 1-充值 2-礼物 3-守护 4-通话 * 类型 1-充值 2-礼物 3-守护 4-通话
*/ */
private Integer type; private Integer type;
/** /**
* 业务ID * 业务状态码
*/ */
private Integer sourceBusinessId; private String businessEnum;
/**
* 跟踪ID
*/
private Long traceId;
/** /**
* 发生金额 * 发生金额
*/ */
@@ -163,9 +168,11 @@ public class ConsumeLog implements Serializable {
this.setSourceUserId(fromUser.getId()); this.setSourceUserId(fromUser.getId());
this.setSourcePhone(fromUser.getMobile()); this.setSourcePhone(fromUser.getMobile());
this.setSourceUsercode(fromUser.getUsercode()); this.setSourceUsercode(fromUser.getUsercode());
if(toUser != null){
this.setTargetUserId(toUser.getId()); this.setTargetUserId(toUser.getId());
this.setTargetUsercode(toUser.getUsercode()); this.setTargetUsercode(toUser.getUsercode());
this.setTargetPhone(toUser.getMobile()); this.setTargetPhone(toUser.getMobile());
} }
}
} }

View File

@@ -47,10 +47,7 @@ public class GuardLog implements Serializable {
* 守护值 * 守护值
*/ */
private Long guardValue; private Long guardValue;
/** private Long traceId;
* 流水ID
*/
private Long consumeLogId;
private LocalDateTime createTime; private LocalDateTime createTime;
private LocalDateTime updateTime; private LocalDateTime updateTime;

View File

@@ -30,6 +30,7 @@ public class RechargeOrder implements Serializable {
* 用户ID * 用户ID
*/ */
private Long userId; private Long userId;
private Long traceId;
/** /**
* 商品ID * 商品ID
*/ */

View File

@@ -57,7 +57,7 @@ public class UserGift implements Serializable {
*/ */
private Long giftAmount; private Long giftAmount;
private Long consumerLogId; private Long traceId;
private LocalDateTime createTime; private LocalDateTime createTime;

View File

@@ -5,43 +5,47 @@ import lombok.Getter;
@Getter @Getter
public enum AccountBusinessEnum { public enum AccountBusinessEnum {
// 用户端 /**
A1("101","紫贝充值","增加充值的紫贝"), * 提现
A2("102","注册奖励","增加充值的紫贝"), */
A3("103","首充奖励","增加充值的紫贝"), WITHDRAW(AccountChangeEnum.WITHDRAW,null,null,null),
A4("104","送出礼物","扣除紫贝"), /**
A5("105","送出守护","扣除紫贝"), * 守护
A6("106","视频支出","扣除紫贝"), */
A7("106","聊天支出","扣除紫贝"), GUARD(AccountChangeEnum.USER_GUARD,AccountChangeEnum.ANCHOR_GUARD,AccountChangeEnum.ONE_GUARD,AccountChangeEnum.UNION_GUARD),
A8("108","提现","扣除收益的紫贝"), /**
* 赠送礼物
*/
GIFT(AccountChangeEnum.USER_GIFT,AccountChangeEnum.ANCHOR_GIFT,AccountChangeEnum.ONE_GIFT,AccountChangeEnum.UNION_GIFT),
/**
* 视频
*/
VIDEO(AccountChangeEnum.USER_VIDEO,AccountChangeEnum.ANCHOR_VIDEO,AccountChangeEnum.ONE_VIDEO,AccountChangeEnum.UNION_VIDEO),
// 主播端 /**
B1("201","收到礼物","增加收益的紫贝"), * 充值
B2("202","收到守护","增加收益的紫贝"), */
B3("203","视频收入","增加收益的紫贝"), RECHARGE(AccountChangeEnum.USER_RECHARGE,null,AccountChangeEnum.ONE_RECHARGE,null),
// 分销
C1("301","充值分成","增加收益的紫贝"),
C2("301","礼物分成","增加收益的紫贝"),
C3("301","守护分成","增加收益的紫贝"),
C4("301","视频分成","增加收益的紫贝"),
// 工会
D1("401","礼物工会分成","增加收益的紫贝"),
D2("401","守护工会分成","增加收益的紫贝"),
D3("401","视频工会分成","增加收益的紫贝"),
// 系统
Z1("1001","系统调账","系统调账"),
; ;
private final AccountChangeEnum sourceEnum;
private final AccountChangeEnum targetEnum;
private final AccountChangeEnum oneEnum;
private final AccountChangeEnum unionEnum;
private final String code; AccountBusinessEnum(AccountChangeEnum sourceEnum, AccountChangeEnum targetEnum, AccountChangeEnum oneEnum, AccountChangeEnum unionEnum) {
private final String name; this.sourceEnum = sourceEnum;
private final String desc; this.targetEnum = targetEnum;
this.oneEnum = oneEnum;
this.unionEnum = unionEnum;
}
AccountBusinessEnum(String code, String name, String desc) { public static AccountBusinessEnum getByName(String name){
this.code = code; AccountBusinessEnum[] values = AccountBusinessEnum.values();
this.name = name; for (AccountBusinessEnum value : values) {
this.desc = desc; if(value.name().equals(name)){
return value;
}
}
return null;
} }
} }

View File

@@ -0,0 +1,50 @@
package com.ruoyi.cai.enums;
import lombok.Getter;
@Getter
public enum AccountChangeEnum {
// 用户端
USER_RECHARGE(101,"充值",""),
// A2(102,"注册奖励","增加充值的紫贝"),
// A3(103,"首充奖励","增加充值的紫贝"),
USER_GIFT(104,"送出礼物",""),
USER_GUARD(105,"送出守护",""),
USER_VIDEO(106,"视频支出",""),
A7(107,"聊天支出",""),
WITHDRAW(108,"提现",""),
// 主播端
ANCHOR_GIFT(201,"收到礼物",""),
ANCHOR_GUARD(202,"收到守护",""),
ANCHOR_VIDEO(203,"视频收入",""),
// 分销
ONE_RECHARGE(301,"充值分成",""),
ONE_GIFT(302,"礼物分成",""),
ONE_GUARD(303,"守护分成",""),
ONE_VIDEO(304,"视频分成",""),
// 工会
UNION_GIFT(401,"礼物工会分成",""),
UNION_GUARD(402,"守护工会分成",""),
UNION_VIDEO(403,"视频工会分成",""),
// 系统
SYSTEM_COIN_INCS(1001,"系统调账","后台人工调增余额"),
SYSTEM_COIN_DECR(1002,"系统调账","后台人工调减余额"),
SYSTEM_INCOME_COIN_INCS(1003,"系统调账","后台人工调增收益"),
SYSTEM_INCOME_COIN_DECR(1004,"系统调账","后台人工调减收益"),
;
private final Integer code;
private final String name;
private final String desc;
AccountChangeEnum(Integer code, String name, String desc) {
this.code = code;
this.name = name;
this.desc = desc;
}
}

View File

@@ -0,0 +1,20 @@
package com.ruoyi.cai.enums;
import lombok.Getter;
/**
* -1-无须分销 0-待分销 1-已分销
* <p>created on 2024/1/5 16:40</p>
* @author duet
*/
@Getter
public enum ConsumeLogStatus {
NO(-1),
READY(0),
ALREADY(1);
private final Integer code;
ConsumeLogStatus(Integer code) {
this.code = code;
}
}

View File

@@ -11,7 +11,7 @@ import org.springframework.stereotype.Component;
*/ */
@Getter @Getter
public enum ConsumeLogType { public enum ConsumeLogType {
PAY(1), RECHARGE(1),
GIFT(2), GIFT(2),
GUARD(3), GUARD(3),
VIDEO(4), VIDEO(4),

View File

@@ -0,0 +1,26 @@
package com.ruoyi.cai.manager;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
public class IdManager {
private static final Snowflake SNOWFLAKE;
static {
int dataId = 1;
String id = System.getProperty("DATA_ID");
if(id != null){
dataId = Integer.parseInt(id);
}
SNOWFLAKE = IdUtil.getSnowflake(1, dataId);
}
public static Long nextId(){
return SNOWFLAKE.nextId();
}
public static String nextIdStr(){
return SNOWFLAKE.nextIdStr();
}
}

View File

@@ -8,6 +8,8 @@ public class LockManager {
public static final String LOCK_DEAL_INVITE_REDIS = RedisConstant.REDIS_P + "lock:dealInvite:%s"; public static final String LOCK_DEAL_INVITE_REDIS = RedisConstant.REDIS_P + "lock:dealInvite:%s";
public static final String LOCK_ADD_USER_GREET_REDIS = RedisConstant.REDIS_P + "lock:addUserGreet:%s"; public static final String LOCK_ADD_USER_GREET_REDIS = RedisConstant.REDIS_P + "lock:addUserGreet:%s";
public static final String LOCK_SEND_GREET_REDIS = RedisConstant.REDIS_P + "lock:sendGreet:%s"; public static final String LOCK_SEND_GREET_REDIS = RedisConstant.REDIS_P + "lock:sendGreet:%s";
public static final String LOCK_SEND_GUARD_REDIS = RedisConstant.REDIS_P + "lock:sendGuard:%s";
public static final String LOCK_SEND_GIFT_REDIS = RedisConstant.REDIS_P + "lock:sendGift:%s";
public static String getRegisterLockKey(String mobile){ public static String getRegisterLockKey(String mobile){
return String.format(LOCK_REGISTER_REDIS,mobile); return String.format(LOCK_REGISTER_REDIS,mobile);
@@ -24,4 +26,12 @@ public class LockManager {
public static String getSendGreetLock(Long userId){ public static String getSendGreetLock(Long userId){
return String.format(LOCK_SEND_GREET_REDIS,userId); return String.format(LOCK_SEND_GREET_REDIS,userId);
} }
public static String getSendGuardLock(Long userId){
return String.format(LOCK_SEND_GUARD_REDIS,userId);
}
public static String getSendGiftLock(Long userId){
return String.format(LOCK_SEND_GIFT_REDIS,userId);
}
} }

View File

@@ -2,6 +2,10 @@ package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.AccountChangeLog; import com.ruoyi.cai.domain.AccountChangeLog;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.AccountChangeEnum;
import com.ruoyi.cai.pay.RechargeTypeEnum;
/** /**
* 账户明细Service接口 * 账户明细Service接口
@@ -11,4 +15,9 @@ import com.ruoyi.cai.domain.AccountChangeLog;
*/ */
public interface AccountChangeLogService extends IService<AccountChangeLog> { public interface AccountChangeLogService extends IService<AccountChangeLog> {
AccountChangeLog saveLogNoAdmin(Long userId, String usercode, RechargeTypeEnum rechargeTypeEnum, AccountChangeEnum accountChangeEnum, Long price,Long traceId);
AccountChangeLog saveLog(Long userId,String usercode, RechargeTypeEnum rechargeTypeEnum, AccountChangeEnum accountChangeEnum, Long price, Long traceId,Integer admin);
AccountChangeLog saveLogAdmin(Long userId,String usercode, RechargeTypeEnum rechargeTypeEnum, AccountChangeEnum accountChangeEnum, Long price,Long traceId);
} }

View File

@@ -5,7 +5,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.Account; import com.ruoyi.cai.domain.Account;
import com.ruoyi.cai.domain.ConsumeLog; import com.ruoyi.cai.domain.ConsumeLog;
import com.ruoyi.cai.dto.admin.vo.AccountAdminVo; import com.ruoyi.cai.dto.admin.vo.AccountAdminVo;
import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.AccountChangeEnum;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 用户账户Service接口 * 用户账户Service接口
@@ -17,9 +20,13 @@ public interface AccountService extends IService<Account> {
Account getByUserId(Long userId); Account getByUserId(Long userId);
ConsumeLog decr(ConsumeLog log); ConsumeLog decr(ConsumeLog log, AccountBusinessEnum businessEnum);
void withdraw(Long userId, Long incomeCoin); void withdraw(Long userId, Long incomeCoin, Long traceId);
void recharge(ConsumeLog consumeLog);
Page<AccountAdminVo> pageAdmin(PageQuery pageQuery, AccountAdminVo bo); Page<AccountAdminVo> pageAdmin(PageQuery pageQuery, AccountAdminVo bo);
void distribution(Long userId, Long amount, AccountChangeEnum oneEnum,Long traceId);
} }

View File

@@ -11,4 +11,7 @@ import com.ruoyi.cai.domain.ConsumeLog;
*/ */
public interface ConsumeLogService extends IService<ConsumeLog> { public interface ConsumeLogService extends IService<ConsumeLog> {
void dealFenxiao(Long id);
ConsumeLog calculateInitFenxiao(ConsumeLog consumeLog);
} }

View File

@@ -7,6 +7,7 @@ import com.ruoyi.cai.dto.AddRechargeOrderAdminDto;
import com.ruoyi.cai.dto.AddRechargeOrderDto; import com.ruoyi.cai.dto.AddRechargeOrderDto;
import com.ruoyi.cai.dto.admin.vo.RechargeOrderAdminVo; import com.ruoyi.cai.dto.admin.vo.RechargeOrderAdminVo;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 充值订单Service接口 * 充值订单Service接口
@@ -16,9 +17,14 @@ import com.ruoyi.common.core.domain.PageQuery;
*/ */
public interface RechargeOrderService extends IService<RechargeOrder> { public interface RechargeOrderService extends IService<RechargeOrder> {
RechargeOrder getByOrderNo(String orderNo);
Page<RechargeOrderAdminVo> pageAdmin(PageQuery pageQuery, RechargeOrderAdminVo bo); Page<RechargeOrderAdminVo> pageAdmin(PageQuery pageQuery, RechargeOrderAdminVo bo);
RechargeOrder addRechargeOrder(AddRechargeOrderDto addRechargeOrderDto); RechargeOrder addRechargeOrder(AddRechargeOrderDto addRechargeOrderDto);
@Transactional(rollbackFor = Exception.class)
void orderSuccess(String orderNo);
RechargeOrder updateAdminRechargeOrder(AddRechargeOrderAdminDto dto); RechargeOrder updateAdminRechargeOrder(AddRechargeOrderAdminDto dto);
} }

View File

@@ -8,6 +8,7 @@ import com.ruoyi.cai.domain.AccountCash;
import com.ruoyi.cai.domain.WithdrawExchange; import com.ruoyi.cai.domain.WithdrawExchange;
import com.ruoyi.cai.dto.admin.vo.AccountCashAdminVo; import com.ruoyi.cai.dto.admin.vo.AccountCashAdminVo;
import com.ruoyi.cai.dto.app.query.WithdrawReq; import com.ruoyi.cai.dto.app.query.WithdrawReq;
import com.ruoyi.cai.manager.IdManager;
import com.ruoyi.cai.mapper.AccountCashMapper; import com.ruoyi.cai.mapper.AccountCashMapper;
import com.ruoyi.cai.service.AccountCashService; import com.ruoyi.cai.service.AccountCashService;
import com.ruoyi.cai.service.AccountBankcardService; import com.ruoyi.cai.service.AccountBankcardService;
@@ -39,10 +40,12 @@ public class AccountCashServiceImpl extends ServiceImpl<AccountCashMapper, Accou
if(withdrawExchange == null){ if(withdrawExchange == null){
throw new ServiceException("参数不正确"); throw new ServiceException("参数不正确");
} }
Long traceId = IdManager.nextId();
Long coinNum = withdrawExchange.getCoinNum(); Long coinNum = withdrawExchange.getCoinNum();
accountService.withdraw(res.getUserId(), coinNum); accountService.withdraw(res.getUserId(), coinNum,traceId);
AccountCash cash = new AccountCash(); AccountCash cash = new AccountCash();
cash.setUserId(res.getUserId()); cash.setUserId(res.getUserId());
cash.setTraceId(traceId);
cash.setOrderNo("orderNo"); cash.setOrderNo("orderNo");
cash.setWithdrawCoin(coinNum); cash.setWithdrawCoin(coinNum);
cash.setCashMoney(BigDecimal.valueOf(withdrawExchange.getMoney())); cash.setCashMoney(BigDecimal.valueOf(withdrawExchange.getMoney()));

View File

@@ -2,7 +2,9 @@ package com.ruoyi.cai.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.AccountChangeLog; import com.ruoyi.cai.domain.AccountChangeLog;
import com.ruoyi.cai.enums.AccountChangeEnum;
import com.ruoyi.cai.mapper.AccountChangeLogMapper; import com.ruoyi.cai.mapper.AccountChangeLogMapper;
import com.ruoyi.cai.pay.RechargeTypeEnum;
import com.ruoyi.cai.service.AccountChangeLogService; import com.ruoyi.cai.service.AccountChangeLogService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -15,4 +17,34 @@ import org.springframework.stereotype.Service;
@Service @Service
public class AccountChangeLogServiceImpl extends ServiceImpl<AccountChangeLogMapper,AccountChangeLog> implements AccountChangeLogService { public class AccountChangeLogServiceImpl extends ServiceImpl<AccountChangeLogMapper,AccountChangeLog> implements AccountChangeLogService {
@Override
public AccountChangeLog saveLogNoAdmin(Long userId, String usercode, RechargeTypeEnum rechargeTypeEnum, AccountChangeEnum accountChangeEnum, Long price,Long traceId){
return this.saveLog(userId,usercode,rechargeTypeEnum,accountChangeEnum,price,traceId,0);
}
@Override
public AccountChangeLog saveLog(Long userId,String usercode, RechargeTypeEnum rechargeTypeEnum,
AccountChangeEnum accountChangeEnum, Long price, Long traceId,Integer admin){
AccountChangeLog log = new AccountChangeLog();
log.setUserId(userId);
log.setUsercode(usercode);
log.setTraceId(traceId);
log.setAccountType(rechargeTypeEnum.getCode());
log.setCateId(accountChangeEnum.getCode());
log.setCateName(accountChangeEnum.getName());
log.setRemark(accountChangeEnum.getDesc());
log.setChangeValue(price);
// log.setRemark();
log.setIsAdmin(admin);
this.save(log);
return log;
}
@Override
public AccountChangeLog saveLogAdmin(Long userId, String usercode, RechargeTypeEnum rechargeTypeEnum, AccountChangeEnum accountChangeEnum, Long price,Long traceId) {
return this.saveLog(userId,usercode,rechargeTypeEnum,accountChangeEnum,price,traceId,1);
}
} }

View File

@@ -6,8 +6,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.*; import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.admin.vo.AccountAdminVo; import com.ruoyi.cai.dto.admin.vo.AccountAdminVo;
import com.ruoyi.cai.enums.ConsumeLogType; import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.AccountChangeEnum;
import com.ruoyi.cai.mapper.AccountMapper; import com.ruoyi.cai.mapper.AccountMapper;
import com.ruoyi.cai.pay.RechargeTypeEnum;
import com.ruoyi.cai.service.*; import com.ruoyi.cai.service.*;
import com.ruoyi.cai.util.NumCaUtil; import com.ruoyi.cai.util.NumCaUtil;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
@@ -30,15 +32,9 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
@Autowired @Autowired
private ConsumeLogService consumeLogService; private ConsumeLogService consumeLogService;
@Autowired @Autowired
private UserInviteService userInviteService;
@Autowired
private UserService userService; private UserService userService;
@Autowired @Autowired
private UnionUserService unionUserService; private AccountChangeLogService accountChangeLogService;
@Autowired
private UnionService unionService;
@Autowired
private UserInfoService userInfoService;
@Override @Override
@@ -48,7 +44,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ConsumeLog decr(ConsumeLog consumeLog) { public ConsumeLog decr(ConsumeLog consumeLog, AccountBusinessEnum businessEnum) {
log.info("开始扣费 consumeLog={}", JSON.toJSONString(consumeLog)); log.info("开始扣费 consumeLog={}", JSON.toJSONString(consumeLog));
Long userId = consumeLog.getSourceUserId(); Long userId = consumeLog.getSourceUserId();
Long amount = consumeLog.getAmount(); Long amount = consumeLog.getAmount();
@@ -59,12 +55,15 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
throw new ServiceException("余额不足"); throw new ServiceException("余额不足");
} }
boolean flag = false; boolean flag = false;
long coin = account.getCoin();
long incomeCoin = 0;
long diff = account.getCoin() - amount; long diff = account.getCoin() - amount;
// 充值币够用 // 充值币够用
if(diff > 0){ if(diff > 0){
long l = baseMapper.decrCoin(userId, amount); long l = baseMapper.decrCoin(userId, coin);
flag = l > 0; flag = l > 0;
} else { // 充值币不够用 } else { // 充值币不够用
incomeCoin = diff;
long decrCoin = baseMapper.decrCoin(userId, account.getCoin()); long decrCoin = baseMapper.decrCoin(userId, account.getCoin());
long decrIncomeCoin = baseMapper.decrIncomeCoin(userId, -diff); long decrIncomeCoin = baseMapper.decrIncomeCoin(userId, -diff);
if(decrCoin > 0 && decrIncomeCoin > 0){ if(decrCoin > 0 && decrIncomeCoin > 0){
@@ -80,19 +79,30 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
if(targetUserId != null){ if(targetUserId != null){
Long anchorAmount = NumCaUtil.coin(amount,consumeLog.getTargetRate()); Long anchorAmount = NumCaUtil.coin(amount,consumeLog.getTargetRate());
consumeLog.setAnchorAmount(anchorAmount); consumeLog.setAnchorAmount(anchorAmount);
baseMapper.incsCoin(targetUserId,anchorAmount); baseMapper.incsIncomeCoin(targetUserId,anchorAmount);
}
// 记录消费方的流水
if(coin != 0){
accountChangeLogService.saveLogNoAdmin(userId,consumeLog.getSourceUsercode(), RechargeTypeEnum.COIN,businessEnum.getSourceEnum(),coin,consumeLog.getTraceId());
}
if(incomeCoin != 0){
accountChangeLogService.saveLogNoAdmin(userId,consumeLog.getSourceUsercode(), RechargeTypeEnum.COIN_INCOME,businessEnum.getSourceEnum(),incomeCoin,consumeLog.getTraceId());
}
if(targetUserId != null){
accountChangeLogService.saveLogNoAdmin(targetUserId,consumeLog.getTargetUsercode(), RechargeTypeEnum.COIN_INCOME,businessEnum.getTargetEnum(),incomeCoin,consumeLog.getTraceId());
} }
// 获取分销的比例和用户 // 获取分销的比例和用户
fenxiao(consumeLog); consumeLogService.calculateInitFenxiao(consumeLog);
consumeLogService.save(consumeLog); consumeLogService.save(consumeLog);
return consumeLog; return consumeLog;
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void withdraw(Long userId, Long incomeCoin){ public void withdraw(Long userId, Long incomeCoin,Long traceId){
User user = userService.getById(userId);
Account account = this.getByUserId(userId); Account account = this.getByUserId(userId);
if(account == null){ if(account == null || user == null){
throw new ServiceException("无效账号"); throw new ServiceException("无效账号");
} }
if(account.getIncomeCoin() < incomeCoin){ if(account.getIncomeCoin() < incomeCoin){
@@ -102,80 +112,50 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
if(incs <= 0){ if(incs <= 0){
throw new ServiceException(""+incomeCoin+"紫贝才可提现"); throw new ServiceException(""+incomeCoin+"紫贝才可提现");
} }
// TODO accountChangeLogService.saveLogNoAdmin(user.getId(),user.getUsercode(), RechargeTypeEnum.COIN_INCOME,AccountBusinessEnum.WITHDRAW.getSourceEnum(),incomeCoin,traceId);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void recharge(ConsumeLog consumeLog){
log.info("开始扣费 consumeLog={}", JSON.toJSONString(consumeLog));
Long userId = consumeLog.getSourceUserId();
Long amount = consumeLog.getAmount();
User user = userService.getById(userId);
Account account = this.getByUserId(userId);
if(account == null || user == null){
throw new ServiceException("无效账号");
}
baseMapper.incsIncomeCoin(userId, amount);
accountChangeLogService.saveLogNoAdmin(user.getId(),user.getUsercode(), RechargeTypeEnum.COIN,AccountBusinessEnum.RECHARGE.getOneEnum(),amount,consumeLog.getTraceId());
// 获取分销的比例和用户
consumeLogService.calculateInitFenxiao(consumeLog);
consumeLogService.save(consumeLog);
}
@Override @Override
public Page<AccountAdminVo> pageAdmin(PageQuery pageQuery, AccountAdminVo bo) { public Page<AccountAdminVo> pageAdmin(PageQuery pageQuery, AccountAdminVo bo) {
return baseMapper.pageAdmin(pageQuery.build(),bo); return baseMapper.pageAdmin(pageQuery.build(),bo);
} }
private void fenxiao(ConsumeLog consumeLog){ /**
if(ConsumeLogType.PAY.getCode().equals(consumeLog.getType())){ * 分销
Long sourceUserId = consumeLog.getSourceUserId(); */
UserInvite userInvite = userInviteService.getByUserId(sourceUserId); @Override
if(userInvite != null){ public void distribution(Long userId, Long amount, AccountChangeEnum accountChangeEnum,Long traceId) {
User oneUser = userService.getById(userInvite.getInviteId()); User user = userService.getById(userId);
if(oneUser != null && oneUser.getStatus() == 0){ Account account = this.getByUserId(userId);
UserInfo userInfo = userInfoService.getByUserId(userInvite.getUserId()); if(account == null || user == null){
consumeLog.setOneRate(userInfo.getPayIncomeRate()); log.error("分销失败,无效账号 userId={}",userId);
consumeLog.setOneUserId(userInvite.getInviteId());
consumeLog.setOneUsercode(oneUser.getUsercode());
consumeLog.setOnePhone(oneUser.getMobile());
consumeLog.setOneJoin(userInvite.getEnableRate());
consumeLog.setOneIsUnion(oneUser.getIsUnion());
}
}
return; return;
} }
Long targetUserId = consumeLog.getTargetUserId(); if(amount == null || accountChangeEnum == null){
if(targetUserId != null){ log.error("分销失败,参数错误 amount={},accountChangeEnum={}",amount,accountChangeEnum);
// 获取一级分销 return;
UserInvite userInvite = userInviteService.getByUserId(targetUserId);
if(userInvite != null){
User oneUser = userService.getById(userInvite.getInviteId());
if(oneUser != null && oneUser.getStatus() == 0){
UserInfo userInfo = userInfoService.getByUserId(userInvite.getUserId());
if(ConsumeLogType.GUARD.getCode().equals(consumeLog.getType())){
consumeLog.setOneRate(userInfo.getGuardIncomeRate());
}else if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())){
consumeLog.setOneRate(userInfo.getGiftIncomeRate());
}else if(ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
consumeLog.setOneRate(userInfo.getVideoIncomeRate());
}
consumeLog.setOneUserId(userInvite.getInviteId());
consumeLog.setOneUsercode(oneUser.getUsercode());
consumeLog.setOnePhone(oneUser.getMobile());
consumeLog.setOneJoin(userInvite.getEnableRate());
consumeLog.setOneIsUnion(oneUser.getIsUnion());
}
}
// 工会分销 只有通话和礼物才有
if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())
|| ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
UnionUser unionUser = unionUserService.getByUserId(targetUserId);
if(unionUser != null){
User user = userService.getById(unionUser.getId());
if(user != null && user.getIsUnion() == 1 && user.getStatus() == 0){
Union union = unionService.getById(unionUser.getUnionId());
if(union != null){
consumeLog.setUnionUsercode(user.getUsercode());
consumeLog.setUnionPhone(user.getMobile());
consumeLog.setUnionUserId(user.getId());
consumeLog.setUnionJoin(false);
if(unionUser.getEnableRate() && union.getEnableRate()){
consumeLog.setUnionJoin(true);
}
if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())){
consumeLog.setUnionRate(unionUser.getGiftDivide());
}else if(ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
consumeLog.setUnionRate(unionUser.getVideoDivide());
}
}
}
}
} }
baseMapper.incsCoin(userId, amount);
accountChangeLogService.saveLogNoAdmin(userId,user.getUsercode(), RechargeTypeEnum.COIN_INCOME,accountChangeEnum,amount,traceId);
} }
}
} }

View File

@@ -1,10 +1,22 @@
package com.ruoyi.cai.service.impl; package com.ruoyi.cai.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.ConsumeLog; import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.ConsumeLogStatus;
import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.mapper.ConsumeLogMapper; import com.ruoyi.cai.mapper.ConsumeLogMapper;
import com.ruoyi.cai.service.ConsumeLogService; import com.ruoyi.cai.service.*;
import com.ruoyi.cai.util.NumCaUtil;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.helper.LoginHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 消费记录Service业务层处理 * 消费记录Service业务层处理
@@ -13,6 +25,148 @@ import org.springframework.stereotype.Service;
* @date 2023-12-24 * @date 2023-12-24
*/ */
@Service @Service
@Slf4j
public class ConsumeLogServiceImpl extends ServiceImpl<ConsumeLogMapper, ConsumeLog> implements ConsumeLogService { public class ConsumeLogServiceImpl extends ServiceImpl<ConsumeLogMapper, ConsumeLog> implements ConsumeLogService {
@Autowired
private UserInviteService userInviteService;
@Autowired
private UserInfoService userInfoService;
@Autowired
private UserService userService;
@Autowired
private UnionUserService unionUserService;
@Autowired
private UnionService unionService;
@Autowired
private AccountService accountService;
@Override
@Transactional(rollbackFor = Exception.class)
public void dealFenxiao(Long id){
ConsumeLog consumer = this.getById(id);
if(consumer == null){
return;
}
if(!ConsumeLogStatus.READY.getCode().equals(consumer.getStatus())){
// 已经分销完成,无需继续分销
return;
}
if(!BooleanUtils.isTrue(consumer.getCalculateStatus())){
// 先计算
boolean update = this.update(Wrappers.lambdaUpdate(ConsumeLog.class)
.eq(ConsumeLog::getId, id)
.eq(ConsumeLog::getCalculateStatus, false)
.set(ConsumeLog::getCalculateStatus, true));
if(update){
consumer = calculateInitFenxiao(consumer);
consumer.setCalculateStatus(true);
this.updateById(consumer);
}
}
LoginUser loginUser = LoginHelper.getLoginUser();
// 在分销
boolean update = this.update(Wrappers.lambdaUpdate(ConsumeLog.class)
.eq(ConsumeLog::getId, id)
.eq(ConsumeLog::getStatus, ConsumeLogStatus.READY.getCode())
.set(ConsumeLog::getOpName, loginUser!=null?loginUser.getUsername():"system")
.set(ConsumeLog::getOpId, loginUser!=null?loginUser.getUserId():"-1")
.set(ConsumeLog::getStatus, ConsumeLogStatus.ALREADY.getCode()));
if(!update){
log.error("无需分销 consumer={}", JSON.toJSONString(consumer));
return;
}
AccountBusinessEnum accountBusinessEnum = AccountBusinessEnum.getByName(consumer.getBusinessEnum());
if(accountBusinessEnum == null){
log.error("分销失败 BusinessEnum状态错误! consumerLog={}",JSON.toJSONString(consumer));
return;
}
try {
// 计算一级
if(consumer.getOneUserId() != null && BooleanUtils.isTrue(consumer.getOneJoin())
&& consumer.getOneAmount() > 0){
accountService.distribution(consumer.getOneUserId(),consumer.getOneAmount(),accountBusinessEnum.getOneEnum(),consumer.getTraceId());
}
// 计算工会
if(consumer.getUnionUserId() != null && BooleanUtils.isTrue(consumer.getUnionJoin())
&& consumer.getUnionAmount() > 0){
accountService.distribution(consumer.getUnionUserId(),consumer.getUnionAmount(),accountBusinessEnum.getUnionEnum(),consumer.getTraceId());
}
}catch (Exception e){
log.error("分销发生未知错误,请联系开发检查!",e);
}
}
@Override
public ConsumeLog calculateInitFenxiao(ConsumeLog consumeLog){
if(ConsumeLogType.RECHARGE.getCode().equals(consumeLog.getType())){
Long sourceUserId = consumeLog.getSourceUserId();
UserInvite userInvite = userInviteService.getByUserId(sourceUserId);
if(userInvite != null){
User oneUser = userService.getById(userInvite.getInviteId());
if(oneUser != null && oneUser.getStatus() == 0){
UserInfo userInfo = userInfoService.getByUserId(userInvite.getUserId());
consumeLog.setOneRate(userInfo.getPayIncomeRate());
consumeLog.setOneUserId(userInvite.getInviteId());
consumeLog.setOneUsercode(oneUser.getUsercode());
consumeLog.setOnePhone(oneUser.getMobile());
consumeLog.setOneJoin(userInvite.getEnableRate());
consumeLog.setOneIsUnion(oneUser.getIsUnion());
consumeLog.setOneAmount(NumCaUtil.coin(consumeLog.getAmount(),consumeLog.getOneRate()));
}
}
return consumeLog;
}
Long targetUserId = consumeLog.getTargetUserId();
if(targetUserId != null){
// 获取一级分销
UserInvite userInvite = userInviteService.getByUserId(targetUserId);
if(userInvite != null){
User oneUser = userService.getById(userInvite.getInviteId());
if(oneUser != null && oneUser.getStatus() == 0){
UserInfo userInfo = userInfoService.getByUserId(userInvite.getUserId());
if(ConsumeLogType.GUARD.getCode().equals(consumeLog.getType())){
consumeLog.setOneRate(userInfo.getGuardIncomeRate());
}else if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())){
consumeLog.setOneRate(userInfo.getGiftIncomeRate());
}else if(ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
consumeLog.setOneRate(userInfo.getVideoIncomeRate());
}
consumeLog.setOneUserId(userInvite.getInviteId());
consumeLog.setOneUsercode(oneUser.getUsercode());
consumeLog.setOnePhone(oneUser.getMobile());
consumeLog.setOneJoin(userInvite.getEnableRate());
consumeLog.setOneIsUnion(oneUser.getIsUnion());
consumeLog.setOneAmount(NumCaUtil.coin(consumeLog.getAnchorAmount(),consumeLog.getOneRate()));
}
}
// 工会分销 只有通话和礼物才有
if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())
|| ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
UnionUser unionUser = unionUserService.getByUserId(targetUserId);
if(unionUser != null){
User user = userService.getById(unionUser.getId());
if(user != null && user.getIsUnion() == 1 && user.getStatus() == 0){
Union union = unionService.getById(unionUser.getUnionId());
if(union != null){
consumeLog.setUnionUsercode(user.getUsercode());
consumeLog.setUnionPhone(user.getMobile());
consumeLog.setUnionUserId(user.getId());
consumeLog.setUnionJoin(false);
if(unionUser.getEnableRate() && union.getEnableRate()){
consumeLog.setUnionJoin(true);
}
if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())){
consumeLog.setUnionRate(unionUser.getGiftDivide());
}else if(ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
consumeLog.setUnionRate(unionUser.getVideoDivide());
}
consumeLog.setOneAmount(NumCaUtil.coin(consumeLog.getAnchorAmount(),consumeLog.getUnionRate()));
}
}
}
}
}
return consumeLog;
}
} }

View File

@@ -9,19 +9,25 @@ import com.ruoyi.cai.dto.app.query.GiveGuardReq;
import com.ruoyi.cai.dto.app.dto.GuardTotalDTO; import com.ruoyi.cai.dto.app.dto.GuardTotalDTO;
import com.ruoyi.cai.dto.app.vo.index.GuardIndexVo; import com.ruoyi.cai.dto.app.vo.index.GuardIndexVo;
import com.ruoyi.cai.dto.app.vo.index.GuardListPageVo; import com.ruoyi.cai.dto.app.vo.index.GuardListPageVo;
import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.ConsumeLogType; import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.enums.SystemConfigEnum; import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.manager.IdManager;
import com.ruoyi.cai.manager.LockManager;
import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.mapper.GuardTotalMapper; import com.ruoyi.cai.mapper.GuardTotalMapper;
import com.ruoyi.cai.service.*; import com.ruoyi.cai.service.*;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -43,6 +49,9 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
private GuardLogService guardLogService; private GuardLogService guardLogService;
@Autowired @Autowired
private SystemConfigManager systemConfigManager; private SystemConfigManager systemConfigManager;
@Autowired
private RedissonClient redissonClient;
@Override @Override
public GuardIndexVo guardInfoVo(Long fromUserId, Long toUserId, Integer limit) { public GuardIndexVo guardInfoVo(Long fromUserId, Long toUserId, Integer limit) {
@@ -87,13 +96,22 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
if(!query.getGuardPrice().equals(guardPrice)){ if(!query.getGuardPrice().equals(guardPrice)){
throw new ServiceException("守护价格发生变化"); throw new ServiceException("守护价格发生变化");
} }
String guardLock = LockManager.getSendGuardLock(fromUserId);
RLock lock = redissonClient.getLock(guardLock);
if(lock.isLocked()){
throw new ServiceException("您点击太快了");
}
try {
lock.lock(3, TimeUnit.SECONDS);
Long guardValue = query.getGuardNum() * guardPrice; Long guardValue = query.getGuardNum() * guardPrice;
Long tractId = IdManager.nextId();
ConsumeLog consumeLog = new ConsumeLog(); ConsumeLog consumeLog = new ConsumeLog();
consumeLog.init(fromUser,toUser); consumeLog.init(fromUser,toUser);
consumeLog.setTraceId(tractId);
consumeLog.setType(ConsumeLogType.GUARD.getCode()); consumeLog.setType(ConsumeLogType.GUARD.getCode());
consumeLog.setAmount(guardValue); consumeLog.setAmount(guardValue);
consumeLog.setTargetRate(anchor.getGuardRate()); consumeLog.setTargetRate(anchor.getGuardRate());
consumeLog = accountService.decr(consumeLog); accountService.decr(consumeLog, AccountBusinessEnum.GUARD);
GuardLog guardLog = new GuardLog(); GuardLog guardLog = new GuardLog();
guardLog.setFromUserId(fromUserId); guardLog.setFromUserId(fromUserId);
guardLog.setFromUsercode(fromUser.getUsercode()); guardLog.setFromUsercode(fromUser.getUsercode());
@@ -104,7 +122,7 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
guardLog.setGuardNum(query.getGuardNum()); guardLog.setGuardNum(query.getGuardNum());
guardLog.setGuardValue(guardValue); guardLog.setGuardValue(guardValue);
guardLog.setGuardPrice(guardPrice); guardLog.setGuardPrice(guardPrice);
guardLog.setConsumeLogId(consumeLog.getId()); guardLog.setTraceId(tractId);
guardLogService.save(guardLog); guardLogService.save(guardLog);
GuardTotal one = this.getOne(Wrappers.lambdaQuery(GuardTotal.class) GuardTotal one = this.getOne(Wrappers.lambdaQuery(GuardTotal.class)
.eq(GuardTotal::getToUserId, query.getToUserId()) .eq(GuardTotal::getToUserId, query.getToUserId())
@@ -120,6 +138,9 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
this.save(one); this.save(one);
} }
baseMapper.incs(fromUserId,query.getToUserId(),query.getGuardNum(),guardValue); baseMapper.incs(fromUserId,query.getToUserId(),query.getGuardNum(),guardValue);
}finally {
lock.unlock();
}
return true; return true;
} }

View File

@@ -1,29 +1,29 @@
package com.ruoyi.cai.service.impl; package com.ruoyi.cai.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.Account; import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.domain.Goods;
import com.ruoyi.cai.domain.RechargeOrder;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.dto.AddRechargeOrderAdminDto; import com.ruoyi.cai.dto.AddRechargeOrderAdminDto;
import com.ruoyi.cai.dto.AddRechargeOrderDto; import com.ruoyi.cai.dto.AddRechargeOrderDto;
import com.ruoyi.cai.dto.admin.vo.RechargeOrderAdminVo; import com.ruoyi.cai.dto.admin.vo.RechargeOrderAdminVo;
import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.AccountChangeEnum;
import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.manager.IdManager;
import com.ruoyi.cai.mapper.AccountMapper; import com.ruoyi.cai.mapper.AccountMapper;
import com.ruoyi.cai.mapper.RechargeOrderMapper; import com.ruoyi.cai.mapper.RechargeOrderMapper;
import com.ruoyi.cai.mapper.UserMapper;
import com.ruoyi.cai.pay.OrderNoUtil; import com.ruoyi.cai.pay.OrderNoUtil;
import com.ruoyi.cai.pay.PayStatusEnum; import com.ruoyi.cai.pay.PayStatusEnum;
import com.ruoyi.cai.pay.PlatformTypeEnum; import com.ruoyi.cai.pay.PlatformTypeEnum;
import com.ruoyi.cai.pay.RechargeTypeEnum; import com.ruoyi.cai.pay.RechargeTypeEnum;
import com.ruoyi.cai.service.AccountService; import com.ruoyi.cai.service.*;
import com.ruoyi.cai.service.GoodsService;
import com.ruoyi.cai.service.RechargeOrderService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -38,6 +38,7 @@ import java.math.BigDecimal;
* @date 2024-01-03 * @date 2024-01-03
*/ */
@Service @Service
@Slf4j
public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,RechargeOrder> implements RechargeOrderService { public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,RechargeOrder> implements RechargeOrderService {
@@ -49,6 +50,14 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
private AccountService accountService; private AccountService accountService;
@Resource @Resource
private AccountMapper accountMapper; private AccountMapper accountMapper;
@Autowired
private AccountChangeLogService accountChangeLogService;
@Override
public RechargeOrder getByOrderNo(String orderNo){
return this.getOne(Wrappers.lambdaQuery(RechargeOrder.class).eq(RechargeOrder::getOrderNo,orderNo)
.last("limit 1"));
}
@Override @Override
public Page<RechargeOrderAdminVo> pageAdmin(PageQuery pageQuery, RechargeOrderAdminVo bo) { public Page<RechargeOrderAdminVo> pageAdmin(PageQuery pageQuery, RechargeOrderAdminVo bo) {
@@ -77,6 +86,36 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
return order; return order;
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void orderSuccess(String orderNo){
RechargeOrder rechargeOrder = this.getByOrderNo(orderNo);
if(rechargeOrder == null){
throw new ServiceException("订单不存在");
}
if(!PayStatusEnum.READY_PAY.getCode().equals(rechargeOrder.getPayStatus())){
log.error("订单支付状态错误!vipOrder={}", JSON.toJSONString(rechargeOrder));
throw new ServiceException("订单支付状态错误!");
}
Long traceId = IdManager.nextId();
boolean update = this.update(Wrappers.lambdaUpdate(RechargeOrder.class)
.eq(RechargeOrder::getOrderNo, rechargeOrder.getOrderNo())
.eq(RechargeOrder::getPayStatus, PayStatusEnum.READY_PAY.getCode())
.set(RechargeOrder::getPayStatus, PayStatusEnum.PAY.getCode())
.set(RechargeOrder::getTraceId,traceId));
if(!update){
log.error("订单支付状态错误!vipOrder={}", JSON.toJSONString(rechargeOrder));
throw new ServiceException("订单支付状态错误!");
}
User user = userService.getById(rechargeOrder.getUserId());
ConsumeLog consumeLog = new ConsumeLog();
consumeLog.init(user,null);
consumeLog.setTraceId(traceId);
consumeLog.setType(ConsumeLogType.RECHARGE.getCode());
consumeLog.setAmount(rechargeOrder.getRechargeCoin());
accountService.recharge(consumeLog);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public RechargeOrder updateAdminRechargeOrder(AddRechargeOrderAdminDto dto){ public RechargeOrder updateAdminRechargeOrder(AddRechargeOrderAdminDto dto){
@@ -89,6 +128,7 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
throw new ServiceException("参数错误"); throw new ServiceException("参数错误");
} }
Long userId = user.getId(); Long userId = user.getId();
Long traceId = IdManager.nextId();
RechargeOrder order = new RechargeOrder(); RechargeOrder order = new RechargeOrder();
order.setUserId(userId); order.setUserId(userId);
order.setRechargeName(rechargeTypeEnum.getName()); order.setRechargeName(rechargeTypeEnum.getName());
@@ -102,16 +142,19 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
order.setAdmin(true); order.setAdmin(true);
order.setAdminId(LoginHelper.getUserId()); order.setAdminId(LoginHelper.getUserId());
order.setRemark(dto.getRemark()); order.setRemark(dto.getRemark());
order.setTraceId(traceId);
this.save(order); this.save(order);
Account account = accountService.getByUserId(userId); Account account = accountService.getByUserId(userId);
if(rechargeTypeEnum == RechargeTypeEnum.COIN){ // 余额调整 if(rechargeTypeEnum == RechargeTypeEnum.COIN){ // 余额调整
if(dto.getRechargeCoin() > 0){ if(dto.getRechargeCoin() > 0){
accountMapper.incsCoin(userId,dto.getRechargeCoin()); accountMapper.incsCoin(userId,dto.getRechargeCoin());
accountChangeLogService.saveLogAdmin(user.getId(),user.getUsercode(),RechargeTypeEnum.COIN, AccountChangeEnum.SYSTEM_COIN_INCS,dto.getRechargeCoin(),traceId);
}else{ }else{
if(account.getCoin() < -dto.getRechargeCoin()){ if(account.getCoin() < -dto.getRechargeCoin()){
throw new ServiceException("调整后余额为负数,无法调整"); throw new ServiceException("调整后余额为负数,无法调整");
} }
long l = accountMapper.decrCoin(userId, -dto.getRechargeCoin()); long l = accountMapper.decrCoin(userId, -dto.getRechargeCoin());
accountChangeLogService.saveLogAdmin(user.getId(),user.getUsercode(),RechargeTypeEnum.COIN, AccountChangeEnum.SYSTEM_COIN_DECR,dto.getRechargeCoin(),traceId);
if(l == 0){ if(l == 0){
throw new ServiceException("调整后余额为负数,无法调整"); throw new ServiceException("调整后余额为负数,无法调整");
} }
@@ -119,11 +162,13 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
}else{ }else{
if(dto.getRechargeCoin() > 0){ if(dto.getRechargeCoin() > 0){
accountMapper.incsIncomeCoin(userId,dto.getRechargeCoin()); accountMapper.incsIncomeCoin(userId,dto.getRechargeCoin());
accountChangeLogService.saveLogAdmin(user.getId(),user.getUsercode(),RechargeTypeEnum.COIN_INCOME, AccountChangeEnum.SYSTEM_INCOME_COIN_INCS,dto.getRechargeCoin(),traceId);
}else{ }else{
if(account.getIncomeCoin() < -dto.getRechargeCoin()){ if(account.getIncomeCoin() < -dto.getRechargeCoin()){
throw new ServiceException("调整后收益为负数,无法调整"); throw new ServiceException("调整后收益为负数,无法调整");
} }
long l = accountMapper.decrIncomeCoin(userId, -dto.getRechargeCoin()); long l = accountMapper.decrIncomeCoin(userId, -dto.getRechargeCoin());
accountChangeLogService.saveLogAdmin(user.getId(),user.getUsercode(),RechargeTypeEnum.COIN_INCOME, AccountChangeEnum.SYSTEM_INCOME_COIN_DECR,dto.getRechargeCoin(),traceId);
if(l == 0){ if(l == 0){
throw new ServiceException("调整后收益为负数,无法调整"); throw new ServiceException("调整后收益为负数,无法调整");
} }

View File

@@ -4,16 +4,23 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.*; import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.app.query.GiveGiftRes; import com.ruoyi.cai.dto.app.query.GiveGiftRes;
import com.ruoyi.cai.dto.app.vo.index.UserGiftIndexVo; import com.ruoyi.cai.dto.app.vo.index.UserGiftIndexVo;
import com.ruoyi.cai.enums.AccountBusinessEnum;
import com.ruoyi.cai.enums.ConsumeLogType; import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.manager.IdManager;
import com.ruoyi.cai.manager.LockManager;
import com.ruoyi.cai.mapper.UserGiftMapper; import com.ruoyi.cai.mapper.UserGiftMapper;
import com.ruoyi.cai.service.*; import com.ruoyi.cai.service.*;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* 礼物记录Service业务层处理 * 礼物记录Service业务层处理
@@ -33,6 +40,8 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
private UserService userService; private UserService userService;
@Autowired @Autowired
private AnchorService anchorService; private AnchorService anchorService;
@Autowired
private RedissonClient redissonClient;
@Override @Override
@@ -41,23 +50,33 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean giveGift(GiveGiftRes query) { public boolean giveGift(GiveGiftRes query) {
Long fromUserId = LoginHelper.getUserId(); Long fromUserId = LoginHelper.getUserId();
Gift gift = giftService.getById(query.getGiftId()); Gift gift = giftService.getById(query.getGiftId());
if(gift == null){ if(gift == null){
throw new ServiceException("礼物不存在"); throw new ServiceException("礼物不存在");
} }
String guardLock = LockManager.getSendGuardLock(fromUserId);
RLock lock = redissonClient.getLock(guardLock);
if(lock.isLocked()){
throw new ServiceException("您点击太快了");
}
try {
lock.lock(3, TimeUnit.SECONDS);
User fromUser = userService.getById(fromUserId); User fromUser = userService.getById(fromUserId);
User toUser = userService.getById(query.getToUserId()); User toUser = userService.getById(query.getToUserId());
Anchor anchor = anchorService.getByUserId(query.getToUserId()); Anchor anchor = anchorService.getByUserId(query.getToUserId());
Long price = gift.getPrice(); Long price = gift.getPrice();
Long traceId = IdManager.nextId();
Long giftAmount = query.getGiftCount() * price; Long giftAmount = query.getGiftCount() * price;
ConsumeLog consumeLog = new ConsumeLog(); ConsumeLog consumeLog = new ConsumeLog();
consumeLog.init(fromUser,toUser); consumeLog.init(fromUser,toUser);
consumeLog.setTraceId(traceId);
consumeLog.setType(ConsumeLogType.GIFT.getCode()); consumeLog.setType(ConsumeLogType.GIFT.getCode());
consumeLog.setAmount(giftAmount); consumeLog.setAmount(giftAmount);
consumeLog.setTargetRate(anchor.getGiftRate()); consumeLog.setTargetRate(anchor.getGiftRate());
consumeLog = accountService.decr(consumeLog); accountService.decr(consumeLog, AccountBusinessEnum.GIFT);
UserGift userGift = new UserGift(); UserGift userGift = new UserGift();
userGift.setType(query.getType()); userGift.setType(query.getType());
userGift.setFromUid(fromUserId); userGift.setFromUid(fromUserId);
@@ -72,8 +91,11 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
userGift.setGiftPrice(gift.getPrice()); userGift.setGiftPrice(gift.getPrice());
userGift.setGiftCount(query.getGiftCount()); userGift.setGiftCount(query.getGiftCount());
userGift.setGiftAmount(giftAmount); userGift.setGiftAmount(giftAmount);
userGift.setConsumerLogId(consumeLog.getId()); userGift.setTraceId(traceId);
this.save(userGift); this.save(userGift);
}finally {
lock.unlock();
}
return true; return true;
} }
} }

View File

@@ -39,10 +39,6 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
@Autowired @Autowired
private MemberPriceService memberPriceService; private MemberPriceService memberPriceService;
@Autowired @Autowired
private ConsumeLogService consumeLogService;
@Autowired
private UserService userService;
@Autowired
private UserMemberService userMemberService; private UserMemberService userMemberService;
/** /**
@@ -159,7 +155,7 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
userMemberService.saveOrUpdate(userMember); userMemberService.saveOrUpdate(userMember);
return true; return true;
} }
if(longs == 1){ // 已经是永久会员还买? 什么都不干 if(longs == 1){ // 已经是永久会员还买? 傻逼
return true; return true;
} }
userMember.setCreateTime(createTime); userMember.setCreateTime(createTime);

View File

@@ -14,6 +14,9 @@ public class NumCaUtil {
* @return * @return
*/ */
public static Long coin(Long value, BigDecimal rate){ public static Long coin(Long value, BigDecimal rate){
if(value == null || rate == null){
return 0L;
}
BigDecimal decimal = NumberUtil.mul(value, rate); BigDecimal decimal = NumberUtil.mul(value, rate);
return decimal.setScale(0, RoundingMode.DOWN).longValue(); return decimal.setScale(0, RoundingMode.DOWN).longValue();
} }