diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..8e55362a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,145 @@ +# 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//index.ts # API 对象;类型少可同文件,多则拆 types.ts +src/api//types.ts +src/views///index.vue +src/views///config/ # 可选:search/content/add/edit/options +src/components// # 模块私有可复用组件 +src/composables/use.ts # 新 composable 直接引用,不并入上游 index.ts +src/enums/.ts # 新枚举独立文件,不并入上游 enums/index.ts +src/constants/.ts +``` + +- 目录 kebab-case(`app-manager`、`save-flow`),组件 PascalCase(`DeviceSnDetail`)。 +- 页面私有组件/类型留在页面目录;跨页面复用才提升到 `src/components//`。 +- 业务类型不放 `src/types/`;通用工具可在 `src/utils/` 新建独立文件,禁止修改上游已有工具文件;业务状态不放上游 `src/stores/*`。 +- 现有范例:`src/views/update/`、`src/views/devices/`、`src/views/app-manager/`、`src/components/DeviceSn/`。 + +## 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>({ url: `${BASE_URL}/page`, method: "get", params }); + }, +}; +``` + +- 分页统一用 `@/api/common` 的 `PageQuery` / `PageResult`。 +- 错误提示由拦截器统一弹出;页面 `catch` 只做善后(关 loading、关弹窗、回滚状态),不要重复 `ElMessage.error`。 +- 轮询/探测请求用 `silentErrorStatuses` 静默指定状态码。 +- 免鉴权请求用 `anonymous: true` 或 `headers: { Authorization: "no-auth" }`(类型见 `types/axios.d.ts`)。 + +## 8. 页面与 UI 规范 + +- 统一 `