This commit is contained in:
张成
2025-10-08 21:42:22 +08:00
parent 07aa8d493a
commit 453414f647
6 changed files with 1791 additions and 2 deletions

View File

@@ -0,0 +1,143 @@
# 快速配置组件映射
## 🎯 一句话说明
**在 `Vue.use()` 时传入 `componentMap` 参数,将后端权限菜单中的组件路径映射到实际组件。**
## 📝 三步配置
### 步骤1查看权限菜单接口
查看后端接口返回的所有 `component` 字段:
```json
{
"data": [
{ "component": "ball/games.vue" },
{ "component": "order/pay_orders.vue" },
{ "component": "ball/wch_users.vue" }
]
}
```
### 步骤2创建并导入组件
```javascript
// src/main.js
import GamesComponent from './views/ball/games.vue'
import PayOrdersComponent from './views/order/pay_orders.vue'
import WchUsersComponent from './views/ball/wch_users.vue'
```
### 步骤3配置映射
```javascript
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent,
'ball/wch_users': WchUsersComponent
}
})
```
## ✅ 完成!
现在权限菜单中的所有业务页面都能正常显示了。
## 📋 配置模板
```javascript
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ViewUI from 'view-design'
import createPersistedState from 'vuex-persistedstate'
import 'view-design/dist/styles/iview.css'
import AdminFramework from '../../src/index.js'
import config from './config'
import App from './App.vue'
// ==================== 导入业务组件 ====================
// TODO: 根据权限菜单接口,导入所有业务组件
// import XXXComponent from './views/xxx/xxx.vue'
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
// TODO: 配置组件映射
// 'xxx/xxx': XXXComponent
}
})
new Vue({
el: '#app',
router: AdminFramework.router,
store: AdminFramework.store,
render: h => h(App),
mounted() {
AdminFramework.uiTool.setRem()
this.$store.dispatch('user/setAuthorityMenus', {
Main: AdminFramework.Main,
ParentView: AdminFramework.ParentView,
Page404: AdminFramework.Page404
})
}
})
```
## 💡 关键要点
### 1. 路径不需要 .vue 后缀
```javascript
// ✅ 正确
componentMap: {
'ball/games': GamesComponent
}
// ❌ 错误(虽然也能用,但不推荐)
componentMap: {
'ball/games.vue': GamesComponent
}
```
### 2. 系统组件无需配置
这些已自动映射,**不需要**在 componentMap 中配置:
- `home/index.vue`
- `system/sys_user.vue`
- `system/sys_role.vue`
- `system/sys_log.vue`
- `system/sys_param_setup.vue`
- `system_high/sys_menu.vue`
- `system_high/sys_control.vue`
- `system_high/sys_title.vue`
### 3. 未映射的组件会显示提示
如果组件没有配置映射,页面会显示:
```
⚠️ 警告
页面组件未加载: ball/games.vue
请在项目中创建此组件或在组件映射表中注册
```
## 📚 完整文档
查看详细说明:[权限菜单组件配置指南.md](./权限菜单组件配置指南.md)
---
**配置完成后,所有权限菜单中的页面都能正常显示!** 🎉

View File

