Files
DjangoAdmin_Flask_EleVue/CLAUDE.md
T

9.3 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

重构状态:项目已按《重构方案-v2.md》完成 P1-P7 全部阶段。 后端源码位于 src/(core/common/modules/routes),API 统一 /api/v1 前缀, 服务层为「入参数据/出参数据 + BizError」范式,全项目 flake8 零告警。

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:

  • src/modules/<domain>/<name>/router.py — Route controllers (Flask Blueprint). Registered under /api/v1 prefix (see src/routes/v1.py). Each file defines routes decorated with @check_permission("sys:module:action"). Routers parse request params, delegate to service functions, and wrap with R.ok()/R.failed(). Write operations check FLASK_DEMO first (via @check_demo).
  • src/modules/<domain>/<name>/service.py — Business logic layer. 服务函数「入参数据/出参数据」(不直接读 request,不返回 R);业务失败 raise BizError;私有辅助函数以 _ 开头。数据访问委托 repository。
  • src/modules/<domain>/<name>/models.py — SQLAlchemy models. All models inherit from BaseModel + BaseDB (in src/common/). Table names use DB_PREFIX (default flask_) + snake_case class name.
  • src/modules/<domain>/<name>/repository.py — 数据访问层,继承 BaseRepository(src/common/base_repository.py)。

AOP Transaction Management

The framework uses an AOP-style transaction interceptor (src/core/middleware.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

  • src/app.py — App factory (create_app()). Initialization order: Flask core -> Redis config -> DB config -> JSON encoder -> CORS -> ProxyFix -> op_log/transaction -> register /api/v1 routes -> init extensions -> middleware -> error handlers -> DI injection.
  • src/routes/v1.py — API v1 路由注册中心。所有业务蓝图挂载到 /api/v1 前缀。
  • src/core/middleware.py — check_login (before_request hook, JWT validation with token blacklist, whitelist matching), check_demo, register_transaction (AOP 事务), register_operation_log (操作日志,写入器 DI 注入), register_error_handlers.
  • src/core/permission.py — check_permission (RBAC decorator; superadmin user_id=1 bypasses; 权限数据通过 current_app.extensions['permission_provider'] 注入,见 src/app.py _inject_dependencies).
  • src/core/exceptions.py — BizError 业务异常(业务层 raise BizError 统一转 R.failed)。
  • src/common/forms/ — WTForms 验证表单。继承 BaseForm(含 ArrayField JSON 序列化)。
  • src/common/constants/ — 共享常量:PAGE_SIZE=10, DEFAULT_PASSWORD="123456", MESSAGE_OK/FAIL, SERIALIZE_EXCLUDE_FIELDS.
  • 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.
  • src/extensions.py — Flask extension registration orchestration (register_extends(app)). 实例定义在 src/core/(database/redis_client/mail/scheduler)。
  • src/core/ — response(R 统一响应)、jwt、password(bcrypt)、security(get_user_id/get_username)、redis_client。
  • src/common/utils/ — model_utils(models_to_list/model_to_dict)、request(parse_request_body/parse_id_list)、case_converter(camelCase <-> snake_case)、regular(WTForms 错误提取)、captcha、file、rich_text、ip、user_agent、formatter、json、ip2region.

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 src/modules/<domain>/<name>/models.py inheriting BaseModel + BaseDB
  2. Create service in src/modules/<domain>/<name>/service.py(入参数据/出参数据 + raise BizError)
  3. Create repository in src/modules/<domain>/<name>/repository.py inheriting BaseRepository
  4. Create router in src/modules/<domain>/<name>/router.py with routes and permission decorators
  5. Create schema in src/modules/<domain>/<name>/schema.py inheriting BaseForm if input validation needed
  6. Add the blueprint to BLUEPRINTS list in src/routes/v1.py
  7. Add frontend API in ui/src/api/{module}/, views in ui/src/views/{module}/(API 前缀 /api/v1)

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