feat(utils): 重构路由生成逻辑
- 移除 autoRoutes.js 文件,改为使用 apps.js 存储路由信息 - 新增 createRoutes 函数,用于动态生成应用路由 - 更新 build.js,增加路由生成步骤 - 修改 router.js,使用新的路由配置 - 更新 .gitignore,忽略新的 apps.js 文件
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -30,3 +30,4 @@ yarn-error.log*
|
||||
/examples/router/apps.js
|
||||
/src/apps/
|
||||
/src/config.json
|
||||
/src/utils/apps.js
|
||||
|
||||
61
bin/build.js
61
bin/build.js
@@ -1,5 +1,6 @@
|
||||
const axios = require('axios')
|
||||
const {fsExtra, copyFiles} = require("./tools");
|
||||
const {fsExtra, copyFiles, findApp, chalkTag, fs} = require("./tools");
|
||||
const compiler = require('vue-template-compiler')
|
||||
const getBuildConfig = id => {
|
||||
axios.post('http://192.168.1.87:12525/node/custom/detail', null, {params: {id}}).then(res => {
|
||||
if (res?.data) {
|
||||
@@ -9,6 +10,60 @@ const getBuildConfig = id => {
|
||||
}
|
||||
})
|
||||
}
|
||||
const getAppInfo = (file, apps) => {
|
||||
if (/[\\\/](App[A-Z][^\\\/]+)\.vue$/g.test(file)) {
|
||||
const name = file.replace(/.+[\\\/](App[^\\\/]+)\.vue$/, '$1'),
|
||||
source = fs.readFileSync(file).toString(),
|
||||
parsed = compiler.parseComponent(source),
|
||||
script = parsed.script?.content || "",
|
||||
label = script.match(/label:[^,]+/)?.[0]?.replace(/.+["']([^"']+).+/, '$1')
|
||||
const paths = file.split(/[\\\/]/)
|
||||
apps.push({
|
||||
id: file.replace(/\.vue$/, '').replace(/[\\\/]/g, '_'),
|
||||
label: label || name,
|
||||
path: `/${file.replace(/\.vue$/, '').replace(/[\\\/]/g, '/')}`,
|
||||
workspace: paths.at(0),
|
||||
esm: file.replace(/[\\\/]/g, '/').substring(4),
|
||||
name
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置生成应用路由
|
||||
* @param {Object} config - 配置对象,用于定制化路由生成过程
|
||||
* @returns {Promise} - 返回一个Promise对象,表示路由生成完成
|
||||
*/
|
||||
const createRoutes = (config = {}) => {
|
||||
// 初始化路由数组
|
||||
const routes = []
|
||||
// 获取签到页面的路径,如果未指定,则使用默认路径
|
||||
let signPage = '../views/sign'
|
||||
if (config.extra?.signPage) {
|
||||
const sign = config.extra.signPage
|
||||
signPage = `../apps/custom/${sign}/${sign}`
|
||||
}
|
||||
|
||||
// 查找并处理所有应用,将它们的信息添加到路由中
|
||||
return findApp("src/apps", app => getAppInfo(app, routes)).then(() => {
|
||||
// 生成并输出apps.js文件,定义所有应用的路由
|
||||
fsExtra.outputFile('src/utils/apps.js', `export default [
|
||||
{path: "/login", name: "登录", component: () => import('${signPage}')},
|
||||
{path: '/dv', name: '数据大屏入口', component: () => import('../views/dvIndex')},
|
||||
{path: '/v', name: 'Home', component: () => import('../views/home'), children: [
|
||||
${routes.map(e => {
|
||||
// 解构每个路由的属性,用于生成路由配置
|
||||
const {name, label, path, esm} = e
|
||||
// 生成单个路由配置的字符串表示
|
||||
return `{name:"${name}",label:"${label}",path:"${path}",component:()=>import("../${esm}")}`
|
||||
}).join(',\n')}
|
||||
]},
|
||||
{path: '/', name: "init"},
|
||||
]`)
|
||||
// 扫描完毕,使用chalkTag标记任务完成
|
||||
chalkTag.done("扫描完毕")
|
||||
})
|
||||
}
|
||||
|
||||
const createPages = (config = {}) => {
|
||||
fsExtra.emptyDir("src/apps", err => {
|
||||
@@ -24,13 +79,13 @@ const createPages = (config = {}) => {
|
||||
copyFiles("src/apps/core", "packages/core"),
|
||||
copyFiles("src/apps/custom", `project/${customPath}`),
|
||||
...Object.keys(stdApps).map(e => copyFiles(`src/apps/${e.replace(/^packages[\\\/]/, '')}`, e)),
|
||||
]).then(() => fsExtra.ensureFile("src/apps/actions.js"))
|
||||
]).then(() => createRoutes(config)).then(() => fsExtra.ensureFile("src/apps/actions.js"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const start = () => {
|
||||
const buildId = process.argv[2] || 'f670cc46-7cf7-4a0f-86ee-3077044c0b17'
|
||||
const buildId = process.argv[2] || process.env.VUE_APP_OMS_ID || 'f670cc46-7cf7-4a0f-86ee-3077044c0b17'
|
||||
getBuildConfig(buildId)
|
||||
}
|
||||
start()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Message} from 'element-ui'
|
||||
import { Message } from 'element-ui'
|
||||
import instance from 'dui/lib/js/request'
|
||||
|
||||
let baseURLs = {
|
||||
@@ -12,6 +12,9 @@ instance.interceptors.request.use(config => {
|
||||
}
|
||||
if (process.env.VUE_APP_IS_SIMPLE_SERVER == 1) {
|
||||
config.url = config.url.replace(/(app|auth|admin)\//, "api/")
|
||||
if (['xumu'].includes(process.env.VUE_APP_SCOPE)) {
|
||||
config.url = config.url.replace("/api/", "/")
|
||||
}
|
||||
}
|
||||
return config
|
||||
}, error => Message.error(error))
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"preview": "node bin/build.js && vue-cli-service serve",
|
||||
"predev": "node bin/scanApps.js",
|
||||
"preoms": "dotenv -e .env.oms node bin/scanApps.js",
|
||||
"prexumu": "dotenv -e .env.xumu node bin/scanApps.js"
|
||||
"prexumu": "dotenv -e .env.xumu node bin/scanApps.js",
|
||||
"preview:xumu":"dotenv -e .env.xumu node bin/build.js&& vue-cli-service serve --mode xumu"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
|
||||
@@ -6,7 +6,6 @@ import utils from './utils';
|
||||
import vcUI from 'dui/packages';
|
||||
import appComp from 'dui/dv';
|
||||
import store from './utils/store';
|
||||
import autoRoutes from "./utils/autoRoutes";
|
||||
import extra from "./config.json"
|
||||
import axios from "./utils/axios";
|
||||
//备注底座信息,勿删
|
||||
@@ -19,7 +18,7 @@ Vue.config.productionTip = false;
|
||||
Vue.prototype.$cdn = "https://cdn.cunwuyun.cn"
|
||||
Vue.prototype.$request = axios
|
||||
Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e]));
|
||||
const loadPage = () => autoRoutes.init().finally(() => new Vue({router, store, render: h => h(App)}).$mount("#app"))
|
||||
const loadPage = () => new Vue({router, store, render: h => h(App)}).$mount("#app")
|
||||
let theme = null
|
||||
store.dispatch('getSystem', extra.sysInfo).then(res => {
|
||||
theme = JSON.parse(res?.colorScheme || null)
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import {waiting} from "./index";
|
||||
import router from "./router";
|
||||
import store from "./store";
|
||||
import {Message} from "element-ui";
|
||||
import Vue from "vue";
|
||||
import extra from "../config.json"
|
||||
|
||||
let {state: {user}, commit, dispatch} = store
|
||||
const signOut = () => commit("signOut"),
|
||||
getUserInfo = () => dispatch("getUserInfo"),
|
||||
existRoute = route => {
|
||||
return router.getRoutes()?.find(e => e.name == route?.name || e.path == route?.path)
|
||||
},
|
||||
goto = (route, next) => {
|
||||
const exist = !!existRoute(route)
|
||||
return exist ? route.name ? next() : router.replace(route) :
|
||||
!route.name && route.path == "/" ? router.replace({name: "Home"}).catch(() => 0) :
|
||||
Message.error("无法找到路由,请联系系统管理员!")
|
||||
}
|
||||
const loadApps = () => {
|
||||
//新App的自动化格式
|
||||
waiting.init({innerHTML: '应用加载中..'})
|
||||
let apps = require.context('../apps', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, "lazy")
|
||||
return Promise.all(apps.keys().map(path => apps(path).then(file => {
|
||||
if (file.default) {
|
||||
let {name} = file.default
|
||||
waiting.setContent(`加载${name}...`)
|
||||
Vue.component(name, file.default)
|
||||
} else return 0
|
||||
}))).then(() => {
|
||||
waiting.setContent(`正在进入系统...`)
|
||||
setTimeout(() => waiting.close(), 1000)
|
||||
})
|
||||
}
|
||||
const addHome = homePage => {
|
||||
const component = extra?.homePage || homePage.path
|
||||
if (extra?.homePage && Vue.component(component)) {
|
||||
homePage = {...homePage, path: component, component: () => import('../views/mainEntry'), meta: component}
|
||||
}
|
||||
router.addRoute('Home', homePage)
|
||||
router.options.routes[2].children.unshift(homePage)
|
||||
commit("setHomePage", {
|
||||
...homePage,
|
||||
label: homePage.name,
|
||||
id: `/v/${component}`,
|
||||
isMenu: 1,
|
||||
route: homePage.name,
|
||||
component,
|
||||
path: component,
|
||||
})
|
||||
}
|
||||
const generateRoutes = (to, from, next) => {
|
||||
if (router.options.routes[2].children.length > 0) {
|
||||
goto(to, next)
|
||||
} else {
|
||||
Promise.all([getUserInfo(), loadApps()]).then(() => {
|
||||
//初始化默认工作台
|
||||
let homePage = {name: "工作台", path: "console", style: "iconfont iconNav_Dashborad", component: () => import('../views/console')}
|
||||
addHome(homePage)
|
||||
const mods = user.info.menuSet?.filter(e => !!e.component)?.map(e => ({route: e.id, ...e}))
|
||||
mods?.map(({route: name, path, component}) => {
|
||||
if (!!Vue.component(component) && path && !existRoute({name})) {
|
||||
let search = path.split("?")
|
||||
path = search?.[0] || path
|
||||
const route = {name, path, component: () => import('../views/mainEntry'), meta: component}
|
||||
router.addRoute('Home', route)
|
||||
router.options.routes[2].children.push(route)
|
||||
}
|
||||
})
|
||||
to.name == "Home" ? next({name: homePage.name, replace: true}) : next({...to, replace: true})
|
||||
}).then(() => commit("setRoutes", router.options.routes[2].children))
|
||||
}
|
||||
}
|
||||
export const routes = [
|
||||
{path: "/login", name: "登录", component: () => import('../views/sign')},
|
||||
{path: '/dv', name: '数据大屏入口', component: () => import('../views/dvIndex')},
|
||||
{path: '/v', name: 'Home', component: () => import('../views/home'), children: []},
|
||||
{path: '/', name: "init"},
|
||||
]
|
||||
export default {
|
||||
init: () => {
|
||||
router.beforeEach((to, from, next) => {
|
||||
console.log('%s=>%s', from.name, to.name)
|
||||
if (to.hash == "#pddv") {
|
||||
const {query} = to
|
||||
dispatch("getToken", {
|
||||
username: "18971406276",
|
||||
password: "admin321!"
|
||||
}).then(() => next({name: "数据大屏入口", query, hash: "#dv"}))
|
||||
} else if (["数据大屏入口", "登录"].includes(to.name)) {
|
||||
next()
|
||||
} else if (to.hash == "#dv") {
|
||||
//数据大屏进行的独立页面跳转
|
||||
let {query, hash} = to
|
||||
next({name: "数据大屏入口", query, hash})
|
||||
} else if (user.token) {
|
||||
to.name == "init" ? next({name: "Home"}) : generateRoutes(to, from, next)
|
||||
} else {
|
||||
signOut()
|
||||
}
|
||||
})
|
||||
router.onError(err => {
|
||||
console.error(err)
|
||||
})
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import {routes} from "./autoRoutes"
|
||||
import routes from "./apps.js"
|
||||
import config from "../config.json"
|
||||
import store from "@/utils/store";
|
||||
|
||||
const {state: {user}, commit, dispatch} = store
|
||||
const signOut = () => commit("signOut")
|
||||
Vue.use(VueRouter)
|
||||
export default new VueRouter({
|
||||
const router = new VueRouter({
|
||||
base: config.base || '/',
|
||||
mode: 'history',
|
||||
hashbang: false,
|
||||
@@ -17,3 +20,29 @@ export default new VueRouter({
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
console.log('%s=>%s', from.name, to.name)
|
||||
if (to.hash == "#pddv") {
|
||||
const {query} = to
|
||||
dispatch("getToken", {
|
||||
username: "18971406276",
|
||||
password: "admin321!"
|
||||
}).then(() => next({name: "数据大屏入口", query, hash: "#dv"}))
|
||||
} else if (["数据大屏入口", "登录"].includes(to.name)) {
|
||||
next()
|
||||
} else if (to.hash == "#dv") {
|
||||
//数据大屏进行的独立页面跳转
|
||||
let {query, hash} = to
|
||||
next({name: "数据大屏入口", query, hash})
|
||||
} else if (user.token) {
|
||||
to.name == "init" ? next({name: "Home"}) : next()
|
||||
} else {
|
||||
signOut()
|
||||
}
|
||||
})
|
||||
router.onError(err => {
|
||||
console.error(err)
|
||||
})
|
||||
|
||||
export default router
|
||||
|
||||
Reference in New Issue
Block a user