init
This commit is contained in:
114
.cursor/rules/admin-framework-strict.mdc
Normal file
114
.cursor/rules/admin-framework-strict.mdc
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
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(应内聚)。
|
||||
Reference in New Issue
Block a user