diff --git a/README.zh.md b/README.zh.md
index 511caf9..dea0106 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -1,214 +1,214 @@
-# Django-Vue3-Admin
-
-[](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [](https://python.org/) [](https://docs.djangoproject.com/zh-hans/3.2/) [](https://nodejs.org/zh-cn/) [](https://gitee.com/liqianglog/django-vue-admin)
-
-[预 览](https://demo.dvadmin.com) | [官网文档](https://www.django-vue-admin.com) | [群聊](https://qm.qq.com/cgi-bin/qm/qr?k=fOdnHhC8DJlRHGYSnyhoB8P5rgogA6Vs&jump_from=webapi) | [社区](https://bbs.django-vue-admin.com) | [插件市场](https://bbs.django-vue-admin.com/plugMarket.html) | [Github](https://github.com/liqianglog/django-vue-admin)
-
-
-
-💡 **「关于」**
-
-我们是一群热爱代码的青年,在这个炙热的时代下,我们希望静下心来通过Code带来一点我们的色彩和颜色。
-
-因为热爱,所以拥抱未来!
-
-
-## 平台简介
-
-💡 [django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin.git) 是一套全部开源的快速开发平台,毫无保留给个人免费使用、团体授权使用。
- django-vue3-admin 基于RBAC模型的权限控制的一整套基础开发平台,权限粒度达到列级别,前后端分离,后端采用django + django-rest-framework,前端采用基于 vue3 + CompositionAPI + typescript + vite + element plus
-
-
-
-
-* 🧑🤝🧑前端采用 Vue3+TS+pinia+fastcrud(感谢[vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/))
-* 👭后端采用 Python 语言 Django 框架以及强大的 [Django REST Framework](https://pypi.org/project/djangorestframework)。
-* 👫权限认证使用[Django REST Framework SimpleJWT](https://pypi.org/project/djangorestframework-simplejwt),支持多终端认证系统。
-* 👬支持加载动态权限菜单,多方式轻松权限控制。
-* 👬全新的列权限管控,粒度细化到每一列。
-* 💏特别鸣谢:[vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/)。
-* 💡特别感谢[jetbrains](https://www.jetbrains.com/) 为本开源项目提供免费的 IntelliJ IDEA 授权。
-
-#### 🏭 环境支持
-
-| Edge | Firefox | Chrome | Safari |
-| --------- | ------------ | ----------- | ----------- |
-| Edge ≥ 79 | Firefox ≥ 78 | Chrome ≥ 64 | Safari ≥ 12 |
-
-> 由于 Vue3 不再支持 IE11,故而 ElementPlus 也不支持 IE11 及之前版本。
-
-
-
-## 在线体验
-
-👩👧👦演示地址:[https://demo.dvadmin.com](https://demo.dvadmin.com)
-
-- 账号:superadmin
-
-- 密码:admin123456
-
-👩👦👦文档地址:[coding](https://dvadmin-private.coding.net/share/km/cec69f3d-30fe-47d5-bd97-e9e851f0b776/K-2)
-
-
-
-## 交流
-
-- 交流社区:[戳我](https://bbs.django-vue-admin.com)👩👦👦
-
-- 插件市场:[戳我](https://bbs.django-vue-admin.com/plugMarket.html)👩👦👦
-
-- django-vue-admin交流01群(已满):812482043 [点击链接加入群聊](https://qm.qq.com/cgi-bin/qm/qr?k=aJVwjDvH-Es4MPJQuoO32N0SucK22TE5&jump_from=webapi)
-- django-vue-admin交流02群(已满):687252418 [点击链接加入群聊](https://qm.qq.com/cgi-bin/qm/qr?k=4jJN4IjWGfxJ8YJXbb_gTsuWjR34WLdc&jump_from=webapi)
-- django-vue-admin交流03群:442108213 [点击链接加入群聊](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=wsm5oSz3K8dElBYUDtLTcQSEPhINFkl8&authKey=M6sbER0z59ZakgBr5erFeZyFZU15CI52bErNZa%2FxSvvGIuVAbY0N5866v89hm%2FK4&noverify=0&group_code=442108213)
-
-- 二维码
-
-
-
-## 源码地址
-
-gitee地址(主推):[https://gitee.com/huge-dream/django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin)👩👦👦
-
-github地址:[https://github.com/huge-dream/django-vue3-admin](https://github.com/huge-dream/django-vue3-admin)👩👦👦
-
-
-## 内置功能
-
-1. 👨⚕️菜单管理:配置系统菜单,操作权限,按钮权限标识、后端接口权限等。
-2. 🧑⚕️部门管理:配置系统组织机构(公司、部门、角色)。
-3. 👩⚕️角色管理:角色菜单权限分配、数据权限分配、设置角色按部门进行数据范围权限划分。
-4. 🧑🎓按钮权限控制:授权角色的按钮权限和接口权限,可做到每一个接口都能授权数据范围。
-5. 🧑🎓字段列权限控制:授权页面的字段显示权限,具体到某一列的显示权限。
-7. 👨🎓用户管理:用户是系统操作者,该功能主要完成系统用户配置。
-8. 👬接口白名单:配置不需要进行权限校验的接口。
-9. 🧑🔧字典管理:对系统中经常使用的一些较为固定的数据进行维护。
-10. 🧑🔧地区管理:对省市县区域进行管理。
-11. 📁附件管理:对平台上所有文件、图片等进行统一管理。
-12. 🗓️操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
-13. 🔌[插件市场 ](https://bbs.django-vue-admin.com/plugMarket.html):基于Django-Vue-Admin框架开发的应用和插件。
-
-## 插件市场 🔌
-更新中...
-
-## 仓库分支说明 💈
-主分支:master(稳定版本)
-开发分支:develop
-
-
-## 准备工作
-~~~
-Python >= 3.11.0 (最低3.9+版本)
-nodejs >= 16.0
-Mysql >= 8.0 (可选,默认数据库sqlite3,支持5.7+,推荐8.0版本)
-Redis (可选,最新版)
-~~~
-
-## 前端♝
-
-```bash
-# 克隆项目
-git clone https://gitee.com/huge-dream/django-vue3-admin.git
-
-# 进入项目目录
-cd web
-
-# 安装依赖
-npm install yarn
-yarn install --registry=https://registry.npm.taobao.org
-
-# 启动服务
-yarn build
-# 浏览器访问 http://localhost:8080
-# .env.development 文件中可配置启动端口等参数
-# 构建生产环境
-# yarn run build
-```
-
-
-
-## 后端💈
-
-~~~bash
-1. 进入项目目录 cd backend
-2. 在项目根目录中,复制 ./conf/env.example.py 文件为一份新的到 ./conf 文件夹下,并重命名为 env.py
-3. 在 env.py 中配置数据库信息
- mysql数据库版本建议:8.0
- mysql数据库字符集:utf8mb4
-4. 安装依赖环境
- pip3 install -r requirements.txt
-5. 执行迁移命令:
- python3 manage.py makemigrations
- python3 manage.py migrate
-6. 初始化数据
- python3 manage.py init
-7. 初始化省市县数据:
- python3 manage.py init_area
-8. 启动项目
- python3 manage.py runserver 0.0.0.0:8000
-或使用 uvicorn :
- uvicorn application.asgi:application --port 8000 --host 0.0.0.0 --workers 8
-~~~
-## 开发建议
-前后端backend与web各自单独一个窗口打开进行开发
-
-### 访问项目
-
-- 访问地址:[http://localhost:8080](http://localhost:8080) (默认为此地址,如有修改请按照配置文件)
-- 账号:`superadmin` 密码:`admin123456`
-
-
-
-
-
-### docker-compose 运行
-
-~~~shell
-# 先安装docker-compose (自行百度安装),执行此命令等待安装,如有使用celery插件请打开docker-compose.yml中celery 部分注释
-docker-compose up -d
-# 初始化后端数据(第一次执行即可)
-docker exec -ti dvadmin3-django bash
-python manage.py makemigrations
-python manage.py migrate
-python manage.py init_area
-python manage.py init
-exit
-
-前端地址:http://127.0.0.1:8080
-后端地址:http://127.0.0.1:8080/api
-# 在服务器上请把127.0.0.1 换成自己公网ip
-账号:superadmin 密码:admin123456
-
-# docker-compose 停止
-docker-compose down
-# docker-compose 重启
-docker-compose restart
-# docker-compose 启动时重新进行 build
-docker-compose up -d --build
-~~~
-
-
-
-## 演示图✅
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+# Django-Vue3-Admin
+
+[](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [](https://python.org/) [](https://docs.djangoproject.com/zh-hans/3.2/) [](https://nodejs.org/zh-cn/) [](https://gitee.com/liqianglog/django-vue-admin)
+
+[预 览](https://demo.dvadmin.com) | [官网文档](https://www.django-vue-admin.com) | [群聊](https://qm.qq.com/cgi-bin/qm/qr?k=fOdnHhC8DJlRHGYSnyhoB8P5rgogA6Vs&jump_from=webapi) | [社区](https://bbs.django-vue-admin.com) | [插件市场](https://bbs.django-vue-admin.com/plugMarket.html) | [Github](https://github.com/liqianglog/django-vue-admin)
+
+
+
+💡 **「关于」**
+
+我们是一群热爱代码的青年,在这个炙热的时代下,我们希望静下心来通过Code带来一点我们的色彩和颜色。
+
+因为热爱,所以拥抱未来!
+
+
+## 平台简介
+
+💡 [django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin.git) 是一套全部开源的快速开发平台,毫无保留给个人免费使用、团体授权使用。
+ django-vue3-admin 基于RBAC模型的权限控制的一整套基础开发平台,权限粒度达到列级别,前后端分离,后端采用django + django-rest-framework,前端采用基于 vue3 + CompositionAPI + typescript + vite + element plus
+
+
+
+
+* 🧑🤝🧑前端采用 Vue3+TS+pinia+fastcrud(感谢[vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/))
+* 👭后端采用 Python 语言 Django 框架以及强大的 [Django REST Framework](https://pypi.org/project/djangorestframework)。
+* 👫权限认证使用[Django REST Framework SimpleJWT](https://pypi.org/project/djangorestframework-simplejwt),支持多终端认证系统。
+* 👬支持加载动态权限菜单,多方式轻松权限控制。
+* 👬全新的列权限管控,粒度细化到每一列。
+* 💏特别鸣谢:[vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/)。
+* 💡特别感谢[jetbrains](https://www.jetbrains.com/) 为本开源项目提供免费的 IntelliJ IDEA 授权。
+
+#### 🏭 环境支持
+
+| Edge | Firefox | Chrome | Safari |
+| --------- | ------------ | ----------- | ----------- |
+| Edge ≥ 79 | Firefox ≥ 78 | Chrome ≥ 64 | Safari ≥ 12 |
+
+> 由于 Vue3 不再支持 IE11,故而 ElementPlus 也不支持 IE11 及之前版本。
+
+
+
+## 在线体验
+
+👩👧👦演示地址:[https://demo.dvadmin.com](https://demo.dvadmin.com)
+
+- 账号:superadmin
+
+- 密码:admin123456
+
+👩👦👦文档地址:[DVAdmin官网](https://www.django-vue-admin.com)
+
+
+
+## 交流
+
+- 交流社区:[戳我](https://bbs.django-vue-admin.com)👩👦👦
+
+- 插件市场:[戳我](https://bbs.django-vue-admin.com/plugMarket.html)👩👦👦
+
+- django-vue-admin交流01群(已满):812482043 [点击链接加入群聊](https://qm.qq.com/cgi-bin/qm/qr?k=aJVwjDvH-Es4MPJQuoO32N0SucK22TE5&jump_from=webapi)
+- django-vue-admin交流02群(已满):687252418 [点击链接加入群聊](https://qm.qq.com/cgi-bin/qm/qr?k=4jJN4IjWGfxJ8YJXbb_gTsuWjR34WLdc&jump_from=webapi)
+- django-vue-admin交流03群:442108213 [点击链接加入群聊](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=wsm5oSz3K8dElBYUDtLTcQSEPhINFkl8&authKey=M6sbER0z59ZakgBr5erFeZyFZU15CI52bErNZa%2FxSvvGIuVAbY0N5866v89hm%2FK4&noverify=0&group_code=442108213)
+
+- 二维码
+
+
+
+## 源码地址
+
+gitee地址(主推):[https://gitee.com/huge-dream/django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin)👩👦👦
+
+github地址:[https://github.com/huge-dream/django-vue3-admin](https://github.com/huge-dream/django-vue3-admin)👩👦👦
+
+
+## 内置功能
+
+1. 👨⚕️菜单管理:配置系统菜单,操作权限,按钮权限标识、后端接口权限等。
+2. 🧑⚕️部门管理:配置系统组织机构(公司、部门、角色)。
+3. 👩⚕️角色管理:角色菜单权限分配、数据权限分配、设置角色按部门进行数据范围权限划分。
+4. 🧑🎓按钮权限控制:授权角色的按钮权限和接口权限,可做到每一个接口都能授权数据范围。
+5. 🧑🎓字段列权限控制:授权页面的字段显示权限,具体到某一列的显示权限。
+7. 👨🎓用户管理:用户是系统操作者,该功能主要完成系统用户配置。
+8. 👬接口白名单:配置不需要进行权限校验的接口。
+9. 🧑🔧字典管理:对系统中经常使用的一些较为固定的数据进行维护。
+10. 🧑🔧地区管理:对省市县区域进行管理。
+11. 📁附件管理:对平台上所有文件、图片等进行统一管理。
+12. 🗓️操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
+13. 🔌[插件市场 ](https://bbs.django-vue-admin.com/plugMarket.html):基于Django-Vue-Admin框架开发的应用和插件。
+
+## 插件市场 🔌
+更新中...
+
+## 仓库分支说明 💈
+主分支:master(稳定版本)
+开发分支:develop
+
+
+## 准备工作
+~~~
+Python >= 3.11.0 (最低3.9+版本)
+nodejs >= 16.0
+Mysql >= 8.0 (可选,默认数据库sqlite3,支持5.7+,推荐8.0版本)
+Redis (可选,最新版)
+~~~
+
+## 前端♝
+
+```bash
+# 克隆项目
+git clone https://gitee.com/huge-dream/django-vue3-admin.git
+
+# 进入项目目录
+cd web
+
+# 安装依赖
+npm install yarn
+yarn install --registry=https://registry.npm.taobao.org
+
+# 启动服务
+yarn build
+# 浏览器访问 http://localhost:8080
+# .env.development 文件中可配置启动端口等参数
+# 构建生产环境
+# yarn run build
+```
+
+
+
+## 后端💈
+
+~~~bash
+1. 进入项目目录 cd backend
+2. 在项目根目录中,复制 ./conf/env.example.py 文件为一份新的到 ./conf 文件夹下,并重命名为 env.py
+3. 在 env.py 中配置数据库信息
+ mysql数据库版本建议:8.0
+ mysql数据库字符集:utf8mb4
+4. 安装依赖环境
+ pip3 install -r requirements.txt
+5. 执行迁移命令:
+ python3 manage.py makemigrations
+ python3 manage.py migrate
+6. 初始化数据
+ python3 manage.py init
+7. 初始化省市县数据:
+ python3 manage.py init_area
+8. 启动项目
+ python3 manage.py runserver 0.0.0.0:8000
+或使用 uvicorn :
+ uvicorn application.asgi:application --port 8000 --host 0.0.0.0 --workers 8
+~~~
+## 开发建议
+前后端backend与web各自单独一个窗口打开进行开发
+
+### 访问项目
+
+- 访问地址:[http://localhost:8080](http://localhost:8080) (默认为此地址,如有修改请按照配置文件)
+- 账号:`superadmin` 密码:`admin123456`
+
+
+
+
+
+### docker-compose 运行
+
+~~~shell
+# 先安装docker-compose (自行百度安装),执行此命令等待安装,如有使用celery插件请打开docker-compose.yml中celery 部分注释
+docker-compose up -d
+# 初始化后端数据(第一次执行即可)
+docker exec -ti dvadmin3-django bash
+python manage.py makemigrations
+python manage.py migrate
+python manage.py init_area
+python manage.py init
+exit
+
+前端地址:http://127.0.0.1:8080
+后端地址:http://127.0.0.1:8080/api
+# 在服务器上请把127.0.0.1 换成自己公网ip
+账号:superadmin 密码:admin123456
+
+# docker-compose 停止
+docker-compose down
+# docker-compose 重启
+docker-compose restart
+# docker-compose 启动时重新进行 build
+docker-compose up -d --build
+~~~
+
+
+
+## 演示图✅
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/dvadmin/system/views/menu_button.py b/backend/dvadmin/system/views/menu_button.py
index 2a6c742..f91839a 100644
--- a/backend/dvadmin/system/views/menu_button.py
+++ b/backend/dvadmin/system/views/menu_button.py
@@ -80,4 +80,29 @@ class MenuButtonViewSet(CustomModelViewSet):
else:
role_id = request.user.role.values_list('id', flat=True)
queryset = RoleMenuButtonPermission.objects.filter(role__in=role_id).values_list('menu_button__value',flat=True).distinct()
- return DetailResponse(data=queryset)
\ No newline at end of file
+ return DetailResponse(data=queryset)
+
+ @action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
+ def batch_create(self, request, *args, **kwargs):
+ """
+ 批量创建菜单“增删改查查”权限
+ 创建的数据来源于菜单,需要规范创建菜单参数
+ value:菜单的component_name:method
+ api:菜单的web_path增加'/api'前缀,并根据method增加{id}
+ """
+ menu_obj = Menu.objects.filter(id=request.data['menu']).first()
+ result_list = [
+ {'menu': menu_obj.id, 'name': '新增', 'value': f'{menu_obj.component_name}:Create', 'api': f'/api{menu_obj.web_path}/',
+ 'method': 1},
+ {'menu': menu_obj.id, 'name': '删除', 'value': f'{menu_obj.component_name}:Delete', 'api': f'/api{menu_obj.web_path}/{{id}}/',
+ 'method': 3},
+ {'menu': menu_obj.id, 'name': '修改', 'value': f'{menu_obj.component_name}:Update', 'api': f'/api{menu_obj.web_path}/{{id}}/',
+ 'method': 2},
+ {'menu': menu_obj.id, 'name': '查询', 'value': f'{menu_obj.component_name}:Search', 'api': f'/api{menu_obj.web_path}/',
+ 'method': 0},
+ {'menu': menu_obj.id, 'name': '详情', 'value': f'{menu_obj.component_name}:Retrieve', 'api': f'/api{menu_obj.web_path}/{{id}}/',
+ 'method': 0}]
+ serializer = self.get_serializer(data=result_list, many=True)
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ return SuccessResponse(serializer.data, msg="批量创建成功")
diff --git a/backend/dvadmin/system/views/role_menu_button_permission.py b/backend/dvadmin/system/views/role_menu_button_permission.py
index b86952c..604ebe2 100644
--- a/backend/dvadmin/system/views/role_menu_button_permission.py
+++ b/backend/dvadmin/system/views/role_menu_button_permission.py
@@ -23,13 +23,13 @@ class RoleMenuButtonPermissionSerializer(CustomModelSerializer):
"""
菜单按钮-序列化器
"""
+
class Meta:
model = RoleMenuButtonPermission
fields = "__all__"
read_only_fields = ["id"]
-
class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer):
"""
初始化菜单按钮-序列化器
@@ -67,17 +67,17 @@ class RoleButtonPermissionSerializer(CustomModelSerializer):
return None
return obj.data_range
-
class Meta:
model = MenuButton
- fields = ['id','name','value','isCheck','data_range']
+ fields = ['id', 'name', 'value', 'isCheck', 'data_range']
+
class RoleFieldPermissionSerializer(CustomModelSerializer):
-
class Meta:
model = FieldPermission
fields = "__all__"
+
class RoleMenuFieldSerializer(CustomModelSerializer):
is_query = serializers.SerializerMethodField()
is_create = serializers.SerializerMethodField()
@@ -103,24 +103,38 @@ class RoleMenuFieldSerializer(CustomModelSerializer):
if queryset:
return queryset.is_update
return False
+
class Meta:
model = MenuField
- fields = ['id','field_name','title','is_query','is_create','is_update']
+ 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()
+ # 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_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(
@@ -130,19 +144,18 @@ class RoleMenuPermissionSerializer(CustomModelSerializer):
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
+ 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)
+ serializer = RoleMenuFieldSerializer(col_list, many=True, request=self.request)
return serializer.data
-
-
class Meta:
model = Menu
- fields = ['id','name','isCheck','btns','columns']
+ fields = ['id', 'name', 'isCheck', 'btns', 'columns']
+
class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
"""
@@ -167,54 +180,54 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
:return: menu,btns,columns
"""
params = request.query_params
- role = params.get('role',None)
- if role is None:
+ role = params.get('role', None)
+ if role is None:
return ErrorResponse(msg="未获取到角色信息")
is_superuser = request.user.is_superuser
- # if is_superuser:
- # queryset = Menu.objects.filter(status=1,is_catalog=False).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('id',flat=True)
- # queryset = Menu.objects.filter(status=1, is_catalog=False,id__in=menu_list).values('name', 'id').all()
- # serializer = RoleMenuPermissionSerializer(queryset,many=True,request=request)
- # data = serializer.data
- # return DetailResponse(data=data)
- data = []
if is_superuser:
- queryset = Menu.objects.filter(status=1,is_catalog=False).values('name', 'id').all()
+ 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('id',flat=True)
- queryset = Menu.objects.filter(status=1, is_catalog=False,id__in=menu_list).values('name', 'id')
- for item in queryset:
- parent_list = Menu.get_all_parent(item['id'])
- names = [d["name"] for d in parent_list]
- completeName = "/".join(names)
- isCheck = RoleMenuPermission.objects.filter(
- menu__id=item['id'],
- role__id=role,
- ).exists()
- mbCheck = RoleMenuButtonPermission.objects.filter(
- menu_button=OuterRef("pk"),
- role__id=role,
- )
- btns = MenuButton.objects.filter(
- menu__id=item['id'],
- ).annotate(isCheck=Exists(mbCheck)).values('id', 'name', 'value', 'isCheck',
- data_range=F('menu_button_permission__data_range'))
- dicts = {
- 'name': completeName,
- 'id': item['id'],
- 'isCheck': isCheck,
- 'btns': btns,
-
- }
- data.append(dicts)
+ menu_list = RoleMenuPermission.objects.filter(role__in=role_id).values_list('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)
+ # data = []
+ # if is_superuser:
+ # queryset = Menu.objects.filter(status=1, is_catalog=False).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('id', flat=True)
+ # queryset = Menu.objects.filter(status=1, is_catalog=False, id__in=menu_list).values('name', 'id')
+ # for item in queryset:
+ # parent_list = Menu.get_all_parent(item['id'])
+ # names = [d["name"] for d in parent_list]
+ # completeName = "/".join(names)
+ # isCheck = RoleMenuPermission.objects.filter(
+ # menu__id=item['id'],
+ # role__id=role,
+ # ).exists()
+ # mbCheck = RoleMenuButtonPermission.objects.filter(
+ # menu_button=OuterRef("pk"),
+ # role__id=role,
+ # )
+ # btns = MenuButton.objects.filter(
+ # menu__id=item['id'],
+ # ).annotate(isCheck=Exists(mbCheck)).values('id', 'name', 'value', 'isCheck',
+ # data_range=F('menu_button_permission__data_range'))
+ # dicts = {
+ # 'name': completeName,
+ # 'id': item['id'],
+ # 'isCheck': isCheck,
+ # 'btns': btns,
+ #
+ # }
+ # data.append(dicts)
+ # return DetailResponse(data=data)
@action(methods=['PUT'], detail=True, permission_classes=[IsAuthenticated])
- def set_role_premission(self,request,pk):
+ def set_role_premission(self, request, pk):
"""
对角色的菜单和按钮及按钮范围授权:
:param request:
@@ -224,29 +237,30 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
body = request.data
RoleMenuPermission.objects.filter(role=pk).delete()
RoleMenuButtonPermission.objects.filter(role=pk).delete()
- for menu in body:
- if menu.get('isCheck'):
- menu_parent = Menu.get_all_parent(menu.get('id'))
- role_menu_permission_list = []
- for d in menu_parent:
- role_menu_permission_list.append(RoleMenuPermission(role_id=pk, menu_id=d["id"]))
- RoleMenuPermission.objects.bulk_create(role_menu_permission_list)
- # RoleMenuPermission.objects.create(role_id=pk, menu_id=menu.get('id'))
- for btn in menu.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 menu.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')
- })
+ for item in body:
+ for menu in item["menus"]:
+ if menu.get('isCheck'):
+ menu_parent = Menu.get_all_parent(menu.get('id'))
+ role_menu_permission_list = []
+ for d in menu_parent:
+ role_menu_permission_list.append(RoleMenuPermission(role_id=pk, menu_id=d["id"]))
+ RoleMenuPermission.objects.bulk_create(role_menu_permission_list)
+ # RoleMenuPermission.objects.create(role_id=pk, menu_id=menu.get('id'))
+ for btn in menu.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 menu.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="授权成功")
-
-
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
def role_menu_get_button(self, request):
"""
diff --git a/backend/extra-hooks/hooks-uvicorn.py b/backend/extra-hooks/hooks-uvicorn.py
deleted file mode 100644
index 51c77d7..0000000
--- a/backend/extra-hooks/hooks-uvicorn.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# extra-hooks/hooks-uvicorn.py
-from PyInstaller.utils.hooks import get_package_paths, collect_submodules
-
-datas = [(get_package_paths('uvicorn')[1], 'uvicorn'), (get_package_paths('whitenoise')[1], 'whitenoise')]
-
-hiddenimports = collect_submodules('whitenoise')
diff --git a/docker_env/web/DockerfileBuild b/docker_env/web/DockerfileBuild
index 284221c..1f725ca 100644
--- a/docker_env/web/DockerfileBuild
+++ b/docker_env/web/DockerfileBuild
@@ -1,4 +1,4 @@
FROM node:16.19-alpine
WORKDIR /
COPY ./web/package.json .
-RUN yarn install --registry=https://registry.npm.taobao.org
+RUN yarn install --registry=https://registry.npmmirror.com
diff --git a/web/src/utils/columnPermission.ts b/web/src/utils/columnPermission.ts
index e35030d..4a9d9f1 100644
--- a/web/src/utils/columnPermission.ts
+++ b/web/src/utils/columnPermission.ts
@@ -47,6 +47,8 @@ export const handleColumnPermission = async (func: Function, crudOptions: any,ex
continue
} else if(item.field_name === col) {
columns[col].column.show = item['is_query']
+ // 如果列表不可见,则禁止在列设置中选择
+ if(!item['is_query'])columns[col].column.columnSetDisabled = true
columns[col].addForm = {
show: item['is_create']
}
diff --git a/web/src/views/system/menu/components/MenuButtonCom/api.ts b/web/src/views/system/menu/components/MenuButtonCom/api.ts
index bc473fc..d91f920 100644
--- a/web/src/views/system/menu/components/MenuButtonCom/api.ts
+++ b/web/src/views/system/menu/components/MenuButtonCom/api.ts
@@ -39,3 +39,12 @@ export function DelObj(id: DelReq) {
data: { id },
});
}
+
+export function BatchAdd(obj: AddReq) {
+ return request({
+ url: apiPrefix + 'batch_create/',
+ method: 'post',
+ data: obj,
+ });
+}
+
diff --git a/web/src/views/system/menu/components/MenuButtonCom/crud.tsx b/web/src/views/system/menu/components/MenuButtonCom/crud.tsx
index c1a7a1f..908cf2a 100644
--- a/web/src/views/system/menu/components/MenuButtonCom/crud.tsx
+++ b/web/src/views/system/menu/components/MenuButtonCom/crud.tsx
@@ -2,6 +2,8 @@ import {AddReq, DelReq, EditReq, dict, CreateCrudOptionsRet, CreateCrudOptionsPr
import * as api from './api';
import {auth} from '/@/utils/authFunction'
import {request} from '/@/utils/service';
+import { successNotification } from '/@/utils/message';
+import { ElMessage } from 'element-plus';
//此处为crudOptions配置
export const createCrudOptions = function ({crudExpose, context}: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async () => {
@@ -40,6 +42,22 @@ export const createCrudOptions = function ({crudExpose, context}: CreateCrudOpti
add: {
show: auth('btn:Create')
},
+ batchAdd: {
+ show: true,
+ type: 'primary',
+ text: '批量生成',
+ click: async () => {
+ if (context!.selectOptions.value.id == undefined) {
+ ElMessage.error('请选择菜单');
+ return;
+ }
+ const result = await api.BatchAdd({ menu: context!.selectOptions.value.id });
+ if (result.code == 2000) {
+ successNotification(result.msg);
+ crudExpose.doRefresh();
+ }
+ },
+ },
},
},
rowHandle: {
diff --git a/web/src/views/system/menu/components/MenuFieldCom/index.vue b/web/src/views/system/menu/components/MenuFieldCom/index.vue
index ec3822b..435ce3d 100644
--- a/web/src/views/system/menu/components/MenuFieldCom/index.vue
+++ b/web/src/views/system/menu/components/MenuFieldCom/index.vue
@@ -4,8 +4,15 @@