迁移管理员逻辑

This commit is contained in:
YunaiV
2020-07-05 18:28:14 +08:00
parent 6a4b6fe67f
commit 51a5e5b750
35 changed files with 676 additions and 323 deletions

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>system</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>system-biz-api</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,26 +0,0 @@
package cn.iocoder.mall.system.biz.enums.errorcode;
/**
* 错误码枚举,内置错误码是在 枚举中
* @author ding
*/
public enum ErrorCodeTypeEnum {
/**
* 内置错误码
*/
SYSTEM(1),
/**
* 自定义错误码
*/
CUSTOM(2);
private final Integer type;
ErrorCodeTypeEnum(Integer type) {
this.type = type;
}
public Integer getType() {
return type;
}
}

View File

@@ -1,6 +0,0 @@
/**
* 该项目,主要用于暴露一些共享的枚举类等。
*
* 例如说RPC 接口提供错误码给调用方
*/
package cn.iocoder.mall.system.biz;

View File

@@ -1,22 +0,0 @@
package cn.iocoder.mall.system.rest.request.admin;
import cn.iocoder.common.framework.vo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@ApiModel("管理员 - 管理员模块 - 管理员分页信息 Request")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AdminsAdminPageRequest extends PageParam {
@ApiModelProperty(value = "真实名字,模糊匹配", example = "小王")
private String name;
@ApiModelProperty(value = "部门编号")
private Integer departmentId;
}

View File

@@ -1,29 +0,0 @@
package cn.iocoder.mall.system.rest.request.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Author: jiangweifan
* @Date: 2020/5/12
* @Description: 管理员 - 用户信息 - 用户分页列表
*/
@ApiModel("用户分页列表Request")
@Data
@Accessors(chain = true)
public class AdminsUserPageRequest {
@ApiModelProperty(name = "nickname", value = "昵称,模糊匹配", example = "小王")
private String nickname;
@ApiModelProperty(name = "status", value = "状态。1 - 开启2 - 禁用", example = "0")
private Integer status;
@ApiModelProperty(name = "pageNo", value = "页码,从 1 开始", example = "1")
private Integer pageNo = 1;
@ApiModelProperty(name = "pageSize", value = "每页条数", required = true, example = "10")
private Integer pageSize = 10;
}

View File

@@ -1,27 +0,0 @@
package cn.iocoder.mall.system.rest.request.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* @Author: jiangweifan
* @Date: 2020/5/12
* @Description: 管理员 - 用户信息 - 更新用户状态
*/
@ApiModel("更新用户状态Request")
@Data
@Accessors(chain = true)
public class AdminsUserUpdateStatusRequest {
@ApiModelProperty(name = "id", value = "用户编号", required = true, example = "1")
@NotNull(message = "用户编号不能为空")
private Integer id;
@ApiModelProperty(name = "status", value = "用户状态。1 - 开启2 - 禁用", required = true, example = "1")
@NotNull(message = "用户状态不能为空")
private Integer status;
}

View File

