This commit is contained in:
张成
2025-10-28 11:24:11 +08:00
parent a8d52f74ad
commit e039ae8c62
39 changed files with 636 additions and 676 deletions

View File

@@ -20,197 +20,64 @@ import uiTool from './utils/uiTool'
import http from './utils/http'
import * as tools from './utils/tools'
import storeModules, { userModule, appModule } from './store'
import storeModules, { createStore } from './store'
import { createBaseRoutes, setupRouterGuards } from './router'
import { createBaseRoutes, setupRouterGuards, createRouter, getRoutes } from './router'
import HomePage from './views/home/index.vue'
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'
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 components from './components/index'
import pages from './views/index'
// 导入页面组件
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'
import TreeGrid from './components/treeGrid'
import AsyncModal from './components/asyncModal'
import InfoCard from './components/info-card'
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'
import editModal from './components/tables/editModal.vue'
import fieldItem from './components/tables/fieldItem.vue'
// 通过模块化方式导入页面组件
const {
HomePage,
LoginPage,
Page401,
Page404,
Page500,
SysLog,
SysParamSetup,
SysRole,
SysUser,
SysControl,
SysMenu,
SysTitle,
setupComponentMap
} = pages
// 导入组件相关功能
import components, { registerGlobalComponents, registerComponents } from './components/index'
import * as systemApi from './api/system'
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.ViewUI = null
this.tools = tools
this.uiTool = uiTool
this.http = http
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
this.pages = pages
this.components = components
this.systemApi = systemApi
this.systemHighApi = systemHighApi
}
/**
* Vue plugin install method
* @param {Object} Vue - Vue instance
* @param {Object} options - config options
*/
install(Vue, options = {}) {
if (this.installed) return
this.installed = true
const { config = {}, ViewUI, VueRouter, Vuex, createPersistedState, componentMap } = options
this.config = config
this.ViewUI = ViewUI
if (ViewUI) {
Vue.use(ViewUI)
}
if (VueRouter) {
Vue.use(VueRouter)
}
if (Vuex) {
Vue.use(Vuex)
}
Vue.prototype.$config = config
Vue.prototype.$http = http
Vue.prototype.$tools = tools
Vue.prototype.$uiTool = uiTool
Vue.prototype.$framework = this
this.registerGlobalComponents(Vue)
this.setupComponentMap(componentMap)
if (Vuex && !this.store) {
this.store = this.createStore(Vuex, {}, createPersistedState)
http.init(config, this.store)
}
if (VueRouter && !this.router) {
const mainRoute = this.getRoutes({ Main, ParentView, Page404, HomePage: this.HomePage })
this.router = this.createRouter(VueRouter, {
Main,
ParentView,
LoginPage,
Page401,
Page404,
Page500
}, mainRoute ? [mainRoute] : [], ViewUI)
}
}
/**
* 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)
Vue.component('TreeGrid', TreeGrid)
Vue.component('AsyncModal', AsyncModal)
Vue.component('InfoCard', InfoCard)
Vue.component('LoadFlower', LoadFlower)
Vue.component('SplitPane', SplitPane)
Vue.component('TextArea', TextArea)
Vue.component('CommonIcon', CommonIcon)
Vue.component('Editor', Editor)
Vue.component('editModal', editModal)
Vue.component('fieldItem', fieldItem)
}
/**
* Setup component map
* @param {Object} customMap - custom component map
*/
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
}
const map = {}
Object.keys(components).forEach(path => {
const cleanPath = path.replace(/\.vue$/, '')
map[cleanPath] = components[path]
map[cleanPath + '.vue'] = components[path]
})
uiTool.setComponentMap(map)
}
/**
* Add custom component map
@@ -222,7 +89,7 @@ class AdminFramework {
* })
*/
addComponentMap(customMap) {
uiTool.setComponentMap(customMap)
setupComponentMap(customMap, uiTool)
}
/**
@@ -235,88 +102,9 @@ class AdminFramework {
this.store = store
}
/**
* 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
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
}
/**
* 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({
modules: {
user: userModule,
app: appModule,
...customModules
},
plugins: createPersistedState ? [
createPersistedState({
storage: window.localStorage
})
] : []
})
this.store = store
return store
}
/**
* Get dynamic routes
* @param {Object} components - component object
* @returns {Object} main route config
*/
getRoutes(components = {}) {
const { Main, ParentView, Page404, HomePage } = components
if (!Main || !ParentView || !Page404) {
console.error('Missing required layout components')
return null
}
return uiTool.getRoutes(Main, ParentView, Page404, HomePage || this.HomePage)
}
/**
* Register global components
* @param {Object} Vue - Vue instance
* @param {Object} components - component object
*/
registerComponents(Vue, components = {}) {
Object.keys(components).forEach(name => {
Vue.component(name, components[name])
})
}
/**
* Create app with simplified API (推荐使用)
@@ -329,23 +117,50 @@ class AdminFramework {
* @returns {Object} Vue instance
*/
createApp(config = {}) {
// Auto install framework using internal dependencies
if (!this.installed) {
const { componentMap, ...appConfig } = config
// 如果没有提供 uploadUrl自动从 apiUrl 推导
if (!config.uploadUrl && config.apiUrl) {
config.uploadUrl = config.apiUrl + (config.apiUrl.endsWith('/') ? 'upload' : '/upload')
}
// 如果没有提供 uploadUrl自动从 apiUrl 推导
if (!appConfig.uploadUrl && appConfig.apiUrl) {
appConfig.uploadUrl = appConfig.apiUrl + (appConfig.apiUrl.endsWith('/') ? 'upload' : '/upload')
}
// 设置配置
this.config = config
this.install(Vue, {
config: appConfig,
ViewUI,
VueRouter,
Vuex,
createPersistedState: null,
componentMap: componentMap || {}
})
// 初始化 Vue 插件
Vue.use(ViewUI)
Vue.use(VueRouter)
Vue.use(Vuex)
// 设置全局属性
Vue.prototype.$config = config
Vue.prototype.$http = http
Vue.prototype.$tools = tools
Vue.prototype.$uiTool = uiTool
Vue.prototype.$framework = this
// 注册全局组件
registerGlobalComponents(Vue)
// 设置组件映射
setupComponentMap(config.componentMap || {}, uiTool)
// 创建 Store
if (!this.store) {
this.store = createStore(Vuex, {}, null)
http.init(config, this.store)
}
// 创建 Router
if (!this.router) {
const mainRoute = getRoutes({ Main, ParentView, Page404, HomePage: this.HomePage }, uiTool)
this.router = createRouter(VueRouter, {
Main,
ParentView,
LoginPage,
Page401,
Page404,
Page500
}, mainRoute ? [mainRoute] : [], ViewUI)
}
// Create Vue instance with auto menu/title restoration
@@ -421,9 +236,6 @@ export {
http,
storeModules,
userModule,
appModule,
createBaseRoutes,
setupRouterGuards,