补贴管理 - 操作记录

This commit is contained in:
gaowdong 2025-04-09 16:48:31 +08:00
parent 8879270fac
commit f3d3268f7b
14 changed files with 247 additions and 40 deletions

View File

@ -0,0 +1,40 @@
package com.bonus.canteen.core.account.constants;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public enum WalletBalanceOperationEnum {
ADD_BAL(1, "钱包加钱"),
REDUCE_BAL(2, "钱包减钱"),
FROZEN_BAL(3, "钱包冻结"),
UNFROZEN_BAL(4, "钱包解冻");
private final Integer key;
private final String desc;
private static final Map<Integer, WalletBalanceOperationEnum> ENUM_MAP = Arrays.stream(values())
.collect(Collectors.toMap(WalletBalanceOperationEnum::getKey, e -> e));
private WalletBalanceOperationEnum(Integer key, String desc) {
this.key = key;
this.desc = desc;
}
public static String getDesc(Integer key) {
WalletBalanceOperationEnum enumValue = ENUM_MAP.get(key);
return enumValue != null ? enumValue.getDesc() : "";
}
public static WalletBalanceOperationEnum getEnum(Integer key) {
return ENUM_MAP.get(key);
}
public Integer getKey() {
return this.key;
}
public String getDesc() {
return this.desc;
}
}

View File

@ -158,7 +158,7 @@ public class AccInfoController extends BaseController {
}
@ApiOperation("账户操作记录")
@PostMapping({"/operation/list"})
@PostMapping({"/operation/record"})
public AjaxResult queryPageAccOperationRecord(@RequestBody AccOperationQueryParam param) {
return AjaxResult.success(this.accOperationHistoryService.selectAccOperationHistory(param));
}

View File

@ -78,4 +78,10 @@ public class AccSubsidyController extends BaseController {
public AjaxResult batchAccSubsidyClearCheck(@RequestBody @Valid AccSubsidyParam param) {
return AjaxResult.success(accSubService.batchOperationWalletClearCheck(param));
}
// @ApiOperation("补贴记录")
// @PostMapping({"/history"})
// public AjaxResult queryAccSubRechargePage(@RequestBody AccSubRechargePageDTO request) {
// return AjaxResult.success(this.accSubService.queryAccSubRechargePage(request));
// }
}

View File

