会员: 增加会员分组功能

plp
owen 2 years ago
parent de83531285
commit 8ae3401452

@ -0,0 +1,36 @@
create table member_group
(
id bigint auto_increment comment '' primary key,
name varchar(30) default '' not null comment '',
remark varchar(255) default '' not null comment '',
status tinyint default 0 not null comment '',
creator varchar(64) default '' null comment '',
create_time datetime default CURRENT_TIMESTAMP not null comment '',
updater varchar(64) default '' null comment '',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '',
deleted bit default b'0' not null comment '',
tenant_id bigint default 0 not null comment ''
)
comment '';
alter table member_user add column group_id bigint null comment '';
-- SQL
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
VALUES ('', '', 2, 5, 2262, 'group', '', 'member/group/index', 0, 'MemberGroup');
-- ID
-- MySQL OraclePostgreSQLSQLServer @parentId
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'member:group:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'member:group:create', 3, 2, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'member:group:update', 3, 3, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'member:group:delete', 3, 4, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'member:group:export', 3, 5, @parentId, '', '', '', 0);

@ -52,4 +52,9 @@ public interface ErrorCodeConstants {
ErrorCode LEVEL_LOG_NOT_EXISTS = new ErrorCode(1004007100, "会员等级记录不存在");
ErrorCode EXPERIENCE_LOG_NOT_EXISTS = new ErrorCode(1004007200, "会员经验记录不存在");
ErrorCode LEVEL_REASON_NOT_EXISTS = new ErrorCode(1004007300, "会员等级调整原因不能为空");
//========== 用户分组 1004011000 ==========
ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1004011000, "用户分组不存在");
ErrorCode GROUP_HAS_USER = new ErrorCode(1004011001, "用户分组下存在用户,无法删除");
}

