!580 会员: 增加会员分组功能

Merge pull request !580 from 疯狂的世界/member_dev
plp
芋道源码 2 years ago committed by Gitee
commit 883bdc65a1
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F

@ -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);

@ -24,9 +24,10 @@ public interface ErrorCodeConstants {
// ========== 用户收件地址 1004004000 ==========
ErrorCode ADDRESS_NOT_EXISTS = new ErrorCode(1004004000, "用户收件地址不存在");
//========== 会员标签 1004006000 ==========
ErrorCode TAG_NOT_EXISTS = new ErrorCode(1004006000, "会员标签不存在");
ErrorCode TAG_NAME_EXISTS = new ErrorCode(1004006001, "会员标签已经存在");
//========== 用户标签 1004006000 ==========
ErrorCode TAG_NOT_EXISTS = new ErrorCode(1004006000, "用户标签不存在");
ErrorCode TAG_NAME_EXISTS = new ErrorCode(1004006001, "用户标签已经存在");
ErrorCode TAG_HAS_USER = new ErrorCode(1004006002, "用户标签下存在用户,无法删除");
//========== 积分配置 1004007000 ==========
@ -39,14 +40,20 @@ public interface ErrorCodeConstants {
//========== 签到配置 1004010000 ==========
//========== 会员等级 1004007000 ==========
ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1004007000, "会员等级不存在");
ErrorCode LEVEL_NAME_EXISTS = new ErrorCode(1004007001, "会员等级名称[{}]已被使用");
ErrorCode LEVEL_VALUE_EXISTS = new ErrorCode(1004007002, "会员等级值[{}]已被[{}]使用");
ErrorCode LEVEL_EXPERIENCE_MIN = new ErrorCode(1004007003, "升级经验必须大于上一个等级[{}]设置的升级经验[{}]");
ErrorCode LEVEL_EXPERIENCE_MAX = new ErrorCode(1004007004, "升级经验必须小于下一个等级[{}]设置的升级经验[{}]");
//========== 用户等级 1004011000 ==========
ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1004011000, "用户等级不存在");
ErrorCode LEVEL_NAME_EXISTS = new ErrorCode(1004011001, "用户等级名称[{}]已被使用");
ErrorCode LEVEL_VALUE_EXISTS = new ErrorCode(1004011002, "用户等级值[{}]已被[{}]使用");
ErrorCode LEVEL_EXPERIENCE_MIN = new ErrorCode(1004011003, "升级经验必须大于上一个等级[{}]设置的升级经验[{}]");
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 LEVEL_REASON_NOT_EXISTS = new ErrorCode(1004011300, "用户等级调整原因不能为空");
//========== 用户分组 1004012000 ==========
ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1004012000, "用户分组不存在");
ErrorCode GROUP_HAS_USER = new ErrorCode(1004012001, "用户分组下存在用户,无法删除");
ErrorCode LEVEL_LOG_NOT_EXISTS = new ErrorCode(1004007100, "会员等级记录不存在");
ErrorCode EXPERIENCE_LOG_NOT_EXISTS = new ErrorCode(1004007200, "会员经验记录不存在");
ErrorCode LEVEL_REASON_NOT_EXISTS = new ErrorCode(1004007300, "会员等级调整原因不能为空");
}

