重构:重构系统管理/角色管理功能
1. 使用抽屉代替对话框 2. 优化数据权限权限范围存储,新增角色和部门关联表 3. 新增角色和菜单关联表 4. 部分细节优化
This commit is contained in:
parent
510f86031f
commit
297fbd3675
@ -37,7 +37,7 @@ public @interface CrudRequestMapping {
|
||||
/**
|
||||
* API 列表
|
||||
*/
|
||||
Api[] api() default {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT};
|
||||
Api[] api() default {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT};
|
||||
|
||||
/**
|
||||
* API 枚举
|
||||
@ -62,7 +62,7 @@ public @interface CrudRequestMapping {
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
CREATE,
|
||||
ADD,
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
|
@ -117,8 +117,8 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
|
||||
@Operation(summary = "新增数据")
|
||||
@ResponseBody
|
||||
@PostMapping
|
||||
protected R<Long> create(@Validated(BaseRequest.Create.class) @RequestBody C request) {
|
||||
Long id = baseService.create(request);
|
||||
protected R<Long> add(@Validated(BaseRequest.Create.class) @RequestBody C request) {
|
||||
Long id = baseService.add(request);
|
||||
return R.ok("新增成功", id);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.common.base;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
|
||||
/**
|
||||
* Mapper 基类
|
||||
*
|
||||
* @param <T>
|
||||
* 实体类
|
||||
* @author Charles7c
|
||||
* @since 2023/2/19 20:47
|
||||
*/
|
||||
public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> {
|
||||
|
||||
/**
|
||||
* 批量插入记录
|
||||
*
|
||||
* @param entityList
|
||||
* 实体列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
default boolean insertBatch(Collection<T> entityList) {
|
||||
return Db.saveBatch(entityList);
|
||||
}
|
||||
}
|
@ -78,7 +78,7 @@ public interface BaseService<V, D, Q, C extends BaseRequest> {
|
||||
* 创建信息
|
||||
* @return 自增 ID
|
||||
*/
|
||||
Long create(C request);
|
||||
Long add(C request);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
|
@ -41,6 +41,7 @@ import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Opt;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
|
||||
@ -107,7 +108,7 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(C request) {
|
||||
public Long add(C request) {
|
||||
if (request == null) {
|
||||
return 0L;
|
||||
}
|
||||
@ -153,7 +154,7 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext
|
||||
protected <E> List<E> list(Q query, SortQuery sortQuery, Class<E> targetClass) {
|
||||
QueryWrapper<T> queryWrapper = QueryHelper.build(query);
|
||||
// 设置排序
|
||||
Sort sort = sortQuery.getSort();
|
||||
Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort();
|
||||
for (Sort.Order order : sort) {
|
||||
queryWrapper.orderBy(order != null, order.isAscending(), StrUtil.toUnderlineCase(order.getProperty()));
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import top.charles7c.cnadmin.common.base.BaseMapper;
|
||||
import top.charles7c.cnadmin.system.model.entity.RoleDeptDO;
|
||||
|
||||
/**
|
||||
* 角色和部门 Mapper
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/2/18 21:57
|
||||
*/
|
||||
public interface RoleDeptMapper extends BaseMapper<RoleDeptDO> {
|
||||
|
||||
/**
|
||||
* 根据角色 ID 查询
|
||||
*
|
||||
* @param roleId
|
||||
* 角色 ID
|
||||
* @return 部门 ID 列表
|
||||
*/
|
||||
@Select("SELECT `dept_id` FROM `sys_role_dept` WHERE `role_id` = #{roleId}")
|
||||
List<Long> selectDeptIdsByRoleId(@Param("roleId") Long roleId);
|
||||
}
|
@ -16,8 +16,12 @@
|
||||
|
||||
package top.charles7c.cnadmin.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import top.charles7c.cnadmin.common.base.BaseMapper;
|
||||
import top.charles7c.cnadmin.system.model.entity.RoleMenuDO;
|
||||
|
||||
/**
|
||||
@ -26,4 +30,15 @@ import top.charles7c.cnadmin.system.model.entity.RoleMenuDO;
|
||||
* @author Charles7c
|
||||
* @since 2023/2/15 20:30
|
||||
*/
|
||||
public interface RoleMenuMapper extends BaseMapper<RoleMenuDO> {}
|
||||
public interface RoleMenuMapper extends BaseMapper<RoleMenuDO> {
|
||||
|
||||
/**
|
||||
* 根据角色 ID 查询
|
||||
*
|
||||
* @param roleId
|
||||
* 角色 ID
|
||||
* @return 菜单 ID 列表
|
||||
*/
|
||||
@Select("SELECT `menu_id` FROM `sys_role_menu` WHERE `role_id` = #{roleId}")
|
||||
List<Long> selectMenuIdsByRoleId(@Param("roleId") Long roleId);
|
||||
}
|
||||
|
@ -16,14 +16,10 @@
|
||||
|
||||
package top.charles7c.cnadmin.system.model.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
|
||||
import top.charles7c.cnadmin.common.base.BaseDO;
|
||||
import top.charles7c.cnadmin.common.enums.DataScopeEnum;
|
||||
@ -62,12 +58,6 @@ public class RoleDO extends BaseDO {
|
||||
*/
|
||||
private DataScopeEnum dataScope;
|
||||
|
||||
/**
|
||||
* 数据权限范围(部门 ID 数组)
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<Long> dataScopeDeptIds;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.system.model.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
/**
|
||||
* 角色和部门实体
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/2/18 21:57
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@TableName("sys_role_dept")
|
||||
public class RoleDeptDO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 角色 ID
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 部门 ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
public RoleDeptDO(Long roleId, Long deptId) {
|
||||
this.roleId = roleId;
|
||||
this.deptId = deptId;
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ package top.charles7c.cnadmin.system.model.entity;
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@ -29,6 +30,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
* @since 2023/2/15 20:20
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@TableName("sys_role_menu")
|
||||
public class RoleMenuDO implements Serializable {
|
||||
|
||||
@ -43,4 +45,9 @@ public class RoleMenuDO implements Serializable {
|
||||
* 菜单 ID
|
||||
*/
|
||||
private Long menuId;
|
||||
|
||||
public RoleMenuDO(Long roleId, Long menuId) {
|
||||
this.roleId = roleId;
|
||||
this.menuId = menuId;
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class RoleQuery implements Serializable {
|
||||
* 角色名称
|
||||
*/
|
||||
@Schema(description = "角色名称")
|
||||
@Query(type = Query.Type.INNER_LIKE)
|
||||
@Query(blurry = "roleName,roleCode")
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
|
@ -66,17 +66,11 @@ public class RoleRequest extends BaseRequest {
|
||||
private String roleCode;
|
||||
|
||||
/**
|
||||
* 数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)
|
||||
* 角色排序
|
||||
*/
|
||||
@Schema(description = "数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)", type = "Integer",
|
||||
allowableValues = {"1", "2", "3", "4", "5"})
|
||||
private DataScopeEnum dataScope;
|
||||
|
||||
/**
|
||||
* 数据权限范围(部门 ID 数组)
|
||||
*/
|
||||
@Schema(description = "数据权限范围(部门 ID 数组)")
|
||||
private List<Long> dataScopeDeptIds;
|
||||
@Schema(description = "角色排序")
|
||||
@NotNull(message = "角色排序不能为空")
|
||||
private Integer roleSort;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
@ -86,11 +80,23 @@ public class RoleRequest extends BaseRequest {
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 角色排序
|
||||
* 功能权限:菜单 ID 列表
|
||||
*/
|
||||
@Schema(description = "角色排序")
|
||||
@NotNull(message = "角色排序不能为空")
|
||||
private Integer roleSort;
|
||||
@Schema(description = "功能权限:菜单 ID 列表")
|
||||
private List<Long> menuIds;
|
||||
|
||||
/**
|
||||
* 数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)
|
||||
*/
|
||||
@Schema(description = "数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)", type = "Integer",
|
||||
allowableValues = {"1", "2", "3", "4", "5"})
|
||||
private DataScopeEnum dataScope;
|
||||
|
||||
/**
|
||||
* 权限范围:部门 ID 列表
|
||||
*/
|
||||
@Schema(description = "权限范围:部门 ID 列表")
|
||||
private List<Long> deptIds;
|
||||
|
||||
/**
|
||||
* 状态(1启用 2禁用)
|
||||
|
@ -71,19 +71,6 @@ public class RoleDetailVO extends BaseDetailVO {
|
||||
@ExcelProperty(value = "数据权限", converter = ExcelBaseEnumConverter.class)
|
||||
private DataScopeEnum dataScope;
|
||||
|
||||
/**
|
||||
* 数据权限范围(部门 ID 数组)
|
||||
*/
|
||||
@Schema(description = "数据权限范围(部门 ID 数组)")
|
||||
private List<Long> dataScopeDeptIds;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
@ExcelProperty(value = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 角色排序
|
||||
*/
|
||||
@ -97,4 +84,23 @@ public class RoleDetailVO extends BaseDetailVO {
|
||||
@Schema(description = "状态(1启用 2禁用)")
|
||||
@ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class)
|
||||
private DisEnableStatusEnum status;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
@ExcelProperty(value = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 功能权限:菜单 ID 列表
|
||||
*/
|
||||
@Schema(description = "功能权限:菜单 ID 列表")
|
||||
private List<Long> menuIds;
|
||||
|
||||
/**
|
||||
* 权限范围:部门 ID 列表
|
||||
*/
|
||||
@Schema(description = "权限范围:部门 ID 列表")
|
||||
private List<Long> deptIds;
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package top.charles7c.cnadmin.system.model.vo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -67,18 +65,6 @@ public class RoleVO extends BaseVO {
|
||||
@Schema(description = "数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)")
|
||||
private DataScopeEnum dataScope;
|
||||
|
||||
/**
|
||||
* 数据权限范围(部门 ID 数组)
|
||||
*/
|
||||
@Schema(description = "数据权限范围(部门 ID 数组)")
|
||||
private List<Long> dataScopeDeptIds;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 角色排序
|
||||
*/
|
||||
@ -91,6 +77,12 @@ public class RoleVO extends BaseVO {
|
||||
@Schema(description = "状态(1启用 2禁用)")
|
||||
private DisEnableStatusEnum status;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否禁用修改
|
||||
*/
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.system.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色和部门业务接口
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/2/19 10:40
|
||||
*/
|
||||
public interface RoleDeptService {
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @param deptIds
|
||||
* 部门 ID 列表
|
||||
* @param roleId
|
||||
* 角色 ID
|
||||
*/
|
||||
void save(List<Long> deptIds, Long roleId);
|
||||
|
||||
/**
|
||||
* 根据角色 ID 查询
|
||||
*
|
||||
* @param roleId
|
||||
* 角色 ID
|
||||
* @return 部门 ID 列表
|
||||
*/
|
||||
List<Long> listDeptIdByRoleId(Long roleId);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.system.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色和菜单业务接口
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/2/19 10:40
|
||||
*/
|
||||
public interface RoleMenuService {
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @param menuIds
|
||||
* 菜单 ID 列表
|
||||
* @param roleId
|
||||
* 角色 ID
|
||||
*/
|
||||
void save(List<Long> menuIds, Long roleId);
|
||||
|
||||
/**
|
||||
* 根据角色 ID 查询
|
||||
*
|
||||
* @param roleId
|
||||
* 角色 ID
|
||||
* @return 菜单 ID 列表
|
||||
*/
|
||||
List<Long> listMenuIdByRoleId(Long roleId);
|
||||
}
|
@ -58,14 +58,14 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO,
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(DeptRequest request) {
|
||||
public Long add(DeptRequest request) {
|
||||
String deptName = request.getDeptName();
|
||||
boolean isExists = this.checkNameExists(deptName, request.getParentId(), request.getDeptId());
|
||||
CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", deptName));
|
||||
|
||||
// 保存信息
|
||||
request.setStatus(DisEnableStatusEnum.ENABLE);
|
||||
return super.create(request);
|
||||
return super.add(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,14 +53,14 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(MenuRequest request) {
|
||||
public Long add(MenuRequest request) {
|
||||
String menuName = request.getMenuName();
|
||||
boolean isExists = this.checkNameExists(menuName, request.getParentId(), request.getMenuId());
|
||||
CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", menuName));
|
||||
|
||||
// 保存信息
|
||||
request.setStatus(DisEnableStatusEnum.ENABLE);
|
||||
return super.create(request);
|
||||
return super.add(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.system.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
|
||||
import top.charles7c.cnadmin.system.mapper.RoleDeptMapper;
|
||||
import top.charles7c.cnadmin.system.model.entity.RoleDeptDO;
|
||||
import top.charles7c.cnadmin.system.service.RoleDeptService;
|
||||
|
||||
/**
|
||||
* 角色和部门业务实现类
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/2/19 10:47
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RoleDeptServiceImpl implements RoleDeptService {
|
||||
|
||||
private final RoleDeptMapper roleDeptMapper;
|
||||
|
||||
@Override
|
||||
public void save(List<Long> deptIds, Long roleId) {
|
||||
if (CollUtil.isEmpty(deptIds)) {
|
||||
return;
|
||||
}
|
||||
// 删除原有关联
|
||||
roleDeptMapper.delete(Wrappers.<RoleDeptDO>lambdaQuery().eq(RoleDeptDO::getRoleId, roleId));
|
||||
// 保存最新关联
|
||||
List<RoleDeptDO> roleDeptList =
|
||||
deptIds.stream().map(deptId -> new RoleDeptDO(roleId, deptId)).collect(Collectors.toList());
|
||||
roleDeptMapper.insertBatch(roleDeptList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listDeptIdByRoleId(Long roleId) {
|
||||
return roleDeptMapper.selectDeptIdsByRoleId(roleId);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.cnadmin.system.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
|
||||
import top.charles7c.cnadmin.system.mapper.RoleMenuMapper;
|
||||
import top.charles7c.cnadmin.system.model.entity.RoleMenuDO;
|
||||
import top.charles7c.cnadmin.system.service.RoleMenuService;
|
||||
|
||||
/**
|
||||
* 角色和菜单业务实现类
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/2/19 10:43
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RoleMenuServiceImpl implements RoleMenuService {
|
||||
|
||||
private final RoleMenuMapper roleMenuMapper;
|
||||
|
||||
@Override
|
||||
public void save(List<Long> menuIds, Long roleId) {
|
||||
if (CollUtil.isEmpty(menuIds)) {
|
||||
return;
|
||||
}
|
||||
// 删除原有关联
|
||||
roleMenuMapper.delete(Wrappers.<RoleMenuDO>lambdaQuery().eq(RoleMenuDO::getRoleId, roleId));
|
||||
// 保存最新关联
|
||||
List<RoleMenuDO> roleMenuList =
|
||||
menuIds.stream().map(menuId -> new RoleMenuDO(roleId, menuId)).collect(Collectors.toList());
|
||||
roleMenuMapper.insertBatch(roleMenuList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listMenuIdByRoleId(Long roleId) {
|
||||
return roleMenuMapper.selectMenuIdsByRoleId(roleId);
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
package top.charles7c.cnadmin.system.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@ -24,16 +25,17 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
|
||||
import top.charles7c.cnadmin.common.consts.Constants;
|
||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
||||
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
|
||||
import top.charles7c.cnadmin.system.mapper.RoleMapper;
|
||||
import top.charles7c.cnadmin.system.model.entity.RoleDO;
|
||||
import top.charles7c.cnadmin.system.model.query.RoleQuery;
|
||||
import top.charles7c.cnadmin.system.model.request.RoleRequest;
|
||||
import top.charles7c.cnadmin.system.model.vo.MenuVO;
|
||||
import top.charles7c.cnadmin.system.model.vo.RoleDetailVO;
|
||||
import top.charles7c.cnadmin.system.model.vo.RoleVO;
|
||||
import top.charles7c.cnadmin.system.service.RoleService;
|
||||
import top.charles7c.cnadmin.system.service.UserService;
|
||||
import top.charles7c.cnadmin.system.service.*;
|
||||
|
||||
/**
|
||||
* 角色业务实现类
|
||||
@ -46,18 +48,26 @@ import top.charles7c.cnadmin.system.service.UserService;
|
||||
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO, RoleDetailVO, RoleQuery, RoleRequest>
|
||||
implements RoleService {
|
||||
|
||||
private final RoleMenuService roleMenuService;
|
||||
private final RoleDeptService roleDeptService;
|
||||
private final MenuService menuService;
|
||||
private final UserService userService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(RoleRequest request) {
|
||||
public Long add(RoleRequest request) {
|
||||
String roleName = request.getRoleName();
|
||||
boolean isExist = this.checkNameExists(roleName, request.getRoleId());
|
||||
CheckUtils.throwIf(() -> isExist, String.format("新增失败,'%s'已存在", roleName));
|
||||
|
||||
// 保存信息
|
||||
// 新增角色
|
||||
request.setStatus(DisEnableStatusEnum.ENABLE);
|
||||
return super.create(request);
|
||||
Long roleId = super.add(request);
|
||||
// 保存角色和菜单关联
|
||||
roleMenuService.save(request.getMenuIds(), roleId);
|
||||
// 保存角色和部门关联
|
||||
roleDeptService.save(request.getDeptIds(), roleId);
|
||||
return roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -67,7 +77,13 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
|
||||
boolean isExist = this.checkNameExists(roleName, request.getRoleId());
|
||||
CheckUtils.throwIf(() -> isExist, String.format("修改失败,'%s'已存在", roleName));
|
||||
|
||||
// 更新角色
|
||||
super.update(request);
|
||||
Long roleId = request.getRoleId();
|
||||
// 保存角色和菜单关联
|
||||
roleMenuService.save(request.getMenuIds(), roleId);
|
||||
// 保存角色和部门关联
|
||||
roleDeptService.save(request.getDeptIds(), roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -89,4 +105,21 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
|
||||
private boolean checkNameExists(String name, Long id) {
|
||||
return super.lambdaQuery().eq(RoleDO::getRoleName, name).ne(id != null, RoleDO::getRoleId, id).exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillDetail(Object detailObj) {
|
||||
super.fillDetail(detailObj);
|
||||
if (detailObj instanceof RoleDetailVO) {
|
||||
RoleDetailVO detailVO = (RoleDetailVO)detailObj;
|
||||
Long roleId = detailVO.getRoleId();
|
||||
if (Constants.ADMIN_ROLE_CODE.equals(detailVO.getRoleCode())) {
|
||||
List<MenuVO> list = menuService.list(null, null);
|
||||
List<Long> menuIds = list.stream().map(MenuVO::getMenuId).collect(Collectors.toList());
|
||||
detailVO.setMenuIds(menuIds);
|
||||
} else {
|
||||
detailVO.setMenuIds(roleMenuService.listMenuIdByRoleId(roleId));
|
||||
}
|
||||
detailVO.setDeptIds(roleDeptService.listDeptIdByRoleId(roleId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,11 @@ export interface RoleRecord {
|
||||
roleId?: number;
|
||||
roleName: string;
|
||||
roleCode?: string;
|
||||
dataScope: number;
|
||||
dataScopeDeptIds?: string;
|
||||
roleSort?: number;
|
||||
description?: string;
|
||||
roleSort: number;
|
||||
menuIds?: Array<number>;
|
||||
dataScope: number;
|
||||
deptIds?: Array<number>;
|
||||
status?: number;
|
||||
createUserString?: string;
|
||||
createTime?: string;
|
||||
|
@ -120,3 +120,18 @@ body {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldset {
|
||||
padding: 15px 15px 0 15px;
|
||||
margin-bottom: 15px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
}
|
||||
fieldset legend {
|
||||
color: #5e6d82;
|
||||
padding: 2px 5px 2px 5px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
}
|
@ -178,9 +178,10 @@
|
||||
</a-table>
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<a-modal
|
||||
<a-drawer
|
||||
:title="title"
|
||||
:visible="visible"
|
||||
:width="570"
|
||||
:mask-closable="false"
|
||||
unmount-on-close
|
||||
render-to-body
|
||||
@ -188,61 +189,91 @@
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item label="角色名称" field="roleName">
|
||||
<a-input v-model="form.roleName" placeholder="请输入角色名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="角色编码" field="roleCode">
|
||||
<a-input v-model="form.roleCode" placeholder="请输入角色编码" />
|
||||
</a-form-item>
|
||||
<a-form-item label="数据权限" field="dataScope">
|
||||
<a-select
|
||||
v-model="form.dataScope"
|
||||
:options="dataScopeOptions"
|
||||
placeholder="请选择数据权限"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="form.dataScope === 5"
|
||||
label="数据范围"
|
||||
field="dataScopeDeptIds"
|
||||
>
|
||||
<a-tree-select
|
||||
v-model="form.dataScopeDeptIds"
|
||||
:data="treeData"
|
||||
placeholder="请选择数据范围"
|
||||
allow-search
|
||||
allow-clear
|
||||
tree-checkable
|
||||
tree-check-strictly
|
||||
:filter-tree-node="filterDeptTree"
|
||||
:fallback-option="false"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="角色排序" field="roleSort">
|
||||
<a-input-number
|
||||
v-model="form.roleSort"
|
||||
placeholder="请输入角色排序"
|
||||
:min="1"
|
||||
mode="button"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="描述" field="description">
|
||||
<a-textarea
|
||||
v-model="form.description"
|
||||
:max-length="200"
|
||||
placeholder="请输入描述"
|
||||
:auto-size="{
|
||||
minRows: 3,
|
||||
}"
|
||||
show-word-limit
|
||||
/>
|
||||
</a-form-item>
|
||||
<fieldset>
|
||||
<legend>基础信息</legend>
|
||||
<a-form-item label="角色名称" field="roleName">
|
||||
<a-input v-model="form.roleName" placeholder="请输入角色名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="角色编码" field="roleCode">
|
||||
<a-input v-model="form.roleCode" placeholder="请输入角色编码" />
|
||||
</a-form-item>
|
||||
<a-form-item label="角色排序" field="roleSort">
|
||||
<a-input-number
|
||||
v-model="form.roleSort"
|
||||
placeholder="请输入角色排序"
|
||||
:min="1"
|
||||
mode="button"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="描述" field="description">
|
||||
<a-textarea
|
||||
v-model="form.description"
|
||||
:max-length="200"
|
||||
placeholder="请输入描述"
|
||||
:auto-size="{
|
||||
minRows: 3,
|
||||
}"
|
||||
show-word-limit
|
||||
/>
|
||||
</a-form-item>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>功能权限</legend>
|
||||
<a-form-item label="功能权限">
|
||||
<a-space style="margin-top: 2px">
|
||||
<a-checkbox v-model="menuExpandAll" @change="handleExpandAll('menu')">展开/折叠</a-checkbox>
|
||||
<a-checkbox v-model="menuCheckAll" @change="handleCheckAll('menu')">全选/全不选</a-checkbox>
|
||||
<a-checkbox v-model="menuCheckStrictly">父子联动</a-checkbox>
|
||||
</a-space>
|
||||
<template #extra>
|
||||
<a-spin v-if="menuLoading" />
|
||||
<a-tree
|
||||
v-if="!menuLoading"
|
||||
ref="menuRef"
|
||||
:data="menuOptions"
|
||||
:default-checked-keys="form.menuIds"
|
||||
:check-strictly="!menuCheckStrictly"
|
||||
:default-expand-all="menuExpandAll"
|
||||
checkable
|
||||
/>
|
||||
</template>
|
||||
</a-form-item>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>数据权限</legend>
|
||||
<a-form-item label="数据权限" field="dataScope">
|
||||
<a-select
|
||||
v-model="form.dataScope"
|
||||
:options="dataScopeOptions"
|
||||
placeholder="请选择数据权限"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.dataScope === 5" label="权限范围">
|
||||
<a-space style="margin-top: 2px">
|
||||
<a-checkbox v-model="deptExpandAll" @change="handleExpandAll('dept')">展开/折叠</a-checkbox>
|
||||
<a-checkbox v-model="deptCheckAll" @change="handleCheckAll('dept')">全选/全不选</a-checkbox>
|
||||
<a-checkbox v-model="deptCheckStrictly">父子联动</a-checkbox>
|
||||
</a-space>
|
||||
<template #extra>
|
||||
<a-spin v-if="deptLoading" />
|
||||
<a-tree
|
||||
v-if="!deptLoading"
|
||||
ref="deptRef"
|
||||
:data="deptOptions"
|
||||
:default-checked-keys="form.deptIds"
|
||||
:check-strictly="!deptCheckStrictly"
|
||||
:default-expand-all="deptExpandAll"
|
||||
checkable
|
||||
/>
|
||||
</template>
|
||||
</a-form-item>
|
||||
</fieldset>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-drawer>
|
||||
|
||||
<!-- 详情区域 -->
|
||||
<a-drawer
|
||||
title="部门详情"
|
||||
title="角色详情"
|
||||
:visible="detailVisible"
|
||||
:width="570"
|
||||
:footer="false"
|
||||
@ -250,88 +281,96 @@
|
||||
render-to-body
|
||||
@cancel="handleDetailCancel"
|
||||
>
|
||||
<a-descriptions title="基础信息" :column="2" bordered size="large">
|
||||
<a-descriptions-item label="角色名称">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.roleName }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="角色编码">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.roleCode }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>
|
||||
<a-tag v-if="role.status === 1" color="green">启用</a-tag>
|
||||
<a-tag v-else color="red">禁用</a-tag>
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="数据权限">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>
|
||||
<span v-if="role.dataScope === 1">全部数据权限</span>
|
||||
<span v-else-if="role.dataScope === 2">本部门及以下数据权限</span>
|
||||
<span v-else-if="role.dataScope === 3">本部门数据权限</span>
|
||||
<span v-else-if="role.dataScope === 4">仅本人数据权限</span>
|
||||
<span v-else>自定义数据权限</span>
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建人">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.createUserString }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.createTime }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="修改人">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.updateUserString }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="修改时间">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.updateTime }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="描述">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.description }}</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-descriptions
|
||||
<a-card title="基础信息" :bordered="false">
|
||||
<a-descriptions :column="2" bordered size="large">
|
||||
<a-descriptions-item label="角色名称">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.roleName }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="角色编码">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.roleCode }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>
|
||||
<a-tag v-if="role.status === 1" color="green">启用</a-tag>
|
||||
<a-tag v-else color="red">禁用</a-tag>
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="数据权限">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>
|
||||
<span v-if="role.dataScope === 1">全部数据权限</span>
|
||||
<span v-else-if="role.dataScope === 2">本部门及以下数据权限</span>
|
||||
<span v-else-if="role.dataScope === 3">本部门数据权限</span>
|
||||
<span v-else-if="role.dataScope === 4">仅本人数据权限</span>
|
||||
<span v-else>自定义数据权限</span>
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建人">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.createUserString }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.createTime }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="修改人">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.updateUserString }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="修改时间">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.updateTime }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="描述">
|
||||
<a-skeleton v-if="detailLoading" :animation="true">
|
||||
<a-skeleton-line :rows="1" />
|
||||
</a-skeleton>
|
||||
<span v-else>{{ role.description }}</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<a-card :loading="menuLoading" title="功能权限" :bordered="false">
|
||||
<a-tree
|
||||
:data="menuOptions"
|
||||
:checked-keys="role.menuIds"
|
||||
:default-expand-all="false"
|
||||
check-strictly
|
||||
checkable
|
||||
/>
|
||||
</a-card>
|
||||
<a-card
|
||||
v-if="role.dataScope === 5"
|
||||
:loading="deptLoading"
|
||||
title="数据权限"
|
||||
:column="2"
|
||||
bordered
|
||||
size="large"
|
||||
style="margin-top: 25px"
|
||||
:bordered="false"
|
||||
>
|
||||
<a-descriptions-item label="数据范围">
|
||||
<a-tree-select
|
||||
v-model="role.dataScopeDeptIds"
|
||||
:data="treeData"
|
||||
tree-checkable
|
||||
disabled
|
||||
/>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-tree
|
||||
:data="deptOptions"
|
||||
:checked-keys="role.deptIds"
|
||||
default-expand-all
|
||||
check-strictly
|
||||
checkable
|
||||
/>
|
||||
</a-card>
|
||||
</a-drawer>
|
||||
</a-card>
|
||||
</div>
|
||||
@ -349,7 +388,7 @@
|
||||
updateRole,
|
||||
deleteRole,
|
||||
} from '@/api/system/role';
|
||||
import { listDeptTree } from '@/api/common';
|
||||
import { listMenuTree, listDeptTree } from '@/api/common';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
|
||||
@ -357,14 +396,15 @@
|
||||
const role = ref<RoleRecord>({
|
||||
roleName: '',
|
||||
roleCode: '',
|
||||
dataScope: 1,
|
||||
description: '',
|
||||
roleSort: 0,
|
||||
status: 1,
|
||||
dataScope: 1,
|
||||
createUserString: '',
|
||||
createTime: '',
|
||||
updateUserString: '',
|
||||
updateTime: '',
|
||||
description: '',
|
||||
menuIds: undefined,
|
||||
deptIds: undefined,
|
||||
});
|
||||
const total = ref(0);
|
||||
const ids = ref<Array<number>>([]);
|
||||
@ -388,7 +428,16 @@
|
||||
{ label: '仅本人数据权限', value: 4 },
|
||||
{ label: '自定义数据权限', value: 5 },
|
||||
]);
|
||||
const treeData = ref<TreeNodeData[]>();
|
||||
const menuLoading = ref(false);
|
||||
const deptLoading = ref(false);
|
||||
const menuOptions = ref<TreeNodeData[]>([]);
|
||||
const deptOptions = ref<TreeNodeData[]>([]);
|
||||
const menuExpandAll = ref(false);
|
||||
const deptExpandAll = ref(true);
|
||||
const menuCheckAll = ref(false);
|
||||
const deptCheckAll = ref(false);
|
||||
const menuCheckStrictly = ref(true);
|
||||
const deptCheckStrictly = ref(true);
|
||||
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
@ -405,7 +454,6 @@
|
||||
rules: {
|
||||
roleName: [{ required: true, message: '请输入角色名称' }],
|
||||
dataScope: [{ required: true, message: '请选择数据权限' }],
|
||||
dataScopeDeptIds: [{ required: true, message: '请选择数据范围' }],
|
||||
roleSort: [{ required: true, message: '请输入角色排序' }],
|
||||
},
|
||||
});
|
||||
@ -434,11 +482,10 @@
|
||||
*/
|
||||
const toCreate = () => {
|
||||
reset();
|
||||
listDeptTree({ status: 1 }).then((res) => {
|
||||
treeData.value = res.data;
|
||||
});
|
||||
getMenuTree();
|
||||
title.value = '新增角色';
|
||||
visible.value = true;
|
||||
getDeptTree();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -448,9 +495,10 @@
|
||||
*/
|
||||
const toUpdate = (id: number) => {
|
||||
reset();
|
||||
listDeptTree({}).then((res) => {
|
||||
treeData.value = res.data;
|
||||
});
|
||||
menuCheckStrictly.value = false;
|
||||
deptCheckStrictly.value = false;
|
||||
getMenuTree();
|
||||
getDeptTree();
|
||||
getRole(id).then((res) => {
|
||||
form.value = res.data;
|
||||
title.value = '修改角色';
|
||||
@ -458,19 +506,60 @@
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询菜单树
|
||||
*/
|
||||
const getMenuTree = () => {
|
||||
if (menuOptions.value.length <= 0) {
|
||||
menuLoading.value = true;
|
||||
}
|
||||
listMenuTree({})
|
||||
.then((res) => {
|
||||
menuOptions.value = res.data;
|
||||
})
|
||||
.finally(() => {
|
||||
menuLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询部门树
|
||||
*/
|
||||
const getDeptTree = () => {
|
||||
if (deptOptions.value.length <= 0) {
|
||||
deptLoading.value = true;
|
||||
}
|
||||
listDeptTree({})
|
||||
.then((res) => {
|
||||
deptOptions.value = res.data;
|
||||
})
|
||||
.finally(() => {
|
||||
deptLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
const reset = () => {
|
||||
menuExpandAll.value = false;
|
||||
menuCheckAll.value = false;
|
||||
menuCheckStrictly.value = true;
|
||||
deptExpandAll.value = true;
|
||||
deptCheckAll.value = false;
|
||||
deptCheckStrictly.value = true;
|
||||
proxy.$refs.menuRef?.expandAll(menuExpandAll.value);
|
||||
proxy.$refs.deptRef?.expandAll(deptExpandAll.value);
|
||||
form.value = {
|
||||
roleId: undefined,
|
||||
roleName: '',
|
||||
roleCode: undefined,
|
||||
dataScope: 4,
|
||||
dataScopeDeptIds: undefined,
|
||||
description: '',
|
||||
roleSort: 999,
|
||||
status: 1,
|
||||
menuIds: [],
|
||||
deptIds: [],
|
||||
};
|
||||
proxy.$refs.formRef?.resetFields();
|
||||
};
|
||||
@ -483,6 +572,38 @@
|
||||
proxy.$refs.formRef.resetFields();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取所有选中的菜单
|
||||
*/
|
||||
const getMenuAllCheckedKeys = () => {
|
||||
// 获取目前被选中的菜单
|
||||
const checkedNodes = proxy.$refs.menuRef.getCheckedNodes();
|
||||
const checkedKeys = checkedNodes.map((item: TreeNodeData) => item.key);
|
||||
|
||||
// 获取半选中的菜单
|
||||
const halfCheckedNodes = proxy.$refs.menuRef.getHalfCheckedNodes();
|
||||
const halfCheckedKeys = halfCheckedNodes.map((item: TreeNodeData) => item.key);
|
||||
// eslint-disable-next-line prefer-spread
|
||||
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
|
||||
return checkedKeys;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取所有选中的部门
|
||||
*/
|
||||
const getDeptAllCheckedKeys = () => {
|
||||
// 获取目前被选中的部门
|
||||
const checkedNodes = proxy.$refs.deptRef.getCheckedNodes();
|
||||
const checkedKeys = checkedNodes.map((item: TreeNodeData) => item.key);
|
||||
|
||||
// 获取半选中的部门
|
||||
const halfCheckedNodes = proxy.$refs.deptRef.getHalfCheckedNodes();
|
||||
const halfCheckedKeys = halfCheckedNodes.map((item: TreeNodeData) => item.key);
|
||||
// eslint-disable-next-line prefer-spread
|
||||
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
|
||||
return checkedKeys;
|
||||
};
|
||||
|
||||
/**
|
||||
* 确定
|
||||
*/
|
||||
@ -490,12 +611,16 @@
|
||||
proxy.$refs.formRef.validate((valid: any) => {
|
||||
if (!valid) {
|
||||
if (form.value.roleId !== undefined) {
|
||||
form.value.menuIds = getMenuAllCheckedKeys();
|
||||
form.value.deptIds = getDeptAllCheckedKeys();
|
||||
updateRole(form.value).then((res) => {
|
||||
handleCancel();
|
||||
getList();
|
||||
proxy.$message.success(res.msg);
|
||||
});
|
||||
} else {
|
||||
form.value.menuIds = getMenuAllCheckedKeys();
|
||||
form.value.deptIds = getDeptAllCheckedKeys();
|
||||
createRole(form.value).then((res) => {
|
||||
handleCancel();
|
||||
getList();
|
||||
@ -513,6 +638,8 @@
|
||||
*/
|
||||
const toDetail = async (id: number) => {
|
||||
if (detailLoading.value) return;
|
||||
getMenuTree();
|
||||
getDeptTree();
|
||||
detailLoading.value = true;
|
||||
detailVisible.value = true;
|
||||
getRole(id)
|
||||
@ -603,18 +730,29 @@
|
||||
};
|
||||
|
||||
/**
|
||||
* 过滤部门树
|
||||
* 展开/折叠
|
||||
*
|
||||
* @param searchValue 搜索值
|
||||
* @param nodeData 节点值
|
||||
* @param type 类型(菜单/部门)
|
||||
*/
|
||||
const filterDeptTree = (searchValue: string, nodeData: TreeNodeData) => {
|
||||
if (nodeData.title) {
|
||||
return (
|
||||
nodeData.title.toLowerCase().indexOf(searchValue.toLowerCase()) > -1
|
||||
);
|
||||
const handleExpandAll = (type: string) => {
|
||||
if (type === 'menu') {
|
||||
proxy.$refs.menuRef.expandAll(menuExpandAll.value);
|
||||
} else if (type === 'dept') {
|
||||
proxy.$refs.deptRef.expandAll(deptExpandAll.value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 全选/全不选
|
||||
*
|
||||
* @param type 类型(菜单/部门)
|
||||
*/
|
||||
const handleCheckAll = (type: string) => {
|
||||
if (type === 'menu') {
|
||||
proxy.$refs.menuRef.checkAll(menuCheckAll.value);
|
||||
} else if (type === 'dept') {
|
||||
proxy.$refs.deptRef.checkAll(deptCheckAll.value);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -44,7 +44,7 @@ import top.charles7c.cnadmin.system.service.DeptService;
|
||||
*/
|
||||
@Tag(name = "部门管理 API")
|
||||
@RestController
|
||||
@CrudRequestMapping(value = "/system/dept", api = {Api.LIST, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
|
||||
@CrudRequestMapping(value = "/system/dept", api = {Api.LIST, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
|
||||
public class DeptController extends BaseController<DeptService, DeptVO, DeptDetailVO, DeptQuery, DeptRequest> {
|
||||
|
||||
@Override
|
||||
|
@ -43,7 +43,7 @@ import top.charles7c.cnadmin.system.service.MenuService;
|
||||
*/
|
||||
@Tag(name = "菜单管理 API")
|
||||
@RestController
|
||||
@CrudRequestMapping(value = "/system/menu", api = {Api.LIST, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
|
||||
@CrudRequestMapping(value = "/system/menu", api = {Api.LIST, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
|
||||
public class MenuController extends BaseController<MenuService, MenuVO, MenuVO, MenuQuery, MenuRequest> {
|
||||
|
||||
@Override
|
||||
|
@ -1,28 +1,6 @@
|
||||
-- liquibase formatted sql
|
||||
|
||||
-- changeset Charles7c:1
|
||||
-- 初始化默认部门
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (1, 'Xxx科技有限公司', 0, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (2, '天津总部', 1, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (3, '研发部', 2, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (4, 'UI部', 2, '系统初始部门', 2, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (5, '测试部', 2, '系统初始部门', 3, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (6, '运维部', 2, '系统初始部门', 4, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (7, '研发一组', 3, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (8, '研发二组', 3, '系统初始部门', 2, 2, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认用户:admin/admin123;test/123456
|
||||
INSERT IGNORE INTO `sys_user` VALUES (1, 'admin', '超级管理员', '9802815bcc5baae7feb1ae0d0566baf2', 1, '18888888888', 'charles7c@126.com', NULL, '系统初始用户', 1, NOW(), 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_user` VALUES (2, 'test', '测试员', '8e114197e1b33783a00542ad67e80516', 0, NULL, NULL, NULL, '系统初始用户', 2, NOW(), 2, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认角色
|
||||
INSERT IGNORE INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, NULL, '系统初始角色', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_role` VALUES (2, '测试人员', 'test', 4, NULL, '系统初始角色', 2, 2, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认用户和角色关联数据
|
||||
INSERT IGNORE INTO `sys_user_role` VALUES (1, 1);
|
||||
INSERT IGNORE INTO `sys_user_role` VALUES (2, 2);
|
||||
|
||||
-- 初始化默认菜单
|
||||
INSERT IGNORE INTO `sys_menu` VALUES (1000, '系统管理', 0, 1, 'system', NULL, NULL, 'settings', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_menu` VALUES (1010, '角色管理', 1000, 2, '/system/role', 'Role', 'system/role/index', NULL, b'0', b'0', b'0', 'system:role:list', 2, 1, 1, NOW(), 1, NOW());
|
||||
@ -48,3 +26,46 @@ INSERT IGNORE INTO `sys_menu` VALUES (2050, '操作日志', 2000, 2, '/monitor/l
|
||||
INSERT IGNORE INTO `sys_menu` VALUES (2070, '系统日志', 2000, 2, '/monitor/log/system', 'SystemLog', 'monitor/log/system/index', NULL, b'0', b'0', b'0', 'monitor:log:system:list', 4, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_menu` VALUES (10000, 'Arco Design Vue', 0, 1, 'https://arco.design/vue/docs/start', NULL, NULL, 'link', b'1', b'0', b'0', NULL, 100, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_menu` VALUES (10001, 'GitHub', 0, 1, 'https://github.com/Charles7c/continew-admin', NULL, NULL, 'github', b'1', b'0', b'0', NULL, 101, 1, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认部门
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (1, 'Xxx科技有限公司', 0, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (2, '天津总部', 1, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (3, '研发部', 2, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (4, 'UI部', 2, '系统初始部门', 2, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (5, '测试部', 2, '系统初始部门', 3, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (6, '运维部', 2, '系统初始部门', 4, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (7, '研发一组', 3, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_dept` VALUES (8, '研发二组', 3, '系统初始部门', 2, 2, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认角色
|
||||
INSERT IGNORE INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '系统初始角色', 1, 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_role` VALUES (2, '测试人员', 'test', 5, '系统初始角色', 2, 2, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认用户:admin/admin123;test/123456
|
||||
INSERT IGNORE INTO `sys_user` VALUES (1, 'admin', '超级管理员', '9802815bcc5baae7feb1ae0d0566baf2', 1, '18888888888', 'charles7c@126.com', NULL, '系统初始用户', 1, NOW(), 1, 1, NOW(), 1, NOW());
|
||||
INSERT IGNORE INTO `sys_user` VALUES (2, 'test', '测试员', '8e114197e1b33783a00542ad67e80516', 0, NULL, NULL, NULL, '系统初始用户', 2, NOW(), 2, 1, NOW(), 1, NOW());
|
||||
|
||||
-- 初始化默认角色和菜单关联数据
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1000);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1010);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1011);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1012);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1013);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1014);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1030);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1031);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1032);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1033);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1034);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1050);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1051);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1052);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1053);
|
||||
INSERT INTO `sys_role_menu` VALUES (2, 1054);
|
||||
|
||||
-- 初始化默认角色和部门关联数据
|
||||
INSERT INTO `sys_role_dept` VALUES (2, 5);
|
||||
|
||||
-- 初始化默认用户和角色关联数据
|
||||
INSERT IGNORE INTO `sys_user_role` VALUES (1, 1);
|
||||
INSERT IGNORE INTO `sys_user_role` VALUES (2, 2);
|
@ -1,6 +1,31 @@
|
||||
-- liquibase formatted sql
|
||||
|
||||
-- changeset Charles7c:1
|
||||
CREATE TABLE IF NOT EXISTS `sys_menu` (
|
||||
`menu_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '菜单ID',
|
||||
`menu_name` varchar(255) NOT NULL COMMENT '菜单名称',
|
||||
`parent_id` bigint(20) unsigned DEFAULT 0 COMMENT '上级菜单ID',
|
||||
`menu_type` tinyint(1) unsigned DEFAULT 1 COMMENT '菜单类型(1目录 2菜单 3按钮)',
|
||||
`path` varchar(512) DEFAULT NULL COMMENT '路由地址',
|
||||
`name` varchar(255) DEFAULT NULL COMMENT '组件名称',
|
||||
`component` varchar(255) DEFAULT NULL COMMENT '组件路径',
|
||||
`icon` varchar(255) DEFAULT NULL COMMENT '菜单图标',
|
||||
`is_external` bit(1) DEFAULT b'0' COMMENT '是否外链',
|
||||
`is_cache` bit(1) DEFAULT b'0' COMMENT '是否缓存',
|
||||
`is_hidden` bit(1) DEFAULT b'0' COMMENT '是否隐藏',
|
||||
`permission` varchar(255) DEFAULT NULL COMMENT '权限标识',
|
||||
`menu_sort` int(11) unsigned DEFAULT 999 COMMENT '菜单排序',
|
||||
`status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
|
||||
`create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) unsigned NOT NULL COMMENT '修改人',
|
||||
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`menu_id`) USING BTREE,
|
||||
INDEX `idx_parent_id`(`parent_id`) USING BTREE,
|
||||
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜单表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_dept` (
|
||||
`dept_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '部门ID',
|
||||
`dept_name` varchar(255) NOT NULL COMMENT '部门名称',
|
||||
@ -18,6 +43,35 @@ CREATE TABLE IF NOT EXISTS `sys_dept` (
|
||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_role` (
|
||||
`role_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '角色ID',
|
||||
`role_name` varchar(255) NOT NULL COMMENT '角色名称',
|
||||
`role_code` varchar(255) DEFAULT NULL COMMENT '角色编码',
|
||||
`data_scope` tinyint(1) DEFAULT 4 COMMENT '数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)',
|
||||
`description` varchar(512) DEFAULT NULL COMMENT '描述',
|
||||
`role_sort` int(11) unsigned DEFAULT 999 COMMENT '角色排序',
|
||||
`status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
|
||||
`create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) unsigned NOT NULL COMMENT '修改人',
|
||||
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`role_id`) USING BTREE,
|
||||
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_role_menu` (
|
||||
`role_id` bigint(20) unsigned NOT NULL COMMENT '角色ID',
|
||||
`menu_id` bigint(20) unsigned NOT NULL COMMENT '菜单ID',
|
||||
PRIMARY KEY (`role_id`,`menu_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和菜单关联表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_role_dept` (
|
||||
`role_id` bigint(20) unsigned NOT NULL COMMENT '角色ID',
|
||||
`dept_id` bigint(20) unsigned NOT NULL COMMENT '部门ID',
|
||||
PRIMARY KEY (`role_id`,`dept_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和部门关联表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_user` (
|
||||
`user_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '用户ID',
|
||||
`username` varchar(255) NOT NULL COMMENT '用户名',
|
||||
@ -43,61 +97,12 @@ CREATE TABLE IF NOT EXISTS `sys_user` (
|
||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_role` (
|
||||
`role_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '角色ID',
|
||||
`role_name` varchar(255) NOT NULL COMMENT '角色名称',
|
||||
`role_code` varchar(255) DEFAULT NULL COMMENT '角色编码',
|
||||
`data_scope` tinyint(1) DEFAULT 4 COMMENT '数据权限(1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限 5自定义数据权限)',
|
||||
`data_scope_dept_ids` json DEFAULT NULL COMMENT '数据权限范围(部门ID数组)',
|
||||
`description` varchar(512) DEFAULT NULL COMMENT '描述',
|
||||
`role_sort` int(11) unsigned DEFAULT 999 COMMENT '角色排序',
|
||||
`status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
|
||||
`create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) unsigned NOT NULL COMMENT '修改人',
|
||||
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`role_id`) USING BTREE,
|
||||
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_user_role` (
|
||||
`user_id` bigint(20) unsigned NOT NULL COMMENT '用户ID',
|
||||
`role_id` bigint(20) unsigned NOT NULL COMMENT '角色ID',
|
||||
PRIMARY KEY (`user_id`,`role_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和角色关联表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_menu` (
|
||||
`menu_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '菜单ID',
|
||||
`menu_name` varchar(255) NOT NULL COMMENT '菜单名称',
|
||||
`parent_id` bigint(20) unsigned DEFAULT 0 COMMENT '上级菜单ID',
|
||||
`menu_type` tinyint(1) unsigned DEFAULT 1 COMMENT '菜单类型(1目录 2菜单 3按钮)',
|
||||
`path` varchar(512) DEFAULT NULL COMMENT '路由地址',
|
||||
`name` varchar(255) DEFAULT NULL COMMENT '组件名称',
|
||||
`component` varchar(255) DEFAULT NULL COMMENT '组件路径',
|
||||
`icon` varchar(255) DEFAULT NULL COMMENT '菜单图标',
|
||||
`is_external` bit(1) DEFAULT b'0' COMMENT '是否外链',
|
||||
`is_cache` bit(1) DEFAULT b'0' COMMENT '是否缓存',
|
||||
`is_hidden` bit(1) DEFAULT b'0' COMMENT '是否隐藏',
|
||||
`permission` varchar(255) DEFAULT NULL COMMENT '权限标识',
|
||||
`menu_sort` int(11) unsigned DEFAULT 999 COMMENT '菜单排序',
|
||||
`status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
|
||||
`create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) unsigned NOT NULL COMMENT '修改人',
|
||||
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`menu_id`) USING BTREE,
|
||||
INDEX `idx_parent_id`(`parent_id`) USING BTREE,
|
||||
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜单表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_role_menu` (
|
||||
`role_id` bigint(20) unsigned NOT NULL COMMENT '角色ID',
|
||||
`menu_id` bigint(20) unsigned NOT NULL COMMENT '菜单ID',
|
||||
PRIMARY KEY (`role_id`,`menu_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和菜单关联表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sys_log` (
|
||||
`log_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '日志ID',
|
||||
`description` varchar(255) NOT NULL COMMENT '日志描述',
|
||||
|
Loading…
Reference in New Issue
Block a user