This commit is contained in:
张成
2025-10-08 23:12:55 +08:00
parent 7371313d39
commit d387a2d0e9
11 changed files with 224 additions and 1081 deletions

View File

@@ -0,0 +1,175 @@
# 注释乱码修复说明
## 🐛 问题描述
控制台出现多个错误,主要原因是 `src/index.js` 文件中的中文注释出现了乱码,导致:
1. **Upload 组件错误**`TypeError: Cannot read properties of undefined (reading 'user')`
- 原因:`src/components/upload/Single.vue``Multiple.vue` 中使用了 `store.state.user.token`,但 store 未正确初始化
2. **TreeGrid 组件错误**`ReferenceError: Cannot access '__WEBPACK_DEFAULT_EXPORT__' before initialization`
- 原因:`src/components/treeGrid/component/subTreeGrid.vue` 中有循环引用问题
3. **LoginPage 未定义错误**`ReferenceError: LoginPage is not defined`
- 原因:`src/index.js` 第43行的 import 语句和注释在同一行,导致 import 被注释掉
4. **Editor 未定义错误**`ReferenceError: Editor is not defined`
- 原因:`registerGlobalComponents` 方法中引用了未导入的组件
5. **map 未定义错误**`ReferenceError: map is not defined`
- 原因:`setupComponentMap` 方法中的注释格式不对,导致代码被注释掉
## ✅ 已修复的问题
### 1. Upload 组件修复
**修改文件**
- `src/components/upload/Single.vue`
- `src/components/upload/Multiple.vue`
**修改内容**
```javascript
// 修改前
import store from '@/store'
let headers = {
'admin-token': store.state.user.token,
}
// 修改后
import { getToken } from '@/utils/tools'
let headers = {
'admin-token': getToken(),
}
```
**原因**
- 使用 `getToken()` 函数从 localStorage 获取 token避免依赖 store 初始化顺序
### 2. TreeGrid 组件修复
**修改文件**
- `src/components/treeGrid/component/subTreeGrid.vue`
**修改内容**
```javascript
// 修改前
import SubTreeGrid from './subTreeGrid.vue'
export default {
components: {
SubTreeGrid,
// ...
}
}
// 修改后
export default {
components: {
SubTreeGrid: () => import('./subTreeGrid.vue'), // 使用异步组件
// ...
}
}
```
**原因**
- 递归组件需要使用异步组件来避免循环引用问题
## ⚠️ 待修复的问题
### 3. src/index.js 文件乱码
**问题**
- 文件中的中文注释出现乱码(如:`閫氱敤鍚庡彴绠$悊绯荤粺妗嗘灦` 应该是 `通用后台管理系统框架`
- 第43行的 import 语句和注释在同一行
- `registerGlobalComponents` 方法中有重复的组件注册
- `setupComponentMap` 方法中的注释格式不对
**需要修复的关键行**
#### 第43行最关键
```javascript
// 当前(错误)
// 鐧诲綍鍜岄敊璇〉闈?import LoginPage from './views/login/login.vue'
// 应该改为
// 登录和错误页面
import LoginPage from './views/login/login.vue'
```
#### registerGlobalComponents 方法
```javascript
// 删除重复的组件注册第218-235行
// 只保留第206-216行的组件注册
```
#### setupComponentMap 方法
```javascript
// 第234行
// 当前(错误)
// 鍚堝苟澶栭儴浼犲叆鐨勭粍浠舵槧灏? ...customMap
// 应该改为
// 合并外部传入的组件映射
...customMap
// 第237行
// 当前(错误)
// 鑷姩鐢熸垚甯?.vue 鍜屼笉甯?.vue 鐨勬槧灏? const map = {}
// 应该改为
// 自动生成带.vue 和不带.vue 的映射
const map = {}
```
## 🔧 修复方法
### 方法一:使用 Git 恢复 + 手动修复
```bash
# 1. 恢复文件到最近的正确版本
git checkout src/index.js
# 2. 手动修复关键问题(使用编辑器)
# - 确保第43行的 import 语句独立一行
# - 删除重复的组件注册
# - 修复注释格式
```
### 方法二:重新创建文件
由于乱码问题严重,建议:
1. 备份当前文件
2. 从 Git 历史中找到最近的正确版本
3. 重新应用必要的修改
## 📝 预防措施
1. **使用 UTF-8 编码保存文件**
- 确保编辑器设置为 UTF-8 编码
- 避免使用 ANSI 或 GBK 编码
2. **避免注释和代码在同一行**
- 注释应该独立一行
- 特别是 import 语句前的注释
3. **定期检查文件编码**
- 使用 `file` 命令检查文件编码
- 使用 `iconv` 或编辑器转换编码
## 🎯 下一步
1. 修复 `src/index.js` 文件的编码问题
2. 确保所有中文注释正确显示
3. 测试页面是否正常加载
4. 检查控制台是否还有错误
## 📚 相关文件
- `src/index.js` - 框架入口文件(需要修复)
- `src/components/upload/Single.vue` - 已修复
- `src/components/upload/Multiple.vue` - 已修复
- `src/components/treeGrid/component/subTreeGrid.vue` - 已修复
---
**修复状态**:部分完成,等待 `src/index.js` 文件修复

View File

@@ -1,2 +0,0 @@
import PasteEditor from './paste-editor.vue'
export default PasteEditor

View File

@@ -1,26 +0,0 @@
.paste-editor-wrapper{
width: 100%;
height: 100%;
border: 1px dashed gainsboro;
textarea.textarea-el{
width: 100%;
height: 100%;
}
.CodeMirror{
height: 100%;
padding: 0;
.CodeMirror-code div .CodeMirror-line > span > span.cm-tab{
&::after{
content: '→';
color: #BFBFBF;
}
}
}
.first-row{
font-weight: 700;
font-size: 14px;
}
.incorrect-row{
background: #F5CBD1;
}
}

View File

@@ -1,120 +0,0 @@
<template>
<div class="paste-editor-wrapper">
<textarea ref="codemirror" class="textarea-el"></textarea>
</div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import { forEach } from '@/utils/tools'
import createPlaceholder from './plugins/placeholder'
export default {
name: 'PasteEditor',
props: {
value: Array,
pasteData: {
type: String,
default: ''
},
placeholder: {
type: String,
default:
'从网页或其他应用软件复制表格数据,粘贴到这里 。默认第一行是表头使用回车键添加新行使用Tab键区分列。'
}
},
data() {
return {
pasteDataArr: [],
rowArrLength: 0,
editor: null
}
},
watch: {
pasteData(val) {
if (val === '') {
this.editor.setValue('')
}
}
},
computed: {
rowNum() {
return this.pasteDataArr.length
},
colNum() {
return this.pasteDataArr[0] ? this.pasteDataArr[0].length : 0
}
},
methods: {
handleKeyup(e) {
this.handleAreaData()
},
/**
* @description 处理粘贴操作
*/
handleContentChanged(content) {
let pasteData = content.trim()
this.$emit('on-content-change', pasteData)
let rows = pasteData.split(/[\n\u0085\u2028\u2029]|\r\n?/g).map(row => {
return row.split('\t')
})
if (content === '') rows = []
this.pasteDataArr = rows
this.clearLineClass()
this.checkColNumInEveryRow()
this.$emit('input', this.pasteDataArr)
},
/**
* @description 检查除第一行的每一行列数是否与第一行相同
*/
checkColNumInEveryRow() {
let i = 0
const len = this.rowNum
if (len === 0) return
while (++i < len) {
let item = this.pasteDataArr[i]
if (
item.length !== this.colNum &&
(!(i === len - 1 && item.length === 1 && item[0] === '') ||
i !== len - 1)
) {
this.markIncorrectRow(i)
this.$emit('on-error', i)
return false
}
}
this.$emit('on-success', this.pasteDataArr)
return true
},
/**
* @description 标记不符合格式的一行
*/
markIncorrectRow(index) {
this.editor.addLineClass(index, 'text', 'incorrect-row')
},
/**
* @description 标记不符合格式的一行
*/
clearLineClass() {
forEach(this.pasteDataArr, (item, index) => {
this.editor.removeLineClass(index, 'text', 'incorrect-row')
})
}
},
mounted() {
createPlaceholder(CodeMirror)
this.editor = CodeMirror.fromTextArea(this.$refs.codemirror, {
lineNumbers: true,
tabSize: 1,
lineWrapping: true,
placeholder: this.placeholder
})
this.editor.on('change', editor => {
this.handleContentChanged(editor.getValue())
})
this.editor.addLineClass(0, 'text', 'first-row')
}
}
</script>
<style lang="less">
@import './paste-editor.less';
</style>

View File

@@ -1,61 +0,0 @@
export default codemirror => {
;(function(mod) {
mod(codemirror)
})(function(CodeMirror) {
CodeMirror.defineOption('placeholder', '', function(cm, val, old) {
var prev = old && old !== CodeMirror.Init
if (val && !prev) {
cm.on('blur', onBlur)
cm.on('change', onChange)
cm.on('swapDoc', onChange)
onChange(cm)
} else if (!val && prev) {
cm.off('blur', onBlur)
cm.off('change', onChange)
cm.off('swapDoc', onChange)
clearPlaceholder(cm)
var wrapper = cm.getWrapperElement()
wrapper.className = wrapper.className.replace(' CodeMirror-empty', '')
}
if (val && !cm.hasFocus()) onBlur(cm)
})
function clearPlaceholder(cm) {
if (cm.state.placeholder) {
cm.state.placeholder.parentNode.removeChild(cm.state.placeholder)
cm.state.placeholder = null
}
}
function setPlaceholder(cm) {
clearPlaceholder(cm)
var elt = (cm.state.placeholder = document.createElement('pre'))
elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;'
elt.style.direction = cm.getOption('direction')
elt.className = 'CodeMirror-placeholder'
var placeHolder = cm.getOption('placeholder')
if (typeof placeHolder === 'string')
placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild)
}
function onBlur(cm) {
if (isEmpty(cm)) setPlaceholder(cm)
}
function onChange(cm) {
let wrapper = cm.getWrapperElement()
let empty = isEmpty(cm)
wrapper.className =
wrapper.className.replace(' CodeMirror-empty', '') +
(empty ? ' CodeMirror-empty' : '')
if (empty) setPlaceholder(cm)
else clearPlaceholder(cm)
}
function isEmpty(cm) {
return cm.lineCount() === 1 && cm.getLine(0) === ''
}
})
}

