From 536f579523e899bc467df094745bae297033f138 Mon Sep 17 00:00:00 2001 From: aixianling Date: Tue, 17 Dec 2024 09:34:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(utils):=20=E9=87=8D=E6=9E=84=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E7=94=9F=E6=88=90=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 autoRoutes.js 文件,改为使用 apps.js 存储路由信息 - 新增 createRoutes 函数,用于动态生成应用路由 - 更新 build.js,增加路由生成步骤 - 修改 router.js,使用新的路由配置 - 更新 .gitignore,忽略新的 apps.js 文件 --- .gitignore | 1 + bin/build.js | 61 ++++++++++++++++++++-- examples/router/axios.js | 5 +- package.json | 3 +- src/main.js | 3 +- src/utils/autoRoutes.js | 107 --------------------------------------- src/utils/router.js | 33 +++++++++++- 7 files changed, 97 insertions(+), 116 deletions(-) delete mode 100644 src/utils/autoRoutes.js diff --git a/.gitignore b/.gitignore index d8c17abb..ad55a302 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ yarn-error.log* /examples/router/apps.js /src/apps/ /src/config.json +/src/utils/apps.js diff --git a/bin/build.js b/bin/build.js index a82030f9..04a78070 100644 --- a/bin/build.js +++ b/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() diff --git a/examples/router/axios.js b/examples/router/axios.js index 92ef0538..a5be821d 100644 --- a/examples/router/axios.js +++ b/examples/router/axios.js @@ -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)) diff --git a/package.json b/package.json index f6d65669..40d4b00c 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/main.js b/src/main.js index be3ac3d8..8799943c 100644 --- a/src/main.js +++ b/src/main.js @@ -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) diff --git a/src/utils/autoRoutes.js b/src/utils/autoRoutes.js deleted file mode 100644 index b9ce6410..00000000 --- a/src/utils/autoRoutes.js +++ /dev/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() - } -} diff --git a/src/utils/router.js b/src/utils/router.js index ba25ce28..73524ce7 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -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