Files
zyt/CLAUDE.md
T
2026-04-21 15:56:04 +08:00

138 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Multi-client SaaS platform (基于 likeadmin 脚手架改造) centered on 中医在线问诊 — video consultations (TRTC), prescriptions, medicine library, 企微 (QYWX) integration, and payments. Single repo contains a PHP backend plus four independent frontend clients.
## Top-Level Layout
| Dir | Stack | Purpose |
|-----|-------|---------|
| `server/` | ThinkPHP 8 + PHP 8.0+ | REST API, the single source of truth |
| `admin/` | Vue 3 + Vite + Element Plus + Tailwind | 管理后台 (desktop) |
| `pc/` | Nuxt 3 + Element Plus | 公开 PC 站 (SSR/SSG) |
| `uniapp/` | uni-app (Vue 3, Vite) | H5 / 小程序 / App 多端客户端 |
| `wx/` | uni-app 微信小程序 | 独立 TRTC 微信小程序壳 |
| `TUICallKit*/` | Tencent TRTC UIKit | Vendor SDK source used by clients |
| `docker/` | docker-compose (nginx + php-fpm + mysql) | Local dev stack |
| `doc/`, `ps/` | Supporting docs / psd | Design & reference material |
Each frontend is deployed to `server/public/<client>/` (see `server/route/app.php` fallback routes). Dont rely on a root-level workspace — each client has its own `package.json` and must be built separately.
## Common Commands
### Backend (`server/`)
```
composer install # install deps
php think run --host 0.0.0.0 --port 8080 # dev server (if PHP CLI)
php think <command> # run CLI commands (see app/command/)
php think crontab # trigger cron tasks manually
```
- Docker alternative: `cd docker && docker-compose up -d` (exposes nginx on :80, mysql on :3306).
- SQL migrations live in `server/sql/<version>/*.sql` (versioned by date). Apply manually in order; there is no automatic migration runner. Current version directory: `server/sql/1.9.20260420/`.
### Admin (`admin/`)
```
npm install
npm run dev # Vite dev server
npm run build # production build + node scripts/release.mjs
npm run type-check # vue-tsc --noEmit
npm run lint # ESLint with --fix
npm run clean # node scripts/clean.mjs
```
### PC (`pc/`)
```
npm install
npm run dev # Nuxt dev server on :3000
npm run build # nuxt generate + scripts/build.mjs (static export)
npm run build:ssr # Nuxt SSR build
```
### uniapp (`uniapp/`)
```
npm install
npm run dev:h5 # H5
npm run dev:mp-weixin # 微信小程序
npm run dev:app # App
npm run build:h5 # build + scripts/release.mjs
# other targets: mp-alipay, mp-baidu, mp-qq, mp-toutiao, quickapp-webview...
npm run lint
```
### Running a single test
There is no unit-test harness checked in (no Jest/Vitest/PHPUnit config). When adding tests, wire the framework first; dont assume one exists.
## Backend Architecture (likeadmin conventions)
`server/app/` is a ThinkPHP multi-app project. Three apps with a shared `common/` layer:
- `adminapi/` — admin panel API (consumed by `admin/`)
- `api/` — public/end-user API (consumed by `pc/`, `uniapp/`, `wx/`)
- `index/` — default app fallback
- `common/` — shared models, services, enums, exceptions, listeners
Each app follows the layered pattern:
```
<app>/
├── controller/ # HTTP entry; extends BaseAdminController / BaseApiController
├── logic/ # Business logic; static methods invoked by controllers
├── lists/ # List-query objects (pagination/filter/export encapsulation)
├── validate/ # Request validation rules
├── service/ # App-scoped services
├── http/ # Middleware, route groups
└── config/ # App-specific config
```
Key conventions:
- **Controllers stay thin.** They pull `$this->request->get()/post()`, delegate to a `Logic` class, and wrap the result with `$this->data(...)` / `$this->success(...)` / `$this->fail(...)` from `BaseLikeAdminController` (in `common/controller`).
- **Logic returns plain arrays.** Throw `\app\common\exception\*` for failures — the global exception handler (`app/ExceptionHandle.php`) converts them to JSON envelopes.
- **Models extend `app\common\model\BaseModel`** which auto-completes image paths via `FileService`.
- **Route registration is menu-driven.** Admin routes are auto-resolved from menu entries (see `add_conversion_stats_menu.sql` as an example of wiring a new admin page). Public routes are declared in `app/api/route/` and `server/route/app.php`.
- **Payment / third-party callbacks** bypass auth — declared explicitly in `server/route/app.php` (e.g. wechat-notify, alipay-notify, TRTC recording-notify).
## Admin Architecture (`admin/src/`)
```
src/
├── api/ # One file per domain (stats.ts, order.ts, doctor.ts...)
├── views/ # Page components grouped by domain (mirrors api/)
├── router/
│ ├── index.ts # Dynamic route generation from backend menu
│ └── routes.ts # Static/constant routes + LAYOUT wrapper
├── stores/modules/ # Pinia stores (user, app, tagsView...)
├── components/ # Shared components
├── utils/request/ # Axios instance + interceptors
├── hooks/ # Composables
├── install/ # Global plugin registration (app.use(install))
└── permission.ts # Login/permission guard mounted on router
```
- **Views are dynamically loaded** via `import.meta.glob('/src/views/**/*.vue')` in `router/index.ts`. A view path from the backend menu (e.g. `stats/conversion/index`) resolves to `src/views/stats/conversion/index.vue`. When adding a page, the corresponding menu record must be inserted via SQL (pattern: `server/sql/.../add_*_menu.sql`).
- **API calls go through `utils/request`** which normalizes the response envelope and handles auth/error toasts. Dont use axios directly.
- **Auto-imports**: Element Plus components, `ref`/`reactive`/router composables are auto-imported via `unplugin-auto-import` — no need to import them explicitly (see `auto-imports.d.ts`).
## Cross-Cutting Concerns
- **Versioned SQL migrations.** New schema/menu changes go in `server/sql/<version>/*.sql`. When adding an admin view, pair it with an `add_*_menu.sql` file (see current WIP: `add_conversion_stats_menu.sql` + `admin/src/views/stats/conversion/`).
- **TRTC integration.** Video-call logic is split between `TUICallKit/` (vendor), `admin/src/utils/call-*.ts` and `src/utils/im-*.ts`, and the `api/controller/TrtcController`. Cloud recording is triggered server-side and written back via the `/api/trtc/recording-notify` callback.
- **企微 (QYWX).** `server/app/adminapi/controller/qywx/` + `admin/src/views/qywx/` + `pc/` pages exchange via `easywechat`. OAuth/bind flow uses `admin/src/utils/wecomOauthPostMessage.ts` and `wecomBindGuard.ts`.
- **Multi-cloud storage.** File uploads support Qiniu / Tencent COS / Aliyun OSS — configuration is driven by runtime admin settings, resolved in `FileService`.
## Trellis Workflow
This repo is Trellis-managed (see `.trellis/`). New work should go through:
1. `/trellis:start` — loads session context
2. `/trellis:brainstorm` for complex/vague asks (creates `prd.md`)
3. Research → `task.py init-context` → Implement → Check agents
4. `/trellis:finish-work` before committing
Code-spec files under `.trellis/spec/` are injected into sub-agent contexts automatically. Relevant thinking guides live in `.trellis/spec/guides/`.
## Language & Docs
All user-facing commentary, commit messages, and code comments in this repo use 简体中文 when addressing the product domain; identifiers, API paths, and this file stay in English. The backend still carries original likeadmin attribution headers — do not remove them on edit.