@ -0,0 +1,91 @@
package cn.iocoder.yudao.module.member.controller.admin.group;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.*;
import cn.iocoder.yudao.module.member.convert.group.MemberGroupConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import cn.iocoder.yudao.module.member.service.group.MemberGroupService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 用户分组")
@RestController
@RequestMapping("/member/group")
@Validated
public class MemberGroupController {
@Resource
private MemberGroupService groupService;
@PostMapping("/create")
@Operation(summary = "创建用户分组")
@PreAuthorize("@ss.hasPermission('member:group:create')")
public CommonResult<Long> createGroup(@Valid @RequestBody MemberGroupCreateReqVO createReqVO) {
return success(groupService.createGroup(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新用户分组")
@PreAuthorize("@ss.hasPermission('member:group:update')")
public CommonResult<Boolean> updateGroup(@Valid @RequestBody MemberGroupUpdateReqVO updateReqVO) {
groupService.updateGroup(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户分组")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:group:delete')")
public CommonResult<Boolean> deleteGroup(@RequestParam("id") Long id) {
groupService.deleteGroup(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得用户分组")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:group:query')")
public CommonResult<MemberGroupRespVO> getGroup(@RequestParam("id") Long id) {
MemberGroupDO group = groupService.getGroup(id);
return success(MemberGroupConvert.INSTANCE.convert(group));
}
@GetMapping("/list")
@Operation(summary = "获得用户分组列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('member:group:query')")
public CommonResult<List<MemberGroupRespVO>> getGroupList(@RequestParam("ids") Collection<Long> ids) {
List<MemberGroupDO> list = groupService.getGroupList(ids);
return success(MemberGroupConvert.INSTANCE.convertList(list));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取会员分组精简信息列表", description = "只包含被开启的会员分组,主要用于前端的下拉选项")
public CommonResult<List<MemberGroupSimpleRespVO>> getSimpleGroupList() {
// 获用户列表,只要开启状态的
List<MemberGroupDO> list = groupService.getEnableGroupList();
return success(MemberGroupConvert.INSTANCE.convertSimpleList(list));
}
@GetMapping("/page")
@Operation(summary = "获得用户分组分页")
@PreAuthorize("@ss.hasPermission('member:group:query')")
public CommonResult<PageResult<MemberGroupRespVO>> getGroupPage(@Valid MemberGroupPageReqVO pageVO) {
PageResult<MemberGroupDO> pageResult = groupService.getGroupPage(pageVO);
return success(MemberGroupConvert.INSTANCE.convertPage(pageResult));
}
}

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* Base VO VO 使
* VO Swagger
*/
@Data
public class MemberGroupBaseVO {
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "购物达人")
@NotNull(message = "名称不能为空")
private String name;
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
private String remark;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
private Integer status;
}

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 用户分组创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MemberGroupCreateReqVO extends MemberGroupBaseVO {
}

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 用户分组分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MemberGroupPageReqVO extends PageParam {
@Schema(description = "名称", example = "购物达人")
private String name;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 用户分组 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MemberGroupRespVO extends MemberGroupBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20357")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 用户分组 Response VO")
@Data
@ToString(callSuper = true)
public class MemberGroupSimpleRespVO {
@Schema(description = "编号", example = "6103")
private Long id;
@Schema(description = "等级名称", example = "芋艿")
private String name;
}

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 用户分组更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MemberGroupUpdateReqVO extends MemberGroupBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20357")
@NotNull(message = "编号不能为空")
private Long id;
}

@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.member.controller.admin.level.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
@ -10,9 +9,8 @@ import lombok.ToString;
*/
@Schema(description = "管理后台 - 会员等级 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MemberLevelSimpleRespVO extends MemberLevelBaseVO {
public class MemberLevelSimpleRespVO {
@Schema(description = "编号", example = "6103")
private Long id;

@ -7,9 +7,11 @@ import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReq
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserRespVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
import cn.iocoder.yudao.module.member.dal.dataobject.tag.MemberTagDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.group.MemberGroupService;
import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
import cn.iocoder.yudao.module.member.service.tag.MemberTagService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
@ -22,10 +24,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -42,6 +41,8 @@ public class MemberUserController {
private MemberTagService memberTagService;
@Resource
private MemberLevelService memberLevelService;
@Resource
private MemberGroupService memberGroupService;
@PutMapping("/update")
@Operation(summary = "更新会员用户")
@ -69,18 +70,27 @@ 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<MemberGroupDO> groups = memberGroupService.getGroupList(groupIds);
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels));
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels, groups));
}
}

@ -56,4 +56,7 @@ public class MemberUserBaseVO {
@Schema(description = "会员等级编号", example = "1")
private Long levelId;
@Schema(description = "用户分组编号", example = "1")
private Long groupId;
}

@ -35,7 +35,10 @@ public class MemberUserPageReqVO extends PageParam {
@Schema(description = "会员标签编号列表", example = "[1, 2]")
private List<Long> tagIds;
@Schema(description = "会员等级号", example = "1")
@Schema(description = "会员等级号", example = "1")
private Long levelId;
@Schema(description = "用户分组编号", example = "1")
private Long groupId;
}

@ -38,4 +38,7 @@ public class MemberUserRespVO extends MemberUserBaseVO {
@Schema(description = "会员等级", example = "黄金会员")
private String levelName;
@Schema(description = "用户分组", example = "购物达人")
private String groupName;
}

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.member.convert.group;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupCreateReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupRespVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupSimpleRespVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupUpdateReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* Convert
*
* @author owen
*/
@Mapper
public interface MemberGroupConvert {
MemberGroupConvert INSTANCE = Mappers.getMapper(MemberGroupConvert.class);
MemberGroupDO convert(MemberGroupCreateReqVO bean);
MemberGroupDO convert(MemberGroupUpdateReqVO bean);
MemberGroupRespVO convert(MemberGroupDO bean);
List<MemberGroupRespVO> convertList(List<MemberGroupDO> list);
PageResult<MemberGroupRespVO> convertPage(PageResult<MemberGroupDO> page);
List<MemberGroupSimpleRespVO> convertSimpleList(List<MemberGroupDO> list);
}

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserRespVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserInfoRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
import cn.iocoder.yudao.module.member.dal.dataobject.tag.MemberTagDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
@ -38,17 +39,20 @@ public interface MemberUserConvert {
default PageResult<MemberUserRespVO> convertPage(PageResult<MemberUserDO> pageResult,
List<MemberTagDO> tags,
List<MemberLevelDO> levels) {
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));
vo.setLevelName(MapUtil.getStr(levelMap, vo.getLevelId(), StrUtil.EMPTY));
vo.setGroupName(MapUtil.getStr(groupMap, vo.getGroupId(), StrUtil.EMPTY));
}
return result;
}

