补贴管理 - 批量操作预检

This commit is contained in:
gaowdong 2025-04-09 14:11:44 +08:00
parent f25aabd615
commit 7e2e18dc5d
11 changed files with 227 additions and 7 deletions

View File

@ -0,0 +1,25 @@
package com.bonus.canteen.core.account.constants;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public enum AccSubsidyEnum {
SUBSIDY(1, "补贴"),
SUBSIDY_CLEAR(2, "清空补贴");
private final Integer key;
private final String desc;
private AccSubsidyEnum(Integer key, String desc) {
this.key = key;
this.desc = desc;
}
public Integer getKey() {
return this.key;
}
public String getDesc() {
return this.desc;
}
}

View File

@ -55,16 +55,27 @@ public class AccSubsidyController extends BaseController {
return AjaxResult.success();
}
@ApiOperation("单人补贴")
@ApiOperation("批量补贴")
@PostMapping("/batch/add")
public AjaxResult batchAccSubsidyAdd(@RequestBody @Valid AccSubsidyParam param) {
this.accSubService.batchAccSubsidyAdd(param);
return AjaxResult.success();
}
@ApiOperation("补贴清空")
@ApiOperation("批量补贴校验")
@PostMapping("/batch/add/check")
public AjaxResult batchAccSubsidyAddCheck(@RequestBody @Valid AccSubsidyParam param) {
return AjaxResult.success(accSubService.batchOperationWalletAddCheck(param));
}
@ApiOperation("批量补贴清空")
@PostMapping({"/batch/clear"})
public AjaxResult batchAccSubsidyClear(@RequestBody @Valid AccSubsidyParam param) {
this.accSubService.batchAccSubsidyClear(param);
return AjaxResult.success();
}
@ApiOperation("批量补贴清空校验")
@PostMapping({"/batch/clear/check"})
public AjaxResult batchAccSubsidyClearCheck(@RequestBody @Valid AccSubsidyParam param) {
return AjaxResult.success(accSubService.batchOperationWalletClearCheck(param));
}
}

View File

@ -1,6 +1,7 @@
package com.bonus.canteen.core.account.domain.param;
import com.bonus.common.core.web.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -40,4 +41,7 @@ public class AccSubsidyParam extends BaseEntity {
) BigDecimal amount;
@ApiModelProperty("清空类型 清空-1 清空至-2")
private Integer clearType = 1;
@ApiModelProperty("操作类型 补贴-1 清空补贴-2")
@JsonIgnore
private Integer operationType;
}

View File

@ -0,0 +1,19 @@
package com.bonus.canteen.core.account.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class AccBatchOperationWallerErrorVO {
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("用户姓名")
private String nickName;
@ApiModelProperty("用户手机号")
private String phoneNumber;
@ApiModelProperty("充值金额")
private BigDecimal amount;
@ApiModelProperty("失败原因")
private String errorMessage;
}

View File

@ -0,0 +1,26 @@
package com.bonus.canteen.core.account.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class AccBatchOperationWalletPreCheckVO {
@ApiModelProperty("总人数")
private Integer totalUserSum;
@ApiModelProperty("有效人数")
private Integer validCount;
@ApiModelProperty("有效充值总额")
private BigDecimal validTotalAmount;
@ApiModelProperty("成功用户id集合")
private List<Long> validUserIdList;
@ApiModelProperty("无效人数")
private Integer invalidCount;
@ApiModelProperty("失败用户信息集合")
private List<AccBatchOperationWallerErrorVO> errVOList;
@ApiModelProperty("操作金额")
private BigDecimal amount;
@ApiModelProperty("备注")
private String remark;
}

View File

@ -81,4 +81,8 @@ public interface AccWalletInfoMapper {
@Param("userId") Long userId,
@Param("walletId") Integer walletId
);
void clearAccWalletInfo(@Param("userId") Long userId,
@Param("walletId") Integer walletId
);
}

View File

@ -1,6 +1,7 @@
package com.bonus.canteen.core.account.service;
import com.bonus.canteen.core.account.domain.param.AccSubsidyParam;
import com.bonus.canteen.core.account.domain.vo.AccBatchOperationWalletPreCheckVO;
import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal;
@ -14,4 +15,8 @@ public interface AccSubService {
void batchAccSubsidyAdd(AccSubsidyParam param);
void batchAccSubsidyClear(AccSubsidyParam param);
AccBatchOperationWalletPreCheckVO batchOperationWalletAddCheck(AccSubsidyParam param);
AccBatchOperationWalletPreCheckVO batchOperationWalletClearCheck(AccSubsidyParam param);
}

