291 lines
12 KiB
Plaintext
291 lines
12 KiB
Plaintext
---
|
||
description: Admin 前端 admin-framework 使用约定(详尽版,对照 admin_core 与 README)
|
||
globs: admin/src/**/*.{vue,js},admin_core/src/**/*.{vue,js}
|
||
alwaysApply: false
|
||
---
|
||
|
||
# Admin Framework 使用约定(详尽)
|
||
|
||
适用于 **Vue 2 + Vue Router 3 + Vuex 3 + View Design** 的后台;约定与 **`admin_core` 源码**、根目录 **`README.md`**、分发 **`admin-framework.md`** 一致。默认构建产物为 **`dist/admin-framework.js`(UMD)**,浏览器全局为 **`window.AdminFramework`** / **`window.framework`**(单例)。
|
||
|
||
---
|
||
|
||
## 1. 依赖与引入
|
||
|
||
### 1.1 Peer 依赖(须由宿主安装)
|
||
|
||
`vue`、`vue-router`、`vuex`、`view-design`、`axios` 等须满足 **`package.json` 中 peerDependencies**;打包时将框架作 externals 或正常解析均可,须与 UMD externals 一致。
|
||
|
||
### 1.2 入口最小示例
|
||
|
||
```javascript
|
||
import AdminFramework from 'admin-framework' // 或 dist 路径
|
||
import componentMap from './router/component-map.js'
|
||
|
||
const app = AdminFramework.createApp({
|
||
title: '某某管理系统',
|
||
apiUrl: 'https://api.example.com/admin_api/',
|
||
componentMap,
|
||
HomePage: null, // 可选:自定义首页组件
|
||
onReady() {
|
||
// this 为根 Vue 实例
|
||
}
|
||
})
|
||
app.$mount('#app')
|
||
```
|
||
|
||
---
|
||
|
||
## 2. `createApp(config)` 配置项
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `apiUrl` | string | **必填**;`http` 的 `baseURL` |
|
||
| `uploadUrl` | string | 可选;不传则按 `apiUrl` 自动拼 `upload` 或 `/upload` |
|
||
| `title` | string | 默认 `document.title`、未登录或 `getSysTitle` 失败时的标题基线 |
|
||
| `componentMap` | object | 业务页组件路径 → 组件构造器;与菜单 `component` 字段对应 |
|
||
| `HomePage` | Component | 可选;覆盖默认欢迎首页 |
|
||
| `onReady` | function | 可选;根实例 `created` 末尾、`this` 指向根实例 |
|
||
|
||
**执行后**可用:`AdminFramework.store`、`AdminFramework.router`、`AdminFramework.config`、`AdminFramework.http`、`AdminFramework.uiTool`、`AdminFramework.tools` 等(与单例上字段一致)。
|
||
|
||
---
|
||
|
||
## 3. 框架单例 API 速查(`index.js` / README)
|
||
|
||
| API | 用途 |
|
||
|-----|------|
|
||
| `createApp(config)` | 一键创建 store、router、根实例 |
|
||
| `addComponentMap(customMap)` | 运行时合并组件映射(内部 `setupComponentMap`) |
|
||
| `initHttp(config, store)` | 非 `createApp` 场景手动绑定 http 与 store |
|
||
| `version` | 版本字符串 |
|
||
| `pages` | 内置登录、错误页、部分系统页导出 |
|
||
| `components` | **Main**、**ParentView**、**Tables**、**AsyncModal**、**editModal**、**FieldRenderer** 等 |
|
||
| `systemApi` | `src/api/system` 聚合(框架自带系统接口封装) |
|
||
| `storeModules` | 默认 `user`/`app` 模块引用,扩展 store 时可参考 |
|
||
| `createBaseRoutes` / `setupRouterGuards` / `createRouter` / `getRoutes` | 高级自定义路由时使用 |
|
||
| `registerComponents` / `registerGlobalComponents` | 高级注册组件 |
|
||
|
||
---
|
||
|
||
## 4. 全局注入(`createApp` 内)
|
||
|
||
- **`Vue.prototype.$config`**:`createApp` 的 config。
|
||
- **`$http`**、`$tools`**、`$uiTool`**、`$framework`**:与单例一致。
|
||
|
||
组件内推荐 **`this.$http`** / **`this.$uiTool`**;单元测试或非组件模块可用 **`AdminFramework.http`**。
|
||
|
||
---
|
||
|
||
## 5. HTTP 模块(`src/utils/http.js`)
|
||
|
||
### 5.1 成功约定
|
||
|
||
- 后端 JSON:**`code === 0`** 为业务成功;否则拦截器 **`Message.error`** 并 **reject**。
|
||
- `get`/`post` 返回的 Promise **resolve 值为 `response.data`**(即整包 `{ code, message, data }`),业务通常再判断 **`res.code === 0`** 后使用 **`res.data`**。
|
||
|
||
### 5.2 方法一览
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `get(url, param, config)` | Query;**`config.hideLoad`** 为 true 时不显示全局 loading |
|
||
| `post(url, param, config)` | JSON body;**始终**显示 loading |
|
||
| `postFormData(url, data)` | `application/x-www-form-urlencoded` |
|
||
| `fileExport(url, param, filename, is_down)` | `blob` 下载;默认 **`is_down=true`** 时内部 **`uiTool.downloadFile`** |
|
||
| `baseUrl()` | 当前 `apiUrl` |
|
||
| `ImgSrc(src)` | `baseUrl() + src` |
|
||
|
||
### 5.3 401 行为
|
||
|
||
- 清空 **`user.token`**;依赖 **`window.framework.router`** 跳转 **`/login`**(布局代码应避免在非浏览器环境假设 router 已挂 window)。
|
||
|
||
---
|
||
|
||
## 6. uiTool 模块(README §6 整段,`src/utils/uiTool.js`)
|
||
|
||
通过 **`this.$uiTool`** 或 **`AdminFramework.uiTool`** 使用(**类静态方法**)。
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `setComponentMap(map)` | 合并组件映射表 |
|
||
| `getComponent(path)` | 按路径取组件,`path` 可带或不带 `.vue` |
|
||
| `downloadFile(res, fileName)` | Blob 下载 |
|
||
| `setRem()` | 根据屏宽设置根字体(自适应) |
|
||
| `getImgSrc(src)` | 图片地址(同 http 规则) |
|
||
| `getBtn(h, options)` | Render 函数里生成操作按钮组 |
|
||
| `getDropdown(h, items)` | 下拉更多菜单 |
|
||
| `delConfirm(callback)` | 删除确认框 |
|
||
| `showConfirm({ title, content }, callback)` | 通用确认框 |
|
||
| `transformTree(list, cb)` | 扁平列表转树 |
|
||
| `subTree` / `menuToRoute` / `getRoutes` | 菜单转路由(框架内部与权限菜单配合) |
|
||
|
||
**树表示例:**
|
||
|
||
```javascript
|
||
const tree = this.$uiTool.transformTree(flatListFromApi)
|
||
```
|
||
|
||
**与路由、菜单的衔接**:`menuToRoute`、`getRoutes` 与动态权限、`componentMap` 的配合见 **`admin-framework-routing-store.mdc`**;`downloadFile` 与 **`this.$http.fileExport`** 配合见本文 §5。
|
||
|
||
---
|
||
|
||
## 6.2 通用工具 `tools`(README §6.2,`src/utils/tools.js`)
|
||
|
||
通过 **`this.$tools`** 使用(具体以源码为准)。
|
||
|
||
常用包括:
|
||
|
||
- **Cookie / Token**:`getToken`、`setToken`、`TOKEN_KEY`
|
||
- **日期**:`formatDate(val, fmt)`(dayjs)
|
||
- **数组**:`forEach`、`hasOneOf`、`getUnion`、`getIntersection`
|
||
- **对象**:`objEqual`、`removeEmptyObject`、`isNullorEmpty`
|
||
- **路由/菜单**:`getBreadCrumbList`、`getHomeRoute`、`getMenuByRouter`、`filterMenu`
|
||
- **本地存储**:`localSave`、`localRead`
|
||
- **其它**:`generateUUID`、`getUrlParam`、`downStream`、`scrollTop` 等
|
||
|
||
**示例:**
|
||
|
||
```javascript
|
||
if (this.$tools.getToken()) { /* 已登录 */ }
|
||
```
|
||
|
||
---
|
||
|
||
## 6.3 表格组件 `Tables`(README §12.2)
|
||
|
||
基于 View Design **`Table`** 封装,支持分页条、导出、列配置、可编辑列等。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `value` | 表格数据数组 |
|
||
| `columns` | 列配置(同 iView Table `columns`,框架内会做对齐等默认处理) |
|
||
| `title` / `tip` | 表格标题与灰色提示 |
|
||
| `isDown` | 为 true 且 `value` 非空时显示「下载」链接触发导出 |
|
||
| `pageOption` | 分页:`{ page, pageSize, total }`,存在则显示 `Page` |
|
||
| `width` / `height` | 传给内部 Table |
|
||
| `maxHeightOffset` | 表格外层最大高度:`auto`(默认,按视口计算)或数字,用于 `calc(100vh - offset)` |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| `header` | 标题行右侧区域 |
|
||
| 默认 | 透传给内部 Table(如 `slot-scope` 列) |
|
||
| `footer` / `loading` | 透传 Table 同名插槽 |
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `changePage` | 分页变更(内部已更新 `pageOption.page`) |
|
||
| `on-select` | 多选变化 |
|
||
| `downExecl` | 点击下载时,`{ value, columns }` |
|
||
|
||
```vue
|
||
<Tables
|
||
:value="tableData"
|
||
:columns="columns"
|
||
:page-option="{ page: 1, pageSize: 10, total: 100 }"
|
||
title="用户列表"
|
||
@changePage="loadData"
|
||
/>
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 系统 API(`systemApi`,README §8 整段)
|
||
|
||
`AdminFramework.systemApi` 聚合导出 **`admin_core/src/api/system/index.js`** 中的服务(与源码 `export { default as ... }` 一致;以下为当前版本完整导出)。
|
||
|
||
| 导出名 | 模块文件 | 典型用途 |
|
||
|--------|----------|----------|
|
||
| `fileServe` | `fileServe.js` | 文件上传下载 |
|
||
| `plaAccountServer` | `pla_account_server.js` | 平台账号管理 |
|
||
| `rolePermissionServer` | `rolePermissionServer.js` | 角色权限 |
|
||
| `roleServer` | `roleServer.js` | 角色管理 |
|
||
| `sysAddressServer` | `sysAddressServer.js` | 地址字典 |
|
||
| `sysModuleServer` | `sysModuleServer.js` | 模块管理 |
|
||
| `sysLogServe` | `sys_log_serve.js` | 系统日志 |
|
||
| `systemTypeServer` | `systemType_server.js` | 系统类型配置 |
|
||
| `tableServer` | `tableServer.js` | 表结构相关 |
|
||
| `userServer` | `userServer.js` | 登录、用户 CRUD、权限菜单 |
|
||
| `formFieldServer` | `formFieldServer.js` | 表单字段 |
|
||
| `formServer` | `formServer.js` | 表单模型 |
|
||
| `menuServer` | `menuServer.js` | 菜单管理 |
|
||
| `modelFieldServer` | `modelFieldServer.js` | 数据模型字段 |
|
||
| `modelServer` | `modelServer.js` | 数据模型 |
|
||
| `paramSetupServer` | `paramSetupServer.js` | 系统参数(标题、Logo) |
|
||
| `sysControlTypeServer` | `sysControlTypeServer.js` | 控件类型 |
|
||
| `sysTenantServer` | `sysTenantServer.js` | 租户管理 |
|
||
|
||
**调用示例:**
|
||
|
||
```javascript
|
||
const { userServer } = AdminFramework.systemApi
|
||
|
||
async function login() {
|
||
const res = await userServer.login({ username: 'admin', password: '***' })
|
||
if (res.code === 0) {
|
||
// 写入 token、拉菜单等由登录页与 store 配合完成
|
||
}
|
||
}
|
||
```
|
||
|
||
实际请求仍走全局配置的 **`http`**(`apiUrl`、`admin-token` 头)。
|
||
|
||
> **说明**:`src/api/system` 中若存在**未**在 **`index.js`** 聚合导出的文件(例如实验性模块),**不会**出现在 **`AdminFramework.systemApi`**;新增系统接口时须同时 **`export`** 才能在框架聚合对象上访问。
|
||
|
||
---
|
||
|
||
## 8. Vuex 内置模块
|
||
|
||
### 8.1 `user`(namespaced)
|
||
|
||
- **state**:`token`、`userName`、`authorityMenus`、`menuList`、`currentTenant`、`avatorImgPath` 等。
|
||
- **常用 action**:**`handleLogin`**、**`handleLogOut`**、**`setAuthorityMenus`**。
|
||
- **租户**:**`currentTenant`** 与 **`localStorage.currentTenant`** 由 **`setCurrentTenant`** 同步。
|
||
|
||
### 8.2 `app`(namespaced)
|
||
|
||
- **state**:**`sysFormModel`**(标题、Logo)、**`breadCrumbList`**、**`homeRoute`**。
|
||
- **action**:**`getSysTitle`** — 必须使用 **`app/getSysTitle`** 形式 dispatch。
|
||
|
||
### 8.3 扩展 Store
|
||
|
||
```javascript
|
||
import { createStore } from 'admin-framework/src/store' // 按实际包路径调整
|
||
import createPersistedState from 'vuex-persistedstate'
|
||
|
||
// 第三个参数传工厂函数则启用持久化
|
||
const store = createStore(Vuex, { myModule }, createPersistedState)
|
||
```
|
||
|
||
默认 **`createApp`** 内为 **`createStore(Vuex, {}, null)`**,即**无** persistedstate 插件。
|
||
|
||
---
|
||
|
||
## 9. 路由
|
||
|
||
- **Hash 模式**(`router/index.js`)。
|
||
- **动态菜单**:依赖 **`localStorage.authorityMenus`** + **`setAuthorityMenus`** 与 **`router.addRoute`**;详见 routing-store 文档。
|
||
- **守卫**:未登录跳转登录、已登录访问登录重定向 **`home`**、动态路由未命中延迟重试等,见 routing-store 文档。
|
||
|
||
---
|
||
|
||
## 10. 与后端协作约定
|
||
|
||
- **管理端 API** 路径通常带 **`/admin_api/`** 前缀(以项目 `apiUrl` 为准)。
|
||
- **请求体/查询**:与 Node 端 **`snake_case`** 字段对齐;前端展示层若用驼峰,应在边界单次映射,避免全页双写。
|
||
- **分页**:若后端使用框架 **`ctx.getPageSize`**,则与 **`pageOption`** JSON 约定一致(见 node-core 规范)。
|
||
|
||
---
|
||
|
||
## 11. 调试与排错
|
||
|
||
- **`window.framework`**:单例、router、store、config。
|
||
- **`window.rootVue`**:`createApp` 返回的根实例。
|
||
- 动态页空白:控制台搜 **「组件未找到」**;检查菜单 **`component`** 与 **`componentMap`**。
|
||
- 刷新后丢菜单:检查 **`token`** 与 **`localStorage.authorityMenus`** 是否仍存在、是否执行了 **`setAuthorityMenus`**。
|
||
|
||
---
|
||
|
||
## 12. 版本与构建
|
||
|
||
- 框架版本见 **`AdminFramework.version`** 与 **`README`**;发版时注意 **`admin-framework.js`** 与 **`admin-framework.md`** 同步分发。
|