@ -0,0 +1,45 @@
package cn.iocoder.yudao.module.member.dal.dataobject.group;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* DO
*
* @author owen
*/
@TableName("member_group")
@KeySequence("member_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberGroupDO extends BaseDO {
/**
*
*/
@TableId
private Long id;
/**
*
*/
private String name;
/**
*
*/
private String remark;
/**
*
* <p>
* {@link CommonStatusEnum}
*/
private Integer status;
}

@ -124,6 +124,10 @@ public class MemberUserDO extends TenantBaseDO {
*
*/
private Integer experience;
/**
*
*/
private Long groupId;
// TODO 积分等等
}

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.member.dal.mysql.group;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.group.vo.MemberGroupPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* Mapper
*
* @author owen
*/
@Mapper
public interface MemberGroupMapper extends BaseMapperX<MemberGroupDO> {
default PageResult<MemberGroupDO> selectPage(MemberGroupPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MemberGroupDO>()
.likeIfPresent(MemberGroupDO::getName, reqVO.getName())
.eqIfPresent(MemberGroupDO::getStatus, reqVO.getStatus())
.betweenIfPresent(MemberGroupDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MemberGroupDO::getId));
}
default List<MemberGroupDO> selectListByStatus(Integer status) {
return selectList(MemberGroupDO::getStatus, status);
}
}

@ -45,6 +45,7 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
.likeIfPresent(MemberUserDO::getNickname, reqVO.getNickname())
.betweenIfPresent(MemberUserDO::getCreateTime, reqVO.getCreateTime())
.eqIfPresent(MemberUserDO::getLevelId, reqVO.getLevelId())
.eqIfPresent(MemberUserDO::getGroupId, reqVO.getGroupId())
.apply(StrUtil.isNotEmpty(tagIdSql), tagIdSql)
.orderByDesc(MemberUserDO::getId));
}
@ -61,4 +62,8 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
.set(MemberUserDO::getExperience, 0)
.set(MemberUserDO::getLevelId, null));
}
default Long selectCountByGroupId(Long groupId) {
return selectCount(MemberUserDO::getGroupId, groupId);
}
}

