签入版本
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## What this is
|
||||
|
||||
DjangoAdmin (Django + EleVue) is a **low-code admin framework**: a full CRUD module — Django app, Vue view, API module, menu & permission records — is *generated from a database table definition*, not hand-written. The code generator is the heart of the project; the `application/example/` module and `config.json` at the repo root are samples of its output.
|
||||
|
||||
- Backend: Django 6.0.3 + DRF (installed, but views are plain Django `View` classes), MySQL, Redis, JWT auth. All in Python under `application/`.
|
||||
- Frontend: Vue 3 + TypeScript + Element Plus + Pinia + Vite, in `ui/`. Derived from the vben-admin architecture.
|
||||
- Both sides are heavily documented in Chinese docstrings/comments; code identifiers and API field names are English.
|
||||
|
||||
## Commands
|
||||
|
||||
### Backend (repo root)
|
||||
|
||||
Dependencies: `requirements.txt` is **UTF-16LE encoded** — `pip install -r requirements.txt` may fail on some platforms; re-save it as UTF-8 first if so. MySQL and Redis must be running; all connection settings live in `.env` (loaded by `config/env.py`, imported everywhere as `from config.env import ...`).
|
||||
|
||||
```bash
|
||||
python manage.py runserver # http://127.0.0.1:8000
|
||||
python manage.py makemigrations <app> && python manage.py migrate
|
||||
python manage.py test
|
||||
python manage.py add_full_comments # custom command: backfill DB field comments
|
||||
```
|
||||
|
||||
`application/settings.py` hardcodes `DEBUG = True`; switch behavior via `.env` values (e.g. `DJANGO_DEMO=True` blocks all write endpoints with a demo message).
|
||||
|
||||
### Code generator CLI (repo root)
|
||||
|
||||
```bash
|
||||
python generator.py django_<table> # parse DB table -> config.json -> generate module + Vue + menus
|
||||
python generator.py django_<table> --dry-run # only print config (add --output config.json to save it)
|
||||
python generator.py --config config.json # generate code from an existing config file
|
||||
```
|
||||
|
||||
Equivalent web UI exists at `/generator` (the `application/generator` app). Backend code runs `python generator.py ...` from the repo root with the venv active.
|
||||
|
||||
### Frontend (`ui/`)
|
||||
|
||||
```bash
|
||||
cd ui
|
||||
pnpm install # (package.json also aliases this as "bootstrap")
|
||||
pnpm dev # http://localhost:8001; proxies /api -> http://127.0.0.1:8000/ (see ui/.env.development)
|
||||
pnpm build # prod build
|
||||
pnpm type:check # vue-tsc --noEmit
|
||||
pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### The code generator (read these three to understand the whole project)
|
||||
|
||||
1. `generator.py` — `TableSchemaParser` introspects a MySQL table (field type/comment/length/index) and heuristically classifies fields (image, rich-text, status, sort, code, filterable, choices) into a JSON "config" like the checked-in `config.json`.
|
||||
2. `generator_config.py` — `CodeGenerator` consumes that config, renders Jinja2 templates from `public/templates/` (e.g. `*.py.tpl`, `ui/*.vue.tpl`), and writes:
|
||||
- backend module files under `application/<module>/` (models/forms/services/views/urls/admin/apps + a migration),
|
||||
- Vue files under `ui/src/views/...` and an API module under `ui/src/api/tool/<module>.ts`,
|
||||
- then runs `makemigrations`/`migrate`, inserts menu + permission nodes into the DB (`application.menu.models.Menu`), and **appends the route to `application/urls.py` and the app to `INSTALLED_APPS` in `application/settings.py`**.
|
||||
3. `application/generator/` — web endpoint wrapper around the same logic (`services.generate_tables`).
|
||||
|
||||
Adding a table → config → generated module is the normal way new features are built; don't hand-write a full module unless you need custom logic.
|
||||
|
||||
### Backend module pattern
|
||||
|
||||
Every app under `application/<module>/` follows the same generated layout:
|
||||
|
||||
- `models.py` — inherits abstract `BaseModel` (`application/models.py`): `id, create_user, create_time, update_user, update_time, is_delete`. **All queries filter `is_delete=False`** (soft delete).
|
||||
- `forms.py` — Django `ModelForm` with per-field validation and Chinese `error_messages`.
|
||||
- `services.py` — **all business logic lives here**, in functions like `get_<m>_page`, `add_<m>`, `update_<m>`, `delete_<m>` (batch delete via comma-joined IDs), `update_<m>_status`. Uses `parse_request_body` + `regular.get_err` from `utils/`. Pagination via Django `Paginator`; response shape `{records, total, size, current, pages}`.
|
||||
- `views.py` — one class per endpoint, each `@method_decorator(check_login, name="<method>")`, subclassing `PermissionRequired` with `permission_required = ("sys:<module>:<action>",)`, and write/read handlers decorated with `@operation_log(title=..., log_type=LogType.<X>)` from `application/operation_log/decorators.py`.
|
||||
- `urls.py` — declared per-module, wired into `application/urls.py` (each path is a module prefix like `level/`, `dict/item/`, `role/menu/`).
|
||||
|
||||
Convention: DB/field names are snake_case; JSON payloads use camelCase (`create_user` ↔ `createUser`). Views/services build dicts manually per record.
|
||||
|
||||
### Auth & permissions
|
||||
|
||||
- `check_login` (`middleware/login_middleware.py`) validates the `Authorization: Bearer <token>` JWT (parsed by `utils/jwts.py`); `ignoreURL = ['/login', '/captcha']`.
|
||||
- `PermissionRequired` (`middleware/permission_middleware.py`) — user id **1 is superadmin (bypass)**, otherwise checks the `sys:<module>:<action>` node against `application/menu/services.get_user_permissions(user_id)`.
|
||||
- Frontend hides/disable buttons with the `v-perm` directive using the same `sys:...` codes.
|
||||
|
||||
### Response convention
|
||||
|
||||
`utils/R.py` — every endpoint returns `R.ok(...)` / `R.failed(...)`, envelope `{code: 0/1, data, msg, ok}`. Read it before writing a view.
|
||||
|
||||
### Frontend (`ui/`)
|
||||
|
||||
- **Routes and menus are dynamic, driven by the backend.** On login the router guard (`src/router/router-guards.ts` → `generator-routers.ts`) calls `GET /index/getMenus`, and the returned menu tree becomes Vue Router records + `<el-menu>` items. Each menu row's `component` field must match a `.vue` under `src/views/**` (resolved via `import.meta.glob`). So new pages appear by inserting a menu row in the DB, **not** by editing a frontend route file.
|
||||
- API modules live under `src/api/<domain>/<name>.ts`, importing `http` from `@/utils/http/axios` (base `/api`, JWT header injection, unwraps `{code, data, msg}`). See `src/api/tool/example.ts` for the canonical CRUD shape.
|
||||
- A generated CRUD view is a folder `src/views/<domain>/<entity>/` with `index.vue` (search `BasicForm` via `useForm` + `querySchemas.ts`, list `BasicTable` + `columns.ts`, `TableAction` row buttons), plus lazy-loaded `edit.vue` / `detail.vue` dialogs. Shared components: `BasicTable`, `BasicForm`, `PageWrapper` from `src/components/`. Store: Pinia in `src/store/modules/` (notably `asyncRoute.ts`, `user.ts`).
|
||||
- Dev networking: Vite on 8001 proxies `/api` to Django 127.0.0.1:8000 (`.env.development`); change backend target there.
|
||||
|
||||
## Conventions to follow
|
||||
|
||||
- Every source file begins with a long Chinese copyright banner from 小蚂蚁云团队 — keep it on new files (including generator output).
|
||||
- Docs/comments are in Chinese; identifiers, APIs, and commit-adjacent names in English.
|
||||
- New modules should be produced through the generator where possible; if writing one by hand, mirror `application/example/` exactly (models/forms/services/views/urls) and remember to register the app in `settings.py` `INSTALLED_APPS` and add its routes to `application/urls.py`.
|
||||
- Permissions are `sys:<module>:<action>` for actions `page/list/detail/add/update/delete/status`.
|
||||
Reference in New Issue
Block a user