diff --git a/README.md b/README.md index a289e48..ddc3105 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,27 @@ celery -A backend flower --port=5555 --basic_auth=admin:admin123 将 `VITE_OSS_ENABLED` 设置为 `false` 或删除相关配置即可。 +## 演示环境配置 + +### 启用演示模式 + +在 `docker/.env.prod` 中设置: + +```env +DEMO_MODE=true +``` + +演示模式下: +- 全局禁止所有修改和删除操作(POST、PUT、PATCH、DELETE) +- 只允许登录、登出等基础操作 +- 所有修改/删除请求将返回 403 错误 +- **禁用 Django Admin 后台管理界面** +- 适用于在线演示,防止数据被误操作 + +### 禁用演示模式 + +将 `DEMO_MODE` 设置为 `false` 或删除该配置即可正常使用所有功能,包括 Admin 后台。 + --- # 技术架构 diff --git a/backend/backend/settings.py b/backend/backend/settings.py index b5f9396..1fb84f2 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -25,6 +25,9 @@ SECRET_KEY = 'django-insecure-m4@pv814c_m^pgpyhz^i96a@mcqh_@m9ccu(17*895t!79e!nb # SECURITY WARNING: don't run with debug turned on in production! DEBUG = os.getenv('DEBUG', 'False') == 'True' +# 演示环境配置 +DEMO_MODE = os.getenv('DEMO_MODE', 'False') == 'False' + ALLOWED_HOSTS = [ '*', ] @@ -64,6 +67,10 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +# 演示环境中间件 - 全局禁止修改和删除操作 +if DEMO_MODE: + MIDDLEWARE.append('utils.middleware.DemoModeMiddleware') + AUTH_USER_MODEL = 'system.User' ROOT_URLCONF = 'backend.urls' diff --git a/backend/backend/urls.py b/backend/backend/urls.py index 99291cf..04d3763 100644 --- a/backend/backend/urls.py +++ b/backend/backend/urls.py @@ -16,8 +16,12 @@ Including another URLconf """ from django.contrib import admin from django.urls import path, include +from django.conf import settings urlpatterns = [ - path('admin/', admin.site.urls), path('api/system/', include('system.urls')), ] + +# 演示环境下禁用 admin 路由 +if not settings.DEMO_MODE: + urlpatterns.insert(0, path('admin/', admin.site.urls)) diff --git a/backend/utils/middleware.py b/backend/utils/middleware.py new file mode 100644 index 0000000..f620b88 --- /dev/null +++ b/backend/utils/middleware.py @@ -0,0 +1,43 @@ +import json +from django.http import JsonResponse +from django.utils.deprecation import MiddlewareMixin +from rest_framework import status + + +class DemoModeMiddleware(MiddlewareMixin): + """ + 演示环境中间件 + 全局禁止修改和删除操作 + """ + + def process_request(self, request): + # 只处理 API 请求 + if not request.path.startswith('/api/'): + return None + + # 禁止的 HTTP 方法 + forbidden_methods = ['POST', 'PUT', 'PATCH', 'DELETE'] + + if request.method in forbidden_methods: + # 检查是否是登录接口,登录接口允许 POST + if request.path.endswith('/login/') or request.path.endswith('/auth/login/'): + return None + + # 检查是否是登出接口,登出接口允许 POST + if request.path.endswith('/logout/') or request.path.endswith('/auth/logout/'): + return None + + # 其他修改/删除操作一律禁止 + response_data = { + 'code': 403, + 'message': '演示环境禁止修改和删除操作', + 'data': None + } + + return JsonResponse( + response_data, + status=status.HTTP_403_FORBIDDEN, + content_type='application/json' + ) + + return None \ No newline at end of file diff --git a/docker/.env.dev b/docker/.env.dev index 0c74022..e897506 100644 --- a/docker/.env.dev +++ b/docker/.env.dev @@ -7,7 +7,8 @@ MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=58ce16c2ee80311e130b30f11160ef77e0ac6aa7 # Django -DEBUG=False +DEBUG=True +DEMO_MODE=False DJANGO_ALLOWED_HOSTS=* DB_NAME=django_vue DB_USER=root diff --git a/docker/.env.example b/docker/.env.example index 9fa3aa1..8d22869 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -17,7 +17,8 @@ MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=58ce16c2ee80311e130b30f11160ef77e0ac6aa7 # Django -DEBUG=False +DEBUG=True +DEMO_MODE=False DJANGO_ALLOWED_HOSTS=* DB_NAME=django_vue DB_USER=root diff --git a/docker/.env.prod b/docker/.env.prod index f93d27a..e9e63c4 100644 --- a/docker/.env.prod +++ b/docker/.env.prod @@ -10,6 +10,7 @@ MYSQL_ROOT_PASSWORD=58ce16c2ee80311e130b30f11160ef77e0ac6aa7 # Django DEBUG=False +DEMO_MODE=False DJANGO_ALLOWED_HOSTS=* DB_NAME=django_vue DB_USER=root diff --git a/web/apps/web-antd/src/views/_core/authentication/login.vue b/web/apps/web-antd/src/views/_core/authentication/login.vue index 8bcc45d..ab1bc8a 100644 --- a/web/apps/web-antd/src/views/_core/authentication/login.vue +++ b/web/apps/web-antd/src/views/_core/authentication/login.vue @@ -16,10 +16,6 @@ const authStore = useAuthStore(); const MOCK_USER_OPTIONS: BasicOption[] = [ { label: 'Super', - value: 'vben', - }, - { - label: 'Admin', value: 'admin', }, {