Files
framework_project_web/.cursor/rules/admin-framework-strict.mdc
张成 dee3a336ce init
2026-04-29 13:34:39 +08:00

115 lines
7.1 KiB
Plaintext
Raw Permalink 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.
---
description: Admin 前端 admin-framework 严格约束(详尽版,对照 admin_core
globs: admin/src/**/*.{vue,js},admin_core/src/**/*.{vue,js}
alwaysApply: false
---
# Admin Framework 严格约束(详尽)
本规则用于 `admin` / `admin_core` 业务页面与入口,**优先级高于建议类文档**。与 `admin_core` 中 `http.js`、`store/user.js`、`router/index.js`、`index.js` 行为冲突的写法一律禁止。
---
## 1. 禁止项(违反即应重构)
### 1.1 HTTP 与 axios
- **禁止**在业务 `vue/js` 中 `import axios` 或 `axios.create`,用于替代 `this.$http``http.js` 已集中处理拦截器、loading、`admin-token`)。
- **禁止**手工设置请求头 **`admin-token`**(或复制一套与 `getHttpInstance` 等价的拦截器);例外仅存在于框架内部的 **`fileExport`**(独立 `axios.post`),业务仍应调用 **`this.$http.fileExport`**。
- **禁止**在页面内维护第二套 **`apiUrl` / baseURL** 常量拼接 URL统一 `createApp({ apiUrl })` 与 **`this.$http`**。
### 1.2 与框架重复的基础设施
- **禁止**复制 **`formatParamete`**(去空串、日期格式化)、全局 Loading DOM`spin-box-one`、401 跳转登录等与 **`http`** 重复的逻辑。
- **禁止**在已有 **`editModal` / `AsyncModal` / `FieldRenderer`** 能满足需求时,再写一套通用弹窗/动态表单渲染(除非产品明确要求完全不同的交互且与框架无关)。
### 1.3 路由与菜单
- **禁止**直接写 **`localStorage.authorityMenus`**、**`localStorage.menuList`** 替代 **`user` 模块 mutation/action**(除非你在做迁移脚本且不在运行时页面)。
- **禁止**绕过 **`setAuthorityMenus`** 直接 **`router.addRoutes`** 拼装主布局(会与框架内 **`router.options.routes` splice + addRoute** 逻辑冲突)。
### 1.4 命名与兼容
- **禁止**接口/表单字段 **`snake_case` 与 `camelCase` 双读兜底**(如 `row.user_id ?? row.userId`),除非后端合同明文双写且规范文档特许。
- **禁止**对框架已约定 API 的 **`ref`** 写 **`typeof ref.show === 'function'`**、**`if (!this.$refs.modal) return`** 等防御式分支(规范用法下 ref 由模板绑定保证;若条件渲染导致 ref 不稳定,应调整 `v-if` 与调用时机,而非堆兼容分支)。
---
## 2. 必须项(代码审查硬标准)
### 2.1 请求与错误
- **必须**使用 **`this.$http`**(组件)或 **`AdminFramework.http`**(非组件);二者指向同一封装实例。
- **必须**对 `await this.$http.*` 使用 **`try/catch`**(或等价的 `.catch`);原因:后端 **`code !== 0`**、网络错误、401 均可能 **reject**;拦截器已 `Message.error` 时catch 内可避免重复弹窗,但**不可**空 catch 吞掉需上报的逻辑。
- **必须**对**写库、改状态**类接口优先使用 **`POST`**,路径 **`snake_case`** 分段(与后端控制器风格一致)。
### 2.2 Loading 策略
- **必须**用 **`this.$http.get(url, params, { hideLoad: true })`** 实现无感轮询/预加载;**不得**为绕过 `post` 的强制 loading 而引入 axios。
- 若业务确需「POST 且无 loading」**正确做法**是扩展 **`admin_core` 的 `http.post`**(例如增加可选 `config.hideLoad`)并升版框架,**禁止**仅在业务仓库私改 axios。
### 2.3 动态路由与 `componentMap`
- **必须**保证后端菜单「页面/功能」行的 **`component`** 在 **`setupComponentMap` / `addComponentMap`** 合并后的表可解析。
- **必须**在新菜单页合并前本地验证:**`uiTool.getComponent(菜单路径)`**(或通过实际登录 + 点击菜单)无「组件未找到」占位。
- 映射键:**建议**与菜单字符串完全一致;框架虽自动补 **无 `.vue` / 有 `.vue`** 双键,但**路径前缀、大小写、子目录**仍须一致。
### 2.4 刷新菜单与标题
- 菜单 CRUD 后刷新侧栏:**必须** `dispatch('user/setAuthorityMenus', { Main, ParentView, Page404, HomePage })`(参数与 **`sys_menu.vue`** 等处一致,使用 **`this.$framework.components`** 与 **`this.$framework.pages`** / **`HomePage`**)。
- 修改站点标题/Logo 后:**必须** `dispatch('app/getSysTitle', { defaultTitle: this.$config.title, defaultLogo: '' })`**带 `app/` 命名空间**)。
### 2.5 框架组件 `ref` 调用
- **`AsyncModal`、`FloatPanel`、`editModal`****直接** `this.$refs.xxx.show()` / `hide()` / 文档约定方法;**禁止**多套 hide 回退、反射内部 state。
- 若组件为 `v-if` 控制,**必须**在 **`$nextTick`** 后再调 `ref` 方法,而不是写「若不存在则静默 return」掩盖时序 bug。
### 2.6 子组件内聚
- 表单 **`data` / `rules` / `loading` / `visible`**、校验、重置:**必须**放在子组件内;父组件只传 **`id`**、**只读上下文**、**`@success`** 等;**禁止**父组件 `v-model` 绑十几项内部字段。
---
## 3. `createApp` 入口(硬约束)
- **必须** `AdminFramework.createApp(config)` 得到根实例后再 **`$mount`**。
- **`config.apiUrl` 必填**`title`、`componentMap`、`HomePage`、`onReady` 按项目需要。
- **不得**在业务页重复 `Vue.use(VueRouter)` / `Vuex` / `ViewUI` 以替换框架已注册插件(二次 `createApp` 也不会卸载已 `Vue.use` 的插件,易脏状态)。
### 3.1 运行时补映射
- **必须**使用 **`AdminFramework.addComponentMap(map)`****禁止**直接改 **`uiTool`** 内部 `componentMap` 对象引用。
---
## 4. Token 与 Cookie与 `tools.js` 一致)
- Cookie 键 **`TOKEN_KEY === 'token'`**(不是 `admin-token`**HTTP 请求头**才是 **`admin-token`**,值来自 **`store.state.user.token`**。
- 登录/登出须走 **`user`** 模块的 **`setToken` / `handleLogOut`**,保证 Cookie 与 store 一致。
---
## 5. 反例与正例(摘要)
| 反例 | 正例 |
|------|------|
| `import axios from 'axios'; axios.get(...)` | `await this.$http.get(...)` |
| `headers: { 'admin-token': xxx }` | 使用 `this.$http`token 由 store 注入 |
| `dispatch('getSysTitle')` | `dispatch('app/getSysTitle', { ... })` |
| `post` 轮询且无 loading | `get` + `{ hideLoad: true }` 或扩展框架 |
| `receiving_id ?? receivingId` | 只使用合同字段名(如 `receiving_id` |
| `if (this.$refs.m && this.$refs.m.show) this.$refs.m.show()` | `this.$nextTick(() => this.$refs.m.show())` |
---
## 6. 提交前自检(详尽清单)
- [ ] 全文搜索 **`import axios`** / **`axios.create`**(业务目录应为 0
- [ ] 全文搜索 **`admin-token`**(除注释外应为 0框架内 `fileExport` 除外若复制代码)。
- [ ] 变更接口是否 **`POST`** + **`snake_case`** URL。
- [ ] 新页面是否已写入 **`componentMap`**(或运行时 **`addComponentMap`**)。
- [ ] 标题刷新是否 **`app/getSysTitle`**。
- [ ] 所有 **`await this.$http`** 是否处于 **`try/catch`** 或链式 **`catch`**。
- [ ] 是否存在 **`??` 双字段名**、**`typeof === 'function'` ref 防御**(应删除或改为规范时序)。
- [ ] 子组件是否仍接收大量「仅表单内部使用」的 props应内聚