- src/api/system/device -> src/api/device,原 app-icon 类型拆为 appIcon.types.ts - src/api/system/developer -> src/api/developer - src/components/DeviceSn -> src/views/devices/sn/components,页内改为显式导入 - 同步更新 AGENTS.md 的模块目录与 API 分域约定
150 lines
8.1 KiB
Markdown
150 lines
8.1 KiB
Markdown
# AGENTS.md — vue3-element-admin-ttstd 本地定制规范
|
||
|
||
## 1. 项目定位与远程
|
||
|
||
- 上游模板:`gitee` 远程 `youlaiorg/vue3-element-admin`,通用后台模板。
|
||
- 本地业务仓:`origin` 远程 `gitea.ttstd.com/tt/vue3-element-admin`,承载 TTSTD 业务定制。
|
||
- 技术栈:Vue 3 + Vite + TypeScript + Element Plus + Pinia + UnoCSS + vxe-table。
|
||
- 上级目录的 `AGENTS.md` 同样生效,尤其是 `*-origin/` 只读约定。
|
||
|
||
目标:**本地业务可扩展,上游代码可随时合并**。判断标准是合并 `gitee/master` 时冲突越少越好。
|
||
|
||
## 2. 核心原则:保持上游干净
|
||
|
||
默认假设:**上游已有文件是只读的**。
|
||
|
||
1. 除第 4 节白名单外,上游文件不修改、不删除、不重命名。
|
||
2. 新功能、新页面、新接口、新组件一律新建文件。
|
||
3. 需要扩展上游能力时,优先"包装"而不是"改造":新组件包旧组件、新 composable 包旧逻辑、新 API 模块调接口。
|
||
4. 禁止删除或简化上游功能,禁止把上游文件改成"本地专用版"。
|
||
5. 修改上游文件前先确认无替代方案;确需修改时,改动最小化并在提交信息中写明原因。
|
||
|
||
改动前自问三句:**这是新文件吗?不改上游能实现吗?合并上游时会冲突吗?**
|
||
|
||
## 3. 本地定制清单(不要"顺手修复")
|
||
|
||
以下差异是刻意保留的,修改前必须确认:
|
||
|
||
| 位置 | 定制内容 |
|
||
| --- | --- |
|
||
| `src/utils/request.ts` | 本地版请求层:`http` + `uploadHttp` 双实例、Bearer 注入、内置 token 刷新重试、响应直接解包 `data` |
|
||
| `src/utils/sse.ts` | 本地 SSE 实现(重连、鉴权、解析),由 `src/composables/index.ts` 导出 |
|
||
| `.env.development` | `VITE_APP_BASE_API`、`VITE_APP_API_URL`、`VITE_BAIDU_MAP_AK`、`VITE_API_TYPE`,后端指向 `api.ttstd.com` |
|
||
| `vite.config.ts` | `/static` 代理到后端、端口兜底 3000 |
|
||
| `types/env.d.ts` | 上述环境变量类型 |
|
||
| `package.json` | `apk-meta-parser`(浏览器端解析 APK 元数据) |
|
||
| `src/utils/token-refresh.ts` | 上游遗留文件,本地未使用,不要贸然接入 |
|
||
|
||
## 4. 允许本地化的文件(白名单)
|
||
|
||
| 文件 | 允许的改动 |
|
||
| --- | --- |
|
||
| `.env.development` / `.env.production` | 新增或调整环境变量 |
|
||
| `types/env.d.ts` | 补充环境变量类型 |
|
||
| `vite.config.ts` | 代理、端口、构建参数 |
|
||
| `package.json` / `pnpm-lock.yaml` | 依赖与脚本(lock 只能由 `pnpm add/remove` 生成,禁止手改) |
|
||
| `src/router/index.ts` | **仅在数组末尾追加**本地静态路由块,禁止改动已有条目 |
|
||
| `uno.config.ts` / `*.config.*` | 确有配置需求时 |
|
||
|
||
## 5. 路由与页面注册
|
||
|
||
- **业务页面默认走后端菜单动态注册**:`src/router/views.ts` 通过 `import.meta.glob("/src/views/**/*.vue")` 自动收集页面,菜单组件路径填 `模块/页面`(如 `devices/sn`)即可,**无需改路由文件**。
|
||
- 新增页面时,菜单数据同步写入后端 `sys_menu`,SQL 脚本放在 `youlai-boot-ttstd/sql/`(参考 `menu_update_manager.sql`、`menu_device_sn.sql`)。
|
||
- 只有"无菜单入口 / 不套 Layout / 全屏"的页面才用静态路由,按 `src/router/index.ts` 中 `/data-screen` 的写法追加独立分组。
|
||
- 不要把业务页面写进 `constantRoutes` 已有项,不要改 `screenRoutes`。
|
||
|
||
## 6. 新模块目录约定
|
||
|
||
```text
|
||
src/api/<module>.ts # 类型少时单文件(API 对象 + interface)
|
||
src/api/<module>/index.ts # API 对象;类型多时拆 types.ts
|
||
src/api/<module>/types.ts
|
||
src/views/<module>/<page>/index.vue
|
||
src/views/<module>/<page>/config/ # 可选:search/content/add/edit/options
|
||
src/views/<module>/<page>/components/ # 可选:页面私有组件与类型
|
||
src/components/<ModuleName>/ # 跨页面复用才提升到这里
|
||
src/composables/use<Name>.ts # 新 composable 直接引用,不并入上游 index.ts
|
||
src/enums/<module>.ts # 新枚举独立文件,不并入上游 enums/index.ts
|
||
src/constants/<module>.ts
|
||
```
|
||
|
||
- 目录 kebab-case(`app-manager`、`save-flow`),组件 PascalCase(`DeviceSnDetail`)。
|
||
- 业务 API 一律放 `src/api/<module>`,**不要放进上游的 `src/api/system/`**(会被上游同步覆盖或覆盖上游 `user`/`role` 等模块)。
|
||
- 页面私有组件/类型留在页面目录的 `components/`;跨页面复用才提升到 `src/components/<ModuleName>/`。
|
||
- 业务类型不放 `src/types/`;通用工具可在 `src/utils/` 新建独立文件,禁止修改上游已有工具文件;业务状态不放上游 `src/stores/*`。
|
||
- 现有范例:`src/views/update/`、`src/views/devices/`、`src/views/app-manager/`、`src/views/devices/sn/components/`。
|
||
|
||
## 7. API 层规范
|
||
|
||
- 只通过 `@/utils/request` 发请求,禁止直接使用 `axios`;大文件(APK、补丁)用同模块的 `uploadHttp`。
|
||
- 响应拦截器已解包,`await xxx()` 直接得到业务数据,不要再取 `.data`。
|
||
- 统一导出 `XxxAPI` 常量对象,模块内定义 `BASE_URL`:
|
||
|
||
```ts
|
||
const BASE_URL = "/api/v1/xxx";
|
||
|
||
export const XxxAPI = {
|
||
getPage(params: XxxPageQuery) {
|
||
return request<unknown, PageResult<Xxx>>({ url: `${BASE_URL}/page`, method: "get", params });
|
||
},
|
||
};
|
||
```
|
||
|
||
- 分页统一用 `@/api/common` 的 `PageQuery` / `PageResult`。
|
||
- 一个模块下有多组业务类型时按域拆文件(如 `src/api/device/types.ts` 与 `src/api/device/appIcon.types.ts`),不要混放在一个 `types.ts`。
|
||
- 错误提示由拦截器统一弹出;页面 `catch` 只做善后(关 loading、关弹窗、回滚状态),不要重复 `ElMessage.error`。
|
||
- 轮询/探测请求用 `silentErrorStatuses` 静默指定状态码。
|
||
- 免鉴权请求用 `anonymous: true` 或 `headers: { Authorization: "no-auth" }`(类型见 `types/axios.d.ts`)。
|
||
|
||
## 8. 页面与 UI 规范
|
||
|
||
- 统一 `<script setup lang="ts">`。
|
||
- 优先复用:`Crud`、`Pagination`、`TableActions`、`StatusDot`、`DictSelect`、`Upload`、`ECharts` 等现有组件。
|
||
- 列表页优先复用 `usePageTable`、`useTableSelection`,交互与上游页面保持一致。
|
||
- 查询/表格/表单配置拆到 `config/`(参考 `src/views/devices/sn/config/`)。
|
||
- 样式用 scoped + UnoCSS;不新增全局样式,不覆盖上游主题变量。
|
||
- 静态资源地址(图标、截图、安装包)统一用 `@/utils/asset-url` 的 `withBase()` 拼接,禁止在页面里重复实现。
|
||
- 文案统一中文。
|
||
|
||
## 9. 代码风格与 diff 卫生
|
||
|
||
- 遵循 `.prettierrc.yaml`:2 空格、LF、`printWidth: 100`、尾随逗号。
|
||
- **不要整体格式化上游文件**,否则会产生无意义的大 diff;Prettier/ESLint 只作用于本次新增或确有修改的文件。
|
||
- 不要给上游代码补注释、改命名、调顺序。
|
||
- 注释只写"为什么"(非显而易见的约束/兼容原因),不写"做了什么"。
|
||
- 提交信息用 `pnpm commit`(cz-git),如 `feat(update): 新增灰度更新页面`。
|
||
|
||
## 10. 校验
|
||
|
||
```bash
|
||
pnpm type-check # vue-tsc
|
||
pnpm lint:check
|
||
pnpm format:check
|
||
pnpm style:check
|
||
# 或一次性
|
||
pnpm check
|
||
```
|
||
|
||
页面类改动必须 `pnpm dev` 实际打开验证;仅通过类型/构建检查不算完成。
|
||
|
||
## 11. 上游同步
|
||
|
||
```bash
|
||
git fetch gitee
|
||
git merge gitee/master
|
||
```
|
||
|
||
- 冲突原则:**保留本地定制,并把定制迁移到新文件**,不把上游代码改成兼容本地的样子。
|
||
- 合并后重点回归:`src/utils/request.ts`、`src/router/index.ts`、`vite.config.ts`、`.env.*`、`package.json`、`types/env.d.ts`。
|
||
- 上游若重构了 `request.ts`(如 `token-refresh.ts`),不要直接替换本地版;先评估再把上游能力以新文件方式接入。
|
||
- 同步后执行 `pnpm check && pnpm build`。
|
||
- 禁止强推 `origin/master`,禁止改写已推送的合并提交。
|
||
|
||
## 12. 禁止事项
|
||
|
||
- 禁止修改 `../vue3-element-admin-origin/`、`../youlai-boot-origin/` 等 `*-origin/` 目录。
|
||
- 禁止把业务代码塞进上游页面、组件、store、工具函数。
|
||
- 禁止为"减包"删除上游示例页(`src/views/demo/`)或 API 模块。
|
||
- 禁止直接改 `node_modules/`、`dist/`。
|
||
- 禁止在代码中硬编码后端地址、密钥、AK;统一走环境变量。
|