Files
rui-docs/frontend/design/admin-ui-module-build-design.md
vifo d0771597a6 init: 初始化项目文档中心
- 添加前端设计文档(rui-admin、收银系统、模块打包)
- 添加前端实施计划(收银后台功能完善)
- 添加通用规范(API、编码、数据库、前端开发规则)
- 建立文档索引和使用指南
2026-06-04 08:47:08 +08:00

372 lines
13 KiB
Markdown
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.
# Admin-UI 分模块打包功能设计文档
> **设计日期**: 2026-06-04
> **版本**: v1.0
> **状态**: 已批准
> **目标**: 实现 Admin-UI 按系统配置分模块打包,支持不同租户类型输出不同产物包
---
## 一、背景与目标
### 1.1 现状分析
当前 Admin-UI 存在以下问题:
1. **路由硬编码**:所有页面路由集中在 `router/index.ts` 中硬编码,无法按模块裁剪
2. **构建产物单一**:无论服务哪个租户,都打包所有页面代码,产物体积大
3. **缺乏系统差异化**:Dashboard、登录页等核心页面无法根据不同系统定制
4. **模块管理已有雏形**:后端已支持租户模块配置(`ModuleDialog.vue`),但前端构建未与之配合
### 1.2 目标定义
1. **构建时分包**:根据 JSON 配置文件,构建时只打包指定模块的代码
2. **动态路由生成**:替换硬编码路由,构建时根据配置动态生成路由表
3. **系统差异化页面**:支持 Dashboard、登录页按系统配置加载不同子组件
4. **多产物输出**:不同系统输出到 `dist/{systemKey}/` 目录
5. **保持现有功能**:菜单 API 获取、权限控制、主题切换等功能不受影响
---
## 二、详细设计
### 2.1 整体架构
```
构建流程:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ build-config/ │ │ Vite Plugin │ │ 构建产物 │
│ cashier.json │────→│ (module-build) │────→│ dist/cashier/ │
│ admin.json │ │ │ │ dist/admin/ │
│ super.json │ │ 1. 读取配置 │ │ dist/super/ │
└─────────────────┘ │ 2. 生成路由 │ │ │
│ 3. 注入配置 │ └─────────────────┘
│ 4. 配置输出 │
└──────────────────┘
运行时:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 统一入口页面 │────→│ 虚拟模块配置 │────→│ 系统特定子组件 │
│ Dashboard │ │ __SYSTEM_CONFIG__│ │ systems/ │
│ Login │ │ │ │ Cashier.vue │
└─────────────────┘ └──────────────────┘ │ Super.vue │
└─────────────────┘
```
### 2.2 核心组件
#### 2.2.1 配置文件(`build-config/`
每个系统一个 JSON 配置文件:
```typescript
interface BuildConfig {
/** 系统唯一标识,产物目录名 */
key: string
/** 系统显示名称 */
name: string
/** 系统描述 */
description?: string
/** 包含的模块列表 */
modules: string[]
/** 登录页配置 */
login: {
/** 登录组件名(对应 views/login/systems/ 下的组件) */
component: string
/** 是否显示租户ID输入 */
showTenantInput: boolean
/** 页面标题 */
title: string
/** 副标题 */
subtitle?: string
/** 背景图路径 */
background?: string
/** Logo路径 */
logo?: string
}
/** Dashboard配置 */
dashboard: {
/** Dashboard组件名(对应 views/dashboard/systems/ 下的组件) */
component: string
/** 页面标题 */
title: string
}
/** 主题配置 */
theme: {
/** 主题色 */
primaryColor: string
/** 页面标题 */
title: string
}
}
```
**示例配置:**
```json
// build-config/super.json
{
"key": "super",
"name": "超级管理后台",
"description": "超级租户专用,包含租户管理",
"modules": ["system", "user"],
"login": {
"component": "Super",
"showTenantInput": false,
"title": "睿核平台管理",
"subtitle": "超级管理员登录"
},
"dashboard": {
"component": "Super",
"title": "平台运营概览"
},
"theme": {
"primaryColor": "#722ed1",
"title": "睿核平台管理"
}
}
```
```json
// build-config/cashier.json
{
"key": "cashier",
"name": "收银系统",
"description": "面向收银场景的管理后台",
"modules": ["system", "user", "cms", "cashier"],
"login": {
"component": "Cashier",
"showTenantInput": true,
"title": "睿核收银",
"subtitle": "门店管理系统"
},
"dashboard": {
"component": "Cashier",
"title": "收银数据概览"
},
"theme": {
"primaryColor": "#1677ff",
"title": "睿核收银"
}
}
```
#### 2.2.2 Vite 插件(`scripts/vite-plugin-module-build.ts`
插件职责:
1. **解析命令行参数**:读取 `--system={key}` 参数
2. **加载配置**:读取 `build-config/{key}.json`
3. **生成虚拟路由模块**`virtual:generated-routes`
- 根据 `config.modules` 从路由模板中组装路由表
- 只包含指定模块的路由 + 核心页面路由(登录、Dashboard入口、个人中心、设置)
4. **生成虚拟配置模块**`virtual:system-config`
- 将配置对象注入为全局常量 `__SYSTEM_CONFIG__`
5. **配置构建输出**
- `build.outDir = dist/${config.key}`
- `build.rollupOptions.treeshake = true` 确保未使用代码被移除
**路由生成逻辑:**
```typescript
// router/modules/system.ts
export const systemRoutes = [
{ path: 'system/menu', name: 'SystemMenu', component: () => import('@/views/system/menu/Index.vue'), meta: { i18n: 'menu.systemMenu' } },
{ path: 'system/role', name: 'SystemRole', component: () => import('@/views/system/role/Index.vue'), meta: { i18n: 'menu.systemRole' } },
// ...
]
// router/modules/user.ts
export const userRoutes = [
{ path: 'user/info', name: 'UserInfo', component: () => import('@/views/user/info/Index.vue'), meta: { i18n: 'menu.userInfo' } },
// ...
]
// 插件根据 config.modules 动态组装
const moduleRoutes = config.modules.flatMap(module => {
const routeModule = routeModules[module]
return routeModule ? routeModule.routes : []
})
```
#### 2.2.3 统一入口页面
**Dashboard 入口(`views/dashboard/Index.vue`):**
```vue
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import systemConfig from 'virtual:system-config'
// 动态加载系统特定的 Dashboard 组件
const dashboardComponent = defineAsyncComponent(() =>
import(`./systems/${systemConfig.dashboard.component}.vue`)
)
</script>
<template>
<component :is="dashboardComponent" />
</template>
```
**登录页入口(`views/login/Index.vue`):**
```vue
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import systemConfig from 'virtual:system-config'
// 动态加载系统特定的登录组件
const loginComponent = defineAsyncComponent(() =>
import(`./systems/${systemConfig.login.component}.vue`)
)
</script>
<template>
<component :is="loginComponent" :config="systemConfig.login" />
</template>
```
### 2.3 模块映射关系
建立 `src/views/` 下的页面目录与模块标识的映射:
| 模块标识 | 对应目录 | 包含页面 |
|---------|---------|---------|
| `system` | `views/system/*` | 菜单、角色、部门、岗位、字典、配置、日志、登录日志、租户、租户套餐、数据权限、OAuth2客户端 |
| `user` | `views/user/*` | 用户信息、用户详情、等级、等级日志、地址、账户 |
| `order` | `views/order/*` | 订单列表、退款记录 |
| `cms` | `views/cms/*` | 文章、分类、轮播图 |
| `marketing` | `views/marketing/*` | 优惠券、活动管理 |
| `demo` | `views/demo/*` | 图标演示、列表演示 |
| `cashier` | `views/cashier/*` | 门店、包间、定价、订单、商品、报表 |
**核心页面(所有系统默认包含,不依赖模块配置):**
- `views/login/Index.vue` - 登录页入口
- `views/login/systems/*.vue` - 系统特定登录组件
- `views/dashboard/Index.vue` - Dashboard 入口
- `views/dashboard/systems/*.vue` - 系统特定 Dashboard 组件
- `views/profile/Index.vue` - 个人中心
- `views/settings/Index.vue` - 系统设置
### 2.4 目录结构
```
admin-ui/
├── build-config/ # 系统打包配置
│ ├── cashier.json
│ ├── admin.json
│ ├── super.json
│ └── default.json # 默认配置(全模块,用于开发)
├── scripts/ # 构建脚本
│ └── vite-plugin-module-build.ts # Vite 插件
├── src/
│ ├── router/
│ │ ├── index.ts # 改造:使用虚拟路由模块
│ │ └── modules/ # 新增:按模块拆分路由配置
│ │ ├── core.ts # 核心路由(登录、Dashboard入口等)
│ │ ├── system.ts
│ │ ├── user.ts
│ │ ├── order.ts
│ │ ├── cms.ts
│ │ ├── marketing.ts
│ │ ├── demo.ts
│ │ └── cashier.ts
│ ├── views/
│ │ ├── login/
│ │ │ ├── Index.vue # 改造:统一入口
│ │ │ └── systems/ # 新增:系统特定登录组件
│ │ │ ├── Default.vue # 默认登录页
│ │ │ ├── Super.vue # 超级租户登录页
│ │ │ └── Cashier.vue # 收银系统登录页
│ │ ├── dashboard/
│ │ │ ├── Index.vue # 改造:统一入口
│ │ │ └── systems/ # 新增:系统特定 Dashboard
│ │ │ ├── Default.vue # 默认 Dashboard
│ │ │ ├── Cashier.vue # 收银系统 Dashboard
│ │ │ └── Super.vue # 超级租户 Dashboard
│ │ └── ... # 业务页面(保持现有结构)
│ ├── types/
│ │ └── system-config.d.ts # 系统配置类型定义
│ └── ...
├── package.json # 改造:添加构建命令
└── vite.config.ts # 改造:注册插件
```
### 2.5 构建命令
```json
// package.json
{
"scripts": {
"dev": "vite --port 3000",
"dev:cashier": "vite --port 3000 -- --system=cashier",
"dev:super": "vite --port 3000 -- --system=super",
"build": "vue-tsc && vite build",
"build:cashier": "vue-tsc && vite build -- --system=cashier",
"build:super": "vue-tsc && vite build -- --system=super",
"build:admin": "vue-tsc && vite build -- --system=admin",
"build:all": "pnpm build:cashier && pnpm build:super && pnpm build:admin"
}
}
```
**产物输出:**
```
dist/
├── cashier/ # 收银系统(system + user + cms + cashier
├── super/ # 超级租户(system + user
├── admin/ # 普通后台(system + user + order + cms + marketing
└── default/ # 默认(全模块,用于开发测试)
```
### 2.6 主题配置应用
系统配置中的 `theme` 字段在运行时应用:
```typescript
// App.vue 或布局组件
import systemConfig from 'virtual:system-config'
// 设置页面标题
document.title = systemConfig.theme.title
// 设置主题色(Element Plus
const el = document.documentElement
el.style.setProperty('--el-color-primary', systemConfig.theme.primaryColor)
```
---
## 三、验收标准
- [ ] 执行 `pnpm build:super` 成功构建,产物输出到 `dist/super/`,只包含 system 和 user 模块的页面
- [ ] 执行 `pnpm build:cashier` 成功构建,产物输出到 `dist/cashier/`,包含 system、user、cms、cashier 模块的页面
- [ ] 不同系统的 Dashboard 显示不同的子组件内容
- [ ] 不同系统的登录页显示不同的子组件内容(超级租户无租户ID输入)
- [ ] 构建产物中不包含未配置模块的页面代码(Tree Shaking 生效)
- [ ] 现有菜单 API 获取、权限控制、主题切换功能正常
- [ ] 开发模式 `pnpm dev:cashier` 正常工作,热更新无问题
---
## 四、风险与依赖
| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| Vite 插件开发复杂度 | 中 | 插件逻辑清晰拆分:配置读取、路由生成、虚拟模块、输出配置 |
| Tree Shaking 不彻底 | 中 | 使用 `import()` 动态导入,配合 Rollup 的 `treeshake` 配置,构建后检查产物 |
| 动态组件加载失败 | 低 | 添加错误处理,加载失败时回退到 Default 组件 |
| 现有功能回归 | 中 | 构建后逐一验证核心功能:登录、菜单、CRUD、主题切换 |
| 多人协作冲突 | 低 | 配置文件集中管理,模块路由独立文件,减少冲突 |
---
## 五、后续扩展
1. **国际化支持**:配置文件中可扩展 `locales` 字段,支持系统特定的翻译覆盖
2. **模块懒加载**:未来可考虑运行时动态加载模块(Module Federation
3. **版本管理**:配置文件支持 `version` 字段,用于产物版本控制
4. **CI/CD 集成**:构建命令可直接接入 Jenkins/GitHub Actions,参数化构建不同系统