@@ -0,0 +1,575 @@
# 权限菜单组件配置指南
## 🎯 核心问题
**问题**:后端权限菜单接口返回的组件路径需要映射到实际组件,否则会显示 404。
**解决**:在 `Vue.use()` 时传入 `componentMap` 参数,一次性注册所有业务组件。
## 📝 配置步骤
### 第一步:查看权限菜单接口返回的组件路径
后端接口返回的菜单数据示例:
```json
{
"code": 0,
"data": [
{ "component": "home/index.vue" },
{ "component": "system/sys_user.vue" },
{ "component": "ball/games.vue" },
{ "component": "order/pay_orders.vue" },
{ "component": "ball/wch_users.vue" }
]
}
```
### 第二步:创建对应的业务组件
在项目中创建对应的组件文件:
```
src/views/
├── ball/
│ ├── games.vue
│ └── wch_users.vue
└── order/
└── pay_orders.vue
```
### 第三步:在 main.js 中配置组件映射
```javascript
import Vue from 'vue'
import AdminFramework from '../../src/index.js'
import config from './config'
// ✅ 导入所有业务组件(根据权限菜单接口的 component 字段)
import GamesComponent from './views/ball/games.vue'
import PayOrdersComponent from './views/order/pay_orders.vue'
import WchUsersComponent from './views/ball/wch_users.vue'
// 使用框架
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
// ✅ 一次性注册所有组件映射
componentMap: {
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent,
'ball/wch_users': WchUsersComponent
// 添加更多业务组件...
}
})
// 创建 Vue 实例
new Vue({
el: '#app',
router: AdminFramework.router,
store: AdminFramework.store,
render: h => h(App),
mounted() {
// 设置权限菜单(会自动加载映射的组件)
this.$store.dispatch('user/setAuthorityMenus', {
Main: AdminFramework.Main,
ParentView: AdminFramework.ParentView,
Page404: AdminFramework.Page404
})
}
})
```
## 🔧 两种配置方式
### 方式一:在 Vue.use 时配置(推荐)
```javascript
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent
}
})
```
**优点**
- ✅ 集中配置,清晰明了
- ✅ 在框架初始化时就完成映射
- ✅ 代码简洁
### 方式二:使用 addComponentMap 方法
```javascript
Vue.use(AdminFramework, { config, ViewUI, VueRouter, Vuex, createPersistedState })
// 之后添加映射
AdminFramework.addComponentMap({
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent
})
```
**适用场景**
- 需要动态添加组件映射
- 分模块配置
## 📋 完整示例
### 根据你的权限菜单接口配置
查看你的接口返回数据,列出所有 `component` 字段:
```javascript
// 权限菜单返回的组件列表:
// - home/index.vue
// - system/sys_user.vue
// - system/sys_role.vue
// - system_high/sys_menu.vue
// - system/sys_log.vue
// - system/sys_param_setup.vue
// - ball/games.vue ← 业务组件,需要自己创建
// - ball/wch_users.vue ← 业务组件,需要自己创建
// - ball/venues.vue ← 业务组件,需要自己创建
// - order/pay_orders.vue ← 业务组件,需要自己创建
// - order/wch_wallets.vue ← 业务组件,需要自己创建
// - users/user_follows.vue ← 业务组件,需要自己创建
```
### 完整的 main.js 配置
```javascript
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ViewUI from 'view-design'
import createPersistedState from 'vuex-persistedstate'
import 'view-design/dist/styles/iview.css'
import AdminFramework from '../../src/index.js'
import config from './config'
import App from './App.vue'
// ==================== 导入业务组件 ====================
// 球局模块
import GamesComponent from './views/ball/games.vue'
import WchUsersComponent from './views/ball/wch_users.vue'
import VenuesComponent from './views/ball/venues.vue'
import GameParticipantsComponent from './views/ball/game_participants.vue'
import GameCommentsComponent from './views/ball/game_comments.vue'
// 订单模块
import PayOrdersComponent from './views/order/pay_orders.vue'
import WchWalletsComponent from './views/order/wch_wallets.vue'
import WalletTransactionsComponent from './views/order/wallet_transactions.vue'
import TransferDetailsComponent from './views/order/transfer_details.vue'
import FrozenFundsComponent from './views/order/frozen_funds.vue'
// 用户模块
import UserFollowsComponent from './views/users/user_follows.vue'
import RecommendBlocksComponent from './views/users/recommend_blocks.vue'
import UserTrackingComponent from './views/users/user_tracking.vue'
// 资源模块
import ResourcesComponent from './views/statistics/resources.vue'
import NtrQuestionsComponent from './views/ntrp/ntr_questions.vue'
import NtrRecordsComponent from './views/ntrp/ntr_records.vue'
// 消息模块
import MsgNotificationsComponent from './views/message/msg_notifications.vue'
// 使用框架
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
// ✅ 组件映射表
componentMap: {
// 球局模块
'ball/games': GamesComponent,
'ball/wch_users': WchUsersComponent,
'ball/venues': VenuesComponent,
'ball/game_participants': GameParticipantsComponent,
'ball/game_comments': GameCommentsComponent,
// 订单模块
'order/pay_orders': PayOrdersComponent,
'order/wch_wallets': WchWalletsComponent,
'order/wallet_transactions': WalletTransactionsComponent,
'order/transfer_details': TransferDetailsComponent,
'order/frozen_funds': FrozenFundsComponent,
// 用户模块
'users/user_follows': UserFollowsComponent,
'users/recommend_blocks': RecommendBlocksComponent,
'users/user_tracking': UserTrackingComponent,
// 资源模块
'statistics/resources': ResourcesComponent,
'ntrp/ntr_questions': NtrQuestionsComponent,
'ntrp/ntr_records': NtrRecordsComponent,
// 消息模块
'message/msg_notifications': MsgNotificationsComponent
}
})
// 创建 Vue 实例
new Vue({
el: '#app',
router: AdminFramework.router,
store: AdminFramework.store,
render: h => h(App),
mounted() {
AdminFramework.uiTool.setRem()
// 设置权限菜单(会自动根据映射表加载组件)
this.$store.dispatch('user/setAuthorityMenus', {
Main: AdminFramework.Main,
ParentView: AdminFramework.ParentView,
Page404: AdminFramework.Page404
})
// 获取系统标题
this.$store.dispatch('app/getSysTitle', {
defaultTitle: 'Demo 管理系统',
defaultLogo: ''
})
}
})
// 响应式适配
window.addEventListener('load', AdminFramework.uiTool.setRem)
window.addEventListener('resize', AdminFramework.uiTool.setRem)
```
## 🎯 关键要点
### 1. 路径命名规则
**后端返回**
```json
{ "component": "ball/games.vue" }
```
**项目文件**
```
src/views/ball/games.vue
```
**配置映射**(不需要 .vue 后缀):
```javascript
componentMap: {
'ball/games': GamesComponent // ✅ 不需要写 .vue
}
```
**框架会自动处理**
- `ball/games`
- `ball/games.vue`
### 2. 框架内置组件
以下组件**无需配置**,框架已自动映射:
- `home/index.vue` → HomePage
- `system/sys_user.vue` → SysUser
- `system/sys_role.vue` → SysRole
- `system/sys_log.vue` → SysLog
- `system/sys_param_setup.vue` → SysParamSetup
- `system_high/sys_menu.vue` → SysMenu
- `system_high/sys_control.vue` → SysControl
- `system_high/sys_title.vue` → SysTitle
### 3. 业务组件
需要在项目中:
1. **创建组件文件**
2. **在 main.js 中导入**
3. **在 componentMap 中配置**
## ⚠️ 组件未找到的提示
如果后端返回的组件路径没有在映射表中,会显示:
```
┌────────────────────────────────────┐
│ ⚠️ 警告 │
│ 页面组件未加载: ball/games.vue │
│ 请在项目中创建此组件或在组件映射表中注册 │
└────────────────────────────────────┘
```
**控制台也会输出**
```
⚠️ 组件未找到: ball/games.vue使用占位组件
```
## 💡 快速配置技巧
### 技巧1批量导入组件
```javascript
// 按模块组织导入
// 球局模块
import GamesComponent from './views/ball/games.vue'
import WchUsersComponent from './views/ball/wch_users.vue'
// 订单模块
import PayOrdersComponent from './views/order/pay_orders.vue'
import WchWalletsComponent from './views/order/wch_wallets.vue'
```
### 技巧2使用对象展开
```javascript
// 定义模块组件映射
const ballComponents = {
'ball/games': GamesComponent,
'ball/wch_users': WchUsersComponent
}
const orderComponents = {
'order/pay_orders': PayOrdersComponent,
'order/wch_wallets': WchWalletsComponent
}
// 合并配置
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
...ballComponents,
...orderComponents
}
})
```
### 技巧3注释待开发的组件
```javascript
componentMap: {
'ball/games': GamesComponent, // ✅ 已开发
// 'ball/venues': VenuesComponent, // ⏳ 待开发
// 'order/pay_orders': PayOrdersComponent // ⏳ 待开发
}
```
## 📊 配置流程图
```
后端接口返回菜单
查看所有 component 字段
在项目中创建对应的 .vue 文件
在 main.js 中导入组件
在 componentMap 中配置映射
框架自动生成路由
页面正常显示 ✅
```
## 🚀 实战示例
### 示例:添加"球局管理"页面
#### 1. 后端返回的菜单
```json
{
"id": 123,
"name": "球局表",
"path": "games",
"component": "ball/games.vue",
"type": "页面"
}
```
#### 2. 创建组件文件
```vue
<!-- src/views/ball/games.vue -->
<template>
<div class="games-page">
<h2>球局管理</h2>
<Table :columns="columns" :data="list" />
</div>
</template>
<script>
export default {
name: 'games',
data() {
return {
list: [],
columns: []
}
},
mounted() {
this.getData()
},
methods: {
async getData() {
const res = await this.$http.post('ball/games/list', {})
this.list = res.data
}
}
}
</script>
```
#### 3. 在 main.js 中配置
```javascript
// 导入
import GamesComponent from './views/ball/games.vue'
// 配置映射
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
'ball/games': GamesComponent // ✅ 添加映射
}
})
```
#### 4. 完成!
登录后,权限菜单中的"球局表"会自动加载 `GamesComponent` 组件。
## 📚 框架自动处理
### 已自动映射的系统组件
| 后端路径 | 组件 | 说明 |
|---------|------|------|
| `home/index.vue` | HomePage | 主页 |
| `system/sys_user.vue` | SysUser | 用户管理 |
| `system/sys_role.vue` | SysRole | 角色管理 |
| `system/sys_log.vue` | SysLog | 日志管理 |
| `system/sys_param_setup.vue` | SysParamSetup | 参数设置 |
| `system_high/sys_menu.vue` | SysMenu | 菜单管理 |
| `system_high/sys_control.vue` | SysControl | 控制器管理 |
| `system_high/sys_title.vue` | SysTitle | 系统标题设置 |
### 需要手动配置的业务组件
根据你的权限菜单接口,需要配置:
-`ball/games.vue` - 球局表
-`ball/wch_users.vue` - 微信用户
-`ball/venues.vue` - 场地表
-`ball/game_participants.vue` - 球局参与者
-`ball/game_comments.vue` - 球局评论
-`order/pay_orders.vue` - 支付订单
-`order/wch_wallets.vue` - 用户钱包
-`order/wallet_transactions.vue` - 交易记录
-`order/transfer_details.vue` - 转账详情
-`order/frozen_funds.vue` - 冻结资金
-`users/user_follows.vue` - 用户关注
-`users/recommend_blocks.vue` - 推荐屏蔽
-`users/user_tracking.vue` - 行为追踪
-`statistics/resources.vue` - 图库资源表
-`ntrp/ntr_questions.vue` - 题库管理
-`ntrp/ntr_records.vue` - 测试记录
-`message/msg_notifications.vue` - 消息管理
-`system/wch_professions.vue` - 职业管理
-`system/wch_cities.vue` - 城市管理
-`business/hot_city_qr.vue` - 热门城市
## 🎯 推荐配置模板
```javascript
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ViewUI from 'view-design'
import createPersistedState from 'vuex-persistedstate'
import 'view-design/dist/styles/iview.css'
import AdminFramework from '../../src/index.js'
import config from './config'
import App from './App.vue'
// ==================== 导入业务组件 ====================
// TODO: 根据权限菜单接口返回的 component 字段,导入对应组件
// 使用框架
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
// TODO: 在这里添加业务组件映射
// 格式:'后端返回的路径(不含.vue': 导入的组件
}
})
// 创建 Vue 实例
new Vue({
el: '#app',
router: AdminFramework.router,
store: AdminFramework.store,
render: h => h(App),
mounted() {
AdminFramework.uiTool.setRem()
this.$store.dispatch('user/setAuthorityMenus', {
Main: AdminFramework.Main,
ParentView: AdminFramework.ParentView,
Page404: AdminFramework.Page404
})
this.$store.dispatch('app/getSysTitle', {
defaultTitle: config.title,
defaultLogo: ''
})
}
})
window.addEventListener('load', AdminFramework.uiTool.setRem)
window.addEventListener('resize', AdminFramework.uiTool.setRem)
```
## 📝 总结
### ✅ 优化后的优势
1. **代码简洁**
- 不需要重复写 `.vue` 后缀的映射
- 框架自动生成
2. **集中配置**
-`Vue.use()` 时一次性配置所有映射
- 清晰明了
3. **灵活扩展**
- 可以随时使用 `addComponentMap()` 添加新映射
- 支持分模块配置
### 🔗 相关文档
- [../README.md](../README.md) - 项目说明
- [../CHANGELOG.md](../CHANGELOG.md) - 更新日志
- [../../完整使用文档.md](../../完整使用文档.md) - 框架文档
---
**配置完成后,重启项目即可看到所有权限菜单中的页面!** 🎉