@ -0,0 +1,81 @@
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.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-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,29 @@
package cn.iocoder.yudao.module.member.controller.admin.group.vo;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
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 = "状态不能为空")
@InEnum(CommonStatusEnum.class)
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,10 +2,6 @@ package cn.iocoder.yudao.module.member.controller.admin.level;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogExcelVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogRespVO;
import cn.iocoder.yudao.module.member.convert.level.MemberExperienceLogConvert;
@ -16,17 +12,15 @@ 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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
// TODO @疯狂:要不 Log 改成 Record和 PointRecord 保持一致
@Tag(name = "管理后台 - 会员经验记录")
@ -38,16 +32,6 @@ public class MemberExperienceLogController {
@Resource
private MemberExperienceLogService experienceLogService;
// TODO @疯狂:不允许删除经验哈
@DeleteMapping("/delete")
@Operation(summary = "删除会员经验记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:experience-log:delete')")
public CommonResult<Boolean> deleteExperienceLog(@RequestParam("id") Long id) {
experienceLogService.deleteExperienceLog(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得会员经验记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@ -57,16 +41,6 @@ public class MemberExperienceLogController {
return success(MemberExperienceLogConvert.INSTANCE.convert(experienceLog));
}
// TODO @疯狂:这个接口可以删除哈,应该用不到
@GetMapping("/list")
@Operation(summary = "获得会员经验记录列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('member:experience-log:query')")
public CommonResult<List<MemberExperienceLogRespVO>> getExperienceLogList(@RequestParam("ids") Collection<Long> ids) {
List<MemberExperienceLogDO> list = experienceLogService.getExperienceLogList(ids);
return success(MemberExperienceLogConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得会员经验记录分页")
@PreAuthorize("@ss.hasPermission('member:experience-log:query')")
@ -75,17 +49,4 @@ public class MemberExperienceLogController {
return success(MemberExperienceLogConvert.INSTANCE.convertPage(pageResult));
}
// TODO @疯狂:导出可以先不支持,场景不多
@GetMapping("/export-excel")
@Operation(summary = "导出会员经验记录 Excel")
@PreAuthorize("@ss.hasPermission('member:experience-log:export')")
@OperateLog(type = EXPORT)
public void exportExperienceLogExcel(@Valid MemberExperienceLogExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<MemberExperienceLogDO> list = experienceLogService.getExperienceLogList(exportReqVO);
// 导出 Excel
List<MemberExperienceLogExcelVO> datas = MemberExperienceLogConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "会员经验记录.xls", "数据", MemberExperienceLogExcelVO.class, datas);
}
}

@ -15,7 +15,6 @@ 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;
@ -62,16 +61,6 @@ public class MemberLevelController {
return success(MemberLevelConvert.INSTANCE.convert(level));
}
// TODO @疯狂:这个应该用不到哈
@GetMapping("/list")
@Operation(summary = "获得会员等级列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('member:level:query')")
public CommonResult<List<MemberLevelRespVO>> getLevelList(@RequestParam("ids") Collection<Long> ids) {
List<MemberLevelDO> list = levelService.getLevelList(ids);
return success(MemberLevelConvert.INSTANCE.convertList(list));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取会员等级精简信息列表", description = "只包含被开启的会员等级,主要用于前端的下拉选项")
public CommonResult<List<MemberLevelSimpleRespVO>> getSimpleLevelList() {

@ -2,10 +2,6 @@ package cn.iocoder.yudao.module.member.controller.admin.level;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogExcelVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogRespVO;
import cn.iocoder.yudao.module.member.convert.level.MemberLevelLogConvert;
@ -16,17 +12,15 @@ 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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
// TODO @疯狂:是不是不用这个 controller因为日志只是为了记录db 可以查询、和审计即可,目前暂时不需要开放出来;
@Tag(name = "管理后台 - 会员等级记录")
@ -38,16 +32,6 @@ public class MemberLevelLogController {
@Resource
private MemberLevelLogService levelLogService;
// TODO @疯狂:这个不允许删除哈
@DeleteMapping("/delete")
@Operation(summary = "删除会员等级记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:level-log:delete')")
public CommonResult<Boolean> deleteLevelLog(@RequestParam("id") Long id) {
levelLogService.deleteLevelLog(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得会员等级记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@ -57,16 +41,6 @@ public class MemberLevelLogController {
return success(MemberLevelLogConvert.INSTANCE.convert(levelLog));
}
// TODO @疯狂:这个接口,应该没用
@GetMapping("/list")
@Operation(summary = "获得会员等级记录列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('member:level-log:query')")
public CommonResult<List<MemberLevelLogRespVO>> getLevelLogList(@RequestParam("ids") Collection<Long> ids) {
List<MemberLevelLogDO> list = levelLogService.getLevelLogList(ids);
return success(MemberLevelLogConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得会员等级记录分页")
@PreAuthorize("@ss.hasPermission('member:level-log:query')")
@ -74,18 +48,4 @@ public class MemberLevelLogController {
PageResult<MemberLevelLogDO> pageResult = levelLogService.getLevelLogPage(pageVO);
return success(MemberLevelLogConvert.INSTANCE.convertPage(pageResult));
}
// TODO @疯狂:导出可以去掉先
@GetMapping("/export-excel")
@Operation(summary = "导出会员等级记录 Excel")
@PreAuthorize("@ss.hasPermission('member:level-log:export')")
@OperateLog(type = EXPORT)
public void exportLevelLogExcel(@Valid MemberLevelLogExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<MemberLevelLogDO> list = levelLogService.getLevelLogList(exportReqVO);
// 导出 Excel
List<MemberLevelLogExcelVO> datas = MemberLevelLogConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "会员等级记录.xls", "数据", MemberLevelLogExcelVO.class, datas);
}
}

@ -8,8 +8,6 @@ import javax.validation.constraints.NotNull;
/**
* Base VO VO 使
* VO Swagger
*
* @author owen
*/
@Data
public class MemberExperienceLogBaseVO {

@ -1,48 +0,0 @@
package cn.iocoder.yudao.module.member.controller.admin.level.vo.experience;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.member.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Excel VO
*
* @author owen
*/
@Data
public class MemberExperienceLogExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("用户编号")
private Long userId;
@ExcelProperty(value = "业务类型", converter = DictConvert.class)
@DictFormat(DictTypeConstants.MEMBER_EXPERIENCE_BIZ_TYPE)
private Integer bizType;
@ExcelProperty("业务编号")
private String bizId;
@ExcelProperty("标题")
private String title;
@ExcelProperty("经验")
private Integer experience;
@ExcelProperty("变更后的经验")
private Integer totalExperience;
@ExcelProperty("描述")
private String description;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.member.controller.admin.level.vo.experience;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员经验记录 Excel 导出 Request VO参数和 MemberExperienceLogPageReqVO 是一致的")
@Data
public class MemberExperienceLogExportReqVO {
@Schema(description = "用户编号", example = "3638")
private Long userId;
@Schema(description = "业务类型", example = "1")
private Integer bizType;
@Schema(description = "业务编号", example = "12164")
private String bizId;
@Schema(description = "标题", example = "增加经验")
private String title;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -11,9 +11,6 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员经验记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -7,9 +7,6 @@ import lombok.ToString;
import java.time.LocalDateTime;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员经验记录 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -14,8 +14,6 @@ import javax.validation.constraints.Positive;
/**
* Base VO VO 使
* VO Swagger
*
* @author owen
*/
@Data
public class MemberLevelBaseVO {

@ -5,10 +5,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
// TODO @疯狂:项目的 vo 和 controller 不写 author 信息哈,只写 swagger 注解
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -6,9 +6,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -7,9 +7,6 @@ import lombok.ToString;
import java.time.LocalDateTime;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.member.controller.admin.level.vo.level;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
// TODO @疯狂:不需要继承 MemberLevelBaseVO
@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,6 @@ import lombok.ToString;
import javax.validation.constraints.NotNull;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -8,8 +8,6 @@ import javax.validation.constraints.NotNull;
/**
* Base VO VO 使
* VO Swagger
*
* @author owen
*/
@Data
public class MemberLevelLogBaseVO {

@ -1,46 +0,0 @@
package cn.iocoder.yudao.module.member.controller.admin.level.vo.log;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Excel VO
*
* @author owen
*/
@Data
public class MemberLevelLogExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("用户编号")
private Long userId;
@ExcelProperty("等级编号")
private Long levelId;
@ExcelProperty("会员等级")
private Integer level;
@ExcelProperty("享受折扣")
private Integer discount;
@ExcelProperty("升级经验")
private Integer experience;
@ExcelProperty("会员此时的经验")
private Integer userExperience;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("描述")
private String description;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -1,28 +0,0 @@
package cn.iocoder.yudao.module.member.controller.admin.level.vo.log;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级记录 Excel 导出 Request VO参数和 MemberLevelLogPageReqVO 是一致的")
@Data
public class MemberLevelLogExportReqVO {
@Schema(description = "用户编号", example = "25923")
private Long userId;
@Schema(description = "等级编号", example = "25985")
private Long levelId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -11,9 +11,6 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -7,9 +7,6 @@ import lombok.ToString;
import java.time.LocalDateTime;
/**
* @author owen
*/
@Schema(description = "管理后台 - 会员等级记录 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)

@ -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,17 +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();
// 拼接
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels));
// 处理用户分组返显
List<MemberGroupDO> groups = memberGroupService.getGroupList(groupIds);
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);
}

@ -1,7 +1,6 @@
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.experience.MemberExperienceLogExcelVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceLogDO;
import org.mapstruct.Mapper;
@ -25,6 +24,4 @@ public interface MemberExperienceLogConvert {
PageResult<MemberExperienceLogRespVO> convertPage(PageResult<MemberExperienceLogDO> page);
List<MemberExperienceLogExcelVO> convertList02(List<MemberExperienceLogDO> list);
}

@ -1,7 +1,6 @@
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.MemberLevelLogExcelVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelLogDO;
import org.mapstruct.Mapper;
@ -25,6 +24,4 @@ public interface MemberLevelLogConvert {
PageResult<MemberLevelLogRespVO> convertPage(PageResult<MemberLevelLogDO> page);
List<MemberLevelLogExcelVO> convertList02(List<MemberLevelLogDO> 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,15 +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;
}

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
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.system.enums.common.SexEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
@ -121,12 +122,18 @@ public class MemberUserDO extends TenantBaseDO {
/**
*
*
* {@link MemberLevelDO#getLevel()}
* {@link MemberLevelDO#getId()}
*/
private Long levelId;
/**
*
*/
private Integer experience;
/**
*
*
* {@link MemberGroupDO#getId()}
*/
private Long groupId;
}

@ -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);
}
}

@ -3,13 +3,10 @@ package cn.iocoder.yudao.module.member.dal.mysql.level;
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.level.vo.experience.MemberExperienceLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceLogDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* Mapper
*
@ -28,14 +25,4 @@ public interface MemberExperienceLogMapper extends BaseMapperX<MemberExperienceL
.orderByDesc(MemberExperienceLogDO::getId));
}
default List<MemberExperienceLogDO> selectList(MemberExperienceLogExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<MemberExperienceLogDO>()
.eqIfPresent(MemberExperienceLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(MemberExperienceLogDO::getBizId, reqVO.getBizId())
.eqIfPresent(MemberExperienceLogDO::getBizType, reqVO.getBizType())
.eqIfPresent(MemberExperienceLogDO::getTitle, reqVO.getTitle())
.betweenIfPresent(MemberExperienceLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MemberExperienceLogDO::getId));
}
}

@ -3,13 +3,10 @@ package cn.iocoder.yudao.module.member.dal.mysql.level;
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.level.vo.log.MemberLevelLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelLogDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* Mapper
*
@ -26,12 +23,4 @@ public interface MemberLevelLogMapper extends BaseMapperX<MemberLevelLogDO> {
.orderByDesc(MemberLevelLogDO::getId));
}
default List<MemberLevelLogDO> selectList(MemberLevelLogExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<MemberLevelLogDO>()
.eqIfPresent(MemberLevelLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(MemberLevelLogDO::getLevelId, reqVO.getLevelId())
.betweenIfPresent(MemberLevelLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MemberLevelLogDO::getId));
}
}

@ -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));
}
@ -62,4 +63,18 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
.set(MemberUserDO::getExperience, 0)
.set(MemberUserDO::getLevelId, null));
}
default Long selectCountByGroupId(Long groupId) {
return selectCount(MemberUserDO::getGroupId, groupId);
}
default Long selectCountByLevelId(Long levelId) {
return selectCount(MemberUserDO::getLevelId, levelId);
}
default Long selectCountByTagId(Long tagId) {
return selectCount(new LambdaQueryWrapperX<MemberUserDO>()
.apply("FIND_IN_SET({0}, tag_ids)", tagId));
}
}