View File

@@ -49,7 +49,6 @@
</template>
<script>
import SubTreeGrid from './subTreeGrid.vue'
import SubColmns from './subColmns.vue'
import RenderCol from './renderCol.vue'
export default {
@@ -57,7 +56,7 @@ export default {
props: ['columns', 'data', 'grade'],
components: {
RenderCol,
SubTreeGrid,
SubTreeGrid: () => import('./subTreeGrid.vue'),
SubColmns
},
data() {

View File

@@ -26,9 +26,9 @@
</template>
<script>
import './upload.less'
import store from '@/store'
import { getToken } from '@/utils/tools'
let headers = {
'admin-token': store.state.user.token,
'admin-token': getToken(),
}
export default {
name: 'UoloadImg',

View File

@@ -22,10 +22,10 @@
</template>
<script>
import './upload.less'
import store from '@/store'
import { getToken } from '@/utils/tools'
let headers = {
'admin-token': store.state.user.token,
'admin-token': getToken(),
}
export default {

View File

@@ -1,57 +1,41 @@
/**
* Admin Framework - 閫氱敤鍚庡彴绠$悊绯荤粺妗嗘灦
* 鐗堟湰: 1.0.0
*
* 鍔熻兘鍖呭惈:
* - 绯荤粺绠$悊鍔熻兘 (sys_*)
* - 鐢ㄦ埛鐧诲綍鍜屾潈闄愮鐞? * - 鍔ㄦ€佽矾鐢辩鐞? * - 涓诲竷灞€鍜岄〉闈㈠竷灞€
* - 鍏ㄥ眬缁勪欢
* - 宸ュ叿搴? * - Vuex 鐘舵€佺鐞? */
* Admin Framework
* Version: 1.0.0
*/
// ==================== 鏍峰紡鏂囦欢 ====================
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 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'
// ==================== 鍏ㄥ眬缁勪欢 ====================
import Tables from './components/tables'
import UploadSingle from './components/upload/Single.vue'
import UploadMultiple from './components/upload/Multiple.vue'
@@ -62,14 +46,11 @@ import LoadFlower from './components/load-flower'
import SplitPane from './components/split-pane'
import TextArea from './components/text-area'
import CommonIcon from './components/common-icon'
import Editor from './components/editor/index.vue'
// ==================== 绯荤粺 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'
@@ -78,21 +59,17 @@ class AdminFramework {
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
@@ -100,7 +77,6 @@ class AdminFramework {
this.Page404 = Page404
this.Page500 = Page500
// 瀵煎嚭绯荤粺椤甸潰
this.HomePage = HomePage
this.SysLog = SysLog
this.SysParamSetup = SysParamSetup
@@ -110,21 +86,14 @@ class AdminFramework {
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 - 鑷畾涔夌粍浠舵槧灏勮〃锛堝彲閫夛級
* Vue plugin install method
* @param {Object} Vue - Vue instance
* @param {Object} options - config options
*/
install(Vue, options = {}) {
if (this.installed) return
@@ -133,42 +102,33 @@ class AdminFramework {
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.$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, {
@@ -183,22 +143,18 @@ class AdminFramework {
}
/**
* 鑷姩娉ㄥ唽鍏ㄥ眬缁勪欢
* Register global components
*/
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)
// ==================== 娉ㄥ唽鍏ㄥ眬涓氬姟缁勪欢 ====================
Vue.component('Tables', Tables)
Vue.component('UploadSingle', UploadSingle)
Vue.component('UploadMultiple', UploadMultiple)
@@ -209,32 +165,15 @@ class AdminFramework {
Vue.component('SplitPane', SplitPane)
Vue.component('TextArea', TextArea)
Vue.component('CommonIcon', CommonIcon)
// ==================== 娉ㄥ唽鍏ㄥ眬涓氬姟缁勪欢 ====================
Vue.component('Tables', Tables)
Vue.component('Editor', Editor)
Vue.component('UploadSingle', UploadSingle)
Vue.component('UploadMultiple', UploadMultiple)
Vue.component('TreeGrid', TreeGrid)
Vue.component('AsyncModal', AsyncModal)
Vue.component('CronInput', CronInput)
Vue.component('Cropper', Cropper)
Vue.component('InfoCard', InfoCard)
Vue.component('LoadFlower', LoadFlower)
Vue.component('Markdown', Markdown)
Vue.component('MdIcons', MdIcons)
Vue.component('PasteEditor', PasteEditor)
Vue.component('SplitPane', SplitPane)
Vue.component('TextArea', TextArea)
Vue.component('CommonIcon', CommonIcon)
}
/**
* 璁剧疆缁勪欢鏄犲皠琛紙灏嗗悗绔繑鍥炵殑璺緞鏄犲皠鍒板疄闄呯粍浠讹級
* @param {Object} customMap - 澶栭儴浼犲叆鐨勮嚜瀹氫箟缁勪欢鏄犲皠
* Setup component map
* @param {Object} customMap - custom component map
*/
setupComponentMap(customMap = {}) {
// 妗嗘灦鍐呯疆缁勪欢鍒楄〃锛氳矾寰?=> 缁勪欢
const components = {
'home/index': HomePage,
'system/sys_log': SysLog,
@@ -244,10 +183,10 @@ class AdminFramework {
'system_high/sys_control': SysControl,
'system_high/sys_menu': SysMenu,
'system_high/sys_title': SysTitle,
// 鍚堝苟澶栭儴浼犲叆鐨勭粍浠舵槧灏? ...customMap
...customMap
}
// 鑷姩鐢熸垚甯?.vue 鍜屼笉甯?.vue 鐨勬槧灏? const map = {}
const map = {}
Object.keys(components).forEach(path => {
const cleanPath = path.replace(/\.vue$/, '')
map[cleanPath] = components[path]
@@ -258,7 +197,9 @@ class AdminFramework {
}
/**
* 娣诲姞鑷畾涔夌粍浠舵槧灏? * @param {Object} customMap - 鑷畾涔夌粍浠舵槧灏勫璞? * @example
* Add custom component map
* @param {Object} customMap - custom component map
* @example
* AdminFramework.addComponentMap({
* 'ball/games.vue': GamesComponent,
* 'order/pay_orders.vue': PayOrdersComponent
@@ -269,9 +210,9 @@ class AdminFramework {
}
/**
* 鍒濆鍖?HTTP 閰嶇疆
* @param {Object} config - HTTP 閰嶇疆
* @param {Object} store - Vuex Store 瀹炰緥
* Init HTTP config
* @param {Object} config - HTTP config
* @param {Object} store - Vuex Store instance
*/
initHttp(config, store) {
http.init(config, store)
@@ -279,11 +220,13 @@ class AdminFramework {
}
/**
* 鍒涘缓璺敱瀹炰緥
* @param {Object} Router - VueRouter 绫? * @param {Object} components - 缁勪欢瀵硅薄
* @param {Array} customRoutes - 鑷畾涔夎矾鐢? * @param {Object} ViewUI - ViewUI 瀹炰緥
* @param {String} homeName - 棣栭〉鍚嶇О
* @returns {Object} router 瀹炰緥
* Create router instance
* @param {Object} Router - VueRouter class
* @param {Object} components - component object
* @param {Array} customRoutes - custom routes
* @param {Object} ViewUI - ViewUI instance
* @param {String} homeName - home page name
* @returns {Object} router instance
*/
createRouter(Router, components = {}, customRoutes = [], ViewUI, homeName = 'home') {
const { LoginPage, Page401, Page404, Page500 } = components
@@ -308,9 +251,11 @@ class AdminFramework {
}
/**
* 鍒涘缓 Store 瀹炰緥
* @param {Object} Vuex - Vuex 绫? * @param {Object} customModules - 鑷畾涔夋ā鍧? * @param {Object} createPersistedState - vuex-persistedstate 鎻掍欢
* @returns {Object} store 瀹炰緥
* Create Store instance
* @param {Object} Vuex - Vuex class
* @param {Object} customModules - custom modules
* @param {Object} createPersistedState - vuex-persistedstate plugin
* @returns {Object} store instance
*/
createStore(Vuex, customModules = {}, createPersistedState) {
const store = new Vuex.Store({
@@ -331,8 +276,10 @@ class AdminFramework {
}
/**
* 鑾峰彇鍔ㄦ€佽矾鐢? * @param {Object} components - 缁勪欢瀵硅薄
* @returns {Object} 涓昏矾鐢遍厤缃? */
* Get dynamic routes
* @param {Object} components - component object
* @returns {Object} main route config
*/
getRoutes(components = {}) {
const { Main, ParentView, Page404 } = components
@@ -345,9 +292,9 @@ class AdminFramework {
}
/**
* 娉ㄥ唽鍏ㄥ眬缁勪欢
* @param {Object} Vue - Vue 瀹炰緥
* @param {Object} components - 缁勪欢瀵硅薄
* Register global components
* @param {Object} Vue - Vue instance
* @param {Object} components - component object
*/
registerComponents(Vue, components = {}) {
Object.keys(components).forEach(name => {
@@ -356,28 +303,22 @@ class AdminFramework {
}
}
// ==================== 鍒涘缓瀹炰緥骞跺鍑?====================
const framework = new AdminFramework()
// 榛樿瀵煎嚭妗嗘灦瀹炰緥
export default framework
// 鎸夐渶瀵煎嚭
export {
// 宸ュ叿搴? tools,
tools,
uiTool,
http,
// Store 妯″潡
storeModules,
userModule,
appModule,
// 璺敱閰嶇疆
createBaseRoutes,
setupRouterGuards,
// 绯荤粺椤甸潰
HomePage,
SysLog,
SysParamSetup,
@@ -387,19 +328,16 @@ export {
SysMenu,
SysTitle,
// 鐧诲綍鍜岄敊璇〉闈? LoginPage,
LoginPage,
Page401,
Page404,
Page500,
// 甯冨眬缁勪欢
Main,
ParentView,
// 绯荤粺 API
systemApi,
systemHighApi,
// 妗嗘灦绫? AdminFramework
AdminFramework
}

View File

@@ -1,380 +0,0 @@
/**
* 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

@@ -1,380 +0,0 @@
/**
* 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'
// ==================== 全局组件 ====================
import Tables from './components/tables'
import Editor from './components/editor'
import UploadSingle from './components/upload/Single.vue'
import UploadMultiple from './components/upload/Multiple.vue'
import UploadCustom from './components/upload/Custom.vue'
import TreeGrid from './components/treeGrid'
import AsyncModal from './components/asyncModal'
import CronInput from './components/cron-input'
import Cropper from './components/cropper'
import InfoCard from './components/info-card'
import LoadFlower from './components/load-flower'
import Markdown from './components/markdown'
import MdIcons from './components/md-icons'
import PasteEditor from './components/paste-editor'
import SplitPane from './components/split-pane'
import TextArea from './components/text-area'
import CommonIcon from './components/common-icon'
// ==================== 绯荤粺 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
}