View File

@@ -0,0 +1,233 @@
# 组件映射修复总结
## ✅ 问题解决
### 问题:所有页面都显示 404
**原因**
1. 权限菜单接口返回的组件路径(如 `ball/games.vue`)没有映射到实际组件
2. 之前的代码将所有未知组件都设置为 `Page404`
### 解决方案
创建了完整的组件映射机制:
- ✅ 框架自动映射系统组件
- ✅ 支持用户配置业务组件映射
- ✅ 自动处理带和不带 `.vue` 后缀的路径
- ✅ 未映射组件显示友好提示
## 🔧 核心修改
### 1. `src/utils/uiTool.js`
#### 添加组件映射功能
```javascript
// 组件映射表
const componentMap = {}
// 设置组件映射
static setComponentMap(map) {
Object.assign(componentMap, map)
}
// 获取组件
static getComponent(componentPath) {
const normalizedPath = componentPath.replace(/\.vue$/, '')
return componentMap[normalizedPath] || componentMap[componentPath]
}
```
#### 优化 menuToRoute 方法
```javascript
static menuToRoute(menus, ParentView, Page404) {
menus.forEach(item => {
if (item.type === '页面') {
// 从映射表获取组件
let component = uiTool.getComponent(item.component)
if (component) {
item.component = component // ✅ 使用映射的组件
} else {
// 显示友好提示
console.warn(`组件未找到: ${item.component}`)
item.component = PlaceholderComponent
}
}
})
}
```
### 2. `src/index.js`
#### 添加 setupComponentMap 方法
```javascript
setupComponentMap(customMap = {}) {
// 框架内置组件
const components = {
'home/index': HomePage,
'system/sys_log': SysLog,
'system/sys_param_setup': SysParamSetup,
'system/sys_role': SysRole,
'system/sys_user': SysUser,
'system_high/sys_control': SysControl,
'system_high/sys_menu': SysMenu,
'system_high/sys_title': SysTitle,
// 合并用户传入的业务组件
...customMap
}
// 自动生成带 .vue 和不带 .vue 的映射
const map = {}
Object.keys(components).forEach(path => {
const cleanPath = path.replace(/\.vue$/, '')
map[cleanPath] = components[path]
map[cleanPath + '.vue'] = components[path]
})
uiTool.setComponentMap(map)
}
```
#### 支持在 install 时传入 componentMap
```javascript
install(Vue, options = {}) {
const { config, ViewUI, VueRouter, Vuex, createPersistedState, componentMap } = options
// 设置组件映射(包含用户传入的映射)
this.setupComponentMap(componentMap)
// ...
}
```
#### 添加 addComponentMap 方法
```javascript
addComponentMap(customMap) {
uiTool.setComponentMap(customMap)
}
```
## 📊 代码优化
### 优化前(重复代码多)
```javascript
const map = {
'system/sys_user.vue': SysUser,
'system/sys_user': SysUser, // ← 重复
'system/sys_role.vue': SysRole,
'system/sys_role': SysRole, // ← 重复
// ...每个组件都写两遍
}
```
### 优化后(自动生成)
```javascript
const components = {
'system/sys_user': SysUser,
'system/sys_role': SysRole
}
// 自动生成带 .vue 的映射
Object.keys(components).forEach(path => {
map[path] = components[path]
map[path + '.vue'] = components[path]
})
```
**代码量减少 50%**
## 🚀 使用方法
### 方法一:在 Vue.use 时配置(推荐)
```javascript
import GamesComponent from './views/ball/games.vue'
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
'ball/games': GamesComponent
}
})
```
### 方法二:使用 addComponentMap
```javascript
Vue.use(AdminFramework, { config, ViewUI, VueRouter, Vuex, createPersistedState })
AdminFramework.addComponentMap({
'ball/games': GamesComponent
})
```
## 📝 配置清单
根据你的权限菜单接口,需要配置的业务组件:
### 球局模块
- [ ] `ball/games.vue` - 球局表
- [ ] `ball/wch_users.vue` - 微信用户
- [ ] `ball/venues.vue` - 场地表
- [ ] `ball/game_participants.vue` - 球局参与者
- [ ] `ball/game_comments.vue` - 球局评论
### 订单模块
- [ ] `order/pay_orders.vue` - 支付订单
- [ ] `order/wch_wallets.vue` - 用户钱包
- [ ] `order/wallet_transactions.vue` - 交易记录
- [ ] `order/transfer_details.vue` - 转账详情
- [ ] `order/frozen_funds.vue` - 冻结资金
### 用户模块
- [ ] `users/user_follows.vue` - 用户关注
- [ ] `users/recommend_blocks.vue` - 推荐屏蔽
- [ ] `users/user_tracking.vue` - 行为追踪
### 资源模块
- [ ] `statistics/resources.vue` - 图库资源表
- [ ] `ntrp/ntr_questions.vue` - 题库管理
- [ ] `ntrp/ntr_records.vue` - 测试记录
### 其他
- [ ] `message/msg_notifications.vue` - 消息管理
- [ ] `system/wch_professions.vue` - 职业管理
- [ ] `system/wch_cities.vue` - 城市管理
- [ ] `business/hot_city_qr.vue` - 热门城市
## 🎯 已自动映射(无需配置)
-`home/index.vue` - 主页
-`system/sys_user.vue` - 系统用户
-`system/sys_role.vue` - 角色管理
-`system/sys_log.vue` - 日志管理
-`system/sys_param_setup.vue` - 参数设置
-`system_high/sys_menu.vue` - 菜单管理
-`system_high/sys_control.vue` - 控制器管理
-`system_high/sys_title.vue` - 系统标题设置
## 📚 相关文档
- [快速配置组件映射.md](./快速配置组件映射.md) - 快速指南
- [权限菜单组件配置指南.md](./权限菜单组件配置指南.md) - 详细教程
- [../README.md](../README.md) - 项目说明
- [../../完整使用文档.md](../../完整使用文档.md) - 框架文档
---
**修复时间**: 2025-10-08
**修复人员**: light
**现在配置完 componentMap所有菜单页面都能正常显示了** 🎉