View File

@ -71,4 +71,5 @@ public interface IAccWalletInfoService {
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);
}

View File

@ -5,6 +5,8 @@ import com.bonus.canteen.core.account.constants.AccWalletClearTypeEnum;
import com.bonus.canteen.core.account.constants.AccWalletIdEnum;
import com.bonus.canteen.core.account.domain.AccWalletInfo;
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;
import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO;
import com.bonus.canteen.core.account.service.AccSubService;
import com.bonus.canteen.core.account.service.IAccInfoService;
@ -22,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -60,7 +63,7 @@ public class AccSubServiceImpl implements AccSubService {
throw new ServiceException("账户不存在");
}
accInfoService.checkAccStatus(accInfoVO);
this.clearAccSubsidyHandler(accInfoVO, param);
clearAllAccSubsidyHandler(accInfoVO, param);
}
private void clearAccSubsidyHandler(AccInfoDetailsVO accInfoVO, AccSubsidyParam param) {
@ -70,17 +73,25 @@ public class AccSubServiceImpl implements AccSubService {
}
BigDecimal walletBal = walletInfo.getWalletBal();
if (walletBal.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException(I18n.getMessage("补贴钱包余额不足"));
throw new ServiceException("补贴钱包余额必须大于0元");
} else {
BigDecimal clearAmount = this.calculateClearAmount(walletBal, param.getClearType(), param.getAmount());
if (clearAmount.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException(I18n.getMessage("清空后补贴钱包余额小于等于0"));
throw new ServiceException("清空金额必须大于0元");
} else {
reduceAccWalletBalance(clearAmount, param.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
}
}
}
private void clearAllAccSubsidyHandler(AccInfoDetailsVO accInfoVO, AccSubsidyParam param) {
AccWalletInfo walletInfo = accWalletInfoService.selectAccWalletInfoByUserIdAndWalletId(accInfoVO.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
if(Objects.isNull(walletInfo)) {
throw new ServiceException("补贴钱包不存在");
}
clearAccWalletBalance(param.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
}
private BigDecimal calculateClearAmount(BigDecimal walletBal, Integer clearType, BigDecimal amount) {
BigDecimal clearAmount;
if (AccWalletClearTypeEnum.CLEAR_BY.getKey().equals(clearType)) {
@ -135,8 +146,8 @@ public class AccSubServiceImpl implements AccSubService {
}
accInfoService.checkAccStatus(accInfoVO);
addAccWalletBalance(amount, accInfo.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
} catch (Exception var10) {
log.error("批量补贴充值异常", var10);
} catch (Exception ex) {
log.error("批量补贴充值异常, 用户id: {}, 补贴金额:{}", accInfo.getUserId(), amount, ex);
}
});
@ -199,4 +210,106 @@ public class AccSubServiceImpl implements AccSubService {
AccRedisUtils.unlockUpdateAccWalletBalance(userId);
}
}
public void clearAccWalletBalance(Long userId, Integer walletId) {
log.info("清空补贴入参: userId{}walletId{}", userId, walletId);
AccRedisUtils.lockUpdateAccWalletBalance(userId);
try {
accWalletInfoService.clearAccWalletInfo(userId, walletId);
log.info("清空补贴结束");
} finally {
AccRedisUtils.unlockUpdateAccWalletBalance(userId);
}
}
public AccBatchOperationWalletPreCheckVO batchOperationWalletClearCheck(AccSubsidyParam param) {
log.info("批量清空校验操作人数:{}", param.getUserIds().size());
List<AccInfoDetailsVO> accInfoVOList = accInfoService.queryAccInfoByUserIds(param.getUserIds());
if (CollUtil.isEmpty(accInfoVOList)) {
throw new ServiceException("批量补贴查询到的用户为空");
}
List<AccBatchOperationWallerErrorVO> errVOList = new ArrayList<>();
List<Long> validUserList = new ArrayList<>();
List<BigDecimal> amountList = new ArrayList<>();
for (AccInfoDetailsVO accInfo : accInfoVOList) {
try {
checkAccount(accInfo);
AccWalletInfo walletInfo = accWalletInfoService.selectAccWalletInfoByUserIdAndWalletId(accInfo.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
if(Objects.isNull(walletInfo)) {
throw new ServiceException("补贴钱包不存在");
}
BigDecimal walletBal = walletInfo.getWalletBal();
// if (walletBal.compareTo(BigDecimal.ZERO) <= 0) {
// throw new ServiceException("补贴钱包余额必须大于0元");
// } else {
// BigDecimal clearAmount = this.calculateClearAmount(walletBal, param.getClearType(), param.getAmount());
// if (clearAmount.compareTo(BigDecimal.ZERO) <= 0) {
// throw new ServiceException("清空金额必须大于0元");
// }else{
// amountList.add(clearAmount);
// }
// }
amountList.add(walletBal);
validUserList.add(walletInfo.getUserId());
} catch (Exception ex) {
errVOList.add(createErrorVO(accInfo, param.getAmount(), ex.getMessage()));
}
}
BigDecimal validTotalAmount = amountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
return buildResult(param, validUserList, errVOList, validTotalAmount);
}
public AccBatchOperationWalletPreCheckVO batchOperationWalletAddCheck(AccSubsidyParam param) {
log.info("批量校验操作人数:{}", param.getUserIds().size());
List<AccInfoDetailsVO> accInfoVOList = accInfoService.queryAccInfoByUserIds(param.getUserIds());
if (CollUtil.isEmpty(accInfoVOList)) {
throw new ServiceException("批量补贴查询到的用户为空");
}
List<AccBatchOperationWallerErrorVO> errVOList = new ArrayList<>();
List<Long> sucVoList = new ArrayList<>();
for (AccInfoDetailsVO accInfo : accInfoVOList) {
try {
checkAccount(accInfo);
sucVoList.add(accInfo.getUserId());
} catch (Exception ex) {
errVOList.add(createErrorVO(accInfo, param.getAmount(), ex.getMessage()));
}
}
BigDecimal validTotalAmount = param.getAmount().multiply(new BigDecimal(sucVoList.size()));
return buildResult(param, sucVoList, errVOList, validTotalAmount);
}
private void checkAccount(AccInfoDetailsVO accInfo) {
AccInfoDetailsVO accInfoVO = accInfoService.queryAccInfoByUserId(accInfo.getUserId());
accInfoService.checkAccStatus(accInfoVO);
}
private AccBatchOperationWallerErrorVO createErrorVO(AccInfoDetailsVO accInfo, BigDecimal amount, String errMsg) {
AccBatchOperationWallerErrorVO errVO = new AccBatchOperationWallerErrorVO();
errVO.setUserId(accInfo.getUserId());
errVO.setNickName(accInfo.getNickName());
errVO.setPhoneNumber(accInfo.getPhoneNumber());
errVO.setAmount(amount);
errVO.setErrorMessage(errMsg);
return errVO;
}
private AccBatchOperationWalletPreCheckVO buildResult(AccSubsidyParam param,
List<Long> sucVoList,
List<AccBatchOperationWallerErrorVO> errVOList,
BigDecimal validTotalAmount) {
AccBatchOperationWalletPreCheckVO result = new AccBatchOperationWalletPreCheckVO();
result.setTotalUserSum(param.getUserIds().size());
result.setValidCount(sucVoList.size());
result.setValidTotalAmount(validTotalAmount);
result.setValidUserIdList(sucVoList);
result.setInvalidCount(errVOList.size());
result.setErrVOList(errVOList);
result.setAmount(param.getAmount());
result.setRemark(param.getRemark());
return result;
}
}

View File

@ -160,4 +160,9 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
public void reduceAccWalletInfo(BigDecimal amount, Long userId, Integer walletId) {
accWalletInfoMapper.reduceAccWalletInfo(amount, userId, walletId);
}
@Override
public void clearAccWalletInfo(Long userId, Integer walletId) {
accWalletInfoMapper.clearAccWalletInfo(userId, walletId);
}
}

View File

@ -168,4 +168,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
WHERE user_id = #{custId}
AND wallet_id = #{walletId}
</update>
<update id="clearAccWalletInfo">
UPDATE acc_wallet_info
SET wallet_bal = 0
WHERE user_id = #{custId}
AND wallet_id = #{walletId}
</update>
</mapper>