Kaynağa Gözat

会员: 重构会员等级逻辑

owen 1 yıl önce
ebeveyn
işleme
dc382d80bb
17 değiştirilmiş dosya ile 130 ekleme ve 205 silme
  1. 2 2
      yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java
  2. 1 0
      yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
  3. 12 2
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java
  4. 2 2
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberExperienceRecordController.java
  5. 2 2
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java
  6. 3 0
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java
  7. 10 0
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java
  8. 0 1
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/level/MemberLevelRecordDO.java
  9. 0 14
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MemberUserMapper.java
  10. 5 23
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java
  11. 12 20
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java
  12. 6 44
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java
  13. 5 59
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java
  14. 1 1
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelService.java
  15. 49 35
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java
  16. 8 0
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java
  17. 12 0
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java

+ 2 - 2
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java

@@ -14,8 +14,8 @@ public interface MemberLevelApi {
      *
      * @param userId     会员ID
      * @param experience 经验
-     * @param bizType    业务类型
+     * @param bizType    业务类型 {@link MemberExperienceBizTypeEnum}
      * @param bizId      业务编号
      */
-    void plusExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId);
+    void plusExperience(Long userId, Integer experience, Integer bizType, String bizId);
 }

+ 1 - 0
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java

@@ -50,6 +50,7 @@ public interface ErrorCodeConstants {
 
     ErrorCode LEVEL_LOG_NOT_EXISTS = new ErrorCode(1004011100, "用户等级记录不存在");
     ErrorCode EXPERIENCE_LOG_NOT_EXISTS = new ErrorCode(1004011200, "用户经验记录不存在");
+    ErrorCode EXPERIENCE_BIZ_NOT_SUPPORT = new ErrorCode(1004011201, "用户经验业务类型不支持");
 
     //========== 用户分组 1004012000 ==========
     ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1004012000, "用户分组不存在");

+ 12 - 2
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java

@@ -1,11 +1,16 @@
 package cn.iocoder.yudao.module.member.api.level;
 
