code review:会员等级

This commit is contained in:
YunaiV
2023-08-24 00:53:09 +08:00
parent 0619989586
commit 9b6f5bd503
18 changed files with 63 additions and 181 deletions

View File

@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.api.level;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
/**
* 会员等级 API接口
* 会员等级 API 接口
*
* @author owen
*/
@ -17,5 +17,6 @@ public interface MemberLevelApi {
* @param bizType 业务类型 {@link MemberExperienceBizTypeEnum}
* @param bizId 业务编号
*/
void plusExperience(Long userId, Integer experience, Integer bizType, String bizId);
void addExperience(Long userId, Integer experience, Integer bizType, String bizId);
}

View File

@ -48,8 +48,6 @@ public interface ErrorCodeConstants {
ErrorCode LEVEL_EXPERIENCE_MAX = new ErrorCode(1004011004, "升级经验必须小于下一个等级[{}]设置的升级经验[{}]");
ErrorCode LEVEL_HAS_USER = new ErrorCode(1004011005, "用户等级下存在用户,无法删除");
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 ==========

View File

@ -11,18 +11,20 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum MemberExperienceBizTypeEnum {
/**
* 管理员调整、邀请新用户、下单、退单、签到、抽奖
*/
ADMIN(0, "管理员调整","管理员调整获得{}经验"),
INVITE_REGISTER(1, "邀新奖励","邀请好友获得{}经验"),
ORDER(2, "下单奖励", "下单获得{}经验"),
REFUND(3, "退单扣除","退单获得{}经验"),
SIGN_IN(4, "签到奖励","签到获得{}经验"),
LOTTERY(5, "抽奖奖励","抽奖获得{}经验"),
ADMIN(0, "管理员调整","管理员调整获得 {} 经验"),
INVITE_REGISTER(1, "邀新奖励","邀请好友获得 {} 经验"),
ORDER(2, "下单奖励", "下单获得 {} 经验"),
REFUND(3, "退单扣除","退单获得 {} 经验"),
SIGN_IN(4, "签到奖励","签到获得 {} 经验"),
LOTTERY(5, "抽奖奖励","抽奖获得 {} 经验"),
;
private final int value;
private final int type;
private final String title;
private final String desc;
private final String description;
}

View File

@ -24,12 +24,15 @@ public class MemberLevelApiImpl implements MemberLevelApi {
@Resource
private MemberLevelService memberLevelService;
public void plusExperience(Long userId, Integer experience, Integer bizType, String bizId) {
MemberExperienceBizTypeEnum bizTypeEnum = EnumUtil.getBy(MemberExperienceBizTypeEnum.class, e -> Objects.equals(bizType, e.getValue()));
@Override
public void addExperience(Long userId, Integer experience, Integer bizType, String bizId) {
// TODO @疯狂:可以在 MemberExperienceBizTypeEnum 增加一个方法,获得哈。
MemberExperienceBizTypeEnum bizTypeEnum = EnumUtil.getBy(MemberExperienceBizTypeEnum.class,
e -> Objects.equals(bizType, e.getType()));
if (bizTypeEnum == null) {
throw exception(EXPERIENCE_BIZ_NOT_SUPPORT);
}
memberLevelService.addExperience(userId, experience, bizTypeEnum, bizId);
}
}

View File

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

View File

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

View File

@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 会员等级分页 Request VO")
@Schema(description = "管理后台 - 会员等级列表筛选 Request VO")
@Data
@ToString(callSuper = true)
public class MemberLevelListReqVO {

View File

@ -25,10 +25,14 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 会员用户")
@RestController
@ -79,26 +83,19 @@ public class MemberUserController {
return success(PageResult.empty());
}
Set<Long> groupIds = new HashSet<>(pageResult.getList().size());
// 处理用户标签返显
Set<Long> tagIds = pageResult.getList().stream()
.peek(m -> {
if (m.getGroupId() != null) {
groupIds.add(m.getGroupId());
}
})
.map(MemberUserDO::getTagIds)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
List<MemberTagDO> tags = memberTagService.getTagList(tagIds);
// 处理用户级别返显
List<MemberLevelDO> levels = memberLevelService.getEnableLevelList();
List<MemberLevelDO> levels = memberLevelService.getLevelList(
convertSet(pageResult.getList(), MemberUserDO::getLevelId));
// 处理用户分组返显
List<MemberGroupDO> groups = memberGroupService.getGroupList(groupIds);
List<MemberGroupDO> groups = memberGroupService.getGroupList(
convertSet(pageResult.getList(), MemberUserDO::getGroupId));
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels, groups));
}

