优化:用户新增类型字段,用于标识用户是系统内置或自定义
1.系统内置用户不允许禁用、删除、变更所属角色 2.删除用户时,自动删除用户和角色关联
This commit is contained in:
parent
ff24f3ba78
commit
139cb337d7
@ -23,6 +23,7 @@ import lombok.Data;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.base.BaseDO;
|
import top.charles7c.cnadmin.common.base.BaseDO;
|
||||||
|
import top.charles7c.cnadmin.common.enums.DataTypeEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.GenderEnum;
|
import top.charles7c.cnadmin.common.enums.GenderEnum;
|
||||||
|
|
||||||
@ -83,6 +84,11 @@ public class UserDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private DisEnableStatusEnum status;
|
private DisEnableStatusEnum status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型(1:系统内置,2:自定义)
|
||||||
|
*/
|
||||||
|
private DataTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后一次修改密码时间
|
* 最后一次修改密码时间
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@ package top.charles7c.cnadmin.system.model.vo;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -28,8 +29,10 @@ import com.alibaba.excel.annotation.ExcelProperty;
|
|||||||
|
|
||||||
import top.charles7c.cnadmin.common.base.BaseDetailVO;
|
import top.charles7c.cnadmin.common.base.BaseDetailVO;
|
||||||
import top.charles7c.cnadmin.common.config.easyexcel.ExcelBaseEnumConverter;
|
import top.charles7c.cnadmin.common.config.easyexcel.ExcelBaseEnumConverter;
|
||||||
|
import top.charles7c.cnadmin.common.enums.DataTypeEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.GenderEnum;
|
import top.charles7c.cnadmin.common.enums.GenderEnum;
|
||||||
|
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户详情信息
|
* 用户详情信息
|
||||||
@ -93,6 +96,13 @@ public class UserDetailVO extends BaseDetailVO {
|
|||||||
@ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class)
|
@ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class)
|
||||||
private DisEnableStatusEnum status;
|
private DisEnableStatusEnum status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型(1:系统内置,2:自定义)
|
||||||
|
*/
|
||||||
|
@Schema(description = "类型(1:系统内置,2:自定义)")
|
||||||
|
@ExcelProperty(value = "类型", converter = ExcelBaseEnumConverter.class)
|
||||||
|
private DataTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
@ -131,4 +141,9 @@ public class UserDetailVO extends BaseDetailVO {
|
|||||||
@Schema(description = "所属角色")
|
@Schema(description = "所属角色")
|
||||||
@ExcelProperty(value = "所属角色")
|
@ExcelProperty(value = "所属角色")
|
||||||
private String roleNames;
|
private String roleNames;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getDisabled() {
|
||||||
|
return DataTypeEnum.SYSTEM.equals(type) || Objects.equals(this.getId(), LoginHelper.getUserId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import cn.hutool.core.util.DesensitizedUtil;
|
import cn.hutool.core.util.DesensitizedUtil;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.base.BaseVO;
|
import top.charles7c.cnadmin.common.base.BaseVO;
|
||||||
|
import top.charles7c.cnadmin.common.enums.DataTypeEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.GenderEnum;
|
import top.charles7c.cnadmin.common.enums.GenderEnum;
|
||||||
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
||||||
@ -85,6 +86,12 @@ public class UserVO extends BaseVO {
|
|||||||
@Schema(description = "状态(1:启用,2:禁用)")
|
@Schema(description = "状态(1:启用,2:禁用)")
|
||||||
private DisEnableStatusEnum status;
|
private DisEnableStatusEnum status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型(1:系统内置,2:自定义)
|
||||||
|
*/
|
||||||
|
@Schema(description = "类型(1:系统内置,2:自定义)")
|
||||||
|
private DataTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
|
@ -53,4 +53,12 @@ public interface UserRoleService {
|
|||||||
* @return 角色 ID 列表
|
* @return 角色 ID 列表
|
||||||
*/
|
*/
|
||||||
List<Long> listRoleIdByUserId(Long userId);
|
List<Long> listRoleIdByUserId(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户 ID 删除
|
||||||
|
*
|
||||||
|
* @param userIds
|
||||||
|
* 用户 ID 列表
|
||||||
|
*/
|
||||||
|
void deleteByUserIds(List<Long> userIds);
|
||||||
}
|
}
|
@ -23,8 +23,6 @@ import lombok.RequiredArgsConstructor;
|
|||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
|
|
||||||
import top.charles7c.cnadmin.system.mapper.UserRoleMapper;
|
import top.charles7c.cnadmin.system.mapper.UserRoleMapper;
|
||||||
import top.charles7c.cnadmin.system.model.entity.UserRoleDO;
|
import top.charles7c.cnadmin.system.model.entity.UserRoleDO;
|
||||||
import top.charles7c.cnadmin.system.service.UserRoleService;
|
import top.charles7c.cnadmin.system.service.UserRoleService;
|
||||||
@ -43,9 +41,6 @@ public class UserRoleServiceImpl implements UserRoleService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(List<Long> roleIds, Long userId) {
|
public void save(List<Long> roleIds, Long userId) {
|
||||||
if (CollUtil.isEmpty(roleIds)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 删除原有关联
|
// 删除原有关联
|
||||||
userRoleMapper.lambdaUpdate().eq(UserRoleDO::getUserId, userId).remove();
|
userRoleMapper.lambdaUpdate().eq(UserRoleDO::getUserId, userId).remove();
|
||||||
// 保存最新关联
|
// 保存最新关联
|
||||||
@ -63,4 +58,9 @@ public class UserRoleServiceImpl implements UserRoleService {
|
|||||||
public List<Long> listRoleIdByUserId(Long userId) {
|
public List<Long> listRoleIdByUserId(Long userId) {
|
||||||
return userRoleMapper.selectRoleIdByUserId(userId);
|
return userRoleMapper.selectRoleIdByUserId(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteByUserIds(List<Long> userIds) {
|
||||||
|
userRoleMapper.lambdaUpdate().in(UserRoleDO::getUserId, userIds).remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package top.charles7c.cnadmin.system.service.impl;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.io.file.FileNameUtil;
|
import cn.hutool.core.io.file.FileNameUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
@ -37,6 +40,7 @@ import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties;
|
|||||||
import top.charles7c.cnadmin.common.constant.FileConsts;
|
import top.charles7c.cnadmin.common.constant.FileConsts;
|
||||||
import top.charles7c.cnadmin.common.constant.StringConsts;
|
import top.charles7c.cnadmin.common.constant.StringConsts;
|
||||||
import top.charles7c.cnadmin.common.constant.SysConsts;
|
import top.charles7c.cnadmin.common.constant.SysConsts;
|
||||||
|
import top.charles7c.cnadmin.common.enums.DataTypeEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.cnadmin.common.model.dto.LoginUser;
|
import top.charles7c.cnadmin.common.model.dto.LoginUser;
|
||||||
import top.charles7c.cnadmin.common.service.CommonUserService;
|
import top.charles7c.cnadmin.common.service.CommonUserService;
|
||||||
@ -95,6 +99,16 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
|
|||||||
String username = request.getUsername();
|
String username = request.getUsername();
|
||||||
boolean isExists = this.checkNameExists(username, id);
|
boolean isExists = this.checkNameExists(username, id);
|
||||||
CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username));
|
CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username));
|
||||||
|
UserDO oldUser = super.getById(id);
|
||||||
|
if (DataTypeEnum.SYSTEM.equals(oldUser.getType())) {
|
||||||
|
CheckUtils.throwIf(() -> DisEnableStatusEnum.DISABLE.equals(request.getStatus()),
|
||||||
|
String.format("'%s' 是系统内置用户,不允许禁用", oldUser.getNickname()));
|
||||||
|
List<Long> oldRoleIdList =
|
||||||
|
userRoleService.listRoleIdByUserId(id).stream().sorted().collect(Collectors.toList());
|
||||||
|
List<Long> newRoleIdList = request.getRoleIds().stream().sorted().collect(Collectors.toList());
|
||||||
|
CheckUtils.throwIf(() -> !CollUtil.isEqualList(newRoleIdList, oldRoleIdList),
|
||||||
|
String.format("'%s' 是系统内置用户,不允许变更所属角色", oldUser.getNickname()));
|
||||||
|
}
|
||||||
|
|
||||||
// 更新信息
|
// 更新信息
|
||||||
super.update(request, id);
|
super.update(request, id);
|
||||||
@ -102,6 +116,21 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
|
|||||||
userRoleService.save(request.getRoleIds(), id);
|
userRoleService.save(request.getRoleIds(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void delete(List<Long> ids) {
|
||||||
|
List<UserDO> list =
|
||||||
|
baseMapper.lambdaQuery().select(UserDO::getNickname, UserDO::getType).in(UserDO::getId, ids).list();
|
||||||
|
Optional<UserDO> isSystemData = list.stream().filter(u -> DataTypeEnum.SYSTEM.equals(u.getType())).findFirst();
|
||||||
|
CheckUtils.throwIf(isSystemData::isPresent,
|
||||||
|
String.format("所选用户 '%s' 是系统内置用户,不允许删除", isSystemData.orElseGet(UserDO::new).getNickname()));
|
||||||
|
|
||||||
|
// 删除用户
|
||||||
|
super.delete(ids);
|
||||||
|
// 删除用户和角色关联
|
||||||
|
userRoleService.deleteByUserIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fillDetail(Object detailObj) {
|
public void fillDetail(Object detailObj) {
|
||||||
super.fillDetail(detailObj);
|
super.fillDetail(detailObj);
|
||||||
|
@ -12,6 +12,7 @@ export interface UserRecord {
|
|||||||
phone?: string;
|
phone?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
|
type?: number;
|
||||||
pwdResetTime?: string;
|
pwdResetTime?: string;
|
||||||
createUserString?: string;
|
createUserString?: string;
|
||||||
createTime?: string;
|
createTime?: string;
|
||||||
|
@ -139,15 +139,15 @@
|
|||||||
>
|
>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<a-table-column title="ID" data-index="id" />
|
<a-table-column title="ID" data-index="id" />
|
||||||
<a-table-column title="用户名">
|
<a-table-column title="用户名" :width="115">
|
||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
<a-link @click="toDetail(record.id)">{{
|
<a-link @click="toDetail(record.id)">{{
|
||||||
record.username
|
record.username
|
||||||
}}</a-link>
|
}}</a-link>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
<a-table-column title="昵称" data-index="nickname" :width="120" />
|
<a-table-column title="昵称" data-index="nickname" :width="115" />
|
||||||
<a-table-column title="性别">
|
<a-table-column title="性别" align="center">
|
||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
<span v-if="record.gender === 1">男</span>
|
<span v-if="record.gender === 1">男</span>
|
||||||
<span v-else-if="record.gender === 2">女</span>
|
<span v-else-if="record.gender === 2">女</span>
|
||||||
@ -161,7 +161,7 @@
|
|||||||
</a-avatar>
|
</a-avatar>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
<a-table-column title="联系方式" :width="175">
|
<a-table-column title="联系方式" :width="170">
|
||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
{{ record.email }}<br v-if="record.email && record.phone">
|
{{ record.email }}<br v-if="record.email && record.phone">
|
||||||
{{ record.phone }}
|
{{ record.phone }}
|
||||||
@ -178,7 +178,12 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
<a-table-column title="描述" data-index="description" ellipsis tooltip />
|
<a-table-column title="类型" align="center">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-tag v-if="record.type === 1" color="red">系统内置</a-tag>
|
||||||
|
<a-tag v-else color="arcoblue">自定义</a-tag>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
<a-table-column title="创建人/创建时间" :width="175">
|
<a-table-column title="创建人/创建时间" :width="175">
|
||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
{{ record.createUserString }}<br>
|
{{ record.createUserString }}<br>
|
||||||
@ -243,6 +248,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
title="分配角色"
|
title="分配角色"
|
||||||
|
:disabled="record.disabled"
|
||||||
@click="toUpdateRole(record.id)"
|
@click="toUpdateRole(record.id)"
|
||||||
>
|
>
|
||||||
<template #icon><svg-icon icon-class="reference" /></template>
|
<template #icon><svg-icon icon-class="reference" /></template>
|
||||||
@ -319,7 +325,7 @@
|
|||||||
style="width: 431px"
|
style="width: 431px"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="所属角色" field="roleIds">
|
<a-form-item label="所属角色" field="roleIds" :disabled="form.disabled">
|
||||||
<a-select
|
<a-select
|
||||||
v-model="form.roleIds"
|
v-model="form.roleIds"
|
||||||
:options="roleOptions"
|
:options="roleOptions"
|
||||||
@ -674,6 +680,7 @@
|
|||||||
status: 1,
|
status: 1,
|
||||||
deptId: undefined,
|
deptId: undefined,
|
||||||
roleIds: [] as Array<string>,
|
roleIds: [] as Array<string>,
|
||||||
|
disabled: false,
|
||||||
};
|
};
|
||||||
proxy.$refs.formRef?.resetFields();
|
proxy.$refs.formRef?.resetFields();
|
||||||
};
|
};
|
||||||
@ -825,11 +832,19 @@
|
|||||||
* @param record 记录信息
|
* @param record 记录信息
|
||||||
*/
|
*/
|
||||||
const handleChangeStatus = (record: UserRecord) => {
|
const handleChangeStatus = (record: UserRecord) => {
|
||||||
if (record.id) {
|
const { id } = record;
|
||||||
|
if (id) {
|
||||||
const tip = record.status === 1 ? '启用' : '禁用';
|
const tip = record.status === 1 ? '启用' : '禁用';
|
||||||
updateUser(record, record.id)
|
getUser(id)
|
||||||
.then(() => {
|
.then((res) => {
|
||||||
proxy.$message.success(`${tip}成功`);
|
res.data.status = record.status;
|
||||||
|
updateUser(res.data, id)
|
||||||
|
.then(() => {
|
||||||
|
proxy.$message.success(`${tip}成功`);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
record.status = record.status === 1 ? 2 : 1;
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
record.status = record.status === 1 ? 2 : 1;
|
record.status = record.status === 1 ? 2 : 1;
|
||||||
|
@ -49,8 +49,8 @@ INSERT IGNORE INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '系统
|
|||||||
INSERT IGNORE INTO `sys_role` VALUES (2, '测试人员', 'test', 5, NULL, 2, 1, 2, 1, NOW(), 1, NOW());
|
INSERT IGNORE INTO `sys_role` VALUES (2, '测试人员', 'test', 5, NULL, 2, 1, 2, 1, NOW(), 1, NOW());
|
||||||
|
|
||||||
-- 初始化默认用户:admin/admin123;test/123456
|
-- 初始化默认用户:admin/admin123;test/123456
|
||||||
INSERT IGNORE INTO `sys_user` VALUES (1, 'admin', '超级管理员', '9802815bcc5baae7feb1ae0d0566baf2', 1, 'charles7c@126.com', '18888888888', NULL, '系统初始用户', 1, NOW(), 1, 1, NOW(), 1, NOW());
|
INSERT IGNORE INTO `sys_user` VALUES (1, 'admin', '超级管理员', '9802815bcc5baae7feb1ae0d0566baf2', 1, 'charles7c@126.com', '18888888888', NULL, '系统初始用户', 1, 1, NOW(), 1, 1, NOW(), 1, NOW());
|
||||||
INSERT IGNORE INTO `sys_user` VALUES (2, 'test', '测试员', '8e114197e1b33783a00542ad67e80516', 2, NULL, NULL, NULL, '系统初始用户', 2, NOW(), 5, 1, NOW(), 1, NOW());
|
INSERT IGNORE INTO `sys_user` VALUES (2, 'test', '测试员', '8e114197e1b33783a00542ad67e80516', 2, NULL, NULL, NULL, NULL, 2, 2, NOW(), 5, 1, NOW(), 1, NOW());
|
||||||
|
|
||||||
-- 初始化默认角色和菜单关联数据
|
-- 初始化默认角色和菜单关联数据
|
||||||
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 1000);
|
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 1000);
|
||||||
|
@ -86,6 +86,7 @@ CREATE TABLE IF NOT EXISTS `sys_user` (
|
|||||||
`avatar` varchar(255) DEFAULT NULL COMMENT '头像地址',
|
`avatar` varchar(255) DEFAULT NULL COMMENT '头像地址',
|
||||||
`description` varchar(512) DEFAULT NULL COMMENT '描述',
|
`description` varchar(512) DEFAULT NULL COMMENT '描述',
|
||||||
`status` tinyint(1) UNSIGNED DEFAULT 1 COMMENT '状态(1:启用,2:禁用)',
|
`status` tinyint(1) UNSIGNED DEFAULT 1 COMMENT '状态(1:启用,2:禁用)',
|
||||||
|
`type` tinyint(1) UNSIGNED DEFAULT 2 COMMENT '类型(1:系统内置,2:自定义)',
|
||||||
`pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码时间',
|
`pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码时间',
|
||||||
`dept_id` bigint(20) UNSIGNED NOT NULL COMMENT '部门ID',
|
`dept_id` bigint(20) UNSIGNED NOT NULL COMMENT '部门ID',
|
||||||
`create_user` bigint(20) UNSIGNED NOT NULL COMMENT '创建人',
|
`create_user` bigint(20) UNSIGNED NOT NULL COMMENT '创建人',
|
||||||
|
Loading…
Reference in New Issue
Block a user