@@ -1,79 +0,0 @@
package cn.iocoder.mall.system.rest.response.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
@ApiModel("管理员 - 管理员模块 - 管理员分页信息 Response")
@Data
@Accessors(chain = true)
public class AdminsAdminPageResponse {
@ApiModel("角色")
@Data
@Accessors(chain = true)
public static class Role {
@ApiModelProperty(value = "角色编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "角色名", required = true, example = "码神")
private String name;
}
@ApiModel("部门")
@Data
@Accessors(chain = true)
public static class Department {
@ApiModelProperty(value = "部门编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "部门名称", required = true, example = "研发部")
private String name;
}
@ApiModel("账号")
@Data
@Accessors(chain = true)
public static class Account {
@ApiModelProperty(value = "账号编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "登陆账号", required = true, example = "15601691300")
private String username;
}
@ApiModelProperty(value = "管理员编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "真实名字", required = true, example = "小王")
private String name;
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
private Date createTime;
@ApiModelProperty(value = "在职状态", required = true, example = "1", notes = "见 AdminStatusEnum 枚举")
private Integer status;
/**
* 账号
*/
private Account account;
/**
* 角色列表
*/
private List<Role> roles;
/**
* 所在部门
*/
private Department department;
}

View File

@@ -1,32 +0,0 @@
package cn.iocoder.mall.system.rest.response.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Author: jiangweifan
* @Date: 2020/5/12
* @Description: 管理员 - 用户信息 - 用户分页列表Response
*/
@ApiModel("用户分页信息 Response")
@Data
@Accessors(chain = true)
public class AdminsUserPageResponse {
@ApiModelProperty(value = "用户编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "昵称", required = false, example = "1")
private String nickname;
@ApiModelProperty(value = "手机号", required = true, example = "13631780241")
private String mobile;
@ApiModelProperty(value = "头像", required = false, example = "http://www.iocoder.cn/xxx.jpg")
private String avatar;
@ApiModelProperty(value = "用户状态 1 - 开启2 - 禁用", required = true, example = "1")
private Integer status;
}

View File

@@ -1,15 +0,0 @@
package cn.iocoder.mall.system.api.constant;
public class AdminConstants {
/**
* 账号 - 管理员
*/
public static final String USERNAME_ADMIN = "admin";
/**
* 账号 - 演示账号
*/
public static final String USERNAME_DEMO = "yudaoyuanma";
}

View File

@@ -1,39 +0,0 @@
package cn.iocoder.mall.system.api.dto.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
@ApiModel("管理员添加 DTO")
@Data
@Accessors(chain = true)
public class AdminAddDTO implements Serializable {
@ApiModelProperty(value = "登陆账号", required = true, example = "15601691300")
@NotEmpty(message = "登陆账号不能为空")
@Length(min = 5, max = 16, message = "账号长度为 5-16 位")
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母")
private String username;
@ApiModelProperty(value = "昵称", required = true, example = "小王")
@NotEmpty(message = "昵称不能为空")
@Length(max = 10, message = "昵称长度最大为 10 位")
private String nickname;
@ApiModelProperty(value = "密码", required = true, example = "buzhidao")
@NotEmpty(message = "密码不能为空")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
@ApiModelProperty(value = "部门ID", required = true, example = "1")
@NotNull(message = "部门不能为空")
private Integer deptmentId;
}

View File

@@ -1,21 +0,0 @@
package cn.iocoder.mall.system.api.dto.admin;
import cn.iocoder.common.framework.vo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
@ApiModel(value = "管理员分页 DTO")
@Data
@Accessors(chain = true)
public class AdminPageDTO extends PageParam {
@ApiModelProperty(value = "昵称,模糊匹配", example = "小王")
private String nickname;
@ApiModelProperty(value = "所在部门ID")
private Integer deptmentId;
}

View File

@@ -1,42 +0,0 @@
package cn.iocoder.mall.system.api.dto.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
@ApiModel("管理员更新 DTO")
@Data
@Accessors(chain = true)
public class AdminUpdateDTO implements Serializable {
@ApiModelProperty(value = "管理员编号", required = true, example = "1")
@NotNull(message = "管理员编号不能为空")
private Integer id;
@ApiModelProperty(value = "登陆账号", required = true, example = "15601691300")
@NotEmpty(message = "登陆账号不能为空")
@Length(min = 5, max = 16, message = "账号长度为 5-16 位")
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母")
private String username;
@ApiModelProperty(value = "昵称", required = true, example = "小王")
@NotEmpty(message = "昵称不能为空")
@Length(max = 10, message = "昵称长度最大为 10 位")
private String nickname;
@ApiModelProperty(value = "密码", example = "buzhidao")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
@ApiModelProperty(value = "部门ID", required = true, example = "1")
@NotNull(message = "部门不能为空")
private Integer deptmentId;
}

View File

@@ -1,26 +0,0 @@
package cn.iocoder.mall.system.api.dto.admin;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
@ApiModel("管理员更新状态 DTO")
@Data
@Accessors(chain = true)
public class AdminUpdateStatusDTO {
@ApiModelProperty(value = "管理员编号", required = true, example = "1")
@NotNull(message = "管理员编号不能为空")
private Integer id;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}

View File

@@ -43,161 +43,6 @@ public class AdminServiceImpl implements AdminService {
@Autowired
private RoleServiceImpl roleService;
@Override
public PageResult<AdminBO> getAdminPage(AdminPageDTO adminPageDTO) {
IPage<AdminDO> page = adminMapper.selectPage(adminPageDTO);
return AdminConvert.INSTANCE.convert(page);
}
@Override
public AdminBO addAdmin(Integer adminId, AdminAddDTO adminAddDTO) {
// 校验账号唯一
if (adminMapper.selectByUsername(adminAddDTO.getUsername()) != null) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_EXISTS.getCode());
}
// 保存到数据库
AdminDO admin = AdminConvert.INSTANCE.convert(adminAddDTO)
.setPassword(encodePassword(adminAddDTO.getPassword())) // 加密密码
.setStatus(CommonStatusEnum.ENABLE.getValue());
admin.setCreateTime(new Date());
admin.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
adminMapper.insert(admin);
// TODO 插入操作日志
// 返回成功
return AdminConvert.INSTANCE.convert(admin);
}
@Override
public Boolean updateAdmin(Integer adminId, AdminUpdateDTO adminUpdateDTO) {
// 校验账号存在
AdminDO admin = adminMapper.selectById(adminUpdateDTO.getId());
if (admin == null) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
}
if (AdminConstants.USERNAME_ADMIN.equals(admin.getUsername())
|| AdminConstants.USERNAME_DEMO.equals(admin.getUsername())) { // 特殊账号,不允许编辑
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_ADMIN_CAN_NOT_UPDATE.getCode());
}
// 校验账号唯一
AdminDO usernameAdmin = adminMapper.selectByUsername(adminUpdateDTO.getUsername());
if (usernameAdmin != null && !usernameAdmin.getId().equals(adminUpdateDTO.getId())) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_EXISTS.getCode());
}
// 更新到数据库
AdminDO updateAdmin = AdminConvert.INSTANCE.convert(adminUpdateDTO);
adminMapper.updateById(updateAdmin);
// TODO 插入操作日志
// 返回成功
return true;
}
@Override
@Transactional
public Boolean updateAdminStatus(Integer adminId, AdminUpdateStatusDTO adminUpdateStatusDTO) {
// 校验账号存在
AdminDO admin = adminMapper.selectById(adminUpdateStatusDTO.getId());
if (admin == null) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
}
if (AdminConstants.USERNAME_ADMIN.equals(admin.getUsername())
|| AdminConstants.USERNAME_DEMO.equals(admin.getUsername())) { // 特殊账号,不允许编辑
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE.getCode());
}
// 如果状态相同,则返回错误
if (adminUpdateStatusDTO.getStatus().equals(admin.getStatus())) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_STATUS_EQUALS.getCode());
}
// 更新管理员状态
AdminDO updateAdmin = new AdminDO().setId(adminUpdateStatusDTO.getId()).setStatus(adminUpdateStatusDTO.getStatus());
adminMapper.updateById(updateAdmin);
// 如果是关闭管理员,则标记 token 失效。否则,管理员还可以继续蹦跶
if (CommonStatusEnum.DISABLE.getValue().equals(adminUpdateStatusDTO.getStatus())) {
oauth2Service.removeToken(new OAuth2RemoveTokenByUserDTO().setUserId(adminId).setUserType(UserTypeEnum.ADMIN.getValue()));
}
// TODO 插入操作日志
// 返回成功
return true;
}
@Override
@Transactional
public Boolean deleteAdmin(Integer adminId, Integer updateAdminId) {
// 校验账号存在
AdminDO admin = adminMapper.selectById(updateAdminId);
if (admin == null) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
}
// 只有禁用的账号才可以删除
if (CommonStatusEnum.ENABLE.getValue().equals(admin.getStatus())) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_DELETE_ONLY_DISABLE.getCode());
}
// 标记删除 AdminDO
adminMapper.deleteById(updateAdminId); // 标记删除
// 标记删除 AdminRole
adminRoleMapper.deleteByAdminId(updateAdminId);
// TODO 插入操作日志
// 返回成功
return true;
}
@Override
public Map<Integer, Collection<RoleBO>> getAdminRolesMap(Collection<Integer> adminIds) {
// 查询管理员拥有的角色关联数据
List<AdminRoleDO> adminRoleList = adminRoleMapper.selectListByAdminIds(adminIds);
if (adminRoleList.isEmpty()) {
return Collections.emptyMap();
}
// 查询角色数据
List<RoleBO> roleList = roleService.getRoleList(CollectionUtil.convertSet(adminRoleList, AdminRoleDO::getRoleId));
Map<Integer, RoleBO> roleMap = CollectionUtil.convertMap(roleList, RoleBO::getId);
// 拼接数据
Multimap<Integer, RoleBO> result = ArrayListMultimap.create();
adminRoleList.forEach(adminRole -> result.put(adminRole.getAdminId(), roleMap.get(adminRole.getRoleId())));
return result.asMap();
}
@Override
public List<RoleBO> getRoleList(Integer adminId) {
// 查询管理员拥有的角色关联数据
List<AdminRoleDO> adminRoleList = adminRoleMapper.selectByAdminId(adminId);
if (adminRoleList.isEmpty()) {
return Collections.emptyList();
}
// 查询角色数据
return roleService.getRoleList(CollectionUtil.convertSet(adminRoleList, AdminRoleDO::getRoleId));
}
@Override
@Transactional
public Boolean assignAdminRole(Integer adminId, AdminAssignRoleDTO adminAssignRoleDTO) {
// 校验账号存在
AdminDO admin = adminMapper.selectById(adminAssignRoleDTO.getId());
if (admin == null) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
}
// 校验是否有不存在的角色
if (!CollectionUtil.isEmpty(adminAssignRoleDTO.getRoleIds())) {
List<RoleDO> roles = roleService.getRoles(adminAssignRoleDTO.getRoleIds());
if (roles.size() != adminAssignRoleDTO.getRoleIds().size()) {
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_ASSIGN_ROLE_NOT_EXISTS.getCode());
}
}
// TODO 芋艿,这里先简单实现。即方式是,删除老的分配的角色关系,然后添加新的分配的角色关系
// 标记管理员角色源关系都为删除
adminRoleMapper.deleteByAdminId(adminAssignRoleDTO.getId());
// 创建 RoleResourceDO 数组,并插入到数据库
if (!CollectionUtil.isEmpty(adminAssignRoleDTO.getRoleIds())) {
List<AdminRoleDO> adminRoleDOs = adminAssignRoleDTO.getRoleIds().stream().map(roleId -> {
AdminRoleDO roleResource = new AdminRoleDO().setAdminId(adminAssignRoleDTO.getId()).setRoleId(roleId);
roleResource.setCreateTime(new Date());
roleResource.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
return roleResource;
}).collect(Collectors.toList());
adminRoleMapper.insertList(adminRoleDOs);
}
// TODO 插入操作日志
// 返回成功
return true;
}
}