View File

@ -42,12 +42,10 @@ public interface MemberUserConvert {
List<MemberLevelDO> levels,
List<MemberGroupDO> groups) {
PageResult<MemberUserRespVO> result = convertPage(pageResult);
// 处理关联数据
Map<Long, String> tagMap = convertMap(tags, MemberTagDO::getId, MemberTagDO::getName);
Map<Long, String> levelMap = convertMap(levels, MemberLevelDO::getId, MemberLevelDO::getName);
Map<Long, String> groupMap = convertMap(groups, MemberGroupDO::getId, MemberGroupDO::getName);
// 填充关联数据
for (MemberUserRespVO vo : result.getList()) {
vo.setTagNames(convertList(vo.getTagIds(), tagMap::get));
@ -56,4 +54,5 @@ public interface MemberUserConvert {
}
return result;
}
}

View File

@ -69,6 +69,7 @@ public class MemberGroupServiceImpl implements MemberGroupService {
}
}
// TODO @疯狂:不要直接调用 memberUserMapper需要对方 service 提供方法
void validateGroupHasUser(Long id) {
Long count = memberUserMapper.selectCountByGroupId(id);
if (count > 0) {

View File

@ -26,7 +26,6 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord
@Resource
private MemberExperienceRecordMapper experienceLogMapper;
@Override
public MemberExperienceRecordDO getExperienceRecord(Long id) {
return experienceLogMapper.selectById(id);
@ -45,12 +44,11 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord
@Override
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);
String description = StrUtil.format(bizType.getDescription(), experience);
MemberExperienceRecordDO record = MemberExperienceRecordConvert.INSTANCE.convert(
userId, experience, totalExperience,
bizId, bizType.getType(), bizType.getTitle(), description);
experienceLogMapper.insert(record);
}
}

View File

@ -4,9 +4,6 @@ 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.MemberLevelRecordDO;
import java.util.Collection;
import java.util.List;
/**
* 会员等级记录 Service 接口
*
@ -22,14 +19,6 @@ public interface MemberLevelRecordService {
*/
MemberLevelRecordDO getLevelRecord(Long id);
/**
* 获得会员等级记录列表
*
* @param ids 编号
* @return 会员等级记录列表
*/
List<MemberLevelRecordDO> getLevelRecordList(Collection<Long> ids);
/**
* 获得会员等级记录分页
*
@ -44,4 +33,5 @@ public interface MemberLevelRecordService {
* @param levelRecord 会员等级记录
*/
void createLevelRecord(MemberLevelRecordDO levelRecord);
}

View File

@ -8,11 +8,6 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.LEVEL_LOG_NOT_EXISTS;
/**
* 会员等级记录 Service 实现类
@ -26,22 +21,11 @@ public class MemberLevelRecordServiceImpl implements MemberLevelRecordService {
@Resource
private MemberLevelRecordMapper levelLogMapper;
private void validateLevelLogExists(Long id) {
if (levelLogMapper.selectById(id) == null) {
throw exception(LEVEL_LOG_NOT_EXISTS);
}
}
@Override
public MemberLevelRecordDO getLevelRecord(Long id) {
return levelLogMapper.selectById(id);
}
@Override
public List<MemberLevelRecordDO> getLevelRecordList(Collection<Long> ids) {
return levelLogMapper.selectBatchIds(ids);
}
@Override
public PageResult<MemberLevelRecordDO> getLevelRecordPage(MemberLevelRecordPageReqVO pageReqVO) {
return levelLogMapper.selectPage(pageReqVO);

View File

@ -65,7 +65,6 @@ public interface MemberLevelService {
*/
List<MemberLevelDO> getLevelList(MemberLevelListReqVO listReqVO);
/**
* 获得指定状态的会员等级列表
*
@ -74,7 +73,6 @@ public interface MemberLevelService {
*/
List<MemberLevelDO> getLevelListByStatus(Integer status);
/**
* 获得开启状态的会员等级列表
*
@ -100,4 +98,5 @@ public interface MemberLevelService {
* @param bizId 业务编号
*/
void addExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId);
}

