Browse Source

member: 佣金解冻

owen 1 year ago
parent
commit
2f6092005b

+ 1 - 0
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 {
     ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
     ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
     ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
+    ErrorCode MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH = new ErrorCode(1004001003, "用户冻结佣金({})数量不足");
 
     // ========== AUTH 模块 1004003000 ==========
     ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");

+ 15 - 0
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;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.member.controller.admin.brokerage.record.vo.MemberBrokerageRecordPageReqVO;
 import cn.iocoder.yudao.module.member.dal.dataobject.brokerage.record.MemberBrokerageRecordDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
+import java.util.List;
+
 /**
  * 佣金记录 Mapper
  *
@@ -24,4 +28,15 @@ public interface MemberBrokerageRecordMapper extends BaseMapperX<MemberBrokerage
                 .orderByDesc(MemberBrokerageRecordDO::getId));
     }
 
+    default List<MemberBrokerageRecordDO> selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) {
+        return selectList(new LambdaQueryWrapper<MemberBrokerageRecordDO>()
+                .eq(MemberBrokerageRecordDO::getStatus, status)
+                .lt(MemberBrokerageRecordDO::getUnfreezeTime, unfreezeTime));
+    }
+
+    default int updateByIdAndStatus(Integer id, Integer status, MemberBrokerageRecordDO updateObj) {
+        return update(updateObj, new LambdaQueryWrapper<MemberBrokerageRecordDO>()
+                .eq(MemberBrokerageRecordDO::getId, id)
+                .eq(MemberBrokerageRecordDO::getStatus, status));
+    }
 }

+ 16 - 0
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> {
         update(null, lambdaUpdateWrapper);
     }
 
+    /**
+     * 更新用户冻结佣金(减少)
+     *
+     * @param id        用户编号
+     * @param incrCount 减少冻结佣金(负数)
+     * @return 更新条数
+     */
+    default int updateFrozenBrokeragePriceDecr(Long id, int incrCount) {
+        Assert.isTrue(incrCount < 0);
+        LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
+                .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount + // 负数,所以使用 + 号
+                        ", brokerage_price = brokerage_price + " + -incrCount) // 负数,所以使用 - 号
+                .eq(MemberUserDO::getId, id)
+                .ge(MemberUserDO::getFrozenBrokeragePrice, -incrCount); // cas 逻辑
+        return update(null, lambdaUpdateWrapper);
+    }
 }

+ 29 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/job/brokerage/MemberBrokerageRecordUnfreezeJob.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.member.job.brokerage;
+
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
+import cn.iocoder.yudao.module.member.service.brokerage.record.MemberBrokerageRecordService;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 佣金解冻 Job
+ *
+ * @author owen
+ */
+@Component
+@TenantJob
+public class MemberBrokerageRecordUnfreezeJob implements JobHandler {
+
+    @Resource
+    private MemberBrokerageRecordService memberBrokerageRecordService;
+
+    @Override
+    public String execute(String param) {
+        int count = memberBrokerageRecordService.unfreezeRecord();
+        return StrUtil.format("解冻佣金 {} 个", count);
+    }
+
+}

+ 8 - 0
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 {
      * @param list   请求参数列表
      */
     void addBrokerage(Long userId, List<BrokerageAddReqDTO> list);
+
+    /**
+     * 解冻佣金:将待结算的佣金记录,状态修改为已结算
+     *
+     * @return 解冻佣金的数量
+     */
+    int unfreezeRecord();
+
 }

+ 57 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/brokerage/record/MemberBrokerageRecordServiceImpl.java

@@ -1,8 +1,10 @@
 package cn.iocoder.yudao.module.member.service.brokerage.record;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.BooleanUtil;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.api.brokerage.dto.BrokerageAddReqDTO;
 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
 import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 import cn.iocoder.yudao.module.member.dal.mysql.brokerage.record.MemberBrokerageRecordMapper;
+import cn.iocoder.yudao.module.member.enums.brokerage.BrokerageRecordStatusEnum;
 import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService;
 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
@@ -52,6 +56,7 @@ public class MemberBrokerageRecordServiceImpl implements MemberBrokerageRecordSe
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void addBrokerage(Long buyerId, List<BrokerageAddReqDTO> list) {
         MemberPointConfigDO memberConfig = memberConfigService.getPointConfig();
         // 0 未启用分销功能
@@ -148,4 +153,56 @@ public class MemberBrokerageRecordServiceImpl implements MemberBrokerageRecordSe
         }
     }
 
+    @Override
+    public int unfreezeRecord() {
+        // 1. 查询待结算的佣金记录
+        List<MemberBrokerageRecordDO> records = memberBrokerageRecordMapper.selectListByStatusAndUnfreezeTimeLt(
+                BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus(), LocalDateTime.now());
+        if (CollUtil.isEmpty(records)) {
+            return 0;
+        }
+
+        // 2. 遍历执行
+        int count = 0;
+        for (MemberBrokerageRecordDO record : records) {
+            try {
+                boolean successful = getSelf().unfreezeRecord(record);
+                if (successful) {
+                    count++;
+                }
+            } catch (Exception e) {
+                log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId(), e);
+            }
+        }
+        return count;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public boolean unfreezeRecord(MemberBrokerageRecordDO record) {
+        // 更新记录状态
+        MemberBrokerageRecordDO updateObj = new MemberBrokerageRecordDO()
+                .setStatus(BrokerageRecordStatusEnum.SETTLEMENT.getStatus())
+                .setUnfreezeTime(LocalDateTime.now());
+        int updateRows = memberBrokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
+        if (updateRows == 0) {
+            log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId());
+            return false;
+        }
+
+        // 更新用户冻结佣金
+        memberUserService.updateUserFrozenBrokeragePrice(record.getUserId(), record.getPrice());
+
+        log.info("[unfreezeRecord][record({}) 更新为已结算成功]", record.getId());
+        return true;
+    }
+
+    /**
+     * 获得自身的代理对象,解决 AOP 生效问题
+     *
+     * @return 自己
+     */
+    private MemberBrokerageRecordServiceImpl getSelf() {
+        return SpringUtil.getBean(getClass());
+    }
+
 }

+ 2 - 2
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 {
     MemberUserDO getBrokerageUser(Long id);
 
     /**
-     * 增加用户佣金
+     * 更新用户佣金
      *
      * @param id             用户编号
      * @param brokeragePrice 用户可用佣金
@@ -184,7 +184,7 @@ public interface MemberUserService {
     void updateUserBrokeragePrice(Long id, int brokeragePrice);
 
     /**
-     * 增加用户佣金
+     * 更新用户冻结佣金
      *
      * @param id                   用户编号
      * @param frozenBrokeragePrice 用户冻结佣金

+ 8 - 1
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 {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateUserFrozenBrokeragePrice(Long id, int frozenBrokeragePrice) {
-        memberUserMapper.updateFrozenBrokeragePriceIncr(id, frozenBrokeragePrice);
+        if (frozenBrokeragePrice > 0) {
+            memberUserMapper.updateFrozenBrokeragePriceIncr(id, frozenBrokeragePrice);
+        } else if (frozenBrokeragePrice < 0) {
+            int updateRows = memberUserMapper.updateFrozenBrokeragePriceDecr(id, frozenBrokeragePrice);
+            if (updateRows == 0) {
+                throw exception(MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH);
+            }
+        }
     }
 
 }