7.7 KiB
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 byadmin/)api/— public/end-user API (consumed bypc/,uniapp/,wx/)index/— default app fallbackcommon/— 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 aLogicclass, and wrap the result with$this->data(...)/$this->success(...)/$this->fail(...)fromBaseLikeAdminController(incommon/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\BaseModelwhich auto-completes image paths viaFileService. - Route registration is menu-driven. Admin routes are auto-resolved from menu entries (see
add_conversion_stats_menu.sqlas an example of wiring a new admin page). Public routes are declared inapp/api/route/andserver/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')inrouter/index.ts. A view path from the backend menu (e.g.stats/conversion/index) resolves tosrc/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/requestwhich 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 viaunplugin-auto-import— no need to import them explicitly (seeauto-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 anadd_*_menu.sqlfile (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-*.tsandsrc/utils/im-*.ts, and theapi/controller/TrtcController. Cloud recording is triggered server-side and written back via the/api/trtc/recording-notifycallback. - 企微 (QYWX).
server/app/adminapi/controller/qywx/+admin/src/views/qywx/+pc/pages exchange viaeasywechat. OAuth/bind flow usesadmin/src/utils/wecomOauthPostMessage.tsandwecomBindGuard.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:
/trellis:start— loads session context/trellis:brainstormfor complex/vague asks (createsprd.md)- Research →
task.py init-context→ Implement → Check agents /trellis:finish-workbefore 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.