From 0c3a73b6474ac35a0b6e6a8ff1e16dad3cfa892c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Mon, 29 Mar 2021 01:54:41 +0800 Subject: [PATCH 1/2] =?UTF-8?q?!4=20system=E6=B6=88=E6=81=AF=E9=80=9A?= =?UTF-8?q?=E7=9F=A5:=E4=BF=AE=E5=A4=8D=E5=B7=B2=E8=AF=BB=E6=B6=88?= =?UTF-8?q?=E6=81=AFbug;permission:=E6=8E=A5=E5=8F=A3=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=AE=8C=E6=88=90=20*=20system=E6=B6=88=E6=81=AF=E9=80=9A?= =?UTF-8?q?=E7=9F=A5:=E4=BF=AE=E5=A4=8D=E5=B7=B2=E8=AF=BB=E6=B6=88?= =?UTF-8?q?=E6=81=AFbug;permission:=E6=8E=A5=E5=8F=A3=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E3=80=82=20*=20system=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E9=80=9A=E7=9F=A5:=E4=BF=AE=E5=A4=8D=E5=B7=B2=E8=AF=BB?= =?UTF-8?q?=E6=B6=88=E6=81=AFbug=20*=20docker=5Fenv:=E5=88=A0=E9=99=A4dock?= =?UTF-8?q?er=E4=B8=AD=E7=9A=84nginx=E3=80=81dvadmin-doc;=E6=9D=83?= =?UTF-8?q?=E9=99=90=E7=AE=A1=E7=90=86:=E5=AF=B9=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5=E7=9A=84=E6=9D=83?= =?UTF-8?q?=E9=99=90=E6=8E=A7=E5=88=B6=20*=20=E5=88=A0=E9=99=A4mongodb?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20Merge=20branch=20'dvadmin-dev'=20of=20?= =?UTF-8?q?https://gitee.com/liqianglog/django-vue-admin=20*=20-=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=AE=A1=E7=90=86=E2=80=94=E2=80=94=E6=B8=85=E7=90=86?= =?UTF-8?q?=E5=BA=9F=E5=BC=83=E6=96=87=E4=BB=B6=E5=8A=9F=E8=83=BD=20*=20-?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=AE=A1=E7=90=86=E2=80=94=E2=80=94=E6=B8=85?= =?UTF-8?q?=E7=90=86=E5=BA=9F=E5=BC=83=E6=96=87=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +- docker-compose.yml | 48 -- docker_env/nginx/Dockerfile | 6 - .../nginx/keys/api.django-vue-admin.com.crt | 61 --- .../nginx/keys/api.django-vue-admin.com.key | 27 - .../keys/daily.api.django-vue-admin.com.crt | 61 --- .../keys/daily.api.django-vue-admin.com.key | 27 - .../keys/daily.demo.django-vue-admin.com.crt | 61 --- .../keys/daily.demo.django-vue-admin.com.key | 27 - .../nginx/keys/demo.django-vue-admin.com.crt | 61 --- .../nginx/keys/demo.django-vue-admin.com.key | 27 - .../nginx/keys/www.django-vue-admin.com.crt | 61 --- .../nginx/keys/www.django-vue-admin.com.key | 27 - docker_env/nginx/nginx.conf | 15 - docker_env/nginx/sites-enabled/api.conf | 46 -- docker_env/nginx/sites-enabled/daily.api.conf | 46 -- .../nginx/sites-enabled/daily.demo.conf | 44 -- docker_env/nginx/sites-enabled/demo.conf | 44 -- docker_env/nginx/sites-enabled/root.conf | 37 -- docker_env/nginx/sites-enabled/www.conf | 37 -- docker_env/vue-doc/Dockerfile | 5 - dvadmin-backend/application/settings.py | 34 +- dvadmin-backend/application/urls.py | 2 +- dvadmin-backend/apps/vadmin/op_drf/filters.py | 12 +- .../apps/vadmin/op_drf/middleware.py | 83 +++- dvadmin-backend/apps/vadmin/op_drf/mixins.py | 10 +- .../apps/vadmin/op_drf/serializers.py | 1 + .../apps/vadmin/permission/models/menu.py | 28 +- .../apps/vadmin/permission/models/users.py | 24 + .../apps/vadmin/permission/permissions.py | 95 ++++ .../apps/vadmin/permission/serializers.py | 10 +- .../apps/vadmin/permission/views.py | 65 +-- dvadmin-backend/apps/vadmin/system/filters.py | 1 + .../apps/vadmin/system/models/__init__.py | 1 - .../apps/vadmin/system/models/save_file.py | 1 + .../apps/vadmin/system/models/web_set.py | 19 - .../apps/vadmin/system/serializers.py | 18 +- dvadmin-backend/apps/vadmin/system/urls.py | 7 + dvadmin-backend/apps/vadmin/system/views.py | 155 ++++-- dvadmin-backend/apps/vadmin/urls.py | 2 +- .../apps/vadmin/utils/export_excel.py | 2 + .../apps/vadmin/utils/file_util.py | 48 ++ .../apps/vadmin/utils/request_util.py | 26 +- dvadmin-backend/apps/vadmin/utils/response.py | 35 +- dvadmin-backend/conf/env.example.py | 11 +- dvadmin-backend/requirements.txt | 1 + dvadmin-doc/docs/.vuepress/config.js | 47 -- dvadmin-doc/docs/.vuepress/public/logo.jpg | Bin 175155 -> 0 bytes dvadmin-doc/docs/.vuepress/public/logo.png | Bin 75745 -> 0 bytes dvadmin-doc/docs/README.md | 22 - dvadmin-doc/docs/about/README.md | 1 - dvadmin-doc/docs/document/README.md | 1 - dvadmin-doc/docs/document/gxrz.md | 1 - dvadmin-doc/docs/document/hjbs.md | 98 ---- dvadmin-doc/docs/document/kslj.md | 1 - dvadmin-doc/docs/document/server.md | 1 - dvadmin-doc/docs/document/web.md | 29 -- dvadmin-doc/docs/other/cjwt.md | 1 - dvadmin-doc/docs/other/jzzc.md | 1 - dvadmin-doc/package.json | 15 - dvadmin-ui/package.json | 4 +- dvadmin-ui/src/api/vadmin/permission/dept.js | 4 +- dvadmin-ui/src/api/vadmin/permission/menu.js | 4 +- dvadmin-ui/src/api/vadmin/system/config.js | 2 +- dvadmin-ui/src/api/vadmin/system/dict/data.js | 2 +- .../components/CommonStaticTable/index.vue | 465 ------------------ .../src/components/FileUpload/index.vue | 12 +- dvadmin-ui/src/main.js | 2 + dvadmin-ui/src/utils/ruoyi.js | 14 + .../views/vadmin/permission/dept/index.vue | 2 +- .../views/vadmin/permission/menu/index.vue | 8 +- .../views/vadmin/permission/post/index.vue | 2 +- .../views/vadmin/permission/role/index.vue | 2 +- .../views/vadmin/permission/user/index.vue | 2 +- .../src/views/vadmin/system/config/index.vue | 4 +- .../src/views/vadmin/system/dict/data.vue | 22 +- .../src/views/vadmin/system/dict/index.vue | 2 +- .../src/views/vadmin/system/message/index.vue | 8 +- .../src/views/vadmin/system/notice/index.vue | 4 +- .../views/vadmin/system/savefile/index.vue | 46 +- 80 files changed, 629 insertions(+), 1674 deletions(-) delete mode 100644 docker_env/nginx/Dockerfile delete mode 100644 docker_env/nginx/keys/api.django-vue-admin.com.crt delete mode 100644 docker_env/nginx/keys/api.django-vue-admin.com.key delete mode 100755 docker_env/nginx/keys/daily.api.django-vue-admin.com.crt delete mode 100755 docker_env/nginx/keys/daily.api.django-vue-admin.com.key delete mode 100755 docker_env/nginx/keys/daily.demo.django-vue-admin.com.crt delete mode 100755 docker_env/nginx/keys/daily.demo.django-vue-admin.com.key delete mode 100755 docker_env/nginx/keys/demo.django-vue-admin.com.crt delete mode 100755 docker_env/nginx/keys/demo.django-vue-admin.com.key delete mode 100644 docker_env/nginx/keys/www.django-vue-admin.com.crt delete mode 100644 docker_env/nginx/keys/www.django-vue-admin.com.key delete mode 100644 docker_env/nginx/nginx.conf delete mode 100644 docker_env/nginx/sites-enabled/api.conf delete mode 100644 docker_env/nginx/sites-enabled/daily.api.conf delete mode 100644 docker_env/nginx/sites-enabled/daily.demo.conf delete mode 100644 docker_env/nginx/sites-enabled/demo.conf delete mode 100644 docker_env/nginx/sites-enabled/root.conf delete mode 100644 docker_env/nginx/sites-enabled/www.conf delete mode 100644 docker_env/vue-doc/Dockerfile create mode 100644 dvadmin-backend/apps/vadmin/permission/permissions.py delete mode 100644 dvadmin-backend/apps/vadmin/system/models/web_set.py create mode 100644 dvadmin-backend/apps/vadmin/utils/file_util.py delete mode 100644 dvadmin-doc/docs/.vuepress/config.js delete mode 100644 dvadmin-doc/docs/.vuepress/public/logo.jpg delete mode 100644 dvadmin-doc/docs/.vuepress/public/logo.png delete mode 100644 dvadmin-doc/docs/README.md delete mode 100644 dvadmin-doc/docs/about/README.md delete mode 100644 dvadmin-doc/docs/document/README.md delete mode 100644 dvadmin-doc/docs/document/gxrz.md delete mode 100644 dvadmin-doc/docs/document/hjbs.md delete mode 100644 dvadmin-doc/docs/document/kslj.md delete mode 100644 dvadmin-doc/docs/document/server.md delete mode 100644 dvadmin-doc/docs/document/web.md delete mode 100644 dvadmin-doc/docs/other/cjwt.md delete mode 100644 dvadmin-doc/docs/other/jzzc.md delete mode 100644 dvadmin-doc/package.json delete mode 100644 dvadmin-ui/src/components/CommonStaticTable/index.vue diff --git a/README.md b/README.md index a678795..ea9949d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 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/pypi/v/django-simpleui.svg)](https://pypi.org/project/django-simpleui/#history) [![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)[![img](https://img.shields.io/badge/node-%3E%3D%2012.0.0-brightgreen)](https://nodejs.org/zh-cn/download/releases/)[![img](https://img.shields.io/pypi/dm/django-simpleui.svg)](https://pypi.org/project/django-simpleui/) +[![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/pypi/v/django-simpleui.svg)](https://pypi.org/project/django-simpleui/#history) [![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)![img](https://img.shields.io/badge/node-%3E%3D%2012.0.0-brightgreen) @@ -68,9 +68,6 @@ git clone https://gitee.com/liqianglog/django-vue-admin.git cd dvadmin-ui # 安装依赖 -npm install - -# 建议不要直接使用cnpm安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题。 npm install --registry=https://registry.npm.taobao.org # 启动服务 @@ -95,7 +92,12 @@ npm run build:prod ~~~bash 1. 进入项目目录 cd dvadmin-backend 2. 在项目根目录中,复制 ./conf/env.example.py 文件为一份新的到 ./conf 文件夹下,并重命名为 env.py + 3. 在 env.py 中配置数据库信息 + mysql数据库版本建议:5.7以上 + mysql数据库字符集:utf8mb4 + mysql数据库排序规则:utf8mb4_0900_ai_ci + 4. 安装依赖环境 pip3 install -r requirements.txt 5. 执行迁移命令: @@ -104,10 +106,13 @@ npm run build:prod 6. 初始化数据 python3 manage.py init 7. 启动项目 - python3 manage.py runserver 0.0.0.0:8000 + 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 diff --git a/docker-compose.yml b/docker-compose.yml index 7cb5dd6..2df19eb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,25 +25,6 @@ services: npm run build:prod - dvadmin-doc: - container_name: dvadmin-doc - build: - context: ./ - dockerfile: ./docker_env/vue-doc/Dockerfile - environment: - TZ: Asia/Shanghai - volumes: - - "./dvadmin-doc:/dvadmin-doc" - command: - - /bin/bash - - -c - - | - cd /dvadmin-doc - npm install --registry=https://registry.npm.taobao.org - rm -rf /dvadmin-doc/dist - npm run docs:build - - dvadmin-redis: image: redis:latest container_name: dvadmin-redis @@ -134,32 +115,3 @@ services: restart: always networks: - dvadmin_net - - - dvadmin-nginx: - image: nginx:latest - container_name: dvadmin-nginx - # build: ./docker_env/nginx - restart: always - ports: - - "80:80" - - "443:443" - expose: - - "80" - - "443" - volumes: - - ./docker_env/nginx/nginx.conf:/etc/nginx/nginx.conf - - ./docker_env/nginx/sites-enabled:/etc/nginx/sites-enabled - - ./docker_env/nginx/keys:/nginx/keys - - ./dvadmin-backend:/dvadmin-backend - - ./dvadmin-doc:/dvadmin-doc - - ./dvadmin-ui:/dvadmin-ui - - ./logs/nginx:/var/log/nginx - depends_on: - - dvadmin-django - networks: - - dvadmin_net - -networks: - dvadmin_net: - driver: bridge diff --git a/docker_env/nginx/Dockerfile b/docker_env/nginx/Dockerfile deleted file mode 100644 index c5159e8..0000000 --- a/docker_env/nginx/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM nginx:latest - -COPY nginx.conf /etc/nginx/nginx.conf - -CMD ["nginx", "-g", "daemon off;"] - diff --git a/docker_env/nginx/keys/api.django-vue-admin.com.crt b/docker_env/nginx/keys/api.django-vue-admin.com.crt deleted file mode 100644 index 3964184..0000000 --- a/docker_env/nginx/keys/api.django-vue-admin.com.crt +++ /dev/null @@ -1,61 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFoTCCBImgAwIBAgIQA4TN09XlucVnL4BLCuvHijANBgkqhkiG9w0BAQsFADBy -MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg -SW5jLjEdMBsGA1UECxMURG9tYWluIFZhbGlkYXRlZCBTU0wxHTAbBgNVBAMTFFRy -dXN0QXNpYSBUTFMgUlNBIENBMB4XDTIxMDMwMzAwMDAwMFoXDTIyMDMwMjIzNTk1 -OVowIzEhMB8GA1UEAxMYYXBpLmRqYW5nby12dWUtYWRtaW4uY29tMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5QSBTQbToLUu4wCYy/BNoinqFkXiTZE -aV6/5PJIeNsz75fnAEuBpIATEHqRsY6L9HdYAvBiAEv6ufCZhzwWF7ph1ZMhg6ul -foaQwoVCkbKi/zgwi3tvteda5vXQs4e8GvgZ6zkabQ4cZFjVpb3dA6huBbs20jLf -YYXsXWsJEGF3JK5okQ08+u/h/q0lFDFa70S9hpQXMtSfCCW/AuEc/+tG7rnUul1o -MXjpVnDOmg+CZfIYgi9D30/zd1DYFJOEwawl5FKLFQY7TOn3RlZ3SR4mNbbhIgHP -L9S1xHGcm8UC7PKuOgh8+5Nl0aeeUB1liuzM/w5JbF4L4FoZW6ciNQIDAQABo4IC -gDCCAnwwHwYDVR0jBBgwFoAUf9OZ86BHDjEAVlYijrfMnt3KAYowHQYDVR0OBBYE -FHvXBhsuPta7SwvCVVgv9e/bZ9AeMCMGA1UdEQQcMBqCGGFwaS5kamFuZ28tdnVl -LWFkbWluLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG -CCsGAQUFBwMCMD4GA1UdIAQ3MDUwMwYGZ4EMAQIBMCkwJwYIKwYBBQUHAgEWG2h0 -dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBkgYIKwYBBQUHAQEEgYUwgYIwNAYI -KwYBBQUHMAGGKGh0dHA6Ly9zdGF0dXNlLmRpZ2l0YWxjZXJ0dmFsaWRhdGlvbi5j -b20wSgYIKwYBBQUHMAKGPmh0dHA6Ly9jYWNlcnRzLmRpZ2l0YWxjZXJ0dmFsaWRh -dGlvbi5jb20vVHJ1c3RBc2lhVExTUlNBQ0EuY3J0MAkGA1UdEwQCMAAwggEEBgor -BgEEAdZ5AgQCBIH1BIHyAPAAdgApeb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZc -JV3HhAAAAXf48Te1AAAEAwBHMEUCIDjqPKTNX4EcFxayaLirTT1y98X9X1HP97bM -IV0HpJmYAiEAjMdYYUqFuHLkSl4/bq5F/FPtt25AbKGhyolIVDWvsNoAdgAiRUUH -WVUkVpY/oS/x922G4CMmY63AS39dxoNcbuIPAgAAAXf48TgFAAAEAwBHMEUCIBQM -bXvVtAOXQfBjp+7HzsyWH51BZ2vyH1VyLpuGSs7dAiEAiyt4h7P7oRheoZKmn8wp -CptaYocY509Dr8aFbCicWWAwDQYJKoZIhvcNAQELBQADggEBAJG3Ne57IlaucGjH -y6j/zJsRnCsIrVNoPUROma+2FD7SauHT6U7iDLtNT5BIrBmDcEnYdqMAjJQoRJC1 -VvXSkABEngUajpdpB0m8k9UVB5W+6Extt8TYyRLu1/Xpq0JHiOg+rPYK3UljYybG -2V9KWNhYd2G5yg0+1ZzvaC3zEFIfQJpuESio6hEbilT6FLeVC8TabL0/2tqE12n/ -uWYU3Pr9AokD0OQkzN4BUswwIpYBfAXa6HLvj+V6tLOthxY0PLuOm7WiwU2MP0bz -dq6LIFu0z8fkwBkkqXXtgSfCigqvRhybaKKF0FT4cdJUb0cfMhUshlzWpJ5EEskO -46xDUok= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIErjCCA5agAwIBAgIQBYAmfwbylVM0jhwYWl7uLjANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xNzEyMDgxMjI4MjZaFw0yNzEyMDgxMjI4MjZaMHIxCzAJBgNVBAYTAkNO -MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMR0wGwYDVQQL -ExREb21haW4gVmFsaWRhdGVkIFNTTDEdMBsGA1UEAxMUVHJ1c3RBc2lhIFRMUyBS -U0EgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWa9X+ph+wAm8 -Yh1Fk1MjKbQ5QwBOOKVaZR/OfCh+F6f93u7vZHGcUU/lvVGgUQnbzJhR1UV2epJa -e+m7cxnXIKdD0/VS9btAgwJszGFvwoqXeaCqFoP71wPmXjjUwLT70+qvX4hdyYfO -JcjeTz5QKtg8zQwxaK9x4JT9CoOmoVdVhEBAiD3DwR5fFgOHDwwGxdJWVBvktnoA -zjdTLXDdbSVC5jZ0u8oq9BiTDv7jAlsB5F8aZgvSZDOQeFrwaOTbKWSEInEhnchK -ZTD1dz6aBlk1xGEI5PZWAnVAba/ofH33ktymaTDsE6xRDnW97pDkimCRak6CEbfe -3dXw6OV5AgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUf9OZ86BHDjEAVlYijrfMnt3K -AYowHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD -AgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAG -AQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au -ZGlnaWNlcnQuY29tMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwTAYDVR0gBEUwQzA3Bglg -hkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t -L0NQUzAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBAK3dVOj5dlv4MzK2i233 -lDYvyJ3slFY2X2HKTYGte8nbK6i5/fsDImMYihAkp6VaNY/en8WZ5qcrQPVLuJrJ -DSXT04NnMeZOQDUoj/NHAmdfCBB/h1bZ5OGK6Sf1h5Yx/5wR4f3TUoPgGlnU7EuP -ISLNdMRiDrXntcImDAiRvkh5GJuH4YCVE6XEntqaNIgGkRwxKSgnU3Id3iuFbW9F -UQ9Qqtb1GX91AJ7i4153TikGgYCdwYkBURD8gSVe8OAco6IfZOYt/TEwii1Ivi1C -qnuUlWpsF1LdQNIdfbW3TSe0BhQa7ifbVIfvPWHYOu3rkg1ZeMo6XRU9B4n5VyJY -RmE= ------END CERTIFICATE----- \ No newline at end of file diff --git a/docker_env/nginx/keys/api.django-vue-admin.com.key b/docker_env/nginx/keys/api.django-vue-admin.com.key deleted file mode 100644 index 55add62..0000000 --- a/docker_env/nginx/keys/api.django-vue-admin.com.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAu5QSBTQbToLUu4wCYy/BNoinqFkXiTZEaV6/5PJIeNsz75fn -AEuBpIATEHqRsY6L9HdYAvBiAEv6ufCZhzwWF7ph1ZMhg6ulfoaQwoVCkbKi/zgw -i3tvteda5vXQs4e8GvgZ6zkabQ4cZFjVpb3dA6huBbs20jLfYYXsXWsJEGF3JK5o -kQ08+u/h/q0lFDFa70S9hpQXMtSfCCW/AuEc/+tG7rnUul1oMXjpVnDOmg+CZfIY -gi9D30/zd1DYFJOEwawl5FKLFQY7TOn3RlZ3SR4mNbbhIgHPL9S1xHGcm8UC7PKu -Ogh8+5Nl0aeeUB1liuzM/w5JbF4L4FoZW6ciNQIDAQABAoIBAAEnd9Xq3GknAm6V -/bTFCDQQ8rElPTEVsaWRVO5wdDQ0KxVkEqKMlGNh+1wMWQWl6iQKsPKxrnSwgv4u -Zg9wNfWW6r+w7FGeVoIZC157Ce4SEpEt9BSDoawVnJhTtmFIakajNKufGhPGNLQE -XOosaSX63RRxcrSn5fp4Y7wuaqucXzPV3MuRABrDTHugW1O37570HLwvY9Hmf2+N -WIqEasCjeZ575EwTcqqVwB/j3BNqyrbkxP6aFszxYdMvlK/mpPhrShV6+QmuP02j -OvRt9HM8knUVzsGJzuDk5V5VUGejih3VZO1BuqP1LFb1j4siWBoKpVQrP0wSJzaa -5Vru/wECgYEA9SygrrkPESbjSLYIJU4mRmC4zSqbUoWpvTgpK29nNmif7BSJ9bRr -2QSCIho58a0bl3a7GLwY0dnEyDYKF9nTQ8HqlkvwRwxdMql+0hU0o5hOBnljYoyM -BBptFvoihCe2se+1FEQkunAFCDph00S5utz+8uTlHSFiSy/fQ4GOZwECgYEAw9xl -kZOPSGNEd69F9gtkOAT0kWuazvePSoeYNldZ/MZyE0zE4Wyh5Dk8y5cBt3Pw0ZTr -NN1dc24EkjcFIBop4Me5n5zKr4rH1XKsUQ2jaTurp/fVQwGo820n+ChO8cIEobHY -p6wmKopnnDKOATMjZd8hg+Gck7qWoeTxk3XizzUCgYAFGGJWfz4S6y36Ct5seA1P -lR8CFIqZ0nFOn2YrousQNGhubZbYZmF/ZxqVPtpJbYGPSkZlIzOY2N/AEW9wQ3Si -idsoOHfL4jPlo6QhFZO8eqPUep1YJPeb9jiiK5ygBntDg2nN/ASPY1iXbS8vRtRd -T850mdExI8p5KYuISZ7+AQKBgHF/ENhoErqW04ErbzYh6cRQksyF92KBsGY25uxu -d/XzpP0sGlaq1bFjvagYbGU7aUx5qEatFE8kbL+x5GVy49uewSEOAaHxoNU+qz4Y -0h3T9yfRhKJcnuPY2DWEXiLYFEkCvxKCvmceZuXrocBuOs/4mfpLTamJkWplOdwC -jxkVAoGBALU/996M9frxtjvzQdF3ncbKrDcptZN6s1hIBVk1t2PzcT0XgiOUZRqj -jvUqZWg7MV6kovdjg7N2KSE0u9p2nysL4ejvZRKMNNBdaFJvOUcaYCMTHok1KfXp -Bq75mMgfFLrY+huWzKdRWkEjqD6A05Us48iuikW5Ec32sI6mUzg9 ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/docker_env/nginx/keys/daily.api.django-vue-admin.com.crt b/docker_env/nginx/keys/daily.api.django-vue-admin.com.crt deleted file mode 100755 index 8c94cff..0000000 --- a/docker_env/nginx/keys/daily.api.django-vue-admin.com.crt +++ /dev/null @@ -1,61 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFrDCCBJSgAwIBAgIQDw9E1qRxoRsSagKtIUbGJzANBgkqhkiG9w0BAQsFADBy -MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg -SW5jLjEdMBsGA1UECxMURG9tYWluIFZhbGlkYXRlZCBTU0wxHTAbBgNVBAMTFFRy -dXN0QXNpYSBUTFMgUlNBIENBMB4XDTIxMDMyMDAwMDAwMFoXDTIyMDMxOTIzNTk1 -OVowKTEnMCUGA1UEAxMeZGFpbHkuYXBpLmRqYW5nby12dWUtYWRtaW4uY29tMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyijP5M9nLFbIimHuhYl4cK7C -e4SewgiERRThx+4/iLzFKMVHpSQ0GgcSN7e6tLlfgMzRcUbAnUsia4bzcp0UG+w0 -Ny6OrFF7XuU71YQ3B+35NpfAvJGr7pw71aFpl1l+jz9iym4iw6yN5F8poq6TR7Gl -PNhX1YWZ+Wy0MCDnvQ00MBsQ/42CGEPzE6ZdKJ3l19NY/9/djnxZE+OgMVR3cdCI -I/Et0mahIWYaPGP14/nIzNfOcEZtJMHmgSGF/l9NyUdsrRRK7ltV87YWeU86e2Da -hqW9v0oSOLepOzg4PB4wU2IJfykRMXfJNUG6iWjOMVPdqIFTXjJZvtvZg5J4GQID -AQABo4IChTCCAoEwHwYDVR0jBBgwFoAUf9OZ86BHDjEAVlYijrfMnt3KAYowHQYD -VR0OBBYEFOqwsoYN4FxXPwL2my2kdh/PuVB4MCkGA1UdEQQiMCCCHmRhaWx5LmFw -aS5kamFuZ28tdnVlLWFkbWluLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw -FAYIKwYBBQUHAwEGCCsGAQUFBwMCMD4GA1UdIAQ3MDUwMwYGZ4EMAQIBMCkwJwYI -KwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBkgYIKwYBBQUH -AQEEgYUwgYIwNAYIKwYBBQUHMAGGKGh0dHA6Ly9zdGF0dXNlLmRpZ2l0YWxjZXJ0 -dmFsaWRhdGlvbi5jb20wSgYIKwYBBQUHMAKGPmh0dHA6Ly9jYWNlcnRzLmRpZ2l0 -YWxjZXJ0dmFsaWRhdGlvbi5jb20vVHJ1c3RBc2lhVExTUlNBQ0EuY3J0MAkGA1Ud -EwQCMAAwggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdQBGpVXrdfqRIDC1oolp9PN9 -ESxBdL79SbiFq/L8cP5tRwAAAXhNdRxuAAAEAwBGMEQCICntYjFg4csRL4bxiJvr -ma95JmMzYRrLx84UgLbd1iWhAiB64xH69vjCf4JfVB+3G1UN6G4pphW4m/nYBA2E -ElFuIgB2ACJFRQdZVSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABeE11HF4A -AAQDAEcwRQIhANsjDO2cASF5sGZCyjS8jz9qA+5N4WWFxG+tO4VyELjtAiAIqurr -QbHF9fkBFDg995q5eR16ncpS1d75a0Nhis62PjANBgkqhkiG9w0BAQsFAAOCAQEA -DADo2zekDxm3zbuHGAlQR17h4BtD3tRDy58J58L5CnL+VhNLAN2Fp4AQF1w4a4+z -89ZFOKn+RcwSwyYDFHqsKYa7QYL97z7GJ1ASPG79faO5osbo1SOrSdwzIjjUnSD5 -V4Fr0Fw6NYkq72pJPZkPEeivGEG3MvhzTaFSTwkylDVx6wxzaPY/p9WJpbopKN/8 -+2WSM0b6UB1cuOgfJlhcqYYFqAPO/2XLY60uPpKgboPFAznT8T2QSaYd7JXHndYJ -IgTtXPr7hPOeXP9kDdUycCf3WOjp00gSk/guSujW4ZEaqCrJOkiMCbOrgyCIF7AK -pzwp4H5aJpzHXqObsb5n3Q== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIErjCCA5agAwIBAgIQBYAmfwbylVM0jhwYWl7uLjANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xNzEyMDgxMjI4MjZaFw0yNzEyMDgxMjI4MjZaMHIxCzAJBgNVBAYTAkNO -MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMR0wGwYDVQQL -ExREb21haW4gVmFsaWRhdGVkIFNTTDEdMBsGA1UEAxMUVHJ1c3RBc2lhIFRMUyBS -U0EgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWa9X+ph+wAm8 -Yh1Fk1MjKbQ5QwBOOKVaZR/OfCh+F6f93u7vZHGcUU/lvVGgUQnbzJhR1UV2epJa -e+m7cxnXIKdD0/VS9btAgwJszGFvwoqXeaCqFoP71wPmXjjUwLT70+qvX4hdyYfO -JcjeTz5QKtg8zQwxaK9x4JT9CoOmoVdVhEBAiD3DwR5fFgOHDwwGxdJWVBvktnoA -zjdTLXDdbSVC5jZ0u8oq9BiTDv7jAlsB5F8aZgvSZDOQeFrwaOTbKWSEInEhnchK -ZTD1dz6aBlk1xGEI5PZWAnVAba/ofH33ktymaTDsE6xRDnW97pDkimCRak6CEbfe -3dXw6OV5AgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUf9OZ86BHDjEAVlYijrfMnt3K -AYowHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD -AgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAG -AQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au -ZGlnaWNlcnQuY29tMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwTAYDVR0gBEUwQzA3Bglg -hkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t -L0NQUzAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBAK3dVOj5dlv4MzK2i233 -lDYvyJ3slFY2X2HKTYGte8nbK6i5/fsDImMYihAkp6VaNY/en8WZ5qcrQPVLuJrJ -DSXT04NnMeZOQDUoj/NHAmdfCBB/h1bZ5OGK6Sf1h5Yx/5wR4f3TUoPgGlnU7EuP -ISLNdMRiDrXntcImDAiRvkh5GJuH4YCVE6XEntqaNIgGkRwxKSgnU3Id3iuFbW9F -UQ9Qqtb1GX91AJ7i4153TikGgYCdwYkBURD8gSVe8OAco6IfZOYt/TEwii1Ivi1C -qnuUlWpsF1LdQNIdfbW3TSe0BhQa7ifbVIfvPWHYOu3rkg1ZeMo6XRU9B4n5VyJY -RmE= ------END CERTIFICATE----- diff --git a/docker_env/nginx/keys/daily.api.django-vue-admin.com.key b/docker_env/nginx/keys/daily.api.django-vue-admin.com.key deleted file mode 100755 index d953f23..0000000 --- a/docker_env/nginx/keys/daily.api.django-vue-admin.com.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAyijP5M9nLFbIimHuhYl4cK7Ce4SewgiERRThx+4/iLzFKMVH -pSQ0GgcSN7e6tLlfgMzRcUbAnUsia4bzcp0UG+w0Ny6OrFF7XuU71YQ3B+35NpfA -vJGr7pw71aFpl1l+jz9iym4iw6yN5F8poq6TR7GlPNhX1YWZ+Wy0MCDnvQ00MBsQ -/42CGEPzE6ZdKJ3l19NY/9/djnxZE+OgMVR3cdCII/Et0mahIWYaPGP14/nIzNfO -cEZtJMHmgSGF/l9NyUdsrRRK7ltV87YWeU86e2DahqW9v0oSOLepOzg4PB4wU2IJ -fykRMXfJNUG6iWjOMVPdqIFTXjJZvtvZg5J4GQIDAQABAoIBAFYjOqXXe7IoTi2s -mbnbf+6fgC2qLg0mHNnkkmmiif7E1EtRd/wVJ4AZmDkWd57ux5M1cl6OU58R9xoS -9+NTq9BT/lGu7ErfMy6VhT+upNYjn4cT9SND/Jrghhw6OSgskWEPFJSFhhmTCiiP -Jcn0EbxAJNR+qDpKQXfGSiahtqxV01kNRU/j6YmVrQEoVif/9+LJmcs5Uy+gqA4a -fQou8/QQjrmPHPOSSWZ8aZlPNt89+E4P+XIkf4rPxD8lrWd2ufDeCdm1As4qYQQD -c/eeBh6qkrKijZZ8NRgonTaCYPXkkkHME4BgdP2gVCW/KMVfdM5pVVk7dctSs+6w -VFfF5CsCgYEA/pXLQXt6PUlJAVSFodK8CndZY1pAbzLNVTsDAVuEAepwmEL7Tw0O -nV4igsANdRxZxEdYWsY8CClNTNLNY92zaAbpsQXHxHqnXnl2ZGQi1Jb2eFR6zw+m -8Qyb6aca58Q95flHQY75/+IFWemj76p1aT7aIvpElMdkBUh1Ak92cv8CgYEAy0hu -MqJga0/3UoMLhjhUVWGXI6NBpvWNv7FqSeQ2SDj0iBib7nyrlP41bCcyHFXryrXf -YsbG4fq0mmyhQUz4++OP57lxXXBu3UvBd6qQUorWX9HVHy6ljun8PsJdNUGj9Q2v -arH6Rv/emIx86IAOGjgIgK+YiNwiw/uEYgNzTOcCgYBryjh4zTMAZ9sFOSgrT/JV -7Bpounm1myjdAVNQa9MEjKKHlTSaT8j0UDsEaRRJlWtcc2ixZmVcf0A/WrGjquaf -EO45CV1/jv72PS8nak5k/FX2tK4apWHlhZUt5Ja7spcSm+zTkRnAgY4Kd6X1f5Ke -sQHi9Vu8Mn/izL7d748TOQKBgH75txuZoXBmeq3nfQNRnBvY4Xc5OoD3UJs0Tpfp -HJ7wNI3uETheVy6xutzbfsmEQcxU3jvsvb3Zw4XR5MfNNJjiA7lSdCVRXW6NK0N8 -HrnwTwd7IgxgLrmeHhl1fpMNdURUUAXtNc+zc28GEd+IXUazSVxYUobqOi0Apigy -z4pxAoGBAPKd+WMUS94Ne7WMHDzcCcQKl2dJmBVj036qCtPgUL4yDyRDc/H1fQxI -jr/+JueqktrJgJsOL4uygn0zzKIJyQIToufxOodUdmviRLaH2UskNUBUjIBqyDc0 -pjPebC7sxg6HZQmVpgX4klj1IWDpudD+cCRGF9SIzKRvNEadLgOl ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/docker_env/nginx/keys/daily.demo.django-vue-admin.com.crt b/docker_env/nginx/keys/daily.demo.django-vue-admin.com.crt deleted file mode 100755 index 941c1e6..0000000 --- a/docker_env/nginx/keys/daily.demo.django-vue-admin.com.crt +++ /dev/null @@ -1,61 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFsDCCBJigAwIBAgIQBbQIKLDxaNeKW6HjUJCFNjANBgkqhkiG9w0BAQsFADBy -MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg -SW5jLjEdMBsGA1UECxMURG9tYWluIFZhbGlkYXRlZCBTU0wxHTAbBgNVBAMTFFRy -dXN0QXNpYSBUTFMgUlNBIENBMB4XDTIxMDMyMDAwMDAwMFoXDTIyMDMxOTIzNTk1 -OVowKjEoMCYGA1UEAxMfZGFpbHkuZGVtby5kamFuZ28tdnVlLWFkbWluLmNvbTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKAOwxsoKm4vH/gv8h7OHYHI -5dQAAKm3tk1ZsyY9cMlSq/GIMSY15BZSwdSiwyI3vcCpmz2YCVRXpH8r0LNm/Ygu -fjVeK1H+F6fQkGj7065ye1Z15PtgI6Dx9dhLlFlR3lZYm0MVwSIW2xgVqbL+WNKl -198afnP+/B/Klzjyud4wqAlzDcD8lIh8iL0LMY3HSHzSzr8xtYZLxUvEzcl+vRF9 -a9GjTOgg01Ukk04zHXan7VInK1/lurQ+WuntfPFDe/jmlEid4/wvB/lCMi0KUSWd -0C9CCB+2q/Lsa0hr8v4DF1TS1/YGg/y0Ye1+DzpKLKv/mfe6py18Ca7FcnFoKVsC -AwEAAaOCAogwggKEMB8GA1UdIwQYMBaAFH/TmfOgRw4xAFZWIo63zJ7dygGKMB0G -A1UdDgQWBBQ14z4HfGEjC4tAPVnN/AvsXmgHYDAqBgNVHREEIzAhgh9kYWlseS5k -ZW1vLmRqYW5nby12dWUtYWRtaW4uY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE -FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwPgYDVR0gBDcwNTAzBgZngQwBAgEwKTAn -BggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGSBggrBgEF -BQcBAQSBhTCBgjA0BggrBgEFBQcwAYYoaHR0cDovL3N0YXR1c2UuZGlnaXRhbGNl -cnR2YWxpZGF0aW9uLmNvbTBKBggrBgEFBQcwAoY+aHR0cDovL2NhY2VydHMuZGln -aXRhbGNlcnR2YWxpZGF0aW9uLmNvbS9UcnVzdEFzaWFUTFNSU0FDQS5jcnQwCQYD -VR0TBAIwADCCAQUGCisGAQQB1nkCBAIEgfYEgfMA8QB3AEalVet1+pEgMLWiiWn0 -830RLEF0vv1JuIWr8vxw/m1HAAABeE1yhJEAAAQDAEgwRgIhAIdZiX5qq+KJjdtl -2Z9ejh5o9VHKyVVUgkJb0+S8aQGlAiEA5nEVffySiTcUogz+b7n34hmG2aW3YO02 -UhMzyv7hoGcAdgAiRUUHWVUkVpY/oS/x922G4CMmY63AS39dxoNcbuIPAgAAAXhN -coRmAAAEAwBHMEUCIDFWIi3mkGmkB/uuTCqJyPTz8/WS4vqvdAUWO+MuxuaoAiEA -yP80fJCLnfso7VoJcWQT1l6bN6XL/jxip1OjXU0+dQMwDQYJKoZIhvcNAQELBQAD -ggEBAB0vH0OMrwGOQHdRdaN9t+2Yc1xnBNcksHcCmVD09gO2clA06OqTiu77g8lw -KwO2M5DmNFAA2onDxRVIL6auyLNdyK4X2m9i1eGnyAKro7d4owIlG30JdJ7uHzLG -ROL9SR0ibNZwOhoKSfpy3a+fWngMjCdW8pAFJHfPbOf6lP/CpGwoBnLvm9a9ZG3K -m2NmFN1/GPje25tXy0S/NaVFDVcJyfMeuVKqdwY9sbN7nOYGUury5NC5LWbgJ0T2 -KWLcZc3LCa791kHLWVt/KI+9UgpM6Xiie0jUUIU92NaxBD/wY/jybPiogJkAz/sl -TncbnwO2+WpN6jIy9ccs8ogUMTQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIErjCCA5agAwIBAgIQBYAmfwbylVM0jhwYWl7uLjANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xNzEyMDgxMjI4MjZaFw0yNzEyMDgxMjI4MjZaMHIxCzAJBgNVBAYTAkNO -MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMR0wGwYDVQQL -ExREb21haW4gVmFsaWRhdGVkIFNTTDEdMBsGA1UEAxMUVHJ1c3RBc2lhIFRMUyBS -U0EgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWa9X+ph+wAm8 -Yh1Fk1MjKbQ5QwBOOKVaZR/OfCh+F6f93u7vZHGcUU/lvVGgUQnbzJhR1UV2epJa -e+m7cxnXIKdD0/VS9btAgwJszGFvwoqXeaCqFoP71wPmXjjUwLT70+qvX4hdyYfO -JcjeTz5QKtg8zQwxaK9x4JT9CoOmoVdVhEBAiD3DwR5fFgOHDwwGxdJWVBvktnoA -zjdTLXDdbSVC5jZ0u8oq9BiTDv7jAlsB5F8aZgvSZDOQeFrwaOTbKWSEInEhnchK -ZTD1dz6aBlk1xGEI5PZWAnVAba/ofH33ktymaTDsE6xRDnW97pDkimCRak6CEbfe -3dXw6OV5AgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUf9OZ86BHDjEAVlYijrfMnt3K -AYowHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD -AgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAG -AQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au -ZGlnaWNlcnQuY29tMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwTAYDVR0gBEUwQzA3Bglg -hkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t -L0NQUzAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBAK3dVOj5dlv4MzK2i233 -lDYvyJ3slFY2X2HKTYGte8nbK6i5/fsDImMYihAkp6VaNY/en8WZ5qcrQPVLuJrJ -DSXT04NnMeZOQDUoj/NHAmdfCBB/h1bZ5OGK6Sf1h5Yx/5wR4f3TUoPgGlnU7EuP -ISLNdMRiDrXntcImDAiRvkh5GJuH4YCVE6XEntqaNIgGkRwxKSgnU3Id3iuFbW9F -UQ9Qqtb1GX91AJ7i4153TikGgYCdwYkBURD8gSVe8OAco6IfZOYt/TEwii1Ivi1C -qnuUlWpsF1LdQNIdfbW3TSe0BhQa7ifbVIfvPWHYOu3rkg1ZeMo6XRU9B4n5VyJY -RmE= ------END CERTIFICATE----- diff --git a/docker_env/nginx/keys/daily.demo.django-vue-admin.com.key b/docker_env/nginx/keys/daily.demo.django-vue-admin.com.key deleted file mode 100755 index 589526f..0000000 --- a/docker_env/nginx/keys/daily.demo.django-vue-admin.com.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAoA7DGygqbi8f+C/yHs4dgcjl1AAAqbe2TVmzJj1wyVKr8Ygx -JjXkFlLB1KLDIje9wKmbPZgJVFekfyvQs2b9iC5+NV4rUf4Xp9CQaPvTrnJ7VnXk -+2AjoPH12EuUWVHeVlibQxXBIhbbGBWpsv5Y0qXX3xp+c/78H8qXOPK53jCoCXMN -wPyUiHyIvQsxjcdIfNLOvzG1hkvFS8TNyX69EX1r0aNM6CDTVSSTTjMddqftUicr -X+W6tD5a6e188UN7+OaUSJ3j/C8H+UIyLQpRJZ3QL0IIH7ar8uxrSGvy/gMXVNLX -9gaD/LRh7X4POkosq/+Z97qnLXwJrsVycWgpWwIDAQABAoIBABaP2NHdrhQnwWu/ -T8km3dhFz5vm6jECVrN9nE1yJhFtqBOH0qx5C+9Xor9iDXv9JoWKLaTCPI0ZPkoM -4kI/wietrMMXb1IuAqX4YOWORgRrr9YmupdIBzhbPdVLsMbhzaPB9r+UnqEQXrmn -ksB1WQ5MgWsPdYQit+XqrWQXgbrU9kAP5+aO2GKrlnWZqBgshUkd2Sq5rdgrK5nv -kcmVBGClPsgOG2HgA+aJoFGLccoF8NMrBWaSc+zlHjiT8fP2YnMcDsX8Fw1tETbK -P9jf9wd4b/2ezKL3TWJMkbTRnxBwDgARWFVrD9jZqLtw342YuGQnEhPJFFdepKpQ -3GtbyiECgYEA0KlSF3K+coEjCjBGSFD5ACmB5ipl/NFPXVjCG1vHGHRh/0WnXBPI -zY3pRHFr9cJKLxQPe+4085yFXGTV7GHhH4nd1tEVxrH8ouNok0/WL4HHtvfGOq/H -sKQsZKVaUXd+NTZmzoXXJsb9Jgnu6r4AS4QazP1FRxSbSToxbut1ezsCgYEAxF6f -mAFz9p5ptNStJLXV53nTgNHK0Hk2cISu5aAUGQKA26VwnZTEo09Wt+WOGjzjTkSi -+TCoFfG77aqFQ1AyuAYWWErcS4/1/p0SeINXdztx34CJM/OqJ/AtjdL+09xwUZe6 -JeUWWPMJukkrFkjNkCjkdQlVxG+a3jMlmM016GECgYEAoJJ8QuEhH7qyvUdy/nmZ -dH98oCPmggyM15fTH/yblP0S4L+4T8pFz7EyXmIuI1xVfC8iz0r7YrEDi5tpaFPW -S0/r8EDMUjBr6um3cw2QFNT5XJsF5+mXcR6Vrwn0HBcpf0eTC8DBVezxqFEik3CN -h49slG0e39lCurJWkjYOHTsCgYBeA/Oi4ic0DvoLErvm1IwZ7BDgHxFcKHxw+IWH -+NFGfBVXk+jL+Vr/2U9qciRL2ZT2dxQT/ECtaPQRwM9WwAHYa0mtcgHwx3b+NROP -0UpCEprdZ/vIfMOdpXcZ7MgGhQbdeags1naRlaK1pqxTWf3ZJErk4dhHWSurcI9y -jeVeYQKBgQCsIaGmX/xigoLaEucXOM4V34QU1gepJkDLDNEw4r9EoNHoBCwIaGxX -CWCsyuOwnCWM2OJJth5a+1xPYul0jsh7HCShICpkMsktoq4UdYbBfVNQiqenI7L7 -l6/mzU5Ds6KXKVh2FZ7O8zcup1BYs0pAHTZqF+P/1FjSu1jbGfezFg== ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/docker_env/nginx/keys/demo.django-vue-admin.com.crt b/docker_env/nginx/keys/demo.django-vue-admin.com.crt deleted file mode 100755 index 342d769..0000000 --- a/docker_env/nginx/keys/demo.django-vue-admin.com.crt +++ /dev/null @@ -1,61 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFoTCCBImgAwIBAgIQBL1afhbyouKA0yBDgDhq/zANBgkqhkiG9w0BAQsFADBy -MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg -SW5jLjEdMBsGA1UECxMURG9tYWluIFZhbGlkYXRlZCBTU0wxHTAbBgNVBAMTFFRy -dXN0QXNpYSBUTFMgUlNBIENBMB4XDTIxMDMyMDAwMDAwMFoXDTIyMDMxOTIzNTk1 -OVowJDEiMCAGA1UEAxMZZGVtby5kamFuZ28tdnVlLWFkbWluLmNvbTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMk2tqLVSJyC/VTuWlZ+a+bjthUotJ/o -yQcXMC6eu/KyHbWqh5Ccj2kLh/zf9uhcs/GcYl/H1hyIVuiC+SHGmGfCqQB96vLl -uwwJDlM+y910xKmKV2S6DEFbXDZP76pShrpPs1nDkU5gftuGhX1S77pmMqjbOsG+ -gZJAlAZKzT5xnGwpo4rkHc8xPY0ac29+9HXYDawpmySSdbfG+W0kape/wBexFmO+ -KLt/oRk+QJbtPguLNLLlvZznf+fFp5UcmsVks/scg9fM1pnj3QQaCB8RXQQKkskm -Hi67PGFJOeepNFkApzHO4sUM3ya2Rskzfs9DtTlCODn3XFSVJz7DyTsCAwEAAaOC -An8wggJ7MB8GA1UdIwQYMBaAFH/TmfOgRw4xAFZWIo63zJ7dygGKMB0GA1UdDgQW -BBSRBeJj2dUcPqhi3km5tbW5lZP3aTAkBgNVHREEHTAbghlkZW1vLmRqYW5nby12 -dWUtYWRtaW4uY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD -AQYIKwYBBQUHAwIwPgYDVR0gBDcwNTAzBgZngQwBAgEwKTAnBggrBgEFBQcCARYb -aHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGSBggrBgEFBQcBAQSBhTCBgjA0 -BggrBgEFBQcwAYYoaHR0cDovL3N0YXR1c2UuZGlnaXRhbGNlcnR2YWxpZGF0aW9u -LmNvbTBKBggrBgEFBQcwAoY+aHR0cDovL2NhY2VydHMuZGlnaXRhbGNlcnR2YWxp -ZGF0aW9uLmNvbS9UcnVzdEFzaWFUTFNSU0FDQS5jcnQwCQYDVR0TBAIwADCCAQIG -CisGAQQB1nkCBAIEgfMEgfAA7gB1AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr -8vxw/m1HAAABeE1whV0AAAQDAEYwRAIgPFX8oV29XVZMDi2tbEuBo2AuS4udT2I/ -tMHo9EPNPOYCIGFeOpkGfPcG4szSvKEmUIYimb3vejH0QJ6qB3+T6E5kAHUAIkVF -B1lVJFaWP6Ev8fdthuAjJmOtwEt/XcaDXG7iDwIAAAF4TXCFeAAABAMARjBEAiBC -HxlN8ItLz/FW/gYrmGGXTVvxxnVKv9t5bsj2AsdmOQIgJVu8zYZVNjt7AHFusZWg -ZYSY0Qd+11v1oXBHAi0OUAowDQYJKoZIhvcNAQELBQADggEBAEKj+pGihWMbm/Bm -d+7Ra6gngG5N/c7S1cPzmOAlX3bWOFLqZRVPiC8Xa5uzLuqkYMiRIuIFUjZj2CwS -gKVwEk3xIL76sMVURV17mhjV7jbhzCSIqnEVLpiGRsuEoHKW8UUAzBdAZjjk4D+Y -LZKOQKcWojGTCyRJA5dRHy+sWtnZcHGaD36UHeVh0ctFhoVcc9Oxsh9T6W4NnMd/ -CthO8fDic3643232J+6VF1vH5fkz1Q6UGbH+GbmkZ70Rv9YCl78zU77juBfTy9ht -HJmcwLWF6Hef7Z+K2QnvT6H+cIb6OxSErshy9TlKgTRjVD7A3wTrri/dCJqfINVk -FoBVzmQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIErjCCA5agAwIBAgIQBYAmfwbylVM0jhwYWl7uLjANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xNzEyMDgxMjI4MjZaFw0yNzEyMDgxMjI4MjZaMHIxCzAJBgNVBAYTAkNO -MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMR0wGwYDVQQL -ExREb21haW4gVmFsaWRhdGVkIFNTTDEdMBsGA1UEAxMUVHJ1c3RBc2lhIFRMUyBS -U0EgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWa9X+ph+wAm8 -Yh1Fk1MjKbQ5QwBOOKVaZR/OfCh+F6f93u7vZHGcUU/lvVGgUQnbzJhR1UV2epJa -e+m7cxnXIKdD0/VS9btAgwJszGFvwoqXeaCqFoP71wPmXjjUwLT70+qvX4hdyYfO -JcjeTz5QKtg8zQwxaK9x4JT9CoOmoVdVhEBAiD3DwR5fFgOHDwwGxdJWVBvktnoA -zjdTLXDdbSVC5jZ0u8oq9BiTDv7jAlsB5F8aZgvSZDOQeFrwaOTbKWSEInEhnchK -ZTD1dz6aBlk1xGEI5PZWAnVAba/ofH33ktymaTDsE6xRDnW97pDkimCRak6CEbfe -3dXw6OV5AgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUf9OZ86BHDjEAVlYijrfMnt3K -AYowHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD -AgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAG -AQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au -ZGlnaWNlcnQuY29tMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwTAYDVR0gBEUwQzA3Bglg -hkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t -L0NQUzAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBAK3dVOj5dlv4MzK2i233 -lDYvyJ3slFY2X2HKTYGte8nbK6i5/fsDImMYihAkp6VaNY/en8WZ5qcrQPVLuJrJ -DSXT04NnMeZOQDUoj/NHAmdfCBB/h1bZ5OGK6Sf1h5Yx/5wR4f3TUoPgGlnU7EuP -ISLNdMRiDrXntcImDAiRvkh5GJuH4YCVE6XEntqaNIgGkRwxKSgnU3Id3iuFbW9F -UQ9Qqtb1GX91AJ7i4153TikGgYCdwYkBURD8gSVe8OAco6IfZOYt/TEwii1Ivi1C -qnuUlWpsF1LdQNIdfbW3TSe0BhQa7ifbVIfvPWHYOu3rkg1ZeMo6XRU9B4n5VyJY -RmE= ------END CERTIFICATE----- diff --git a/docker_env/nginx/keys/demo.django-vue-admin.com.key b/docker_env/nginx/keys/demo.django-vue-admin.com.key deleted file mode 100755 index fb97c8c..0000000 --- a/docker_env/nginx/keys/demo.django-vue-admin.com.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAyTa2otVInIL9VO5aVn5r5uO2FSi0n+jJBxcwLp678rIdtaqH -kJyPaQuH/N/26Fyz8ZxiX8fWHIhW6IL5IcaYZ8KpAH3q8uW7DAkOUz7L3XTEqYpX -ZLoMQVtcNk/vqlKGuk+zWcORTmB+24aFfVLvumYyqNs6wb6BkkCUBkrNPnGcbCmj -iuQdzzE9jRpzb370ddgNrCmbJJJ1t8b5bSRql7/AF7EWY74ou3+hGT5Alu0+C4s0 -suW9nOd/58WnlRyaxWSz+xyD18zWmePdBBoIHxFdBAqSySYeLrs8YUk556k0WQCn -Mc7ixQzfJrZGyTN+z0O1OUI4OfdcVJUnPsPJOwIDAQABAoIBAA8baQX7vnplyVBt -nuG8lyxcL2kSR9FzwFgkcQ0nBNR5dAqWNZxxbMEFyR1+0UJr52S+CZLIZbZ5tBC7 -+KmFCB9OObMcQR4ginUiXu14GwVTBYr3JI2e/FmR2vAG+2cN0Ci/4CberJO2Yf/o -bzBUIESd9LLB1v0B6SeKarK4PgWwjrr/twowABRBhkkKFErfYZjfNh1mALXPNEUA -7z3a8abw+JWympIFKWxi3YXyLOJZaGawOPDhq+ZVv+7rXvIyAzUzpmwCprjZFL4Q -hgN7IY7KjYK772Ffe0nwMbd3wbwYeAelM9fndH9dTMrQ1n6EcDBzla8Cwl6OVEk3 -GpQqOfECgYEA+7qFHw75AOI3FFke/2VOJ58m0rrYJwDrLazlrzashi7qgJOBY6jp -yjLgGCOcR9v8pRWkOw2VLy+dhdr16Xp/XYhuSa6O5EC7igtnUVx9xu+XAksZiB97 -f4lm7F3uirEh7ewuqiRETI9o6V5iGTCSMSc21zlJ1zoxnLMSuMyCKTECgYEAzKDD -PNJVZAiZJ25JKinkZlTyQ9VmQkfrvsIBWheN844uoSmmLR4PNwriZQtlURI58WA2 -pe20aHJaleOJvzgW/OvcB+7mf/Ukn1mw6Ciusj6jXLXmmq8i80W0RMr1Rdbq8+dp -DNZt0iDXEZXHEGqdkpkn/gsvYL+jeIiKyuJ9PisCgYAoZGF//lMORT45UaObr5G+ -4dbE8Z5Fg+w4xAmG9+rvDRAr2X9lknERNOCofu5QyYfcpYBYyXEqxSUtmVjkQfe1 -9nJb+FqNXaW6HOJTN9gm18MPZyWNph+W82FEhD4Gmy2qk79ZJcCf2FMpPy/Wguiy -Ymx2VIb4tinHzyQt6wLnwQKBgAURSiR8dP7oM5rFYWx44x4hpmpFo6WqkE0GEvB/ -OtW4RLFbDbF6WBgd3eNwt86dK/AtWM0dKOWZR2ME4olowzD6SlWr9etfT8vedcIa -F9F0Oal3G8Hi6nOp20AE4rQbEXB+35wgx1F33LujwO1IJqTVxCbHciHsPQkkIIPL -vhxHAoGAdwbRiK2OCmycedsD+L5qdxOYiL8JIAXLP+H7ZD0Jyx21UxQAmvza6fIx -HygnDGzrTJoOPEWu5WmGs4i6mr1bChHpo85LVNfytsxbE59y3I0va1IlSUC6wjXP -Yy3caUiBgxmzz4vhqCFdpLhT2SyyB4m13ggLmeyqLy88WnYCgiE= ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/docker_env/nginx/keys/www.django-vue-admin.com.crt b/docker_env/nginx/keys/www.django-vue-admin.com.crt deleted file mode 100644 index 673ce7f..0000000 --- a/docker_env/nginx/keys/www.django-vue-admin.com.crt +++ /dev/null @@ -1,61 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFszCCBJugAwIBAgIQCGwikUrRfEUk8GbxRWLVIDANBgkqhkiG9w0BAQsFADBy -MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg -SW5jLjEdMBsGA1UECxMURG9tYWluIFZhbGlkYXRlZCBTU0wxHTAbBgNVBAMTFFRy -dXN0QXNpYSBUTFMgUlNBIENBMB4XDTIxMDMwMzAwMDAwMFoXDTIyMDMwMjIzNTk1 -OVowHzEdMBsGA1UEAxMUZGphbmdvLXZ1ZS1hZG1pbi5jb20wggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC0iitqUeTxkq5qabbVcB+7a+YArfKAJBRvcj+T -VVdRkvEjcfGLvXIJUTvcUqJkRRYFbimdjB5q7CWCld8bgz/UOpIEmbdqn+WgzrNn -WWZrRiN5ylHAsIaKlgYKh6gcftEco6OgkrM8oyq1gORRBIcSj95VcqpIeAUMVyCX -R0h3dXnLCVe70ejr8w2cyHrSeS68mXw7LlAdfC0JAZTB/wxwcitSnnIVEbV6wMzG -BD5Ka/WprnJgJa7Prb5KHiZh4UG4Es2JpIHALMYLIeKQCUCIP1NmW8Ale+nhY9kD -tJeSEIY+/dRoDjpPkkIZalMp+5p0yDQ1LIO4pDZxnoI2vFLFAgMBAAGjggKWMIIC -kjAfBgNVHSMEGDAWgBR/05nzoEcOMQBWViKOt8ye3coBijAdBgNVHQ4EFgQUru5P -/0LuJj6hxqHWVYUN690wFNEwOQYDVR0RBDIwMIIUZGphbmdvLXZ1ZS1hZG1pbi5j -b22CGHd3dy5kamFuZ28tdnVlLWFkbWluLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYD -VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMD4GA1UdIAQ3MDUwMwYGZ4EMAQIB -MCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBkgYI -KwYBBQUHAQEEgYUwgYIwNAYIKwYBBQUHMAGGKGh0dHA6Ly9zdGF0dXNlLmRpZ2l0 -YWxjZXJ0dmFsaWRhdGlvbi5jb20wSgYIKwYBBQUHMAKGPmh0dHA6Ly9jYWNlcnRz -LmRpZ2l0YWxjZXJ0dmFsaWRhdGlvbi5jb20vVHJ1c3RBc2lhVExTUlNBQ0EuY3J0 -MAkGA1UdEwQCMAAwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdgBGpVXrdfqRIDC1 -oolp9PN9ESxBdL79SbiFq/L8cP5tRwAAAXf475pDAAAEAwBHMEUCIHTgL1+oRWE+ -REuWNRa5J1cflPKW63jk6/3ibF+Sm5peAiEAt74SK9Ka9QyMJfP57eDl3xA1Ctnb -Bz6zTLIQFFicPGsAdgAiRUUHWVUkVpY/oS/x922G4CMmY63AS39dxoNcbuIPAgAA -AXf475pNAAAEAwBHMEUCIQDOE36oL7MAxmHdEoI338jLW0xnBN8VeW9XyuTzIcq7 -eQIgLwJTNfLqgw7TofY3dKqof5rkcuJWMmSI4aapUUBjFfIwDQYJKoZIhvcNAQEL -BQADggEBAC9lYBZuCzle1tSaJ4nVfogwHf0B4lKjDI8ixEnrDaY0tAuYst4S7zoU -76dZcpdwQjVLtlLk5jyaNdN5ohsu9WpErq6N7bXKhbSPBavCPxP4sMWMvmeQQUtB -UKqqRofXbx3WcWtsf1/Wlg3pyb0oyJ7kKt3iDG9OYEihQzEyG5Y72IE+HsbhTAWR -zqxGnmMumQ+JTnxCCudPoVPk25i2BfndMbcY4N6YyJYuLwMojtMkAeWtRdMmqtiy -lMb7EbWLYCHDyv892WTzie1BqZ7YcOaE59OChhmoYxiSXNHPCToIFECTz6BhPxlI -T3LbIM4+81HNDebdR17NUE3zN44OjsA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIErjCCA5agAwIBAgIQBYAmfwbylVM0jhwYWl7uLjANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xNzEyMDgxMjI4MjZaFw0yNzEyMDgxMjI4MjZaMHIxCzAJBgNVBAYTAkNO -MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMR0wGwYDVQQL -ExREb21haW4gVmFsaWRhdGVkIFNTTDEdMBsGA1UEAxMUVHJ1c3RBc2lhIFRMUyBS -U0EgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWa9X+ph+wAm8 -Yh1Fk1MjKbQ5QwBOOKVaZR/OfCh+F6f93u7vZHGcUU/lvVGgUQnbzJhR1UV2epJa -e+m7cxnXIKdD0/VS9btAgwJszGFvwoqXeaCqFoP71wPmXjjUwLT70+qvX4hdyYfO -JcjeTz5QKtg8zQwxaK9x4JT9CoOmoVdVhEBAiD3DwR5fFgOHDwwGxdJWVBvktnoA -zjdTLXDdbSVC5jZ0u8oq9BiTDv7jAlsB5F8aZgvSZDOQeFrwaOTbKWSEInEhnchK -ZTD1dz6aBlk1xGEI5PZWAnVAba/ofH33ktymaTDsE6xRDnW97pDkimCRak6CEbfe -3dXw6OV5AgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUf9OZ86BHDjEAVlYijrfMnt3K -AYowHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD -AgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAG -AQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au -ZGlnaWNlcnQuY29tMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwTAYDVR0gBEUwQzA3Bglg -hkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t -L0NQUzAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBAK3dVOj5dlv4MzK2i233 -lDYvyJ3slFY2X2HKTYGte8nbK6i5/fsDImMYihAkp6VaNY/en8WZ5qcrQPVLuJrJ -DSXT04NnMeZOQDUoj/NHAmdfCBB/h1bZ5OGK6Sf1h5Yx/5wR4f3TUoPgGlnU7EuP -ISLNdMRiDrXntcImDAiRvkh5GJuH4YCVE6XEntqaNIgGkRwxKSgnU3Id3iuFbW9F -UQ9Qqtb1GX91AJ7i4153TikGgYCdwYkBURD8gSVe8OAco6IfZOYt/TEwii1Ivi1C -qnuUlWpsF1LdQNIdfbW3TSe0BhQa7ifbVIfvPWHYOu3rkg1ZeMo6XRU9B4n5VyJY -RmE= ------END CERTIFICATE----- \ No newline at end of file diff --git a/docker_env/nginx/keys/www.django-vue-admin.com.key b/docker_env/nginx/keys/www.django-vue-admin.com.key deleted file mode 100644 index 23cba35..0000000 --- a/docker_env/nginx/keys/www.django-vue-admin.com.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAtIoralHk8ZKuamm21XAfu2vmAK3ygCQUb3I/k1VXUZLxI3Hx -i71yCVE73FKiZEUWBW4pnYweauwlgpXfG4M/1DqSBJm3ap/loM6zZ1lma0YjecpR -wLCGipYGCoeoHH7RHKOjoJKzPKMqtYDkUQSHEo/eVXKqSHgFDFcgl0dId3V5ywlX -u9Ho6/MNnMh60nkuvJl8Oy5QHXwtCQGUwf8McHIrUp5yFRG1esDMxgQ+Smv1qa5y -YCWuz62+Sh4mYeFBuBLNiaSBwCzGCyHikAlAiD9TZlvAJXvp4WPZA7SXkhCGPv3U -aA46T5JCGWpTKfuadMg0NSyDuKQ2cZ6CNrxSxQIDAQABAoIBAA5RZOcOLp9/+Agl -cSQVO9cD1B5arUA/XEWIZIVdP8sO4cPjXfosoJYflKVBAnL8TaZJmdBOU/071C+6 -jhKjApVkvb7SqAqzOqVZrz2zh91bFyYqBvjGpyznf/wmzQzRe+kPC0OJTuCwugrh -+Xl5Z/LvaP0S1nFf31qesE1/ED609pvWtdUWj2oop9zORBzjaGcXeOKNqX8XnQCp -rJ487wcnuL8Nnuu+vuh8dC9o7zwjGrKwXhM3sijLp4q9VOF9fW2bYLyfLUR3FCFq -JPrQXe1mY28w+uIlnEdPkwgGIJbzur601BuzU9ZH5MSl7iYV319MPz+rtizFJxLm -OCg5hcMCgYEA7RrgQsrSj4fhi0VVkQ3fFeLJPQlvVcMK0OOYxP3cKQYSgXo79bQK -i9yRCRVS2UTGh8B3MGbPr+sRINokeYtjWxGDOwAlkye9kRiCKzzZOrlwDAY/SEDZ -HH5mVnv9UHtxCFSUub67IVWH7wCmoprKEK/loyvJFiE5jsxVmNZl3o8CgYEAwu1R -nBsETJLuN5/fB9rW3NvjaHGT1B6LQ1uIBmsU6V71gBasawX/X3ENOoX1dQa2japp -x58pjLJuP/t4WgZ41PBagij2G83VdFBdvrcVSk7B1yt8rudxmcvo1K6FR2FG7DMU -9kkb9JKFT3/FM7LT+z4xXxJ0AoNg6QD1IIT5Y2sCgYEAyQUvOxGQISY334bh+8AB -8iE7MidsoA5jfiRoIiOEY7eFOwbyDOcexeMzh7rvacs4cmGH655O2Lv34p1vrSiz -DMO1OfFu6esYegqIWbYWCgar61XkkxJ/v/ueMhae9nwhoclr6mq9Zo6IV+Z6YIPR -awJmM8fsjXmPvfSZYaHr7hsCgYAPzW99SU9q6cp4JfTNzTb4BreD4xlJ7AP8PPJl -Gs9CMBmU/cGSl5ThZufco7mHeDjaeUNEFKooptp7Q2a5Xab0FFwyCyIQlPpGCLHg -4TTPplzelb7w6wBxqG9CtrdFVySJx4ZehQTIKgy2qjQRgeDfkGYuP++5uG7l1NcK -gN066wKBgDg2F4yMx4SBWL3aBjIVd+Zilm+pkU1ZGC1XcuLnqSSMcoDy/JMszQC1 -SEdDxgnCGlkWjtaxNPwfZTPU0SIoX5dcAx1EaHDJ+ibiIKGtM8forSCiP8fNz0oR -SYNZaYVuDJb1SFk9vKJMuIIFWS+AM6rlcOpNu6A0+1MbstM4BvwS ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/docker_env/nginx/nginx.conf b/docker_env/nginx/nginx.conf deleted file mode 100644 index dad006a..0000000 --- a/docker_env/nginx/nginx.conf +++ /dev/null @@ -1,15 +0,0 @@ -events { - worker_connections 1024; -} -http { - include mime.types; - default_type application/octet-stream; - sendfile on; - client_max_body_size 100m; - include /etc/nginx/sites-enabled/*;#主要是这个地方,把新建的两配置文件包含进来 - server { - listen 80 default_server; - server_name _; - return 404; - } -} diff --git a/docker_env/nginx/sites-enabled/api.conf b/docker_env/nginx/sites-enabled/api.conf deleted file mode 100644 index f198ca3..0000000 --- a/docker_env/nginx/sites-enabled/api.conf +++ /dev/null @@ -1,46 +0,0 @@ -## 将HTTP请求全部重定向至HTTPS -server { - listen 80; - server_name api.django-vue-admin.com; - charset utf-8; - access_log /var/log/nginx/api-80.access.log; - error_log /var/log/nginx/api-80.error.log; - rewrite ^(.*)$ https://${server_name}$1 permanent; -} -server { - listen 443 ssl; - server_name api.django-vue-admin.com; - root /dvadmin-backend/;#项目路径 - charset utf-8; - ssl_certificate /nginx/keys/api.django-vue-admin.com.crt;#.pem证书路径 - ssl_certificate_key /nginx/keys/api.django-vue-admin.com.key;#.key证书路径 - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - error_page 497 https://$host$request_uri; - proxy_set_header Host $proxy_host; - proxy_set_header X-DTS-SCHEMA api; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - location / { - root html/www; - include uwsgi_params; - uwsgi_pass dvadmin-django:8000; - uwsgi_param UWSGI_SCRIPT home.wsgi; - uwsgi_param UWSGI_CHDIR /dvadmin-backend/;#项目路径 - - } - # Django media - location /media { - alias /dvadmin-backend/media; # your Django project's media files - amend as required - } - # Django static - location /static { - alias /dvadmin-backend/static; # your Django project's static files - amend as required - } - - access_log /var/log/nginx/api-443.access.log; - error_log /var/log/nginx/api-443.error.log; - } diff --git a/docker_env/nginx/sites-enabled/daily.api.conf b/docker_env/nginx/sites-enabled/daily.api.conf deleted file mode 100644 index 5ccebf1..0000000 --- a/docker_env/nginx/sites-enabled/daily.api.conf +++ /dev/null @@ -1,46 +0,0 @@ -## 将HTTP请求全部重定向至HTTPS -server { - listen 80; - server_name daily.api.django-vue-admin.com; - charset utf-8; - access_log /var/log/nginx/api-80.access.log; - error_log /var/log/nginx/api-80.error.log; - rewrite ^(.*)$ https://${server_name}$1 permanent; -} -server { - listen 443 ssl; - server_name daily.api.django-vue-admin.com; - root /dvadmin-backend/;#项目路径 - charset utf-8; - ssl_certificate /nginx/keys/daily.api.django-vue-admin.com.crt;#.pem证书路径 - ssl_certificate_key /nginx/keys/daily.api.django-vue-admin.com.key;#.key证书路径 - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - error_page 497 https://$host$request_uri; - proxy_set_header Host $proxy_host; - proxy_set_header X-DTS-SCHEMA daily.api; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - location / { - root html/www; - include uwsgi_params; - uwsgi_pass dvadmin-django:8000; - uwsgi_param UWSGI_SCRIPT home.wsgi; - uwsgi_param UWSGI_CHDIR /dvadmin-backend/;#项目路径 - - } - # Django media - location /media { - alias /dvadmin-backend/media; # your Django project's media files - amend as required - } - # Django static - location /static { - alias /dvadmin-backend/static; # your Django project's static files - amend as required - } - - access_log /var/log/nginx/daily.api-443.access.log; - error_log /var/log/nginx/daily.api-443.error.log; - } diff --git a/docker_env/nginx/sites-enabled/daily.demo.conf b/docker_env/nginx/sites-enabled/daily.demo.conf deleted file mode 100644 index eeb7d03..0000000 --- a/docker_env/nginx/sites-enabled/daily.demo.conf +++ /dev/null @@ -1,44 +0,0 @@ -## 将HTTP请求全部重定向至HTTPS -server { - listen 80; - server_name daily.demo.django-vue-admin.com; - charset utf-8; - access_log /var/log/nginx/daily.demo-80.access.log; - error_log /var/log/nginx/daily.demo-80.error.log; - rewrite ^(.*)$ https://${server_name}$1 permanent; -} -server { - listen 443 ssl; - server_name daily.demo.django-vue-admin.com; - root /vadmin-doc/;#项目路径 - charset utf-8; - ssl_certificate /nginx/keys/daily.demo.django-vue-admin.com.crt;#.pem证书路径 - ssl_certificate_key /nginx/keys/daily.demo.django-vue-admin.com.key;#.key证书路径 - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - error_page 497 https://$host$request_uri; - proxy_set_header Host $proxy_host; - proxy_set_header X-DTS-SCHEMA daily.demo; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - location / { - try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404 - root /dvadmin-ui/dist/; - add_header Cache-Control max-age=no-cache; - index index.html index.php index.htm; - } - location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ { - access_log off; - add_header Cache-Control max-age=604800; - root /dvadmin-ui/dist/; - index index.html index.php index.htm; - } - location @router { - rewrite ^.*$ /index.html last; - } - access_log /var/log/nginx/daily.demo-443.access.log; - error_log /var/log/nginx/daily.demo-443.error.log; - } diff --git a/docker_env/nginx/sites-enabled/demo.conf b/docker_env/nginx/sites-enabled/demo.conf deleted file mode 100644 index a620990..0000000 --- a/docker_env/nginx/sites-enabled/demo.conf +++ /dev/null @@ -1,44 +0,0 @@ -## 将HTTP请求全部重定向至HTTPS -server { - listen 80; - server_name demo.django-vue-admin.com; - charset utf-8; - access_log /var/log/nginx/demo-80.access.log; - error_log /var/log/nginx/demo-80.error.log; - rewrite ^(.*)$ https://${server_name}$1 permanent; -} -server { - listen 443 ssl; - server_name demo.django-vue-admin.com; - root /vadmin-doc/;#项目路径 - charset utf-8; - ssl_certificate /nginx/keys/demo.django-vue-admin.com.crt;#.pem证书路径 - ssl_certificate_key /nginx/keys/demo.django-vue-admin.com.key;#.key证书路径 - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - error_page 497 https://$host$request_uri; - proxy_set_header Host $proxy_host; - proxy_set_header X-DTS-SCHEMA demo; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - location / { - try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404 - root /dvadmin-ui/dist/; - add_header Cache-Control max-age=no-cache; - index index.html index.php index.htm; - } - location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ { - access_log off; - add_header Cache-Control max-age=604800; - root /dvadmin-ui/dist/; - index index.html index.php index.htm; - } - location @router { - rewrite ^.*$ /index.html last; - } - access_log /var/log/nginx/demo-443.access.log; - error_log /var/log/nginx/demo-443.error.log; - } diff --git a/docker_env/nginx/sites-enabled/root.conf b/docker_env/nginx/sites-enabled/root.conf deleted file mode 100644 index 47dda17..0000000 --- a/docker_env/nginx/sites-enabled/root.conf +++ /dev/null @@ -1,37 +0,0 @@ -## 将HTTP请求全部重定向至HTTPS -server { - listen 80; - server_name django-vue-admin.com; - charset utf-8; - access_log /var/log/nginx/www-80.access.log; - error_log /var/log/nginx/www-80.error.log; - rewrite ^(.*)$ https://${server_name}$1 permanent; -} -server { - listen 443 ssl; - server_name django-vue-admin.com; - root /vadmin-doc/;#项目路径 - charset utf-8; - ssl_certificate /nginx/keys/www.django-vue-admin.com.crt;#.pem证书路径 - ssl_certificate_key /nginx/keys/www.django-vue-admin.com.key;#.key证书路径 - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - error_page 497 https://$host$request_uri; - proxy_set_header Host $proxy_host; - proxy_set_header X-DTS-SCHEMA www; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - location / { - try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404 - root /dvadmin-doc/docs/.vuepress/dist/; - index index.html index.php index.htm; - } - location @router { - rewrite ^.*$ /index.html last; - } - access_log /var/log/nginx/www-443.access.log; - error_log /var/log/nginx/www-443.error.log; - } diff --git a/docker_env/nginx/sites-enabled/www.conf b/docker_env/nginx/sites-enabled/www.conf deleted file mode 100644 index 67cdc59..0000000 --- a/docker_env/nginx/sites-enabled/www.conf +++ /dev/null @@ -1,37 +0,0 @@ -## 将HTTP请求全部重定向至HTTPS -server { - listen 80; - server_name www.django-vue-admin.com; - charset utf-8; - access_log /var/log/nginx/www-80.access.log; - error_log /var/log/nginx/www-80.error.log; - rewrite ^(.*)$ https://${server_name}$1 permanent; -} -server { - listen 443 ssl; - server_name www.django-vue-admin.com; - root /vadmin-doc/;#项目路径 - charset utf-8; - ssl_certificate /nginx/keys/www.django-vue-admin.com.crt;#.pem证书路径 - ssl_certificate_key /nginx/keys/www.django-vue-admin.com.key;#.key证书路径 - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - error_page 497 https://$host$request_uri; - proxy_set_header Host $proxy_host; - proxy_set_header X-DTS-SCHEMA www; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - location / { - try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404 - root /dvadmin-doc/docs/.vuepress/dist/; - index index.html index.php index.htm; - } - location @router { - rewrite ^.*$ /index.html last; - } - access_log /var/log/nginx/www-443.access.log; - error_log /var/log/nginx/www-443.error.log; - } diff --git a/docker_env/vue-doc/Dockerfile b/docker_env/vue-doc/Dockerfile deleted file mode 100644 index d99db88..0000000 --- a/docker_env/vue-doc/Dockerfile +++ /dev/null @@ -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"] diff --git a/dvadmin-backend/application/settings.py b/dvadmin-backend/application/settings.py index f2894a4..ee3fc5b 100644 --- a/dvadmin-backend/application/settings.py +++ b/dvadmin-backend/application/settings.py @@ -21,7 +21,7 @@ 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')) +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/ @@ -54,6 +54,7 @@ INSTALLED_APPS = [ ] MIDDLEWARE = [ + 'vadmin.op_drf.middleware.PermissionModeMiddleware', # 权限中间件 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -202,7 +203,7 @@ LOGGING = { 'loggers': { # default日志 '': { - 'handlers': ['console','error','file'], + 'handlers': ['console', 'error', 'file'], 'level': 'INFO', }, # 数据库相关日志 @@ -239,7 +240,6 @@ else: } } -connect(MONGO_DATABASE_NAME, host=os.getenv('MONGO_HOST') or MONGO_HOST, port=MONGO_PORT, serverSelectionTimeoutMS=1000, connect=False) # redis 缓存 REDIS_URL = f'redis://:{REDIS_PASSWORD if REDIS_PASSWORD else ""}@{os.getenv("REDIS_HOST") or REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}' CACHES = { @@ -301,24 +301,30 @@ USERNAME_FIELD = 'username' # ************** 登录验证码配置 ************** # # ================================================= # CAPTCHA_STATE = CAPTCHA_STATE -#字母验证码 -CAPTCHA_IMAGE_SIZE = (160, 60) # 设置 captcha 图片大小 -CAPTCHA_LENGTH = 4 # 字符个数 -CAPTCHA_TIMEOUT = 1 # 超时(minutes) -#加减乘除验证码 +# 字母验证码 +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_FONT_SIZE = 40 # 字体大小 CAPTCHA_FOREGROUND_COLOR = '#0033FF' # 前景色 CAPTCHA_BACKGROUND_COLOR = '#F5F7F4' # 背景色 CAPTCHA_NOISE_FUNCTIONS = ( - # 'captcha.helpers.noise_arcs', # 线 - # 'captcha.helpers.noise_dots', # 点 - ) + # '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}:{REDIS_PORT}/2' #Broker使用Redis, 使用0数据库(暂时不是很清楚原理) -CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' #Backend数据库 +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)} diff --git a/dvadmin-backend/application/urls.py b/dvadmin-backend/application/urls.py index 9ad09e0..1bd1ed6 100644 --- a/dvadmin-backend/application/urls.py +++ b/dvadmin-backend/application/urls.py @@ -22,7 +22,7 @@ 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 vadmin.utils.response import SuccessResponse class CaptchaRefresh(APIView): diff --git a/dvadmin-backend/apps/vadmin/op_drf/filters.py b/dvadmin-backend/apps/vadmin/op_drf/filters.py index ed99b93..1703e08 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/filters.py +++ b/dvadmin-backend/apps/vadmin/op_drf/filters.py @@ -10,7 +10,6 @@ from django.utils import six from mongoengine.queryset import visitor from rest_framework.filters import BaseFilterBackend, SearchFilter, OrderingFilter -from ..permission.models import Dept from ..utils.model_util import get_dept logger = logging.getLogger(__name__) @@ -119,7 +118,7 @@ class DataLevelPermissionsFilter(BaseFilterBackend): return queryset.none() # 1. 判断过滤的数据是否有创建人所在部门 "dept_belong_id" 字段 - if not hasattr(queryset.model, 'dept_belong_id'): + if not getattr(queryset.model, 'dept_belong_id', None): return queryset # 2. 如果用户没有关联角色则返回本部门数据 @@ -127,7 +126,7 @@ class DataLevelPermissionsFilter(BaseFilterBackend): return queryset.filter(dept_belong_id=user_dept_id) # 3. 根据所有角色 获取所有权限范围 - role_list = request.user.role.all().values('admin', 'dataScope') + role_list = request.user.role.filter(status='1').values('admin', 'dataScope') dataScope_list = [] for ele in role_list: # 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据 @@ -138,16 +137,15 @@ class DataLevelPermissionsFilter(BaseFilterBackend): # 4. 只为仅本人数据权限时只返回过滤本人数据,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据) if dataScope_list == ['5']: - return queryset.filter(creator=request.user, dept_belong_id=request.user.dept_id) + 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.all().values_list('dept__id', flat=True)) + 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,)) + dept_list.extend(get_dept(user_dept_id, )) return queryset.filter(dept_belong_id__in=list(set(dept_list))) - diff --git a/dvadmin-backend/apps/vadmin/op_drf/middleware.py b/dvadmin-backend/apps/vadmin/op_drf/middleware.py index ad3f98d..bf28947 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/middleware.py +++ b/dvadmin-backend/apps/vadmin/op_drf/middleware.py @@ -1,14 +1,20 @@ """ django中间件 """ +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.permission.models import Menu from apps.vadmin.system.models import OperationLog from ..utils.request_util import get_request_ip, get_request_data, get_request_path, get_browser, get_os, \ - get_login_location + get_login_location, get_request_canonical_path, get_request_user +from ..utils.response import ErrorJsonResponse + +logger = logging.getLogger(__name__) class ApiLoggingMiddleware(MiddlewareMixin): @@ -77,3 +83,78 @@ class PermissionModeMiddleware(MiddlewareMixin): """ 权限模式拦截判断 """ + + def process_request(self, request): + """ + 判断环境变量中,是否为演示模式(正常可忽略此判断) + :param request: + :return: + """ + white_list = ['/admin/logout/', '/admin/login/'] + if os.getenv('DEMO_ENV') and not request.method == 'GET' and request.path not in white_list: + return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!') + + 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: + return 30 + return -10 + + def process_view(self, request, view_func, view_args, view_kwargs): + 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 diff --git a/dvadmin-backend/apps/vadmin/op_drf/mixins.py b/dvadmin-backend/apps/vadmin/op_drf/mixins.py index 3d9b674..d081530 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/mixins.py +++ b/dvadmin-backend/apps/vadmin/op_drf/mixins.py @@ -320,12 +320,13 @@ class ImportSerializerMixin: updateSupport = request.data.get('updateSupport') # 从excel中组织对应的数据结构,然后使用序列化器保存 data = excel_to_data(request.data.get('file_url'), self.import_field_data) - unique_list = [ele.attname for ele in self.get_queryset().model._meta.get_fields() if + 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 = self.get_queryset().filter(**filter_dic).first() + instance = queryset.filter(**filter_dic).first() if instance and not updateSupport: continue if not filter_dic: @@ -357,6 +358,7 @@ class ExportSerializerMixin: "'%s' 请配置对应的导出模板字段。" % self.__class__.__name__ ) - data = self.export_serializer_class(self.get_queryset(), many=True).data + 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(self.get_queryset())}.xls')) + f'导出{get_verbose_name(queryset)}.xls')) diff --git a/dvadmin-backend/apps/vadmin/op_drf/serializers.py b/dvadmin-backend/apps/vadmin/op_drf/serializers.py index 5e47537..b642d9e 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/serializers.py +++ b/dvadmin-backend/apps/vadmin/op_drf/serializers.py @@ -20,6 +20,7 @@ class CustomModelSerializer(ModelSerializer): # 添加默认时间返回格式 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) diff --git a/dvadmin-backend/apps/vadmin/permission/models/menu.py b/dvadmin-backend/apps/vadmin/permission/models/menu.py index 67788e9..acee146 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/menu.py +++ b/dvadmin-backend/apps/vadmin/permission/models/menu.py @@ -1,4 +1,5 @@ -from django.db.models import IntegerField, ForeignKey, CharField, CASCADE +from django.core.cache import cache +from django.db.models import IntegerField, ForeignKey, CharField, CASCADE, Q from ...op_drf.models import CoreModel @@ -34,6 +35,31 @@ class Menu(CoreModel): visible = CharField(max_length=8, verbose_name="显示状态") isCache = CharField(max_length=8, verbose_name="是否缓存") + @classmethod + def get_interface_dict(cls): + """ + 获取所有接口列表 + :return: + """ + interface_dict = cache.get('permission_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')] + cache.set('permission_interface_dict', interface_dict, 84600) + return interface_dict + + @classmethod + def delete_cache(cls): + """ + 清空缓存中的接口列表 + :return: + """ + cache.delete('permission_interface_dict') + class Meta: verbose_name = '菜单管理' verbose_name_plural = verbose_name diff --git a/dvadmin-backend/apps/vadmin/permission/models/users.py b/dvadmin-backend/apps/vadmin/permission/models/users.py index 822577c..2fead2f 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/users.py +++ b/dvadmin-backend/apps/vadmin/permission/models/users.py @@ -1,6 +1,7 @@ from uuid import uuid4 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 ...op_drf.fields import CreateDateTimeField, UpdateDateTimeField @@ -28,6 +29,29 @@ class UserProfile(AbstractUser): create_datetime = CreateDateTimeField() update_datetime = UpdateDateTimeField() + @property + def get_user_interface_dict(self): + interface_dict = cache.get(f'permission_interface_dict{self.username}', {}) + 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] + cache.set(f'permission_interface_dict_{self.username}', interface_dict, 84600) + return interface_dict + + @property + def delete_cache(self): + """ + 清空缓存中的接口列表 + :return: + """ + return cache.delete(f'permission_interface_dict_{self.username}') class Meta: verbose_name = '用户管理' verbose_name_plural = verbose_name diff --git a/dvadmin-backend/apps/vadmin/permission/permissions.py b/dvadmin-backend/apps/vadmin/permission/permissions.py new file mode 100644 index 0000000..0186adb --- /dev/null +++ b/dvadmin-backend/apps/vadmin/permission/permissions.py @@ -0,0 +1,95 @@ +""" +常用的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 ..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 diff --git a/dvadmin-backend/apps/vadmin/permission/serializers.py b/dvadmin-backend/apps/vadmin/permission/serializers.py index dc820a2..f9bfaf3 100644 --- a/dvadmin-backend/apps/vadmin/permission/serializers.py +++ b/dvadmin-backend/apps/vadmin/permission/serializers.py @@ -37,6 +37,10 @@ class MenuCreateUpdateSerializer(CustomModelSerializer): # 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__' @@ -91,7 +95,7 @@ class DeptTreeSerializer(serializers.ModelSerializer): class Meta: model = Dept - fields = ('id', 'label', 'parentId') + fields = ('id', 'label', 'parentId', 'status') # ================================================= # @@ -216,7 +220,7 @@ class UserProfileSerializer(CustomModelSerializer): unread_msg_count = serializers.SerializerMethodField(read_only=True) def get_admin(self, obj: UserProfile): - role_list = obj.role.all().values_list('admin', flat=True) + role_list = obj.role.filter(status='1').values_list('admin', flat=True) if True in list(set(role_list)): return True return False @@ -261,7 +265,7 @@ class UserProfileCreateUpdateSerializer(CustomModelSerializer): }) def get_admin(self, obj: UserProfile): - role_list = obj.role.all().values_list('admin', flat=True) + role_list = obj.role.filter(status='1').values_list('admin', flat=True) if True in list(set(role_list)): return True return False diff --git a/dvadmin-backend/apps/vadmin/permission/views.py b/dvadmin-backend/apps/vadmin/permission/views.py index 9cc1218..bec3b8e 100644 --- a/dvadmin-backend/apps/vadmin/permission/views.py +++ b/dvadmin-backend/apps/vadmin/permission/views.py @@ -2,6 +2,7 @@ from django.contrib.auth import authenticate from rest_framework.request import Request from rest_framework.views import APIView +from .permissions import CommonPermission from ..op_drf.filters import DataLevelPermissionsFilter from ..op_drf.viewsets import CustomModelViewSet from ..permission.filters import MenuFilter, DeptFilter, PostFilter, RoleFilter, UserProfileFilter @@ -12,7 +13,6 @@ from ..permission.serializers import UserProfileSerializer, MenuSerializer, Role PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer, \ UserProfileImportSerializer from ..system.models import DictDetails -from ..utils.export_excel import export_excel_save_model from ..utils.response import SuccessResponse, ErrorResponse @@ -25,6 +25,7 @@ class GetUserProfileView(APIView): 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), @@ -78,9 +79,9 @@ class MenuModelViewSet(CustomModelViewSet): update_serializer_class = MenuCreateUpdateSerializer filter_class = MenuFilter extra_filter_backends = [DataLevelPermissionsFilter] - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('name',) ordering = 'create_datetime' # 默认排序 @@ -127,9 +128,9 @@ class DeptModelViewSet(CustomModelViewSet): update_serializer_class = DeptCreateUpdateSerializer filter_class = DeptFilter extra_filter_backends = [DataLevelPermissionsFilter] - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('deptName',) ordering = 'create_datetime' # 默认排序 @@ -192,23 +193,13 @@ class PostModelViewSet(CustomModelViewSet): update_serializer_class = PostCreateUpdateSerializer filter_class = PostFilter extra_filter_backends = [DataLevelPermissionsFilter] - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('postName',) ordering = ['postSort', 'create_datetime'] # 默认排序 - - def export(self, request: Request, *args, **kwargs): - """ - 导出岗位 - :param request: - :param args: - :param kwargs: - :return: - """ - field_data = ['岗位序号', '岗位编码', '岗位名称', '岗位排序', '状态', '创建者', '修改者', '备注'] - data = ExportPostSerializer(Post.objects.all(), many=True).data - return SuccessResponse(export_excel_save_model(request, field_data, data, '导出岗位数据.xls')) + export_field_data = ['岗位序号', '岗位编码', '岗位名称', '岗位排序', '状态', '创建者', '修改者', '备注'] + export_serializer_class = ExportPostSerializer class RoleModelViewSet(CustomModelViewSet): @@ -221,23 +212,13 @@ class RoleModelViewSet(CustomModelViewSet): update_serializer_class = RoleCreateUpdateSerializer filter_class = RoleFilter extra_filter_backends = [DataLevelPermissionsFilter] - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('roleName',) ordering = 'create_datetime' # 默认排序 - - def export(self, request: Request, *args, **kwargs): - """ - 导出角色 - :param request: - :param args: - :param kwargs: - :return: - """ - field_data = ['角色序号', '角色名称', '角色权限', '角色排序', '数据范围', '角色状态', '创建者', '修改者', '备注'] - data = ExportRoleSerializer(Role.objects.all(), many=True).data - return SuccessResponse(export_excel_save_model(request, field_data, data, '导出角色数据.xls')) + export_field_data = ['角色序号', '角色名称', '角色权限', '角色排序', '数据范围', '角色状态', '创建者', '修改者', '备注'] + export_serializer_class = ExportRoleSerializer class UserProfileModelViewSet(CustomModelViewSet): @@ -259,9 +240,9 @@ class UserProfileModelViewSet(CustomModelViewSet): 'gender': '用户性别(男/女/未知)', 'is_active': '帐号状态(启用/禁用)', 'password': '登录密码', 'dept': '部门ID', 'role': '角色ID', 'post': '岗位ID'} - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('username',) ordering = 'create_datetime' # 默认排序 @@ -291,8 +272,8 @@ class UserProfileModelViewSet(CustomModelViewSet): """ userId = request.query_params.get('userId') data = { - 'posts': PostSimpleSerializer(Post.objects.all().order_by('postSort'), many=True).data, - 'roles': RoleSimpleSerializer(Role.objects.all().order_by('roleSort'), many=True).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) diff --git a/dvadmin-backend/apps/vadmin/system/filters.py b/dvadmin-backend/apps/vadmin/system/filters.py index 5db8619..e91edaa 100644 --- a/dvadmin-backend/apps/vadmin/system/filters.py +++ b/dvadmin-backend/apps/vadmin/system/filters.py @@ -43,6 +43,7 @@ class SaveFileFilter(django_filters.rest_framework.FilterSet): 文件管理 简单过滤器 """ name = django_filters.CharFilter(lookup_expr='icontains') + type = django_filters.CharFilter(lookup_expr='icontains') class Meta: model = SaveFile diff --git a/dvadmin-backend/apps/vadmin/system/models/__init__.py b/dvadmin-backend/apps/vadmin/system/models/__init__.py index 51ad9c7..1c100d6 100644 --- a/dvadmin-backend/apps/vadmin/system/models/__init__.py +++ b/dvadmin-backend/apps/vadmin/system/models/__init__.py @@ -1,7 +1,6 @@ from ..models.config_settings import ConfigSettings from ..models.dict_data import DictData from ..models.dict_details import DictDetails -from ..models.web_set import WebSet from ..models.save_file import SaveFile from ..models.message_push import MessagePush from ..models.message_push import MessagePushUser diff --git a/dvadmin-backend/apps/vadmin/system/models/save_file.py b/dvadmin-backend/apps/vadmin/system/models/save_file.py index 62b077f..b43757d 100644 --- a/dvadmin-backend/apps/vadmin/system/models/save_file.py +++ b/dvadmin-backend/apps/vadmin/system/models/save_file.py @@ -16,6 +16,7 @@ class SaveFile(CoreModel): type = CharField(max_length=32, verbose_name="文件类型", null=True, blank=True) size = CharField(max_length=64, verbose_name="文件大小", null=True, blank=True) address = CharField(max_length=16, verbose_name="存储位置", null=True, blank=True) # 本地、阿里云、腾讯云.. + source = CharField(max_length=16, verbose_name="文件来源", null=True, blank=True) # 导出、用户上传. oss_url = CharField(max_length=200, verbose_name="OSS地址", null=True, blank=True) status = BooleanField(default=True, verbose_name="文件是否存在") file = FileField(verbose_name="文件URL", upload_to=files_path, ) diff --git a/dvadmin-backend/apps/vadmin/system/models/web_set.py b/dvadmin-backend/apps/vadmin/system/models/web_set.py deleted file mode 100644 index 4d09094..0000000 --- a/dvadmin-backend/apps/vadmin/system/models/web_set.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.db.models import TextField, CharField - -from ...op_drf.models import CoreModel - - -class WebSet(CoreModel): - name = CharField(max_length=64, verbose_name="站点名称") - web_site = CharField(max_length=256, verbose_name="站点网址", null=True, blank=True) - logo = CharField(max_length=256, verbose_name="网站Logo", null=True, blank=True) - record_info = TextField(verbose_name="备案信息", null=True, blank=True) - statistics_code = TextField(verbose_name="统计代码", null=True, blank=True) - copyright_info = TextField(verbose_name="版权信息", null=True, blank=True) - - class Meta: - verbose_name = '站点设置' - verbose_name_plural = verbose_name - - def __str__(self): - return f"{self.name}" diff --git a/dvadmin-backend/apps/vadmin/system/serializers.py b/dvadmin-backend/apps/vadmin/system/serializers.py index 31d01a9..bb8c6ea 100644 --- a/dvadmin-backend/apps/vadmin/system/serializers.py +++ b/dvadmin-backend/apps/vadmin/system/serializers.py @@ -1,3 +1,4 @@ +from django.core.cache import cache from rest_framework import serializers from .models import LoginInfor, OperationLog, CeleryLog @@ -79,6 +80,10 @@ class DictDetailsCreateUpdateSerializer(CustomModelSerializer): 字典详情 创建/更新时的列化器 """ + def save(self, **kwargs): + cache.delete('system_dict_details') + return super().save(**kwargs) + class Meta: model = DictDetails fields = '__all__' @@ -114,13 +119,17 @@ class ConfigSettingsCreateUpdateSerializer(CustomModelSerializer): 参数设置 创建/更新时的列化器 """ + def save(self, **kwargs): + cache.delete('system_configKey') + return super().save(**kwargs) + class Meta: model = ConfigSettings fields = '__all__' # ================================================= # -# ************** 参数设置 序列化器 ************** # +# ************** 文件管理 序列化器 ************** # # ================================================= # class SaveFileSerializer(CustomModelSerializer): @@ -136,7 +145,7 @@ class SaveFileSerializer(CustomModelSerializer): class SaveFileCreateUpdateSerializer(CustomModelSerializer): """ - 字典详情 创建/更新时的列化器 + 文件管理 创建/更新时的列化器 """ file_url = serializers.CharField(source='file.url', read_only=True) @@ -146,6 +155,7 @@ class SaveFileCreateUpdateSerializer(CustomModelSerializer): self.validated_data['size'] = files.size self.validated_data['type'] = files.content_type self.validated_data['address'] = '本地存储' + self.validated_data['source'] = '用户上传' instance = super().save(**kwargs) # 进行判断是否需要OSS上传 return instance @@ -228,7 +238,6 @@ class LoginInforSerializer(CustomModelSerializer): """ 登录日志 简单序列化器 """ - creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True) class Meta: model = LoginInfor @@ -239,7 +248,6 @@ class ExportLoginInforSerializer(CustomModelSerializer): """ 导出 登录日志 简单序列化器 """ - creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True) class Meta: model = LoginInfor @@ -255,7 +263,6 @@ class OperationLogSerializer(CustomModelSerializer): """ 操作日志 简单序列化器 """ - creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True) class Meta: model = OperationLog @@ -266,7 +273,6 @@ class ExportOperationLogSerializer(CustomModelSerializer): """ 导出 操作日志 简单序列化器 """ - creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True) class Meta: model = OperationLog diff --git a/dvadmin-backend/apps/vadmin/system/urls.py b/dvadmin-backend/apps/vadmin/system/urls.py index d275369..7084014 100644 --- a/dvadmin-backend/apps/vadmin/system/urls.py +++ b/dvadmin-backend/apps/vadmin/system/urls.py @@ -20,10 +20,14 @@ urlpatterns = [ re_path('config/configKey/(?P.*)/', ConfigSettingsModelViewSet.as_view({'get': 'get_config_key'})), # 参数管理导出 re_path('config/export/', ConfigSettingsModelViewSet.as_view({'get': 'export'})), + # 清理参数缓存 + re_path('config/clearCache/', ConfigSettingsModelViewSet.as_view({'delete': 'clearCache', })), # 导出字典管理数据 re_path('dict/type/export/', DictDataModelViewSet.as_view({'get': 'export'})), # 导出字典详情数据 re_path('dict/data/export/', DictDetailsModelViewSet.as_view({'get': 'export'})), + # 清理字典缓存 + re_path('dict/type/clearCache/', DictDetailsModelViewSet.as_view({'delete': 'clearCache', })), # 消息通知导出 re_path('message/export/', MessagePushModelViewSet.as_view({'get': 'export', })), # 用户个人消息列表 @@ -42,5 +46,8 @@ urlpatterns = [ re_path('celery_log/clean/', CeleryLogModelViewSet.as_view({'delete': 'clean_all', })), # 导出定时日志 re_path('celery_log/export/', CeleryLogModelViewSet.as_view({'get': 'export', })), + # 清除废弃文件 + re_path('clearsavefile/', SaveFileModelViewSet.as_view({'post': 'clearsavefile', })), + ] urlpatterns += router.urls diff --git a/dvadmin-backend/apps/vadmin/system/views.py b/dvadmin-backend/apps/vadmin/system/views.py index ba4ce25..a35338f 100644 --- a/dvadmin-backend/apps/vadmin/system/views.py +++ b/dvadmin-backend/apps/vadmin/system/views.py @@ -1,21 +1,27 @@ +import os + +from django.conf import settings +from django.core.cache import cache from django.db.models import Q from rest_framework.request import Request from .models import LoginInfor, OperationLog, CeleryLog from ..op_drf.filters import DataLevelPermissionsFilter from ..op_drf.viewsets import CustomModelViewSet +from ..permission.permissions import CommonPermission from ..system.filters import DictDetailsFilter, DictDataFilter, ConfigSettingsFilter, MessagePushFilter, \ SaveFileFilter, LoginInforFilter, OperationLogFilter, CeleryLogFilter from ..system.models import DictData, DictDetails, ConfigSettings, SaveFile, MessagePush from ..system.models import MessagePushUser from ..system.serializers import DictDataSerializer, DictDataCreateUpdateSerializer, DictDetailsSerializer, \ - DictDetailsCreateUpdateSerializer, DictDetailsListSerializer, ConfigSettingsSerializer, \ + DictDetailsCreateUpdateSerializer, ConfigSettingsSerializer, \ ConfigSettingsCreateUpdateSerializer, SaveFileSerializer, SaveFileCreateUpdateSerializer, \ ExportConfigSettingsSerializer, ExportDictDataSerializer, ExportDictDetailsSerializer, \ MessagePushSerializer, MessagePushCreateUpdateSerializer, ExportMessagePushSerializer, LoginInforSerializer, \ OperationLogSerializer, ExportOperationLogSerializer, ExportLoginInforSerializer, CeleryLogSerializer, \ ExportCeleryLogSerializer from ..utils.export_excel import export_excel_save_model +from ..utils.file_util import get_all_files, remove_empty_dir, delete_files from ..utils.response import SuccessResponse @@ -31,23 +37,13 @@ class DictDataModelViewSet(CustomModelViewSet): # retrieve_serializer_class = DetailRoleSerializer extra_filter_backends = [DataLevelPermissionsFilter] filter_class = DictDataFilter - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('dictName',) ordering = 'id' # 默认排序 - - def export(self, request: Request, *args, **kwargs): - """ - 导出字典管理数据 - :param request: - :param args: - :param kwargs: - :return: - """ - field_data = ['字典主键', '字典名称', '字典类型', '字典状态', '创建者', '修改者', '备注'] - data = ExportDictDataSerializer(DictData.objects.all(), many=True).data - return SuccessResponse(export_excel_save_model(request, field_data, data, '导出参数管理数据.xls')) + export_field_data = ['字典主键', '字典名称', '字典类型', '字典状态', '创建者', '修改者', '备注'] + export_serializer_class = ExportDictDataSerializer class DictDetailsModelViewSet(CustomModelViewSet): @@ -60,9 +56,9 @@ class DictDetailsModelViewSet(CustomModelViewSet): update_serializer_class = DictDetailsCreateUpdateSerializer filter_class = DictDetailsFilter extra_filter_backends = [DataLevelPermissionsFilter] - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('dictLabel',) ordering = 'sort' # 默认排序 @@ -74,11 +70,30 @@ class DictDetailsModelViewSet(CustomModelViewSet): :param kwargs: :return: """ - queryset = self.queryset.filter(dict_data__dictType=kwargs.get('pk')).order_by('sort') - if hasattr(self, 'handle_logging'): - self.handle_logging(request, *args, **kwargs) - serializer = DictDetailsListSerializer(queryset, many=True) - return SuccessResponse(serializer.data) + dict_details_dic = cache.get('system_dict_details', {}) + if not dict_details_dic: + queryset = self.filter_queryset(self.get_queryset()) + queryset_dic = queryset.order_by('sort').values('dict_data__dictType', 'dictLabel', 'dictValue', + 'is_default') + for ele in queryset_dic: + dictType = ele.pop('dict_data__dictType') + if dictType in dict_details_dic: + dict_details_dic[dictType].append(ele) + else: + dict_details_dic[dictType] = [ele] + cache.set('system_dict_details', dict_details_dic, 84600) + return SuccessResponse(dict_details_dic.get(kwargs.get('pk'), [])) + + def clearCache(self, request: Request, *args, **kwargs): + """ + 清理键值缓存 + :param request: + :param args: + :param kwargs: + :return: + """ + cache.delete('system_dict_details') + return SuccessResponse(msg='清理成功!') def export(self, request: Request, *args, **kwargs): """ @@ -103,12 +118,14 @@ class ConfigSettingsModelViewSet(CustomModelViewSet): create_serializer_class = ConfigSettingsCreateUpdateSerializer update_serializer_class = ConfigSettingsCreateUpdateSerializer filter_class = ConfigSettingsFilter - extra_filter_backends = [DataLevelPermissionsFilter] - # update_extra_permission_classes = (IsManagerPermission,) - # destroy_extra_permission_classes = (IsManagerPermission,) - # create_extra_permission_classes = (IsManagerPermission,) search_fields = ('configName',) ordering = 'id' # 默认排序 + extra_filter_backends = [DataLevelPermissionsFilter] + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) + export_field_data = ['参数主键', '参数名称', '参数键名', '参数键值', '系统内置', '参数状态', '创建者', '修改者', '备注'] + export_serializer_class = ExportConfigSettingsSerializer def get_config_key(self, request: Request, *args, **kwargs): """ @@ -118,22 +135,24 @@ class ConfigSettingsModelViewSet(CustomModelViewSet): :param kwargs: :return: """ - queryset = self.queryset.filter(configKey=kwargs.get('pk')).first() - # if hasattr(self, 'handle_logging'): - # self.handle_logging(request, *args, **kwargs) - return SuccessResponse(msg=queryset.configValue if queryset else '') + config_key_dic = cache.get('system_configKey') + if not config_key_dic: + queryset = self.filter_queryset(self.get_queryset()) + config_key_dic = {ele.get('configKey'): ele.get('configValue') for ele in + queryset.values('configValue', 'configKey')} + cache.set('system_configKey', config_key_dic, 84600) + return SuccessResponse(msg=config_key_dic.get(kwargs.get('pk'), '')) - def export(self, request: Request, *args, **kwargs): + def clearCache(self, request: Request, *args, **kwargs): """ - 导出参数管理数据 + 清理键值缓存 :param request: :param args: :param kwargs: :return: """ - field_data = ['参数主键', '参数名称', '参数键名', '参数键值', '系统内置', '参数状态', '创建者', '修改者', '备注'] - data = ExportConfigSettingsSerializer(ConfigSettings.objects.all(), many=True).data - return SuccessResponse(export_excel_save_model(request, field_data, data, '导出参数管理数据.xls')) + cache.delete('system_configKey') + return SuccessResponse(msg='清理成功!') class SaveFileModelViewSet(CustomModelViewSet): @@ -146,9 +165,32 @@ class SaveFileModelViewSet(CustomModelViewSet): update_serializer_class = SaveFileCreateUpdateSerializer filter_class = SaveFileFilter extra_filter_backends = [DataLevelPermissionsFilter] + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) search_fields = ('configName',) ordering = '-create_datetime' # 默认排序 + def clearsavefile(self, request: Request, *args, **kwargs): + """ + 清理废弃文件 + :param request: + :param args: + :param kwargs: + :return: + """ + # 获取废弃文件列表 + file_list = get_all_files(os.path.join(settings.MEDIA_ROOT, 'system')) + queryset_files = [os.path.join(os.path.join(settings.MEDIA_ROOT) + os.sep, ele) for ele in + list(self.get_queryset().values_list('file', flat=True))] + + delete_list = list(set(file_list) - set(queryset_files)) + # 进行文件删除操作 + delete_files(delete_list) + # 递归删除空文件 + remove_empty_dir(os.path.join(settings.MEDIA_ROOT, 'system')) + return SuccessResponse(msg=f"成功清理废弃文件{len(delete_list)}个") + class MessagePushModelViewSet(CustomModelViewSet): """ @@ -159,8 +201,14 @@ class MessagePushModelViewSet(CustomModelViewSet): create_serializer_class = MessagePushCreateUpdateSerializer update_serializer_class = MessagePushCreateUpdateSerializer extra_filter_backends = [DataLevelPermissionsFilter] + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) filter_class = MessagePushFilter ordering = "-update_datetime" # 默认排序 + export_field_data = ['消息序号', '标题', '内容', '消息类型', '是否审核', '消息状态', '通知接收消息用户', + '创建者', '修改者', '修改时间', '创建时间'] + export_serializer_class = ExportMessagePushSerializer def get_user_messages(self, request: Request, *args, **kwargs): """ @@ -170,11 +218,12 @@ class MessagePushModelViewSet(CustomModelViewSet): is_read = request.query_params.get('is_read', None) if is_read: if is_read == 'False': - queryset = queryset.filter(Q(messagepushuser_message_push__is_read=is_read) | Q(user=None)) - else: - queryset = queryset.filter(messagepushuser_message_push__is_read=is_read) - - queryset = queryset.filter(is_reviewed=True) + queryset = queryset.exclude(Q(messagepushuser_message_push__is_read=True), + Q(messagepushuser_message_push__user=request.user)) + elif is_read == 'True': + queryset = queryset.filter(messagepushuser_message_push__is_read=True, + messagepushuser_message_push__user=request.user) + queryset = queryset.filter(is_reviewed=True).distinct() page = self.paginate_queryset(queryset) if hasattr(self, 'handle_logging'): self.handle_logging(request, *args, **kwargs) @@ -197,18 +246,6 @@ class MessagePushModelViewSet(CustomModelViewSet): instance.save() return SuccessResponse() - def export(self, request: Request, *args, **kwargs): - """ - 导出岗位 - :param request: - :param args: - :param kwargs: - :return: - """ - field_data = ['消息序号', '标题', '内容', '消息类型', '是否审核', '消息状态', '通知接收消息用户', '创建者', '修改者', '修改时间', '创建时间'] - data = ExportMessagePushSerializer(MessagePush.objects.all(), many=True).data - return SuccessResponse(export_excel_save_model(request, field_data, data, '导出岗位数据.xls')) - class LoginInforModelViewSet(CustomModelViewSet): """ @@ -218,6 +255,9 @@ class LoginInforModelViewSet(CustomModelViewSet): serializer_class = LoginInforSerializer filter_class = LoginInforFilter extra_filter_backends = [DataLevelPermissionsFilter] + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) ordering = '-create_datetime' # 默认排序 export_field_data = ['访问编号', '用户名称', '登录地址', '登录地点', '浏览器', '操作系统', '登录状态', '操作信息', '登录日期'] @@ -243,6 +283,9 @@ class OperationLogModelViewSet(CustomModelViewSet): serializer_class = OperationLogSerializer filter_class = OperationLogFilter extra_filter_backends = [DataLevelPermissionsFilter] + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) ordering = '-create_datetime' # 默认排序 export_field_data = ['请求模块', '请求地址', '请求参数', '请求方式', '操作说明', '请求ip地址', '请求浏览器', '响应状态码', '操作地点', '操作系统', '返回信息', '响应状态', '操作用户名'] @@ -266,6 +309,10 @@ class CeleryLogModelViewSet(CustomModelViewSet): """ queryset = CeleryLog.objects.all() serializer_class = CeleryLogSerializer + extra_filter_backends = [DataLevelPermissionsFilter] + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) filter_class = CeleryLogFilter ordering = '-create_datetime' # 默认排序 export_field_data = ['任务名称', '执行参数', '执行时间', '运行状态', '任务结果', '创建时间'] diff --git a/dvadmin-backend/apps/vadmin/urls.py b/dvadmin-backend/apps/vadmin/urls.py index 093e65d..cf4051d 100644 --- a/dvadmin-backend/apps/vadmin/urls.py +++ b/dvadmin-backend/apps/vadmin/urls.py @@ -22,9 +22,9 @@ from django.urls import re_path, include from rest_framework.documentation import include_docs_urls from rest_framework.views import APIView -from .op_drf.response import SuccessResponse from .permission.views import GetUserProfileView, GetRouters from .utils.login import LoginView, LogoutView +from .utils.response import SuccessResponse class CaptchaRefresh(APIView): diff --git a/dvadmin-backend/apps/vadmin/utils/export_excel.py b/dvadmin-backend/apps/vadmin/utils/export_excel.py index c6484bd..eda0567 100644 --- a/dvadmin-backend/apps/vadmin/utils/export_excel.py +++ b/dvadmin-backend/apps/vadmin/utils/export_excel.py @@ -134,7 +134,9 @@ def export_excel_save_model(request, field_data, data, FilName): savefile.type = 'application/vnd.ms-excel' savefile.size = os.path.getsize(os.path.join(settings.MEDIA_ROOT, file_rul)) savefile.address = '本地存储' + savefile.source = '导出' savefile.creator = request.user + savefile.dept_belong_id = getattr(request.user, 'dept_id', None) savefile.modifier = request.user.username savefile.save() return SaveFileSerializer(savefile).data diff --git a/dvadmin-backend/apps/vadmin/utils/file_util.py b/dvadmin-backend/apps/vadmin/utils/file_util.py new file mode 100644 index 0000000..1a3cdca --- /dev/null +++ b/dvadmin-backend/apps/vadmin/utils/file_util.py @@ -0,0 +1,48 @@ +""" +封装文件操作: + ● 递归读取所有文件目录形成列表 + ● 递归删除空目录 + ● 批量删除文件 +""" +import os + + +def get_all_files(targetDir): + """ + 递归读取所有文件目录形成列表 + :param targetDir: + :return: + """ + files = [] + listFiles = os.listdir(targetDir) + for i in range(0, len(listFiles)): + path = os.path.join(targetDir, listFiles[i]) + if os.path.isdir(path): + files.extend(get_all_files(path)) + elif os.path.isfile(path): + files.append(path) + return files + + +def remove_empty_dir(path): + """ + 递归删除空目录 + :param path: + :return: + """ + for root, dirs, files in os.walk(path, topdown=False): + if not files and not dirs: + os.rmdir(root) + + +def delete_files(delete_list: list): + """ + 批量删除文件 + :param delete_list: + :return: + """ + for file_path in delete_list: + try: + os.remove(file_path) + except(FileNotFoundError): + pass diff --git a/dvadmin-backend/apps/vadmin/utils/request_util.py b/dvadmin-backend/apps/vadmin/utils/request_util.py index 374499b..6952cf0 100644 --- a/dvadmin-backend/apps/vadmin/utils/request_util.py +++ b/dvadmin-backend/apps/vadmin/utils/request_util.py @@ -8,10 +8,10 @@ from django.contrib.auth.models import AbstractBaseUser from django.contrib.auth.models import AnonymousUser from django.core.cache import cache from django.urls.resolvers import ResolverMatch -from rest_framework.authentication import BaseAuthentication -from rest_framework.settings import api_settings as drf_settings from user_agents import parse +from apps.vadmin.utils.authentication import OpAuthJwtAuthentication + logger = logging.getLogger(__name__) @@ -26,18 +26,8 @@ def get_request_user(request, authenticate=True): user: AbstractBaseUser = getattr(request, 'user', None) if user and user.is_authenticated: return user - authentication: BaseAuthentication = None - for authentication_class in drf_settings.DEFAULT_AUTHENTICATION_CLASSES: - try: - authentication = authentication_class() - user_auth_tuple = authentication.authenticate(request) - if user_auth_tuple is not None: - user, token = user_auth_tuple - if authenticate: - request.user = user - return user - except Exception: - pass + user, tokrn = OpAuthJwtAuthentication().authenticate(request) + print(22, user) return user or AnonymousUser() @@ -127,9 +117,11 @@ def get_request_canonical_path(request, *args, **kwargs): for value in resolver_match.args: path = path.replace(f"/{value}", "/{id}") for key, value in resolver_match.kwargs.items(): - path = path.replace(f"/{value}", f"/{{{key}}}") if key == 'pk': - pass + path = path.replace(f"/{value}", f"/{{id}}") + continue + path = path.replace(f"/{value}", f"/{{{key}}}") + return path @@ -182,7 +174,7 @@ def get_login_location(request, *args, **kwargs): r = requests.get(apiurl) content = r.content.decode('GBK') location = str(content).replace('\r', '').replace('\n', '')[:64] - cache.set(request_ip, location, 8640) + cache.set(request_ip, location, 86400) return location except Exception as e: pass diff --git a/dvadmin-backend/apps/vadmin/utils/response.py b/dvadmin-backend/apps/vadmin/utils/response.py index 4a0bbe7..ccfb35d 100644 --- a/dvadmin-backend/apps/vadmin/utils/response.py +++ b/dvadmin-backend/apps/vadmin/utils/response.py @@ -1,7 +1,7 @@ """ 常用的Response以及Django的Response、DRF的Response """ -from django.http.response import DjangoJSONEncoder +from django.http.response import DjangoJSONEncoder, JsonResponse from rest_framework.response import Response @@ -56,3 +56,36 @@ class ErrorResponse(Response): 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) diff --git a/dvadmin-backend/conf/env.example.py b/dvadmin-backend/conf/env.example.py index 9f5a203..be45875 100644 --- a/dvadmin-backend/conf/env.example.py +++ b/dvadmin-backend/conf/env.example.py @@ -15,13 +15,6 @@ DATABASE_PASSWORD = "q1w2e3r4T%Y^U&MYSQL" # 数据库名 DATABASE_NAME = "django-vue-admin" -# ================================================= # -# ************** mongodb 数据库配置 ************** # -# ================================================= # -MONGO_DATABASE_NAME = 'django-vue-admin' -MONGO_HOST = 'localhost' -MONGO_PORT = 27017 - # ================================================= # # ************** redis 数据库配置 ************** # # ================================================= # @@ -29,6 +22,8 @@ REDIS_DB = 1 REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379 REDIS_PASSWORD = 'q1w2e3r4T%Y^U&' +# celery 定时任务redis 库号 +CELERY_DB = 2 # ================================================= # # ************** 默认配置 ************** # @@ -44,3 +39,5 @@ CAPTCHA_STATE = True # 操作日志配置 API_LOG_ENABLE = True API_LOG_METHODS = ['POST', 'DELETE', 'PUT'] # 'ALL' or ['POST', 'DELETE'] +# 接口权限 +INTERFACE_PERMISSION = True diff --git a/dvadmin-backend/requirements.txt b/dvadmin-backend/requirements.txt index e6f6139..5e06ebc 100644 --- a/dvadmin-backend/requirements.txt +++ b/dvadmin-backend/requirements.txt @@ -1,4 +1,5 @@ asgiref==3.3.1 +celery==5.0.5 Django==2.2.16 django-cors-headers==3.7.0 django_celery_beat==2.2.0 diff --git a/dvadmin-doc/docs/.vuepress/config.js b/dvadmin-doc/docs/.vuepress/config.js deleted file mode 100644 index 6afea8c..0000000 --- a/dvadmin-doc/docs/.vuepress/config.js +++ /dev/null @@ -1,47 +0,0 @@ -module.exports = { - title: 'Django-Vue-Admin', - base: '/', - head: [ - [ - 'link', // 设置 favicon.ico,注意图片放在 public 文件夹下 - { rel: 'icon', href: '/logo.png' } - ] - ], - description: '', - themeConfig: { - logo: '/logo.png', - nav: [ - { text: '在线文档', link: '/document/' }, - { text: '关于我们', link: '/about/' }, - { text: '在线体验', link: 'https://demo.django-vue-admin.com/' }, - { text: 'Gitee', link: 'https://gitee.com/liqianglog/django-vue-admin' }, - { text: 'Github', link: 'https://github.com/liqianglog/django-vue-admin' }, - ], - sidebar: [ - { - title: '文档', // 必要的 - // path: '/document/', // 可选的, 标题的跳转链接,应为绝对路径且必须存在 - collapsable: false, // 可选的, 默认值是 true, - sidebarDepth: 1, // 可选的, 默认值是 1 - children: [ - '/document/', - '/document/kslj', - '/document/hjbs', - '/document/web', - '/document/server', - '/document/gxrz', - ] - }, - { - title: '其他', - children: [ - '/other/cjwt', - '/other/jzzc', - ], - collapsable: false, - sidebarDepth: 1, - initialOpenGroupIndex: -1 // 可选的, 默认值是 0 - } - ] - } -} diff --git a/dvadmin-doc/docs/.vuepress/public/logo.jpg b/dvadmin-doc/docs/.vuepress/public/logo.jpg deleted file mode 100644 index d504f9149791032b25bcfe285cd6285a98118159..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175155 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%0A;+nwYD##nn4B-Nwe*oVhmH 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 - diff --git a/dvadmin-doc/docs/other/cjwt.md b/dvadmin-doc/docs/other/cjwt.md deleted file mode 100644 index b43101d..0000000 --- a/dvadmin-doc/docs/other/cjwt.md +++ /dev/null @@ -1 +0,0 @@ -# 常见问题 diff --git a/dvadmin-doc/docs/other/jzzc.md b/dvadmin-doc/docs/other/jzzc.md deleted file mode 100644 index bdb7e98..0000000 --- a/dvadmin-doc/docs/other/jzzc.md +++ /dev/null @@ -1 +0,0 @@ -# 捐赠支持 diff --git a/dvadmin-doc/package.json b/dvadmin-doc/package.json deleted file mode 100644 index 8367e44..0000000 --- a/dvadmin-doc/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "django-vue-admin-doc", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "docs:dev": "vuepress dev docs", - "docs:build": "vuepress build docs" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "vuepress": "^1.8.2" - } -} diff --git a/dvadmin-ui/package.json b/dvadmin-ui/package.json index 2637669..beaf7ec 100755 --- a/dvadmin-ui/package.json +++ b/dvadmin-ui/package.json @@ -79,8 +79,8 @@ "vue-template-compiler": "2.6.12" }, "engines": { - "node": ">=8.9", - "npm": ">= 3.0.0" + "node": ">=12.0", + "npm": ">= 6.0.0" }, "browserslist": [ "> 1%", diff --git a/dvadmin-ui/src/api/vadmin/permission/dept.js b/dvadmin-ui/src/api/vadmin/permission/dept.js index 2366951..17918b1 100755 --- a/dvadmin-ui/src/api/vadmin/permission/dept.js +++ b/dvadmin-ui/src/api/vadmin/permission/dept.js @@ -28,7 +28,7 @@ export function getDept(deptId) { // 查询部门下拉树结构 export function treeselect() { return request({ - url: '/admin/permission/dept/treeselect/', + url: '/admin/permission/dept/treeselect/?status=1', method: 'get' }) } @@ -36,7 +36,7 @@ export function treeselect() { // 根据角色ID查询部门树结构 export function roleDeptTreeselect(roleId) { return request({ - url: '/admin/permission/dept/roleDeptTreeselect/' + roleId + '/', + url: '/admin/permission/dept/roleDeptTreeselect/' + roleId + '/?status=1', method: 'get' }) } diff --git a/dvadmin-ui/src/api/vadmin/permission/menu.js b/dvadmin-ui/src/api/vadmin/permission/menu.js index 6da7ad5..cd1cceb 100755 --- a/dvadmin-ui/src/api/vadmin/permission/menu.js +++ b/dvadmin-ui/src/api/vadmin/permission/menu.js @@ -20,7 +20,7 @@ export function getMenu(menuId) { // 查询菜单下拉树结构 export function treeselect() { return request({ - url: '/admin/permission/menus/treeselect/', + url: '/admin/permission/menus/treeselect/?status=1', method: 'get' }) } @@ -28,7 +28,7 @@ export function treeselect() { // 根据角色ID查询菜单下拉树结构 export function roleMenuTreeselect(roleId) { return request({ - url: '/admin/permission/menus/roleMenuTreeselect/' + roleId + '/', + url: '/admin/permission/menus/roleMenuTreeselect/' + roleId + '/?status=1', method: 'get' }) } diff --git a/dvadmin-ui/src/api/vadmin/system/config.js b/dvadmin-ui/src/api/vadmin/system/config.js index 456c46c..beaf681 100755 --- a/dvadmin-ui/src/api/vadmin/system/config.js +++ b/dvadmin-ui/src/api/vadmin/system/config.js @@ -20,7 +20,7 @@ export function getConfig(configId) { // 根据参数键名查询参数值 export function getConfigKey(configKey) { return request({ - url: '/admin/system/config/configKey/' + configKey + '/', + url: '/admin/system/config/configKey/' + configKey + '/?status=1', method: 'get' }) } diff --git a/dvadmin-ui/src/api/vadmin/system/dict/data.js b/dvadmin-ui/src/api/vadmin/system/dict/data.js index 96d5e76..cdbef01 100755 --- a/dvadmin-ui/src/api/vadmin/system/dict/data.js +++ b/dvadmin-ui/src/api/vadmin/system/dict/data.js @@ -20,7 +20,7 @@ export function getData(dictCode) { // 根据字典类型查询字典数据信息 export function getDicts(dictType) { return request({ - url: '/admin/system/dict/get/type/' + dictType + '/', + url: '/admin/system/dict/get/type/' + dictType + '/?status=1', method: 'get' }) } diff --git a/dvadmin-ui/src/components/CommonStaticTable/index.vue b/dvadmin-ui/src/components/CommonStaticTable/index.vue deleted file mode 100644 index fe92660..0000000 --- a/dvadmin-ui/src/components/CommonStaticTable/index.vue +++ /dev/null @@ -1,465 +0,0 @@ - - - - - diff --git a/dvadmin-ui/src/components/FileUpload/index.vue b/dvadmin-ui/src/components/FileUpload/index.vue index 8447bca..32bce09 100755 --- a/dvadmin-ui/src/components/FileUpload/index.vue +++ b/dvadmin-ui/src/components/FileUpload/index.vue @@ -39,9 +39,9 @@ + +