- git 初始化 + .gitignore 补全(根 .env / logs / instance / __pycache__ 等) - 修复 utils/.gitignore 误将整个 utils/ 源码层忽略的问题,补入全部工具源码(含 ip2region.xdb) - 含后端全部代码:application / extensions / utils / config / migrations - 含前端 ui/(后续整体迁走) - 不含根 .env(含密钥,本地保留) Co-Authored-By: Claude <noreply@anthropic.com>
9.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
DjangoAdmin Flask+EleVue is a separated frontend-backend admin framework. Backend: Flask + SQLAlchemy + MySQL + Redis. Frontend: Vue 3 + Element Plus + TypeScript + Vite + Pinia. The project is primarily documented and commented in Chinese.
Development Commands
Backend (Python/Flask)
# Install dependencies
pip install -r requirements.txt
# Run dev server (default: 127.0.0.1:8021)
python app.py
# Database migrations (Flask-Migrate/Alembic)
flask db init # Initialize migration repository (already done)
flask db migrate # Generate migration from model changes
flask db upgrade # Apply migrations
flask db downgrade # Rollback migration
Frontend (Vue 3 / ui/)
cd ui
# Install dependencies (uses pnpm)
pnpm install
# Run dev server (default: localhost:8001, proxies /api to backend :8021)
pnpm run dev
# Build for production
pnpm run build:prod
# Lint
pnpm run lint:eslint
pnpm run lint:prettier
pnpm run lint:stylelint
# Type check
pnpm run type:check
Docker
cd docker
docker-compose up -d
Architecture
Backend Structure (Three-Layer Pattern)
Each business module follows a strict View -> Service -> Model separation:
application/views/— Route controllers (Flask Blueprint). Each file defines routes using@{module}_blue.route(), decorated with@check_permission("sys:module:action"). Views are thin — they delegate to service functions and returnR.ok()/R.failed()responses. Write operations checkFLASK_DEMOfirst to block demo-mode writes.application/services/— Business logic layer. Contains all query building, data transformation, and orchestration. Functions receive data fromrequestobject directly (not passed as parameters from views). Private helpers prefixed with_(e.g.,_apply_filters,_build_page_data).application/models/— SQLAlchemy models. All models inherit fromBaseModel(provides id, create_user, create_time, update_user, update_time, is_delete fields) andBaseDB(provides save(), save_all(), delete() methods). Table names useDB_PREFIX(defaultflask_) + snake_case class name.
AOP Transaction Management
The framework uses an AOP-style transaction interceptor (application/middleware/transaction.py) registered via register_transaction(app). Business code never calls commit/rollback directly.
before_request: marks transaction activeafter_request: auto-commits on POST/PUT/DELETE/PATCH only if HTTP 2xx ANDcode==0in response JSON; auto-rollbacks on business failures (R.failedreturns HTTP 200 butcode=1)teardown_request: rollback on unhandled exceptions
BaseDB.save() and BaseDB.save_all() call db.session.flush() only — the AOP interceptor handles commit. For special cases, use @transactional decorator, @transactional_response decorator, or TransactionContext context manager.
Key Backend Modules
application/__init__.py— App factory (create_app()). Initialization order: Flask core -> Redis config -> DB config -> JSON encoder -> CORS -> ProxyFix -> AOP transaction -> register blueprints -> init extensions -> register middleware.application/views/__init__.py— Auto-discovery blueprint registration. Add module name to_blueprint_moduleslist; the system dynamically imports the module and registers anyBlueprintinstance found in it. No manualapp.register_blueprint()needed.application/middleware/—check_login(before_request hook, JWT validation with token blacklist, whitelist matching via exact/prefix/wildcard patterns) andcheck_permission(RBAC decorator; superadmin user_id=1 bypasses all checks; internal calls via API key or IP whitelist also bypass).application/forms/— WTForms validation forms. All inheritBaseForm(informs/forms.py) which handlesArrayFieldJSON serialization. Forms are instantiated withdata=json_datafrom parsed request body.application/constants/— Shared constants:PAGE_SIZE=10,DEFAULT_PASSWORD="123456",MESSAGE_OK/FAIL,SERIALIZE_EXCLUDE_FIELDS(is_delete, password, salt excluded fromto_dict()).config/— Split intobase.py(Flask host/port/debug/paths),database.py(SQLAlchemy URI, SSL options),redis.py(Redis URL),auth.py(JWT salt, permission toggle, login whitelist, internal API key). All read from.envvia python-dotenv.config/__init__.pyloads.envbefore any sub-module imports.extensions/— Flask extension initialization: SQLAlchemy (db), Redis, APScheduler. All initialized viaregister_extends(app).utils/—R(standardized JSON response:{code, data, msg, ok}where code=0 is success, code=1 is failure),jwt(JWT token handling with blacklist),model_utils(models_to_list, model_to_dict, format_datetime),request(parse_request_body, parse_id_list),security(get_user_id, get_username from JWT),case_converter(camelCase <-> snake_case for dict keys, recursive),regular(WTForms error extraction),password(bcrypt-based encrypt/verify — imported asfrom utils import passwordthen used asbcrypt.verify_password()etc.),captcha,file,content(rich text + file URL handling),redis_client,ip,user_agent,formatter,json.
Frontend Structure (ui/src/)
api/— Axios API calls organized by module. Each function useshttp.request()fromutils/http/axios/. The HTTP client auto-prependsVITE_GLOB_API_URL_PREFIX(/api) and sends JWT asAuthorization: Bearer <token>.views/— Page components matching backend modules (system, content, monitor, etc.).router/— Vue Router with dynamic route generation from backend menu data.generator-routers.tstransforms backend menu tree into Vue Router routes;asyncImportRouteusesimport.meta.glob('../views/**/*.{vue,tsx}')for lazy loading.store/— Pinia stores:user(auth state),asyncRoute(dynamic routes),projectSetting,tabsView,lockscreen,ossConfig.components/— Reusable UI components.layout/— Main layout shell (sidebar, header, content area).hooks/— Composable functions.utils/— Frontend utilities (HTTP client with interceptors, date formatting, etc.).
API Conventions
- Backend routes follow RESTful patterns:
GET /{module}/page,GET /{module}/detail/<id>,POST /{module}/add,PUT /{module}/update,DELETE /{module}/delete/<id>,PUT /{module}/status,GET /{module}/list - All responses use
R.ok(data=...)/R.failed(msg=...)format with{code, data, msg, ok}structure - Frontend response handler checks
code === 0for success;code=401triggers re-login - Permission strings follow pattern:
sys:module:action(e.g.,sys:user:page,sys:role:add) - Frontend proxies
/apiprefix to backend via Vite dev server proxy (configured inui/.env.developmentasVITE_PROXY=[["/api","http://127.0.0.1:8021/"]])
Naming Conventions
- Backend service functions: snake_case (e.g.,
get_user_page,add_user) - Backend model tables:
flask_prefix + snake_case (e.g.,flask_user,flask_role) - Service layer uses camelCase for parameters/return keys (matching frontend), snake_case for DB fields
- Private service functions prefixed with
_(e.g.,_apply_filters,_build_page_data) BaseModel.__init__auto-converts camelCase kwargs to snake_case and filters to valid model columns onlyto_dict()returns snake_case keys; services useconvert_snake_to_camelwhen frontend needs camelCase
Adding a New Module
- Create model in
application/models/{module}.pyinheritingBaseModel+BaseDB - Create service in
application/services/{module}.pywith business logic - Create view in
application/views/{module}.pywith routes and permission decorators - Add module name string to
_blueprint_moduleslist inapplication/views/__init__.py - Create form in
application/forms/{module}.pyinheritingBaseFormif input validation needed - Add frontend API in
ui/src/api/{module}/, views inui/src/views/{module}/
Environment Configuration
All config is in .env at project root. Key settings:
FLASK_HOST/FLASK_PORT(default 127.0.0.1:8021)FLASK_SECRET_KEY— must be >= 16 chars or app refuses to startDB_*— MySQL connection (database:djangoadmin.flask.elevue, prefix:flask_)REDIS_*— Redis connectionJWT_SALT— JWT signing key;JWT_EXPIRE_MINUTES(default 20)FLASK_DEMO— Demo mode restricts write operationsPERMISSION_ENABLED— Toggle auth middlewareINTERNAL_API_KEY— Key for scheduler/internal calls (sent asX-Internal-API-KeyorX-Scheduler-Keyheader)LOGIN_WHITELIST_*— Paths exempt from login check (exact, prefix, wildcard patterns)PROXY_NUM— Trusted proxy count for ProxyFix (0=none, 1=Nginx)
Frontend env in ui/.env.development: VITE_PORT=8001, VITE_PROXY, VITE_GLOB_API_URL_PREFIX=/api