Files
xh-medical-sign-web/clinical-web/AGENTS.md
2026-09-01 14:50:50 +08:00

118 lines
5.0 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.
# clinical-web 开发规范
## 技术栈与边界
- 使用 Vue 3、TypeScript、Vite、Vue Router、Pinia、Element Plus 和 Axios。
- 所有接口请求统一经过 `src/utils/request.ts` 的单例实例。
- 开发环境默认使用 `/api`,由 `vite.config.ts` 代理到后端;不要在页面中直接拼接后端域名。
- 当前除登录外的业务接口可以使用 Mock但 Mock 数据必须遵守真实接口类型。
## 目录约定
```text
src/
├─ api/
│ ├─ auth.ts
│ ├─ workbench/
│ │ ├─ home.ts
│ │ ├─ signing.ts
│ │ └─ types.ts
│ └─ management/
│ ├─ documents.ts
│ ├─ reports.ts
│ ├─ users.ts
│ ├─ permissions.ts
│ ├─ document-permissions.ts
│ ├─ settings.ts
│ └─ types.ts
├─ components/
│ ├─ layout/
│ └─ signing/
├─ composables/
├─ stores/
├─ types/
├─ utils/
└─ views/
├─ auth/
├─ workbench/
└─ management/
```
- API 文件按页面业务域对应;管理端直接使用 `documents.ts``reports.ts` 等文件,不再额外套同名目录。
- 每个具体 View 使用 `index.vue` 作为入口;当前页面专用组件放在同级 `components`
- 跨页面的领域组件放在 `src/components`,布局组件统一放在 `src/components/layout`
- API DTO 类型放在对应 API 业务域的 `types.ts`;页面展示和交互类型放在 View 的 `types.ts`;全局类型放在 `src/types/common.ts`
## API 规范
- API 文件只负责请求、响应类型和必要的数据标准化。
- 不在 API 文件中创建新的 Axios 实例,不在 API 层操作组件、路由或 `ElMessage`
- 所有请求通过 `request` 单例发送;接口函数必须提供明确的返回类型。
- 接口地址使用相对路径,不重复写基础地址。
- 业务接口的列表、详情、创建、更新和删除函数按资源命名,例如:
```ts
import { request } from '@/utils/request'
import type { ReportOverviewResponse, ReportQuery } from './types'
export function getReportOverview(params: ReportQuery) {
return request.get<ReportOverviewResponse>('/management/reports/overview', { params })
}
```
- 响应包装、错误码和后端 DTO 与页面展示模型不一致时,在 API 边界或 composable 中转换,组件不负责猜测接口结构。
- 登录 Token、用户信息和本地持久化只由 `stores/login.ts``utils/auth-storage.ts` 管理,页面不直接操作 `localStorage`
## 页面与组件拆分
- `views/**/index.vue` 负责页面编排、接口调用、加载/错误状态、筛选条件和路由联动。
- 当前页面专用组件负责展示和交互,通过类型化 `props` 接收数据,通过 `emit` 通知父组件。
- 展示型组件不直接调用 API、不直接修改全局 Store确有跨页面业务复用时放入领域组件并明确其边界。
- 组件只承担一个清晰职责。不要为了减少文件长度机械拆分小片段,也不要让页面入口堆积复杂表单和弹窗逻辑。
- 复杂表单、弹窗流程、校验、提交和异步状态抽到 `composables/useXxx.ts`;弹窗组件负责表单渲染和事件呈现。
- 签署任务新增流程由 `components/signing/NewSigningTaskDialog.vue``composables/useSigningTaskForm.ts` 共同维护,供签署工作台和文档库复用。
## 状态管理
- 页面只使用一次的表格数据、筛选条件、弹窗显隐和 loading优先使用页面内的 `ref``reactive` 和 composable。
- 只有跨页面共享、需要持久化或代表全局上下文的状态才进入 Pinia。
- Store 按业务域拆分,并统一使用 Composition API 写法:
```ts
export const useExampleStore = defineStore('example', () => {
const value = ref('')
const isReady = computed(() => Boolean(value.value))
function setValue(nextValue: string) {
value.value = nextValue
}
return { value, isReady, setValue }
})
```
- 不使用 Pinia 的 `state``getters``actions` 配置式写法。
- `stores/app.ts` 只管理院区、环境等应用上下文。
- `stores/login.ts` 只管理登录态、用户信息、Token 和登录/退出流程。
- 不把所有业务数据集中到 `app` Store签署任务列表等页面数据默认留在页面或 composable 中。
- 避免 Store 之间互相依赖,尤其不要让 `request.ts` 静态依赖业务 Store防止循环依赖。
## 类型与命名
- 不使用无理由的 `any`;后端字段不确定时先定义 `unknown`,在边界处完成校验或标准化。
- Vue 组件使用 PascalCaseAPI、composable、Store 和工具文件使用 kebab-case 或项目已有命名方式。
- `useXxx` 表示 composable`useXxxStore` 表示 Pinia Store。
- 类型名描述业务含义,避免使用 `Data``Info` 等无语义名称。
## 提交前检查
```bash
npm run lint
npm run format:check
npx vue-tsc --noEmit
npm run build
```
如果构建被本机 `node_modules` 或已有 `dist` 的权限问题阻断,应保留错误信息并使用临时输出目录验证,不要删除或覆盖已有构建产物。