@ -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);
}
}

@ -1,7 +1,6 @@
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.experience.MemberExperienceLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceLogDO;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
@ -16,13 +15,6 @@ import java.util.List;
*/
public interface MemberExperienceLogService {
/**
*
*
* @param id
*/
void deleteExperienceLog(Long id);
/**
*
*
@ -47,14 +39,6 @@ public interface MemberExperienceLogService {
*/
PageResult<MemberExperienceLogDO> getExperienceLogPage(MemberExperienceLogPageReqVO pageReqVO);
/**
* , Excel
*
* @param exportReqVO
* @return
*/
List<MemberExperienceLogDO> getExperienceLogList(MemberExperienceLogExportReqVO exportReqVO);
/**
*
*

@ -2,7 +2,6 @@ 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.MemberExperienceLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceLogPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceLogDO;
import cn.iocoder.yudao.module.member.dal.mysql.level.MemberExperienceLogMapper;
@ -14,9 +13,6 @@ 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.EXPERIENCE_LOG_NOT_EXISTS;
/**
* Service
*
@ -29,19 +25,6 @@ public class MemberExperienceLogServiceImpl implements MemberExperienceLogServic
@Resource
private MemberExperienceLogMapper experienceLogMapper;
@Override
public void deleteExperienceLog(Long id) {
// 校验存在
validateExperienceLogExists(id);
// 删除
experienceLogMapper.deleteById(id);
}
private void validateExperienceLogExists(Long id) {
if (experienceLogMapper.selectById(id) == null) {
throw exception(EXPERIENCE_LOG_NOT_EXISTS);
}
}
@Override
public MemberExperienceLogDO getExperienceLog(Long id) {
@ -58,11 +41,6 @@ public class MemberExperienceLogServiceImpl implements MemberExperienceLogServic
return experienceLogMapper.selectPage(pageReqVO);
}
@Override
public List<MemberExperienceLogDO> getExperienceLogList(MemberExperienceLogExportReqVO exportReqVO) {
return experienceLogMapper.selectList(exportReqVO);
}
@Override
public void createAdjustLog(Long userId, int experience, int totalExperience) {
// 管理员调整时, 没有业务编号, 记录对应的枚举值

@ -1,7 +1,6 @@
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.MemberLevelLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelLogDO;
@ -48,14 +47,6 @@ public interface MemberLevelLogService {
*/
PageResult<MemberLevelLogDO> getLevelLogPage(MemberLevelLogPageReqVO pageReqVO);
/**
* , Excel
*
* @param exportReqVO
* @return
*/
List<MemberLevelLogDO> getLevelLogList(MemberLevelLogExportReqVO exportReqVO);
/**
*
*

@ -1,7 +1,6 @@
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.MemberLevelLogExportReqVO;
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelLogPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelLogDO;
@ -58,11 +57,6 @@ public class MemberLevelLogServiceImpl implements MemberLevelLogService {
return levelLogMapper.selectPage(pageReqVO);
}
@Override
public List<MemberLevelLogDO> getLevelLogList(MemberLevelLogExportReqVO exportReqVO) {
return levelLogMapper.selectList(exportReqVO);
}
@Override
public void createCancelLog(Long userId, String reason) {
MemberLevelLogDO levelLogDO = new MemberLevelLogDO();

@ -74,9 +74,10 @@ public class MemberLevelServiceImpl implements MemberLevelService {
@Override
public void deleteLevel(Long id) {
// TODO @疯狂:校验是否有用户使用该等级
// 校验存在
validateLevelExists(id);
// 校验分组下是否有用户
validateLevelHasUser(id);
// 删除
levelMapper.deleteById(id);
}
@ -149,6 +150,14 @@ public class MemberLevelServiceImpl implements MemberLevelService {
validateExperienceOutRange(list, id, level, experience);
}
@VisibleForTesting
void validateLevelHasUser(Long id) {
Long count = memberUserMapper.selectCountByLevelId(id);
if (count > 0) {
throw exception(GROUP_HAS_USER);
}
}
@Override
public MemberLevelDO getLevel(Long id) {
return levelMapper.selectById(id);

@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.member.controller.admin.tag.vo.MemberTagUpdateReq
import cn.iocoder.yudao.module.member.convert.tag.MemberTagConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.tag.MemberTagDO;
import cn.iocoder.yudao.module.member.dal.mysql.tag.MemberTagMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -18,8 +19,7 @@ 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.TAG_NAME_EXISTS;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.TAG_NOT_EXISTS;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
/**
* Service
@ -32,6 +32,8 @@ public class MemberTagServiceImpl implements MemberTagService {
@Resource
private MemberTagMapper tagMapper;
@Resource
private MemberUserMapper memberUserMapper;
@Override
public Long createTag(MemberTagCreateReqVO createReqVO) {
@ -59,6 +61,8 @@ public class MemberTagServiceImpl implements MemberTagService {
public void deleteTag(Long id) {
// 校验存在
validateTagExists(id);
// 校验标签下是否有用户
validateTagHasUser(id);
// 删除
tagMapper.deleteById(id);
}
@ -87,6 +91,13 @@ public class MemberTagServiceImpl implements MemberTagService {
}
}
void validateTagHasUser(Long id) {
Long count = memberUserMapper.selectCountByTagId(id);
if (count > 0) {
throw exception(TAG_HAS_USER);
}
}
@Override
public MemberTagDO getTag(Long id) {
return tagMapper.selectById(id);

@ -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