View File

@@ -50,56 +50,6 @@ public class AdminController {
@Autowired
private DeptmentService deptmentService;
// =========== 管理员管理 API ===========
//TODO 目前需要增加搜索所有子部门的用户
@GetMapping("/page")
@RequiresPermissions("system.admin.page")
@ApiOperation(value = "管理员分页")
public CommonResult<PageResult<AdminVO>> page(AdminPageDTO adminPageDTO) {
PageResult<AdminBO> page = adminService.getAdminPage(adminPageDTO);
PageResult<AdminVO> resultPage = AdminConvert.INSTANCE.convertAdminVOPage(page);
// 拼接结果
if (!resultPage.getList().isEmpty()) {
// 查询角色数组
Map<Integer, Collection<RoleBO>> roleMap = adminService.getAdminRolesMap(CollectionUtil.convertList(resultPage.getList(), AdminBO::getId));
resultPage.getList().forEach(admin -> admin.setRoles(AdminConvert.INSTANCE.convertAdminVORoleList(roleMap.get(admin.getId()))));
// 查询对应部门
List<DeptmentBO> deptmentBOS = deptmentService.getAllDeptments();
Map<Integer, String> deptNameMap = deptmentBOS.stream().collect(Collectors.toMap(d->d.getId(), d->d.getName()));
//管理员所在部门被删后,变成未分配状态
deptNameMap.put(0, "未分配");
resultPage.getList().forEach(admin->{
admin.setDeptment(new AdminVO.Deptment(admin.getDeptmentId(), deptNameMap.get(admin.getDeptmentId())));
});
}
return success(resultPage);
}
@PostMapping("/add")
@ApiOperation(value = "创建管理员")
public CommonResult<AdminBO> add(AdminAddDTO adminAddDTO) {
return success(adminService.addAdmin(AdminSecurityContextHolder.getContext().getAdminId(), adminAddDTO));
}
@PostMapping("/update")
@ApiOperation(value = "更新管理员")
public CommonResult<Boolean> update(AdminUpdateDTO adminUpdateDTO) {
return success(adminService.updateAdmin(AdminSecurityContextHolder.getContext().getAdminId(), adminUpdateDTO));
}
@PostMapping("/update_status")
@ApiOperation(value = "更新管理员状态")
public CommonResult<Boolean> updateStatus(AdminUpdateStatusDTO adminUpdateStatusDTO) {
return success(adminService.updateAdminStatus(AdminSecurityContextHolder.getContext().getAdminId(), adminUpdateStatusDTO));
}
@PostMapping("/delete")
@ApiOperation(value = "删除管理员")
@ApiImplicitParam(name = "id", value = "管理员编号", required = true, example = "1")
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
return success(adminService.deleteAdmin(AdminSecurityContextHolder.getContext().getAdminId(), id));
}
}