@ -0,0 +1,86 @@
package cn.iocoder.yudao.module.member.service.group;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupCreateReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupUpdateReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author owen
*/
public interface MemberGroupService {
/**
*
*
* @param createReqVO
* @return
*/
Long createGroup(@Valid MemberGroupCreateReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateGroup(@Valid MemberGroupUpdateReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteGroup(Long id);
/**
*
*
* @param id
* @return
*/
MemberGroupDO getGroup(Long id);
/**
*
*
* @param ids
* @return
*/
List<MemberGroupDO> getGroupList(Collection<Long> ids);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<MemberGroupDO> getGroupPage(MemberGroupPageReqVO pageReqVO);
/**
*
*
* @param status
* @return
*/
List<MemberGroupDO> getGroupListByStatus(Integer status);
/**
*
*
* @return
*/
default List<MemberGroupDO> getEnableGroupList() {
return getGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
}
}

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.member.service.group;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupCreateReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupUpdateReqVO;
import cn.iocoder.yudao.module.member.convert.group.MemberGroupConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
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.GROUP_HAS_USER;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_NOT_EXISTS;
/**
* Service
*
* @author owen
*/
@Service
@Validated
public class MemberGroupServiceImpl implements MemberGroupService {
@Resource
private MemberGroupMapper groupMapper;
@Resource
private MemberUserMapper memberUserMapper;
@Override
public Long createGroup(MemberGroupCreateReqVO createReqVO) {
// 插入
MemberGroupDO group = MemberGroupConvert.INSTANCE.convert(createReqVO);
groupMapper.insert(group);
// 返回
return group.getId();
}
@Override
public void updateGroup(MemberGroupUpdateReqVO updateReqVO) {
// 校验存在
validateGroupExists(updateReqVO.getId());
// 更新
MemberGroupDO updateObj = MemberGroupConvert.INSTANCE.convert(updateReqVO);
groupMapper.updateById(updateObj);
}
@Override
public void deleteGroup(Long id) {
// 校验存在
validateGroupExists(id);
// 校验分组下是否有用户
validateGroupHasUser(id);
// 删除
groupMapper.deleteById(id);
}
void validateGroupExists(Long id) {
if (groupMapper.selectById(id) == null) {
throw exception(GROUP_NOT_EXISTS);
}
}
void validateGroupHasUser(Long id) {
Long count = memberUserMapper.selectCountByGroupId(id);
if (count > 0) {
throw exception(GROUP_HAS_USER);
}
}
@Override
public MemberGroupDO getGroup(Long id) {
return groupMapper.selectById(id);
}
@Override
public List<MemberGroupDO> getGroupList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return groupMapper.selectBatchIds(ids);
}
@Override
public PageResult<MemberGroupDO> getGroupPage(MemberGroupPageReqVO pageReqVO) {
return groupMapper.selectPage(pageReqVO);
}
@Override
public List<MemberGroupDO> getGroupListByStatus(Integer status) {
return groupMapper.selectListByStatus(status);
}
}

@ -0,0 +1,160 @@
package cn.iocoder.yudao.module.member.service.group;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupCreateReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupUpdateReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_HAS_USER;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_NOT_EXISTS;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link MemberGroupServiceImpl}
*
* @author owen
*/
@Import(MemberGroupServiceImpl.class)
public class MemberGroupServiceImplTest extends BaseDbUnitTest {
@Resource
private MemberGroupServiceImpl groupService;
@Resource
private MemberGroupMapper groupMapper;
@Resource
private MemberUserMapper memberUserMapper;
@Test
public void testCreateGroup_success() {
// 准备参数
MemberGroupCreateReqVO reqVO = randomPojo(MemberGroupCreateReqVO.class);
// 调用
Long groupId = groupService.createGroup(reqVO);
// 断言
assertNotNull(groupId);
// 校验记录的属性是否正确
MemberGroupDO group = groupMapper.selectById(groupId);
assertPojoEquals(reqVO, group);
}
@Test
public void testUpdateGroup_success() {
// mock 数据
MemberGroupDO dbGroup = randomPojo(MemberGroupDO.class);
groupMapper.insert(dbGroup);// @Sql: 先插入出一条存在的数据
// 准备参数
MemberGroupUpdateReqVO reqVO = randomPojo(MemberGroupUpdateReqVO.class, o -> {
o.setId(dbGroup.getId()); // 设置更新的 ID
});
// 调用
groupService.updateGroup(reqVO);
// 校验是否更新正确
MemberGroupDO group = groupMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, group);
}
@Test
public void testUpdateGroup_notExists() {
// 准备参数
MemberGroupUpdateReqVO reqVO = randomPojo(MemberGroupUpdateReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> groupService.updateGroup(reqVO), GROUP_NOT_EXISTS);
}
@Test
public void testDeleteGroup_success() {
// mock 数据
MemberGroupDO dbGroup = randomPojo(MemberGroupDO.class);
groupMapper.insert(dbGroup);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbGroup.getId();
// 调用
groupService.deleteGroup(id);
// 校验数据不存在了
assertNull(groupMapper.selectById(id));
}
@Test
public void testDeleteGroup_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> groupService.deleteGroup(id), GROUP_NOT_EXISTS);
}
@Test
public void testDeleteGroup_hasUser() {
// mock 数据
MemberGroupDO dbGroup = randomPojo(MemberGroupDO.class);
groupMapper.insert(dbGroup);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbGroup.getId();
// mock 会员数据
MemberUserDO dbUser = randomPojo(MemberUserDO.class, o -> {
o.setGroupId(id);
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
});
memberUserMapper.insert(dbUser);
// 调用, 并断言异常
assertServiceException(() -> groupService.deleteGroup(id), GROUP_HAS_USER);
}
@Test
public void testGetGroupPage() {
String name = randomString();
int status = CommonStatusEnum.ENABLE.getStatus();
// mock 数据
MemberGroupDO dbGroup = randomPojo(MemberGroupDO.class, o -> { // 等会查询到
o.setName(name);
o.setStatus(status);
o.setCreateTime(buildTime(2023, 2, 18));
});
groupMapper.insert(dbGroup);
// 测试 name 不匹配
groupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setName("")));
// 测试 status 不匹配
groupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 测试 createTime 不匹配
groupMapper.insert(cloneIgnoreId(dbGroup, o -> o.setCreateTime(null)));
// 准备参数
MemberGroupPageReqVO reqVO = new MemberGroupPageReqVO();
reqVO.setName(name);
reqVO.setStatus(status);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<MemberGroupDO> pageResult = groupService.getGroupPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbGroup, pageResult.getList().get(0));
}
}