@ -1,5 +1,7 @@
package com.bonus.canteen.core.account.domain;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.bonus.common.core.annotation.Excel;
@ -28,7 +30,7 @@ public class AccTrade extends BaseEntity {
@ApiModelProperty(value = "交易时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "交易时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date tradeTime;
private LocalDateTime tradeTime;
/** 人员id */
@Excel(name = "人员id")
@ -43,47 +45,47 @@ public class AccTrade extends BaseEntity {
/** 交易类型 */
@Excel(name = "交易类型")
@ApiModelProperty(value = "交易类型")
private Long tradeType;
private Integer tradeType;
/** 实际交易金额/分 */
@Excel(name = "实际交易金额/分")
@ApiModelProperty(value = "实际交易金额/分")
private Long actualAmount;
private BigDecimal actualAmount;
/** 交易金额/分 */
@Excel(name = "交易金额/分")
@ApiModelProperty(value = "交易金额/分")
private Long amount;
private BigDecimal amount;
/** 钱包可用总余额(不包含冻结金额) */
@Excel(name = "钱包可用总余额(不包含冻结金额)")
@ApiModelProperty(value = "钱包可用总余额(不包含冻结金额)")
private Long walletBalTotal;
private BigDecimal walletBalTotal;
/** 账户总余额(所有钱包余额+冻结金额) */
@Excel(name = "账户总余额(所有钱包余额+冻结金额)")
@ApiModelProperty(value = "账户总余额(所有钱包余额+冻结金额)")
private Long accAllBal;
private BigDecimal accAllBal;
/** 支付渠道 */
@Excel(name = "支付渠道")
@ApiModelProperty(value = "支付渠道")
private Long payChannel;
private Integer payChannel;
/** 支付方式 */
@Excel(name = "支付方式")
@ApiModelProperty(value = "支付方式")
private Long payType;
private Integer payType;
/** 支付状态 */
@Excel(name = "支付状态")
@ApiModelProperty(value = "支付状态")
private Long payState;
private Integer payState;
/** 交易状态 */
@Excel(name = "交易状态")
@ApiModelProperty(value = "交易状态")
private Long tradeState;
private Integer tradeState;
/** 三方支付订单号 */
@Excel(name = "三方支付订单号")

View File

@ -1,5 +1,6 @@
package com.bonus.canteen.core.account.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.bonus.common.core.annotation.Excel;
@ -42,22 +43,22 @@ public class AccTradeWalletDetail extends BaseEntity {
/** 对应钱包交易金额/分 */
@Excel(name = "对应钱包交易金额/分")
@ApiModelProperty(value = "对应钱包交易金额/分")
private Long amount;
private BigDecimal amount;
/** 钱包余额/分 */
@Excel(name = "钱包余额/分")
@ApiModelProperty(value = "钱包余额/分")
private Long walletBal;
private BigDecimal walletBal;
/** 交易类型 */
@Excel(name = "交易类型")
@ApiModelProperty(value = "交易类型")
private Long tradeType;
private Integer tradeType;
/** 对应钱包冻结金额/分 */
@Excel(name = "对应钱包冻结金额/分")
@ApiModelProperty(value = "对应钱包冻结金额/分")
private Long frozenBalance;
private BigDecimal frozenBalance;
/** 交易时间(对应acc_trade交易时间) */
@ApiModelProperty(value = "交易时间(对应acc_trade交易时间)")

View File

@ -31,7 +31,7 @@ public class AccWalletInfo extends BaseEntity {
private Long accId;
/** 钱包类型id */
private Long walletId;
private Integer walletId;
/** 钱包余额/分 */
@Excel(name = "钱包余额/分")

View File

@ -0,0 +1,16 @@
package com.bonus.canteen.core.account.domain.bo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class WalletBalanceOperation {
private BigDecimal amount;
private Long userId;
private Integer walletId;
private Integer operationType;
private Integer tradeType;
private Integer payChannel;
private Integer payType;
}

View File

@ -20,7 +20,7 @@ public interface AccWalletInfoMapper {
* @param userId 钱包详情信息主键
* @return 钱包详情信息
*/
public AccWalletInfo selectAccWalletInfoByUserId(Long userId);
public List<AccWalletInfo> selectAccWalletInfoByUserId(Long userId);
public AccWalletInfo selectAccWalletInfoByUserIdAndWalletId(Long userId, Integer walletId);
List<AccWalletInfoVO> selectAccWalletInfoByUserIds(@Param("userIds") List<Long> userIds);

View File

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import com.bonus.canteen.core.account.domain.AccWalletInfo;
import com.bonus.canteen.core.account.domain.bo.WalletBalanceOperation;
import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO;
import org.apache.ibatis.annotations.Param;
@ -21,7 +22,7 @@ public interface IAccWalletInfoService {
* @param userId 钱包详情信息主键
* @return 钱包详情信息
*/
public AccWalletInfo selectAccWalletInfoByUserId(Long userId);
public List<AccWalletInfo> selectAccWalletInfoByUserId(Long userId);
public AccWalletInfo selectAccWalletInfoByUserIdAndWalletId(Long userId, Integer walletId);
/**
@ -69,7 +70,5 @@ public interface IAccWalletInfoService {
Map<Long, List<AccWalletInfoVO>> selectAccWalletInfoByUserIds(List<Long> userIds);
void updateMinBalance(List<Long> userIds, Integer walletId, BigDecimal minBalance);
void addAccWalletInfo(BigDecimal amount, Long userId, Integer walletId);
void reduceAccWalletInfo(BigDecimal amount, Long userId, Integer walletId);
void clearAccWalletInfo(Long userId, Integer walletId);
void acWalletBalanceOperation(WalletBalanceOperation operation);
}

View File

@ -198,7 +198,7 @@ public class AccInfoServiceImpl implements IAccInfoService {
AccWalletInfo accWalletInfo = new AccWalletInfo();
accWalletInfo.setAccId(accInfo.getAccId());
accWalletInfo.setUserId(sysUser.getUserId());
accWalletInfo.setWalletId(accWalletIdEnum.getKey().longValue());
accWalletInfo.setWalletId(accWalletIdEnum.getKey());
accWalletInfos.add(accWalletInfo);
}

View File

@ -1,9 +1,12 @@
package com.bonus.canteen.core.account.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.bonus.canteen.core.account.constants.AccTradeTypeEnum;
import com.bonus.canteen.core.account.constants.AccWalletClearTypeEnum;
import com.bonus.canteen.core.account.constants.AccWalletIdEnum;
import com.bonus.canteen.core.account.constants.WalletBalanceOperationEnum;
import com.bonus.canteen.core.account.domain.AccWalletInfo;
import com.bonus.canteen.core.account.domain.bo.WalletBalanceOperation;
import com.bonus.canteen.core.account.domain.param.AccSubsidyParam;
import com.bonus.canteen.core.account.domain.vo.AccBatchOperationWallerErrorVO;
import com.bonus.canteen.core.account.domain.vo.AccBatchOperationWalletPreCheckVO;
@ -12,6 +15,9 @@ import com.bonus.canteen.core.account.service.AccSubService;
import com.bonus.canteen.core.account.service.IAccInfoService;
import com.bonus.canteen.core.account.service.IAccWalletInfoService;
import com.bonus.canteen.core.account.utils.AccRedisUtils;
import com.bonus.canteen.core.pay.constants.PayChannelEnum;
import com.bonus.canteen.core.pay.constants.PayTypeEnum;
import com.bonus.canteen.core.pay.constants.TradeTypeEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.i18n.I18n;
import org.slf4j.Logger;
@ -193,7 +199,15 @@ public class AccSubServiceImpl implements AccSubService {
log.info("新增补贴入参: amount{} userId{}walletId{}", amount, userId, walletId);
AccRedisUtils.lockUpdateAccWalletBalance(userId);
try {
accWalletInfoService.addAccWalletInfo(amount, userId, walletId);
WalletBalanceOperation operation = new WalletBalanceOperation();
operation.setAmount(amount);
operation.setUserId(userId);
operation.setWalletId(walletId);
operation.setOperationType(WalletBalanceOperationEnum.ADD_BAL.getKey());
operation.setTradeType(AccTradeTypeEnum.SUBSIDY.getKey());
operation.setPayChannel(PayChannelEnum.GW_SYSTEM.getKey());
operation.setPayType(PayTypeEnum.SUB_GRANT.getKey());
accWalletInfoService.acWalletBalanceOperation(operation);
log.info("新增补贴结束");
} finally {
AccRedisUtils.unlockUpdateAccWalletBalance(userId);
@ -204,7 +218,15 @@ public class AccSubServiceImpl implements AccSubService {
log.info("清空补贴入参: amount{} userId{}walletId{}", amount, userId, walletId);
AccRedisUtils.lockUpdateAccWalletBalance(userId);
try {
accWalletInfoService.reduceAccWalletInfo(amount, userId, walletId);
WalletBalanceOperation operation = new WalletBalanceOperation();
operation.setAmount(amount);
operation.setUserId(userId);
operation.setWalletId(walletId);
operation.setOperationType(WalletBalanceOperationEnum.REDUCE_BAL.getKey());
operation.setTradeType(AccTradeTypeEnum.CLEAR.getKey());
operation.setPayChannel(PayChannelEnum.GW_SYSTEM.getKey());
operation.setPayType(PayTypeEnum.SUB_GRANT.getKey());
accWalletInfoService.acWalletBalanceOperation(operation);
log.info("清空补贴结束");
} finally {
AccRedisUtils.unlockUpdateAccWalletBalance(userId);
@ -215,7 +237,14 @@ public class AccSubServiceImpl implements AccSubService {
log.info("清空补贴入参: userId{}walletId{}", userId, walletId);
AccRedisUtils.lockUpdateAccWalletBalance(userId);
try {
accWalletInfoService.clearAccWalletInfo(userId, walletId);
WalletBalanceOperation operation = new WalletBalanceOperation();
operation.setUserId(userId);
operation.setWalletId(walletId);
operation.setOperationType(WalletBalanceOperationEnum.REDUCE_BAL.getKey());
operation.setTradeType(AccTradeTypeEnum.CLEAR.getKey());
operation.setPayChannel(PayChannelEnum.GW_SYSTEM.getKey());
operation.setPayType(PayTypeEnum.SUB_GRANT.getKey());
accWalletInfoService.acWalletBalanceOperation(operation);
log.info("清空补贴结束");
} finally {
AccRedisUtils.unlockUpdateAccWalletBalance(userId);

View File

@ -1,7 +1,11 @@
package com.bonus.canteen.core.account.service.impl;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.account.domain.bo.AccOperationHistory;
import com.bonus.canteen.core.account.domain.vo.AccTradeVo;
import com.bonus.canteen.core.account.mapper.AccOperationHistoryMapper;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import org.springframework.beans.BeanUtils;
@ -53,11 +57,7 @@ public class AccTradeServiceImpl implements IAccTradeService {
@Override
public int insertAccTrade(AccTrade accTrade) {
accTrade.setCreateTime(DateUtils.getNowDate());
try {
return accTradeMapper.insertAccTrade(accTrade);
} catch (Exception e) {
throw new ServiceException("错误信息描述" + e.getMessage());
}
}
@Override

View File

@ -1,16 +1,33 @@
package com.bonus.canteen.core.account.service.impl;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.account.constants.AccTradeStateEnum;
import com.bonus.canteen.core.account.constants.AccTradeTypeEnum;
import com.bonus.canteen.core.account.constants.WalletBalanceOperationEnum;
import com.bonus.canteen.core.account.domain.AccTrade;
import com.bonus.canteen.core.account.domain.AccTradeWalletDetail;
import com.bonus.canteen.core.account.domain.bo.WalletBalanceOperation;
import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO;
import com.bonus.canteen.core.account.service.IAccTradeService;
import com.bonus.canteen.core.account.service.IAccTradeWalletDetailService;
import com.bonus.canteen.core.pay.constants.PayStateEnum;
import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.system.api.RemoteUserService;
import com.bonus.system.api.domain.SysUser;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +36,8 @@ import com.bonus.canteen.core.account.mapper.AccWalletInfoMapper;
import com.bonus.canteen.core.account.domain.AccWalletInfo;
import com.bonus.canteen.core.account.service.IAccWalletInfoService;
import javax.annotation.Resource;
/**
* 钱包详情信息Service业务层处理
*
@ -31,6 +50,13 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
@Autowired
private AccWalletInfoMapper accWalletInfoMapper;
@Resource
private RemoteUserService remoteUserService;
@Autowired
IAccTradeService accTradeService;
@Autowired
IAccTradeWalletDetailService accTradeWalletDetailService;
/**
* 查询钱包详情信息
@ -39,7 +65,7 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
* @return 钱包详情信息
*/
@Override
public AccWalletInfo selectAccWalletInfoByUserId(Long userId) {
public List<AccWalletInfo> selectAccWalletInfoByUserId(Long userId) {
return accWalletInfoMapper.selectAccWalletInfoByUserId(userId);
}
@ -151,18 +177,69 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
}
}
@Override
public void addAccWalletInfo(BigDecimal amount, Long userId, Integer walletId) {
accWalletInfoMapper.addAccWalletInfo(amount, userId, walletId);
private void addAccWalletInfo(WalletBalanceOperation operation) {
accWalletInfoMapper.addAccWalletInfo(operation.getAmount(), operation.getUserId(), operation.getWalletId());
}
@Override
public void reduceAccWalletInfo(BigDecimal amount, Long userId, Integer walletId) {
accWalletInfoMapper.reduceAccWalletInfo(amount, userId, walletId);
private void reduceAccWalletInfo(WalletBalanceOperation operation) {
accWalletInfoMapper.reduceAccWalletInfo(operation.getAmount(), operation.getUserId(), operation.getWalletId());
}
@Override
public void clearAccWalletInfo(Long userId, Integer walletId) {
accWalletInfoMapper.clearAccWalletInfo(userId, walletId);
private void clearAccWalletInfo(WalletBalanceOperation operation) {
accWalletInfoMapper.clearAccWalletInfo(operation.getUserId(), operation.getWalletId());
}
public void acWalletBalanceOperation(WalletBalanceOperation operation) {
switch (WalletBalanceOperationEnum.getEnum(operation.getOperationType())) {
case ADD_BAL:
addAccWalletInfo(operation);
break;
case REDUCE_BAL:
clearAccWalletInfo(operation);
break;
default:
throw new ServiceException("钱包操作类型错误");
}
List<AccWalletInfo> walletInfoList = selectAccWalletInfoByUserId(operation.getUserId());
BigDecimal accBalTotal = walletInfoList.stream().map(AccWalletInfo::getWalletBal)
.filter(ObjectUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
AjaxResult userResult = remoteUserService.getInfo(operation.getUserId() , SecurityConstants.INNER);
SysUser sysUser = null;
if(Objects.nonNull(userResult)) {
sysUser = userResult.getDataAs(SysUser.class);
}
long tradeId = Id.next();
LocalDateTime tradeTime = LocalDateTime.now();
AccTrade accTrade = new AccTrade();
accTrade.setTradeId(tradeId);
accTrade.setTradeTime(tradeTime);
accTrade.setTradeType(operation.getTradeType());
accTrade.setAmount(operation.getAmount());
accTrade.setActualAmount(operation.getAmount());
accTrade.setWalletBalTotal(accBalTotal);
accTrade.setAccAllBal(accBalTotal);
accTrade.setPayState(PayStateEnum.PAY_SUCC.getKey());
accTrade.setTradeState(AccTradeStateEnum.TAKE_EFFECT.getKey());
accTrade.setUserId(operation.getUserId());
accTrade.setPayChannel(operation.getPayChannel());
accTrade.setPayType(operation.getPayType());
accTrade.setCreateBy(SecurityUtils.getUserId().toString());
if(Objects.nonNull(sysUser)) {
accTrade.setDeptId(sysUser.getDeptId());
}
this.accTradeService.insertAccTrade(accTrade);
AccTradeWalletDetail accTradeWalletDetail = new AccTradeWalletDetail();
accTradeWalletDetail.setTradeId(tradeId);
accTradeWalletDetail.setUserId(operation.getUserId());
accTradeWalletDetail.setTradeType(operation.getTradeType());
accTradeWalletDetail.setAmount(operation.getAmount());
BigDecimal walletBalByWalletId = walletInfoList.stream().filter((item) -> {
return item.getWalletId().equals(operation.getWalletId());
}).map(AccWalletInfo::getWalletBal).filter(ObjectUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
accTradeWalletDetail.setWalletBal(walletBalByWalletId);
accTradeWalletDetail.setTradeTime(DateUtils.getNowDate());
this.accTradeWalletDetailService.insertAccTradeWalletDetail(accTradeWalletDetail);
}
}

View File

@ -0,0 +1,37 @@
package com.bonus.canteen.core.pay.constants;
//import com.bonus.canteen.core.pay.channel.account.extension.AccPayExtension;
//import com.bonus.canteen.core.pay.channel.ali.extension.AliPayExtension;
import java.util.*;
import java.util.stream.Collectors;
public enum PayChannelEnum {
ACC(1, "系统账户", null), //AccPayExtension.class
ALI(3, "支付宝", null), //AliPayExtension.class
GW_SYSTEM(20, "系统后台", null);
private final Integer key;
private final String desc;
private final Class<?> beanClass;
private PayChannelEnum(Integer key, String desc, Class beanName) {
this.key = key;
this.desc = desc;
this.beanClass = beanName;
}
public Integer getKey() {
return this.key;
}
public String getDesc() {
return this.desc;
}
public Class<?> getBeanClass() {
return this.beanClass;
}
}