+import cn.hutool.core.util.EnumUtil;
 import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
 import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.util.Objects;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.EXPERIENCE_BIZ_NOT_SUPPORT;
 
 /**
  * 会员等级 API 实现类
@@ -19,7 +24,12 @@ public class MemberLevelApiImpl implements MemberLevelApi {
     @Resource
     private MemberLevelService memberLevelService;
 
-    public void plusExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId) {
-        memberLevelService.plusExperience(userId, experience, bizType, bizId);
+    public void plusExperience(Long userId, Integer experience, Integer bizType, String bizId) {
+        MemberExperienceBizTypeEnum bizTypeEnum = EnumUtil.getBy(MemberExperienceBizTypeEnum.class, e -> Objects.equals(bizType, e.getValue()));
+        if (bizTypeEnum == null) {
+            throw exception(EXPERIENCE_BIZ_NOT_SUPPORT);
+        }
+
+        memberLevelService.addExperience(userId, experience, bizTypeEnum, bizId);
     }
 }

+ 2 - 2
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberExperienceRecordController.java

@@ -36,7 +36,7 @@ public class MemberExperienceRecordController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('member:experience-record:query')")
     public CommonResult<MemberExperienceRecordRespVO> getExperienceLog(@RequestParam("id") Long id) {
-        MemberExperienceRecordDO experienceLog = experienceLogService.getExperienceLog(id);
+        MemberExperienceRecordDO experienceLog = experienceLogService.getExperienceRecord(id);
         return success(MemberExperienceRecordConvert.INSTANCE.convert(experienceLog));
     }
 
@@ -44,7 +44,7 @@ public class MemberExperienceRecordController {
     @Operation(summary = "获得会员经验记录分页")
     @PreAuthorize("@ss.hasPermission('member:experience-record:query')")
     public CommonResult<PageResult<MemberExperienceRecordRespVO>> getExperienceLogPage(@Valid MemberExperienceRecordPageReqVO pageVO) {
-        PageResult<MemberExperienceRecordDO> pageResult = experienceLogService.getExperienceLogPage(pageVO);
+        PageResult<MemberExperienceRecordDO> pageResult = experienceLogService.getExperienceRecordPage(pageVO);
         return success(MemberExperienceRecordConvert.INSTANCE.convertPage(pageResult));
     }
 

+ 2 - 2
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java

@@ -36,7 +36,7 @@ public class MemberLevelRecordController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('member:level-record:query')")
     public CommonResult<MemberLevelRecordRespVO> getLevelLog(@RequestParam("id") Long id) {
-        MemberLevelRecordDO levelLog = levelLogService.getLevelLog(id);
+        MemberLevelRecordDO levelLog = levelLogService.getLevelRecord(id);
         return success(MemberLevelRecordConvert.INSTANCE.convert(levelLog));
     }
 
@@ -44,7 +44,7 @@ public class MemberLevelRecordController {
     @Operation(summary = "获得会员等级记录分页")
     @PreAuthorize("@ss.hasPermission('member:level-record:query')")
     public CommonResult<PageResult<MemberLevelRecordRespVO>> getLevelLogPage(@Valid MemberLevelRecordPageReqVO pageVO) {
-        PageResult<MemberLevelRecordDO> pageResult = levelLogService.getLevelLogPage(pageVO);
+        PageResult<MemberLevelRecordDO> pageResult = levelLogService.getLevelRecordPage(pageVO);
         return success(MemberLevelRecordConvert.INSTANCE.convertPage(pageResult));
     }
 }

+ 3 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java

@@ -24,4 +24,7 @@ public interface MemberExperienceRecordConvert {
 
     PageResult<MemberExperienceRecordRespVO> convertPage(PageResult<MemberExperienceRecordDO> page);
 
+    MemberExperienceRecordDO convert(Long userId, Integer experience, Integer totalExperience,
+                                     String bizId, Integer bizType,
+                                     String title, String description);
 }

+ 10 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.convert.level;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordRespVO;
+import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
@@ -24,4 +25,13 @@ public interface MemberLevelRecordConvert {
 
     PageResult<MemberLevelRecordRespVO> convertPage(PageResult<MemberLevelRecordDO> page);
 
+    default MemberLevelRecordDO copyTo(MemberLevelDO from, MemberLevelRecordDO to) {
+        if (from != null) {
+            to.setLevelId(from.getId());
+            to.setLevel(from.getLevel());
+            to.setDiscount(from.getDiscount());
+            to.setExperience(from.getExperience());
+        }
+        return to;
+    }
 }

+ 0 - 1
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/level/MemberLevelRecordDO.java

@@ -52,7 +52,6 @@ public class MemberLevelRecordDO extends BaseDO {
      * 会员此时的经验
      */
     private Integer userExperience;
-    // TODO @疯狂:是不是 remark 和 description 可以合并成 description 就够了
     /**
      * 备注
      */

+ 0 - 14
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MemberUserMapper.java

@@ -7,7 +7,6 @@ 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.user.vo.MemberUserPageReqVO;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
@@ -50,19 +49,6 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
                 .orderByDesc(MemberUserDO::getId));
     }
 
-    /**
-     * 取消会员的等级
-     *
-     * @param userId 会员编号
-     * @return 受影响的行数
-     */
-    default int updateUserLevelToNull(Long userId) {
-        return update(null, new LambdaUpdateWrapper<MemberUserDO>()
-                .eq(MemberUserDO::getId, userId)
-                .set(MemberUserDO::getExperience, 0)
-                .set(MemberUserDO::getLevelId, null));
-    }
-
     default Long selectCountByGroupId(Long groupId) {
         return selectCount(MemberUserDO::getGroupId, groupId);
     }

+ 5 - 23
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java