380
src/index.js.backup Normal file
View File

@@ -0,0 +1,380 @@
/**
* Admin Framework - 通用后台管理系统框架
* 版本: 1.0.0
*
* 功能包含:
* - 系统管理功能 (sys_*)
* - 用户登录和权限管理
* - 动态路由管理
* - 主布局和页面布局
* - 全局组件
* - 工具库
* - Vuex 状态管理
*/
// ==================== 样式文件 ====================
import './assets/css/animate.css'
import './assets/css/base.less'
import './assets/css/ivewExpand.less'
import './assets/icons/iconfont.css'
// ==================== 工具库 ====================
import uiTool from './utils/uiTool'
import http from './utils/http'
import * as tools from './utils/tools'
// ==================== Store 模块 ====================
import storeModules, { userModule, appModule } from './store'
// ==================== 路由配置 ====================
import routerConfig, { createBaseRoutes, setupRouterGuards } from './router'
// ==================== 系统页面 ====================
// 主页
import HomePage from './views/home/index.vue'
// system 页面
import SysLog from './views/system/sys_log.vue'
import SysParamSetup from './views/system/sys_param_setup.vue'
import SysRole from './views/system/sys_role.vue'
import SysUser from './views/system/sys_user.vue'
// system_high 页面
import SysControl from './views/system_high/sys_control.vue'
import SysMenu from './views/system_high/sys_menu.vue'
import SysTitle from './views/system_high/sys_title.vue'
// 登录和错误页面
import LoginPage from './views/login/login.vue'
import Page401 from './views/error-page/401.vue'
import Page404 from './views/error-page/404.vue'
import Page500 from './views/error-page/500.vue'
// 布局组件
import Main from './components/main'
import ParentView from './components/parent-view'
// ==================== 系统 API ====================
// system API
import * as systemApi from './api/system'
// system_high API
import * as systemHighApi from './api/system_high'
// ==================== 框架类 ====================
class AdminFramework {
constructor() {
this.version = '1.0.0'
this.installed = false
this.config = {}
this.store = null
this.router = null
// 导出工具
this.tools = tools
this.uiTool = uiTool
this.http = http
// 导出 Store 模块
this.storeModules = storeModules
this.userModule = userModule
this.appModule = appModule
// 导出路由配置
this.createBaseRoutes = createBaseRoutes
this.setupRouterGuards = setupRouterGuards
// 导出组件
this.Main = Main
this.ParentView = ParentView
this.LoginPage = LoginPage
this.Page401 = Page401
this.Page404 = Page404
this.Page500 = Page500
// 导出系统页面
this.HomePage = HomePage
this.SysLog = SysLog
this.SysParamSetup = SysParamSetup
this.SysRole = SysRole
this.SysUser = SysUser
this.SysControl = SysControl
this.SysMenu = SysMenu
this.SysTitle = SysTitle
// 导出 API
this.systemApi = systemApi
this.systemHighApi = systemHighApi
}
/**
* Vue 插件安装方法 - 自动完成所有初始化
* @param {Object} Vue - Vue 实例
* @param {Object} options - 配置选项
* @param {Object} options.config - 应用配置
* @param {Object} options.ViewUI - ViewUI 实例(可选,框架会自动处理)
* @param {Object} options.VueRouter - VueRouter 实例(可选)
* @param {Object} options.Vuex - Vuex 实例(可选)
* @param {Function} options.createPersistedState - vuex-persistedstate可选
* @param {Object} options.componentMap - 自定义组件映射表(可选)
*/
install(Vue, options = {}) {
if (this.installed) return
this.installed = true
const { config = {}, ViewUI, VueRouter, Vuex, createPersistedState, componentMap } = options
this.config = config
// 自动注册 ViewUI
if (ViewUI) {
Vue.use(ViewUI)
}
// 自动注册 VueRouter
if (VueRouter) {
Vue.use(VueRouter)
}
// 自动注册 Vuex
if (Vuex) {
Vue.use(Vuex)
}
// 挂载全局配置和工具
Vue.prototype.$config = config
Vue.prototype.$http = http
Vue.prototype.$tools = tools
Vue.prototype.$uiTool = uiTool
// 自动注册全局组件
this.registerGlobalComponents(Vue)
// 自动设置组件映射表(包含外部传入的映射)
this.setupComponentMap(componentMap)
// 如果提供了 Vuex自动创建 Store
if (Vuex && !this.store) {
this.store = this.createStore(Vuex, {}, createPersistedState)
// 自动初始化 HTTP
http.init(config, this.store)
}
// 如果提供了 VueRouter自动创建 Router
if (VueRouter && !this.router) {
// 获取主路由配置(从后端权限菜单生成)
const mainRoute = this.getRoutes({ Main, ParentView, Page404 })
this.router = this.createRouter(VueRouter, {
Main,
ParentView,
LoginPage,
Page401,
Page404,
Page500
}, mainRoute ? [mainRoute] : [], ViewUI)
}
}
/**
* 自动注册全局组件
*/
registerGlobalComponents(Vue) {
// 注册布局组件
Vue.component('Main', Main)
Vue.component('ParentView', ParentView)
// 注册错误页面
Vue.component('Page401', Page401)
Vue.component('Page404', Page404)
Vue.component('Page500', Page500)
// 注册登录页面
Vue.component('LoginPage', LoginPage)
}
/**
* 设置组件映射表(将后端返回的路径映射到实际组件)
* @param {Object} customMap - 外部传入的自定义组件映射
*/
setupComponentMap(customMap = {}) {
// 框架内置组件列表:路径 => 组件
const components = {
'home/index': HomePage,
'system/sys_log': SysLog,
'system/sys_param_setup': SysParamSetup,
'system/sys_role': SysRole,
'system/sys_user': SysUser,
'system_high/sys_control': SysControl,
'system_high/sys_menu': SysMenu,
'system_high/sys_title': SysTitle,
// 合并外部传入的组件映射
...customMap
}
// 自动生成带 .vue 和不带 .vue 的映射
const map = {}
Object.keys(components).forEach(path => {
const cleanPath = path.replace(/\.vue$/, '')
map[cleanPath] = components[path]
map[cleanPath + '.vue'] = components[path]
})
uiTool.setComponentMap(map)
}
/**
* 添加自定义组件映射
* @param {Object} customMap - 自定义组件映射对象
* @example
* AdminFramework.addComponentMap({
* 'ball/games.vue': GamesComponent,
* 'order/pay_orders.vue': PayOrdersComponent
* })
*/
addComponentMap(customMap) {
uiTool.setComponentMap(customMap)
}
/**
* 初始化 HTTP 配置
* @param {Object} config - HTTP 配置
* @param {Object} store - Vuex Store 实例
*/
initHttp(config, store) {
http.init(config, store)
this.store = store
}
/**
* 创建路由实例
* @param {Object} Router - VueRouter 类
* @param {Object} components - 组件对象
* @param {Array} customRoutes - 自定义路由
* @param {Object} ViewUI - ViewUI 实例
* @param {String} homeName - 首页名称
* @returns {Object} router 实例
*/
createRouter(Router, components = {}, customRoutes = [], ViewUI, homeName = 'home') {
const { LoginPage, Page401, Page404, Page500 } = components
if (!LoginPage || !Page401 || !Page404 || !Page500) {
console.error('Missing required page components')
return null
}
const baseRoutes = createBaseRoutes(LoginPage, Page401, Page404, Page500)
const router = new Router({
routes: [...baseRoutes, ...customRoutes],
mode: 'hash'
})
if (ViewUI) {
setupRouterGuards(router, ViewUI, homeName)
}
return router
}
/**
* 创建 Store 实例
* @param {Object} Vuex - Vuex 类
* @param {Object} customModules - 自定义模块
* @param {Object} createPersistedState - vuex-persistedstate 插件
* @returns {Object} store 实例
*/
createStore(Vuex, customModules = {}, createPersistedState) {
const store = new Vuex.Store({
modules: {
user: userModule,
app: appModule,
...customModules
},
plugins: createPersistedState ? [
createPersistedState({
storage: window.localStorage
})
] : []
})
this.store = store
return store
}
/**
* 获取动态路由
* @param {Object} components - 组件对象
* @returns {Object} 主路由配置
*/
getRoutes(components = {}) {
const { Main, ParentView, Page404 } = components
if (!Main || !ParentView || !Page404) {
console.error('Missing required layout components')
return null
}
return uiTool.getRoutes(Main, ParentView, Page404)
}
/**
* 注册全局组件
* @param {Object} Vue - Vue 实例
* @param {Object} components - 组件对象
*/
registerComponents(Vue, components = {}) {
Object.keys(components).forEach(name => {
Vue.component(name, components[name])
})
}
}
// ==================== 创建实例并导出 ====================
const framework = new AdminFramework()
// 默认导出框架实例
export default framework
// 按需导出
export {
// 工具库
tools,
uiTool,
http,
// Store 模块
storeModules,
userModule,
appModule,
// 路由配置
createBaseRoutes,
setupRouterGuards,
// 系统页面
HomePage,
SysLog,
SysParamSetup,
SysRole,
SysUser,
SysControl,
SysMenu,
SysTitle,
// 登录和错误页面
LoginPage,
Page401,
Page404,
Page500,
// 布局组件
Main,
ParentView,
// 系统 API
systemApi,
systemHighApi,
// 框架类
AdminFramework
}