View File

@ -25,6 +25,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -153,11 +154,12 @@ public class MemberLevelServiceImpl implements MemberLevelService {
validateExperienceOutRange(list, id, level, experience);
}
// TODO 有 Service 提供接口哈,不直接调用对方的 memberUserMapper
@VisibleForTesting
void validateLevelHasUser(Long id) {
Long count = memberUserMapper.selectCountByLevelId(id);
if (count > 0) {
throw exception(GROUP_HAS_USER);
throw exception(LEVEL_HAS_USER);
}
}
@ -168,6 +170,9 @@ public class MemberLevelServiceImpl implements MemberLevelService {
@Override
public List<MemberLevelDO> getLevelList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return levelMapper.selectBatchIds(ids);
}
@ -184,7 +189,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updateUserLevel(MemberUserUpdateLevelReqVO updateReqVO) {
MemberUserDO user = memberUserMapper.selectById(updateReqVO.getId());
MemberUserDO user = memberUserService.getUser(updateReqVO.getId());
if (user == null) {
throw exception(USER_NOT_EXISTS);
}
@ -193,6 +198,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
return;
}
// 记录等级变动
MemberLevelRecordDO levelRecord = new MemberLevelRecordDO()
.setUserId(user.getId())
.setRemark(updateReqVO.getReason());
@ -211,17 +217,16 @@ public class MemberLevelServiceImpl implements MemberLevelService {
levelRecord.setUserExperience(memberLevel.getExperience());
levelRecord.setDescription("管理员调整为:" + memberLevel.getName());
}
// 记录等级变动
memberLevelRecordService.createLevelRecord(levelRecord);
// 记录会员经验变动
memberExperienceRecordService.createExperienceRecord(user.getId(),
levelRecord.getExperience(), levelRecord.getUserExperience(),
MemberExperienceBizTypeEnum.ADMIN, MemberExperienceBizTypeEnum.ADMIN.getValue() + "");
MemberExperienceBizTypeEnum.ADMIN, String.valueOf(MemberExperienceBizTypeEnum.ADMIN.getType()));
// 更新会员表上的等级编号、经验值
memberUserService.updateLevelIdAndExperience(user.getId(), updateReqVO.getLevelId(), levelRecord.getUserExperience());
memberUserService.updateUserLevel(user.getId(), updateReqVO.getLevelId(),
levelRecord.getUserExperience());
// 给会员发送等级变动消息
notifyMemberLevelChange(user.getId(), memberLevel);
@ -259,7 +264,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
}
// 更新会员表上的等级编号、经验值
memberUserService.updateLevelIdAndExperience(user.getId(), levelRecord.getLevelId(), userExperience);
memberUserService.updateUserLevel(user.getId(), levelRecord.getLevelId(), userExperience);
}
/**

View File

@ -133,5 +133,6 @@ public interface MemberUserService {
* @param levelId 用户等级
* @param experience 用户经验
*/
void updateLevelIdAndExperience(Long id, Long levelId, Integer experience);
void updateUserLevel(Long id, Long levelId, Integer experience);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.member.service.user;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
@ -229,11 +230,9 @@ public class MemberUserServiceImpl implements MemberUserService {
}
@Override
public void updateLevelIdAndExperience(Long id, Long levelId, Integer experience) {
if (levelId == null) {
// 0 代表无等级防止UpdateById时会被过滤掉的问题
levelId = 0L;
}
public void updateUserLevel(Long id, Long levelId, Integer experience) {
// 0 代表无等级防止UpdateById时会被过滤掉的问题
levelId = ObjectUtil.defaultIfNull(levelId, 0L);
memberUserMapper.updateById(new MemberUserDO()
.setId(id)
.setLevelId(levelId).setExperience(experience)