重构: 整体提交

pull/48/head
李强 2022-04-05 13:25:15 +08:00
parent 136ff839b6
commit 19eda2533c
490 changed files with 522 additions and 42820 deletions

25
.gitignore vendored
View File

@ -1,22 +1,3 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
docker_env/mysql/data/
docker_env/redis/data/
*/.idea
dvadmin-doc/docs/.vuepress/dist
/backend/venv
/backend/.idea
.idea

214
LICENSE
View File

@ -1,21 +1,201 @@
MIT License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Copyright (c) 2021 李强
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
1. Definitions.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2022] [django-vue-admin]
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.

13
NOTICE Normal file
View File

@ -0,0 +1,13 @@
Copyright 2021 李强
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.

224
README.md
View File

@ -1,24 +1,52 @@
# Django-Vue-Admin
[![img](https://img.shields.io/badge/license-MIT-blue.svg)](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [![img](https://img.shields.io/badge/python-%3E=3.6.x-green.svg)](https://python.org/) [![PyPI - Django Version badge](https://img.shields.io/badge/django%20versions-2.2-blue)](https://docs.djangoproject.com/zh-hans/2.2/) [![img](https://img.shields.io/badge/node-%3E%3D%2012.0.0-brightgreen)](https://nodejs.org/zh-cn/) [![img](https://gitee.com/liqianglog/django-vue-admin/badge/star.svg?theme=dark)](https://gitee.com/liqianglog/django-vue-admin)
[![img](https://img.shields.io/badge/license-MIT-blue.svg)](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [![img](https://img.shields.io/badge/python-%3E=3.6.x-green.svg)](https://python.org/) [![PyPI - Django Version badge](https://img.shields.io/badge/django%20versions-3.2-blue)](https://docs.djangoproject.com/zh-hans/3.2/) [![img](https://img.shields.io/badge/node-%3E%3D%2012.0.0-brightgreen)](https://nodejs.org/zh-cn/) [![img](https://gitee.com/liqianglog/django-vue-admin/badge/star.svg?theme=dark)](https://gitee.com/liqianglog/django-vue-admin)
[预 览](https://demo.django-vue-admin.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/) | [Github](https://github.com/liqianglog/django-vue-admin)
[预 览](https://demo.django-vue-admin.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-Vue-Admin 是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
💡 [django-vue-admin](https://gitee.com/dvadmin/django-vue-admin) 是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 🧑‍🤝‍🧑前端采用[D2Admin](https://github.com/d2-projects/d2-admin) 、[Vue](https://cn.vuejs.org/)、[ElementUI](https://element.eleme.cn/)。
* 👭后端采用 Python 语言 Django 框架以及强大的 [Django REST Framework](https://pypi.org/project/djangorestframework)。
* 👫权限认证使用[Django REST Framework SimpleJWT](https://pypi.org/project/djangorestframework-simplejwt),支持多终端认证系统。
* 👬支持加载动态权限菜单,多方式轻松权限控制。
* 💏特别鸣谢:[D2Admin](https://github.com/d2-projects/d2-admin) 、[Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin)。
* 💡 特别感谢[jetbrains](https://www.jetbrains.com/) 为本开源项目提供免费的 IntelliJ IDEA 授权。
## 在线体验
👩‍👧‍👦演示地址:[http://demo.django-vue-admin.com](http://demo.django-vue-admin.com)
账号superadmin
密码superadmin123456
👩‍👦‍👦文档地址:[https://django-vue-admin.com](https://django-vue-admin.com)
* 前端采用ruoyi-ui 、Vue、Element UI。
* 后端采用Python语言Django框架。
* 权限认证使用Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 特别鸣谢:<u>[Gin-Vue-Admin](https://www.gin-vue-admin.com/)</u>[RuoYi](https://gitee.com/y_project/RuoYi-Vue) [Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin)。
## 交流
- 社区:[戳我](https://bbs.django-vue-admin.com)
- 交流社区:[戳我](https://bbs.django-vue-admin.com)👩‍👦‍👦
- QQ群号812482043 <a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=fOdnHhC8DJlRHGYSnyhoB8P5rgogA6Vs&jump_from=webapi"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="django-vue-admin交流01群" title="django-vue-admin交流01群"></a>
- 插件市场:[戳我](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)
- 二维码
@ -26,78 +54,70 @@ Django-Vue-Admin 是一套全部开源的快速开发平台,毫无保留给个
## 源码地址
gitee地址(主推)[https://gitee.com/liqianglog/django-vue-admin](https://gitee.com/liqianglog/django-vue-admin)
gitee地址(主推)[https://gitee.com/liqianglog/django-vue-admin](https://gitee.com/liqianglog/django-vue-admin)👩‍👦‍👦
github地址[https://github.com/liqianglog/django-vue-admin](https://github.com/liqianglog/django-vue-admin)👩‍👦‍👦
github地址[https://github.com/liqianglog/django-vue-admin](https://github.com/liqianglog/django-vue-admin)
## 内置功能
##### 后期版本 [版本功能说明](https://gitee.com/liqianglog/django-vue-admin/wikis/releaseNote?sort_id=3615540)
1. 👨‍⚕️菜单管理:配置系统菜单,操作权限,按钮权限标识、后端接口权限等。
2. 🧑‍⚕️部门管理:配置系统组织机构(公司、部门、角色)。
3. 👩‍⚕️角色管理:角色菜单权限分配、数据权限分配、设置角色按部门进行数据范围权限划分。
4. 🧑‍🎓权限权限:授权角色的权限范围。
5. 👨‍🎓用户管理:用户是系统操作者,该功能主要完成系统用户配置。
6. 👬接口白名单:配置不需要进行权限校验的接口。
7. 🧑‍🔧字典管理:对系统中经常使用的一些较为固定的数据进行维护。
8. 🧑‍🔧地区管理:对省市县区域进行管理。
9. 📁附件管理:对平台上所有文件、图片等进行统一管理。
10. 🗓️操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
11. 🔌[插件市场 ](https://bbs.django-vue-admin.com/plugMarket.html)基于Django-Vue-Admin框架开发的应用和插件。
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识、后端接口权限等。
5. 角色管理:角色菜单权限分配、数据权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 文件管理:管理所有上传的和导出的文件。
9. 通知公告:发布通知公告给所有人,进行消息的通知。
10. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
11. 登录日志:系统登录日志记录查询包含登录异常。
12. 定时日志celery定时任务执行日志记录。
13. 在线用户:当前系统中活跃用户状态监控、用户强退功能。
14. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
15. 在线构建器拖动表单元素生成相应的HTML代码。
16. 服务监控进行可视化的服务器监控CPU、内存、文件使用率等信息。
## 插件市场 🔌
## 在线体验
- Celery异步任务[dvadmin-celery](https://gitee.com/huge-dream/dvadmin-celery)
- 升级中心后端:[dvadmin-upgrade-center](https://gitee.com/huge-dream/dvadmin-upgrade-center)
- 升级中心前端:[dvadmin-upgrade-center-web](https://gitee.com/huge-dream/dvadmin-upgrade-center-web)
演示地址:[http://demo.django-vue-admin.com](http://demo.django-vue-admin.com) 账号admin 密码123456
## 准备工作
~~~
Python >= 3.6.0 (推荐3.8+版本)
nodejs >= 14.0 (推荐最新)
Mysql >= 5.7.0 (可选默认数据库sqlite3推荐8.0版本)
Redis(可选,最新版)
~~~
文档地址:[http://django-vue-admin.com](http://django-vue-admin.com)
## 前端
### 开发
## 前端♝
```bash
# 克隆项目
git clone https://gitee.com/liqianglog/django-vue-admin.git
# 进入项目目录
cd dvadmin-ui
cd web
# 安装依赖
npm install --registry=https://registry.npm.taobao.org
# 启动服务
npm run dev
# 浏览器访问 http://localhost:8080
# .env.development 文件中可配置启动端口等参数
```
### 发布
```bash
# 构建测试环境
npm run build:stage
# 构建生产环境
npm run build:prod
# npm run build
```
## 后端
## 后端💈
~~~bash
1. 进入项目目录 cd dvadmin-backend
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. 执行迁移命令:
@ -105,75 +125,67 @@ npm run build:prod
python3 manage.py migrate
6. 初始化数据
python3 manage.py init
7. 启动项目
python3 manage.py runserver 127.0.0.1:8000
定时任务启动命令:
celery -A application worker -B --loglevel=info
注:
Windows 运行celery 需要安装 pip install eventlet
celery -A application worker -P eventlet --loglevel=info
初始账号admin 密码123456
后端接口文档地址http://127.0.0.1:8000/docs/
7. 初始化省市县数据:
python3 manage.py init_area
8. 启动项目
python3 manage.py runserver 0.0.0.0:8000
或使用 daphne :
daphne -b 0.0.0.0 -8000 application.asgi:application
~~~
### 访问项目
- 访问地址:[http://localhost:8080](http://localhost:8080) (默认为此地址,如有修改请按照配置文件)
- 账号:`superadmin` 密码:`admin123456`
### docker-compose 运行
~~~shell
# 先安装docker-compose (自行百度安装),执行此命令等待安装
docker-compose up
# 先安装docker-compose (自行百度安装),执行此命令等待安装如有使用celery插件请打开docker-compose.yml中celery 部分注释
docker-compose up -d
# 初始化后端数据(第一次执行即可)
docker exec -ti dvadmin-django bash
docker exec -ti DVAdmin-django bash
python manage.py makemigrations
python manage.py migrate
python manage.py init -y
exit
前端地址http://127.0.0.1:8080
后端地址http://127.0.0.1:8000
账号admin 密码123456
# 在服务器上请把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
~~~
## 演示图
## 演示图✅
![image-01](https://gitee.com/liqianglog/pic/raw/master/master/01.png)
![image-02](https://gitee.com/liqianglog/pic/raw/master/master/02.png)
![image-03](https://gitee.com/liqianglog/pic/raw/master/master/03.png)
![image-04](https://gitee.com/liqianglog/pic/raw/master/master/04.png)
![image-05](https://gitee.com/liqianglog/pic/raw/master/master/05.png)
![image-06](https://gitee.com/liqianglog/pic/raw/master/master/06.png)
![image-07](https://gitee.com/liqianglog/pic/raw/master/master/06.png)
![image-08](https://gitee.com/liqianglog/pic/raw/master/master/08.png)
<table>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/155624_fc01f49e_5074988.jpeg" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/162526_68e8c4c5_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/163049_0a16b3b8_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/163157_628941bc_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/163444_73d4a6ae_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/163456_c4ddcaf6_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/163732_48cca279_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/163756_99176d5d_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/164149_b223657a_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/164226_58653572_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/164259_e06fbfe9_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/164330_6406c28f_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/164359_add984a1_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/181144_9665dae5_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/181700_25edc19f_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/181715_9305b7e8_5074988.png" height="200" width="400"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/181732_953b05e4_5074988.png" height="200" width="400"/></td>
<td><img src="https://images.gitee.com/uploads/images/2021/0505/182122_73bddac6_5074988.png" height="200" width="400"/></td>
</tr>
</table>

View File

@ -1,92 +1,37 @@
# start django command
# local domain
# saas-local.anthembj.com
# ceshi-local.anthembj.com
# docker-compose run --entrypoint '/backend/docker_start.sh' -p 8000:8000 docker_django
version: "3"
services:
dvadmin-ui:
container_name: dvadmin-ui
DVAdmin-web:
container_name: DVAdmin-web
ports:
- "8080:8080"
build:
context: ./
dockerfile: ./docker_env/vue-ui/Dockerfile
dockerfile: ./docker_env/web/Dockerfile
environment:
TZ: Asia/Shanghai
volumes:
- "./dvadmin-ui:/dvadmin-ui"
command:
- /bin/bash
- -c
- |
cd /dvadmin-ui
npm install --registry=https://registry.npm.taobao.org
rm -rf /dvadmin-ui/dist
npm run build:prod
npm run dev
dvadmin-redis:
image: redis:latest
container_name: dvadmin-redis
ports:
- "6380:6379"
- ./docker_env/nginx/my.conf:/etc/nginx/conf.d/my.conf
expose:
- "6379"
volumes:
- ./docker_env/redis/data:/data
- ./docker_env/redis/redis.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
- "8080"
networks:
- dvadmin_net
network:
ipv4_address: 177.7.0.11
dvadmin-mysql:
image: mysql:5.7
container_name: dvadmin-mysql
#使用该参数container内的root拥有真正的root权限否则container内的root只是外部的一个普通用户权限
#设置为true不然数据卷可能挂载不了启动不起
privileged: true
restart: always
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: "q1w2e3r4T%Y^U&MYSQL"
MYSQL_DATABASE: "django-vue-admin"
TZ: Asia/Shanghai
command:
--wait_timeout=31536000
--interactive_timeout=31536000
--max_connections=1000
--default-authentication-plugin=mysql_native_password
volumes:
#映射mysql的数据目录到宿主机保存数据
- "./docker_env/mysql/data:/var/lib/mysql"
#根据宿主机下的配置文件创建容器
- "./docker_env/mysql/conf.d:/etc/mysql/conf.d"
- "./docker_env/mysql/logs:/logs"
networks:
- dvadmin_net
dvadmin-django:
DVAdmin-django:
build:
context: .
dockerfile: ./docker_env/django/Dockerfile
# image: django:2.2
container_name: dvadmin-django
working_dir: /dvadmin-backend
# command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput && python manage.py runserver"
# command: bash
depends_on:
- dvadmin-mysql
- dvadmin-redis
container_name: DVAdmin-django
working_dir: /backend
# 打开mysql 时,打开此选项
# depends_on:
# - DVAdmin-mysql
environment:
- REDIS_HOST=dvadmin-redis
- DATABASE_HOST=dvadmin-mysql
PYTHONUNBUFFERED: 1
DATABASE_HOST: DVAdmin-mysql
TZ: Asia/Shanghai
volumes:
- ./dvadmin-backend:/dvadmin-backend
- ./backend:/backend
- ./logs/log:/var/log
ports:
- "8000:8000"
@ -94,31 +39,62 @@ services:
- "8000"
restart: always
networks:
- dvadmin_net
network:
ipv4_address: 177.7.0.12
# DVAdmin-mysql:
# image: mysql:5.7
# container_name: DVAdmin-mysql
# #使用该参数container内的root拥有真正的root权限否则container内的root只是外部的一个普通用户权限
# #设置为true不然数据卷可能挂载不了启动不起
## privileged: true
# restart: always
# ports:
# - "3306:3306"
# environment:
# MYSQL_ROOT_PASSWORD: "123456"
# MYSQL_DATABASE: "dvadmin_pro"
# TZ: Asia/Shanghai
# command:
# --wait_timeout=31536000
# --interactive_timeout=31536000
# --max_connections=1000
# --default-authentication-plugin=mysql_native_password
# volumes:
# - "./docker_env/mysql/data:/var/lib/mysql"
# - "./docker_env/mysql/conf.d:/etc/mysql/conf.d"
# - "./docker_env/mysql/logs:/logs"
# networks:
# network:
# ipv4_address: 177.7.0.13
dvadmin-celery:
build:
context: .
dockerfile: ./docker_env/celery/Dockerfile
# image: django:2.2
container_name: dvadmin-celery
working_dir: /dvadmin-backend
# command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput && python manage.py runserver"
# command: bash
depends_on:
- dvadmin-mysql
- dvadmin-redis
environment:
- REDIS_HOST=dvadmin-redis
- DATABASE_HOST=dvadmin-mysql
volumes:
- ./dvadmin-backend:/dvadmin-backend
- ./logs/log:/var/log
restart: always
networks:
- dvadmin_net
# 如果使用celery 插件,请自行打开此注释
# DVAdmin-celery:
# build:
# context: .
# dockerfile: ./docker_env/celery/Dockerfile
# # image: django:2.2
# container_name: DVAdmin-celery
# working_dir: /backend
# depends_on:
# - DVAdmin-mysql
# environment:
# PYTHONUNBUFFERED: 1
# DATABASE_HOST: DVAdmin-mysql
# TZ: Asia/Shanghai
# volumes:
# - ./backend:/backend
# - ./logs/log:/var/log
# restart: always
# networks:
# network:
# ipv4_address: 177.7.0.14
networks:
dvadmin_net:
driver: bridge
network:
ipam:
driver: default
config:
- subnet: '177.7.0.0/16'

65
docker_env/README.md Normal file
View File

@ -0,0 +1,65 @@
# docker 镜像打包
### 打包web基础Build包
~~~sh
# 编译打包到本地
docker build -f ./docker_env/web/DockerfileBuild -t registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/node12-base-web:latest .
# 上传到阿里云仓库
docker push registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/node12-base-web:latest
~~~
### 打包Backend基础Build包
~~~sh
# 编译打包到本地
docker build -f ./docker_env/django/DockerfileBuild -t registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/python38-base-backend:latest .
# 上传到阿里云仓库
docker push registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/python38-base-backend:latest
~~~
### 运行前端
~~~
docker build -f ./docker_env/web/Dockerfile -t dvadmin-pro-web .
~~~
### 运行后端
~~~
docker build -f ./docker_env/django/Dockerfile -t dvadmin-pro-django .
~~~
### 运行celery
~~~
docker build -f ./docker_env/celery/Dockerfile -t dvadmin-pro-celery .
~~~
## docker-compose 运行
~~~
# 先安装docker-compose (自行百度安装),执行此命令等待安装如有使用celery插件请打开docker-compose.yml中celery 部分注释
docker-compose up -d
# 初始化后端数据(第一次执行即可)
docker exec -ti dvadmin-django bash
python manage.py makemigrations
python manage.py migrate
python manage.py init -y
exit
前端地址http://127.0.0.1:8080
后端地址http://127.0.0.1:8000
# 在服务器上请把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
~~~

View File

@ -1,16 +1,7 @@
FROM python:3.8
# ENV PYTHONUNBUFFERED 1
RUN sed -i s/deb.debian.org/mirrors.163.com/g /etc/apt/sources.list
RUN cat /etc/apt/sources.list
RUN apt-get clean
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y python3.8-dev libpq-dev libopencv-dev
RUN apt-get install -y redis-tools
RUN mkdir /dvadmin-backend
WORKDIR /dvadmin-backend
COPY ./dvadmin-backend/requirements.txt /
COPY ./dvadmin-backend/conf/env.example.py /dvadmin-backend/conf/env.py
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r /requirements.txt
FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/python38-base-backend:latest
WORKDIR /backend
COPY ./backend/ .
RUN awk 'BEGIN { cmd="cp -i ./conf/env.example.py ./conf/env.py "; print "n" |cmd; }'
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt
CMD ["celery", "-A", "application", "worker", "-B", "--loglevel=info"]

View File

@ -1,2 +0,0 @@
cd ../../backend/
docker build -f docker_env/celery/Dockerfile -t celery:1.0 .

View File

@ -1,16 +1,6 @@
FROM python:3.8
# ENV PYTHONUNBUFFERED 1
RUN sed -i s/deb.debian.org/mirrors.163.com/g /etc/apt/sources.list
RUN cat /etc/apt/sources.list
RUN apt-get clean
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y python3.8-dev libpq-dev libopencv-dev
RUN apt-get install -y redis-tools
RUN mkdir /dvadmin-backend
WORKDIR /dvadmin-backend
COPY ./dvadmin-backend/requirements.txt /
COPY ./dvadmin-backend/conf/env.example.py /dvadmin-backend/conf/env.py
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r /requirements.txt
CMD ["/dvadmin-backend/docker_start.sh"]
# ENTRYPOINT [ "uwsgi --ini /backend/azcrm/uwsgi.ini" ]
FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/python38-base-backend:latest
WORKDIR /backend
COPY ./backend/ .
RUN awk 'BEGIN { cmd="cp -i ./conf/env.example.py ./conf/env.py "; print "n" |cmd; }'
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt
CMD ["daphne","-b","0.0.0.0","-p","8000","application.asgi:application"]

View File

@ -0,0 +1,8 @@
FROM python:3.8-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update && apk add bash bash-doc bash-completion git freetds-dev jpeg-dev linux-headers mysql-client mariadb-dev build-base libffi-dev openssl-dev zlib-dev bzip2-dev pcre-dev ncurses-dev readline-dev tk-dev postgresql-dev
WORKDIR /backend
COPY ./backend/requirements.txt /
COPY ./docker_env/requirements-all.txt /
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r /requirements.txt
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r /requirements-all.txt

View File

@ -1,3 +0,0 @@
cd ../../dvadmin-backend/
docker build -f docker_env/django/Dockerfile -t django:2.2 .

View File

@ -18,7 +18,7 @@ symbolic-links=0
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemdd
#允许最大连接数
max_connections=200
max_connections=1000
#服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
#创建新表时将使用的默认存储引擎

22
docker_env/nginx/my.conf Normal file
View File

@ -0,0 +1,22 @@
server {
listen 8080;
server_name localhost;
client_max_body_size 100M;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
root /usr/share/nginx/html;
index index.html index.php index.htm;
}
location /api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^/api/(.*)$ /$1 break; #重写
proxy_pass http://177.7.0.12:8000/; # 设置代理服务器的协议和地址
}
}

View File

@ -1,9 +0,0 @@
cur_path=`pwd`
# docker pull redis:latest
docker run -d \
-p 6379:6379 \
-v $cur_path/redis.conf:/etc/redis/redis.conf \
--privileged=true \
--name docker-redis \
redis:latest \
redis-server /etc/redis/redis.conf

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
FROM node:12
COPY ./dvadmin-ui/package.json /
RUN npm install --registry=https://registry.npm.taobao.org
#RUN npm run build:prod
#CMD ["npm","run","dev"]

View File

@ -0,0 +1,9 @@
FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/node12-base-web:latest
WORKDIR /web/
COPY web/. .
RUN npm install --registry=https://registry.npm.taobao.org
RUN npm run build
FROM nginx:alpine
COPY ./docker_env/nginx/my.conf /etc/nginx/conf.d/my.conf
COPY --from=0 /web/dist /usr/share/nginx/html

View File

@ -0,0 +1,3 @@
FROM node:14-alpine
COPY ./web/package.json /
RUN npm install --registry=https://registry.npm.taobao.org

View File

@ -1,97 +0,0 @@
# Byte-compiled / optimized / DLL files
*.py[cod]
*$py.class
__pycache__/
# C extensions
*.so
# Distribution / packaging
.Python
env/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
.idea/
*.db
.DS_Store
__pycache__
migrations/
!migrations/__init__.py
*.pyc
conf/
!conf/env.example.py
db.sqlite3

View File

@ -1,18 +0,0 @@
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings')
django.setup()
from channels.auth import AuthMiddlewareStack
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter, URLRouter
websocket_urlpatterns = [
]
application = ProtocolTypeRouter({
"http": AsgiHandler(),
# Just HTTP for now. (We can add other protocols later.)
'websocket': AuthMiddlewareStack(URLRouter(websocket_urlpatterns, )),
})

View File

@ -1,14 +0,0 @@
import os
import django
from celery import Celery, platforms
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', "application.settings")
django.setup()
app = Celery(f"dvadmin")
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
platforms.C_FORCE_ROOT = True

View File

@ -1,336 +0,0 @@
"""
Django settings for application project.
Generated by 'django-admin startproject' using Django 2.2.16.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
# 导入全局环境变量
import datetime
import os
import sys
from mongoengine import connect
from conf.env import *
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ')ns9h-%fl^&ro=+-vgl*b-!+a%2=tuwc#&xbpmcavj0*ufpyjh'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ALLOWED_HOSTS
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'captcha',
'django_celery_beat',
'drf_yasg', # swagger 接口
# 自定义app
'apps.vadmin.permission',
'apps.vadmin.op_drf',
'apps.vadmin.system',
'apps.vadmin.celery',
'apps.vadmin.monitor',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'vadmin.op_drf.middleware.ApiLoggingMiddleware', # 用于记录API访问日志
'vadmin.op_drf.middleware.PermissionModeMiddleware', # 权限中间件
]
# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL
# 允许ajax请求携带cookie
CORS_ALLOW_CREDENTIALS = CORS_ALLOW_CREDENTIALS
X_FRAME_OPTIONS = "ALLOW-FROM"
ROOT_URLCONF = 'application.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'application.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
# 配置语言
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
"""
静态目录多媒体配置
"""
# 访问静态文件的url地址前缀
STATIC_URL = '/static/'
# 收集静态文件,必须将 MEDIA_ROOT,STATICFILES_DIRS先注释
# python manage.py collectstatic
# STATIC_ROOT=os.path.join(BASE_DIR,'static')
# # 设置django的静态文件目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
if not os.path.exists(os.path.join(BASE_DIR, 'media')):
os.makedirs(os.path.join(BASE_DIR, 'media'))
# 访问上传文件的url地址前缀
MEDIA_URL = "/media/"
# 项目中存储上传文件的根目录
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
"""
日志配置
"""
# log 配置部分BEGIN #
SERVER_LOGS_FILE = os.path.join(BASE_DIR, 'logs', 'server.log')
ERROR_LOGS_FILE = os.path.join(BASE_DIR, 'logs', 'error.log')
if not os.path.exists(os.path.join(BASE_DIR, 'logs')):
os.makedirs(os.path.join(BASE_DIR, 'logs'))
# 格式:[2020-04-22 23:33:01][micoservice.apps.ready():16] [INFO] 这是一条日志:
# 格式:[日期][模块.函数名称():行号] [级别] 信息
STANDARD_LOG_FORMAT = '[%(asctime)s][%(name)s.%(funcName)s():%(lineno)d] [%(levelname)s] %(message)s'
CONSOLE_LOG_FORMAT = '[%(asctime)s][%(name)s.%(funcName)s():%(lineno)d] [%(levelname)s] %(message)s'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': STANDARD_LOG_FORMAT
},
'console': {
'format': CONSOLE_LOG_FORMAT,
'datefmt': '%Y-%m-%d %H:%M:%S',
},
'file': {
'format': CONSOLE_LOG_FORMAT,
'datefmt': '%Y-%m-%d %H:%M:%S',
},
},
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': SERVER_LOGS_FILE,
'maxBytes': 1024 * 1024 * 100, # 100 MB
'backupCount': 5, # 最多备份5个
'formatter': 'standard',
'encoding': 'utf-8',
},
'error': {
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'filename': ERROR_LOGS_FILE,
'maxBytes': 1024 * 1024 * 100, # 100 MB
'backupCount': 3, # 最多备份3个
'formatter': 'standard',
'encoding': 'utf-8',
},
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'console',
}
},
'loggers': {
# default日志
'': {
'handlers': ['console', 'error', 'file'],
'level': 'INFO',
},
# 数据库相关日志
'django.db.backends': {
'handlers': [],
'propagate': True,
'level': 'INFO',
},
}
}
# ================================================= #
# ************** 数据库 配置 ************** #
# ================================================= #
if DATABASE_TYPE == "MYSQL":
# Mysql数据库
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"HOST": os.getenv('DATABASE_HOST') or DATABASE_HOST,
"PORT": DATABASE_PORT,
"USER": DATABASE_USER,
"PASSWORD": DATABASE_PASSWORD,
"NAME": DATABASE_NAME,
}
}
else:
# sqlite3 数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# redis 缓存
REDIS_URL = f'redis://:{REDIS_PASSWORD if REDIS_PASSWORD else ""}@{os.getenv("REDIS_HOST") or REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}'
# 是否启用redis
if locals().get("REDIS_ENABLE", True):
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": REDIS_URL,
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
# ================================================= #
# ******************** JWT配置 ******************** #
# ================================================= #
JWT_AUTH = {
'JWT_ALLOW_REFRESH': True,
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=60 * 60 * 24), # JWT有效时间24小时
'JWT_AUTH_HEADER_PREFIX': 'Bearer', # JWT的Header认证头以'JWT '开始
'JWT_AUTH_COOKIE': 'AUTH_JWT',
'JWT_VERIFY_EXPIRATION': True,
'JWT_PAYLOAD_HANDLER': 'apps.vadmin.utils.jwt_util.jwt_payload_handler',
'JWT_GET_USER_SECRET_KEY': 'apps.vadmin.utils.jwt_util.jwt_get_user_secret_key',
'JWT_RESPONSE_PAYLOAD_HANDLER': 'apps.vadmin.utils.jwt_util.jwt_response_payload_handler',
}
# ================================================= #
# ************** REST_FRAMEWORK 配置 ************** #
# ================================================= #
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'apps.vadmin.utils.authentication.RedisOpAuthJwtAuthentication',
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
'DEFAULT_PAGINATION_CLASS': 'vadmin.op_drf.pagination.Pagination',
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
'EXCEPTION_HANDLER': 'apps.vadmin.utils.exceptions.op_exception_handler',
}
# ================================================= #
# ************** 登录方式配置 ************** #
# ================================================= #
AUTHENTICATION_BACKENDS = (
'apps.vadmin.utils.backends.CustomBackend',
'apps.vadmin.utils.backends.SessionAuthentication',
)
AUTH_USER_MODEL = 'permission.UserProfile'
# username_field
USERNAME_FIELD = 'username'
# ================================================= #
# ************** 登录验证码配置 ************** #
# ================================================= #
CAPTCHA_STATE = CAPTCHA_STATE
# 字母验证码
CAPTCHA_IMAGE_SIZE = (160, 60) # 设置 captcha 图片大小
CAPTCHA_LENGTH = 4 # 字符个数
CAPTCHA_TIMEOUT = 1 # 超时(minutes)
# 加减乘除验证码
CAPTCHA_OUTPUT_FORMAT = '%(image)s %(text_field)s %(hidden_field)s '
CAPTCHA_FONT_SIZE = 40 # 字体大小
CAPTCHA_FOREGROUND_COLOR = '#0033FF' # 前景色
CAPTCHA_BACKGROUND_COLOR = '#F5F7F4' # 背景色
CAPTCHA_NOISE_FUNCTIONS = (
# 'captcha.helpers.noise_arcs', # 线
# 'captcha.helpers.noise_dots', # 点
)
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
API_LOG_ENABLE = True
# API_LOG_METHODS = 'ALL' # ['POST', 'DELETE']
# API_LOG_METHODS = ['POST', 'DELETE'] # ['POST', 'DELETE']
BROKER_URL = f'redis://:{REDIS_PASSWORD if REDIS_PASSWORD else ""}@{os.getenv("REDIS_HOST") or REDIS_HOST}:' \
f'{REDIS_PORT}/{locals().get("CELERY_DB", 2)}' # Broker使用Redis
CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' # Backend数据库
# ================================================= #
# ************** 其他配置 ************** #
# ================================================= #
# 接口权限
INTERFACE_PERMISSION = locals().get("INTERFACE_PERMISSION", False)
DJANGO_CELERY_BEAT_TZ_AWARE = False
CELERY_TIMEZONE = 'Asia/Shanghai' # celery 时区问题

View File

@ -1,63 +0,0 @@
"""application URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from captcha.conf import settings as ca_settings
from captcha.helpers import captcha_image_url, captcha_audio_url
from captcha.models import CaptchaStore
from django.conf import settings
from django.urls import re_path, include
from django.views.static import serve
from rest_framework.views import APIView
from apps.vadmin.op_drf.response import SuccessResponse
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact@snippets.local"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
class CaptchaRefresh(APIView):
authentication_classes = []
permission_classes = []
def get(self, request):
new_key = CaptchaStore.pick()
to_json_response = {
"key": new_key,
"image_url": captcha_image_url(new_key),
"audio_url": captcha_audio_url(new_key) if ca_settings.CAPTCHA_FLITE_PATH else None,
}
return SuccessResponse(to_json_response)
urlpatterns = [
re_path(r'media/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT}),
re_path(r'^admin/', include('apps.vadmin.urls')),
re_path(r'^$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

View File

@ -1,11 +0,0 @@
[uwsgi]
chdir = /dvadmin-backend
wsgi-file = /dvadmin-backend/application/wsgi.py
master = true
processes = 8
http-socket = 0.0.0.0:8000
module = application.wsgi:application
vacuum = true
log-maxsize = 20000000
log-reopen = true
buffer-size = 65536

View File

@ -1,16 +0,0 @@
"""
WSGI config for application project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "application.settings")
application = get_wsgi_application()

View File

@ -1 +0,0 @@
from django.contrib import admin

View File

@ -1,7 +0,0 @@
from django.apps import AppConfig
class DpCmdbConfig(AppConfig):
name = 'apps.vadmin.celery'

View File

@ -1,21 +0,0 @@
import django_filters
from django_celery_beat.models import IntervalSchedule, CrontabSchedule, PeriodicTask
class IntervalScheduleFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = IntervalSchedule
fields = '__all__'
class CrontabScheduleFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = CrontabSchedule
exclude = ('timezone',)
class PeriodicTaskFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = PeriodicTask
fields = '__all__'

View File

@ -1,41 +0,0 @@
from django_celery_beat.models import IntervalSchedule, CrontabSchedule, PeriodicTask
from rest_framework import serializers
from apps.vadmin.op_drf.serializers import CustomModelSerializer
from apps.vadmin.utils.exceptions import APIException
class IntervalScheduleSerializer(CustomModelSerializer):
class Meta:
model = IntervalSchedule
fields = '__all__'
class CrontabScheduleSerializer(CustomModelSerializer):
def save(self, **kwargs):
queryset = CrontabSchedule.objects.filter(**self.validated_data)
if queryset.count() and (
queryset.count() == 1 and self.initial_data.get('id', None) not in queryset.values_list('id',
flat=True)):
raise APIException(message='值已存在!!!')
super().save(**kwargs)
class Meta:
model = CrontabSchedule
exclude = ('timezone',)
class PeriodicTaskSerializer(CustomModelSerializer):
interval_list = serializers.SerializerMethodField(read_only=True)
crontab_list = serializers.SerializerMethodField(read_only=True)
def get_interval_list(self, obj):
return IntervalScheduleSerializer(obj.interval).data if obj.interval else {}
def get_crontab_list(self, obj):
return CrontabScheduleSerializer(obj.crontab).data if obj.crontab else {}
class Meta:
model = PeriodicTask
fields = '__all__'

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,20 +0,0 @@
from django.conf.urls import url
from rest_framework.routers import DefaultRouter
from rest_framework.urlpatterns import format_suffix_patterns
from apps.vadmin.celery.views import IntervalScheduleModelViewSet, CrontabScheduleModelViewSet, PeriodicTaskModelViewSet, TasksAsChoices, \
OperateCeleryTask
router = DefaultRouter()
# 调度间隔
router.register(r'intervalschedule', IntervalScheduleModelViewSet)
router.register(r'crontabschedule', CrontabScheduleModelViewSet)
router.register(r'periodictask', PeriodicTaskModelViewSet)
urlpatterns = format_suffix_patterns([
# 获取所有 tasks 名称
url(r'^tasks_as_choices/', TasksAsChoices.as_view()),
url(r'^operate_celery/', OperateCeleryTask.as_view()),
])
urlpatterns += router.urls

View File

@ -1,99 +0,0 @@
from django_celery_beat.admin import TaskSelectWidget
from django_celery_beat.models import IntervalSchedule, CrontabSchedule, PeriodicTask
from rest_framework.views import APIView
from apps.vadmin.celery.filters import IntervalScheduleFilter, CrontabScheduleFilter, PeriodicTaskFilter
from apps.vadmin.celery.serializers import IntervalScheduleSerializer, CrontabScheduleSerializer, PeriodicTaskSerializer
from apps.vadmin.op_drf.views import CustomAPIView
from apps.vadmin.op_drf.viewsets import CustomModelViewSet
from apps.vadmin.op_drf.response import SuccessResponse
class IntervalScheduleModelViewSet(CustomModelViewSet):
"""
IntervalSchedule 调度间隔模型
every 次数
period 时间(,小时,分钟,.毫秒)
"""
queryset = IntervalSchedule.objects.all()
serializer_class = IntervalScheduleSerializer
create_serializer_class = IntervalScheduleSerializer
update_serializer_class = IntervalScheduleSerializer
filter_class = IntervalScheduleFilter
search_fields = ('every', 'period')
ordering = 'every' # 默认排序
class CrontabScheduleModelViewSet(CustomModelViewSet):
"""
CrontabSchedule crontab调度模型
minute 分钟
hour 小时
day_of_week 每周的周几
day_of_month 每月的某一天
month_of_year 每年的某一个月
"""
queryset = CrontabSchedule.objects.all()
serializer_class = CrontabScheduleSerializer
filter_class = CrontabScheduleFilter
search_fields = ('minute', 'hour')
ordering = 'minute' # 默认排序
class PeriodicTaskModelViewSet(CustomModelViewSet):
"""
PeriodicTask celery 任务数据模型
name 名称
task celery任务名称
interval 频率
crontab 任务编排
args 形式参数
kwargs 位置参数
queue 队列名称
exchange 交换
routing_key 路由密钥
expires 过期时间
enabled 是否开启
"""
queryset = PeriodicTask.objects.exclude(name="celery.backend_cleanup")
serializer_class = PeriodicTaskSerializer
filter_class = PeriodicTaskFilter
search_fields = ('name', 'task', 'date_changed')
ordering = 'date_changed' # 默认排序
class TasksAsChoices(APIView):
def get(self, request):
"""
获取所有 tasks 名称
:param request:
:return:
"""
lis = []
def get_data(datas):
for item in datas:
if isinstance(item, (str, int)) and item:
lis.append(item)
else:
get_data(item)
get_data(TaskSelectWidget().tasks_as_choices())
return SuccessResponse(list(set(lis)))
class OperateCeleryTask(CustomAPIView):
def post(self, request):
req_data = request.data
task = req_data.get('celery_name', '')
data = {
'task': ''
}
test = f"""
from {'.'.join(task.split('.')[:-1])} import {task.split('.')[-1]}
task = {task.split('.')[-1]}.delay()
"""
exec(test, data)
return SuccessResponse({'task_id': data.get('task').id})

View File

@ -1,6 +0,0 @@
from django.apps import AppConfig
class MonitorConfig(AppConfig):
name = 'apps.vadmin.monitor'
verbose_name = "系统监控"

View File

@ -1,23 +0,0 @@
import django_filters
from apps.vadmin.monitor.models import Server, Monitor
class ServerFilter(django_filters.rest_framework.FilterSet):
"""
服务器信息 简单过滤器
"""
class Meta:
model = Server
fields = '__all__'
class MonitorFilter(django_filters.rest_framework.FilterSet):
"""
服务器监控信息 简单过滤器
"""
class Meta:
model = Monitor
fields = '__all__'

View File

@ -1,3 +0,0 @@
from apps.vadmin.monitor.models.monitor import Monitor
from apps.vadmin.monitor.models.server import Server
from apps.vadmin.monitor.models.sys_files import SysFiles

View File

@ -1,19 +0,0 @@
from django.db.models import CharField, ForeignKey, CASCADE
from apps.vadmin.op_drf.models import CoreModel
class Monitor(CoreModel):
cpu_num = CharField(max_length=8, verbose_name='CPU核数')
cpu_sys = CharField(max_length=8, verbose_name='CPU已使用率')
mem_num = CharField(max_length=32, verbose_name='内存总数(KB)')
mem_sys = CharField(max_length=32, verbose_name='内存已使用大小(KB)')
seconds = CharField(max_length=32, verbose_name='系统已运行时间')
server = ForeignKey(to='monitor.Server', on_delete=CASCADE, verbose_name="关联服务器信息", db_constraint=False)
class Meta:
verbose_name = '服务器监控信息'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.server and self.server.name and self.server.ip}监控信息"

View File

@ -1,20 +0,0 @@
from django.db import models
from django.db.models import CharField
from apps.vadmin.op_drf.fields import UpdateDateTimeField, CreateDateTimeField
class Server(models.Model):
name = CharField(max_length=256, verbose_name='服务器名称', null=True, blank=True)
ip = CharField(max_length=32, verbose_name="ip地址")
os = CharField(max_length=32, verbose_name="操作系统")
remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True)
update_datetime = UpdateDateTimeField() # 修改时间
create_datetime = CreateDateTimeField() # 创建时间
class Meta:
verbose_name = '服务器信息'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.name and self.ip}"

View File

@ -1,19 +0,0 @@
from django.db.models import CharField, ForeignKey, CASCADE
from apps.vadmin.op_drf.models import CoreModel
class SysFiles(CoreModel):
dir_name = CharField(max_length=32, verbose_name='磁盘路径')
sys_type_name = CharField(max_length=400, verbose_name='系统文件类型')
type_name = CharField(max_length=32, verbose_name='盘符类型')
total = CharField(max_length=32, verbose_name='磁盘总大小(KB)')
disk_sys = CharField(max_length=32, verbose_name='已使用大小(KB)')
monitor = ForeignKey(to='monitor.Monitor', on_delete=CASCADE, verbose_name="关联服务器监控信息", db_constraint=False)
class Meta:
verbose_name = '系统磁盘'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.creator and self.creator.name}"

View File

@ -1,40 +0,0 @@
from apps.vadmin.monitor.models import Server, Monitor
from apps.vadmin.op_drf.serializers import CustomModelSerializer
# ================================================= #
# ************** 服务器信息 序列化器 ************** #
# ================================================= #
class ServerSerializer(CustomModelSerializer):
"""
服务器信息 简单序列化器
"""
class Meta:
model = Server
fields = ("id", "ip", "name", "os", "remark")
class UpdateServerSerializer(CustomModelSerializer):
"""
服务器信息 简单序列化器
"""
class Meta:
model = Server
fields = ("name", "remark")
# ================================================= #
# ************** 服务器监控信息 序列化器 ************** #
# ================================================= #
class MonitorSerializer(CustomModelSerializer):
"""
服务器监控信息 简单序列化器
"""
class Meta:
model = Monitor
fields = '__all__'

View File

@ -1,90 +0,0 @@
import datetime
import logging
import sys
import time
import psutil
from apps.vadmin.monitor.models import Server, Monitor, SysFiles
from apps.vadmin.op_drf.response import SuccessResponse
from apps.vadmin.system.models import ConfigSettings
from apps.vadmin.utils.decorators import BaseCeleryApp
logger = logging.getLogger(__name__)
from platform import platform
def getIP():
"""获取ipv4地址"""
dic = psutil.net_if_addrs()
ipv4_list = []
for adapter in dic:
snicList = dic[adapter]
for snic in snicList:
if snic.family.name == 'AF_INET':
ipv4 = snic.address
if ipv4 != '127.0.0.1':
ipv4_list.append(ipv4)
if len(ipv4_list) >= 1:
return ipv4_list[0]
else:
return None
@BaseCeleryApp(name='apps.vadmin.monitor.tasks.get_monitor_info', save_success_logs=False)
def get_monitor_info():
"""
定时获取系统监控信息
:return:
"""
# 获取服务器
ip = getIP()
if not ip:
logger.error("无法获取到IP")
return
server_obj, create = Server.objects.get_or_create(ip=ip)
if create:
server_obj.name = ip
terse = ('terse' in sys.argv or '--terse' in sys.argv)
aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
server_obj.os = platform(aliased, terse)
server_obj.save()
# 获取CPU和内存信息
mem = psutil.virtual_memory()
monitor_obj = Monitor()
monitor_obj.cpu_num = psutil.cpu_count()
monitor_obj.cpu_sys = float(psutil.cpu_percent(0.1))
monitor_obj.mem_num = int(mem.total / 1024)
monitor_obj.mem_sys = int(mem.used / 1024)
monitor_obj.seconds = time.strftime("%d%H 小时 %M 分 %S 秒", time.gmtime(int(time.time()) - int(psutil.boot_time())))
monitor_obj.server = server_obj
monitor_obj.save()
# 保存磁盘信息
for ele in psutil.disk_partitions():
disk = psutil.disk_usage('/')
sys_files_obj = SysFiles()
sys_files_obj.dir_name = ele.mountpoint
sys_files_obj.sys_type_name = ele.opts
sys_files_obj.type_name = ele.fstype
sys_files_obj.total = disk.total
sys_files_obj.disk_sys = disk.used
sys_files_obj.monitor = monitor_obj
sys_files_obj.save()
return SuccessResponse(msg="")
@BaseCeleryApp(name='apps.vadmin.monitor.tasks.clean_surplus_monitor_info')
def clean_surplus_monitor_info():
"""
定时清理多余 系统监控信息
:return:
"""
config_settings_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first()
today = datetime.datetime.now().date()
clean_day_before = today - datetime.timedelta(days=int(config_settings_obj.configValue or 30))
Monitor.objects.filter(update_datetime__lt=clean_day_before).delete()
logger.info(f"成功清空{config_settings_obj.configValue}天前数据")

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,16 +0,0 @@
from django.urls import re_path
from rest_framework.routers import DefaultRouter
from apps.vadmin.monitor.views import ServerModelViewSet, MonitorModelViewSet
router = DefaultRouter()
router.register(r'server', ServerModelViewSet)
router.register(r'monitor', MonitorModelViewSet)
urlpatterns = [
re_path('monitor/info/(?P<pk>.*)/', MonitorModelViewSet.as_view({'get': 'get_monitor_info'})),
re_path('monitor/rate/(?P<pk>.*)/', MonitorModelViewSet.as_view({'get': 'get_rate_info'})),
re_path('monitor/enabled/', MonitorModelViewSet.as_view({'get': 'enabled_monitor_info'})),
re_path('monitor/clean/', MonitorModelViewSet.as_view({'get': 'clean_all'})),
]
urlpatterns += router.urls

View File

@ -1,184 +0,0 @@
from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSchedule
from rest_framework.request import Request
from apps.vadmin.monitor.filters import ServerFilter, MonitorFilter
from apps.vadmin.monitor.models import Server, Monitor, SysFiles
from apps.vadmin.monitor.serializers import ServerSerializer, MonitorSerializer, UpdateServerSerializer
from apps.vadmin.op_drf.response import SuccessResponse, ErrorResponse
from apps.vadmin.op_drf.viewsets import CustomModelViewSet
from apps.vadmin.permission.permissions import CommonPermission
from apps.vadmin.system.models import ConfigSettings
class ServerModelViewSet(CustomModelViewSet):
"""
服务器信息 模型的CRUD视图
"""
queryset = Server.objects.all()
serializer_class = ServerSerializer
update_serializer_class = UpdateServerSerializer
# extra_filter_backends = [DataLevelPermissionsFilter]
filter_class = ServerFilter
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
ordering = '-create_datetime' # 默认排序
class MonitorModelViewSet(CustomModelViewSet):
"""
服务器监控信息 模型的CRUD视图
"""
queryset = Monitor.objects.all()
serializer_class = MonitorSerializer
# extra_filter_backends = [DataLevelPermissionsFilter]
filter_class = MonitorFilter
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
ordering = '-create_datetime' # 默认排序
def get_rate_info(self, request: Request, *args, **kwargs):
"""
获取使用率 监控信息
:param request:
:param args:
:param kwargs:
:return:
"""
pk = kwargs.get("pk")
queryset = self.filter_queryset(self.get_queryset())
queryset = queryset.filter(server__id=pk).order_by("create_datetime")
# 间隔取值
queryset_count = queryset.count()
Interval_num = 1 if queryset_count < 200 else int(queryset_count / 100)
queryset = queryset.values('cpu_sys', 'mem_num', 'mem_sys', 'create_datetime')[::Interval_num][:100]
data = {
"cpu": [],
"memory": [],
"datetime": [],
}
for ele in queryset:
data["cpu"].append(round(float(ele.get('cpu_sys', 0)), 2))
data["datetime"].append(ele.get('create_datetime').strftime('%Y-%m-%d %H:%M:%S'))
data["memory"].append(round(float(ele.get('mem_num', 0)), 4) and round(float(ele.get('mem_sys', 0)) /
float(ele.get('mem_num', 0)) * 100,
2))
return SuccessResponse(data=data)
def get_monitor_info(self, request: Request, *args, **kwargs):
"""
最新的服务器状态信息
:param request:
:param args:
:param kwargs:
:return:
"""
pk = kwargs.get("pk")
instance = Monitor.objects.filter(server__id=pk).order_by("-create_datetime").first()
if not instance:
return ErrorResponse(msg="未找到服务器信息id")
serializer = self.get_serializer(instance)
data = serializer.data
return SuccessResponse(data={
"cpu": {
"total": int(data.get('cpu_num'), 0),
"used": "", # cpu核心 可不传如指cpu当前主频该值可以传
"rate": float(data.get('cpu_sys', 0)) / 100,
"unit": "核心", # 默认单位 核心
},
"memory": {
"total": int(int(data.get('mem_num', 0)) / 1024),
"used": int(int(data.get('mem_sys', 0)) / 1024),
"rate": int(data.get('mem_num', 0)) and round(int(data.get('mem_sys', 0)) /
int(data.get('mem_num', 0)), 4),
"unit": "MB", # 默认单位 MB
},
"disk": [{
"dir_name": ele.get('dir_name'),
"total": int(int(ele.get('total', 0)) / 1024 / 1024 / 1024),
"used": int(int(ele.get('disk_sys', 0)) / 1024 / 1024 / 1024),
"rate": int(ele.get('total', 0)) and round(int(ele.get('disk_sys', 0)) / int(ele.get('total', 0)),
4),
"unit": "GB", # 默认单位 GB
} for ele in SysFiles.objects.filter(monitor=instance).values('dir_name', 'total', 'disk_sys')]
})
def enabled_monitor_info(self, request: Request, *args, **kwargs):
"""
更新和获取监控信息
:param request:
:param args:
:param kwargs:
:return:
"""
enabled = request.query_params.get('enabled', None)
save_days = request.query_params.get('save_days', None)
interval = request.query_params.get('interval', None)
# 定时获取系统监控信息
periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first()
if not periodictask_obj:
intervalschedule_obj, _ = IntervalSchedule.objects.get_or_create(every=5, period="seconds")
periodictask_obj = PeriodicTask()
periodictask_obj.task = "apps.vadmin.monitor.tasks.get_monitor_info"
periodictask_obj.name = "定时获取系统监控信息"
periodictask_obj.interval = intervalschedule_obj
periodictask_obj.enabled = False
periodictask_obj.save()
# 定时清理多余 系统监控信息
clean_task_obj = PeriodicTask.objects.filter(
task='apps.vadmin.monitor.tasks.clean_surplus_monitor_info').first()
if not clean_task_obj:
crontab_obj, _ = CrontabSchedule.objects.get_or_create(day_of_month="*", day_of_week="*", hour="1",
minute="0", month_of_year="*")
clean_task_obj = PeriodicTask()
clean_task_obj.task = "apps.vadmin.monitor.tasks.clean_surplus_monitor_info"
clean_task_obj.name = "定时清理多余-系统监控信息"
clean_task_obj.crontab = crontab_obj
clean_task_obj.enabled = True
clean_task_obj.save()
# 配置添加
config_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first()
if not config_obj:
config_obj = ConfigSettings()
config_obj.configKey = "sys.monitor.info.save_days"
config_obj.configName = "定时清理多余系统监控信息"
config_obj.configValue = "30"
config_obj.configType = "Y"
config_obj.status = "1"
config_obj.remark = "定时清理多余-系统监控信息默认30天"
config_obj.save()
if enabled:
# 更新监控状态
periodictask_obj.enabled = True if enabled == "1" else False
periodictask_obj.save()
# 更新 定时清理多余 系统监控信息 状态
clean_task_obj.enabled = True if enabled == "1" else False
clean_task_obj.save()
# 更新保留天数
if save_days and config_obj:
config_obj.configValue = save_days
config_obj.save()
# 更新监控获取频率
if interval:
periodictask_obj.interval.every = interval
periodictask_obj.interval.save()
return SuccessResponse(data={
"enabled": periodictask_obj.enabled,
"interval": periodictask_obj.interval.every,
"save_days": config_obj.configValue if config_obj else "30",
})
def clean_all(self, request: Request, *args, **kwargs):
"""
清空监控信息
:param request:
:param args:
:param kwargs:
:return:
"""
self.get_queryset().delete()
return SuccessResponse(msg="清空成功")

View File

@ -1,13 +0,0 @@
import logging
from django.apps import AppConfig
logger = logging.getLogger(__name__)
class OpDrfConfig(AppConfig):
name = 'apps.vadmin.op_drf'
verbose_name = "OP DRF"
def ready(self):
logging.info("OP DRF框架检测完成:success")

View File

@ -1,155 +0,0 @@
from django.contrib.auth import get_user_model
from django.db import models
from django.db.models import SET_NULL
from apps.vadmin.utils.string_util import uuid_8, uuid_16, uuid_32, uuid_36
class IdField(models.CharField):
"""
id = IdField()
"""
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 8)
kwargs['primary_key'] = kwargs.get('primary_key', True)
kwargs['unique'] = kwargs.get('unique', True)
kwargs['db_index'] = kwargs.get('db_index', True)
kwargs['default'] = kwargs.get('default', uuid_8)
kwargs['null'] = kwargs.get('null', False)
kwargs['blank'] = kwargs.get('blank', False)
kwargs['verbose_name'] = kwargs.get('verbose_name', 'ID')
kwargs['help_text'] = kwargs.get('help_text', 'ID')
super().__init__(*args, **kwargs)
class UUID8Field(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 8)
kwargs['default'] = kwargs.get('default', uuid_8)
kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID')
kwargs['help_text'] = kwargs.get('help_text', 'UUID')
super().__init__(*args, **kwargs)
class UUID16Field(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 16)
kwargs['default'] = kwargs.get('default', uuid_16)
kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID')
kwargs['help_text'] = kwargs.get('help_text', 'UUID')
super().__init__(*args, **kwargs)
class UUID32Field(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 32)
kwargs['default'] = kwargs.get('default', uuid_32)
kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID')
kwargs['help_text'] = kwargs.get('help_text', 'UUID')
super().__init__(*args, **kwargs)
class UUID36Field(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 36)
kwargs['unique'] = kwargs.get('unique', True)
kwargs['default'] = kwargs.get('default', uuid_36)
kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID')
kwargs['help_text'] = kwargs.get('help_text', 'UUID')
super().__init__(*args, **kwargs)
class DescriptionField(models.TextField):
"""
description = DescriptionField()
"""
def __init__(self, *args, **kwargs):
if kwargs.get('null', True):
kwargs['default'] = kwargs.get('default', '')
kwargs['blank'] = kwargs.get('blank', True)
kwargs['null'] = kwargs.get('null', True)
kwargs['verbose_name'] = kwargs.get('verbose_name', '描述')
kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '描述')
super().__init__(*args, **kwargs)
class UserForeignKeyField(models.ForeignKey):
"""
user = UserForeignKeyField()
"""
def __init__(self, to=None, on_delete=None, related_name=None, related_query_name=None, limit_choices_to=None,
parent_link=False, to_field=None, db_constraint=False, **kwargs):
if to is None:
to = get_user_model()
if to_field is None:
to_field = 'id'
if on_delete is None:
on_delete = SET_NULL
kwargs['verbose_name'] = kwargs.get('verbose_name', '关联的用户')
kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '关联的用户')
kwargs['editable'] = kwargs.get('default', False)
super().__init__(to, on_delete, related_name, related_query_name, limit_choices_to, parent_link, to_field,
db_constraint, **kwargs)
class UpdateDateTimeField(models.DateTimeField):
"""
update_datetime = ModifyDateTimeField()
"""
def __init__(self, verbose_name=None, name=None, auto_now=True, auto_now_add=False, **kwargs):
verbose_name = verbose_name or '修改时间'
kwargs['help_text'] = kwargs.get('help_text', '修改时间')
kwargs['editable'] = kwargs.get('default', False)
kwargs['blank'] = kwargs.get('blank', True)
kwargs['null'] = kwargs.get('null', True)
super().__init__(verbose_name, name, auto_now, auto_now_add, **kwargs)
class CreateDateTimeField(models.DateTimeField):
"""
create_datetime = CreateDateTimeField()
"""
def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=True, **kwargs):
verbose_name = verbose_name or '创建时间'
kwargs['help_text'] = kwargs.get('help_text', '创建时间')
kwargs['editable'] = kwargs.get('default', False)
kwargs['blank'] = kwargs.get('blank', True)
kwargs['null'] = kwargs.get('null', True)
super().__init__(verbose_name, name, auto_now, auto_now_add, **kwargs)
class CreatorCharField(models.CharField):
"""
creator = CreatorCharField()
"""
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 255)
kwargs['null'] = kwargs.get('null', True)
kwargs['blank'] = kwargs.get('blank', True)
kwargs['verbose_name'] = kwargs.get('verbose_name', '创建者')
kwargs['help_text'] = kwargs.get('help_text', '该记录的创建者')
super().__init__(*args, **kwargs)
class ModifierCharField(models.CharField):
"""
modifier = ModifierCharField()
"""
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 255)
kwargs['null'] = kwargs.get('null', True)
kwargs['blank'] = kwargs.get('blank', True)
kwargs['verbose_name'] = kwargs.get('verbose_name', '修改者')
kwargs['help_text'] = kwargs.get('help_text', '该记录最后修改者')
super().__init__(*args, **kwargs)

View File

@ -1,151 +0,0 @@
"""
常用的过滤器以及DRF的过滤器
"""
import json
import logging
import operator
from functools import reduce
from django.utils import six
from mongoengine.queryset import visitor
from rest_framework.filters import BaseFilterBackend, SearchFilter, OrderingFilter
from apps.vadmin.utils.model_util import get_dept
logger = logging.getLogger(__name__)
def get_as_kwargs(request):
params = request.GET.dict()
if 'as' not in params:
return {}
as_params = json.loads(params.get('as', '{}'))
return as_params
class MongoSearchFilter(SearchFilter):
"""
适配Mongo模型视图的Search过滤器
"""
def filter_queryset(self, request, queryset, view):
search_fields = getattr(view, 'search_fields', None)
search_terms = self.get_search_terms(request)
if not search_fields or not search_terms:
return queryset
orm_lookups = [
self.construct_search(six.text_type(search_field))
for search_field in search_fields
]
if not orm_lookups:
return queryset
conditions = []
for search_term in search_terms:
queries = [
visitor.Q(**{orm_lookup: search_term})
for orm_lookup in orm_lookups
]
conditions.append(reduce(operator.or_, queries))
queryset = queryset.filter(reduce(operator.and_, conditions))
return queryset
class MongoOrderingFilter(OrderingFilter):
"""
适配Mongo模型视图的Search过滤器
"""
def get_valid_fields(self, queryset, view, context={}):
valid_fields = getattr(view, 'ordering_fields', self.ordering_fields)
if valid_fields is None:
return self.get_default_valid_fields(queryset, view, context)
elif valid_fields == '__all__':
# View explicitly allows filtering on any model field
model = view.get_serializer().__class__.Meta.model
valid_fields = [
(field_name, getattr(field, 'verbose_name', field_name)) for field_name, field in model._fields.items()
]
else:
valid_fields = [
(item, item) if isinstance(item, six.string_types) else item
for item in valid_fields
]
return valid_fields
class AdvancedSearchFilter(BaseFilterBackend):
"""
高级搜索过滤器
"""
def filter_queryset(self, request, queryset, view):
as_kwargs = get_as_kwargs(request)
if as_kwargs:
queryset = queryset.filter(**as_kwargs)
return queryset
class MongoAdvancedSearchFilter(BaseFilterBackend):
"""
mongo高级搜索过滤器
"""
def filter_queryset(self, request, queryset, view):
as_kwargs = get_as_kwargs(request)
if as_kwargs:
queryset = queryset.filter(**as_kwargs)
return queryset
class DataLevelPermissionsFilter(BaseFilterBackend):
"""
数据 级权限过滤器
0. 获取用户的部门id没有部门则返回空
1. 判断过滤的数据是否有创建人所在部门 "creator" 字段,没有则返回全部
2. 如果用户没有关联角色则返回本部门数据
3. 根据角色的最大权限进行数据过滤(会有多个角色进行去重取最大权限)
3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据
4. 只为仅本人数据权限时只返回过滤本人数据并且部门为自己本部门(考虑到用户会变部门只能看当前用户所在的部门数据)
5. 自定数据权限 获取部门根据部门过滤
"""
def filter_queryset(self, request, queryset, view):
# 0. 获取用户的部门id没有部门则返回空
user_dept_id = getattr(request.user, 'dept_id')
if not user_dept_id:
return queryset.none()
# 1. 判断过滤的数据是否有创建人所在部门 "dept_belong_id" 字段
if not getattr(queryset.model, 'dept_belong_id', None):
return queryset
# 2. 如果用户没有关联角色则返回本部门数据
if not hasattr(request.user, 'role'):
return queryset.filter(dept_belong_id=user_dept_id)
# 3. 根据所有角色 获取所有权限范围
role_list = request.user.role.filter(status='1').values('admin', 'dataScope')
dataScope_list = []
for ele in role_list:
# 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据
if '1' == ele.get('dataScope') or ele.get('admin') == True:
return queryset
dataScope_list.append(ele.get('dataScope'))
dataScope_list = list(set(dataScope_list))
# 4. 只为仅本人数据权限时只返回过滤本人数据,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据)
if dataScope_list == ['5']:
return queryset.filter(creator=request.user, dept_belong_id=user_dept_id)
# 5. 自定数据权限 获取部门,根据部门过滤
dept_list = []
for ele in dataScope_list:
if ele == '2':
dept_list.extend(request.user.role.filter(status='1').values_list('dept__id', flat=True))
elif ele == '3':
dept_list.append(user_dept_id)
elif ele == '4':
dept_list.extend(get_dept(user_dept_id, ))
return queryset.filter(dept_belong_id__in=list(set(dept_list)))

View File

@ -1,465 +0,0 @@
from django.core.exceptions import ValidationError
from django.db.models.query import QuerySet
from django.http import Http404
from django.shortcuts import get_object_or_404 as _get_object_or_404
from rest_framework.settings import api_settings
from apps.vadmin.utils.jsonpath_util import get_jsonpath, filter_json, search_json
from apps.vadmin.utils.sort_util import sortList
from . import mixins
from .pagination import JsonPagination
from .response import SuccessResponse
from .views import CustomAPIView
def get_object_or_404(queryset, *filter_args, **filter_kwargs):
"""
Same as Django's standard shortcut, but make sure to also raise 404
if the filter_kwargs don't match the required types.
"""
try:
return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
except (TypeError, ValueError, ValidationError):
raise Http404
class GenericAPIView(CustomAPIView):
"""
Base class for all other generic views.
"""
# You'll need to either set these attributes,
# or override `get_queryset()`/`get_serializer_class()`.
# If you are overriding a view method, it is important that you call
# `get_queryset()` instead of accessing the `queryset` property directly,
# as `queryset` will get evaluated only once, and those results are cached
# for all subsequent requests.
queryset = None
serializer_class = None
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
lookup_field = 'pk'
lookup_url_kwarg = None
# The filter backend classes to use for queryset filtering
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
# The style to use for queryset pagination.
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get_queryset(self):
"""
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using `self.queryset`.
This method should always be used rather than accessing `self.queryset`
directly, as `self.queryset` gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different
querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
"""
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
def get_object(self):
"""
Returns the object the view is displaying.
You may want to override this if you need to provide non-standard
queryset lookups. Eg if objects are referenced using multiple
keyword arguments in the url conf.
"""
queryset = self.filter_queryset(self.get_queryset())
# Perform the lookup filtering.
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
def get_serializer_class(self):
"""
Return the class to use for the serializer.
Defaults to using `self.serializer_class`.
You may want to override this if you need to provide different
serializations depending on the incoming request.
(Eg. admins get full serialization, others get basic serialization)
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
return self.serializer_class
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
def filter_queryset(self, queryset):
"""
Given a queryset, filter it with whichever filter backend is in use.
You are unlikely to want to override this method, although you may need
to call it either from a list view, or from a custom `get_object`
method if you want to apply the configured filtering backend to the
default queryset.
"""
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator
def paginate_queryset(self, queryset):
"""
Return a single page of results, or `None` if pagination is disabled.
"""
if self.paginator is None:
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
def get_paginated_response(self, data):
"""
Return a paginated style `Response` object for the given output data.
"""
assert self.paginator is not None
return self.paginator.get_paginated_response(data)
# Concrete view classes that provide method handlers
# by composing the mixin classes with the base view.
class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for creating a model instance.
"""
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
class RetrieveAPIView(mixins.RetrieveModelMixin,
GenericAPIView):
"""
Concrete view for retrieving a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
class DestroyAPIView(mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for deleting a model instance.
"""
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
class UpdateAPIView(mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for updating a model instance.
"""
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset or creating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
class JsonListView(GenericAPIView):
"""
JsonList的查询过滤搜索排序通用视图
"""
# 模糊搜索
search_param = api_settings.SEARCH_PARAM
search_fields = []
ordering_param = api_settings.ORDERING_PARAM
# 可排序属性,默认所有属性可排序
ordering_fields = '__all__'
pagination_class = JsonPagination
queryset: list = []
pagination_total = 0
# 返回的属性
response_fields = '__all__'
# response_fields = ['app_code', 'ip', 'hostname', 'host_type', 'host_env']
# 默认排序, 只支持view中设置ordering, 暂不支持排序参数由请求动态传入
ordering = None # 正序
# ordering = '-ip' # 倒序
_has_ordering = False
_exclude_params = []
# 属性
_json_fields = None
@property
def paginator(self):
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class(len(self.get_queryset()))
self._paginator.request = self.request
return self._paginator
def filter_queryset(self, queryset):
"""
使用jsonpath实现, 重写对查询集的条件过滤逻辑
:param queryset:
:return:
"""
if not self._exclude_params:
self.__class__._exclude_params = []
self.__class__._exclude_params.append(self.paginator.page_size_query_param)
self.__class__._exclude_params.append(self.paginator.page_query_param)
self.__class__._exclude_params.extend(self.paginator.other_page_size_query_param)
self.__class__._exclude_params.extend(self.paginator.other_page_query_param)
self.__class__._exclude_params.append(self.ordering_param)
self.__class__._exclude_params.append(self.search_param)
expr = get_jsonpath(self.request.query_params, self._exclude_params, self.json_fields)
if not expr:
return queryset
_queryset = filter_json(self.get_queryset(), expr)
if not _queryset:
_queryset = []
return _queryset
def get_queryset(self):
"""
获取查询集/初始化查询集
:return:
"""
return self.queryset
@property
def json_fields(self):
if self._json_fields is None:
queryset = self.get_queryset()
if len(queryset):
ele: dict = queryset[0]
self.__class__._json_fields = {key: value.__class__.__name__ for (key, value) in ele.items()}
else:
self.__class__._json_fields = []
return self._json_fields
def queryset_ordering(self):
"""
查询集排序
:return:
"""
if self._has_ordering:
return
_ordering = self.ordering
if _ordering and self.ordering.startswith('-'):
_ordering = self.ordering[1:]
if _ordering and _ordering in self.json_fields:
if (isinstance(self.ordering_fields,
str) and self.ordering_fields.lower() == '__all__') or _ordering in self.ordering_fields:
sortList(self.get_queryset(), self.ordering)
self.__class__._has_ordering = True
def queryset_search(self, queryset):
search_value = self.request.query_params.get(self.search_param, None)
if self.search_fields and search_value:
queryset = search_json(queryset, search_value, self.search_fields)
return queryset
def paginate_queryset(self, queryset):
"""
重写内存分页逻辑
:param queryset:
:return:
"""
paginator: JsonPagination = self.paginator
if paginator is None:
return queryset
request = self.request
page_size = paginator.get_page_size(request)
page_num = paginator.get_page_num(request)
start_index = (page_num - 1) * page_size
end_index = start_index + page_size
page_expr = f"$[{start_index}:{end_index}]"
queryset = filter_json(queryset, page_expr)
return queryset
def get_paginated_response(self, data):
"""
重写分页的返回格式
:param data:
:return:
"""
if self.paginator is None:
return SuccessResponse(data)
return self.paginator.get_paginated_response(data, self.pagination_total)
def filter_response_fields(self, data):
"""
过滤掉不显示的字段
:param data:
:return:
"""
if isinstance(self.response_fields, str) and self.response_fields.lower() == '__all__':
return data
data = [{key: value for key, value in ele.items() if key in self.response_fields} for ele in data]
return data
def filter_json(self):
"""
过滤
(1)查询集排序, 根据ordering对查询集进行正序/倒序
(2)查询集过滤,根据请求参数传入的属性值
(3)分页, 如果存在分页器, 根据输入的分页参数分页
(4)属性字段过滤, 过滤掉不需要返回的属性值
:return:
"""
self.queryset_ordering()
queryset = self.get_queryset()
queryset = self.filter_queryset(queryset)
queryset = self.queryset_search(queryset)
self.paginator.data_count = len(queryset)
queryset = self.paginate_queryset(queryset)
data = self.filter_response_fields(queryset)
return data
def get(self, request, *args, **kwargs):
data = self.filter_json()
return self.get_paginated_response(data)

View File

@ -1,8 +0,0 @@
import logging
class RedisHandler(logging.StreamHandler):
def emit(self, record):
msg = self.format(record)
print(msg)

View File

@ -1,213 +0,0 @@
import logging
from django.db.models import Model
from rest_framework.request import Request
from rest_framework.views import APIView
logger = logging.getLogger(__name__)
class ViewLogger(object):
"""
基于View视图的日志
"""
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
super().__init__()
self.view = view
self.request = request
self.model = None
self.log_prefix: str = ''
if self.view and hasattr(self.view.get_queryset(), 'model'):
self.model: Model = self.view.get_queryset().model
elif self.view and hasattr(self.view.get_serializer(), 'Meta') and hasattr(self.view.get_serializer().Meta,
'model'):
self.model: Model = self.view.get_serializer().Meta.model
if self.model:
request.session['model_name'] = str(getattr(self.model, '_meta').verbose_name)
def handle(self, request: Request, *args, **kwargs):
pass
def logger(self, msg):
"""
:param msg:
:return: logger
"""
self.request.session['request_msg'] = msg
return logger
class APIViewLogger(ViewLogger):
"""
(1)仅在op_drf.views.CustomAPIView的子类中生效
(2)使用: 请勿直接配置view_logger_classes = (APIViewLogger, ), 这样无效,
如有需求, 需要继承APIViewLogger重写其相应的方法
(3)重写handle()方法,所有请求均触发此方法
重写handle_get()方法,仅GET请求均触发此方法
重写handle_post()方法,仅POST请求均触发此方法
重写handle_put()方法,仅PUT请求均触发此方法
重写handle_delete()方法,仅DELETE请求均触发此方法
重写handle_xxx()方法,仅xxx请求均触发此方法
"""
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
super().__init__(view, request, *args, **kwargs)
self.view: APIView = view
self.request: Request = request
self.user = request.user
class ModelViewLogger(APIViewLogger):
"""
基础模型操作日志
(1)仅在op_drf.viewsets.GenericViewSet的子类中生效
(1)在CustomModelViewSet子类中配置: view_logger_classes = [ModelViewLogger, ]
(2)不要在op_drf中继续写具体的日志逻辑代码,
如有需求, 应该继承ModelViewLogger并且重写相应的方法, 例如CustomerModelViewLogger(涉及到其他模块时不要将代码放入op_drf)
"""
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
super().__init__(view, request, *args, **kwargs)
class RelationshipViewLogger(APIViewLogger):
"""
关联关系模型操作日志
(1)在ModelRelationshipView子类中配置: view_logger_classes = [RelationshipViewLogger, ]
(2)不要在op_drf中继续写具体的日志逻辑代码,
如有需求, 应该继承RelationshipViewLogger并且重写相应的方法, 例如CustomerRelationshipViewLogger(涉及到其他模块时不要将代码放入op_drf)
"""
def __init__(self, view=None, request=None, instanceId=None, *args, **kwargs) -> None:
super().__init__(view, request)
self.instanceId: str = instanceId
def handle(self, request: Request, *args, **kwargs):
"""
每一次请求都会触发此方法
"""
pass
class CustomerRelationshipViewLogger(RelationshipViewLogger):
"""
(1)在ModelRelationshipView子类中配置: view_logger_classes = [CustomerRelationshipViewLogger, ]
"""
def __init__(self, view=None, request=None, instanceId=None, *args, **kwargs) -> None:
super().__init__(view, request, instanceId, *args, **kwargs)
self.log_prefix: str = 'RelationshipView日志系统:'
def handle_get(self, request: Request, *args, **kwargs):
"""
仅GET请求才会触发此方法
"""
pass
def handle_post(self, request: Request, *args, **kwargs):
"""
仅POST请求才会触发此方法
"""
operator = self.user.username
model_name = getattr(self.view.model, '_meta').verbose_name
to_field_name = self.view.to_field_name
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
self.logger(
f'{self.log_prefix}用户[username={operator}]新增, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
def handle_put(self, request: Request, *args, **kwargs):
"""
仅PUT请求才会触发此方法
"""
operator = self.user.username
model_name = getattr(self.view.model, '_meta').verbose_name
to_field_name = self.view.to_field_name
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
self.logger(
f'{self.log_prefix}用户[username={operator}]重置, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
def handle_delete(self, request: Request, *args, **kwargs):
"""
仅DELETE请求才会触发此方法
"""
operator = self.user.username
model_name = getattr(self.view.model, '_meta').verbose_name
to_field_name = self.view.to_field_name
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
self.logger(
f'{self.log_prefix}用户[username={operator}]移除, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
class CustomerModelViewLogger(ModelViewLogger):
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
super().__init__(view, request, *args, **kwargs)
self.log_prefix: str = 'CustomModelViewSet日志系统:'
def handle(self, request: Request, *args, **kwargs):
pass
def handle_retrieve(self, request: Request, instance: Model = None, *args, **kwargs):
"""
仅retrieve(GET)请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]检索{model_name}:[{instance}]')
def handle_list(self, request: Request, *args, **kwargs):
"""
仅list(GET)请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]查询{model_name}')
def handle_create(self, request: Request, instance: Model = None, *args, **kwargs):
"""
仅create(POST)请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]创建{model_name}:[{instance}]')
def handle_update(self, request: Request, instance: Model = None, *args, **kwargs):
"""
仅update(PUT)请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]更新{model_name}:[{instance}]')
def handle_partial_update(self, request: Request, instance: Model = None, *args, **kwargs):
"""
仅partial_update(PATCH)请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]部分更新{model_name}:[{instance}]')
def handle_destroy(self, request: Request, instance: Model = None, *args, **kwargs):
"""
仅destroy(DELETE)请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]删除{model_name}:[{instance}]')
def handle_other(self, request: Request, instance: Model = None, *args, **kwargs):
"""
其他 请求才会触发此方法
"""
pass
operator = self.user.username
model_name = getattr(self.model, '_meta').verbose_name
self.logger(f'{self.log_prefix}用户[username={operator}]其他请求{model_name}:[{instance}]')

View File

@ -1,78 +0,0 @@
import logging
import os
import shutil
from django.core.management.base import BaseCommand
logger = logging.getLogger(__name__)
from application.settings import BASE_DIR
class Command(BaseCommand):
"""
创建App命令:
python manage.py createapp app名
python manage.py createapp app01 app02 ...
python manage.py createapp 一级文件名/app01 ... # 支持多级目录建app
"""
def add_arguments(self, parser):
parser.add_argument('app_name', nargs='*', type=str, )
def handle(self, *args, **options):
app_name = options.get('app_name')
for name in app_name:
names = name.split('/')
dnames = ".".join(names)
app_path = os.path.join(BASE_DIR, "apps", *names)
# 判断app是否存在
if os.path.exists(app_path):
print(f"创建失败App {name} 已存在!")
break
source_path = os.path.join(BASE_DIR, "apps", "vadmin", "template")
target_path = app_path
if not os.path.exists(target_path):
# 如果目标路径不存在原文件夹的话就创建
os.makedirs(target_path)
if os.path.exists(source_path):
# 如果目标路径存在原文件夹的话就先删除
shutil.rmtree(target_path)
shutil.copytree(source_path, target_path)
# 修改app中的apps 内容
content = f"""from django.apps import AppConfig
class {name[-1].capitalize()}Config(AppConfig):
name = 'apps.{dnames}'
verbose_name = "{names[-1]}App"
"""
with open(os.path.join(app_path, "apps.py"), 'w', encoding='UTF-8') as f:
f.write(content)
f.close()
# 注册app到 settings.py 中
injection(os.path.join(BASE_DIR, "application", "settings.py"), f" 'apps.{dnames}',\n", "INSTALLED_APPS",
"]")
# 注册app到 urls.py 中
injection(os.path.join(BASE_DIR, "application", "urls.py"),
f" re_path(r'^{name}/', include('apps.{dnames}.urls')),\n", "urlpatterns = [",
"]")
print(f"创建 {name} App成功")
def injection(file_path, insert_content, startswith, endswith):
with open(file_path, "r+", encoding="utf-8") as f:
data = f.readlines()
with open(file_path, 'w', encoding='UTF-8') as f1:
is_INSTALLED_APPS = False
is_insert = False
for content in data:
# 判断文件是否 INSTALLED_APPS 开头
if not is_insert and content.startswith(startswith):
is_INSTALLED_APPS = True
if not is_insert and content.startswith(endswith) and is_INSTALLED_APPS:
# 给前一行插入数据
content = insert_content + content
is_insert = True
f1.writelines(content)

View File

@ -1,169 +0,0 @@
"""
django中间件
"""
import json
import logging
import os
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.utils.deprecation import MiddlewareMixin
from apps.vadmin.op_drf.response import ErrorJsonResponse
from apps.vadmin.permission.models import Menu
from apps.vadmin.system.models import OperationLog
from apps.vadmin.utils.request_util import get_request_ip, get_request_data, get_request_path, get_browser, get_os, \
get_login_location, get_request_canonical_path, get_request_user, get_verbose_name
logger = logging.getLogger(__name__)
class ApiLoggingMiddleware(MiddlewareMixin):
"""
用于记录API访问日志中间件
"""
def __init__(self, get_response=None):
super().__init__(get_response)
self.enable = getattr(settings, 'API_LOG_ENABLE', None) or False
self.methods = getattr(settings, 'API_LOG_METHODS', None) or set()
@classmethod
def __handle_request(cls, request):
request.request_ip = get_request_ip(request)
request.request_data = get_request_data(request)
request.request_path = get_request_path(request)
@classmethod
def __handle_response(cls, request, response):
# request_data,request_ip由PermissionInterfaceMiddleware中间件中添加的属性
body = getattr(request, 'request_data', {})
# 请求含有password则用*替换掉(暂时先用于所有接口的password请求参数)
if isinstance(body, dict) and body.get('password', ''):
body['password'] = '*' * len(body['password'])
if not hasattr(response, 'data') or not isinstance(response.data, dict):
response.data = {}
if not response.data and response.content:
try:
content = json.loads(response.content.decode())
response.data = content if isinstance(content, dict) else {}
except:
pass
user = get_request_user(request)
info = {
'request_ip': getattr(request, 'request_ip', 'unknown'),
'creator': user if not isinstance(user, AnonymousUser) else None,
'dept_belong_id': getattr(request.user, 'dept_id', None),
'request_method': request.method,
'request_path': request.request_path,
'request_body': body,
'response_code': response.data.get('code'),
'request_location': get_login_location(request),
'request_os': get_os(request),
'request_browser': get_browser(request),
'request_msg': request.session.get('request_msg'),
'status': True if response.data.get('code') in [200, 204] else False,
'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')},
'request_modular': request.session.get('model_name'),
}
log = OperationLog(**info)
log.save()
def process_view(self, request, view_func, view_args, view_kwargs):
if hasattr(view_func, 'cls') and hasattr(view_func.cls, 'queryset'):
request.session['model_name'] = get_verbose_name(view_func.cls.queryset)
return
def process_request(self, request):
self.__handle_request(request)
def process_response(self, request, response):
"""
主要请求处理完之后记录
:param request:
:param response:
:return:
"""
if self.enable:
if self.methods == 'ALL' or request.method in self.methods:
self.__handle_response(request, response)
return response
class PermissionModeMiddleware(MiddlewareMixin):
"""
权限模式拦截判断
"""
def process_request(self, request):
return
def has_interface_permission(self, request, method, view_path, user=None):
"""
接口权限验证,优先级:
(1)接口是否接入权限管理, :继续; :通过
(2)认证的user是否superuser, :通过; :继续
(3)user的角色有该接口权限, :通过, :不通过
auth_code含义: auth_code >=0, 表示接口认证通过; auth_code < 0, 表示无接口访问权限, 具体含义如下
-1:
-10: 该请求已认证的用户没有这个接口的访问权限
0:
1: 白名单
10: 该接口没有录入权限系统, 放行 请求中认证的用户为超级管理员, 直接放行
20: 请求中认证的用户是superuser放行
30: 请求中认证的用户对应的角色中,某个角色包含了该接口的访问权限, 放行
1. 先获取所有录入系统的接口
2 判断此用户是否为 superuser
3. 获取此用户所请求的接口
4. 获取此用户关联角色所有有权限的接口
:param interface: 接口模型
:param path: 接口路径
:param method: 请求方法
:param project: 接口所属项目
:param args:
:param kwargs:
:return:
"""
interface_dict = Menu.get_interface_dict()
# (1) 接口是否接入权限管理, 是:继续; 否:通过
if not view_path in interface_dict.get(method, []):
return 10
# (2)认证的user是否superuser, 是:通过; 否:继续
if user.is_superuser or (hasattr(user, 'role') and user.role.filter(status='1', admin=True).count()):
return 20
# (3)user的角色有该接口权限, 是:通过, 否:不通过
if view_path in user.get_user_interface_dict.get(method, []):
return 30
return -10
def process_view(self, request, view_func, view_args, view_kwargs):
# 判断环境变量中,是否为演示模式(正常可忽略此判断)
white_list = ['/admin/logout/', '/admin/login/', '/admin/api-auth/login/']
if os.getenv('DEMO_ENV') and not request.method in ['GET', 'OPTIONS'] and request.path not in white_list:
return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!')
if not settings.INTERFACE_PERMISSION:
return
user = get_request_user(request)
if user and not isinstance(user, AnonymousUser):
method = request.method.upper()
if method == 'GET': # GET 不设置接口权限
return
view_path = get_request_canonical_path(request, *view_args, **view_kwargs)
auth_code = self.has_interface_permission(request, method, view_path, user)
logger.info(f"[{user.username}] {method}:{view_path}, 权限认证:{auth_code}")
if auth_code >= 0:
return
return ErrorJsonResponse(data={}, msg=f'无接口访问权限!')
def process_response(self, request, response):
"""
主要请求处理完之后记录
:param request:
:param response:
:return:
"""
return response

View File

@ -1,366 +0,0 @@
from django.db import transaction
from rest_framework import mixins
from rest_framework import serializers
from rest_framework import status
from rest_framework.relations import ManyRelatedField, RelatedField, PrimaryKeyRelatedField
from rest_framework.request import Request
from apps.vadmin.utils.export_excel import excel_to_data, export_excel_save_model
from apps.vadmin.utils.request_util import get_verbose_name
from .response import SuccessResponse
class CreateModelMixin(mixins.CreateModelMixin):
"""
继承增强DRF的CreateModelMixin, 标准化其返回值
"""
create_serializer_class = None
def create(self, request: Request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=serializer.instance, *args, **kwargs)
headers = self.get_success_headers(serializer.data)
return SuccessResponse(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
super().perform_create(serializer)
class ListModelMixin(mixins.ListModelMixin):
"""
继承增强DRF的CreateModelMixin, 标准化其返回值
"""
list_serializer_class = None
def list(self, request: Request, *args, **kwargs):
if hasattr(self, 'handle_logging'):
self.handle_logging(request, *args, **kwargs)
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
if getattr(self, 'values_queryset', None):
return self.get_paginated_response(page)
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
if getattr(self, 'values_queryset', None):
return SuccessResponse(page)
serializer = self.get_serializer(queryset, many=True)
return SuccessResponse(serializer.data)
class RetrieveModelMixin(mixins.RetrieveModelMixin):
"""
继承增强DRF的CreateModelMixin, 标准化其返回值
"""
retrieve_serializer_class = None
def retrieve(self, request: Request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
class UpdateModelMixin(mixins.UpdateModelMixin):
"""
继承增强DRF的CreateModelMixin, 标准化其返回值
"""
update_serializer_class = None
def update(self, request: Request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
instance._prefetched_objects_cache = {}
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
class DestroyModelMixin(mixins.DestroyModelMixin):
"""
继承增强DRF的CreateModelMixin, 标准化其返回值
"""
destroy_serializer_class = None
def get_object_list(self):
queryset = self.filter_queryset(self.get_queryset())
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {f"{self.lookup_field}__in": self.kwargs[lookup_url_kwarg].split(',')}
obj = queryset.filter(**filter_kwargs)
self.check_object_permissions(self.request, obj)
return obj
def destroy(self, request: Request, *args, **kwargs):
instance = self.get_object_list()
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
self.perform_destroy(instance)
return SuccessResponse(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()
class TableSerializerMixin:
table_option = None
extra_columns = []
FIELD_TYPE_MAP = {
'AutoField': {
'type': 'input',
'addDisabled': True,
},
'CharField': {
'type': 'input',
"maxlength": 255
},
'PasswordField': {
'type': 'input',
'maxlength': 255
},
'URLField': {
'type': 'input',
},
'UUIDField': {
'type': 'input',
'minlength': 32,
'maxlength': 32,
},
'UUID8Field': {
'type': 'input',
'minlength': 8,
'maxlength': 8,
},
'UUID16Field': {
'type': 'input',
'minlength': 16,
'maxlength': 16,
},
'UUID32Field': {
'type': 'input',
'minlength': 32,
'maxlength': 32,
},
'UUID36Field': {
'type': 'input',
'minlength': 36,
'maxlength': 36
},
'DateTimeField': {
'type': 'datetime',
'format': "yyyy-MM-dd hh:mm:ss",
'valueFormat': "yyyy-MM-dd hh:mm:ss",
},
'DateField': {
'type': 'date',
'format': "yyyy-MM-dd",
'valueFormat': "yyyy-MM-dd",
},
'TimeField': {
'type': 'time',
'format': "hh:mm:ss",
'valueFormat': "hh:mm:ss",
},
'BooleanField': {
'type': 'radio',
'dicData': [
{'value': False, 'label': ''},
{'value': True, 'label': ''},
]
},
'ManyRelatedField': {
# 'type': 'select',
'type': 'array',
# "multiple": True,
'required': False,
},
}
FIELD_TYPE_DEFAULT = {
'type': 'input',
}
def getTable(self, serializer: serializers.ModelSerializer = None):
if not serializer:
serializer = self.get_serializer()
serializer_class = serializer.__class__
model = serializer_class.Meta.model
title = model.__name__
if hasattr(model, 'Meta'):
if hasattr(model.Meta, 'verbose_name'):
title = model.Meta.verbose_name or ''
column = self.getColumn(serializer)
table = {
'title': title,
'page': True,
'align': 'center',
'menuAlign': 'center',
'columnBtn': True,
'menu': True,
'menuType': 'icon',
'addBtn': True,
'delBtn': True,
'editBtn': True,
'column': column
}
return table
def getColumn(self, serializer: serializers.ModelSerializer = None):
if not serializer:
serializer = self.get_serializer()
serializer_class = serializer.__class__
fields = serializer.get_fields()
show_fields = getattr(serializer_class.Meta, 'show_fields', set())
hide_fields = getattr(serializer_class.Meta, 'hide_fields', set())
search_fields = getattr(serializer_class.Meta, 'search_fields', set())
sortable_fields = getattr(serializer_class.Meta, 'sortable_fields', set())
column = []
for prop in fields:
field = fields[prop]
field_type = field.__class__.__name__
info = {
'prop': prop,
'label': field.label or prop,
'hide': hide_fields == '__all__' or prop in hide_fields,
'search': search_fields == '__all__' or prop in search_fields,
'sortable': sortable_fields == '__all__' or prop in sortable_fields,
'width': 'auto',
'align': 'left',
'overHidden': False,
}
type_info = self.FIELD_TYPE_MAP.get(field_type, self.FIELD_TYPE_DEFAULT)
info.update(type_info)
allow_null = getattr(field, 'allow_null', False)
allow_blank = getattr(field, 'allow_blank', False)
allow_empty = getattr(field, 'allow_empty', False)
read_only = getattr(field, 'read_only', False)
write_only = getattr(field, 'write_only', False)
if not any([allow_null, allow_blank, allow_empty]):
rules = [{
'required': True,
'message': f"""请输入{info['label']}""",
'trigger': "blur"
}]
info['rules'] = rules
if read_only:
info['editDisabled'] = True,
info['clearable'] = False
if not isinstance(field, (ManyRelatedField, RelatedField, PrimaryKeyRelatedField)):
# 防止序列化该字段的关系模型所有数据
choices = getattr(field, 'choices', None)
if choices:
dicData = list(map(lambda choice: {'value': choice[0], 'label': choice[1]}, choices.items()))
info['dicData'] = dicData
info['type'] = 'select'
column.append(info)
return column
class ImportSerializerMixin:
"""
自定义导出模板导入功能
"""
# 导入字段
import_field_data = {}
# 导入序列化器
import_serializer_class = None
@transaction.atomic # Django 事物
def importTemplate(self, request: Request, *args, **kwargs):
"""
用户导人模板
:param request:
:param args:
:param kwargs:
:return:
"""
assert self.import_field_data, (
"'%s' 请配置对应的导出模板字段。"
% self.__class__.__name__
)
# 导出模板
if request.method == 'GET':
# 示例数据
queryset = self.filter_queryset(self.get_queryset())
return SuccessResponse(
export_excel_save_model(request, self.import_field_data.values(), [],
f'导入{get_verbose_name(queryset)}模板.xls'))
updateSupport = request.data.get('updateSupport')
# 从excel中组织对应的数据结构然后使用序列化器保存
data = excel_to_data(request.data.get('file_url'), self.import_field_data)
queryset = self.filter_queryset(self.get_queryset())
unique_list = [ele.attname for ele in queryset.model._meta.get_fields() if
hasattr(ele, 'unique') and ele.unique == True]
for ele in data:
# 获取 unique 字段
filter_dic = {i: ele.get(i) for i in list(set(self.import_field_data.keys()) & set(unique_list))}
instance = filter_dic and queryset.filter(**filter_dic).first()
if instance and not updateSupport:
continue
if not filter_dic:
instance = None
serializer = self.import_serializer_class(instance, data=ele)
serializer.is_valid(raise_exception=True)
serializer.save()
return SuccessResponse(msg=f"导入成功!")
class ExportSerializerMixin:
"""
自定义导出功能
"""
# 导出字段
export_field_data = []
# 导出序列化器
export_serializer_class = None
def export(self, request: Request, *args, **kwargs):
"""
导出功能
:param request:
:param args:
:param kwargs:
:return:
"""
assert self.export_field_data, (
"'%s' 请配置对应的导出模板字段。"
% self.__class__.__name__
)
queryset = self.filter_queryset(self.get_queryset())
data = self.export_serializer_class(queryset, many=True).data
return SuccessResponse(export_excel_save_model(request, self.export_field_data, data,
f'导出{get_verbose_name(queryset)}.xls'))

View File

@ -1,38 +0,0 @@
from django.conf import settings
from django.db import models
from django.db.models import SET_NULL
from .fields import CreateDateTimeField, DescriptionField, ModifierCharField, UpdateDateTimeField
class BaseModel(models.Model):
"""
标准抽象模型模型,可直接继承使用
"""
description = DescriptionField() # 描述
update_datetime = UpdateDateTimeField() # 修改时间
create_datetime = CreateDateTimeField() # 创建时间
class Meta:
abstract = True
verbose_name = '基本模型'
verbose_name_plural = verbose_name
class CoreModel(models.Model):
"""
核心标准抽象模型模型,可直接继承使用
增加审计字段, 覆盖字段时, 字段名称请勿修改, 必须统一审计字段名称
"""
description = DescriptionField() # 描述
creator = models.ForeignKey(to=settings.AUTH_USER_MODEL, related_query_name='creator_query', null=True,
verbose_name='创建者', on_delete=SET_NULL, db_constraint=False) # 创建者
modifier = ModifierCharField() # 修改者
dept_belong_id = models.CharField(max_length=64, verbose_name="数据归属部门", null=True, blank=True)
update_datetime = UpdateDateTimeField() # 修改时间
create_datetime = CreateDateTimeField() # 创建时间
class Meta:
abstract = True
verbose_name = '核心模型'
verbose_name_plural = verbose_name

View File

@ -1,123 +0,0 @@
from collections import OrderedDict
from rest_framework.pagination import PageNumberPagination, _positive_int
from rest_framework.utils.urls import replace_query_param
from .response import SuccessResponse
class Pagination(PageNumberPagination):
"""
标准分页器
"""
page_size_query_param = 'pageSize'
other_page_size_query_param = []
# other_page_size_query_param = ['pageSize', ]
page_query_param = "pageNum"
other_page_query_param = []
# other_page_query_param = ['currentPage', 'pageNum']
max_page_size = 1000
page_size = 10
def paginate_queryset(self, queryset, request, view=None):
page_num = request.query_params.get(self.page_query_param)
# 判断,如果 pageNum 为all 则取消分页返回所有
if page_num == 'all':
return None
return super().paginate_queryset(queryset, request, view)
def get_next_link(self):
return super().get_next_link()
def get_previous_link(self):
return super().get_previous_link()
def get_page_size(self, request):
"""
获取页大小
:param request:
:return:
"""
if self.other_page_size_query_param:
for param_name in self.other_page_size_query_param:
if param_name in request.query_params:
return _positive_int(
request.query_params[param_name],
strict=True,
cutoff=self.max_page_size
)
return super().get_page_size(request)
def get_page_num(self, request):
"""
获取页码
:param request:
:return:
"""
if self.other_page_query_param:
for param_name in self.other_page_query_param:
if param_name in request.query_params:
return _positive_int(request.query_params[param_name], strict=True)
page_num = request.query_params.get(self.page_query_param, 1)
return _positive_int(page_num, strict=True)
def get_paginated_response(self, data, search_fields=''):
return SuccessResponse(OrderedDict([
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
class JsonPagination(Pagination):
"""
Json数据内存分页器
"""
def __init__(self, count=0) -> None:
super().__init__()
self._page_size = 0
self._page_num = 0
self._count = count
self.data_count = 0
def get_page_size(self, request):
_page_size = super().get_page_size(request)
self._page_size = _page_size
return _page_size
def get_page_num(self, request):
_page_num = super().get_page_num(request)
self._page_num = _page_num
return _page_num
def get_next_link(self):
if self._page_size * self._page_num >= self.data_count:
return None
url = self.request.build_absolute_uri()
url = replace_query_param(url, self.page_query_param, self._page_num + 1)
url = replace_query_param(url, self.page_size_query_param, self._page_size)
return url
def get_previous_link(self, count=0):
if self._page_num <= 1:
return None
url = self.request.build_absolute_uri()
url = replace_query_param(url, self.page_query_param, self._page_num - 1)
url = replace_query_param(url, self.page_size_query_param, self._page_size)
return url
def paginate_queryset(self, queryset, request, view=None):
self.get_page_size(request)
self.get_page_num(request)
return super().paginate_queryset(queryset, request, view)
def get_paginated_response(self, data, search_fields=''):
return SuccessResponse(OrderedDict([
('count', self.data_count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))

View File

@ -1,91 +0,0 @@
"""
常用的Response以及Django的ResponseDRF的Response
"""
from django.http.response import DjangoJSONEncoder, JsonResponse
from rest_framework.response import Response
class OpDRFJSONEncoder(DjangoJSONEncoder):
"""
重写DjangoJSONEncoder
(1)默认返回支持中文格式的json字符串
"""
def __init__(self, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
indent=None, separators=None, default=None):
super().__init__(skipkeys=skipkeys, ensure_ascii=False, check_circular=check_circular,
allow_nan=allow_nan, sort_keys=sort_keys, indent=indent, separators=separators,
default=default)
class SuccessResponse(Response):
"""
标准响应成功的返回, SuccessResponse(data)或者SuccessResponse(data=data)
(1)默认错误码返回200, 不支持指定其他返回码
"""
def __init__(self, data=None, msg='success', status=None, template_name=None, headers=None, exception=False,
content_type=None):
self.std_data = {
"code": 200,
"data": data,
"msg": msg,
"status": 'success'
}
super().__init__(self.std_data, status, template_name, headers, exception, content_type)
def __str__(self):
return str(self.std_data)
class ErrorResponse(Response):
"""
标准响应错误的返回,ErrorResponse(msg='xxx')
(1)默认错误码返回201, 也可以指定其他返回码:ErrorResponse(code=xxx)
"""
def __init__(self, data=None, msg='error', code=201, status=None, template_name=None, headers=None,
exception=False, content_type=None):
self.std_data = {
"code": code,
"data": data,
"msg": msg,
"status": 'error'
}
super().__init__(self.std_data, status, template_name, headers, exception, content_type)
def __str__(self):
return str(self.std_data)
class SuccessJsonResponse(JsonResponse):
"""
标准JsonResponse, SuccessJsonResponse(data)SuccessJsonResponse(data=data)
(1)仅SuccessResponse无法使用时才能推荐使用SuccessJsonResponse
"""
def __init__(self, data, msg='success', encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs):
std_data = {
"code": 200,
"data": data,
"msg": msg,
"status": 'success'
}
super().__init__(std_data, encoder, safe, json_dumps_params, **kwargs)
class ErrorJsonResponse(JsonResponse):
"""
标准JsonResponse, 仅ErrorResponse无法使用时才能使用ErrorJsonResponse
(1)默认错误码返回2001, 也可以指定其他返回码:ErrorJsonResponse(code=xxx)
"""
def __init__(self, data, msg='error', code=201, encoder=OpDRFJSONEncoder, safe=True, json_dumps_params=None,
**kwargs):
std_data = {
"code": code,
"data": data,
"msg": msg,
"status": 'error'
}
super().__init__(std_data, encoder, safe, json_dumps_params, **kwargs)

View File

@ -1,72 +0,0 @@
"""
标准返回
"""
def funcSuccess(data=None, msg='success', **kwargs):
"""
普通函数成功返回格式
:param data:
:param msg:
:return:
"""
return {
"result": True,
"msg": msg,
"data": data,
}
def funcError(data=None, msg='error', **kwargs):
"""
普通函数失败返回格式
:param data:
:param msg:
:return:
"""
return {
"result": False,
"msg": msg,
"data": data,
}
def funcResult(result=True, data=None, msg='success', **kwargs):
"""
普通函数返回格式
:param result:
:param data:
:param msg:
:return:
"""
if result:
return funcSuccess(data=data, msg=msg)
return funcError(data=data, msg=msg)
def paginate(data=None, count=0, next=None, previous=None, msg='success', code=2000):
"""
标准分页返回, 分页错误时:应该直接使用pagination()即可,无需传入任何参数
:param data: 默认为[]
:param count: 默认为len(data); 总计值, 不是data的元素个数,相当于count(*);仅当不传入count时, count==len(data)
:param next: 默认为None, 下一页
:param previous: 默认为None, 上一页
:param msg: 默认为success
:param code: 默认为2000, 建议不传入参数,使用默认即可
:return:
"""
if not data:
data = []
if not count:
count = len(data)
return {
"code": code,
"data": {
"count": count,
"next": next,
"previous": previous,
"results": data
},
"msg": msg,
"status": "success"
}

View File

@ -1,107 +0,0 @@
from django.utils.functional import cached_property
from rest_framework import serializers
from rest_framework.fields import empty
from rest_framework.request import Request
from rest_framework.serializers import ModelSerializer
from rest_framework.utils.serializer_helpers import BindingDict
class CustomModelSerializer(ModelSerializer):
"""
增强DRF的ModelSerializer,可自动更新模型的审计字段记录
(1)仅当op_drf.generics.GenericAPIView的子类里使用时有效
(2)非op_drf.generics.GenericAPIView里使用时, 与ModelSerializer作用一样,没人任何增强
(3)self.request能获取到rest_framework.request.Request对象
"""
# 修改人的审计字段名称, 默认modifier, 继承使用时可自定义覆盖
modifier_field_name = 'modifier'
# 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖
creator_field_name = 'creator'
# 数据所属部门字段
dept_belong_id_field_name = 'dept_belong_id'
# 添加默认时间返回格式
create_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
update_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True)
def __init__(self, instance=None, data=empty, request=None, **kwargs):
super().__init__(instance, data, **kwargs)
self.request: Request = request
def save(self, **kwargs):
return super().save(**kwargs)
def create(self, validated_data):
if self.context.get('request'):
self.request = self.context.get('request')
if self.request:
username = self.get_request_username()
if self.modifier_field_name in self.fields.fields:
validated_data[self.modifier_field_name] = username
if self.creator_field_name in self.fields.fields:
validated_data[self.creator_field_name] = self.request.user
if self.dept_belong_id_field_name in self.fields.fields:
validated_data[self.dept_belong_id_field_name] = getattr(self.request.user, 'dept_id', None)
return super().create(validated_data)
def update(self, instance, validated_data):
if self.request:
if hasattr(self.instance, self.modifier_field_name):
self.instance.modifier = self.get_request_username()
return super().update(instance, validated_data)
def get_request_username(self):
if getattr(self.request, 'user', None):
return getattr(self.request.user, 'username', None)
return None
@cached_property
def fields(self):
fields = BindingDict(self)
for key, value in self.get_fields().items():
fields[key] = value
if not hasattr(self, '_context'):
return fields
is_root = self.root == self
parent_is_list_root = self.parent == self.root and getattr(self.parent, 'many', False)
if not (is_root or parent_is_list_root):
return fields
try:
request = self.request or self.context['request']
except KeyError:
return fields
params = getattr(
request, 'query_params', getattr(request, 'GET', None)
)
if params is None:
pass
try:
filter_fields = params.get('_fields', None).split(',')
except AttributeError:
filter_fields = None
try:
omit_fields = params.get('_omit', None).split(',')
except AttributeError:
omit_fields = []
existing = set(fields.keys())
if filter_fields is None:
allowed = existing
else:
allowed = set(filter(None, filter_fields))
omitted = set(filter(None, omit_fields))
for field in existing:
if field not in allowed:
fields.pop(field, None)
if field in omitted:
fields.pop(field, None)
return fields

View File

@ -1,28 +0,0 @@
"""
重写校验器返回字段
"""
from rest_framework.validators import UniqueValidator, qs_exists
from apps.vadmin.utils.exceptions import APIException
class CustomUniqueValidator(UniqueValidator):
"""
继承,重写必填字段的验证器结果,防止字段暴露
"""
def __call__(self, value, serializer_field):
# Determine the underlying model field name. This may not be the
# same as the serializer field name if `source=<>` is set.
field_name = serializer_field.source_attrs[-1]
# Determine the existing instance, if this is an update operation.
instance = getattr(serializer_field.parent, 'instance', None)
queryset = self.queryset
queryset = self.filter_queryset(value, queryset, field_name)
queryset = self.exclude_current_instance(queryset, instance)
if qs_exists(queryset):
raise APIException(message=self.message)
def __repr__(self):
return super().__repr__()

View File

@ -1,98 +0,0 @@
import logging
import traceback
from types import FunctionType, MethodType
from rest_framework.exceptions import APIException as DRFAPIException
from rest_framework.request import Request
from rest_framework.views import APIView
from apps.vadmin.utils import exceptions
from .response import ErrorResponse
logger = logging.getLogger(__name__)
def op_exception_handler(ex, context):
"""
统一异常拦截处理
目的:(1)取消所有的500异常响应,统一响应为标准错误返回
(2)准确显示错误信息
:param ex:
:param context:
:return:
"""
msg = ''
if isinstance(ex, DRFAPIException):
# set_rollback()
msg = ex.detail
elif isinstance(ex, exceptions.APIException):
msg = ex.message
elif isinstance(ex, Exception):
logger.error(traceback.format_exc())
msg = str(ex)
return ErrorResponse(msg=msg)
class CustomAPIView(APIView):
"""
继承增强DRF的APIView
"""
extra_permission_classes = ()
# 仅当GET方法时会触发该权限的校验
GET_permission_classes = ()
# 仅当POST方法时会触发该权限的校验
POST_permission_classes = ()
# 仅当DELETE方法时会触发该权限的校验
DELETE_permission_classes = ()
# 仅当PUT方法时会触发该权限的校验
PUT_permission_classes = ()
view_logger_classes = ()
def initial(self, request: Request, *args, **kwargs):
super().initial(request, *args, **kwargs)
self.check_extra_permissions(request)
self.check_method_extra_permissions(request)
def get_view_loggers(self, request: Request, *args, **kwargs):
logger_classes = self.view_logger_classes or []
if not logger_classes:
return []
view_loggers = [logger_class(view=self, request=request, *args, **kwargs) for logger_class in logger_classes]
return view_loggers
def handle_logging(self, request: Request, *args, **kwargs):
view_loggers = self.get_view_loggers(request, *args, **kwargs)
method = request.method.lower()
for view_logger in view_loggers:
view_logger.handle(request, *args, **kwargs)
logger_fun = getattr(view_logger, f'handle_{method}', f'handle_other')
if logger_fun and isinstance(logger_fun, (FunctionType, MethodType)):
logger_fun(request, *args, **kwargs)
def get_extra_permissions(self):
return [permission() for permission in self.extra_permission_classes]
def check_extra_permissions(self, request: Request):
for permission in self.get_extra_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
def get_method_extra_permissions(self):
_name = self.request.method.upper()
method_extra_permission_classes = getattr(self, f"{_name}_permission_classes", None)
if not method_extra_permission_classes:
return []
return [permission() for permission in method_extra_permission_classes]
def check_method_extra_permissions(self, request):
for permission in self.get_method_extra_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)

View File

@ -1,364 +0,0 @@
from types import FunctionType, MethodType
# from rest_framework_mongoengine.generics import GenericAPIView as MongoGenericAPIView
from django.core.exceptions import ValidationError
from django.http.response import Http404
from django.shortcuts import get_object_or_404 as _get_object_or_404
from django_filters.rest_framework import DjangoFilterBackend
from mongoengine.queryset.base import BaseQuerySet
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.request import Request
from rest_framework.settings import api_settings
from rest_framework.viewsets import ViewSetMixin
from apps.vadmin.utils.exceptions import APIException
from . import mixins
from .filters import MongoSearchFilter, MongoOrderingFilter, AdvancedSearchFilter, MongoAdvancedSearchFilter
from .generics import GenericAPIView
from .logging.view_logger import CustomerModelViewLogger
from .serializers import CustomModelSerializer
def get_object_or_404(queryset, *filter_args, **filter_kwargs):
try:
return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
except (TypeError, ValueError, ValidationError, Http404):
raise APIException(message='该对象不存在或者无访问权限')
class GenericViewSet(ViewSetMixin, GenericAPIView):
extra_filter_backends = []
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter, AdvancedSearchFilter]
view_logger_classes = (CustomerModelViewLogger,)
def handle_logging(self, request: Request, *args, **kwargs):
view_loggers = self.get_view_loggers(request, *args, **kwargs)
for view_logger in view_loggers:
handle_action = getattr(view_logger, f'handle_{self.action}', None)
if handle_action and isinstance(handle_action, (FunctionType, MethodType)):
handle_action(request, *args, **kwargs)
def get_serializer(self, *args, **kwargs):
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
serializer = serializer_class(*args, **kwargs)
if isinstance(serializer, CustomModelSerializer):
serializer.request = self.request
return serializer
def filter_queryset(self, queryset):
for backend in set(set(self.filter_backends) | set(self.extra_filter_backends or [])):
queryset = backend().filter_queryset(self.request, queryset, self)
queryset = self.action_extra_filter_queryset(queryset)
return queryset
def action_extra_filter_queryset(self, queryset):
action__extra_filter_backends = getattr(self, f"{self.action}_extra_filter_backends", None)
if not action__extra_filter_backends:
return queryset
for backend in action__extra_filter_backends:
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
def get_serializer_class(self):
action_serializer_name = f"{self.action}_serializer_class"
action_serializer_class = getattr(self, action_serializer_name, None)
if action_serializer_class:
return action_serializer_class
return super().get_serializer_class()
def reverse_action(self, url_name, *args, **kwargs):
return super().reverse_action(url_name, *args, **kwargs)
def get_action_extra_permissions(self):
"""
获取已配置的action权限校验,并且实例化其对象
:return:
"""
action_extra_permission_classes = getattr(self, f"{self.action}_extra_permission_classes", None)
if not action_extra_permission_classes:
return []
return [permission() for permission in action_extra_permission_classes]
def check_action_extra_permissions(self, request):
"""
逐个校验action权限校验
:param request:
:return:
"""
for permission in self.get_action_extra_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
def check_action_extra_object_permissions(self, request, obj):
"""
action方法的专属对象权限校验
:param request:
:param obj:
:return:
"""
for permission in self.get_action_extra_permissions():
if not permission.has_object_permission(request, self, obj):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
def initial(self, request, *args, **kwargs):
"""
重写initial方法
(1)新增action的权限校验
:param request:
:param args:
:param kwargs:
:return:
"""
super().initial(request, *args, **kwargs)
self.check_action_extra_permissions(request)
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
self.check_object_permissions(self.request, obj)
return obj
def check_object_permissions(self, request, obj):
"""
重新check_object_permissions
(1)新增action方法的专属对象权限检查入口
(2)先校验共同的object_permissions, 再校验action的object_permissions
:param request:
:param obj:
:return:
"""
super().check_object_permissions(request, obj)
self.check_action_extra_object_permissions(request, obj)
class MongoGenericAPIView(GenericAPIView):
""" Adaptation of DRF GenericAPIView """
lookup_field = 'id'
def get_queryset(self):
queryset = super(MongoGenericAPIView, self).get_queryset()
if isinstance(queryset, BaseQuerySet):
queryset = queryset.all()
return queryset
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
# Perform the lookup filtering.
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
self.check_object_permissions(self.request, obj)
return obj
class MongoGenericViewSet(ViewSetMixin, MongoGenericAPIView):
extra_filter_backends = []
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter, AdvancedSearchFilter]
view_logger_classes = (CustomerModelViewLogger,)
def handle_logging(self, request: Request, *args, **kwargs):
view_loggers = self.get_view_loggers(request, *args, **kwargs)
for view_logger in view_loggers:
handle_action = getattr(view_logger, f'handle_{self.action}', None)
if handle_action and isinstance(handle_action, (FunctionType, MethodType)):
handle_action(request, *args, **kwargs)
def get_serializer(self, *args, **kwargs):
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
serializer = serializer_class(*args, **kwargs)
if isinstance(serializer, CustomModelSerializer):
serializer.request = self.request
return serializer
def filter_queryset(self, queryset):
for backend in set(set(self.filter_backends) | set(self.extra_filter_backends or [])):
queryset = backend().filter_queryset(self.request, queryset, self)
queryset = self.action_extra_filter_queryset(queryset)
return queryset
def action_extra_filter_queryset(self, queryset):
action__extra_filter_backends = getattr(self, f"{self.action}_extra_filter_backends", None)
if not action__extra_filter_backends:
return queryset
for backend in action__extra_filter_backends:
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
def get_serializer_class(self):
action_serializer_name = f"{self.action}_serializer_class"
action_serializer_class = getattr(self, action_serializer_name, None)
if action_serializer_class:
return action_serializer_class
return super().get_serializer_class()
def reverse_action(self, url_name, *args, **kwargs):
return super().reverse_action(url_name, *args, **kwargs)
def get_action_extra_permissions(self):
"""
获取已配置的action权限校验,并且实例化其对象
:return:
"""
action_extra_permission_classes = getattr(self, f"{self.action}_extra_permission_classes", None)
if not action_extra_permission_classes:
return []
return [permission() for permission in action_extra_permission_classes]
def check_action_extra_permissions(self, request):
"""
逐个校验action权限校验
:param request:
:return:
"""
for permission in self.get_action_extra_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
def check_action_extra_object_permissions(self, request, obj):
"""
action方法的专属对象权限校验
:param request:
:param obj:
:return:
"""
for permission in self.get_action_extra_permissions():
if not permission.has_object_permission(request, self, obj):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
def initial(self, request, *args, **kwargs):
"""
重写initial方法
(1)新增action的权限校验
:param request:
:param args:
:param kwargs:
:return:
"""
super().initial(request, *args, **kwargs)
self.check_action_extra_permissions(request)
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
self.check_object_permissions(self.request, obj)
return obj
def check_object_permissions(self, request, obj):
"""
重新check_object_permissions
(1)新增action方法的专属对象权限检查入口
(2)先校验共同的object_permissions, 再校验action的object_permissions
:param request:
:param obj:
:return:
"""
super().check_object_permissions(request, obj)
self.check_action_extra_object_permissions(request, obj)
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass
class MongoModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
MongoGenericViewSet):
pass
class CustomModelViewSet(ModelViewSet, mixins.TableSerializerMixin,
mixins.ImportSerializerMixin,
mixins.ExportSerializerMixin):
"""
自定义的ModelViewSet:
(1)默认分页器就为统一分页器op_drf.pagination.Pagination
(1)默认使用统一标准返回格式
(1)默认支持高级搜索
(1)默认支持生成前端动态table的option
(1)ORM性能优化, 尽可能使用values_queryset形式
"""
values_queryset = None
ordering_fields = '__all__'
def get_queryset(self):
if getattr(self, 'values_queryset', None):
return self.values_queryset
return super().get_queryset()
class CustomMongoModelViewSet(MongoModelViewSet, mixins.TableSerializerMixin):
filter_backends = (MongoOrderingFilter, MongoSearchFilter, MongoAdvancedSearchFilter)
# filter_fields = '__all__' # 暂不支持__all__
filter_fields = ()
search_fields = ()
ordering_fields = '__all__'
view_logger_classes = (CustomerModelViewLogger,)
def get_queryset(self):
queryset = self.queryset
filtering_kwargs = {}
for param in self.request.query_params:
param = param.strip()
if param in ['pageSize', 'pageNum', 'search', 'ordering', 'as']: continue
if self.filter_fields == '__all__' or param in self.filter_fields:
# if param in self.filter_fields:
filtering_kwargs[param] = self.request.query_params[param]
queryset = queryset.filter(**filtering_kwargs)
ordering_params = self.request.query_params.get(api_settings.ORDERING_PARAM, None)
if ordering_params:
ordering_fields = [field.strip() for field in ordering_params.split(',')]
ordering_fields = filter(lambda field: self.ordering_fields == '__all__' or field in self.ordering_fields,
ordering_fields)
queryset = queryset.order_by(*ordering_fields)
return queryset
def filter_queryset(self, queryset):
return super().filter_queryset(queryset)

View File

@ -1,6 +0,0 @@
from django.apps import AppConfig
class PermissionConfig(AppConfig):
name = 'apps.vadmin.permission'
verbose_name = "权限管理"

View File

@ -1,67 +0,0 @@
import django_filters
from django.contrib.auth import get_user_model
from apps.vadmin.permission.models import Menu, Dept, Post, Role
from apps.vadmin.utils.model_util import get_dept
UserProfile = get_user_model()
class MenuFilter(django_filters.rest_framework.FilterSet):
"""
菜单管理 简单序过滤器
"""
name = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Menu
exclude = ('description', 'creator', 'modifier')
class DeptFilter(django_filters.rest_framework.FilterSet):
"""
部门管理 简单序过滤器
"""
deptName = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Dept
exclude = ('description', 'creator', 'modifier')
class PostFilter(django_filters.rest_framework.FilterSet):
"""
岗位管理 简单序过滤器
"""
postName = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Post
exclude = ('description', 'creator', 'modifier')
class RoleFilter(django_filters.rest_framework.FilterSet):
"""
角色管理 简单序过滤器
"""
roleName = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Role
exclude = ('description', 'creator', 'modifier')
class UserProfileFilter(django_filters.rest_framework.FilterSet):
"""
用户管理 简单序过滤器
"""
username = django_filters.CharFilter(lookup_expr='icontains')
mobile = django_filters.CharFilter(lookup_expr='icontains')
deptId = django_filters.CharFilter(method='filter_deptId')
def filter_deptId(self, queryset, name, value):
return queryset.filter(dept__id__in=get_dept(dept_id=value))
class Meta:
model = UserProfile
exclude = ('secret', 'password',)

View File

@ -1,103 +0,0 @@
import logging
import os
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import connection
from apps.vadmin.scripts import getSql
logger = logging.getLogger(__name__)
class Command(BaseCommand):
"""
项目初始化命令: python manage.py init
"""
def customSql(self, sql_list, model_name, table_name, is_yes):
"""
批量执行sql
:param sql_list:
:param table_name: 表名
:return:
"""
with connection.cursor() as cursor:
num = 0
for ele in table_name.split(','):
cursor.execute("select count(*) from {}".format(ele))
result = cursor.fetchone()
num += result[0]
if num > 0:
while True:
if is_yes is None:
inp = input(f'[{model_name}]模型已初始化完成,继续将清空[{table_name}]表中所有数据,是否继续初始化?【 Y/N 】')
else:
inp = 'Y' if is_yes == True else 'N'
if inp.upper() == 'N':
return False
elif inp.upper() == 'Y':
logger.info(f'正在清空[{table_name}]中数据...')
cursor.execute("SET foreign_key_checks = 0")
for ele in table_name.split(','):
cursor.execute("truncate table {};".format(ele))
cursor.execute("SET foreign_key_checks = 1")
connection.commit()
logger.info(f'清空[{table_name}]中数据{result[0]}')
break
for sql in sql_list:
try:
cursor.execute(sql)
except Exception as e:
print(e)
connection.commit()
return True
def init(self, sql_filename, model_name, table_name, is_yes):
"""
初始化
:param sql_filename: sql存放位置
:param model_name: 模块名
:param table_name: 表名
:return:
"""
logger.info(f'正在初始化[{model_name}]中...')
if self.customSql(getSql(sql_filename), model_name, table_name, is_yes):
logger.info(f'[{model_name}]初始化完成!')
else:
logger.info(f'已取消[{table_name}]初始化')
def add_arguments(self, parser):
parser.add_argument('init_name', nargs='*', type=str, )
parser.add_argument('-y', nargs='*')
parser.add_argument('-Y', nargs='*')
parser.add_argument('-n', nargs='*')
parser.add_argument('-N', nargs='*')
def handle(self, *args, **options):
user_name = "_".join(settings.AUTH_USER_MODEL.lower().split("."))
init_dict = {
'system_dictdata': [os.path.join('system', 'system_dictdata.sql'), '字典管理', 'system_dictdata'],
'system_dictdetails': [os.path.join('system', 'system_dictdetails.sql'), '字典详情', 'system_dictdetails'],
'system_configsettings': [os.path.join('system', 'system_configsettings.sql'), '参数设置',
'system_configsettings'],
'permission_post': [os.path.join('permission', 'permission_post.sql'), '岗位管理', 'permission_post'],
'permission_dept': [os.path.join('permission', 'permission_dept.sql'), '部门管理', 'permission_dept'],
'permission_menu': [os.path.join('permission', 'permission_menu.sql'), '菜单管理', 'permission_menu'],
'permission_role': [os.path.join('permission', 'permission_role.sql'), '角色管理',
','.join(['permission_role', 'permission_role_dept', 'permission_role_menu'])],
'permission_userprofile': [os.path.join('permission', 'permission_userprofile.sql'), '用户管理', ','.join(
[f'{user_name}_groups', f'{user_name}', f'{user_name}_role', f'{user_name}_post'])]
}
init_name = options.get('init_name')
is_yes = None
if isinstance(options.get('y'), list) or isinstance(options.get('Y'), list):
is_yes = True
if isinstance(options.get('n'), list) or isinstance(options.get('N'), list):
is_yes = False
if init_name:
[self.init(*init_dict[ele], is_yes=is_yes) for ele in init_name if ele in init_dict]
else:
for ele in init_dict.values():
self.init(*ele, is_yes=is_yes)

View File

@ -1,5 +0,0 @@
from apps.vadmin.permission.models.dept import Dept
from apps.vadmin.permission.models.menu import Menu
from apps.vadmin.permission.models.post import Post
from apps.vadmin.permission.models.role import Role
from apps.vadmin.permission.models.users import UserProfile

View File

@ -1,22 +0,0 @@
from django.db.models import CASCADE
from django.db.models import CharField, IntegerField, ForeignKey
from apps.vadmin.op_drf.models import CoreModel
class Dept(CoreModel):
deptName = CharField(max_length=64, verbose_name="部门名称")
orderNum = IntegerField(verbose_name="显示排序")
owner = CharField(max_length=32, verbose_name="负责人", null=True, blank=True)
phone = CharField(max_length=32, verbose_name="联系电话", null=True, blank=True)
email = CharField(max_length=32, verbose_name="邮箱", null=True, blank=True)
status = CharField(max_length=8, verbose_name="部门状态", null=True, blank=True)
parentId = ForeignKey(to='permission.Dept', on_delete=CASCADE, default=False, verbose_name="上级部门",
db_constraint=False, null=True, blank=True)
class Meta:
verbose_name = '部门管理'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.deptName}"

View File

@ -1,75 +0,0 @@
from django.core.cache import cache
from django.db.models import IntegerField, ForeignKey, CharField, CASCADE, Q
from application import settings
from apps.vadmin.op_drf.models import CoreModel
class Menu(CoreModel):
# MENU_TYPE_CHOICES = (
# ("0", "目录"),
# ("1", "菜单"),
# ("2", "按钮"),
# )
# METHOD_CHOICE = (
# ('GET', 'GET'),
# ('POST', 'POST'),
# ('PUT', 'PUT'),
# ('PATCH', 'PATCH'),
# ('DELETE', 'DELETE'),
# ('HEAD', 'HEAD'),
# ('OPTIONS', 'OPTIONS'),
# ('TRACE', 'TRACE'),
# )
parentId = ForeignKey(to='Menu', on_delete=CASCADE, verbose_name="上级菜单", null=True, blank=True, db_constraint=False)
menuType = CharField(max_length=8, verbose_name="菜单类型")
icon = CharField(max_length=64, verbose_name="菜单图标", null=True, blank=True)
name = CharField(max_length=64, verbose_name="菜单名称")
orderNum = IntegerField(verbose_name="显示排序")
isFrame = CharField(max_length=8, verbose_name="是否外链")
web_path = CharField(max_length=128, verbose_name="前端路由地址", null=True, blank=True)
component_path = CharField(max_length=128, verbose_name="前端组件路径", null=True, blank=True)
interface_path = CharField(max_length=256, verbose_name="后端接口路径", null=True, blank=True)
interface_method = CharField(max_length=16, default='GET', verbose_name="接口请求方式")
perms = CharField(max_length=256, verbose_name="权限标识", null=True, blank=True)
status = CharField(max_length=8, verbose_name="菜单状态")
visible = CharField(max_length=8, verbose_name="显示状态")
isCache = CharField(max_length=8, verbose_name="是否缓存")
@classmethod
def get_interface_dict(cls):
"""
获取所有接口列表
:return:
"""
try:
interface_dict = cache.get('permission_interface_dict', {}) if getattr(settings, "REDIS_ENABLE",
False) else {}
except:
interface_dict = {}
if not interface_dict:
for ele in Menu.objects.filter(~Q(interface_path=''), ~Q(interface_path=None), status='1', ).values(
'interface_path', 'interface_method'):
if ele.get('interface_method') in interface_dict:
interface_dict[ele.get('interface_method', '')].append(ele.get('interface_path'))
else:
interface_dict[ele.get('interface_method', '')] = [ele.get('interface_path')]
if getattr(settings, "REDIS_ENABLE", False):
cache.set('permission_interface_dict', interface_dict, 84600)
return interface_dict
@classmethod
def delete_cache(cls):
"""
清空缓存中的接口列表
:return:
"""
if getattr(settings, "REDIS_ENABLE", False):
cache.delete('permission_interface_dict')
class Meta:
verbose_name = '菜单管理'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.name}"

View File

@ -1,18 +0,0 @@
from django.db.models import IntegerField, BooleanField, CharField, TextField
from apps.vadmin.op_drf.models import CoreModel
class Post(CoreModel):
postName = CharField(null=False, max_length=64, verbose_name="岗位名称")
postCode = CharField(max_length=32, verbose_name="岗位编码")
postSort = IntegerField(verbose_name="岗位顺序")
status = CharField(max_length=8, verbose_name="岗位状态")
remark = TextField(verbose_name="备注", help_text="备注", null=True, blank=True)
class Meta:
verbose_name = '岗位管理'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.postName}"

View File

@ -1,29 +0,0 @@
from django.db.models import IntegerField, BooleanField, CharField, TextField, ManyToManyField
from apps.vadmin.op_drf.models import CoreModel
class Role(CoreModel):
DATASCOPE_CHOICES = (
('1', "全部数据权限"),
('2', "自定数据权限"),
('3', "本部门数据权限"),
('4', "本部门及以下数据权限"),
('5', "仅本人数据权限"),
)
roleName = CharField(max_length=64, verbose_name="角色名称")
roleKey = CharField(max_length=64, verbose_name="权限字符")
roleSort = IntegerField(verbose_name="角色顺序")
status = CharField(max_length=8, verbose_name="角色状态")
admin = BooleanField(default=False, verbose_name="是否为admin")
dataScope = CharField(max_length=8, default='1', choices=DATASCOPE_CHOICES, verbose_name="权限范围", )
remark = TextField(verbose_name="备注", help_text="备注", null=True, blank=True)
dept = ManyToManyField(to='permission.Dept', verbose_name='数据权限-关联部门', db_constraint=False)
menu = ManyToManyField(to='permission.Menu', verbose_name='关联菜单权限', db_constraint=False)
class Meta:
verbose_name = '角色管理'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.roleName}"

View File

@ -1,66 +0,0 @@
from uuid import uuid4
from django.conf import settings
from django.contrib.auth.models import UserManager, AbstractUser
from django.core.cache import cache
from django.db.models import IntegerField, ForeignKey, CharField, TextField, ManyToManyField, CASCADE
from apps.vadmin.op_drf.models import CoreModel
class UserProfile(AbstractUser, CoreModel):
USER_TYPE_CHOICES = (
(0, "后台用户"),
(1, "前台用户"),
)
objects = UserManager()
username = CharField(max_length=150, unique=True, db_index=True, verbose_name='用户账号')
secret = CharField(max_length=255, default=uuid4, verbose_name='加密秘钥')
email = CharField(max_length=255, verbose_name="邮箱", null=True, blank=True)
mobile = CharField(max_length=255, verbose_name="电话", null=True, blank=True)
avatar = TextField(verbose_name="头像", null=True, blank=True)
name = CharField(max_length=40, verbose_name="姓名")
gender = CharField(max_length=8, verbose_name="性别", null=True, blank=True)
remark = TextField(verbose_name="备注", null=True)
user_type = IntegerField(default=0, verbose_name="用户类型")
post = ManyToManyField(to='permission.Post', verbose_name='关联岗位', db_constraint=False)
role = ManyToManyField(to='permission.Role', verbose_name='关联角色', db_constraint=False)
dept = ForeignKey(to='permission.Dept', verbose_name='归属部门', on_delete=CASCADE, db_constraint=False, null=True,
blank=True)
@property
def get_user_interface_dict(self):
interface_dict = cache.get(f'permission_interface_dict_{self.username}', {}) if \
getattr(settings, "REDIS_ENABLE", False) else {}
if not interface_dict:
for ele in self.role.filter(status='1', menu__status='1').values('menu__interface_path',
'menu__interface_method').distinct():
interface_path = ele.get('menu__interface_path')
if interface_path is None or interface_path == '':
continue
if ele.get('menu__interface_method') in interface_dict:
interface_dict[ele.get('menu__interface_method', '')].append(interface_path)
else:
interface_dict[ele.get('menu__interface_method', '')] = [interface_path]
if getattr(settings, "REDIS_ENABLE", False):
cache.set(f'permission_interface_dict_{self.username}', interface_dict, 84600)
return interface_dict
@property
def delete_cache(self):
"""
清空缓存中的接口列表
:return:
"""
if not getattr(settings, "REDIS_ENABLE", False): return ""
return cache.delete(f'permission_interface_dict_{self.username}')
class Meta:
abstract = settings.AUTH_USER_MODEL != 'permission.UserProfile'
verbose_name = '用户管理'
verbose_name_plural = verbose_name
def __str__(self):
if self.name:
return f"{self.username}({self.name})"
return f"{self.username}"

View File

@ -1,119 +0,0 @@
"""
常用的Permission以及DRF的Permission
@author: ruoxing
"""
import logging
from django.contrib.auth import get_user_model
from rest_framework.permissions import (BasePermission,
)
from rest_framework.request import Request
from rest_framework.views import APIView
from apps.vadmin.permission.models import Dept
from apps.vadmin.utils.model_util import get_dept
logger = logging.getLogger(__name__)
User = get_user_model()
class CustomPermission(BasePermission):
def __init__(self, message=None) -> None:
super().__init__()
self.message = getattr(self.__class__, 'message', '无权限')
self.user: User = None
def init_permission(self, request: Request, view: APIView):
self.user = request.user
def has_permission(self, request: Request, view: APIView):
return True
def has_object_permission(self, request: Request, view: APIView, obj):
return True
class CommonPermission(CustomPermission):
"""
通用权限类判断用户是否有这条数据的查询权限如没有则直接没有操作权限
0. 获取用户的部门id没有部门则返回 False
1. 判断过滤的数据是否有创建人所在部门 "dept_belong_id" 字段没有则返回 True
2. 如果用户没有关联角色则校验该数据是否属于本部门
3. 根据所有角色 获取所有权限范围
3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则有权限操作
4. 只为仅本人数据权限时只有操作本人数据权限并且部门为自己本部门(考虑到用户会变部门只能看当前用户所在的部门数据)
5. 自定数据权限 获取部门根据部门判断是否有权限操作
"""
message = '没有有操作权限'
def check_queryset(self, request, instance):
# 0. 获取用户的部门id没有部门则返回 False
user_dept_id = getattr(request.user, 'dept_id')
if not user_dept_id:
self.message = "该用户无部门,无权限操作!"
return False
# 1. 判断过滤的数据是否有创建人所在部门 "dept_belong_id" 字段,没有则返回 True
if not getattr(instance, 'dept_belong_id', None):
return True
# 2. 如果用户没有关联角色则校验该数据是否属于本部门
if not hasattr(request.user, 'role'):
self.message = "该用户无角色,无权限操作!"
return False
# 3. 根据所有角色 获取所有权限范围
role_list = request.user.role.filter(status='1').values('admin', 'dataScope')
dataScope_list = []
for ele in role_list:
# 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则有权限操作
if '1' == ele.get('dataScope') or ele.get('admin') == True:
return True
dataScope_list.append(ele.get('dataScope'))
dataScope_list = list(set(dataScope_list))
# 4. 只为仅本人数据权限时只有操作本人数据权限,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据)
if dataScope_list == ['5']:
return int(instance.dept_belong_id) == user_dept_id and request.user == instance.creator
# 5. 自定数据权限 获取部门,根据部门判断,是否有权限操作
dept_list = []
for ele in dataScope_list:
if ele == '2':
dept_list.extend(request.user.role.filter(status='1').values_list('dept__id', flat=True))
elif ele == '3':
dept_list.append(user_dept_id)
elif ele == '4':
dept_list.extend(get_dept(user_dept_id, ))
return int(instance.dept_belong_id) in list(set(dept_list))
def has_permission(self, request: Request, view: APIView):
return True
def has_object_permission(self, request: Request, view: APIView, instance):
self.message = f"没有此数据操作权限!"
res = self.check_queryset(request, instance)
return res
class DeptDestroyPermission(CustomPermission):
"""
部门删除权限校验判断部门下是否有用户存在存在不可删除
"""
message = '没有有操作权限'
def has_permission(self, request: Request, view: APIView):
return True
def check_queryset(self, request, instance):
if list(filter(None, instance.values_list('userprofile', flat=True))):
self.message = "该部门下有关联用户,无法删除!"
return False
if Dept.objects.filter(parentId__in=instance).count() > 0:
self.message = "该部门下有下级部门,请先删除下级部门!"
return False
return True
def has_object_permission(self, request: Request, view: APIView, instance):
res = self.check_queryset(request, instance)
return res

View File

@ -1,321 +0,0 @@
import hashlib
from django.contrib.auth import get_user_model
from rest_framework import serializers
from apps.vadmin.op_drf.serializers import CustomModelSerializer
from apps.vadmin.op_drf.validator import CustomUniqueValidator
from apps.vadmin.permission.models import Menu, Dept, Post, Role
from apps.vadmin.system.models import MessagePush
UserProfile = get_user_model()
# ================================================= #
# ************** 菜单管理 序列化器 ************** #
# ================================================= #
class MenuSerializer(CustomModelSerializer):
"""
简单菜单序列化器
"""
parentId = serializers.IntegerField(source="parentId.id", default=0)
class Meta:
model = Menu
exclude = ('description', 'creator', 'modifier')
class MenuCreateUpdateSerializer(CustomModelSerializer):
"""
菜单管理 创建/更新时的列化器
"""
def validate(self, attrs: dict):
# name = attrs['name']
# role: Role = Role.objects.filter(name=name).first()
# if role and attrs.get('instanceId', '') != role.instanceId:
# raise APIException(message=f'角色名称[{name}]不能重复')
# if getattr(self.instance, 'is_public', False) or attrs.get('is_public', False):
# up = UserPermission(self.request.user)
# if not up.is_manager():
# raise APIException(message=f'仅Manger能创建/更新角色为公共角色')
return super().validate(attrs)
def save(self, **kwargs):
Menu.delete_cache()
return super().save(**kwargs)
class Meta:
model = Menu
fields = '__all__'
class MenuTreeSerializer(serializers.ModelSerializer):
"""
菜单树形架构序列化器:递归序列化所有深度的子菜单
"""
label = serializers.CharField(source='name', default='')
parentId = serializers.IntegerField(source="parentId.id", default=0)
class Meta:
model = Menu
fields = ('id', 'label', 'orderNum', 'parentId')
# ================================================= #
# ************** 部门管理 序列化器 ************** #
# ================================================= #
class DeptSerializer(CustomModelSerializer):
"""
部门管理 简单序列化器
"""
parentId = serializers.IntegerField(source="parentId.id", default=0)
class Meta:
model = Dept
exclude = ('description', 'creator', 'modifier')
class DeptCreateUpdateSerializer(CustomModelSerializer):
"""
部门管理 创建/更新时的列化器
"""
def validate(self, attrs: dict):
return super().validate(attrs)
class Meta:
model = Dept
fields = '__all__'
class DeptTreeSerializer(serializers.ModelSerializer):
"""
部门树形架构序列化器:递归序列化所有深度的子部门
"""
label = serializers.CharField(source='deptName', default='')
parentId = serializers.IntegerField(source="parentId.id", default=0)
class Meta:
model = Dept
fields = ('id', 'label', 'parentId', 'status')
# ================================================= #
# ************** 岗位管理 序列化器 ************** #
# ================================================= #
class PostSerializer(CustomModelSerializer):
"""
岗位管理 简单序列化器
"""
class Meta:
model = Post
exclude = ('description', 'creator', 'modifier')
class ExportPostSerializer(CustomModelSerializer):
"""
导出 岗位管理 简单序列化器
"""
class Meta:
model = Post
fields = ('id', 'postName', 'postCode', 'postSort', 'status', 'creator', 'modifier', 'remark')
class PostSimpleSerializer(CustomModelSerializer):
"""
岗位管理 极简单序列化器
"""
class Meta:
model = Post
fields = ('id', 'postName', 'postCode', 'status')
class PostCreateUpdateSerializer(CustomModelSerializer):
"""
岗位管理 创建/更新时的列化器
"""
def validate(self, attrs: dict):
return super().validate(attrs)
class Meta:
model = Post
fields = '__all__'
# ================================================= #
# ************** 角色管理 序列化器 ************** #
# ================================================= #
class RoleSerializer(CustomModelSerializer):
"""
角色管理 简单序列化器
"""
class Meta:
model = Role
exclude = ('description', 'creator', 'modifier')
class ExportRoleSerializer(CustomModelSerializer):
"""
导出 角色管理 简单序列化器
"""
dataScope = serializers.SerializerMethodField()
def get_dataScope(self, obj):
dataScope = obj.get_dataScope_display()
return dataScope
class Meta:
model = Role
fields = ('id', 'roleName', 'roleKey', 'roleSort', 'dataScope', 'status', 'creator', 'modifier', 'remark')
class RoleSimpleSerializer(CustomModelSerializer):
"""
角色管理 极简单序列化器
"""
class Meta:
model = Role
fields = ('id', 'roleName', 'roleKey', 'status')
class RoleCreateUpdateSerializer(CustomModelSerializer):
"""
角色管理 创建/更新时的列化器
"""
menu = MenuSerializer(many=True, read_only=True)
dept = DeptSerializer(many=True, read_only=True)
def validate(self, attrs: dict):
return super().validate(attrs)
def save(self, **kwargs):
data = super().save(**kwargs)
data.dept.set(self.initial_data.get('dept'))
data.menu.set(self.initial_data.get('menu'))
return data
class Meta:
model = Role
fields = '__all__'
# ================================================= #
# ************** 用户管理 序列化器 ************** #
# ================================================= #
class UserProfileSerializer(CustomModelSerializer):
"""
简单用户序列化器
"""
admin = serializers.SerializerMethodField(read_only=True)
deptId = serializers.IntegerField(source='dept.id', read_only=True)
# 未读通知数量
unread_msg_count = serializers.SerializerMethodField(read_only=True)
def get_admin(self, obj: UserProfile):
role_list = obj.role.filter(status='1').values_list('admin', flat=True)
if True in list(set(role_list)):
return True
return False
def get_unread_msg_count(self, obj: UserProfile):
return MessagePush.objects.filter(status='2').exclude(messagepushuser_message_push__is_read=True,
messagepushuser_message_push__user=obj).count()
class Meta:
model = UserProfile
depth = 1
exclude = ('password', 'secret', 'user_permissions', 'groups', 'is_superuser', 'date_joined', 'creator')
class ExportUserProfileSerializer(CustomModelSerializer):
"""
用户导出 序列化器
"""
last_login = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
dept__deptName = serializers.CharField(source='dept.deptName', default='')
dept__owner = serializers.CharField(source='dept.owner', default='')
class Meta:
model = UserProfile
fields = ('id', 'username', 'name', 'email', 'mobile', 'gender', 'is_active', 'last_login', 'dept__deptName',
'dept__owner')
class UserProfileCreateUpdateSerializer(CustomModelSerializer):
"""
用户管理 创建/更新时的列化器
"""
admin = serializers.SerializerMethodField(read_only=True)
post = PostSerializer(many=True, read_only=True)
role = RoleSerializer(many=True, read_only=True)
username = serializers.CharField(required=True, max_length=150,
validators=[
CustomUniqueValidator(queryset=UserProfile.objects.all(), message="用戶已存在")],
error_messages={
"blank": "请输入用户名称",
"required": "用户名称不能为空",
"max_length": "用户名称过长",
})
def get_admin(self, obj: UserProfile):
role_list = obj.role.filter(status='1').values_list('admin', flat=True)
if True in list(set(role_list)):
return True
return False
def validate(self, attrs: dict):
return super().validate(attrs)
def save(self, **kwargs):
self.validated_data['dept_id'] = self.initial_data.get('deptId', None)
data = super().save(**kwargs)
data.post.set(self.initial_data.get('postIds'))
data.role.set(self.initial_data.get('roleIds'))
return data
def create(self, validated_data):
data = super().create(validated_data)
data.set_password(self.initial_data.get('password', None))
data.save()
return data
class Meta:
model = UserProfile
exclude = ('password', 'secret', 'user_permissions', 'groups', 'is_superuser', 'date_joined')
read_only_fields = ('dept',)
class UserProfileImportSerializer(CustomModelSerializer):
def save(self, **kwargs):
data = super().save(**kwargs)
password = hashlib.new('md5', self.initial_data.get('password', '').encode(encoding='UTF-8')).hexdigest()
data.set_password(password)
data.save()
return data
def run_validation(self, data={}):
# 把excel 数据进行格式转换
if type(data) is dict:
data['role'] = str(data['role']).split(',')
data['post'] = str(data['post']).split(',')
data['gender'] = {'': '0', '': '1', '未知': '2'}.get(data['gender'])
data['is_active'] = {'启用': True, '禁用': False}.get(data['is_active'])
return super().run_validation(data)
class Meta:
model = UserProfile
exclude = ('password', 'secret', 'user_permissions', 'groups', 'is_superuser', 'date_joined')

View File

@ -1,20 +0,0 @@
import datetime
import logging
from captcha.models import CaptchaStore
from apps.vadmin.utils.decorators import BaseCeleryApp
from apps.vadmin.op_drf.response import SuccessResponse
logger = logging.getLogger(__name__)
@BaseCeleryApp(name='apps.vadmin.permission.tasks.clear_invalid_captcha')
def clear_invalid_captcha():
"""
清除数据库中废弃失效的验证码
:return:
"""
queryset = CaptchaStore.objects.filter(expiration__lt=datetime.datetime.now())
msg = f"成功删除 {queryset.count()} 条失效验证码!"
logger.info(msg)
queryset.delete()
return SuccessResponse(msg=msg)

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,46 +0,0 @@
from django.urls import re_path
from rest_framework.routers import DefaultRouter
from apps.vadmin.permission.views import MenuModelViewSet, DeptModelViewSet, PostModelViewSet, RoleModelViewSet, \
UserProfileModelViewSet
router = DefaultRouter()
router.register(r'menus', MenuModelViewSet)
router.register(r'dept', DeptModelViewSet)
router.register(r'dept/exclude', DeptModelViewSet)
router.register(r'post', PostModelViewSet)
router.register(r'role', RoleModelViewSet)
router.register(r'user', UserProfileModelViewSet)
urlpatterns = [
re_path('dept/exclude/(?P<pk>.*)/', DeptModelViewSet.as_view({'get': 'exclude_list'})),
re_path('dept/treeselect/', DeptModelViewSet.as_view({'get': 'tree_select_list'})),
re_path('menus/treeselect/', MenuModelViewSet.as_view({'get': 'tree_select_list'})),
# 根据角色ID查询菜单下拉树结构
re_path('menus/roleMenuTreeselect/(?P<pk>.*)/', MenuModelViewSet.as_view({'get': 'role_menu_tree_select'})),
# 根据角色ID查询部门树结构
re_path('dept/roleDeptTreeselect/(?P<pk>.*)/', DeptModelViewSet.as_view({'get': 'role_dept_tree_select'})),
# 更新状态
re_path('user/changeStatus/', UserProfileModelViewSet.as_view({'put': 'change_status'})),
# 获取用户详情
re_path('user/details/', UserProfileModelViewSet.as_view({'get': 'get_user_details'})),
# 后台重置密码
re_path('user/resetPwd/', UserProfileModelViewSet.as_view({'put': 'reset_pwd'})),
# 用户自己重置密码
re_path('user/profile/updatePwd/', UserProfileModelViewSet.as_view({'put': 'update_pwd'})),
# 更新用户头像
re_path('user/profile/avatar/', UserProfileModelViewSet.as_view({'put': 'put_avatar'})),
# 获取、更新用户个人信息
re_path('user/profile/', UserProfileModelViewSet.as_view({'get': 'profile', 'put': 'put_profile'})),
# 导出用户
re_path('user/export/', UserProfileModelViewSet.as_view({'get': 'export', })),
# 导出角色
re_path('role/export/', RoleModelViewSet.as_view({'get': 'export', })),
# 导出岗位
re_path('post/export/', PostModelViewSet.as_view({'get': 'export', })),
# 用户导入模板下载及导入
re_path('user/importTemplate/',
UserProfileModelViewSet.as_view({'get': 'importTemplate', 'post': 'importTemplate'})),
]
urlpatterns += router.urls

View File

@ -1,375 +0,0 @@
from django.contrib.auth import authenticate, get_user_model
from rest_framework.request import Request
from rest_framework.views import APIView
from apps.vadmin.op_drf.response import SuccessResponse, ErrorResponse
from apps.vadmin.permission.permissions import CommonPermission, DeptDestroyPermission
from apps.vadmin.op_drf.filters import DataLevelPermissionsFilter
from apps.vadmin.op_drf.viewsets import CustomModelViewSet
from apps.vadmin.permission.filters import MenuFilter, DeptFilter, PostFilter, RoleFilter, UserProfileFilter
from apps.vadmin.permission.models import Role, Menu, Dept, Post
from apps.vadmin.permission.serializers import UserProfileSerializer, MenuSerializer, RoleSerializer, \
MenuCreateUpdateSerializer, DeptSerializer, DeptCreateUpdateSerializer, PostSerializer, PostCreateUpdateSerializer, \
RoleCreateUpdateSerializer, DeptTreeSerializer, MenuTreeSerializer, UserProfileCreateUpdateSerializer, \
PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer, \
UserProfileImportSerializer
from apps.vadmin.system.models import DictDetails
UserProfile = get_user_model()
class GetUserProfileView(APIView):
"""
获取用户详细信息
"""
def get(self, request, format=None):
user_dict = UserProfileSerializer(request.user).data
permissions_list = ['*:*:*'] if user_dict.get('admin') else Menu.objects.filter(
role__userprofile=request.user).values_list('perms', flat=True)
delete_cache = request.user.delete_cache
return SuccessResponse({
'permissions': [ele for ele in permissions_list if ele],
'roles': Role.objects.filter(userprofile=request.user).values_list('roleKey', flat=True),
'user': user_dict
})
class GetRouters(APIView):
"""
获取路由详细信息
"""
def depth_menu(self, menus):
"""
获取菜单(通过前端递归值)
:param menus:
:return:
"""
return dict
def get(self, request, format=None):
kwargs = {}
if not request.user.is_superuser:
kwargs['role__userprofile'] = request.user
menus = Menu.objects.filter(**kwargs) \
.exclude(menuType='2').values('id', 'name', 'web_path', 'visible', 'status', 'isFrame', 'component_path',
'icon', 'parentId', 'orderNum', 'isCache').distinct()
data = []
sys_show_hide = DictDetails.get_default_dictValue('sys_show_hide')
for ele in menus:
data.append({
'id': ele.get('id'),
'name': ele.get('web_path', '').split('/')[-1] and ele.get('web_path', '').split('/')[-1].capitalize(),
'path': ele.get('web_path'),
'orderNum': ele.get('orderNum'),
'hidden': True if ele.get('visible') != '1' else False,
'redirect': ele.get('web_path') if ele.get('isFrame') == '1' else 'noRedirect',
'component': ele.get('component_path') or 'Layout',
'meta': {'title': ele.get('name'), 'icon': ele.get('icon'),
'noCache': True if ele.get('isCache') == sys_show_hide else False},
'parentId': ele.get('parentId')
})
return SuccessResponse(data)
class MenuModelViewSet(CustomModelViewSet):
"""
菜单模型 的CRUD视图
"""
queryset = Menu.objects.all()
serializer_class = MenuSerializer
create_serializer_class = MenuCreateUpdateSerializer
update_serializer_class = MenuCreateUpdateSerializer
filter_class = MenuFilter
extra_filter_backends = [DataLevelPermissionsFilter]
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
search_fields = ('name',)
ordering = 'create_datetime' # 默认排序
def tree_select_list(self, request: Request, *args, **kwargs):
"""
递归获取部门树
:param request:
:param args:
:param kwargs:
:return:
"""
queryset = self.filter_queryset(self.get_queryset())
if hasattr(self, 'handle_logging'):
self.handle_logging(request, *args, **kwargs)
serializer = MenuTreeSerializer(queryset, many=True)
return SuccessResponse(serializer.data)
def role_menu_tree_select(self, request: Request, *args, **kwargs):
"""
根据角色ID查询菜单下拉树结构
:param request:
:param args:
:param kwargs:
:return:
"""
menu_queryset = Menu.objects.filter(role__id=kwargs.get('pk')).values_list('id', flat=True)
queryset = self.filter_queryset(self.get_queryset())
if hasattr(self, 'handle_logging'):
self.handle_logging(request, *args, **kwargs)
serializer = MenuTreeSerializer(queryset, many=True)
return SuccessResponse({
'menus': serializer.data,
'checkedKeys': menu_queryset
})
class DeptModelViewSet(CustomModelViewSet):
"""
部门管理 的CRUD视图
"""
queryset = Dept.objects.all()
serializer_class = DeptSerializer
create_serializer_class = DeptCreateUpdateSerializer
update_serializer_class = DeptCreateUpdateSerializer
filter_class = DeptFilter
extra_filter_backends = [DataLevelPermissionsFilter]
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission, DeptDestroyPermission)
create_extra_permission_classes = (CommonPermission,)
search_fields = ('deptName',)
ordering = 'create_datetime' # 默认排序
def exclude_list(self, request: Request, *args, **kwargs):
"""
过滤剔除同级部门
:param request:
:param args:
:param kwargs:
:return:
"""
dept_queryset = Dept.objects.filter(id=kwargs.get('pk')).first()
parentId = dept_queryset.parentId if dept_queryset else ''
queryset = self.queryset.exclude(parentId=parentId).order_by('orderNum')
if hasattr(self, 'handle_logging'):
self.handle_logging(request, *args, **kwargs)
serializer = self.get_serializer(queryset, many=True)
return SuccessResponse(serializer.data)
def tree_select_list(self, request: Request, *args, **kwargs):
"""
递归获取部门树
:param request:
:param args:
:param kwargs:
:return:
"""
queryset = self.filter_queryset(self.get_queryset())
if hasattr(self, 'handle_logging'):
self.handle_logging(request, *args, **kwargs)
serializer = DeptTreeSerializer(queryset, many=True)
return SuccessResponse(serializer.data)
def role_dept_tree_select(self, request: Request, *args, **kwargs):
"""
根据角色ID查询部门树结构
:param request:
:param args:
:param kwargs:
:return:
"""
dept_queryset = Dept.objects.filter(role__id=kwargs.get('pk')).values_list('id', flat=True)
queryset = self.filter_queryset(self.get_queryset())
if hasattr(self, 'handle_logging'):
self.handle_logging(request, *args, **kwargs)
serializer = DeptTreeSerializer(queryset, many=True)
return SuccessResponse({
'depts': serializer.data,
'checkedKeys': dept_queryset
})
class PostModelViewSet(CustomModelViewSet):
"""
岗位管理 的CRUD视图
"""
queryset = Post.objects.all()
serializer_class = PostSerializer
create_serializer_class = PostCreateUpdateSerializer
update_serializer_class = PostCreateUpdateSerializer
filter_class = PostFilter
extra_filter_backends = [DataLevelPermissionsFilter]
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
search_fields = ('postName',)
ordering = ['postSort', 'create_datetime'] # 默认排序
export_field_data = ['岗位序号', '岗位编码', '岗位名称', '岗位排序', '状态', '创建者', '修改者', '备注']
export_serializer_class = ExportPostSerializer
class RoleModelViewSet(CustomModelViewSet):
"""
角色管理 的CRUD视图
"""
queryset = Role.objects.all()
serializer_class = RoleSerializer
create_serializer_class = RoleCreateUpdateSerializer
update_serializer_class = RoleCreateUpdateSerializer
filter_class = RoleFilter
extra_filter_backends = [DataLevelPermissionsFilter]
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
search_fields = ('roleName',)
ordering = 'create_datetime' # 默认排序
export_field_data = ['角色序号', '角色名称', '角色权限', '角色排序', '数据范围', '角色状态', '创建者', '修改者', '备注']
export_serializer_class = ExportRoleSerializer
class UserProfileModelViewSet(CustomModelViewSet):
"""
用户管理 的CRUD视图
"""
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
create_serializer_class = UserProfileCreateUpdateSerializer
update_serializer_class = UserProfileCreateUpdateSerializer
filter_class = UserProfileFilter
extra_filter_backends = [DataLevelPermissionsFilter]
# 导出
export_serializer_class = ExportUserProfileSerializer
export_field_data = ['用户序号', '登录名称', '用户名称', '用户邮箱', '手机号码', '用户性别', '帐号状态', '最后登录时间', '部门名称', '部门负责人']
# 导入
import_serializer_class = UserProfileImportSerializer
import_field_data = {'username': '登录账号', 'name': '用户名称', 'email': '用户邮箱', 'mobile': '手机号码',
'gender': '用户性别(男/女/未知)',
'is_active': '帐号状态(启用/禁用)', 'password': '登录密码', 'dept': '部门ID', 'role': '角色ID',
'post': '岗位ID'}
update_extra_permission_classes = (CommonPermission,)
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
search_fields = ('username',)
ordering = 'create_datetime' # 默认排序
def change_status(self, request: Request, *args, **kwargs):
"""
修改用户状态
:param request:
:param args:
:param kwargs:
:return:
"""
instance = self.queryset.get(id=request.data.get('userId'))
instance.is_active = request.data.get('status')
instance.save()
serializer = self.get_serializer(instance)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
def get_user_details(self, request: Request, *args, **kwargs):
"""
获取用户详情
:param request:
:param args:
:param kwargs:
:return:
"""
userId = request.query_params.get('userId')
data = {
'posts': PostSimpleSerializer(Post.objects.filter(status='1').order_by('postSort'), many=True).data,
'roles': RoleSimpleSerializer(Role.objects.filter(status='1').order_by('roleSort'), many=True).data
}
if userId:
instance = self.queryset.get(id=userId)
serializer = self.get_serializer(instance)
data['data'] = serializer.data
data['postIds'] = [ele.get('id') for ele in serializer.data.get('post')]
data['roleIds'] = [ele.get('id') for ele in serializer.data.get('role')]
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(data)
def reset_pwd(self, request: Request, *args, **kwargs):
"""
重置密码
:param request:
:param args:
:param kwargs:
:return:
"""
instance = self.queryset.get(id=request.data.get('userId'))
serializer = self.get_serializer(instance)
instance.set_password(request.data.get('password'))
instance.save()
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
def profile(self, request: Request, *args, **kwargs):
"""
获取用户个人信息
:param request:
:param args:
:param kwargs:
:return:
"""
instance = self.queryset.get(id=request.user.id)
serializer = self.get_serializer(instance)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
def put_profile(self, request: Request, *args, **kwargs):
"""
更新用户个人信息
:param request:
:param args:
:param kwargs:
:return:
"""
instance = self.queryset.get(id=request.user.id)
instance.name = request.data.get('name', None)
instance.mobile = request.data.get('mobile', None)
instance.email = request.data.get('email', None)
instance.gender = request.data.get('gender', None)
instance.save()
serializer = self.get_serializer(instance)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
def put_avatar(self, request: Request, *args, **kwargs):
"""
更新用户头像
:param request:
:param args:
:param kwargs:
:return:
"""
instance = self.queryset.get(id=request.user.id)
instance.avatar = request.data.get('avatar_url', None)
instance.save()
serializer = self.get_serializer(instance)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)
def update_pwd(self, request: Request, *args, **kwargs):
"""
个人修改密码
:param request:
:param args:
:param kwargs:
:return:
"""
instance = self.queryset.get(id=request.user.id)
instance.password = request.data.get('newPassword', None)
if not authenticate(username=request.user.username, password=request.data.get('oldPassword', None)):
return ErrorResponse(msg='旧密码不正确!')
instance.set_password(request.data.get('newPassword'))
instance.save()
serializer = self.get_serializer(instance)
if hasattr(self, 'handle_logging'):
self.handle_logging(request, instance=instance, *args, **kwargs)
return SuccessResponse(serializer.data)

View File

@ -1,20 +0,0 @@
import os
from django.conf import settings
def getSql(filename):
"""
获取文件内所有sql
:param filename: 例如os.path.join('permission','permission_dept.sql')
:return:
"""
abspath = os.path.abspath(os.path.join(os.path.abspath(os.path.dirname(__file__)), ".."))
pwd = os.path.join(abspath, 'scripts', filename)
with open(pwd, 'rb') as fp:
content = fp.read().decode('utf8')
if filename == "permission/permission_userprofile.sql":
user_name = "_".join(settings.AUTH_USER_MODEL.lower().split("."))
content = content.replace("permission_userprofile", user_name). \
replace("userprofile", settings.AUTH_USER_MODEL.lower().split(".")[-1])
return [ele for ele in content.split('\n') if not ele.startswith('--') and ele.strip(' ')]

View File

@ -1,42 +0,0 @@
-- ----------------------------
-- 部门管理 初始化sql
-- Table structure for permission_dept
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_dept`;
-- CREATE TABLE `permission_dept` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `description` longtext,
-- `creator` varchar(255) DEFAULT NULL,
-- `modifier` varchar(255) DEFAULT NULL,
-- `update_datetime` datetime(6) DEFAULT NULL,
-- `create_datetime` datetime(6) DEFAULT NULL,
-- `deptName` varchar(64) NOT NULL,
-- `orderNum` int(11) NOT NULL,
-- `owner` varchar(32) DEFAULT NULL,
-- `phone` varchar(32) DEFAULT NULL,
-- `email` varchar(32) DEFAULT NULL,
-- `status` varchar(8) DEFAULT NULL,
-- `parentId_id` int(11) DEFAULT NULL,
-- PRIMARY KEY (`id`),
-- KEY `permission_dept_parentId_id_43a4fd49` (`parentId_id`) USING BTREE
-- ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_dept
-- ----------------------------
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (1, '', 'admin', '2021-02-27 07:26:20.518695', '2021-02-27 15:18:39.000000', 'XX创新科技', 1, NULL, '15888888888', 'cxkj@qq.com', '1', 1,NULL, 1);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (2, '', 'admin', '2021-02-27 07:25:09.041807', '2021-02-27 07:25:09.041853', '北京总公司', 1, NULL, NULL, NULL, '1', 1, 1, 2);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (3, '', 'admin', '2021-02-27 07:26:14.418894', '2021-02-27 07:25:25.195849', '上海分公司', 2, NULL, NULL, NULL, '1', 1, 1, 3);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (4, '', 'admin', '2021-02-27 07:26:01.993095', '2021-02-27 07:25:38.904644', '杭州分公司', 4, NULL, NULL, NULL, '1', 1, 1, 4);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (5, '', 'admin', '2021-02-27 07:28:15.854856', '2021-02-27 07:25:54.379081', '深圳分公司', 3, NULL, NULL, NULL, '0', 1, 1, 5);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (6, '', 'admin', '2021-02-27 07:26:37.589741', '2021-02-27 07:26:37.589780', '研发部门', 1, NULL, NULL, NULL, '1', 1, 2, 6);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (7, '', 'admin', '2021-02-27 07:26:47.781467', '2021-02-27 07:26:47.781511', '市场部门', 2, NULL, NULL, NULL, '1', 1, 2, 7);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (8, '', 'admin', '2021-02-27 07:26:57.059878', '2021-02-27 07:26:57.059923', '测试部门', 3, NULL, NULL, NULL, '1', 1, 2, 8);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (9, '', 'admin', '2021-02-27 07:27:06.088134', '2021-02-27 07:27:06.088178', '财务部门', 4, NULL, NULL, NULL, '1', 1, 2, 9);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (10, '', 'admin', '2021-02-27 07:27:15.287731', '2021-02-27 07:27:15.287772', '运维部门', 5, NULL, NULL, NULL, '1', 1, 2, 10);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (11, '', 'admin', '2021-02-27 07:27:24.834369', '2021-02-27 07:27:24.834413', '市场部门', 1, NULL, NULL, NULL, '1', 1, 3, 11);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (12, '', 'admin', '2021-02-27 07:27:34.161898', '2021-02-27 07:27:34.161944', '财务部门', 2, NULL, NULL, NULL, '1', 1, 3, 12);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (13, '', 'admin', '2021-02-27 07:28:20.474025', '2021-02-27 07:27:47.938676', '市场部门', 1, NULL, NULL, NULL, '0', 1, 5, 13);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (14, '', 'admin', '2021-02-27 07:28:23.394188', '2021-02-27 07:27:53.794331', '财务部门', 2, NULL, NULL, NULL, '0', 1, 5, 14);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (15, '', 'admin', '2021-02-27 07:28:03.368497', '2021-02-27 07:28:03.368540', '市场部门', 1, NULL, NULL, NULL, '1', 1, 4, 15);
INSERT INTO `permission_dept` (id, description, modifier, update_datetime, create_datetime, deptName, orderNum, owner, phone, email, status, creator_id, parentId_id, dept_belong_id) VALUES (16, '', 'admin', '2021-02-27 07:28:10.532392', '2021-02-27 07:28:10.532436', '财务部门', 2, NULL, NULL, NULL, '1', 1, 4, 16);

View File

@ -1,129 +0,0 @@
-- ----------------------------
-- 菜单管理初始化sql
-- Table structure for permission_menu
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_menu`;
-- CREATE TABLE `permission_menu` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `description` longtext,
-- `creator` varchar(255) DEFAULT NULL,
-- `modifier` varchar(255) DEFAULT NULL,
-- `update_datetime` datetime(6) DEFAULT NULL,
-- `create_datetime` datetime(6) DEFAULT NULL,
-- `menuType` varchar(8) NOT NULL,
-- `icon` varchar(64) DEFAULT NULL,
-- `name` varchar(64) NOT NULL,
-- `orderNum` int(11) NOT NULL,
-- `isFrame` varchar(8) NOT NULL,
-- `web_path` varchar(128) DEFAULT NULL,
-- `component_path` varchar(128) DEFAULT NULL,
-- `interface_path` varchar(256) DEFAULT NULL,
-- `interface_method` varchar(16) NOT NULL,
-- `perms` varchar(256) DEFAULT NULL,
-- `status` varchar(8) NOT NULL,
-- `visible` varchar(8) NOT NULL,
-- `isCache` varchar(8) NOT NULL,
-- `parentId_id` int(11) DEFAULT NULL,
-- PRIMARY KEY (`id`),
-- KEY `permission_menu_parentId_id_df49c7ef_fk_permission_menu_id` (`parentId_id`),
-- CONSTRAINT `permission_menu_parentId_id_df49c7ef_fk_permission_menu_id` FOREIGN KEY (`parentId_id`) REFERENCES `permission_menu` (`id`)
-- ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_menu
-- ----------------------------
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (1, '', 'admin', '2021-02-27 07:50:00.410101', '2021-02-27 07:41:28.660364', '0', 'system', '系统管理', 1, '1', '/system', '', '', 'GET', NULL, '1', '1', '1', 1, NULL, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (2, '', 'admin', '2021-02-27 07:51:14.500722', '2021-02-27 07:51:14.500768', '0', 'peoples', '权限管理', 2, '1', '/permission', '', '', 'GET', NULL, '1', '1', '1', 1, NULL, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (3, '', 'admin', '2021-03-16 14:50:55.740451', '2021-02-27 07:54:38.630670', '1', 'dict', '字典管理', 1, '1', 'dict', 'vadmin/system/dict/index', '', 'GET', '', '1', '1', '1', 1, 1, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (4, '', 'admin', '2021-03-26 00:48:34.067871', '2021-02-27 08:06:51.019173', '1', 'edit', '参数管理', 2, '1', 'config', 'vadmin/system/config/index', '', 'GET', '', '1', '1', '1', 1, 1, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (5, '', 'admin', '2021-03-26 00:49:19.728695', '2021-02-27 08:25:37.339270', '1', 'post', '岗位管理', 1, '1', 'post', 'vadmin/permission/post/index', '', 'GET', '', '1', '1', '1', 1, 2, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (6, '', 'admin', '2021-03-26 00:49:25.882167', '2021-02-27 08:26:48.454553', '1', 'tree', '部门管理', 2, '1', 'dept', 'vadmin/permission/dept/index', '', 'GET', '', '1', '1', '1', 1, 2, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (7, '', 'admin', '2021-03-26 00:49:31.601381', '2021-02-27 08:28:20.411164', '1', 'tree-table', '菜单管理', 3, '1', 'menu', 'vadmin/permission/menu/index', '', 'GET', '', '1', '1', '0', 1, 2, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (8, '', 'admin', '2021-03-26 00:49:37.244296', '2021-02-27 08:29:30.153361', '1', 'peoples', '角色管理', 4, '1', 'role', 'vadmin/permission/role/index', '', 'GET', '', '1', '1', '1', 1, 2, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (9, '', 'admin', '2021-03-26 00:49:42.699298', '2021-02-27 08:30:14.030888', '1', 'user', '用户管理', 5, '1', 'user', 'vadmin/permission/user/index', '', 'GET', '', '1', '1', '1', 1, 2, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (10, '', 'admin', '2021-03-26 00:51:15.986262', '2021-02-27 08:36:04.824117', '0', 'guide', 'dvAdmin官网', 9, '0', 'https://django-vue-admin.com', '', NULL, 'GET', NULL, '1', '1', '1', 1, NULL, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (11, '', 'admin', '2021-03-26 00:48:40.309707', '2021-02-27 16:17:36.685174', '1', 'job', '文件管理', 3, '1', 'savefile', 'vadmin/system/savefile/index', '', 'GET', '', '1', '1', '1', 1, 1, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (13, '', 'admin', '2021-03-03 14:41:08.227821', '2021-03-03 14:18:52.530449', '2', NULL, '用户新增', 1, '1', NULL, NULL, '/admin/permission/user/', 'POST', 'permission:user:post', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (14, '', 'admin', '2021-03-03 14:43:34.207938', '2021-03-03 14:43:34.208093', '2', NULL, '用户修改', 2, '1', NULL, NULL, '/admin/permission/user/{id}/', 'PUT', 'permission:user:{id}:put', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (15, '', 'admin', '2021-03-03 14:44:58.006289', '2021-03-03 14:44:58.006338', '2', NULL, '用户删除', 3, '1', '', NULL, '/admin/permission/user/{id}/', 'DELETE', 'permission:user:{id}:delete', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (16, '', 'admin', '2021-03-03 14:45:50.575443', '2021-03-03 14:45:50.575507', '2', NULL, '用户导出', 4, '1', NULL, NULL, '/admin/permission/user/export/', 'GET', 'permission:user:export:get', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (17, '', 'admin', '2021-03-03 14:51:14.157310', '2021-03-03 14:51:14.157447', '2', NULL, '用户导入', 5, '1', NULL, NULL, '/admin/permission/user/import/', 'POST', 'permission:user:import:post', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (18, '', 'admin', '2021-03-03 14:51:51.220886', '2021-03-03 14:51:51.220933', '2', NULL, '重置密码', 6, '1', NULL, NULL, '/admin/permission/user/resetPwd/', 'PUT', 'permission:user:resetpwd:put', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (19, '', 'admin', '2021-03-03 14:53:47.877063', '2021-03-03 14:53:47.877116', '2', NULL, '角色新增', 1, '1', NULL, NULL, '/admin/permission/role/', 'POST', 'permission:role:post', '1', '1', '1', 1, 8, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (20, '', 'admin', '2021-03-03 14:54:28.794968', '2021-03-03 14:54:28.795015', '2', NULL, '角色修改', 2, '1', NULL, NULL, '/admin/permission/role/{id}/', 'PUT', 'permission:role:{id}:put', '1', '1', '1', 1, 8, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (21, '', 'admin', '2021-03-03 14:58:00.798718', '2021-03-03 14:58:00.798813', '2', NULL, '删除角色', 3, '1', NULL, NULL, '/admin/permission/role/{id}/', 'DELETE', 'permission:role:{id}:delete', '1', '1', '1', 1, 8, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (22, '', 'admin', '2021-03-03 14:58:28.940577', '2021-03-03 14:58:28.940625', '2', NULL, '角色导出', 4, '1', NULL, NULL, '/admin/permission/role/export/', 'GET', 'permission:role:export:get', '1', '1', '1', 1, 8, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (23, '', 'admin', '2021-03-03 15:00:41.081771', '2021-03-03 15:00:41.081832', '2', NULL, '菜单新增', 1, '1', NULL, NULL, '/admin/permission/menus/', 'POST', 'permission:menus:post', '1', '1', '1', 1, 7, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (24, '', 'admin', '2021-03-03 15:01:03.178824', '2021-03-03 15:01:03.178874', '2', NULL, '菜单修改', 2, '1', NULL, NULL, '/admin/permission/menus/{id}/', 'PUT', 'permission:menus:{id}:put', '1', '1', '1', 1, 7, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (25, '', 'admin', '2021-03-03 15:02:56.123525', '2021-03-03 15:02:56.123571', '2', NULL, '菜单删除', 3, '1', NULL, NULL, '/admin/permission/menus/{id}/', 'DELETE', 'permission:menus:{id}:delete', '1', '1', '1', 1, 7, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (26, '', 'admin', '2021-03-03 15:04:35.191774', '2021-03-03 15:04:35.191856', '2', NULL, '部门新增', 1, '1', NULL, NULL, '/admin/permission/dept/', 'POST', 'permission:dept:post', '1', '1', '1', 1, 6, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (27, '', 'admin', '2021-03-03 15:04:56.963168', '2021-03-03 15:04:56.963214', '2', NULL, '部门修改', 2, '1', NULL, NULL, '/admin/permission/dept/{id}/', 'PUT', 'permission:dept:{id}:put', '1', '1', '1', 1, 6, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (28, '', 'admin', '2021-03-03 15:05:39.602577', '2021-03-03 15:05:39.602622', '2', NULL, '部门删除', 3, '1', NULL, NULL, '/admin/permission/dept/{id}/', 'DELETE', 'permission:dept:{id}:delete', '1', '1', '1', 1, 6, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (29, '', 'admin', '2021-03-03 15:06:50.095341', '2021-03-03 15:06:50.095388', '2', NULL, '岗位新增', 1, '1', NULL, NULL, '/admin/permission/post/', 'POST', 'permission:post:post', '1', '1', '1', 1, 5, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (30, '', 'admin', '2021-03-03 15:07:36.013313', '2021-03-03 15:07:36.013358', '2', NULL, '岗位修改', 2, '1', NULL, NULL, '/admin/permission/post/{id}/', 'PUT', 'permission:post:{id}:put', '1', '1', '1', 1, 5, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (31, '', 'admin', '2021-03-03 15:08:10.371530', '2021-03-03 15:08:10.371575', '2', NULL, '岗位删除', 3, '1', NULL, NULL, '/admin/permission/post/{id}/', 'DELETE', 'permission:post:{id}:delete', '1', '1', '1', 1, 5, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (32, '', 'admin', '2021-03-03 15:09:02.213084', '2021-03-03 15:09:02.213131', '2', NULL, '岗位导出', 4, '1', NULL, NULL, '/admin/permission/post/export/', 'GET', 'permission:post:export:get', '1', '1', '1', 1, 5, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (33, '', 'admin', '2021-03-03 15:11:37.616329', '2021-03-03 15:11:37.616415', '2', NULL, '字典新增', 1, '1', NULL, NULL, '/admin/system/dict/type/', 'POST', 'system:dict:type:post', '1', '1', '1', 1, 3, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (34, '', 'admin', '2021-03-03 15:12:47.237658', '2021-03-03 15:12:47.237713', '2', NULL, '字典修改', 2, '1', NULL, NULL, '/admin/system/dict/type/{id}/', 'PUT', 'system:dict:type:{id}:put', '1', '1', '1', 1, 3, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (35, '', 'admin', '2021-03-03 15:13:40.185174', '2021-03-03 15:13:40.185230', '2', NULL, '字典删除', 3, '1', NULL, NULL, '/admin/system/dict/type/{id}/', 'DELETE', 'system:dict:type:{id}:delete', '1', '1', '1', 1, 3, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (36, '', 'admin', '2021-03-03 15:15:12.950584', '2021-03-03 15:15:12.950684', '2', NULL, '字典导出', 4, '1', NULL, NULL, '/admin/system/dict/type/export/', 'GET', 'system:dict:type:export:get', '1', '1', '1', 1, 3, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (37, '', 'admin', '2021-03-03 15:16:54.709780', '2021-03-03 15:16:20.868146', '2', NULL, '清理缓存', 5, '1', NULL, NULL, '/admin/system/dict/type/clearCache/', 'DELETE', 'system:dict:type:clearcache:delete', '1', '1', '1', 1, 3, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (38, '', 'admin', '2021-03-03 15:17:54.232085', '2021-03-03 15:17:54.232166', '2', NULL, '参数新增', 1, '1', NULL, NULL, '/admin/system/config/', 'POST', 'system:config:post', '1', '1', '1', 1, 4, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (39, '', 'admin', '2021-03-03 15:18:37.088187', '2021-03-03 15:18:37.088237', '2', NULL, '参数修改', 2, '1', NULL, NULL, '/admin/system/config/{id}/', 'PUT', 'system:config:{id}:put', '1', '1', '1', 1, 4, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (40, '', 'admin', '2021-03-03 15:19:05.532556', '2021-03-03 15:19:05.532616', '2', NULL, '参数删除', 3, '1', NULL, NULL, '/admin/system/config/{id}/', 'DELETE', 'system:config:{id}:delete', '1', '1', '1', 1, 4, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (41, '', 'admin', '2021-03-03 15:19:49.576174', '2021-03-03 15:19:49.576221', '2', NULL, '参数导出', 4, '1', NULL, NULL, '/admin/system/config/export/', 'GET', 'system:config:export:get', '1', '1', '1', 1, 4, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (42, '', 'admin', '2021-03-03 15:21:20.098250', '2021-03-03 15:21:20.098345', '2', NULL, '清理缓存', 5, '1', NULL, NULL, '/admin/system/config/clearCache/', 'DELETE', 'system:config:clearcache:delete', '1', '1', '1', 1, 4, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (43, '', 'admin', '2021-03-03 15:22:48.492613', '2021-03-03 15:22:48.492666', '2', NULL, '文件上传', 1, '1', NULL, NULL, '/admin/system/savefile/', 'POST', 'system:savefile:post', '1', '1', '1', 1, 11, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (44, '', 'admin', '2021-03-03 15:23:58.219105', '2021-03-03 15:23:58.219155', '2', NULL, '文件删除', 2, '1', NULL, NULL, '/admin/system/savefile/{id}/', 'DELETE', 'system:savefile:{id}:delete', '1', '1', '1', 1, 11, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (45, '', 'admin', '2021-03-03 15:25:15.224971', '2021-03-03 15:25:15.225018', '2', NULL, '清理废弃文件', 3, '1', NULL, NULL, '/admin/system/clearsavefile/', 'POST', 'system:clearsavefile:post', '1', '1', '1', 1, 11, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (46, '', 'admin', '2021-03-03 15:28:30.061632', '2021-03-03 15:27:19.945663', '2', NULL, '文件下载', 4, '1', NULL, NULL, NULL, 'GET', 'system:clearsavefile:download:post', '1', '1', '1', 1, 11, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (47, '', 'admin', '2021-03-26 00:48:49.655959', '2021-03-07 14:32:06.754815', '1', 'message', '通知公告', 4, '1', 'message', 'vadmin/system/message/index', '', 'GET', '', '1', '1', '1', 1, 1, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (48, '', 'admin', '2021-03-07 14:35:06.718432', '2021-03-07 14:35:06.718463', '2', NULL, '发布公告', 1, '1', NULL, NULL, '/admin/system/message/', 'POST', 'system:message:post', '1', '1', '1', 1, 47, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (49, '', 'admin', '2021-03-08 13:04:32.158707', '2021-03-07 14:36:47.675837', '2', NULL, '修改公告', 2, '1', NULL, NULL, '/admin/system/message/{id}/', 'PUT', 'system:message:{id}:put', '1', '1', '1', 1, 47, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (50, '', 'admin', '2021-03-08 13:04:58.206693', '2021-03-07 14:37:52.130567', '2', NULL, '删除公告', 3, '1', NULL, NULL, '/admin/permission/menu/{id}/', 'DELETE', 'permission:menu:{id}:delete', '1', '1', '1', 1, 47, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (51, '', 'admin', '2021-03-07 14:42:37.410336', '2021-03-07 14:42:37.410366', '2', NULL, '公告导出', 4, '1', NULL, NULL, '/admin/system/message/export/', 'GET', 'system:message:export:get', '1', '1', '1', 1, 47, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (52, '', 'admin', '2021-03-09 17:19:13.828166', '2021-03-09 17:18:14.976783', '2', NULL, '字典查询', 0, '1', NULL, NULL, '/admin/system/dict/type/', 'GET', 'system:dict:type:get', '1', '1', '1', 1, 3, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (53, '', 'admin', '2021-03-09 17:19:46.963317', '2021-03-09 17:19:33.953559', '2', NULL, '参数查询', 0, '1', NULL, NULL, '/admin/system/config/', 'GET', 'system:config:get', '1', '1', '1', 1, 4, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (54, '', 'admin', '2021-03-09 17:20:14.749627', '2021-03-09 17:20:02.783389', '2', NULL, '文件查询', 0, '1', NULL, NULL, '/admin/system/savefile/', 'GET', 'system:savefile:get', '1', '1', '1', 1, 11, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (55, '', 'admin', '2021-03-09 17:20:44.604824', '2021-03-09 17:20:36.025364', '2', NULL, '公告查询', 0, '1', NULL, NULL, '/admin/system/message/', 'GET', 'system:message:get', '1', '1', '1', 1, 47, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (56, '', 'admin', '2021-03-09 17:21:06.429585', '2021-03-09 17:21:06.429629', '2', NULL, '岗位查询', 0, '1', NULL, NULL, '/admin/permission/post/', 'GET', 'permission:post:get', '1', '1', '1', 1, 5, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (57, '', 'admin', '2021-03-09 17:21:29.013165', '2021-03-09 17:21:29.013210', '2', NULL, '部门查询', 0, '1', NULL, NULL, '/admin/permission/dept/', 'GET', 'permission:dept:get', '1', '1', '1', 1, 6, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (58, '', 'admin', '2021-03-09 17:21:56.243957', '2021-03-09 17:21:47.358360', '2', NULL, '菜单查询', 0, '1', NULL, NULL, '/admin/permission/menus/', 'GET', 'permission:menus:get', '1', '1', '1', 1, 7, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (59, '', 'admin', '2021-03-09 17:22:20.140143', '2021-03-09 17:22:20.140189', '2', NULL, '角色查询', 0, '1', '', NULL, '/admin/permission/role/', 'GET', 'permission:role:get', '1', '1', '1', 1, 8, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (60, '', 'admin', '2021-03-09 17:22:38.595706', '2021-03-09 17:22:38.595751', '2', NULL, '用户查询', 0, '1', NULL, NULL, '/admin/permission/user/', 'GET', 'permission:user:get', '1', '1', '1', 1, 9, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (61, '', 'admin', '2021-03-21 11:34:17.635680', '2021-03-16 13:34:04.148728', '0', 'log', '日志管理', 5, '1', 'log', 'ParentView', NULL, 'GET', NULL, '1', '1', '1', 1, 1, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (62, '', 'admin', '2021-03-16 15:09:30.396752', '2021-03-16 13:36:00.114652', '1', 'logininfor', '登录日志', 1, '1', 'logininfor', 'vadmin/monitor/logininfor/index', '', 'GET', '', '1', '1', '1', 1, 61, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (63, '', 'admin', '2021-03-16 15:09:38.015636', '2021-03-16 14:28:10.395273', '1', 'log', '操作日志', 2, '1', 'operlog', 'vadmin/monitor/operlog/index', '', 'GET', '', '1', '1', '1', 1, 61, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (64, '', 'admin', '2021-03-16 14:31:27.618230', '2021-03-16 14:31:01.026470', '2', NULL, '登录日志查询', 1, '1', NULL, NULL, '/admin/system/logininfor/', 'GET', 'admin:system:logininfor:get', '1', '1', '1', 1, 62, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (65, '', 'admin', '2021-03-16 14:31:44.112525', '2021-03-16 14:31:44.112572', '2', NULL, '操作日志查询', 1, '1', NULL, NULL, '/admin/system/operlog/', 'GET', 'admin:system:operlog:get', '1', '1', '1', 1, 63, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (66, '', 'admin', '2021-03-26 00:47:50.628148', '2021-03-16 14:33:05.483003', '0', 'monitor', '系统监控', 3, '1', '/monitor', NULL, NULL, 'GET', NULL, '1', '1', '1', 1, NULL, '1');
-- INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (67, '', 'admin', '2021-03-16 14:49:59.260322', '2021-03-16 14:34:59.165065', '1', 'online', '在线用户', 1, '1', 'online', 'vadmin/monitor/online/index', '', 'GET', '', '1', '1', '1', 1, 66, '1');
-- INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (68, '', 'admin', '2021-03-16 14:36:00.989981', '2021-03-16 14:35:50.894454', '2', NULL, '在线用户查询', 1, '1', NULL, NULL, '/admin/monitor/online/', 'GET', 'admin:monitor:online:get', '1', '1', '1', 1, 67, '1');
-- INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (69, '', 'admin', '2021-03-16 14:37:10.577186', '2021-03-16 14:37:10.577231', '2', NULL, '用户强退', 2, '1', NULL, NULL, '/admin/monitor/online/{id}/', 'PUT', 'admin:monitor:online:{id}:put', '1', '1', '1', 1, 67, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (70, '', 'admin', '2021-03-26 00:49:56.410579', '2021-03-16 14:45:51.507961', '1', 'job', '定时任务', 2, '1', 'celery', 'vadmin/monitor/celery/index', '', 'GET', NULL, '1', '1', '1', 1, 66, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (71, '', 'admin', '2021-03-16 15:04:11.799260', '2021-03-16 14:59:53.619219', '2', NULL, '任务查询', 1, '1', NULL, NULL, '/admin/monitor/celery/', 'GET', 'admin:monitor:celery:get', '1', '1', '1', 1, 70, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (72, '', 'admin', '2021-03-16 15:04:06.645135', '2021-03-16 15:00:21.809600', '2', NULL, '任务新增', 2, '1', NULL, NULL, '/admin/monitor/celery/', 'POST', 'admin:monitor:celery:post', '1', '1', '1', 1, 70, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (73, '', 'admin', '2021-03-16 15:04:00.041701', '2021-03-16 15:00:45.994228', '2', NULL, '任务修改', 3, '1', NULL, NULL, '/admin/monitor/celery/{id}/', 'PUT', 'admin:monitor:celery:{id}:put', '1', '1', '1', 1, 70, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (74, '', 'admin', '2021-03-16 15:03:54.891216', '2021-03-16 15:01:19.624182', '2', NULL, '任务删除', 4, '1', NULL, NULL, '/admin/monitor/celery/{id}/', 'DELETE', 'admin:monitor:celery:{id}:delete', '1', '1', '1', 1, 70, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (75, '', 'admin', '2021-03-16 15:07:03.505007', '2021-03-16 15:03:35.796596', '2', NULL, '任务单次执行', 6, '1', NULL, NULL, '/admin/monitor/celery/run/', 'PUT', 'admin:monitor:celery:run:put', '1', '1', '1', 1, 70, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (76, '', 'admin', '2021-03-16 15:08:09.768588', '2021-03-16 15:07:45.064547', '2', NULL, '任务导出', 5, '1', NULL, NULL, '/admin/monitor/celery/export/', 'GET', 'admin:monitor:celery:export:get', '1', '1', '1', 1, 70, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (77, '', 'admin', '2021-03-16 15:09:09.928480', '2021-03-16 15:08:46.299829', '2', NULL, '登录日志导出', 2, '1', NULL, NULL, '/admin/system/logininfor/export/', 'GET', 'admin:system:logininfor:export:get', '1', '1', '1', 1, 62, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (78, '', 'admin', '2021-03-16 15:09:59.500271', '2021-03-16 15:09:59.500333', '2', NULL, '操作日志导出', 2, '1', NULL, NULL, '/admin/system/operlog/export/', 'GET', 'admin:system:operlog:export:get', '1', '1', '1', 1, 63, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (79, '', 'admin', '2021-03-26 00:27:17.614309', '2021-03-16 15:11:05.675729', '1', 'job', '定时日志', 3, '1', 'celerylog', 'vadmin/monitor/celery/celerylog/index', NULL, 'GET', NULL, '1', '1', '1', 1, 61, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (80, '', 'admin', '2021-03-16 15:16:29.349992', '2021-03-16 15:12:19.707979', '2', NULL, '定时日志查询', 1, '1', NULL, NULL, '/admin/monitor/celerylog/', 'GET', 'admin:monitor:celerylog:get', '1', '1', '1', 1, 79, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (81, '', 'admin', '2021-03-16 15:16:34.419420', '2021-03-16 15:12:51.090410', '2', NULL, '定时日志导出', 2, '1', NULL, NULL, '/admin/monitor/celerylog/export/', 'GET', 'admin:monitor:celerylog:export:get', '1', '1', '1', 1, 79, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (82, '', 'admin', '2021-03-26 00:47:37.970118', '2021-03-16 15:15:21.397186', '0', 'tool', '系统工具', 4, '1', '/tool', NULL, NULL, 'GET', NULL, '1', '1', '1', 1, NULL, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (83, '', 'admin', '2021-03-26 00:50:12.345672', '2021-03-16 15:16:10.318426', '1', 'build', '表单构建', 1, '1', 'build', 'vadmin/tool/build/index', NULL, 'GET', NULL, '1', '1', '1', 1, 82, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (84, '', 'admin', '2021-03-16 15:19:24.228395', '2021-03-16 15:17:23.507732', '1', 'swagger', '系统接口', 2, '1', 'swagger', 'vadmin/tool/swagger/index', '/admin/docs/', 'GET', 'admin:docs:get', '1', '1', '1', 1, 82, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (85, '', 'admin', '2021-03-21 11:37:06.119591', '2021-03-21 11:37:06.119623', '2', NULL, '操作日志批量删除', 3, '1', NULL, NULL, '/admin/system/operation_log/{id}/', 'DELETE', 'admin:system:operation_log:{id}:delete', '1', '1', '1', 1, 63, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (86, '', 'admin', '2021-03-21 11:39:07.579469', '2021-03-21 11:39:07.579517', '2', NULL, '操作日志清空', 4, '1', NULL, NULL, '/admin/system/operation_log/clean/', 'DELETE', 'admin:system:operation_log:clean:delete', '1', '1', '1', 1, 63, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (87, '', 'admin', '2021-03-21 23:32:44.308857', '2021-03-21 23:32:44.308882', '2', NULL, '登录日志批量删除', 3, '1', NULL, NULL, '/admin/system/logininfor/{id}/', 'DELETE', 'admin:system:logininfor:{id}:delete', '1', '1', '1', 1, 62, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (88, '', 'admin', '2021-03-21 23:33:30.888568', '2021-03-21 23:33:30.888593', '2', NULL, '登录日志清空', 4, '1', NULL, NULL, '/admin/system/logininfor/clean/', 'DELETE', 'admin:system:logininfor:clean:delete', '1', '1', '1', 1, 62, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (90, '', 'admin', '2021-03-26 00:44:00.756139', '2021-03-26 00:43:14.390228', '2', NULL, '定时日志批量删除', 3, '1', NULL, NULL, '/admin/system/celery_log/{id}/', 'DELETE', 'admin:system:celery_log:{id}:delete', '1', '1', '1', 1, 79, '8');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (91, '', 'admin', '2021-03-26 00:44:36.135658', '2021-03-26 00:44:36.135679', '2', NULL, '定时日志清空', 4, '1', NULL, NULL, '/admin/system/celery_log/clean/', 'DELETE', 'admin:system:celery_log:clean:delete', '1', '1', '1', 1, 79, '8');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (92, '', 'admin', '2021-04-27 23:49:59.036636', '2021-04-27 23:44:54.512207', '1', 'server', '服务监控', 3, '1', '/monitor/server', 'vadmin/monitor/server/index', NULL, 'GET', NULL, '1', '1', '1', 1, 66, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (93, '', 'admin', '2021-04-27 23:57:46.633022', '2021-04-27 23:49:28.569029', '2', NULL, '服务监控查询', 1, '1', NULL, NULL, '/admin/monitor/server/', 'GET', 'admin:monitor:server:get', '1', '1', '1', 1, 92, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (94, '', 'admin', '2021-04-27 23:58:44.705142', '2021-04-27 23:58:13.384483', '2', NULL, '修改服务器信息', 2, '1', NULL, NULL, '/admin/monitor/server/{id}/', 'PUT', 'admin:monitor:server:{id}:put', '1', '1', '1', 1, 92, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (95, '', 'admin', '2021-04-27 23:59:29.530633', '2021-04-27 23:59:07.744938', '2', NULL, '修改监控信息', 3, '1', NULL, NULL, '/admin/monitor/monitor/enabled/', 'GET', 'admin:monitor:monitor:enabled:get', '1', '1', '1', 1, 92, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (96, '', 'admin', '2021-04-28 00:01:15.071889', '2021-04-27 23:59:48.612905', '2', NULL, '清空监控记录', 4, '1', NULL, NULL, '/admin/monitor/monitor/clean/', 'GET', 'admin:monitor:monitor:clean:get', '1', '1', '1', 1, 92, '1');
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (97, '', 'admin', '2021-05-02 19:12:06.813143', '2021-05-02 18:58:06.260280', '0', 'dashboard', '首页', 0, '1', '/index', 'Layout/index', NULL, 'GET', NULL, '1', '1', '1', 1, NULL, '1');

View File

@ -1,27 +0,0 @@
-- ----------------------------
-- 岗位管理初始化sql
-- Table structure for permission_post
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_post`;
-- CREATE TABLE `permission_post` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `description` longtext,
-- `creator` varchar(255) DEFAULT NULL,
-- `modifier` varchar(255) DEFAULT NULL,
-- `update_datetime` datetime(6) DEFAULT NULL,
-- `create_datetime` datetime(6) DEFAULT NULL,
-- `postName` varchar(64) NOT NULL,
-- `postCode` varchar(32) NOT NULL,
-- `postSort` int(11) NOT NULL,
-- `status` varchar(8) NOT NULL,
-- `remark` longtext,
-- PRIMARY KEY (`id`)
-- ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_post
-- ----------------------------
INSERT INTO `permission_post` (id, description, modifier, update_datetime, create_datetime, postName, postCode, postSort, status, remark, creator_id, dept_belong_id) VALUES (1, '', 'admin', '2021-02-27 07:16:10.725970', '2021-02-27 07:16:10.726016', '董事长', 'ceo', 1, '1', NULL, 1, 1);
INSERT INTO `permission_post` (id, description, modifier, update_datetime, create_datetime, postName, postCode, postSort, status, remark, creator_id, dept_belong_id) VALUES (2, '', 'admin', '2021-02-27 07:16:28.139648', '2021-02-27 07:16:28.139689', '项目经理', 'ce', 2, '1', NULL, 1, 1);
INSERT INTO `permission_post` (id, description, modifier, update_datetime, create_datetime, postName, postCode, postSort, status, remark, creator_id, dept_belong_id) VALUES (3, '', 'admin', '2021-02-27 07:16:39.843069', '2021-02-27 07:16:39.843114', '人力资源', 'hr', 3, '1', NULL, 1, 1);
INSERT INTO `permission_post` (id, description, modifier, update_datetime, create_datetime, postName, postCode, postSort, status, remark, creator_id, dept_belong_id) VALUES (4, '', 'admin', '2021-02-27 07:16:51.082769', '2021-02-27 07:16:51.082813', '普通员工', 'user', 4, '1', NULL, 1, 1);

View File

@ -1,192 +0,0 @@
-- ----------------------------
-- 角色管理 初始化
-- Table structure for permission_role
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_role`;
-- CREATE TABLE `permission_role` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `description` longtext,
-- `creator` varchar(255) DEFAULT NULL,
-- `modifier` varchar(255) DEFAULT NULL,
-- `update_datetime` datetime(6) DEFAULT NULL,
-- `create_datetime` datetime(6) DEFAULT NULL,
-- `roleName` varchar(64) NOT NULL,
-- `roleKey` varchar(64) NOT NULL,
-- `roleSort` int(11) NOT NULL,
-- `status` varchar(8) NOT NULL,
-- `admin` tinyint(1) NOT NULL,
-- `dataScope` varchar(8) NOT NULL,
-- `remark` longtext,
-- PRIMARY KEY (`id`)
-- ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_role
-- ----------------------------
INSERT INTO `permission_role` (id, description, modifier, update_datetime, create_datetime, roleName, roleKey, roleSort, status, admin, dataScope, remark, creator_id, dept_belong_id) VALUES (1, '', 'admin', '2021-02-27 08:48:23.225361', '2021-02-27 08:48:08.064911', '超级管理员', 'admin', 1, '1', 1, '2', NULL, 1, 1);
INSERT INTO `permission_role` (id, description, modifier, update_datetime, create_datetime, roleName, roleKey, roleSort, status, admin, dataScope, remark, creator_id, dept_belong_id) VALUES (2, '', 'admin', '2021-02-27 08:49:05.149632', '2021-02-27 08:48:47.317214', '普通角色', 'common', 2, '1', 0, '2', NULL, 1, 1);
-- ----------------------------
-- Table structure for permission_role_dept
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_role_dept`;
-- CREATE TABLE `permission_role_dept` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `role_id` int(11) NOT NULL,
-- `dept_id` int(11) NOT NULL,
-- PRIMARY KEY (`id`),
-- UNIQUE KEY `permission_role_dept_role_id_dept_id_1d89afeb_uniq` (`role_id`,`dept_id`),
-- KEY `permission_role_dept_role_id_99a9f232` (`role_id`) USING BTREE,
-- KEY `permission_role_dept_dept_id_cbe9076a` (`dept_id`) USING BTREE
-- ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_role_dept
-- ----------------------------
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (1, 1, 1);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (2, 1, 2);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (3, 1, 3);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (4, 1, 4);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (5, 1, 5);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (6, 1, 6);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (7, 1, 7);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (8, 1, 8);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (9, 1, 9);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (10, 1, 10);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (11, 1, 11);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (12, 1, 12);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (13, 1, 13);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (14, 1, 14);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (15, 1, 15);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (16, 1, 16);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (17, 2, 1);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (18, 2, 2);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (19, 2, 3);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (20, 2, 4);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (21, 2, 5);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (22, 2, 6);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (23, 2, 7);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (24, 2, 8);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (25, 2, 9);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (26, 2, 10);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (27, 2, 11);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (28, 2, 12);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (29, 2, 13);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (30, 2, 14);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (31, 2, 15);
INSERT INTO `permission_role_dept` (id, role_id, dept_id) VALUES (32, 2, 16);
-- ----------------------------
-- Table structure for permission_role_menu
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_role_menu`;
-- CREATE TABLE `permission_role_menu` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `role_id` int(11) NOT NULL,
-- `menu_id` int(11) NOT NULL,
-- PRIMARY KEY (`id`),
-- UNIQUE KEY `permission_role_menu_role_id_menu_id_bb9e5441_uniq` (`role_id`,`menu_id`),
-- KEY `permission_role_menu_role_id_33541d2b` (`role_id`) USING BTREE,
-- KEY `permission_role_menu_menu_id_0c24555f` (`menu_id`) USING BTREE
-- ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_role_menu
-- ----------------------------
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (1, 1, 1);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (2, 1, 2);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (3, 1, 3);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (4, 1, 4);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (5, 1, 5);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (6, 1, 6);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (7, 1, 7);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (8, 1, 8);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (9, 1, 9);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (10, 1, 10);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (11, 2, 1);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (12, 2, 2);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (13, 2, 3);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (14, 2, 4);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (15, 2, 5);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (16, 2, 6);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (17, 2, 7);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (18, 2, 8);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (19, 2, 9);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (20, 2, 10);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (21, 1, 11);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (22, 1, 13);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (23, 1, 14);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (24, 1, 15);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (25, 1, 16);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (26, 1, 17);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (27, 1, 18);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (28, 1, 19);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (29, 1, 20);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (30, 1, 21);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (31, 1, 22);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (32, 1, 23);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (33, 1, 24);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (34, 1, 25);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (35, 1, 26);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (36, 1, 27);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (37, 1, 28);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (38, 1, 29);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (39, 1, 30);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (40, 1, 31);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (41, 1, 32);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (42, 1, 33);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (43, 1, 34);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (44, 1, 35);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (45, 1, 36);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (46, 1, 37);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (47, 1, 38);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (48, 1, 39);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (49, 1, 40);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (50, 1, 41);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (51, 1, 42);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (52, 1, 43);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (53, 1, 44);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (54, 1, 45);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (55, 1, 46);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (56, 1, 47);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (57, 1, 48);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (58, 1, 49);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (59, 1, 50);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (60, 1, 51);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (61, 1, 52);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (62, 1, 53);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (63, 1, 54);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (64, 1, 55);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (65, 1, 56);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (66, 1, 57);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (67, 1, 58);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (68, 1, 59);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (69, 1, 60);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (74, 1, 61);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (75, 1, 62);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (76, 1, 63);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (70, 1, 64);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (71, 1, 65);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (79, 1, 66);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (80, 1, 70);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (81, 1, 71);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (82, 1, 72);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (83, 1, 73);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (84, 1, 74);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (85, 1, 75);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (86, 1, 76);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (72, 1, 77);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (73, 1, 78);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (92, 1, 79);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (93, 1, 80);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (94, 1, 81);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (88, 1, 82);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (89, 1, 83);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (77, 1, 85);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (78, 1, 86);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (95, 1, 87);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (96, 1, 88);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (97, 1, 90);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (98, 1, 91);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (99, 2, 97);
INSERT INTO `permission_role_menu` (id, role_id, menu_id) VALUES (100, 1, 97);

View File

@ -1,76 +0,0 @@
-- ----------------------------
-- 用户管理 初始化sql
-- Table structure for permission_userprofile
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_userprofile`;
-- CREATE TABLE `permission_userprofile` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `password` varchar(128) NOT NULL,
-- `last_login` datetime(6) DEFAULT NULL,
-- `is_superuser` tinyint(1) NOT NULL,
-- `first_name` varchar(30) NOT NULL,
-- `last_name` varchar(150) NOT NULL,
-- `is_staff` tinyint(1) NOT NULL,
-- `is_active` tinyint(1) NOT NULL,
-- `date_joined` datetime(6) NOT NULL,
-- `username` varchar(150) NOT NULL,
-- `secret` varchar(255) NOT NULL,
-- `email` varchar(255) DEFAULT NULL,
-- `mobile` varchar(255) DEFAULT NULL,
-- `avatar` longtext,
-- `name` varchar(40) NOT NULL,
-- `gender` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
-- `remark` longtext,
-- `user_type` int(11) NOT NULL,
-- `create_datetime` datetime(6) DEFAULT NULL,
-- `update_datetime` datetime(6) DEFAULT NULL,
-- `dept_id` int(11) DEFAULT NULL,
-- PRIMARY KEY (`id`),
-- UNIQUE KEY `username` (`username`),
-- KEY `permission_userprofile_dept_id_bd5c7976` (`dept_id`) USING BTREE
-- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_userprofile
-- ----------------------------
INSERT INTO `permission_userprofile` (id, password, last_login, is_superuser, first_name, last_name, is_staff, is_active, date_joined, username, secret, email, mobile, avatar, name, gender, remark, user_type, create_datetime, update_datetime, dept_id, dept_belong_id, creator_id) VALUES (1, 'pbkdf2_sha256$150000$X0RG2idBumnn$TaMaXFquGzyDtytL3ofZG/sSN+1VR521A9xLkUPxYI4=', '2021-02-27 06:20:28.214775', 1, '', '', 1, 1, '2021-02-27 06:20:09.188689', 'admin', '3704adf3-380f-4c27-a8da-60420e8cb4ab', 'admin@qq.com', NULL, NULL, '管理员', '2', '1', 2, '2021-02-27 06:20:09.263192', '2021-02-27 09:14:30.009998', 1, 1, 1);
INSERT INTO `permission_userprofile` (id, password, last_login, is_superuser, first_name, last_name, is_staff, is_active, date_joined, username, secret, email, mobile, avatar, name, gender, remark, user_type, create_datetime, update_datetime, dept_id, dept_belong_id, creator_id) VALUES (2, 'pbkdf2_sha256$150000$vWY1VIn7rEJz$qq2iiADgcGumy9kNU1FSBhktcimaudYICviCcOKzfKY=', NULL, 0, '', '', 0, 1, '2021-03-03 15:38:27.009893', 'dvadmin', 'b4c5d79a-f01c-4244-92f8-b5288eca1d50', NULL, NULL, NULL, '普通用户', '2', NULL, 0, '2021-03-03 15:38:27.010771', '2021-03-03 15:38:27.086069', 1, 1, 1);
-- ----------------------------
-- Table structure for permission_userprofile_post
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_userprofile_post`;
-- CREATE TABLE `permission_userprofile_post` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `userprofile_id` int(11) NOT NULL,
-- `post_id` int(11) NOT NULL,
-- PRIMARY KEY (`id`),
-- UNIQUE KEY `permission_userprofile_post_userprofile_id_post_id_b9fb91e9_uniq` (`userprofile_id`,`post_id`),
-- KEY `permission_userprofile_post_userprofile_id_229fe756` (`userprofile_id`) USING BTREE,
-- KEY `permission_userprofile_post_post_id_dda441c3` (`post_id`) USING BTREE
-- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_userprofile_post
-- ----------------------------
INSERT INTO `permission_userprofile_post` (id, userprofile_id, post_id) VALUES (1, 1, 1);
INSERT INTO `permission_userprofile_post` (id, userprofile_id, post_id) VALUES (2, 2, 4);
-- ----------------------------
-- Table structure for permission_userprofile_role
-- ----------------------------
-- DROP TABLE IF EXISTS `permission_userprofile_role`;
-- CREATE TABLE `permission_userprofile_role` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `userprofile_id` int(11) NOT NULL,
-- `role_id` int(11) NOT NULL,
-- PRIMARY KEY (`id`),
-- UNIQUE KEY `permission_userprofile_role_userprofile_id_role_id_70affc5e_uniq` (`userprofile_id`,`role_id`),
-- KEY `permission_userprofile_role_userprofile_id_66835002` (`userprofile_id`) USING BTREE,
-- KEY `permission_userprofile_role_role_id_e91fd02e` (`role_id`) USING BTREE
-- ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of permission_userprofile_role
-- ----------------------------
INSERT INTO `permission_userprofile_role` (id, userprofile_id, role_id) VALUES (1, 1, 1);
INSERT INTO `permission_userprofile_role` (id, userprofile_id, role_id) VALUES (2, 2, 2);

View File

@ -1,27 +0,0 @@
-- ----------------------------
-- 参数设置 初始化sql
-- Table structure for system_configsettings
-- ----------------------------
-- DROP TABLE IF EXISTS `system_configsettings`;
-- CREATE TABLE `system_configsettings` (
-- `id` int(11) NOT NULL AUTO_INCREMENT,
-- `description` longtext,
-- `creator` varchar(255) DEFAULT NULL,
-- `modifier` varchar(255) DEFAULT NULL,
-- `update_datetime` datetime(6) DEFAULT NULL,
-- `create_datetime` datetime(6) DEFAULT NULL,
-- `configName` varchar(64) NOT NULL,
-- `configKey` varchar(256) NOT NULL,
-- `configValue` varchar(256) NOT NULL,
-- `configType` varchar(8) NOT NULL,
-- `status` varchar(8) NOT NULL,
-- `remark` varchar(256) DEFAULT NULL,
-- PRIMARY KEY (`id`)
-- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of system_configsettings
-- ----------------------------
INSERT INTO `system_configsettings` (id, description, modifier, update_datetime, create_datetime, configName, configKey, configValue, configType, status, remark, creator_id, dept_belong_id) VALUES (1, '', 'admin', '2021-02-27 07:14:48.935587', '2021-02-27 07:14:48.935634', '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', '1', '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow', 1, 1);
INSERT INTO `system_configsettings` (id, description, modifier, update_datetime, create_datetime, configName, configKey, configValue, configType, status, remark, creator_id, dept_belong_id) VALUES (2, '', 'admin', '2021-02-27 07:15:14.039924', '2021-02-27 07:15:14.039967', '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', '1', '初始化密码 123456', 1, 1);
INSERT INTO `system_configsettings` (id, description, modifier, update_datetime, create_datetime, configName, configKey, configValue, configType, status, remark, creator_id, dept_belong_id) VALUES (3, '', 'admin', '2021-02-27 07:15:36.091655', '2021-02-27 07:15:36.091694', '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', '1', '深色主题theme-dark浅色主题theme-light', 1, 1);

Some files were not shown because too many files have changed in this diff Show More