138 lines
7.7 KiB
Markdown
138 lines
7.7 KiB
Markdown
# 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). Don’t 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; don’t 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. Don’t 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.
|