Files
DjangoAdmin_Flask_EleVue/CLAUDE.md
T
DjangoAdmin DevandClaude 15f2a5e097 chore: 基线提交(重构前代码快照)
- 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>
2026-08-07 12:12:06 +08:00

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 return R.ok()/R.failed() responses. Write operations check FLASK_DEMO first to block demo-mode writes.
  • application/services/ — Business logic layer. Contains all query building, data transformation, and orchestration. Functions receive data from request object 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 from BaseModel (provides id, create_user, create_time, update_user, update_time, is_delete fields) and BaseDB (provides save(), save_all(), delete() methods). Table names use DB_PREFIX (default flask_) + 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 active
  • after_request: auto-commits on POST/PUT/DELETE/PATCH only if HTTP 2xx AND code==0 in response JSON; auto-rollbacks on business failures (R.failed returns HTTP 200 but code=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_modules list; the system dynamically imports the module and registers any Blueprint instance found in it. No manual app.register_blueprint() needed.
  • application/middleware/ — check_login (before_request hook, JWT validation with token blacklist, whitelist matching via exact/prefix/wildcard patterns) and check_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 inherit BaseForm (in forms/forms.py) which handles ArrayField JSON serialization. Forms are instantiated with data=json_data from parsed request body.
  • application/constants/ — Shared constants: PAGE_SIZE=10, DEFAULT_PASSWORD="123456", MESSAGE_OK/FAIL, SERIALIZE_EXCLUDE_FIELDS (is_delete, password, salt excluded from to_dict()).
  • config/ — Split into base.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 .env via python-dotenv. config/__init__.py loads .env before any sub-module imports.
  • extensions/ — Flask extension initialization: SQLAlchemy (db), Redis, APScheduler. All initialized via register_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 as from utils import password then used as bcrypt.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 uses http.request() from utils/http/axios/. The HTTP client auto-prepends VITE_GLOB_API_URL_PREFIX (/api) and sends JWT as Authorization: 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.ts transforms backend menu tree into Vue Router routes; asyncImportRoute uses import.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 === 0 for success; code=401 triggers re-login
  • Permission strings follow pattern: sys:module:action (e.g., sys:user:page, sys:role:add)
  • Frontend proxies /api prefix to backend via Vite dev server proxy (configured in ui/.env.development as VITE_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 only
  • to_dict() returns snake_case keys; services use convert_snake_to_camel when frontend needs camelCase

Adding a New Module

  1. Create model in application/models/{module}.py inheriting BaseModel + BaseDB
  2. Create service in application/services/{module}.py with business logic
  3. Create view in application/views/{module}.py with routes and permission decorators
  4. Add module name string to _blueprint_modules list in application/views/__init__.py
  5. Create form in application/forms/{module}.py inheriting BaseForm if input validation needed
  6. Add frontend API in ui/src/api/{module}/, views in ui/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 start
  • DB_* — MySQL connection (database: djangoadmin.flask.elevue, prefix: flask_)
  • REDIS_* — Redis connection
  • JWT_SALT — JWT signing key; JWT_EXPIRE_MINUTES (default 20)
  • FLASK_DEMO — Demo mode restricts write operations
  • PERMISSION_ENABLED — Toggle auth middleware
  • INTERNAL_API_KEY — Key for scheduler/internal calls (sent as X-Internal-API-Key or X-Scheduler-Key header)
  • 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