362
temp_index.txt Normal file
View File

@@ -0,0 +1,362 @@
/**
* Admin Framework - 閫氱敤鍚庡彴绠$悊绯荤粺妗嗘灦
* 鐗堟湰: 1.0.0
*
* 鍔熻兘鍖呭惈:
* - 绯荤粺绠$悊鍔熻兘 (sys_*)
* - 鐢ㄦ埛鐧诲綍鍜屾潈闄愮鐞? * - 鍔ㄦ€佽矾鐢辩鐞? * - 涓诲竷灞€鍜岄〉闈㈠竷灞€
* - 鍏ㄥ眬缁勪欢
* - 宸ュ叿搴? * - Vuex 鐘舵€佺鐞? */
// ==================== 鏍峰紡鏂囦欢 ====================
import './assets/css/animate.css'
import './assets/css/base.less'
import './assets/css/ivewExpand.less'
import './assets/icons/iconfont.css'
// ==================== 宸ュ叿搴?====================
import uiTool from './utils/uiTool'
import http from './utils/http'
import * as tools from './utils/tools'
// ==================== Store 妯″潡 ====================
import storeModules, { userModule, appModule } from './store'
// ==================== 璺敱閰嶇疆 ====================
import routerConfig, { createBaseRoutes, setupRouterGuards } from './router'
// ==================== 绯荤粺椤甸潰 ====================
// 涓婚〉
import HomePage from './views/home/index.vue'
// system 椤甸潰
import SysLog from './views/system/sys_log.vue'
import SysParamSetup from './views/system/sys_param_setup.vue'
import SysRole from './views/system/sys_role.vue'
import SysUser from './views/system/sys_user.vue'
// system_high 椤甸潰
import SysControl from './views/system_high/sys_control.vue'
import SysMenu from './views/system_high/sys_menu.vue'
import SysTitle from './views/system_high/sys_title.vue'
// 鐧诲綍鍜岄敊璇〉闈?import LoginPage from './views/login/login.vue'
import Page401 from './views/error-page/401.vue'
import Page404 from './views/error-page/404.vue'
import Page500 from './views/error-page/500.vue'
// 甯冨眬缁勪欢
import Main from './components/main'
import ParentView from './components/parent-view'
// ==================== 绯荤粺 API ====================
// system API
import * as systemApi from './api/system'
// system_high API
import * as systemHighApi from './api/system_high'
// ==================== 妗嗘灦绫?====================
class AdminFramework {
constructor() {
this.version = '1.0.0'
this.installed = false
this.config = {}
this.store = null
this.router = null
// 瀵煎嚭宸ュ叿
this.tools = tools
this.uiTool = uiTool
this.http = http
// 瀵煎嚭 Store 妯″潡
this.storeModules = storeModules
this.userModule = userModule
this.appModule = appModule
// 瀵煎嚭璺敱閰嶇疆
this.createBaseRoutes = createBaseRoutes
this.setupRouterGuards = setupRouterGuards
// 瀵煎嚭缁勪欢
this.Main = Main
this.ParentView = ParentView
this.LoginPage = LoginPage
this.Page401 = Page401
this.Page404 = Page404
this.Page500 = Page500
// 瀵煎嚭绯荤粺椤甸潰
this.HomePage = HomePage
this.SysLog = SysLog
this.SysParamSetup = SysParamSetup
this.SysRole = SysRole
this.SysUser = SysUser
this.SysControl = SysControl
this.SysMenu = SysMenu
this.SysTitle = SysTitle
// 瀵煎嚭 API
this.systemApi = systemApi
this.systemHighApi = systemHighApi
}
/**
* Vue 鎻掍欢瀹夎鏂规硶 - 鑷姩瀹屾垚鎵€鏈夊垵濮嬪寲
* @param {Object} Vue - Vue 瀹炰緥
* @param {Object} options - 閰嶇疆閫夐」
* @param {Object} options.config - 搴旂敤閰嶇疆
* @param {Object} options.ViewUI - ViewUI 瀹炰緥锛堝彲閫夛紝妗嗘灦浼氳嚜鍔ㄥ鐞嗭級
* @param {Object} options.VueRouter - VueRouter 瀹炰緥锛堝彲閫夛級
* @param {Object} options.Vuex - Vuex 瀹炰緥锛堝彲閫夛級
* @param {Function} options.createPersistedState - vuex-persistedstate锛堝彲閫夛級
* @param {Object} options.componentMap - 鑷畾涔夌粍浠舵槧灏勮〃锛堝彲閫夛級
*/
install(Vue, options = {}) {
if (this.installed) return
this.installed = true
const { config = {}, ViewUI, VueRouter, Vuex, createPersistedState, componentMap } = options
this.config = config
// 鑷姩娉ㄥ唽 ViewUI
if (ViewUI) {
Vue.use(ViewUI)
}
// 鑷姩娉ㄥ唽 VueRouter
if (VueRouter) {
Vue.use(VueRouter)
}
// 鑷姩娉ㄥ唽 Vuex
if (Vuex) {
Vue.use(Vuex)
}
// 鎸傝浇鍏ㄥ眬閰嶇疆鍜屽伐鍏? Vue.prototype.$config = config
Vue.prototype.$http = http
Vue.prototype.$tools = tools
Vue.prototype.$uiTool = uiTool
// 鑷姩娉ㄥ唽鍏ㄥ眬缁勪欢
this.registerGlobalComponents(Vue)
// 鑷姩璁剧疆缁勪欢鏄犲皠琛紙鍖呭惈澶栭儴浼犲叆鐨勬槧灏勶級
this.setupComponentMap(componentMap)
// 濡傛灉鎻愪緵浜?Vuex锛岃嚜鍔ㄥ垱寤?Store
if (Vuex && !this.store) {
this.store = this.createStore(Vuex, {}, createPersistedState)
// 鑷姩鍒濆鍖?HTTP
http.init(config, this.store)
}
// 濡傛灉鎻愪緵浜?VueRouter锛岃嚜鍔ㄥ垱寤?Router
if (VueRouter && !this.router) {
// 鑾峰彇涓昏矾鐢遍厤缃紙浠庡悗绔潈闄愯彍鍗曠敓鎴愶級
const mainRoute = this.getRoutes({ Main, ParentView, Page404 })
this.router = this.createRouter(VueRouter, {
Main,
ParentView,
LoginPage,
Page401,
Page404,
Page500
}, mainRoute ? [mainRoute] : [], ViewUI)
}
}
/**
* 鑷姩娉ㄥ唽鍏ㄥ眬缁勪欢
*/
registerGlobalComponents(Vue) {
// 娉ㄥ唽甯冨眬缁勪欢
Vue.component('Main', Main)
Vue.component('ParentView', ParentView)
// 娉ㄥ唽閿欒椤甸潰
Vue.component('Page401', Page401)
Vue.component('Page404', Page404)
Vue.component('Page500', Page500)
// 娉ㄥ唽鐧诲綍椤甸潰
Vue.component('LoginPage', LoginPage)
}
/**
* 璁剧疆缁勪欢鏄犲皠琛紙灏嗗悗绔繑鍥炵殑璺緞鏄犲皠鍒板疄闄呯粍浠讹級
* @param {Object} customMap - 澶栭儴浼犲叆鐨勮嚜瀹氫箟缁勪欢鏄犲皠
*/
setupComponentMap(customMap = {}) {
// 妗嗘灦鍐呯疆缁勪欢鍒楄〃锛氳矾寰?=> 缁勪欢
const components = {
'home/index': HomePage,
'system/sys_log': SysLog,
'system/sys_param_setup': SysParamSetup,
'system/sys_role': SysRole,
'system/sys_user': SysUser,
'system_high/sys_control': SysControl,
'system_high/sys_menu': SysMenu,
'system_high/sys_title': SysTitle,
// 鍚堝苟澶栭儴浼犲叆鐨勭粍浠舵槧灏? ...customMap
}
// 鑷姩鐢熸垚甯?.vue 鍜屼笉甯?.vue 鐨勬槧灏? const map = {}
Object.keys(components).forEach(path => {
const cleanPath = path.replace(/\.vue$/, '')
map[cleanPath] = components[path]
map[cleanPath + '.vue'] = components[path]
})
uiTool.setComponentMap(map)
}
/**
* 娣诲姞鑷畾涔夌粍浠舵槧灏? * @param {Object} customMap - 鑷畾涔夌粍浠舵槧灏勫璞? * @example
* AdminFramework.addComponentMap({
* 'ball/games.vue': GamesComponent,
* 'order/pay_orders.vue': PayOrdersComponent
* })
*/
addComponentMap(customMap) {
uiTool.setComponentMap(customMap)
}
/**
* 鍒濆鍖?HTTP 閰嶇疆
* @param {Object} config - HTTP 閰嶇疆
* @param {Object} store - Vuex Store 瀹炰緥
*/
initHttp(config, store) {
http.init(config, store)
this.store = store
}
/**
* 鍒涘缓璺敱瀹炰緥
* @param {Object} Router - VueRouter 绫? * @param {Object} components - 缁勪欢瀵硅薄
* @param {Array} customRoutes - 鑷畾涔夎矾鐢? * @param {Object} ViewUI - ViewUI 瀹炰緥
* @param {String} homeName - 棣栭〉鍚嶇О
* @returns {Object} router 瀹炰緥
*/
createRouter(Router, components = {}, customRoutes = [], ViewUI, homeName = 'home') {
const { LoginPage, Page401, Page404, Page500 } = components
if (!LoginPage || !Page401 || !Page404 || !Page500) {
console.error('Missing required page components')
return null
}
const baseRoutes = createBaseRoutes(LoginPage, Page401, Page404, Page500)
const router = new Router({
routes: [...baseRoutes, ...customRoutes],
mode: 'hash'
})
if (ViewUI) {
setupRouterGuards(router, ViewUI, homeName)
}
return router
}
/**
* 鍒涘缓 Store 瀹炰緥
* @param {Object} Vuex - Vuex 绫? * @param {Object} customModules - 鑷畾涔夋ā鍧? * @param {Object} createPersistedState - vuex-persistedstate 鎻掍欢
* @returns {Object} store 瀹炰緥
*/
createStore(Vuex, customModules = {}, createPersistedState) {
const store = new Vuex.Store({
modules: {
user: userModule,
app: appModule,
...customModules
},
plugins: createPersistedState ? [
createPersistedState({
storage: window.localStorage
})
] : []
})
this.store = store
return store
}
/**
* 鑾峰彇鍔ㄦ€佽矾鐢? * @param {Object} components - 缁勪欢瀵硅薄
* @returns {Object} 涓昏矾鐢遍厤缃? */
getRoutes(components = {}) {
const { Main, ParentView, Page404 } = components
if (!Main || !ParentView || !Page404) {
console.error('Missing required layout components')
return null
}
return uiTool.getRoutes(Main, ParentView, Page404)
}
/**
* 娉ㄥ唽鍏ㄥ眬缁勪欢
* @param {Object} Vue - Vue 瀹炰緥
* @param {Object} components - 缁勪欢瀵硅薄
*/
registerComponents(Vue, components = {}) {
Object.keys(components).forEach(name => {
Vue.component(name, components[name])
})
}
}
// ==================== 鍒涘缓瀹炰緥骞跺鍑?====================
const framework = new AdminFramework()
// 榛樿瀵煎嚭妗嗘灦瀹炰緥
export default framework
// 鎸夐渶瀵煎嚭
export {
// 宸ュ叿搴? tools,
uiTool,
http,
// Store 妯″潡
storeModules,
userModule,
appModule,
// 璺敱閰嶇疆
createBaseRoutes,
setupRouterGuards,
// 绯荤粺椤甸潰
HomePage,
SysLog,
SysParamSetup,
SysRole,
SysUser,
SysControl,
SysMenu,
SysTitle,
// 鐧诲綍鍜岄敊璇〉闈? LoginPage,
Page401,
Page404,
Page500,
// 甯冨眬缁勪欢
Main,
ParentView,
// 绯荤粺 API
systemApi,
systemHighApi,
// 妗嗘灦绫? AdminFramework
}