@ -1,4 +1,5 @@
DELETE FROM "member_user";
DELETE FROM "member_address";
DELETE FROM "member_tag";
DELETE FROM "member_level";
DELETE FROM "member_level";
DELETE FROM "member_group";

@ -1,19 +1,30 @@
CREATE TABLE IF NOT EXISTS "member_user" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '',
"nickname" varchar(30) NOT NULL DEFAULT '' COMMENT '',
"avatar" varchar(255) NOT NULL DEFAULT '' COMMENT '',
"status" tinyint NOT NULL COMMENT '',
"mobile" varchar(11) NOT NULL COMMENT '',
"password" varchar(100) NOT NULL DEFAULT '' COMMENT '',
CREATE TABLE IF NOT EXISTS "member_user"
(
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '',
"nickname" varchar(30) NOT NULL DEFAULT '' COMMENT '',
"name" varchar(30) NULL COMMENT '',
sex tinyint null comment '',
birthday datetime null comment '',
area_id int null comment '',
mark varchar(255) null comment '',
point int default 0 null comment '',
"avatar" varchar(255) NOT NULL DEFAULT '' COMMENT '',
"status" tinyint NOT NULL COMMENT '',
"mobile" varchar(11) NOT NULL COMMENT '',
"password" varchar(100) NOT NULL DEFAULT '' COMMENT '',
"register_ip" varchar(32) NOT NULL COMMENT ' IP',
"login_ip" varchar(50) NULL DEFAULT '' COMMENT 'IP',
"login_date" datetime NULL DEFAULT NULL COMMENT '',
"creator" varchar(64) NULL DEFAULT '' COMMENT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
"updater" varchar(64) NULL DEFAULT '' COMMENT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
"deleted" bit(1) NOT NULL DEFAULT '0' COMMENT '',
"tenant_id" bigint not null default '0',
"login_ip" varchar(50) NULL DEFAULT '' COMMENT 'IP',
"login_date" datetime NULL DEFAULT NULL COMMENT '',
"tag_ids" varchar(255) NULL DEFAULT NULL COMMENT ',',
"level_id" bigint NULL DEFAULT NULL COMMENT '',
"experience" bigint NULL DEFAULT NULL COMMENT '',
"group_id" bigint NULL DEFAULT NULL COMMENT '',
"creator" varchar(64) NULL DEFAULT '' COMMENT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
"updater" varchar(64) NULL DEFAULT '' COMMENT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
"deleted" bit(1) NOT NULL DEFAULT '0' COMMENT '',
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '';
@ -63,4 +74,19 @@ CREATE TABLE IF NOT EXISTS "member_level"
"tenant_id" bigint not null default '0',
"status" int NOT NULL,
PRIMARY KEY ("id")
) COMMENT '';
) COMMENT '';
CREATE TABLE IF NOT EXISTS "member_group"
(
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar NOT NULL,
"remark" varchar NOT NULL,
"status" varchar NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '';
Loading…
Cancel
Save