Commit 2f6092005b09aac72896f67adab6716aa2363083
1 parent
f99e2aec
member: 佣金解冻
Showing
8 changed files
with
136 additions
and
3 deletions
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
| ... | ... | @@ -13,6 +13,7 @@ public interface ErrorCodeConstants { |
| 13 | 13 | ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); |
| 14 | 14 | ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户"); |
| 15 | 15 | ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用"); |
| 16 | + ErrorCode MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH = new ErrorCode(1004001003, "用户冻结佣金({})数量不足"); | |
| 16 | 17 | |
| 17 | 18 | // ========== AUTH 模块 1004003000 ========== |
| 18 | 19 | ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确"); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/brokerage/record/MemberBrokerageRecordMapper.java
| ... | ... | @@ -5,8 +5,12 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | 6 | import cn.iocoder.yudao.module.member.controller.admin.brokerage.record.vo.MemberBrokerageRecordPageReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.member.dal.dataobject.brokerage.record.MemberBrokerageRecordDO; |
| 8 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
| 8 | 9 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 10 | |
| 11 | +import java.time.LocalDateTime; | |
| 12 | +import java.util.List; | |
| 13 | + | |
| 10 | 14 | /** |
| 11 | 15 | * 佣金记录 Mapper |
| 12 | 16 | * |
| ... | ... | @@ -24,4 +28,15 @@ public interface MemberBrokerageRecordMapper extends BaseMapperX<MemberBrokerage |
| 24 | 28 | .orderByDesc(MemberBrokerageRecordDO::getId)); |
| 25 | 29 | } |
| 26 | 30 | |
| 31 | + default List<MemberBrokerageRecordDO> selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) { | |
| 32 | + return selectList(new LambdaQueryWrapper<MemberBrokerageRecordDO>() | |
| 33 | + .eq(MemberBrokerageRecordDO::getStatus, status) | |
| 34 | + .lt(MemberBrokerageRecordDO::getUnfreezeTime, unfreezeTime)); | |
| 35 | + } | |
| 36 | + | |
| 37 | + default int updateByIdAndStatus(Integer id, Integer status, MemberBrokerageRecordDO updateObj) { | |
| 38 | + return update(updateObj, new LambdaQueryWrapper<MemberBrokerageRecordDO>() | |
| 39 | + .eq(MemberBrokerageRecordDO::getId, id) | |
| 40 | + .eq(MemberBrokerageRecordDO::getStatus, status)); | |
| 41 | + } | |
| 27 | 42 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MemberUserMapper.java
| ... | ... | @@ -92,4 +92,20 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> { |
| 92 | 92 | update(null, lambdaUpdateWrapper); |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | + /** | |
| 96 | + * 更新用户冻结佣金(减少) | |
| 97 | + * | |
| 98 | + * @param id 用户编号 | |
| 99 | + * @param incrCount 减少冻结佣金(负数) | |
| 100 | + * @return 更新条数 | |
| 101 | + */ | |
| 102 | + default int updateFrozenBrokeragePriceDecr(Long id, int incrCount) { | |
| 103 | + Assert.isTrue(incrCount < 0); | |
| 104 | + LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>() | |
| 105 | + .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount + // 负数,所以使用 + 号 | |
| 106 | + ", brokerage_price = brokerage_price + " + -incrCount) // 负数,所以使用 - 号 | |
| 107 | + .eq(MemberUserDO::getId, id) | |
| 108 | + .ge(MemberUserDO::getFrozenBrokeragePrice, -incrCount); // cas 逻辑 | |
| 109 | + return update(null, lambdaUpdateWrapper); | |
| 110 | + } | |
| 95 | 111 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/job/brokerage/MemberBrokerageRecordUnfreezeJob.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.job.brokerage; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | |
| 5 | +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; | |
| 6 | +import cn.iocoder.yudao.module.member.service.brokerage.record.MemberBrokerageRecordService; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +import javax.annotation.Resource; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 佣金解冻 Job | |
| 13 | + * | |
| 14 | + * @author owen | |
| 15 | + */ | |
| 16 | +@Component | |
| 17 | +@TenantJob | |
| 18 | +public class MemberBrokerageRecordUnfreezeJob implements JobHandler { | |
| 19 | + | |
| 20 | + @Resource | |
| 21 | + private MemberBrokerageRecordService memberBrokerageRecordService; | |
| 22 | + | |
| 23 | + @Override | |
| 24 | + public String execute(String param) { | |
| 25 | + int count = memberBrokerageRecordService.unfreezeRecord(); | |
| 26 | + return StrUtil.format("解冻佣金 {} 个", count); | |
| 27 | + } | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/brokerage/record/MemberBrokerageRecordService.java
| ... | ... | @@ -37,4 +37,12 @@ public interface MemberBrokerageRecordService { |
| 37 | 37 | * @param list 请求参数列表 |
| 38 | 38 | */ |
| 39 | 39 | void addBrokerage(Long userId, List<BrokerageAddReqDTO> list); |
| 40 | + | |
| 41 | + /** | |
| 42 | + * 解冻佣金:将待结算的佣金记录,状态修改为已结算 | |
| 43 | + * | |
| 44 | + * @return 解冻佣金的数量 | |
| 45 | + */ | |
| 46 | + int unfreezeRecord(); | |
| 47 | + | |
| 40 | 48 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/brokerage/record/MemberBrokerageRecordServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.member.service.brokerage.record; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.hutool.core.util.BooleanUtil; |
| 4 | 5 | import cn.hutool.core.util.NumberUtil; |
| 5 | 6 | import cn.hutool.core.util.ObjectUtil; |
| 7 | +import cn.hutool.extra.spring.SpringUtil; | |
| 6 | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | 9 | import cn.iocoder.yudao.module.member.api.brokerage.dto.BrokerageAddReqDTO; |
| 8 | 10 | import cn.iocoder.yudao.module.member.controller.admin.brokerage.record.vo.MemberBrokerageRecordPageReqVO; |
| ... | ... | @@ -11,10 +13,12 @@ import cn.iocoder.yudao.module.member.dal.dataobject.brokerage.record.MemberBrok |
| 11 | 13 | import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; |
| 12 | 14 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 13 | 15 | import cn.iocoder.yudao.module.member.dal.mysql.brokerage.record.MemberBrokerageRecordMapper; |
| 16 | +import cn.iocoder.yudao.module.member.enums.brokerage.BrokerageRecordStatusEnum; | |
| 14 | 17 | import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService; |
| 15 | 18 | import cn.iocoder.yudao.module.member.service.user.MemberUserService; |
| 16 | 19 | import lombok.extern.slf4j.Slf4j; |
| 17 | 20 | import org.springframework.stereotype.Service; |
| 21 | +import org.springframework.transaction.annotation.Transactional; | |
| 18 | 22 | import org.springframework.validation.annotation.Validated; |
| 19 | 23 | |
| 20 | 24 | import javax.annotation.Resource; |
| ... | ... | @@ -52,6 +56,7 @@ public class MemberBrokerageRecordServiceImpl implements MemberBrokerageRecordSe |
| 52 | 56 | } |
| 53 | 57 | |
| 54 | 58 | @Override |
| 59 | + @Transactional(rollbackFor = Exception.class) | |
| 55 | 60 | public void addBrokerage(Long buyerId, List<BrokerageAddReqDTO> list) { |
| 56 | 61 | MemberPointConfigDO memberConfig = memberConfigService.getPointConfig(); |
| 57 | 62 | // 0 未启用分销功能 |
| ... | ... | @@ -148,4 +153,56 @@ public class MemberBrokerageRecordServiceImpl implements MemberBrokerageRecordSe |
| 148 | 153 | } |
| 149 | 154 | } |
| 150 | 155 | |
| 156 | + @Override | |
| 157 | + public int unfreezeRecord() { | |
| 158 | + // 1. 查询待结算的佣金记录 | |
| 159 | + List<MemberBrokerageRecordDO> records = memberBrokerageRecordMapper.selectListByStatusAndUnfreezeTimeLt( | |
| 160 | + BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus(), LocalDateTime.now()); | |
| 161 | + if (CollUtil.isEmpty(records)) { | |
| 162 | + return 0; | |
| 163 | + } | |
| 164 | + | |
| 165 | + // 2. 遍历执行 | |
| 166 | + int count = 0; | |
| 167 | + for (MemberBrokerageRecordDO record : records) { | |
| 168 | + try { | |
| 169 | + boolean successful = getSelf().unfreezeRecord(record); | |
| 170 | + if (successful) { | |
| 171 | + count++; | |
| 172 | + } | |
| 173 | + } catch (Exception e) { | |
| 174 | + log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId(), e); | |
| 175 | + } | |
| 176 | + } | |
| 177 | + return count; | |
| 178 | + } | |
| 179 | + | |
| 180 | + @Transactional(rollbackFor = Exception.class) | |
| 181 | + public boolean unfreezeRecord(MemberBrokerageRecordDO record) { | |
| 182 | + // 更新记录状态 | |
| 183 | + MemberBrokerageRecordDO updateObj = new MemberBrokerageRecordDO() | |
| 184 | + .setStatus(BrokerageRecordStatusEnum.SETTLEMENT.getStatus()) | |
| 185 | + .setUnfreezeTime(LocalDateTime.now()); | |
| 186 | + int updateRows = memberBrokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj); | |
| 187 | + if (updateRows == 0) { | |
| 188 | + log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId()); | |
| 189 | + return false; | |
| 190 | + } | |
| 191 | + | |
| 192 | + // 更新用户冻结佣金 | |
| 193 | + memberUserService.updateUserFrozenBrokeragePrice(record.getUserId(), record.getPrice()); | |
| 194 | + | |
| 195 | + log.info("[unfreezeRecord][record({}) 更新为已结算成功]", record.getId()); | |
| 196 | + return true; | |
| 197 | + } | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * 获得自身的代理对象,解决 AOP 生效问题 | |
| 201 | + * | |
| 202 | + * @return 自己 | |
| 203 | + */ | |
| 204 | + private MemberBrokerageRecordServiceImpl getSelf() { | |
| 205 | + return SpringUtil.getBean(getClass()); | |
| 206 | + } | |
| 207 | + | |
| 151 | 208 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java
| ... | ... | @@ -176,7 +176,7 @@ public interface MemberUserService { |
| 176 | 176 | MemberUserDO getBrokerageUser(Long id); |
| 177 | 177 | |
| 178 | 178 | /** |
| 179 | - * 增加用户佣金 | |
| 179 | + * 更新用户佣金 | |
| 180 | 180 | * |
| 181 | 181 | * @param id 用户编号 |
| 182 | 182 | * @param brokeragePrice 用户可用佣金 |
| ... | ... | @@ -184,7 +184,7 @@ public interface MemberUserService { |
| 184 | 184 | void updateUserBrokeragePrice(Long id, int brokeragePrice); |
| 185 | 185 | |
| 186 | 186 | /** |
| 187 | - * 增加用户佣金 | |
| 187 | + * 更新用户冻结佣金 | |
| 188 | 188 | * |
| 189 | 189 | * @param id 用户编号 |
| 190 | 190 | * @param frozenBrokeragePrice 用户冻结佣金 | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| ... | ... | @@ -278,7 +278,14 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 278 | 278 | @Override |
| 279 | 279 | @Transactional(rollbackFor = Exception.class) |
| 280 | 280 | public void updateUserFrozenBrokeragePrice(Long id, int frozenBrokeragePrice) { |
| 281 | - memberUserMapper.updateFrozenBrokeragePriceIncr(id, frozenBrokeragePrice); | |
| 281 | + if (frozenBrokeragePrice > 0) { | |
| 282 | + memberUserMapper.updateFrozenBrokeragePriceIncr(id, frozenBrokeragePrice); | |
| 283 | + } else if (frozenBrokeragePrice < 0) { | |
| 284 | + int updateRows = memberUserMapper.updateFrozenBrokeragePriceDecr(id, frozenBrokeragePrice); | |
| 285 | + if (updateRows == 0) { | |
| 286 | + throw exception(MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH); | |
| 287 | + } | |
| 288 | + } | |
| 282 | 289 | } |
| 283 | 290 | |
| 284 | 291 | } | ... | ... |