@@ -21,7 +21,7 @@ public interface MemberExperienceRecordService {
      * @param id 编号
      * @return 会员经验记录
      */
-    MemberExperienceRecordDO getExperienceLog(Long id);
+    MemberExperienceRecordDO getExperienceRecord(Long id);
 
     /**
      * 获得会员经验记录列表
@@ -29,7 +29,7 @@ public interface MemberExperienceRecordService {
      * @param ids 编号
      * @return 会员经验记录列表
      */
-    List<MemberExperienceRecordDO> getExperienceLogList(Collection<Long> ids);
+    List<MemberExperienceRecordDO> getExperienceRecordList(Collection<Long> ids);
 
     /**
      * 获得会员经验记录分页
@@ -37,26 +37,7 @@ public interface MemberExperienceRecordService {
      * @param pageReqVO 分页查询
      * @return 会员经验记录分页
      */
-    PageResult<MemberExperienceRecordDO> getExperienceLogPage(MemberExperienceRecordPageReqVO pageReqVO);
-
-    /**
-     * 获得会员经验记录列表, 用于 Excel 导出
-     *
-     * @param exportReqVO 查询条件
-     * @return 会员经验记录列表
-     */
-    List<MemberExperienceLogDO> getExperienceLogList(MemberExperienceLogExportReqVO exportReqVO);
-
-    // TODO @疯狂:类似 MemberLevelLogService 的方法,这里也需要提供一个通用的方法,用于创建经验变动记录
-
-    /**
-     * 创建 手动调整 经验变动记录
-     *
-     * @param userId          会员编号
-     * @param experience      变动经验值
-     * @param totalExperience 会员当前的经验
-     */
-    void createAdjustLog(Long userId, int experience, int totalExperience);
+    PageResult<MemberExperienceRecordDO> getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO);
 
     /**
      * 根据业务类型, 创建 经验变动记录
@@ -67,5 +48,6 @@ public interface MemberExperienceRecordService {
      * @param bizType         业务类型
      * @param bizId           业务ID
      */
-    void createBizLog(Long userId, int experience, int totalExperience, MemberExperienceBizTypeEnum bizType, String bizId);
+    void createExperienceRecord(Long userId, Integer experience, Integer totalExperience,
+                                MemberExperienceBizTypeEnum bizType, String bizId);
 }

+ 12 - 20
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.level;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO;
+import cn.iocoder.yudao.module.member.convert.level.MemberExperienceRecordConvert;
 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO;
 import cn.iocoder.yudao.module.member.dal.mysql.level.MemberExperienceRecordMapper;
 import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
@@ -27,38 +28,29 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord
 
 
     @Override
