补贴管理
This commit is contained in:
parent
3f099d8951
commit
50cbbb1311
|
|
@ -0,0 +1,23 @@
|
|||
package com.bonus.canteen.core.account.constants;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum AccWalletClearTypeEnum {
|
||||
CLEAR(1, "清空"),
|
||||
CLEAR_BY(2, "清空至");
|
||||
|
||||
private final Integer key;
|
||||
private final String desc;
|
||||
|
||||
private AccWalletClearTypeEnum(Integer key, String desc) {
|
||||
this.key = key;
|
||||
this.desc = desc;
|
||||
}
|
||||
public Integer getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return this.desc;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package com.bonus.canteen.core.account.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.bonus.canteen.core.account.domain.AccInfo;
|
||||
import com.bonus.canteen.core.account.domain.param.AccOperationQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.param.AccSubsidyParam;
|
||||
import com.bonus.canteen.core.account.domain.param.AccountEnableDisableParam;
|
||||
import com.bonus.canteen.core.account.domain.param.AccountInfoQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO;
|
||||
import com.bonus.canteen.core.account.service.AccOperationHistoryService;
|
||||
import com.bonus.canteen.core.account.service.AccSubService;
|
||||
import com.bonus.canteen.core.account.service.IAccInfoService;
|
||||
import com.bonus.common.core.utils.poi.ExcelUtil;
|
||||
import com.bonus.common.core.web.controller.BaseController;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import com.bonus.common.core.web.page.TableDataInfo;
|
||||
import com.bonus.common.houqin.constant.RetCodeEnum;
|
||||
import com.bonus.common.houqin.i18n.I18n;
|
||||
import com.bonus.common.log.annotation.SysLog;
|
||||
import com.bonus.common.log.enums.OperaType;
|
||||
import com.bonus.system.api.domain.SysUser;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 账户资料Controller
|
||||
*
|
||||
* @author xsheng
|
||||
* @date 2025-04-05
|
||||
*/
|
||||
@Api(tags = "账户补贴接口")
|
||||
@RestController
|
||||
@RequestMapping("/acc/subsidy")
|
||||
public class AccSubsidyController extends BaseController {
|
||||
@Autowired
|
||||
private AccSubService accSubService;
|
||||
@ApiOperation("单人补贴")
|
||||
@PostMapping("/add")
|
||||
public AjaxResult individualAccSubsidyAdd(@RequestBody @Valid AccSubsidyParam param) {
|
||||
this.accSubService.individualAccSubsidyAdd(param);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@ApiOperation("补贴清空")
|
||||
@PostMapping({"/clear"})
|
||||
public AjaxResult individualAccSubsidyClear(@RequestBody @Valid AccSubsidyParam param) {
|
||||
this.accSubService.individualAccSubsidyClear(param);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@ApiOperation("单人补贴")
|
||||
@PostMapping("/batch/add")
|
||||
public AjaxResult batchAccSubsidyAdd(@RequestBody @Valid AccSubsidyParam param) {
|
||||
this.accSubService.batchAccSubsidyAdd(param);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
@ApiOperation("补贴清空")
|
||||
@PostMapping({"/batch/clear"})
|
||||
public AjaxResult batchAccSubsidyClear(@RequestBody @Valid AccSubsidyParam param) {
|
||||
this.accSubService.batchAccSubsidyClear(param);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
||||
|
|
@ -19,20 +19,20 @@ public class AccInfoVo {
|
|||
@ApiModelProperty("账户状态 1正常 2冻结 3销户 4过期")
|
||||
private Integer accStatus;
|
||||
@ApiModelProperty("账户可用总余额(不包括冻结金额)")
|
||||
private Long accBalTotal;
|
||||
private BigDecimal accBalTotal;
|
||||
@ApiModelProperty("账户总余额(包含冻结金额)")
|
||||
private Long accAllBal;
|
||||
private BigDecimal accAllBal;
|
||||
@ApiModelProperty("个人钱包(可用)余额/分")
|
||||
private Long walletBal;
|
||||
private BigDecimal walletBal;
|
||||
@ApiModelProperty("补贴钱包(可用)余额/分")
|
||||
private Long subsidyBal;
|
||||
private BigDecimal subsidyBal;
|
||||
@ApiModelProperty("红包余额")
|
||||
private Long redEnvelope;
|
||||
private BigDecimal redEnvelope;
|
||||
@ApiModelProperty("个人钱包冻结金额")
|
||||
private Long walletFreezeBal;
|
||||
private BigDecimal walletFreezeBal;
|
||||
@ApiModelProperty("补贴钱包冻结金额")
|
||||
private Long subFreezeBal;
|
||||
private Long accFreezeBalTotal;
|
||||
private BigDecimal subFreezeBal;
|
||||
private BigDecimal accFreezeBalTotal;
|
||||
private List<AccWalletInfo> walletInfoList;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -35,17 +36,17 @@ public class AccWalletInfo extends BaseEntity {
|
|||
/** 钱包余额/分 */
|
||||
@Excel(name = "钱包余额/分")
|
||||
@ApiModelProperty(value = "钱包余额/分")
|
||||
private Long walletBal;
|
||||
private BigDecimal walletBal;
|
||||
|
||||
/** 最低余额限制/分 */
|
||||
@Excel(name = "最低余额限制/分")
|
||||
@ApiModelProperty(value = "最低余额限制/分")
|
||||
private Long limitBalance;
|
||||
private BigDecimal limitBalance;
|
||||
|
||||
/** 冻结金额 */
|
||||
@Excel(name = "冻结金额")
|
||||
@ApiModelProperty(value = "冻结金额")
|
||||
private Long frozenBalance;
|
||||
private BigDecimal frozenBalance;
|
||||
|
||||
/** 过期时间 */
|
||||
@ApiModelProperty(value = "过期时间")
|
||||
|
|
|
|||
|
|
@ -7,21 +7,21 @@ import java.math.BigDecimal;
|
|||
@Data
|
||||
public class WalletBalanceVO {
|
||||
@ApiModelProperty("个人钱包余额/分")
|
||||
private Long walletBal;
|
||||
private BigDecimal walletBal;
|
||||
@ApiModelProperty("补贴钱包余额/分")
|
||||
private Long subsidyBal;
|
||||
private BigDecimal subsidyBal;
|
||||
@ApiModelProperty("红包余额")
|
||||
private Long redEnvelope;
|
||||
private BigDecimal redEnvelope;
|
||||
@ApiModelProperty("个人钱包冻结金额")
|
||||
private Long walletFreezeBal;
|
||||
private BigDecimal walletFreezeBal;
|
||||
@ApiModelProperty("补贴钱包冻结金额")
|
||||
private Long subFreezeBal;
|
||||
private BigDecimal subFreezeBal;
|
||||
@ApiModelProperty("冻结金额")
|
||||
private Long accFreezeBalTotal;
|
||||
private BigDecimal accFreezeBalTotal;
|
||||
@ApiModelProperty("账户总余额(包含冻结金额)")
|
||||
private Long accAllBal;
|
||||
private BigDecimal accAllBal;
|
||||
@ApiModelProperty("账户可用余额总余额(不包括冻结金额)")
|
||||
private Long accBalTotal;
|
||||
private BigDecimal accBalTotal;
|
||||
@ApiModelProperty("账户状态 1正常 2冻结 3销户 4过期")
|
||||
private Integer accStatus;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.bonus.canteen.core.account.domain.param;
|
||||
|
||||
import com.bonus.common.core.web.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@Data
|
||||
public class AccSubsidyParam extends BaseEntity {
|
||||
@ApiModelProperty(
|
||||
value = "用户编号",
|
||||
required = true
|
||||
)
|
||||
private @NotNull(
|
||||
message = "用户编号不能为空"
|
||||
) Long userId;
|
||||
@ApiModelProperty(
|
||||
value = "用户编号",
|
||||
required = true
|
||||
)
|
||||
private @NotNull(
|
||||
message = "用户编号不能为空"
|
||||
) List<Long> userIds;
|
||||
@ApiModelProperty(
|
||||
value = "充值金额/分",
|
||||
required = true
|
||||
)
|
||||
private @NotNull(
|
||||
message = "金额不能为空"
|
||||
) @Max(
|
||||
value = 10000000L,
|
||||
message = "超过最大金额限制"
|
||||
) @Min(
|
||||
value = 1L,
|
||||
message = "小于最小充值金额"
|
||||
) BigDecimal amount;
|
||||
@ApiModelProperty("清空类型 清空-1 清空至-2")
|
||||
private Integer clearType = 1;
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ import java.util.List;
|
|||
|
||||
@Data
|
||||
public class AccountInfoQueryParam extends BaseEntity {
|
||||
@ApiModelProperty("用户编号集合")
|
||||
private List<Long> userIds;
|
||||
@ApiModelProperty("账户状态 1正常 2停用")
|
||||
private List<Integer> accStatusList;
|
||||
@ApiModelProperty("筛选钱包类型 0-账户总余额 1-个人钱包 2-补贴钱包")
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ public class AccInfoDetailsVO {
|
|||
private Integer userType;
|
||||
@ApiModelProperty("用户部门")
|
||||
private String deptName;
|
||||
@ApiModelProperty("用户部门")
|
||||
private Long deptId;
|
||||
@ApiModelProperty("用户类别(展示)")
|
||||
@Excel(name = "用户类别(展示)")
|
||||
private String userTypeName;
|
||||
|
|
@ -43,9 +45,6 @@ public class AccInfoDetailsVO {
|
|||
@ApiModelProperty("补贴钱包余额/分")
|
||||
@Excel(name = "补贴钱包余额/分")
|
||||
private BigDecimal subsidyBal;
|
||||
@ApiModelProperty("红包余额")
|
||||
@Excel(name = "红包余额")
|
||||
private BigDecimal redEnvelope;
|
||||
@ApiModelProperty("冻结金额")
|
||||
@Excel(name = "冻结金额")
|
||||
private BigDecimal accFreezeBalTotal;
|
||||
|
|
@ -55,7 +54,7 @@ public class AccInfoDetailsVO {
|
|||
@ApiModelProperty("补贴钱包允许最低余额限制")
|
||||
@Excel(name = "补贴钱包允许最低余额限制")
|
||||
private BigDecimal minSubBalLimit;
|
||||
@ApiModelProperty("账户状态 1正常 2冻结 3销户 4过期")
|
||||
@ApiModelProperty("账户状态 1正常 2冻结")
|
||||
private Integer accStatus;
|
||||
@ApiModelProperty("账户状态名称")
|
||||
@Excel(name = "账户状态名称")
|
||||
|
|
|
|||
|
|
@ -76,4 +76,7 @@ public interface AccInfoMapper extends BaseMapper<AccInfo> {
|
|||
AccInfoDetailsVO queryAccInfoBalanceSum(@Param("accountInfoQueryParam") AccountInfoQueryParam accountInfoQueryParam);
|
||||
|
||||
void updateAccInfoEndDateByUserId(LocalDate endDate, List<Long> userIds, String updateBy);
|
||||
List<AccInfoDetailsVO> queryAccInfoByUserIds(@Param("userIds") List<Long> userIds);
|
||||
AccInfoDetailsVO queryAccInfoByUserId(@Param("userId") Long userId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public interface AccWalletInfoMapper {
|
|||
* @return 钱包详情信息
|
||||
*/
|
||||
public AccWalletInfo selectAccWalletInfoByUserId(Long userId);
|
||||
public AccWalletInfo selectAccWalletInfoByUserIdAndWalletId(Long userId, Integer walletId);
|
||||
|
||||
List<AccWalletInfoVO> selectAccWalletInfoByUserIds(@Param("userIds") List<Long> userIds);
|
||||
|
||||
|
|
@ -72,4 +73,12 @@ public interface AccWalletInfoMapper {
|
|||
@Param("updateBy") String updateBy,
|
||||
@Param("updateTime") LocalDate updateTime);
|
||||
|
||||
void addAccWalletInfo(@Param("amount") BigDecimal amount,
|
||||
@Param("userId") Long userId,
|
||||
@Param("walletId") Integer walletId
|
||||
);
|
||||
void reduceAccWalletInfo(@Param("amount") BigDecimal amount,
|
||||
@Param("userId") Long userId,
|
||||
@Param("walletId") Integer walletId
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package com.bonus.canteen.core.account.service;
|
||||
|
||||
import com.bonus.canteen.core.account.domain.param.AccSubsidyParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public interface AccSubService {
|
||||
void individualAccSubsidyAdd(AccSubsidyParam param);
|
||||
|
||||
void individualAccSubsidyClear(AccSubsidyParam param);
|
||||
|
||||
void batchAccSubsidyAdd(AccSubsidyParam param);
|
||||
|
||||
void batchAccSubsidyClear(AccSubsidyParam param);
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import com.bonus.canteen.core.account.domain.param.AccountInfoQueryParam;
|
|||
import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccInfoInvalidSumVO;
|
||||
import com.bonus.system.api.domain.SysUser;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 账户资料Service接口
|
||||
|
|
@ -70,4 +71,7 @@ public interface IAccInfoService {
|
|||
public String getOrderQRCode();
|
||||
|
||||
public WalletBalanceVO queryWalletBalance(AccInfo accInfo);
|
||||
List<AccInfoDetailsVO> queryAccInfoByUserIds(List<Long> userIds);
|
||||
AccInfoDetailsVO queryAccInfoByUserId(Long userId);
|
||||
void checkAccStatus(AccInfoDetailsVO accInfoVO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import java.util.Map;
|
|||
|
||||
import com.bonus.canteen.core.account.domain.AccWalletInfo;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 钱包详情信息Service接口
|
||||
|
|
@ -21,6 +22,7 @@ public interface IAccWalletInfoService {
|
|||
* @return 钱包详情信息
|
||||
*/
|
||||
public AccWalletInfo selectAccWalletInfoByUserId(Long userId);
|
||||
public AccWalletInfo selectAccWalletInfoByUserIdAndWalletId(Long userId, Integer walletId);
|
||||
|
||||
/**
|
||||
* 查询钱包详情信息列表
|
||||
|
|
@ -67,5 +69,6 @@ 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.bonus.canteen.core.account.constants.AccWalletIdEnum;
|
||||
import com.bonus.canteen.core.account.constants.AccStatusEnum;
|
||||
|
|
@ -57,7 +56,6 @@ import javax.annotation.Resource;
|
|||
* @date 2025-04-05
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AccInfoServiceImpl implements IAccInfoService {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccInfoServiceImpl.class);
|
||||
|
||||
|
|
@ -94,6 +92,9 @@ public class AccInfoServiceImpl implements IAccInfoService {
|
|||
@Override
|
||||
public List<AccInfoDetailsVO> selectAccInfoList(AccountInfoQueryParam accountInfoQueryParam) {
|
||||
String encryptedSearchValue = SM4EncryptUtils.sm4Encrypt(accountInfoQueryParam.getSearchValue());
|
||||
if(CollUtil.isEmpty(accountInfoQueryParam.getAccStatusList())) {
|
||||
accountInfoQueryParam.setAccStatusList(Arrays.asList(AccStatusEnum.NORMAL.getKey(), AccStatusEnum.DEACTIVATE.getKey()));
|
||||
}
|
||||
List<AccInfoDetailsVO> list = accInfoMapper.queryAccInfoDetails(accountInfoQueryParam, encryptedSearchValue);
|
||||
handleResult(list);
|
||||
return list;
|
||||
|
|
@ -292,6 +293,9 @@ public class AccInfoServiceImpl implements IAccInfoService {
|
|||
}
|
||||
|
||||
public AccInfoDetailsVO queryAccInfoBalanceSum(AccountInfoQueryParam accountInfoQueryParam) {
|
||||
if(CollUtil.isEmpty(accountInfoQueryParam.getAccStatusList())) {
|
||||
accountInfoQueryParam.setAccStatusList(Arrays.asList(AccStatusEnum.NORMAL.getKey(), AccStatusEnum.DEACTIVATE.getKey()));
|
||||
}
|
||||
return accInfoMapper.queryAccInfoBalanceSum(accountInfoQueryParam);
|
||||
}
|
||||
|
||||
|
|
@ -326,11 +330,36 @@ public class AccInfoServiceImpl implements IAccInfoService {
|
|||
return walletBalanceVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccInfoDetailsVO> queryAccInfoByUserIds(List<Long> userIds) {
|
||||
return accInfoMapper.queryAccInfoByUserIds(userIds);
|
||||
}
|
||||
@Override
|
||||
public AccInfoDetailsVO queryAccInfoByUserId(Long userId) {
|
||||
return accInfoMapper.queryAccInfoByUserId(userId);
|
||||
}
|
||||
@Override
|
||||
public void checkAccStatus(AccInfoDetailsVO accInfoVO) {
|
||||
if (ObjectUtil.isNull(accInfoVO)) {
|
||||
throw new ServiceException("账户不存在");
|
||||
}
|
||||
|
||||
AccStatusEnum statusEnum = AccStatusEnum.getEnum(accInfoVO.getAccStatus());
|
||||
if (ObjectUtil.isNull(statusEnum)) {
|
||||
throw new ServiceException("账户状态异常");
|
||||
}
|
||||
|
||||
if (statusEnum == AccStatusEnum.DEACTIVATE) {
|
||||
throw new ServiceException("账户已停用");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void setAccInfoVODetailList(AccInfoVo accInfoVo, List<AccWalletInfo> walletInfoList) {
|
||||
if (ObjectUtil.isNotEmpty(walletInfoList)) {
|
||||
accInfoVo.setWalletBal(walletInfoList.stream().filter(o -> o.getWalletId().intValue() == AccWalletIdEnum.WALLET.getKey()).mapToLong(AccWalletInfo::getWalletBal).sum());
|
||||
accInfoVo.setSubsidyBal(walletInfoList.stream().filter(o -> o.getWalletId().intValue() == AccWalletIdEnum.SUBSIDY.getKey()).mapToLong(AccWalletInfo::getWalletBal).sum());
|
||||
accInfoVo.setAccAllBal(accInfoVo.getWalletBal() + accInfoVo.getSubsidyBal());
|
||||
}
|
||||
// if (ObjectUtil.isNotEmpty(walletInfoList)) {
|
||||
// accInfoVo.setWalletBal(walletInfoList.stream().filter(o -> o.getWalletId().intValue() == AccWalletIdEnum.WALLET.getKey()).mapToLong(AccWalletInfo::getWalletBal).sum());
|
||||
// accInfoVo.setSubsidyBal(walletInfoList.stream().filter(o -> o.getWalletId().intValue() == AccWalletIdEnum.SUBSIDY.getKey()).mapToLong(AccWalletInfo::getWalletBal).sum());
|
||||
// accInfoVo.setAccAllBal(accInfoVo.getWalletBal() + accInfoVo.getSubsidyBal());
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
package com.bonus.canteen.core.account.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
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.AccInfoDetailsVO;
|
||||
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.common.core.exception.ServiceException;
|
||||
import com.bonus.common.houqin.i18n.I18n;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class AccSubServiceImpl implements AccSubService {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccSubServiceImpl.class);
|
||||
@Autowired
|
||||
@Lazy
|
||||
private IAccInfoService accInfoService;
|
||||
@Autowired
|
||||
@Lazy
|
||||
private IAccWalletInfoService accWalletInfoService;
|
||||
@Resource(
|
||||
name = "smartCanteenTaskExecutor"
|
||||
)
|
||||
@Lazy
|
||||
private AsyncTaskExecutor asyncTaskExecutor;
|
||||
|
||||
@Transactional(
|
||||
rollbackFor = {Exception.class}
|
||||
)
|
||||
public void individualAccSubsidyAdd(AccSubsidyParam param) {
|
||||
AccInfoDetailsVO accInfoVO = this.accInfoService.queryAccInfoByUserId(param.getUserId());
|
||||
if(Objects.isNull(accInfoVO)) {
|
||||
throw new ServiceException("账户不存在");
|
||||
}
|
||||
accInfoService.checkAccStatus(accInfoVO);
|
||||
addAccWalletBalance(param.getAmount(), param.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
|
||||
}
|
||||
@Transactional(
|
||||
rollbackFor = {Exception.class}
|
||||
)
|
||||
public void individualAccSubsidyClear(AccSubsidyParam param) {
|
||||
AccInfoDetailsVO accInfoVO = this.accInfoService.queryAccInfoByUserId(param.getUserId());
|
||||
if(Objects.isNull(accInfoVO)) {
|
||||
throw new ServiceException("账户不存在");
|
||||
}
|
||||
accInfoService.checkAccStatus(accInfoVO);
|
||||
this.clearAccSubsidyHandler(accInfoVO, param);
|
||||
}
|
||||
|
||||
private void clearAccSubsidyHandler(AccInfoDetailsVO accInfoVO, AccSubsidyParam param) {
|
||||
AccWalletInfo walletInfo = accWalletInfoService.selectAccWalletInfoByUserIdAndWalletId(accInfoVO.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
|
||||
if(Objects.isNull(walletInfo)) {
|
||||
throw new ServiceException("补贴钱包不存在");
|
||||
}
|
||||
BigDecimal walletBal = walletInfo.getWalletBal();
|
||||
if (walletBal.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException(I18n.getMessage("补贴钱包余额不足"));
|
||||
} else {
|
||||
BigDecimal clearAmount = this.calculateClearAmount(walletBal, param.getClearType(), param.getAmount());
|
||||
if (clearAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException(I18n.getMessage("清空后补贴钱包余额小于等于0"));
|
||||
} else {
|
||||
reduceAccWalletBalance(clearAmount, param.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BigDecimal calculateClearAmount(BigDecimal walletBal, Integer clearType, BigDecimal amount) {
|
||||
BigDecimal clearAmount;
|
||||
if (AccWalletClearTypeEnum.CLEAR_BY.getKey().equals(clearType)) {
|
||||
clearAmount = amount.compareTo(walletBal) >= 0 ? BigDecimal.ZERO : walletBal.subtract(amount);
|
||||
} else {
|
||||
clearAmount = amount.compareTo(walletBal) >= 0 ? walletBal : amount;
|
||||
}
|
||||
return clearAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : clearAmount;
|
||||
}
|
||||
|
||||
public void batchAccSubsidyClear(AccSubsidyParam param) {
|
||||
log.info("批量清空补贴用户数量:{}", param.getUserIds().size());
|
||||
if(CollUtil.isEmpty(param.getUserIds())) {
|
||||
throw new ServiceException("批量清空补贴用户为空");
|
||||
}
|
||||
List<AccInfoDetailsVO> accInfoVOList = this.accInfoService.queryAccInfoByUserIds(param.getUserIds());
|
||||
log.info("批量清空补贴根据用户编号查询到{}人", accInfoVOList.size());
|
||||
if (CollUtil.isEmpty(accInfoVOList)) {
|
||||
throw new ServiceException("批量清空补贴查询到的用户为空");
|
||||
} else {
|
||||
this.asyncTaskExecutor.execute(() -> {
|
||||
this.batchAccSubsidyClearHandler(accInfoVOList, param.getAmount(), param.getClearType());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void batchAccSubsidyAdd(AccSubsidyParam param) {
|
||||
log.info("批量补贴用户数量:{}", param.getUserIds().size());
|
||||
if(CollUtil.isEmpty(param.getUserIds())) {
|
||||
throw new ServiceException("批量补贴用户为空");
|
||||
}
|
||||
List<AccInfoDetailsVO> accInfoVOList = this.accInfoService.queryAccInfoByUserIds(param.getUserIds());
|
||||
log.info("批量补贴根据用户编号查询到{}人", accInfoVOList.size());
|
||||
if (CollUtil.isEmpty(accInfoVOList)) {
|
||||
throw new ServiceException("批量补贴查询到的用户为空");
|
||||
} else {
|
||||
this.asyncTaskExecutor.execute(() -> {
|
||||
this.batchAccSubsidyAddHandler(accInfoVOList, param.getAmount());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void batchAccSubsidyAddHandler(List<AccInfoDetailsVO> accInfoDetails, BigDecimal amount) {
|
||||
log.info("批量补贴开始:{}", accInfoDetails.size());
|
||||
AccRedisUtils.lockBatchUpdateAccWallet();
|
||||
try {
|
||||
accInfoDetails.forEach((accInfo) -> {
|
||||
try {
|
||||
AccInfoDetailsVO accInfoVO = this.accInfoService.queryAccInfoByUserId(accInfo.getUserId());
|
||||
if(Objects.isNull(accInfoVO)) {
|
||||
throw new ServiceException(accInfo.getNickName() + "的账户不存在");
|
||||
}
|
||||
accInfoService.checkAccStatus(accInfoVO);
|
||||
addAccWalletBalance(amount, accInfo.getUserId(), AccWalletIdEnum.SUBSIDY.getKey());
|
||||
} catch (Exception var10) {
|
||||
log.error("批量补贴充值异常", var10);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
log.error("批量补贴系统异常", ex);
|
||||
} finally {
|
||||
AccRedisUtils.unlockBatchUpdateAccWallet();
|
||||
}
|
||||
|
||||
log.info("批量补贴结束");
|
||||
}
|
||||
|
||||
private void batchAccSubsidyClearHandler(List<AccInfoDetailsVO> accInfoDetails, BigDecimal amount, Integer clearType) {
|
||||
log.info("批量清空补贴开始:{}", accInfoDetails.size());
|
||||
AccRedisUtils.lockBatchUpdateAccWallet();
|
||||
try {
|
||||
accInfoDetails.forEach((accInfo) -> {
|
||||
try {
|
||||
AccInfoDetailsVO accInfoVO = this.accInfoService.queryAccInfoByUserId(accInfo.getUserId());
|
||||
if(Objects.isNull(accInfoVO)) {
|
||||
throw new ServiceException(accInfo.getNickName() + "的账户不存在");
|
||||
}
|
||||
accInfoService.checkAccStatus(accInfoVO);
|
||||
AccSubsidyParam param = new AccSubsidyParam();
|
||||
param.setAmount(amount);
|
||||
param.setUserId(accInfo.getUserId());
|
||||
param.setClearType(clearType);
|
||||
clearAccSubsidyHandler(accInfoVO, param);
|
||||
} catch (Exception var10) {
|
||||
log.error("批量清空补贴充值异常", var10);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
log.error("批量清空补贴系统异常", ex);
|
||||
} finally {
|
||||
AccRedisUtils.unlockBatchUpdateAccWallet();
|
||||
}
|
||||
|
||||
log.info("批量清空补贴结束");
|
||||
}
|
||||
public void addAccWalletBalance(BigDecimal amount, Long userId, Integer walletId) {
|
||||
log.info("新增补贴入参: amount:{}, userId:{},walletId:{}", amount, userId, walletId);
|
||||
AccRedisUtils.lockUpdateAccWalletBalance(userId);
|
||||
try {
|
||||
accWalletInfoService.addAccWalletInfo(amount, userId, walletId);
|
||||
log.info("新增补贴结束");
|
||||
} finally {
|
||||
AccRedisUtils.unlockUpdateAccWalletBalance(userId);
|
||||
}
|
||||
}
|
||||
|
||||
public void reduceAccWalletBalance(BigDecimal amount, Long userId, Integer walletId) {
|
||||
log.info("清空补贴入参: amount:{}, userId:{},walletId:{}", amount, userId, walletId);
|
||||
AccRedisUtils.lockUpdateAccWalletBalance(userId);
|
||||
try {
|
||||
accWalletInfoService.reduceAccWalletInfo(amount, userId, walletId);
|
||||
log.info("清空补贴结束");
|
||||
} finally {
|
||||
AccRedisUtils.unlockUpdateAccWalletBalance(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,11 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
|
|||
return accWalletInfoMapper.selectAccWalletInfoByUserId(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccWalletInfo selectAccWalletInfoByUserIdAndWalletId(Long userId, Integer walletId) {
|
||||
return accWalletInfoMapper.selectAccWalletInfoByUserIdAndWalletId(userId, walletId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询钱包详情信息列表
|
||||
*
|
||||
|
|
@ -146,5 +151,13 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addAccWalletInfo(BigDecimal amount, Long userId, Integer walletId) {
|
||||
accWalletInfoMapper.addAccWalletInfo(amount, userId, walletId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reduceAccWalletInfo(BigDecimal amount, Long userId, Integer walletId) {
|
||||
accWalletInfoMapper.reduceAccWalletInfo(amount, userId, walletId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package com.bonus.canteen.core.account.utils;
|
||||
|
||||
import com.bonus.canteen.core.common.utils.RedisUtil;
|
||||
import com.bonus.canteen.core.common.utils.TenantContextHolder;
|
||||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.houqin.constant.GlobalConstants;
|
||||
import com.bonus.common.houqin.constant.LeConstants;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AccRedisUtils {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccRedisUtils.class);
|
||||
|
||||
public static void lockUpdateAccWalletBalance(Long userId) {
|
||||
String lockerKey = generateWalletLockerKey(userId);
|
||||
if (!RedisUtil.tryLock(lockerKey, 10, 15)) {
|
||||
throw new ServiceException("账户有交易正在进行中");
|
||||
}
|
||||
}
|
||||
|
||||
public static void unlockUpdateAccWalletBalance(Long userId) {
|
||||
String lockerKey = generateWalletLockerKey(userId);
|
||||
try {
|
||||
RedisUtil.safeUnLock(lockerKey);
|
||||
} catch (Exception ex) {
|
||||
log.error("账户操作解锁异常", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void lockBatchUpdateAccWallet() {
|
||||
String lockerKey = generateBatchUpdateAccWalletKey();
|
||||
if (!RedisUtil.setNx(lockerKey, 1, 3600)) {
|
||||
throw new ServiceException("已有任务在执行,请稍后~");
|
||||
}
|
||||
}
|
||||
|
||||
public static void unlockBatchUpdateAccWallet() {
|
||||
RedisUtil.delete(generateBatchUpdateAccWalletKey());
|
||||
}
|
||||
|
||||
private static String generateWalletLockerKey(Long userId) {
|
||||
return String.format("sc:acc_lock_merchant_%s_user_%s_wallet_update",
|
||||
GlobalConstants.TENANT_ID, userId);
|
||||
}
|
||||
|
||||
private static String generateBatchUpdateAccWalletKey() {
|
||||
return String.format("sc:acc_lock_merchant_%s_wallet_batch_update",
|
||||
GlobalConstants.TENANT_ID);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
package com.bonus.canteen.core.common.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.houqin.utils.SpringContextHolder;
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
|
||||
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RedisUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(RedisUtil.class);
|
||||
|
||||
public static void setString(String key, String value) {
|
||||
setString(key, value, (Long)null);
|
||||
}
|
||||
|
||||
public static void setString(String key, String value, Long timeOut) {
|
||||
timeOut = timeoutFilter(timeOut);
|
||||
if (value != null) {
|
||||
if (timeOut != null) {
|
||||
stringRedisTemplate().opsForValue().set(key, value, timeOut, TimeUnit.SECONDS);
|
||||
} else {
|
||||
stringRedisTemplate().opsForValue().set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Boolean setIfPresentString(String key, String value, Long timeOut) {
|
||||
timeOut = timeoutFilter(timeOut);
|
||||
if (value != null) {
|
||||
return timeOut != null ? stringRedisTemplate().opsForValue().setIfPresent(key, value, timeOut, TimeUnit.SECONDS) : stringRedisTemplate().opsForValue().setIfPresent(key, value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean setNx(String key, Object value, int expireTime) {
|
||||
Boolean ifSucc = redisTemplate().opsForValue().setIfAbsent(key, value, (long)expireTime, TimeUnit.SECONDS);
|
||||
return ifSucc == null ? false : ifSucc;
|
||||
}
|
||||
|
||||
public static String getString(String key) {
|
||||
return (String)stringRedisTemplate().opsForValue().get(key);
|
||||
}
|
||||
|
||||
public static void setObj(String key, Object value) {
|
||||
setObj(key, value, (Long)null);
|
||||
}
|
||||
|
||||
public static void setObj(String key, Object value, Long timeOut) {
|
||||
timeOut = timeoutFilter(timeOut);
|
||||
if (value != null) {
|
||||
if (timeOut != null) {
|
||||
redisTemplate().opsForValue().set(key, value, timeOut, TimeUnit.SECONDS);
|
||||
} else {
|
||||
redisTemplate().opsForValue().set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Object getObj(String key) {
|
||||
return redisTemplate().opsForValue().get(key);
|
||||
}
|
||||
|
||||
public static void delete(String key) {
|
||||
redisTemplate().delete(key);
|
||||
}
|
||||
|
||||
public static void deleteByPattern(String keyPattern) {
|
||||
Set<Object> keys = redisTemplate().keys(keyPattern);
|
||||
if (CollUtil.isNotEmpty(keys)) {
|
||||
redisTemplate().delete(keys);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static Long timeoutFilter(Long timeout) {
|
||||
Long maxExpSecond = (Long)environment().getProperty("spring.redis.custom-max-expiration-second", Long.class);
|
||||
if (maxExpSecond != null && (timeout == null || timeout > maxExpSecond)) {
|
||||
timeout = maxExpSecond;
|
||||
}
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public static List<String> keysByPattern(String pattern) {
|
||||
Set<Object> keys = redisTemplate().keys(pattern);
|
||||
return (List)(CollUtil.isEmpty(keys) ? new ArrayList() : (List)keys.stream().map(Object::toString).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public static void multiSet(Map map) {
|
||||
redisTemplate().opsForValue().multiSet(map);
|
||||
}
|
||||
|
||||
public static List multiGet(List keys) {
|
||||
return redisTemplate().opsForValue().multiGet(keys);
|
||||
}
|
||||
|
||||
public static void zAdd(String key, Object value, double score) {
|
||||
redisTemplate().opsForZSet().add(key, value, score);
|
||||
}
|
||||
|
||||
public static Set<ZSetOperations.TypedTuple<Object>> zGetList(String key, long start, long end) {
|
||||
return redisTemplate().opsForZSet().rangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
private static StringRedisTemplate stringRedisTemplate() {
|
||||
return (StringRedisTemplate) SpringContextHolder.getBean(StringRedisTemplate.class);
|
||||
}
|
||||
|
||||
private static RedisTemplate<Object, Object> redisTemplate() {
|
||||
return (RedisTemplate)SpringContextHolder.getBean("redisTemplate");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Environment environment() {
|
||||
return (Environment)SpringContextHolder.getBean(Environment.class);
|
||||
}
|
||||
|
||||
public static Integer incr(String key, Long liveTime) {
|
||||
return getRedisAtomicInteger(key, liveTime, true);
|
||||
}
|
||||
public static Integer getRedisAtomicInteger(String key, Long liveTime, Boolean incrDecrFlag) {
|
||||
RedisConnectionFactory connectionFactory = redisTemplate().getConnectionFactory();
|
||||
if (connectionFactory == null) {
|
||||
throw new ServiceException("Redis连接异常");
|
||||
} else {
|
||||
RedisAtomicInteger entityIdCounter = new RedisAtomicInteger(key, connectionFactory);
|
||||
if (incrDecrFlag == null) {
|
||||
return entityIdCounter.get();
|
||||
} else {
|
||||
int increment;
|
||||
if (incrDecrFlag) {
|
||||
increment = entityIdCounter.getAndIncrement();
|
||||
if (liveTime > 0L) {
|
||||
entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
return increment + 1;
|
||||
} else {
|
||||
increment = entityIdCounter.getAndDecrement();
|
||||
if (liveTime > 0L) {
|
||||
entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
return increment - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static RLock getLock(String key) {
|
||||
return redissonClient().getLock(key);
|
||||
}
|
||||
|
||||
private static RedissonClient redissonClient() {
|
||||
return (RedissonClient)SpringContextHolder.getBean(RedissonClient.class);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean tryLock(String key) {
|
||||
return tryLock(key, (Integer)null, (Integer)null);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public static boolean tryLock(String key, Integer waitSecond) {
|
||||
return tryLock(key, waitSecond, (Integer)null);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public static boolean tryLock(String key, Integer waitSecond, Integer expireSecond) {
|
||||
if (waitSecond == null && expireSecond != null) {
|
||||
throw new ServiceException("不能这样使用");
|
||||
} else {
|
||||
RLock lock = redissonClient().getLock(key);
|
||||
|
||||
try {
|
||||
if (waitSecond != null && expireSecond != null) {
|
||||
return lock.tryLock((long)waitSecond, (long)expireSecond, TimeUnit.SECONDS);
|
||||
} else {
|
||||
return waitSecond != null ? lock.tryLock((long)waitSecond, TimeUnit.SECONDS) : lock.tryLock();
|
||||
}
|
||||
} catch (InterruptedException var5) {
|
||||
log.error("【分布式锁】tryLock失败:{}", var5.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
public static void safeUnLock(String key) {
|
||||
RLock lock = redissonClient().getLock(key);
|
||||
if (lock.isHeldByCurrentThread() && lock.isLocked()) {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Long getIncr(RedisTemplate<Object, Object> redisTemplate, String key) {
|
||||
RedisAtomicLong counter = new RedisAtomicLong(key, (RedisConnectionFactory) Objects.requireNonNull(redisTemplate.getConnectionFactory()));
|
||||
long increment = counter.getAndIncrement();
|
||||
if (increment <= 0L) {
|
||||
setIncr(redisTemplate, key, 2);
|
||||
return 1L;
|
||||
} else {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime max = LocalDate.now().atTime(LocalTime.MAX);
|
||||
long millis = Duration.between(now, max).toMillis();
|
||||
counter.expire(millis, TimeUnit.MILLISECONDS);
|
||||
return increment;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setIncr(RedisTemplate<Object, Object> redisTemplate, String key, int value) {
|
||||
RedisAtomicLong counter = new RedisAtomicLong(key, (RedisConnectionFactory)Objects.requireNonNull(redisTemplate.getConnectionFactory()));
|
||||
counter.set((long)value);
|
||||
long millis = Duration.between(LocalDateTime.now(), LocalDate.now().atTime(LocalTime.MAX)).toMillis();
|
||||
counter.expire(millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public static void lock(String key) {
|
||||
RLock lock = redissonClient().getLock(key);
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -499,4 +499,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
#{userId}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="queryAccInfoByUserIds" resultType="com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO">
|
||||
SELECT ai.acc_id,
|
||||
ai.user_id,
|
||||
ai.end_date,
|
||||
ai.acc_status,
|
||||
su.nick_name,
|
||||
su.phonenumber,
|
||||
su.dept_id
|
||||
FROM acc_info ai
|
||||
LEFT JOIN sys_user su ON su.user_id = ai.user_id
|
||||
LEFT JOIN sys_dept co ON co.dept_id = su.dept_id
|
||||
WHERE ai.user_id in
|
||||
<foreach collection="userIds" item="userId" separator="," open="(" close=")">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="queryAccInfoByUserId" resultType="com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO">
|
||||
SELECT ai.acc_id,
|
||||
ai.user_id,
|
||||
ai.end_date,
|
||||
ai.acc_status,
|
||||
su.nick_name,
|
||||
su.phonenumber,
|
||||
su.dept_id
|
||||
FROM acc_info ai
|
||||
LEFT JOIN sys_user su ON su.user_id = ai.user_id
|
||||
LEFT JOIN sys_dept co ON co.dept_id = su.dept_id
|
||||
WHERE ai.user_id = #{userId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -41,6 +41,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
where user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<select id="selectAccWalletInfoByUserIdAndWalletId" resultMap="AccWalletInfoResult">
|
||||
<include refid="selectAccWalletInfoVo"/>
|
||||
where user_id = #{userId} and wallet_id = #{walletId}
|
||||
</select>
|
||||
|
||||
<select id="selectAccWalletInfoByUserIds" resultType="com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO">
|
||||
SELECT
|
||||
user_id,
|
||||
|
|
@ -149,4 +154,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
AND wallet_id = #{walletId}
|
||||
</where>
|
||||
</update>
|
||||
|
||||
<update id="addAccWalletInfo">
|
||||
UPDATE acc_wallet_info
|
||||
SET wallet_bal = wallet_bal + #{amount}
|
||||
WHERE user_id = #{userId}
|
||||
AND wallet_id = #{walletId}
|
||||
</update>
|
||||
|
||||
<update id="reduceAccWalletInfo">
|
||||
UPDATE acc_wallet_info
|
||||
SET wallet_bal = wallet_bal - #{amount}
|
||||
WHERE user_id = #{custId}
|
||||
AND wallet_id = #{walletId}
|
||||
</update>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue