diff --git a/backend/application/settings.py b/backend/application/settings.py index 1d0adf79b43c695cbb576518c213ea2837303a07..e6bdec5eaa5fa6bc0778592ace87c8da995262ef 100644 --- a/backend/application/settings.py +++ b/backend/application/settings.py @@ -404,7 +404,7 @@ PLUGINS_URL_PATTERNS = [] # ********** 一键导入插件配置开始 ********** # 例如: # from dvadmin_upgrade_center.settings import * # 升级中心 -from dvadmin3_celery.settings import * # celery 异步任务 +# from dvadmin3_celery.settings import * # celery 异步任务 # from dvadmin_third.settings import * # 第三方用户管理 # from dvadmin_ak_sk.settings import * # 秘钥管理管理 # from dvadmin_tenants.settings import * # 租户管理 diff --git a/backend/dvadmin/system/views/role_menu_button_permission.py b/backend/dvadmin/system/views/role_menu_button_permission.py index 3ee596df38d01d44393910c881c6749c422ae446..723cd2a6a4af20c6d1c2b983c7d0e17d4b7383c4 100644 --- a/backend/dvadmin/system/views/role_menu_button_permission.py +++ b/backend/dvadmin/system/views/role_menu_button_permission.py @@ -6,24 +6,20 @@ @Created on: 2021/6/3 003 0:30 @Remark: 菜单按钮管理 """ -from django.db.models import F, Subquery, OuterRef, Exists, BooleanField, Q, Case, Value, When -from django.db.models.functions import Coalesce from rest_framework import serializers from rest_framework.decorators import action -from rest_framework.fields import ListField from rest_framework.permissions import IsAuthenticated -from dvadmin.system.models import RoleMenuButtonPermission, Menu, MenuButton, Dept, RoleMenuPermission, FieldPermission, \ - MenuField -from dvadmin.system.views.menu import MenuSerializer -from dvadmin.utils.json_response import DetailResponse, ErrorResponse +from dvadmin.system.models import RoleMenuButtonPermission, Menu, Dept, MenuButton, RoleMenuPermission, \ + MenuField, FieldPermission +from dvadmin.utils.json_response import DetailResponse from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.viewset import CustomModelViewSet class RoleMenuButtonPermissionSerializer(CustomModelSerializer): """ - 菜单按钮-序列化器 + 角色-菜单-按钮-权限 查询序列化 """ class Meta: @@ -34,7 +30,7 @@ class RoleMenuButtonPermissionSerializer(CustomModelSerializer): class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer): """ - 初始化菜单按钮-序列化器 + 角色-菜单-按钮-权限 创建/修改序列化 """ menu_button__name = serializers.CharField(source='menu_button.name', read_only=True) menu_button__value = serializers.CharField(source='menu_button.value', read_only=True) @@ -45,63 +41,99 @@ class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer): read_only_fields = ["id"] -class RoleButtonPermissionSerializer(CustomModelSerializer): +class RoleMenuSerializer(CustomModelSerializer): + """ + 角色-菜单 序列化 + """ + isCheck = serializers.SerializerMethodField() + + def get_isCheck(self, instance): + params = self.request.query_params + data = self.request.data + return RoleMenuPermission.objects.filter( + menu_id=instance.id, + role_id=params.get('roleId', data.get('roleId')), + ).exists() + + class Meta: + model = Menu + fields = ["id", "name", "parent", "is_catalog", "isCheck"] + + +class RoleMenuButtonSerializer(CustomModelSerializer): """ - 角色按钮权限 + 角色-菜单-按钮 序列化 """ isCheck = serializers.SerializerMethodField() data_range = serializers.SerializerMethodField() + role_menu_btn_perm_id = serializers.SerializerMethodField() + dept = serializers.SerializerMethodField() def get_isCheck(self, instance): params = self.request.query_params + data = self.request.data return RoleMenuButtonPermission.objects.filter( - menu_button__id=instance['id'], - role__id=params.get('role'), + menu_button_id=instance.id, + role_id=params.get('roleId', data.get('roleId')), ).exists() def get_data_range(self, instance): - params = self.request.query_params - obj = RoleMenuButtonPermission.objects.filter( - menu_button__id=instance['id'], - role__id=params.get('role'), - ).first() + obj = self.get_role_menu_btn_prem(instance) if obj is None: return None return obj.data_range - class Meta: - model = MenuButton - fields = ['id', 'name', 'value', 'isCheck', 'data_range'] + def get_role_menu_btn_perm_id(self, instance): + obj = self.get_role_menu_btn_prem(instance) + if obj is None: + return None + return obj.id + def get_dept(self, instance): + obj = self.get_role_menu_btn_prem(instance) + if obj is None: + return None + return obj.dept.all().values_list('id', flat=True) + + def get_role_menu_btn_prem(self, instance): + params = self.request.query_params + data = self.request.data + obj = RoleMenuButtonPermission.objects.filter( + menu_button_id=instance.id, + role_id=params.get('roleId', data.get('roleId')), + ).first() + return obj -class RoleFieldPermissionSerializer(CustomModelSerializer): class Meta: - model = FieldPermission - fields = "__all__" + model = MenuButton + fields = ['id', 'menu', 'name', 'isCheck', 'data_range', 'role_menu_btn_perm_id', 'dept'] class RoleMenuFieldSerializer(CustomModelSerializer): + """ + 角色-菜单-字段 序列化 + """ is_query = serializers.SerializerMethodField() is_create = serializers.SerializerMethodField() is_update = serializers.SerializerMethodField() def get_is_query(self, instance): params = self.request.query_params - queryset = instance.menu_field.filter(role=params.get('role')).first() + queryset = instance.menu_field.filter(role=params.get('roleId')).first() if queryset: return queryset.is_query return False def get_is_create(self, instance): params = self.request.query_params - queryset = instance.menu_field.filter(role=params.get('role')).first() + queryset = instance.menu_field.filter(role=params.get('roleId')).first() if queryset: return queryset.is_create return False def get_is_update(self, instance): params = self.request.query_params - queryset = instance.menu_field.filter(role=params.get('role')).first() + queryset = instance.menu_field.filter(role=params.get('roleId')).first() if queryset: return queryset.is_update return False @@ -111,54 +143,6 @@ class RoleMenuFieldSerializer(CustomModelSerializer): fields = ['id', 'field_name', 'title', 'is_query', 'is_create', 'is_update'] -class RoleMenuSerializer(CustomModelSerializer): - menus = serializers.SerializerMethodField() - - def get_menus(self, instance): - menu_list = Menu.objects.filter(parent=instance['id']).values('id', 'name') - serializer = RoleMenuPermissionSerializer(menu_list, many=True, request=self.request) - return serializer.data - - class Meta: - model = Menu - fields = ['id', 'name', 'menus'] - - -class RoleMenuPermissionSerializer(CustomModelSerializer): - """ - 菜单和按钮权限 - """ - # name = serializers.SerializerMethodField() - isCheck = serializers.SerializerMethodField() - btns = serializers.SerializerMethodField() - columns = serializers.SerializerMethodField() - - # def get_name(self, instance): - # parent_list = Menu.get_all_parent(instance['id']) - # names = [d["name"] for d in parent_list] - # return "/".join(names) - def get_isCheck(self, instance): - params = self.request.query_params - return RoleMenuPermission.objects.filter( - menu__id=instance['id'], - role__id=params.get('role'), - ).exists() - - def get_btns(self, instance): - btn_list = MenuButton.objects.filter(menu__id=instance['id']).values('id', 'name', 'value') - serializer = RoleButtonPermissionSerializer(btn_list, many=True, request=self.request) - return serializer.data - - def get_columns(self, instance): - col_list = MenuField.objects.filter(menu=instance['id']) - serializer = RoleMenuFieldSerializer(col_list, many=True, request=self.request) - return serializer.data - - class Meta: - model = Menu - fields = ['id', 'name', 'isCheck', 'btns', 'columns'] - - class RoleMenuButtonPermissionViewSet(CustomModelViewSet): """ 菜单按钮接口 @@ -174,202 +158,103 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet): update_serializer_class = RoleMenuButtonPermissionCreateUpdateSerializer extra_filter_class = [] - # @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) - # def get_role_premission(self, request): - # """ - # 角色授权获取: - # :param request: role - # :return: menu,btns,columns - # """ - # params = request.query_params - # is_superuser = request.user.is_superuser - # if is_superuser: - # queryset = Menu.objects.filter(status=1, is_catalog=True).values('name', 'id').all() - # else: - # role_id = request.user.role.values_list('id', flat=True) - # menu_list = RoleMenuPermission.objects.filter(role__in=role_id).values_list('menu__id', flat=True) - # queryset = Menu.objects.filter(status=1, is_catalog=True, id__in=menu_list).values('name', 'id').all() - # serializer = RoleMenuSerializer(queryset, many=True, request=request) - # data = serializer.data - # return DetailResponse(data=data) - @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) - def get_role_permission(self, request): - params = request.query_params - # 需要授权的角色信息 - current_role = params.get('role', None) - # 当前登录用户的角色 - role_list = request.user.role.values_list('id', flat=True) - if current_role is None: - return ErrorResponse(msg='参数错误') - is_superuser = request.user.is_superuser - if is_superuser: - menu_queryset = Menu.objects.prefetch_related('menuPermission').prefetch_related( - 'menufield_set') - else: - role_id_list = request.user.role.values_list('id', flat=True) - menu_list = RoleMenuPermission.objects.filter(role__in=role_id_list).values_list('menu__id', flat=True) - - # 当前角色已授权的菜单 - menu_queryset = Menu.objects.filter(id__in=menu_list).prefetch_related('menuPermission').prefetch_related( - 'menufield_set') - result = [] - for menu_item in menu_queryset: - isCheck = RoleMenuPermission.objects.filter( - menu_id=menu_item.id, - role_id=current_role - ).exists() - dicts = { - 'name': menu_item.name, - 'id': menu_item.id, - 'parent': menu_item.parent.id if menu_item.parent else None, - 'isCheck': isCheck, - 'btns': [], - 'columns': [] - } - for mb_item in menu_item.menuPermission.all(): - rolemenubuttonpermission_queryset = RoleMenuButtonPermission.objects.filter( - menu_button_id=mb_item.id, - role_id=current_role - ).first() - dicts['btns'].append( - { - 'id': mb_item.id, - 'name': mb_item.name, - 'value': mb_item.value, - 'data_range': rolemenubuttonpermission_queryset.data_range - if rolemenubuttonpermission_queryset - else None, - 'isCheck': bool(rolemenubuttonpermission_queryset), - 'dept': rolemenubuttonpermission_queryset.dept.all().values_list('id', flat=True) - if rolemenubuttonpermission_queryset - else [], - } - ) - for column_item in menu_item.menufield_set.all(): - # 需要授权角色已拥有的列权限 - fieldpermission_queryset = column_item.menu_field.filter(role_id=current_role).first() - is_query = fieldpermission_queryset.is_query if fieldpermission_queryset else False - is_create = fieldpermission_queryset.is_create if fieldpermission_queryset else False - is_update = fieldpermission_queryset.is_update if fieldpermission_queryset else False - # 当前登录用户角色可分配的列权限 - fieldpermission_queryset_disabled = column_item.menu_field.filter(role_id__in=role_list).first() - disabled_query = fieldpermission_queryset_disabled.is_query if fieldpermission_queryset_disabled else True - disabled_create = fieldpermission_queryset_disabled.is_create if fieldpermission_queryset_disabled else True - disabled_update = fieldpermission_queryset_disabled.is_update if fieldpermission_queryset_disabled else True - - dicts['columns'].append({ - 'id': column_item.id, - 'field_name': column_item.field_name, - 'title': column_item.title, - 'is_query': is_query, - 'is_create': is_create, - 'is_update': is_update, - 'disabled_query': False if is_superuser else not disabled_query, - 'disabled_create': False if is_superuser else not disabled_create, - 'disabled_update': False if is_superuser else not disabled_update, - }) - result.append(dicts) - return DetailResponse(data=result) - - @action(methods=['PUT'], detail=True, permission_classes=[IsAuthenticated]) - def set_role_premission(self, request, pk): + def get_role_menu(self, request): """ - 对角色的菜单和按钮及按钮范围授权: + 获取 角色-菜单 :param request: - :param pk: role :return: """ - body = request.data - RoleMenuPermission.objects.filter(role=pk).delete() - RoleMenuButtonPermission.objects.filter(role=pk).delete() - for item in body: - if item.get('isCheck'): - RoleMenuPermission.objects.create(role_id=pk, menu_id=item["id"]) - for btn in item.get('btns'): - if btn.get('isCheck'): - data_range = btn.get('data_range', 0) or 0 - instance = RoleMenuButtonPermission.objects.create(role_id=pk, menu_button_id=btn.get('id'), - data_range=data_range) - instance.dept.set(btn.get('dept', [])) - for col in item.get('columns'): - FieldPermission.objects.update_or_create(role_id=pk, field_id=col.get('id'), - defaults={ - 'is_query': col.get('is_query'), - 'is_create': col.get('is_create'), - 'is_update': col.get('is_update') - }) - return DetailResponse(msg="授权成功") + menu_queryset = Menu.objects.all() + serializer = RoleMenuSerializer(menu_queryset, many=True, request=request) + return DetailResponse(data=serializer.data) - @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) - def role_menu_get_button(self, request): + @action(methods=['PUT'], detail=False, permission_classes=[IsAuthenticated]) + def set_role_menu(self, request): """ - 当前用户角色和菜单获取可下拉选项的按钮:角色授权页面使用 + 设置 角色-菜单 :param request: :return: """ - if params := request.query_params: - if menu_id := params.get('menu', None): - is_superuser = request.user.is_superuser - if is_superuser: - queryset = MenuButton.objects.filter(menu=menu_id).values('id', 'name') - else: - role_list = request.user.role.values_list('id', flat=True) - queryset = RoleMenuButtonPermission.objects.filter( - role__in=role_list, menu_button__menu=menu_id - ).values(btn_id=F('menu_button__id'), name=F('menu_button__name')) - return DetailResponse(data=queryset) - return ErrorResponse(msg="参数错误") + data = request.data + roleId = data.get('roleId') + menuId = data.get('menuId') + isCheck = data.get('isCheck') + if isCheck: + # 添加权限:创建关联记录 + instance = RoleMenuPermission.objects.create(role_id=roleId, menu_id=menuId) + else: + # 删除权限:移除关联记录 + RoleMenuPermission.objects.filter(role_id=roleId, menu_id=menuId).delete() + menu_instance = Menu.objects.get(id=menuId) + serializer = RoleMenuSerializer(menu_instance, request=request) + return DetailResponse(data=serializer.data, msg="更新成功") @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) - def data_scope(self, request): + def get_role_menu_btn_field(self, request): """ - 获取数据权限范围:角色授权页面使用 + 获取 角色-菜单-按钮-列字段 :param request: :return: """ - is_superuser = request.user.is_superuser - if is_superuser: - data = [ - {"value": 0, "label": '仅本人数据权限'}, - {"value": 1, "label": '本部门及以下数据权限'}, - {"value": 2, "label": '本部门数据权限'}, - {"value": 3, "label": '全部数据权限'}, - {"value": 4, "label": '自定义数据权限'} - ] - return DetailResponse(data=data) + params = request.query_params + menuId = params.get('menuId', None) + menu_btn_queryset = MenuButton.objects.filter(menu_id=menuId) + menu_btn_serializer = RoleMenuButtonSerializer(menu_btn_queryset, many=True, request=request) + menu_field_queryset = MenuField.objects.filter(menu_id=menuId) + menu_field_serializer = RoleMenuFieldSerializer(menu_field_queryset, many=True, request=request) + return DetailResponse(data={'menu_btn': menu_btn_serializer.data, 'menu_field': menu_field_serializer.data}) + + @action(methods=['PUT'], detail=True, permission_classes=[IsAuthenticated]) + def set_role_menu_field(self, request, pk): + """ + 设置 角色-菜单-列字段 + """ + data = request.data + for col in data: + FieldPermission.objects.update_or_create( + role_id=pk, field_id=col.get('id'), + defaults={ + 'is_create': col.get('is_create'), + 'is_update': col.get('is_update'), + 'is_query': col.get('is_query'), + }) + + return DetailResponse(data=[], msg="更新成功") + + @action(methods=['PUT'], detail=False, permission_classes=[IsAuthenticated]) + def set_role_menu_btn(self, request): + """ + 设置 角色-菜单-按钮 + """ + data = request.data + isCheck = data.get('isCheck', None) + roleId = data.get('roleId', None) + btnId = data.get('btnId', None) + if isCheck: + # 添加权限:创建关联记录 + RoleMenuButtonPermission.objects.create(role_id=roleId, menu_button_id=btnId) else: - params = request.query_params - data = [{"value": 0, "label": '仅本人数据权限'}] - role_list = request.user.role.values_list('id', flat=True) - # 权限页面进入初始化获取所有的数据权限范围 - role_queryset = RoleMenuButtonPermission.objects.filter( - role__in=role_list - ).values_list('data_range', flat=True) - # 通过按钮小齿轮获取指定按钮的权限 - if menu_button_id := params.get('menu_button', None): - role_queryset = RoleMenuButtonPermission.objects.filter( - role__in=role_list, menu_button__id=menu_button_id - ).values_list('data_range', flat=True) - - data_range_list = list(set(role_queryset)) - for item in data_range_list: - if item == 0: - data = data - elif item == 1: - data.extend([ - {"value": 1, "label": '本部门及以下数据权限'}, - {"value": 2, "label": '本部门数据权限'} - ]) - elif item == 2: - data.extend([{"value": 2, "label": '本部门数据权限'}]) - elif item == 3: - data.extend([{"value": 3, "label": '全部数据权限'}]) - elif item == 4: - data.extend([{"value": 4, "label": '自定义数据权限'}]) - else: - data = [] - return DetailResponse(data=data) + # 删除权限:移除关联记录 + RoleMenuButtonPermission.objects.filter(role_id=roleId, menu_button_id=btnId).delete() + menu_btn_instance = MenuButton.objects.get(id=btnId) + serializer = RoleMenuButtonSerializer(menu_btn_instance, request=request) + return DetailResponse(data=serializer.data, msg="更新成功") + + @action(methods=['PUT'], detail=False, permission_classes=[IsAuthenticated]) + def set_role_menu_btn_data_range(self, request): + """ + 设置 角色-菜单-按钮-权限 + """ + data = request.data + instance = RoleMenuButtonPermission.objects.get(id=data.get('role_menu_btn_perm_id')) + instance.data_range = data.get('data_range') + instance.dept.add(*data.get('dept')) + if not data.get('dept'): + instance.dept.clear() + instance.save() + serializer = RoleMenuButtonPermissionSerializer(instance, request=request) + return DetailResponse(data=serializer.data, msg="更新成功") @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated]) def role_to_dept_all(self, request): @@ -395,55 +280,3 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet): dept["disabled"] = False if is_superuser else dept["id"] not in dept_checked_disabled data.append(dept) return DetailResponse(data=data) - - @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated]) - def menu_to_button(self, request): - """ - 根据所选择菜单获取已配置的按钮/接口权限:角色授权页面使用 - :param request: - :return: - """ - params = request.query_params - menu_id = params.get('menu', None) - if menu_id is None: - return ErrorResponse(msg="未获取到参数") - is_superuser = request.user.is_superuser - if is_superuser: - queryset = RoleMenuButtonPermission.objects.filter(menu_button__menu=menu_id).values( - 'id', - 'data_range', - 'menu_button', - 'menu_button__name', - 'menu_button__value' - ) - return DetailResponse(data=queryset) - else: - if params: - - role_id = params.get('role', None) - if role_id is None: - return ErrorResponse(msg="未获取到参数") - queryset = RoleMenuButtonPermission.objects.filter(role=role_id, menu_button__menu=menu_id).values( - 'id', - 'data_range', - 'menu_button', - 'menu_button__name', - 'menu_button__value' - ) - return DetailResponse(data=queryset) - return ErrorResponse(msg="未获取到参数") - - @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated]) - def role_to_menu(self, request): - """ - 获取角色对应的按钮权限 - :param request: - :return: - """ - params = request.query_params - role_id = params.get('role', None) - if role_id is None: - return ErrorResponse(msg="未获取到参数") - queryset = RoleMenuPermission.objects.filter(role_id=role_id).values_list('menu_id', flat=True).distinct() - - return DetailResponse(data=queryset) diff --git a/web/src/views/system/role/components/PermissionComNew/api.ts b/web/src/views/system/role/components/PermissionComNew/api.ts deleted file mode 100644 index 0243ab6930f90481c66d157e880fff1a2cab9f02..0000000000000000000000000000000000000000 --- a/web/src/views/system/role/components/PermissionComNew/api.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { request } from "/@/utils/service"; -import XEUtils from "xe-utils"; -/** - * 获取角色的授权列表 - * @param roleId - * @param query - */ -export function getRolePermission(query:object) { - return request({ - url: '/api/system/role_menu_button_permission/get_role_permission/', - method: 'get', - params:query - }).then((res:any)=>{ - return XEUtils.toArrayTree(res.data, {key: 'id', parentKey: 'parent',children: 'children',strict: false}) - }) -} - -/*** - * 设置角色的权限 - * @param roleId - * @param data - */ -export function setRolePremission(roleId:any,data:object) { - return request({ - url: `/api/system/role_menu_button_permission/${roleId}/set_role_premission/`, - method: 'put', - data - }) -} - -export function getDataPermissionRange(query:object) { - return request({ - url: '/api/system/role_menu_button_permission/data_scope/', - method: 'get', - params:query - }) -} - -export function getDataPermissionRangeAll() { - return request({ - url: '/api/system/role_menu_button_permission/data_scope/', - method: 'get', - }) -} -export function getDataPermissionDept(query:object) { - return request({ - url: '/api/system/role_menu_button_permission/role_to_dept_all/', - method: 'get', - params:query - }) -} - -export function getDataPermissionMenu() { - return request({ - url: '/api/system/role_menu_button_permission/get_role_permissions/', - method: 'get' - }) -} - -/** - * 设置按钮的数据范围 - */ -export function setBtnDatarange(roleId:number,data:object) { - return request({ - url: `/api/system/role_menu_button_permission/${roleId}/set_btn_datarange/`, - method: 'put', - data - }) -} - diff --git a/web/src/views/system/role/components/PermissionComNew/index.vue b/web/src/views/system/role/components/PermissionComNew/index.vue deleted file mode 100644 index b1da73fd3488d91ba0a287e9869d7f97f9c4b8cb..0000000000000000000000000000000000000000 --- a/web/src/views/system/role/components/PermissionComNew/index.vue +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - - diff --git a/web/src/views/system/role/components/PermissionComNew/types.ts b/web/src/views/system/role/components/PermissionComNew/types.ts deleted file mode 100644 index 5afc5c0de1d3fb3c6e0f449971ea0d4ba4a05885..0000000000000000000000000000000000000000 --- a/web/src/views/system/role/components/PermissionComNew/types.ts +++ /dev/null @@ -1,29 +0,0 @@ -export interface DataPermissionRangeType { - label: string; - value: number; -} - -export interface CustomDataPermissionDeptType { - id: number; - name: string; - patent: number; - children: CustomDataPermissionDeptType[]; -} - -export interface CustomDataPermissionMenuType { - id: number; - name: string; - is_catalog: boolean; - menuPermission: { id: number; name: string; value: string }[] | null; - columns: { id: number; name: string; title: string }[] | null; - children: CustomDataPermissionMenuType[]; -} - -export interface MenuDataType { - id: string; - name: string; - isCheck: boolean; - btns: { id: number; name: string; value: string; isCheck: boolean; data_range: number; dept: object }[]; - columns: { [key: string]: boolean | string; }[]; - children: MenuDataType[]; -} diff --git a/web/src/views/system/role/components/RoleDrawer.vue b/web/src/views/system/role/components/RoleDrawer.vue new file mode 100644 index 0000000000000000000000000000000000000000..c147b665d295fe0626d5fc8beb5425acf7a0c159 --- /dev/null +++ b/web/src/views/system/role/components/RoleDrawer.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/web/src/views/system/role/components/RoleMenuBtn.vue b/web/src/views/system/role/components/RoleMenuBtn.vue new file mode 100644 index 0000000000000000000000000000000000000000..8d0f1b41f38692f7ea39e94f351e1ccfa552ef43 --- /dev/null +++ b/web/src/views/system/role/components/RoleMenuBtn.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/web/src/views/system/role/components/RoleMenuField.vue b/web/src/views/system/role/components/RoleMenuField.vue new file mode 100644 index 0000000000000000000000000000000000000000..e36767764a0b5a268a28ab74ddd807f41edc2b37 --- /dev/null +++ b/web/src/views/system/role/components/RoleMenuField.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/web/src/views/system/role/components/RoleMenuTree.vue b/web/src/views/system/role/components/RoleMenuTree.vue new file mode 100644 index 0000000000000000000000000000000000000000..c296e9a90a5a59eb2cb627f5ad4e2a32c554a9ba --- /dev/null +++ b/web/src/views/system/role/components/RoleMenuTree.vue @@ -0,0 +1,81 @@ + + + diff --git a/web/src/views/system/role/components/api.ts b/web/src/views/system/role/components/api.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc3a5dc1d1a8b666e8c719a61ffb153897590df5 --- /dev/null +++ b/web/src/views/system/role/components/api.ts @@ -0,0 +1,88 @@ +import { request } from '/@/utils/service'; +import XEUtils from 'xe-utils'; +/** + * 获取 角色-菜单 + * @param query + */ +export function getRoleMenu(query: object) { + return request({ + url: '/api/system/role_menu_button_permission/get_role_menu/', + method: 'get', + params: query, + }).then((res: any) => { + return XEUtils.toArrayTree(res.data, { key: 'id', parentKey: 'parent', children: 'children', strict: false }); + }); +} +/** + * 设置 角色-菜单 + * @param data + * @returns + */ +export function setRoleMenu(data: object) { + return request({ + url: '/api/system/role_menu_button_permission/set_role_menu/', + method: 'put', + data, + }); +} +/** + * 获取 角色-菜单-按钮-列字段 + * @param query + */ +export function getRoleMenuBtnField(query: object) { + return request({ + url: '/api/system/role_menu_button_permission/get_role_menu_btn_field/', + method: 'get', + params: query, + }); +} + +/** + * 设置 角色-菜单-按钮 + * @param data + */ +export function setRoleMenuBtn(data: object) { + return request({ + url: '/api/system/role_menu_button_permission/set_role_menu_btn/', + method: 'put', + data, + }); +} + +/** + * 设置 角色-菜单-列字段 + * @param data + */ +export function setRoleMenuField(roleId: string | number | undefined, data: object) { + return request({ + url: `/api/system/role_menu_button_permission/${roleId}/set_role_menu_field/`, + method: 'put', + data, + }); +} + +/** + * 设置 角色-菜单-按钮-数据权限 + * @param query + * @returns + */ +export function setRoleMenuBtnDataRange(data: object) { + return request({ + url: '/api/system/role_menu_button_permission/set_role_menu_btn_data_range/', + method: 'put', + data, + }); +} + +/** + * 获取当前用户角色下所能授权的部门 + * @param query + * @returns + */ +export function getRoleToDeptAll(query: object) { + return request({ + url: '/api/system/role_menu_button_permission/role_to_dept_all/', + method: 'get', + params: query, + }); +} diff --git a/web/src/views/system/role/crud.tsx b/web/src/views/system/role/crud.tsx index 22ad8fd48444a57f915b0250c32db9f3f581bf5e..1f5c6104f846cc7b9bfd58ee427a8f0481bb51c0 100644 --- a/web/src/views/system/role/crud.tsx +++ b/web/src/views/system/role/crud.tsx @@ -1,189 +1,171 @@ -import {CrudOptions, AddReq, DelReq, EditReq, dict, CrudExpose, compute} from '@fast-crud/fast-crud'; +import { CreateCrudOptionsProps, CreateCrudOptionsRet, AddReq, DelReq, EditReq, dict, compute } from '@fast-crud/fast-crud'; import * as api from './api'; -import {dictionary} from '/@/utils/dictionary'; -import {columnPermission} from '../../../utils/columnPermission'; -import {successMessage} from '../../../utils/message'; -import {auth} from '/@/utils/authFunction' +import { dictionary } from '/@/utils/dictionary'; +import { successMessage } from '../../../utils/message'; +import { auth } from '/@/utils/authFunction'; -interface CreateCrudOptionsTypes { - output: any; - crudOptions: CrudOptions; -} +/** + * + * @param crudExpose:index传递过来的示例 + * @param context:index传递过来的自定义参数 + * @returns + */ +export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const pageRequest = async (query: any) => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + const addRequest = async ({ form }: AddReq) => { + return await api.AddObj(form); + }; -//此处为crudOptions配置 -export const createCrudOptions = function ({ - crudExpose, - rolePermission, - handleDrawerOpen, - }: { - crudExpose: CrudExpose; - rolePermission: any; - handleDrawerOpen: Function; -}): CreateCrudOptionsTypes { - const pageRequest = async (query: any) => { - return await api.GetList(query); - }; - const editRequest = async ({form, row}: EditReq) => { - form.id = row.id; - return await api.UpdateObj(form); - }; - const delRequest = async ({row}: DelReq) => { - return await api.DelObj(row.id); - }; - const addRequest = async ({form}: AddReq) => { - return await api.AddObj(form); - }; - - //权限判定 - - // @ts-ignore - // @ts-ignore - return { - crudOptions: { - request: { - pageRequest, - addRequest, - editRequest, - delRequest, - }, - pagination: { - show: true - }, - actionbar: { - buttons: { - add: { - show: auth('role:Create') - } - } - }, - rowHandle: { - //固定右侧 - fixed: 'right', - width: 320, - buttons: { - view: { - show: true, - }, - edit: { - show: auth('role:Update'), - }, - remove: { - show: auth('role:Delete'), - }, - permission: { - type: 'primary', - text: '权限配置', - show: auth('role:Permission'), - tooltip: { - placement: 'top', - content: '权限配置', - }, - click: (context: any): void => { - const {row} = context; - handleDrawerOpen(row); - }, - }, - }, - }, - form: { - col: {span: 24}, - labelWidth: '100px', - wrapper: { - is: 'el-dialog', - width: '600px', - }, - }, - columns: { - _index: { - title: '序号', - form: {show: false}, - column: { - type: 'index', - align: 'center', - width: '70px', - columnSetDisabled: true, //禁止在列设置中选择 - }, - }, - id: { - title: 'ID', - type: 'text', - column: {show: false}, - search: {show: false}, - form: {show: false}, - }, - name: { - title: '角色名称', - type: 'text', - search: {show: true}, - column: { - minWidth: 120, - sortable: 'custom', - }, - form: { - rules: [{required: true, message: '角色名称必填'}], - component: { - placeholder: '请输入角色名称', - }, - }, - }, - key: { - title: '权限标识', - type: 'text', - search: {show: false}, - column: { - minWidth: 120, - sortable: 'custom', - columnSetDisabled: true, - }, - form: { - rules: [{required: true, message: '权限标识必填'}], - component: { - placeholder: '输入权限标识', - }, - }, - valueBuilder(context) { - const {row, key} = context - return row[key] - } - }, - sort: { - title: '排序', - search: {show: false}, - type: 'number', - column: { - minWidth: 90, - sortable: 'custom', - }, - form: { - rules: [{required: true, message: '排序必填'}], - value: 1, - }, - }, - status: { - title: '状态', - search: {show: true}, - type: 'dict-radio', - column: { - width: 100, - component: { - name: 'fs-dict-switch', - activeText: '', - inactiveText: '', - style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6', - onChange: compute((context) => { - return () => { - api.UpdateObj(context.row).then((res: APIResponseData) => { - successMessage(res.msg as string); - }); - }; - }), - }, - }, - dict: dict({ - data: dictionary('button_status_bool'), - }), - } - }, - }, - }; + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest, + }, + pagination: { + show: true, + }, + actionbar: { + buttons: { + add: { + show: auth('role:Create'), + }, + }, + }, + rowHandle: { + //固定右侧 + fixed: 'right', + width: 320, + buttons: { + view: { + show: true, + }, + edit: { + show: auth('role:Update'), + }, + remove: { + show: auth('role:Delete'), + }, + permission: { + type: 'primary', + text: '权限配置', + show: auth('role:Permission'), + click: (clickContext: any): void => { + const { row } = clickContext; + context.RoleDrawer.handleDrawerOpen(row); + context.RoleMenuBtn.setState([]); + context.RoleMenuField.setState([]); + }, + }, + }, + }, + form: { + col: { span: 24 }, + labelWidth: '100px', + wrapper: { + is: 'el-dialog', + width: '600px', + }, + }, + columns: { + _index: { + title: '序号', + form: { show: false }, + column: { + type: 'index', + align: 'center', + width: '70px', + columnSetDisabled: true, //禁止在列设置中选择 + }, + }, + id: { + title: 'ID', + column: { show: false }, + search: { show: false }, + form: { show: false }, + }, + name: { + title: '角色名称', + search: { show: true }, + column: { + minWidth: 120, + sortable: 'custom', + }, + form: { + rules: [{ required: true, message: '角色名称必填' }], + component: { + placeholder: '请输入角色名称', + }, + }, + }, + key: { + title: '权限标识', + search: { show: false }, + column: { + minWidth: 120, + sortable: 'custom', + columnSetDisabled: true, + }, + form: { + rules: [{ required: true, message: '权限标识必填' }], + component: { + placeholder: '输入权限标识', + }, + }, + valueBuilder(context) { + const { row, key } = context; + return row[key]; + }, + }, + sort: { + title: '排序', + search: { show: false }, + type: 'number', + column: { + minWidth: 90, + sortable: 'custom', + }, + form: { + rules: [{ required: true, message: '排序必填' }], + value: 1, + }, + }, + status: { + title: '状态', + search: { show: true }, + type: 'dict-radio', + column: { + width: 100, + component: { + name: 'fs-dict-switch', + activeText: '', + inactiveText: '', + style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6', + onChange: compute((context) => { + return () => { + api.UpdateObj(context.row).then((res: APIResponseData) => { + successMessage(res.msg as string); + }); + }; + }), + }, + }, + dict: dict({ + value: dictionary('button_status_bool'), + }), + }, + }, + }, + }; }; diff --git a/web/src/views/system/role/index.vue b/web/src/views/system/role/index.vue index 4b12a38d0433f99ed335d876d97a8be078d7a3a6..19e8124263ddc615ea94edf599db8ede7bb10b29 100644 --- a/web/src/views/system/role/index.vue +++ b/web/src/views/system/role/index.vue @@ -1,69 +1,31 @@ diff --git a/web/src/views/system/role/stores/RoleDrawerStores.ts b/web/src/views/system/role/stores/RoleDrawerStores.ts new file mode 100644 index 0000000000000000000000000000000000000000..7121c3713b58febbdc36a992b16e127abb176754 --- /dev/null +++ b/web/src/views/system/role/stores/RoleDrawerStores.ts @@ -0,0 +1,32 @@ +import { defineStore } from 'pinia'; +import { RoleDrawerType } from '../types'; +/** + * 权限配置:抽屉 + */ +const initialState: RoleDrawerType = { + drawerVisible: false, + roleId: undefined, + roleName: undefined, +}; + +export const RoleDrawerStores = defineStore('RoleDrawerStores', { + state: (): RoleDrawerType => ({ + ...initialState, + }), + actions: { + /** + * 打开权限修改抽屉 + */ + handleDrawerOpen(row: any) { + this.drawerVisible = true; + this.roleName = row.name; + this.roleId = row.id; + }, + /** + * 关闭权限修改抽屉 + */ + handleDrawerClose() { + Object.assign(this.$state, initialState); + }, + }, +}); diff --git a/web/src/views/system/role/stores/RoleMenuBtnStores.ts b/web/src/views/system/role/stores/RoleMenuBtnStores.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ef46109622f4e3b518ab274ab2decd5e044240a --- /dev/null +++ b/web/src/views/system/role/stores/RoleMenuBtnStores.ts @@ -0,0 +1,24 @@ +import { defineStore } from 'pinia'; +import { RoleMenuBtnType } from '../types'; +/** + * 权限配置:角色-菜单-按钮 + */ + +export const RoleMenuBtnStores = defineStore('RoleMenuBtnStores', { + state: (): RoleMenuBtnType[] => [], + actions: { + /** + * 初始化 + */ + setState(data: RoleMenuBtnType[]) { + this.$state = data; + this.$state.length = data.length; + }, + updateState(data: RoleMenuBtnType) { + const index = this.$state.findIndex((item) => item.id === data.id); + if (index !== -1) { + this.$state[index] = data; + } + }, + }, +}); diff --git a/web/src/views/system/role/stores/RoleMenuFieldStores.ts b/web/src/views/system/role/stores/RoleMenuFieldStores.ts new file mode 100644 index 0000000000000000000000000000000000000000..c01c0809726f8de73cb059f18936144c0aab7bf5 --- /dev/null +++ b/web/src/views/system/role/stores/RoleMenuFieldStores.ts @@ -0,0 +1,24 @@ +import { defineStore } from 'pinia'; +import { RoleMenuFieldType, RoleMenuFieldHeaderType } from '../types'; +/** + * 权限配置:角色-菜单-列字段 + */ + +export const RoleMenuFieldStores = defineStore('RoleMenuFieldStores', { + state: (): RoleMenuFieldType[] => [], + actions: { + /** 重置 */ + setState(data: RoleMenuFieldType[]) { + this.$state = data; + this.$state.length = data.length; + }, + }, +}); + +export const RoleMenuFieldHeaderStores = defineStore('RoleMenuFieldHeaderStores', { + state: (): RoleMenuFieldHeaderType[] => [ + { value: 'is_create', label: '新增可见', disabled: 'disabled_create', checked: false }, + { value: 'is_update', label: '编辑可见', disabled: 'disabled_update', checked: false }, + { value: 'is_query', label: '列表可见', disabled: 'disabled_query', checked: false }, + ], +}); diff --git a/web/src/views/system/role/stores/RoleMenuTreeStores.ts b/web/src/views/system/role/stores/RoleMenuTreeStores.ts new file mode 100644 index 0000000000000000000000000000000000000000..14f28c657dc2500d7a71cae99d7cfd87bd86f862 --- /dev/null +++ b/web/src/views/system/role/stores/RoleMenuTreeStores.ts @@ -0,0 +1,21 @@ +import { defineStore } from 'pinia'; +import { RoleMenuTreeType } from '../types'; +/** + * 权限抽屉:角色-菜单 + */ + +export const RoleMenuTreeStores = defineStore('RoleMenuTreeStores', { + state: (): RoleMenuTreeType => ({ + id: 0, + parent: 0, + name: '', + isCheck: false, + is_catalog: false, + }), + actions: { + /** 赋值 */ + setRoleMenuTree(data: RoleMenuTreeType) { + this.$state = data; + }, + }, +}); diff --git a/web/src/views/system/role/types.ts b/web/src/views/system/role/types.ts index 6b0027c5aa1e4c1631e9ef4c691d83878c90686b..e38b56f7bca14b20f55872fcffe650986a96f081 100644 --- a/web/src/views/system/role/types.ts +++ b/web/src/views/system/role/types.ts @@ -1,27 +1,88 @@ -import { CrudOptions, CrudExpose } from '@fast-crud/fast-crud'; +/**角色列表数据类型 */ +export interface RoleItemType { + id: string | number; + modifier_name: string; + creator_name: string; + create_datetime: string; + update_datetime: string; + description: string; + modifier: string; + dept_belong_id: string; + name: string; + key: string; + sort: number; + status: boolean; + admin: boolean; + creator: string; +} -export interface CreateCrudReturnTypes { - crudOptions: CrudOptions; +/** + * 权限配置 抽屉组件参数数据类型 + */ +export interface RoleDrawerType { + /** 是否显示抽屉*/ + drawerVisible: boolean; + /** 角色id*/ + roleId: string | number | undefined; + /** 角色名称*/ + roleName: string | undefined; } -export interface CreateCrudOptionsTypes { - crudExpose: CrudExpose; - configPermission: Function; +/** + * 菜单数据类型 + */ +export interface RoleMenuTreeType { + id: number | string | undefined; + /** 父级id */ + parent: number | string | undefined; + name: string; + /** 是否选中 */ + isCheck: boolean; + /** 是否是目录 */ + is_catalog: boolean; +} +/** + * 菜单-按钮数据类型 + */ +export interface RoleMenuBtnType { + id: string | number; + menu_btn_pre_id: string | number; + /** 是否选中 */ + isCheck: boolean; + /** 按钮名称 */ + name: string; + /** 数据权限范围 */ + data_range: number | null; + /** 自定义部门 */ + dept: number[]; } -export interface RoleItemType { - id: string | number; - modifier_name: string; - creator_name: string; - create_datetime: string; - update_datetime: string; - description: string; - modifier: string; - dept_belong_id: string; - name: string; - key: string; - sort: number; - status: boolean; - admin: boolean; - creator: string; -} \ No newline at end of file +/** + * 菜单-列字段数据类型 + */ +export interface RoleMenuFieldType { + id: string | number | boolean; + /** 模型表字段名 */ + field_name: string; + /** 字段显示名 */ + title: string; + /** 是否可查询 */ + is_query: boolean; + /** 是否可创建 */ + is_create: boolean; + /** 是否可更新 */ + is_update: boolean; + [key: string]: string | number | boolean; +} +/** + * 菜单-列字段-标题数据类型 + */ +export interface RoleMenuFieldHeaderType { + value: string; + /** 模型表字段名 */ + label: string; + /** 字段显示名 */ + disabled: string ; + /** 是否可查询 */ + checked: boolean; +}