-    public MemberExperienceRecordDO getExperienceLog(Long id) {
+    public MemberExperienceRecordDO getExperienceRecord(Long id) {
         return experienceLogMapper.selectById(id);
     }
 
     @Override
-    public List<MemberExperienceRecordDO> getExperienceLogList(Collection<Long> ids) {
+    public List<MemberExperienceRecordDO> getExperienceRecordList(Collection<Long> ids) {
         return experienceLogMapper.selectBatchIds(ids);
     }
 
     @Override
-    public PageResult<MemberExperienceRecordDO> getExperienceLogPage(MemberExperienceRecordPageReqVO pageReqVO) {
+    public PageResult<MemberExperienceRecordDO> getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO) {
         return experienceLogMapper.selectPage(pageReqVO);
     }
 
     @Override
-    public void createAdjustLog(Long userId, int experience, int totalExperience) {
-        // 管理员调整时, 没有业务编号, 记录对应的枚举值
-        String bizId = MemberExperienceBizTypeEnum.ADMIN.getValue() + "";
-        this.createBizLog(userId, experience, totalExperience, MemberExperienceBizTypeEnum.ADMIN, bizId);
-    }
-
-    @Override
-    public void createBizLog(Long userId, int experience, int totalExperience, MemberExperienceBizTypeEnum bizType, String bizId) {
-        MemberExperienceRecordDO experienceLogDO = new MemberExperienceRecordDO();
-        experienceLogDO.setUserId(userId);
-        experienceLogDO.setExperience(experience);
-        experienceLogDO.setTotalExperience(totalExperience);
-        experienceLogDO.setBizId(bizId);
-        experienceLogDO.setBizType(bizType.getValue());
-        experienceLogDO.setTitle(bizType.getTitle());
-        experienceLogDO.setDescription(StrUtil.format(bizType.getDesc(), experience));
-        experienceLogMapper.insert(experienceLogDO);
+    public void createExperienceRecord(Long userId, Integer experience, Integer totalExperience,
+                                       MemberExperienceBizTypeEnum bizType, String bizId) {
+        String description = StrUtil.format(bizType.getDesc(), experience);
+        MemberExperienceRecordDO recordDO = MemberExperienceRecordConvert.INSTANCE.convert(userId,
+                experience, totalExperience,
+                bizId, bizType.getValue(), bizType.getTitle(),
+                description);
+        experienceLogMapper.insert(recordDO);
     }
 
 }

+ 6 - 44
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java

@@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.member.service.level;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO;
-import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO;
-import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 
 import java.util.Collection;
 import java.util.List;
@@ -16,20 +14,13 @@ import java.util.List;
  */
 public interface MemberLevelRecordService {
 
-    /**
-     * 删除会员等级记录
-     *
-     * @param id 编号
-     */
-    void deleteLevelLog(Long id);
-
     /**
      * 获得会员等级记录
      *
      * @param id 编号
      * @return 会员等级记录
      */
-    MemberLevelRecordDO getLevelLog(Long id);
+    MemberLevelRecordDO getLevelRecord(Long id);
 
     /**
      * 获得会员等级记录列表
@@ -37,7 +28,7 @@ public interface MemberLevelRecordService {
      * @param ids 编号
      * @return 会员等级记录列表
      */
-    List<MemberLevelRecordDO> getLevelLogList(Collection<Long> ids);
+    List<MemberLevelRecordDO> getLevelRecordList(Collection<Long> ids);
 
     /**
      * 获得会员等级记录分页
@@ -45,41 +36,12 @@ public interface MemberLevelRecordService {
      * @param pageReqVO 分页查询
      * @return 会员等级记录分页
      */
-    PageResult<MemberLevelRecordDO> getLevelLogPage(MemberLevelRecordPageReqVO pageReqVO);
-
-    /**
-     * 获得会员等级记录列表, 用于 Excel 导出
-     *
-     * @param exportReqVO 查询条件
-     * @return 会员等级记录列表
-     */
-    List<MemberLevelLogDO> getLevelLogList(MemberLevelLogExportReqVO exportReqVO);
-
-    // TODO @疯狂:把 createCancelLog、createAdjustLog、createAutoUpgradeLog 几个日志合并成一个通用的日志方法;整体的内容,交给 MemberLevelService 去做;以及对应的 level 变化的通知;
-
-    /**
-     * 创建记录: 取消等级
-     *
-     * @param userId 会员编号
-     * @param reason 调整原因
-     */
-    void createCancelLog(Long userId, String reason);
-
-    /**
-     * 创建记录: 手动调整
-     *
-     * @param user       会员
-     * @param level      等级
-     * @param experience 变动经验值
-     * @param reason     调整原因
-     */
-    void createAdjustLog(MemberUserDO user, MemberLevelDO level, int experience, String reason);
+    PageResult<MemberLevelRecordDO> getLevelRecordPage(MemberLevelRecordPageReqVO pageReqVO);
 
     /**
-     * 创建记录: 自动升级
+     * 创建会员等级记录
      *
-     * @param user  会员
-     * @param level 等级
+     * @param levelRecord 会员等级记录
      */
-    void createAutoUpgradeLog(MemberUserDO user, MemberLevelDO level);
+    void createLevelRecord(MemberLevelRecordDO levelRecord);
 }

+ 5 - 59
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java

@@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.member.service.level;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO;
-import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO;
-import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelRecordMapper;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -28,14 +26,6 @@ public class MemberLevelRecordServiceImpl implements MemberLevelRecordService {
     @Resource
     private MemberLevelRecordMapper levelLogMapper;
 
-    @Override
-    public void deleteLevelLog(Long id) {
-        // 校验存在
-        validateLevelLogExists(id);
-        // 删除
-        levelLogMapper.deleteById(id);
-    }
-
     private void validateLevelLogExists(Long id) {
         if (levelLogMapper.selectById(id) == null) {
             throw exception(LEVEL_LOG_NOT_EXISTS);
@@ -43,67 +33,23 @@ public class MemberLevelRecordServiceImpl implements MemberLevelRecordService {
     }
 
     @Override
-    public MemberLevelRecordDO getLevelLog(Long id) {
+    public MemberLevelRecordDO getLevelRecord(Long id) {
         return levelLogMapper.selectById(id);
     }
 
     @Override
-    public List<MemberLevelRecordDO> getLevelLogList(Collection<Long> ids) {
+    public List<MemberLevelRecordDO> getLevelRecordList(Collection<Long> ids) {
         return levelLogMapper.selectBatchIds(ids);
     }
 
     @Override
-    public PageResult<MemberLevelRecordDO> getLevelLogPage(MemberLevelRecordPageReqVO pageReqVO) {
+    public PageResult<MemberLevelRecordDO> getLevelRecordPage(MemberLevelRecordPageReqVO pageReqVO) {
         return levelLogMapper.selectPage(pageReqVO);
     }
 
     @Override
-    public void createCancelLog(Long userId, String reason) {
-        MemberLevelRecordDO levelLogDO = new MemberLevelRecordDO();
-        levelLogDO.setUserId(userId);
-        levelLogDO.setRemark(reason);
-        levelLogDO.setDescription("管理员取消");
-        levelLogMapper.insert(levelLogDO);
-
-        // 给会员发送等级变动消息
-        notifyMember(userId, levelLogDO);
-    }
-
-    @Override
-    public void createAdjustLog(MemberUserDO user, MemberLevelDO level, int experience, String reason) {
-        MemberLevelRecordDO levelLogDO = new MemberLevelRecordDO();
-        levelLogDO.setUserId(user.getId());
-        levelLogDO.setLevelId(level.getId());
-        levelLogDO.setLevel(level.getLevel());
-        levelLogDO.setDiscount(level.getDiscount());
-        levelLogDO.setUserExperience(level.getExperience());
-        levelLogDO.setExperience(experience);
-        levelLogDO.setRemark(reason);
-        levelLogDO.setDescription("管理员调整为:" + level.getName());
-        levelLogMapper.insert(levelLogDO);
-
-        // 给会员发送等级变动消息
-        notifyMember(user.getId(), levelLogDO);
-    }
-
-    @Override
-    public void createAutoUpgradeLog(MemberUserDO user, MemberLevelDO level) {
-        MemberLevelRecordDO levelLogDO = new MemberLevelRecordDO();
-        levelLogDO.setUserId(user.getId());
-        levelLogDO.setLevelId(level.getId());
-        levelLogDO.setLevel(level.getLevel());
-        levelLogDO.setDiscount(level.getDiscount());
-        levelLogDO.setExperience(level.getExperience());
-        levelLogDO.setUserExperience(user.getExperience());
-        levelLogDO.setDescription("成为:" + level.getName());
-        levelLogMapper.insert(levelLogDO);
-
-        // 给会员发送等级变动消息
-        notifyMember(user.getId(), levelLogDO);
-    }
-
-    private void notifyMember(Long userId, MemberLevelRecordDO level) {
-        //todo: 给会员发消息
+    public void createLevelRecord(MemberLevelRecordDO levelRecord) {
+        levelLogMapper.insert(levelRecord);
     }
 
 }

+ 1 - 1
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelService.java

@@ -100,5 +100,5 @@ public interface MemberLevelService {
      * @param bizType    业务类型
      * @param bizId      业务编号
      */
-    void plusExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId);
+    void addExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId);
 }

+ 49 - 35
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java

@@ -10,11 +10,14 @@ import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLeve
 import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelUpdateReqVO;
 import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateLevelReqVO;
 import cn.iocoder.yudao.module.member.convert.level.MemberLevelConvert;
+import cn.iocoder.yudao.module.member.convert.level.MemberLevelRecordConvert;
 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
+import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelMapper;
 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
 import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
+import cn.iocoder.yudao.module.member.service.user.MemberUserService;
 import com.google.common.annotations.VisibleForTesting;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -47,6 +50,8 @@ public class MemberLevelServiceImpl implements MemberLevelService {
     private MemberExperienceRecordService memberExperienceRecordService;
     @Resource
     private MemberUserMapper memberUserMapper;
+    @Resource
+    private MemberUserService memberUserService;
 
     @Override
     public Long createLevel(MemberLevelCreateReqVO createReqVO) {
@@ -189,68 +194,73 @@ public class MemberLevelServiceImpl implements MemberLevelService {
             return;
         }
 
-        int experience;
-        int totalExperience = 0;
-        // 记录等级变动
+        MemberLevelRecordDO levelRecord = new MemberLevelRecordDO()
+                .setUserId(user.getId())
+                .setRemark(updateReqVO.getReason());
+        MemberLevelDO memberLevel = null;
         if (updateReqVO.getLevelId() == null) {
             // 取消用户等级时,为扣减经验
-            experience = -user.getExperience();
-
-            // 取消了会员的等级
-            memberLevelRecordService.createCancelLog(user.getId(), updateReqVO.getReason());
-            memberUserMapper.updateUserLevelToNull(user.getId());
+            levelRecord.setExperience(-user.getExperience());
+            levelRecord.setDescription("管理员取消了等级");
         } else {
-            MemberLevelDO level = validateLevelExists(updateReqVO.getLevelId());
+            memberLevel = validateLevelExists(updateReqVO.getLevelId());
+            // 复制等级配置
+            MemberLevelRecordConvert.INSTANCE.copyTo(memberLevel, levelRecord);
             // 变动经验值 = 等级的升级经验 - 会员当前的经验;正数为增加经验,负数为扣减经验
-            experience = level.getExperience() - user.getExperience();
+            levelRecord.setExperience(memberLevel.getExperience() - user.getExperience());
             // 会员当前的经验 = 等级的升级经验
-            totalExperience = level.getExperience();
-
-            memberLevelRecordService.createAdjustLog(user, level, experience, updateReqVO.getReason());
-
-            // 更新会员表上的等级编号、经验值
-            updateUserLevelIdAndExperience(user.getId(), updateReqVO.getLevelId(), totalExperience);
+            levelRecord.setUserExperience(memberLevel.getExperience());
+            levelRecord.setDescription("管理员调整为:" + memberLevel.getName());
         }
 
+        // 记录等级变动
+        memberLevelRecordService.createLevelRecord(levelRecord);
+
         // 记录会员经验变动
-        memberExperienceRecordService.createAdjustLog(user.getId(), experience, totalExperience);
+        memberExperienceRecordService.createExperienceRecord(user.getId(),
+                levelRecord.getExperience(), levelRecord.getUserExperience(),
+                MemberExperienceBizTypeEnum.ADMIN, MemberExperienceBizTypeEnum.ADMIN.getValue() + "");
+
+        // 更新会员表上的等级编号、经验值
+        memberUserService.updateLevelIdAndExperience(user.getId(), updateReqVO.getLevelId(), levelRecord.getUserExperience());
+
+        // 给会员发送等级变动消息
+        notifyMemberLevelChange(user.getId(), memberLevel);
     }
 
-    // TODO @疯狂:方法名,建议改成 increase 或者 add 经验,和项目更统一一些
-    // TODO @疯狂:bizType 改成具体数值,主要是枚举在 api 不好传递,rpc 情况下
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void plusExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId) {
+    public void addExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId) {
         if (experience == 0) {
             return;
         }
 
         MemberUserDO user = memberUserMapper.selectById(userId);
 
-        // 防止扣出负数
         int userExperience = NumberUtil.max(user.getExperience() + experience, 0);
+        MemberLevelRecordDO levelRecord = new MemberLevelRecordDO()
+                .setUserId(user.getId())
+                .setExperience(experience)
+                // 防止扣出负数
+                .setUserExperience(userExperience);
+
         // 创建经验记录
-        memberExperienceRecordService.createBizLog(userId, experience, userExperience, bizType, bizId);
+        memberExperienceRecordService.createExperienceRecord(userId, experience, userExperience,
+                bizType, bizId);
 
         // 计算会员等级
         MemberLevelDO newLevel = calculateNewLevel(user, userExperience);
-        Long newLevelId = null;
         if (newLevel != null) {
-            newLevelId = newLevel.getId();
+            // 复制等级配置
+            MemberLevelRecordConvert.INSTANCE.copyTo(newLevel, levelRecord);
             // 保存等级变更记录
-            memberLevelRecordService.createAutoUpgradeLog(user, newLevel);
+            memberLevelRecordService.createLevelRecord(levelRecord);
+            // 给会员发送等级变动消息
+            notifyMemberLevelChange(userId, newLevel);
         }
 
         // 更新会员表上的等级编号、经验值
-        updateUserLevelIdAndExperience(user.getId(), newLevelId, userExperience);
-    }
-
-    // TODO @疯狂:让 memberUserService 那开个方法;每个模块,不直接操作对方的 mapper;
-    private void updateUserLevelIdAndExperience(Long userId, Long levelId, Integer experience) {
-        memberUserMapper.updateById(new MemberUserDO()
-                .setId(userId)
-                .setLevelId(levelId).setExperience(experience)
-        );
+        memberUserService.updateLevelIdAndExperience(user.getId(), levelRecord.getLevelId(), userExperience);
     }
 
     /**
@@ -258,7 +268,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
      *
      * @param user           会员
      * @param userExperience 会员当前的经验值
-     * @return 会员等级编号,null表示无变化
+     * @return 会员新的等级,null表示无变化
      */
     private MemberLevelDO calculateNewLevel(MemberUserDO user, int userExperience) {
         List<MemberLevelDO> list = getEnableLevelList();
@@ -283,4 +293,8 @@ public class MemberLevelServiceImpl implements MemberLevelService {
 
         return matchLevel;
     }
+
+    private void notifyMemberLevelChange(Long userId, MemberLevelDO level) {
+        //todo: 给会员发消息
+    }
 }

+ 8 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java

@@ -126,4 +126,12 @@ public interface MemberUserService {
      */
     PageResult<MemberUserDO> getUserPage(MemberUserPageReqVO pageReqVO);
 
+    /**
+     * 更新用户的等级和经验
+     *
+     * @param id         用户编号
+     * @param levelId    用户等级
+     * @param experience 用户经验
+     */
+    void updateLevelIdAndExperience(Long id, Long levelId, Integer experience);
 }

+ 12 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java

@@ -228,4 +228,16 @@ public class MemberUserServiceImpl implements MemberUserService {
         return memberUserMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public void updateLevelIdAndExperience(Long id, Long levelId, Integer experience) {
+        if (levelId == null) {
+            // 0 代表无等级:防止UpdateById时,会被过滤掉的问题
+            levelId = 0L;
+        }
+        memberUserMapper.updateById(new MemberUserDO()
+                .setId(id)
+                .setLevelId(levelId).setExperience(experience)
+        );
+    }
+
 }