View File

@@ -165,7 +165,10 @@ import createPersistedState from 'vuex-persistedstate'
import AdminFramework from './libs/admin-framework.js' import AdminFramework from './libs/admin-framework.js'
import App from './App.vue' import App from './App.vue'
import config from './config' import config from './config'
import HomePage from './views/home/index.vue' // 可选:自定义首页组件
// 可选:导入业务组件(根据权限菜单接口的 component 字段)
import GamesComponent from './views/ball/games.vue'
import PayOrdersComponent from './views/order/pay_orders.vue'
// 🎉 只需这一行!框架自动完成所有初始化 // 🎉 只需这一行!框架自动完成所有初始化
Vue.use(AdminFramework, { Vue.use(AdminFramework, {
@@ -174,7 +177,12 @@ Vue.use(AdminFramework, {
VueRouter, VueRouter,
Vuex, Vuex,
createPersistedState, createPersistedState,
HomePage // 可选:传入自定义首页组件(不传则使用框架内置组件 // 可选:配置业务组件映射(用于权限菜单
componentMap: {
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent
// 添加更多业务组件...
}
}) })
// 创建 Vue 实例 // 创建 Vue 实例
@@ -1168,6 +1176,94 @@ Vue.use(AdminFramework, { ... })
框架使用时样式会自动注入到页面中,无需任何额外配置! 框架使用时样式会自动注入到页面中,无需任何额外配置!
### Q14: 权限菜单中的业务页面显示 404 怎么办?
A: **需要配置组件映射表。**
**问题原因**
后端权限菜单接口返回的组件路径(如 `ball/games.vue`)需要映射到实际组件。
**解决方案**
#### 方式一:在 Vue.use 时配置(推荐)
```javascript
// 1. 导入业务组件
import GamesComponent from './views/ball/games.vue'
import PayOrdersComponent from './views/order/pay_orders.vue'
// 2. 配置映射
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
// ✅ 配置组件映射
componentMap: {
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent
// 根据权限菜单接口的 component 字段添加...
}
})
```
#### 方式二:使用 addComponentMap 方法
```javascript
// 先使用框架
Vue.use(AdminFramework, { config, ViewUI, VueRouter, Vuex, createPersistedState })
// 然后添加映射
AdminFramework.addComponentMap({
'ball/games': GamesComponent,
'order/pay_orders': PayOrdersComponent
})
```
#### 框架已自动映射的系统组件
以下组件**无需配置**,框架已自动映射:
-`home/index.vue` - 主页
-`system/sys_user.vue` - 用户管理
-`system/sys_role.vue` - 角色管理
-`system/sys_log.vue` - 日志管理
-`system/sys_param_setup.vue` - 参数设置
-`system_high/sys_menu.vue` - 菜单管理
-`system_high/sys_control.vue` - 控制器管理
-`system_high/sys_title.vue` - 系统标题设置
#### 配置技巧
**路径规则**
- 后端返回:`"component": "ball/games.vue"`
- 配置映射:`'ball/games': GamesComponent`(不需要 `.vue` 后缀)
- 框架会自动处理带和不带 `.vue` 的路径
**完整示例**
```javascript
// 根据你的权限菜单接口,导入所有可能用到的组件
import GamesComponent from './views/ball/games.vue'
import WchUsersComponent from './views/ball/wch_users.vue'
import PayOrdersComponent from './views/order/pay_orders.vue'
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState,
componentMap: {
'ball/games': GamesComponent,
'ball/wch_users': WchUsersComponent,
'order/pay_orders': PayOrdersComponent
}
})
```
**未映射的组件**
会显示友好提示:`页面组件未加载: xxx.vue请在项目中创建此组件或在组件映射表中注册`
--- ---
## 📦 完整的项目结构示例 ## 📦 完整的项目结构示例