Commit a973aefa authored by 陈浩玮's avatar 陈浩玮

Merge branch 'feature/shuiluo' into 'master'

feat: 优化国际化异常的问题

See merge request product/kim3-web-vue/starter-web-vue!23
parents f73bbf52 6764e9f3
...@@ -33,8 +33,7 @@ const store = new Vuex.Store({ ...@@ -33,8 +33,7 @@ const store = new Vuex.Store({
//装载vue-router控件 如果开发时 不用动态可直接修改这里 isAsynRount=false //装载vue-router控件 如果开发时 不用动态可直接修改这里 isAsynRount=false
Vue.use(Router); Vue.use(Router);
const isAsynRount = store.state.settingModule.asyncRoutes; const options = initRouter();
const options = initRouter(isAsynRount);
const router = new Router(options); const router = new Router(options);
//装载vue-i18n控件 如果语言优先级 请直接修改这里localeLang和fallbackLang //装载vue-i18n控件 如果语言优先级 请直接修改这里localeLang和fallbackLang
......
<template> <template>
<a-dropdown class="lang header-item"> <a-dropdown class="lang header-item">
<div><a-icon type="global" /> {{ langAlias }}</div> <div><a-icon type="global" /> {{ langAlias }}</div>
<a-menu @click="changeLang" :selected-keys="[lang]" slot="overlay"> <a-menu @click="change" :selected-keys="[lang]" slot="overlay">
<a-menu-item v-for="lang in langList" :key="lang.key"> <a-menu-item v-for="lang in langList" :key="lang.key">
{{ lang.key.toLowerCase() + ' ' + lang.name }} {{ lang.key.toLowerCase() + ' ' + lang.name }}
</a-menu-item> </a-menu-item>
...@@ -27,10 +27,9 @@ export default { ...@@ -27,10 +27,9 @@ export default {
}, },
}, },
methods: { methods: {
change(langKey) { change({ key }) {
this.$i18n.locale = langKey; langUtils.set(key);
this.lang = langKey; window.location.reload();
langUtils.set(langKey);
}, },
}, },
}; };
......
<template> <template>
<div class="side-setting"> <div class="side-setting">
<setting-item> <setting-item>
<a-button @click="saveSetting" type="primary" icon="save">{{$t('save')}}</a-button> <a-button @click="saveSetting" type="primary" icon="save">{{ $t('save') }}</a-button>
<a-button @click="resetSetting" type="dashed" icon="redo" style="float: right">{{$t('reset')}}</a-button> <a-button @click="resetSetting" type="dashed" icon="redo" style="float: right">
{{ $t('reset') }}
</a-button>
</setting-item> </setting-item>
<setting-item :title="$t('theme.title')"> <setting-item :title="$t('theme.title')">
<img-checkbox-group @change="values => setTheme({...theme, mode: values[0]})" :default-values="[theme.mode]"> <img-checkbox-group
<img-checkbox :title="$t('theme.dark')" img="https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg" value="dark" /> @change="values => setTheme({ ...theme, mode: values[0] })"
<img-checkbox :title="$t('theme.light')" img="https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg" value="light" /> :default-values="[theme.mode]"
<img-checkbox :title="$t('theme.night')" img="https://gw.alipayobjects.com/zos/antfincdn/hmKaLQvmY2/LCkqqYNmvBEbokSDscrm.svg" value="night" /> >
<img-checkbox
:title="$t('theme.dark')"
img="https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg"
value="dark"
/>
<img-checkbox
:title="$t('theme.light')"
img="https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg"
value="light"
/>
</img-checkbox-group> </img-checkbox-group>
</setting-item> </setting-item>
<setting-item :title="$t('theme.color')"> <setting-item :title="$t('theme.color')">
<color-checkbox-group @change="(values, colors) => setTheme({...theme, color: colors[0]})" :defaultValues="[palettes.indexOf(theme.color)]" :multiple="false"> <color-checkbox-group
<color-checkbox v-for="(color, index) in palettes" :key="index" :color="color" :value="index" /> @change="(values, colors) => setTheme({ ...theme, color: colors[0] })"
:defaultValues="[palettes.indexOf(theme.color)]"
:multiple="false"
>
<color-checkbox
v-for="(color, index) in palettes"
:key="index"
:color="color"
:value="index"
/>
</color-checkbox-group> </color-checkbox-group>
</setting-item> </setting-item>
<a-divider /> <a-divider />
<setting-item :title="$t('navigate.title')"> <setting-item :title="$t('navigate.title')">
<img-checkbox-group @change="values => setLayout(values[0])" :default-values="[layout]"> <img-checkbox-group @change="values => setLayout(values[0])" :default-values="[layout]">
<img-checkbox :title="$t('navigate.side')" img="https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg" value="side" /> <img-checkbox
<img-checkbox :title="$t('navigate.head')" img="https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg" value="head" /> :title="$t('navigate.side')"
<img-checkbox :title="$t('navigate.mix')" img="https://gw.alipayobjects.com/zos/antfincdn/x8Ob%26B8cy8/LCkqqYNmvBEbokSDscrm.svg" value="mix" /> img="https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg"
value="side"
/>
<img-checkbox
:title="$t('navigate.head')"
img="https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg"
value="head"
/>
<img-checkbox
:title="$t('navigate.mix')"
img="https://gw.alipayobjects.com/zos/antfincdn/x8Ob%26B8cy8/LCkqqYNmvBEbokSDscrm.svg"
value="mix"
/>
</img-checkbox-group> </img-checkbox-group>
</setting-item> </setting-item>
<setting-item> <setting-item>
<a-list :split="false"> <a-list :split="false">
<a-list-item> <a-list-item>
{{$t('navigate.content.title')}} {{ $t('navigate.content.title') }}
<a-select :getPopupContainer="getPopupContainer" :value="pageWidth" @change="setPageWidth" class="select-item" size="small" slot="actions"> <a-select
<a-select-option value="fluid">{{$t('navigate.content.fluid')}}</a-select-option> :getPopupContainer="getPopupContainer"
<a-select-option value="fixed">{{$t('navigate.content.fixed')}}</a-select-option> :value="pageWidth"
@change="setPageWidth"
class="select-item"
size="small"
slot="actions"
>
<a-select-option value="fluid">{{ $t('navigate.content.fluid') }}</a-select-option>
<a-select-option value="fixed">{{ $t('navigate.content.fixed') }}</a-select-option>
</a-select> </a-select>
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
{{$t('navigate.fixedHeader')}} {{ $t('navigate.fixedHeader') }}
<a-switch :checked="fixedHeader" slot="actions" size="small" @change="setFixedHeader" /> <a-switch :checked="fixedHeader" slot="actions" size="small" @change="setFixedHeader" />
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
{{$t('navigate.fixedSideBar')}} {{ $t('navigate.fixedSideBar') }}
<a-switch :checked="fixedSideBar" slot="actions" size="small" @change="setFixedSideBar" /> <a-switch :checked="fixedSideBar" slot="actions" size="small" @change="setFixedSideBar" />
</a-list-item> </a-list-item>
</a-list> </a-list>
...@@ -47,11 +87,11 @@ ...@@ -47,11 +87,11 @@
<setting-item :title="$t('other.title')"> <setting-item :title="$t('other.title')">
<a-list :split="false"> <a-list :split="false">
<a-list-item> <a-list-item>
{{$t('other.multiPages')}} {{ $t('other.multiPages') }}
<a-switch :checked="multiPage" slot="actions" size="small" @change="setMultiPage" /> <a-switch :checked="multiPage" slot="actions" size="small" @change="setMultiPage" />
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
{{$t('other.hideSetting')}} {{ $t('other.hideSetting') }}
<a-switch :checked="hideSetting" slot="actions" size="small" @change="setHideSetting" /> <a-switch :checked="hideSetting" slot="actions" size="small" @change="setHideSetting" />
</a-list-item> </a-list-item>
</a-list> </a-list>
...@@ -60,24 +100,46 @@ ...@@ -60,24 +100,46 @@
<setting-item :title="$t('animate.title')"> <setting-item :title="$t('animate.title')">
<a-list :split="false"> <a-list :split="false">
<a-list-item> <a-list-item>
{{$t('animate.disable')}} {{ $t('animate.disable') }}
<a-switch :checked="animate.disabled" slot="actions" size="small" @change="val => setAnimate({...animate, disabled: val})" /> <a-switch
:checked="animate.disabled"
slot="actions"
size="small"
@change="val => setAnimate({ ...animate, disabled: val })"
/>
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
{{$t('animate.effect')}} {{ $t('animate.effect') }}
<a-select :value="animate.name" :getPopupContainer="getPopupContainer" @change="val => setAnimate({...animate, name: val})" class="select-item" size="small" slot="actions"> <a-select
<a-select-option :key="index" :value="item.name" v-for="(item, index) in animates">{{item.alias}}</a-select-option> :value="animate.name"
:getPopupContainer="getPopupContainer"
@change="val => setAnimate({ ...animate, name: val })"
class="select-item"
size="small"
slot="actions"
>
<a-select-option :key="index" :value="item.name" v-for="(item, index) in animates">{{
item.alias
}}</a-select-option>
</a-select> </a-select>
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
{{$t('animate.direction')}} {{ $t('animate.direction') }}
<a-select :value="animate.direction" :getPopupContainer="getPopupContainer" @change="val => setAnimate({...animate, direction: val})" class="select-item" size="small" slot="actions"> <a-select
<a-select-option :key="index" :value="item" v-for="(item, index) in directions">{{item}}</a-select-option> :value="animate.direction"
:getPopupContainer="getPopupContainer"
@change="val => setAnimate({ ...animate, direction: val })"
class="select-item"
size="small"
slot="actions"
>
<a-select-option :key="index" :value="item" v-for="(item, index) in directions">{{
item
}}</a-select-option>
</a-select> </a-select>
</a-list-item> </a-list-item>
</a-list> </a-list>
</setting-item> </setting-item>
</div> </div>
</template> </template>
...@@ -176,7 +238,7 @@ export default { ...@@ -176,7 +238,7 @@ export default {
}, },
computed: { computed: {
directions() { directions() {
return this.animates.find((item) => item.name == this.animate.name).directions; return this.animates.find(item => item.name == this.animate.name).directions;
}, },
...mapState('settingModule', [ ...mapState('settingModule', [
'theme', 'theme',
...@@ -192,7 +254,7 @@ export default { ...@@ -192,7 +254,7 @@ export default {
]), ]),
}, },
watch: { watch: {
'animate.name': function (val) { 'animate.name': function(val) {
this.setAnimate({ name: val, direction: this.directions[0] }); this.setAnimate({ name: val, direction: this.directions[0] });
}, },
}, },
...@@ -220,7 +282,7 @@ export default { ...@@ -220,7 +282,7 @@ export default {
let config = {}; let config = {};
let mySetting = this.$store.state.settingModule; let mySetting = this.$store.state.settingModule;
let dftSetting = local ? settingConfig : settingConfig; let dftSetting = local ? settingConfig : settingConfig;
Object.keys(mySetting).forEach((key) => { Object.keys(mySetting).forEach(key => {
const dftValue = dftSetting[key], const dftValue = dftSetting[key],
myValue = mySetting[key]; myValue = mySetting[key];
if (dftValue != undefined && !fastEqual(dftValue, myValue)) { if (dftValue != undefined && !fastEqual(dftValue, myValue)) {
......
...@@ -170,6 +170,7 @@ export default { ...@@ -170,6 +170,7 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
.admin-layout { .admin-layout {
height: 100%;
.side-menu { .side-menu {
&.fixed-side { &.fixed-side {
position: fixed; position: fixed;
......
<template>
<router-view />
</template>
<script>
import { mapState } from 'vuex';
export default {
name: 'BlankTemplateView',
computed: {
...mapState('settingModule', ['multiPage']),
},
};
</script>
import BlankTemplateView from './BlankTemplateView';
import PageTemplateView from './PageTemplateView'; import PageTemplateView from './PageTemplateView';
import TabsTemplateView from './TabsTemplateView'; import TabsTemplateView from './TabsTemplateView';
export { BlankTemplateView, PageTemplateView, TabsTemplateView } export { PageTemplateView, TabsTemplateView };
import Home from './index.vue';
export default Home;
import LoginLog from './index.vue';
export default LoginLog;
<template> <template>
<div> <div>
<a-button type="primary" class="tw-mb-2" @click="add">新增</a-button> <a-button type="primary" class="tw-mb-2" @click="add">新增</a-button>
<a-table :dataSource="components" :rowKey="getRowKey"> <a-table :dataSource="components" :rowKey="getRowKey" :pagination="false">
<a-table-column title="组件编码"> <a-table-column title="组件编码">
<template #default="row"> <template #default="row">
<span v-if="row.componentId">{{ row.componentCode }}</span> <span v-if="row.componentId">{{ row.componentCode }}</span>
......
import routerMap from './router.map'
import {parseRoutes} from '@/utils/routerUtil'
// 异步路由配置
const routesConfig = [
'login',
'root',
{
router: 'exp404',
path: '*',
name: '404'
},
{
router: 'exp403',
path: '/403',
name: '403'
}
]
const options = {
routes: parseRoutes(routesConfig, routerMap)
}
export default options
// 视图组件
const view = {
tabs: () => import('@/pages/frame/view/template/TabsTemplateView'),
blank: () => import('@/pages/frame/view/template/BlankTemplateView'),
page: () => import('@/pages/frame/view/template/PageTemplateView'),
};
// 路由组件注册
const routerMap = {
login: {
authority: '*',
path: '/login',
component: () => import('@/pages/frame/view/login'),
},
root: {
path: '/',
name: '首页',
redirect: '/login',
component: view.tabs,
},
exp403: {
authority: '*',
name: '403错误',
path: '403',
component: () => import('@/pages/frame/view/exception/403'),
},
exp404: {
name: '404错误',
path: '404',
component: () => import('@/pages/frame/view/exception/404'),
},
exp500: {
name: '500错误',
path: '500',
component: () => import('@/pages/frame/view/exception/500'),
},
dashboard: {
name: 'Dashboard',
component: view.blank,
},
workbench: {
name: '工作台',
component: () => import('@/pages/dashboard/workbench'),
},
analysis: {
name: '分析页',
component: () => import('@/pages/dashboard/analysis'),
},
system_management: {
name: '系统管理',
component: view.page,
},
menu_management: {
name: '菜单管理',
component: () => import('@/pages/system/view/menu'),
},
};
export default routerMap;
import { BlankTemplateView, PageTemplateView, TabsTemplateView } from '@/pages/frame/view/template'; import { PageTemplateView, TabsTemplateView } from '@/pages/frame/view/template';
// 路由配置 // 路由配置
const options = { const options = {
...@@ -9,11 +9,6 @@ const options = { ...@@ -9,11 +9,6 @@ const options = {
name: '登录页', name: '登录页',
component: () => import('@/pages/frame/view/login'), component: () => import('@/pages/frame/view/login'),
}, },
{
path: '*',
name: '404',
component: () => import('@/pages/frame/view/exception/404'),
},
{ {
path: '/403', path: '/403',
name: '403', name: '403',
...@@ -42,7 +37,6 @@ const options = { ...@@ -42,7 +37,6 @@ const options = {
meta: { meta: {
icon: 'dashboard', icon: 'dashboard',
}, },
component: BlankTemplateView,
children: [ children: [
{ {
path: 'workbench', path: 'workbench',
...@@ -62,7 +56,7 @@ const options = { ...@@ -62,7 +56,7 @@ const options = {
], ],
}, },
{ {
path: 'system_management', path: 'system',
name: '系统管理', name: '系统管理',
meta: { meta: {
icon: 'setting', icon: 'setting',
...@@ -73,29 +67,28 @@ const options = { ...@@ -73,29 +67,28 @@ const options = {
component: PageTemplateView, component: PageTemplateView,
children: [ children: [
{ {
path: 'menu_management', path: 'menu',
name: '菜单管理', name: '菜单管理',
component: () => import('@/pages/system/view/menu'), component: () => import('@/pages/system/view/menu'),
}, },
{ {
path: 'organization_management', path: 'organization',
name: '组织管理', name: '组织管理',
component: BlankTemplateView,
children: [ children: [
{ {
path: 'job_management', path: 'job',
name: '岗位管理', name: '岗位管理',
component: () => component: () =>
import('@/pages/system/view/organization/jobsmanagement/Jobs.vue'), import('@/pages/system/view/organization/jobsmanagement/Jobs.vue'),
}, },
{ {
path: 'user_management', path: 'user',
name: '用户管理', name: '用户管理',
component: () => component: () =>
import('@/pages/system/view/organization/usermanagement/User.vue'), import('@/pages/system/view/organization/usermanagement/User.vue'),
}, },
{ {
path: 'org_management', path: 'org',
name: '机构管理', name: '机构管理',
component: () => component: () =>
import('@/pages/system/view/organization/orgmanagement/Org.vue'), import('@/pages/system/view/organization/orgmanagement/Org.vue'),
...@@ -103,23 +96,22 @@ const options = { ...@@ -103,23 +96,22 @@ const options = {
], ],
}, },
{ {
path: 'role_management', path: 'role',
name: '角色管理', name: '角色管理',
component: () => import('@/pages/system/view/role'), component: () => import('@/pages/system/view/role'),
}, },
{ {
path: 'parameter_management', path: 'parameter',
name: '参数管理', name: '参数管理',
component: BlankTemplateView,
children: [ children: [
{ {
path: 'business_management', path: 'business',
name: '业务参数', name: '业务参数',
component: () => component: () =>
import('@/pages/system/view/parameter/business/index.vue'), import('@/pages/system/view/parameter/business/index.vue'),
}, },
{ {
path: 'operation_management', path: 'operation',
name: '运维参数', name: '运维参数',
component: () => component: () =>
import('@/pages/system/view/parameter/operation/index.vue'), import('@/pages/system/view/parameter/operation/index.vue'),
...@@ -127,37 +119,41 @@ const options = { ...@@ -127,37 +119,41 @@ const options = {
], ],
}, },
{ {
path: 'log_management', path: 'log',
name: '日志管理', name: '日志管理',
component: BlankTemplateView,
children: [ children: [
{ {
path: 'login_log', path: 'login',
name: '登录日志', name: '登录日志',
component: () => import('@/pages/system/view/log/login_log/index.vue'), component: () => import('@/pages/system/view/log/login_log'),
}, },
{ {
path: 'operation_log', path: 'operation',
name: '操作日志', name: '操作日志',
component: () => import('@/pages/system/view/log/operation/index.vue'), component: () => import('@/pages/system/view/log/operation/index.vue'),
}, },
], ],
}, },
{ {
path: 'task_management', path: 'task',
name: '任务管理', name: '任务管理',
component: () => import('@/pages/system/view/task/index.vue'), component: () => import('@/pages/system/view/task/index.vue'),
}, },
], ],
}, },
{ {
path: 'user_center', path: 'user',
name: '个人中心', name: '个人中心',
meta: { icon: 'user' }, meta: { icon: 'user' },
component: () => import('@/pages/user/index.vue'), component: () => import('@/pages/user/index.vue'),
}, },
], ],
}, },
{
path: '*',
name: '404',
component: () => import('@/pages/frame/view/exception/404'),
},
], ],
}; };
......
import syncConfig from './config'; import syncConfig from './config';
import asyncConfig from './async/config.async';
import { formatRoutes } from '../utils/routerUtil'; import { formatRoutes } from '../utils/routerUtil';
// 不需要登录拦截的路由配置 // 不需要登录拦截的路由配置
const loginIgnore = { const loginIgnore = {
names: ['404', '403'], //根据路由名称匹配 names: ['404', '403'], //根据路由名称匹配
paths: ['/login'], //根据路由fullPath匹配 paths: ['/login'], //根据路由fullPath匹配
/** /**
* 判断路由是否包含在该配置中 * 判断路由是否包含在该配置中
* @param route vue-router 的 route 对象 * @param route vue-router 的 route 对象
* @returns {boolean} * @returns {boolean}
*/ */
includes(route) { includes(route) {
return this.names.includes(route.name) || this.paths.includes(route.path) return this.names.includes(route.name) || this.paths.includes(route.path);
} },
}; };
/** /**
...@@ -21,11 +20,10 @@ const loginIgnore = { ...@@ -21,11 +20,10 @@ const loginIgnore = {
* @param isAsync 是否异步路由模式 * @param isAsync 是否异步路由模式
* @returns {options.routes} * @returns {options.routes}
*/ */
function initRouter(isAsync) { function initRouter() {
const options = isAsync ? asyncConfig : syncConfig; const options = syncConfig;
formatRoutes(options.routes); formatRoutes(options.routes);
return options; return options;
} }
export { loginIgnore, initRouter };
export {loginIgnore , initRouter}
import routerMap from "@/router/async/router.map"; import { mergeI18nFromRoutes } from '@/utils/i18nUtil';
import { mergeI18nFromRoutes } from "@/utils/i18nUtil"; import deepMerge from 'deepmerge';
import Router from "vue-router";
import deepMerge from "deepmerge";
import basicOptions from "@/router/async/config.async";
//应用配置 //应用配置
let appOptions = { let appOptions = {
...@@ -29,20 +26,20 @@ function setAppOptions(options) { ...@@ -29,20 +26,20 @@ function setAppOptions(options) {
*/ */
function parseRoutes(routesConfig, routerMap) { function parseRoutes(routesConfig, routerMap) {
let routes = []; let routes = [];
routesConfig.forEach((item) => { routesConfig.forEach(item => {
// 获取注册在 routerMap 中的 router,初始化 routeCfg // 获取注册在 routerMap 中的 router,初始化 routeCfg
let router = undefined, let router = undefined,
routeCfg = {}; routeCfg = {};
if (typeof item === "string") { if (typeof item === 'string') {
router = routerMap[item]; router = routerMap[item];
routeCfg = { path: (router && router.path) || item, router: item }; routeCfg = { path: (router && router.path) || item, router: item };
} else if (typeof item === "object") { } else if (typeof item === 'object') {
router = routerMap[item.router]; router = routerMap[item.router];
routeCfg = item; routeCfg = item;
} }
if (!router) { if (!router) {
console.warn(`can't find register for router ${routeCfg.router}, please register it in advance.`); console.warn(`can't find register for router ${routeCfg.router}, please register it in advance.`);
router = typeof item === "string" ? { path: item, name: item } : item; router = typeof item === 'string' ? { path: item, name: item } : item;
} }
// 从 router 和 routeCfg 解析路由 // 从 router 和 routeCfg 解析路由
const route = { const route = {
...@@ -52,7 +49,11 @@ function parseRoutes(routesConfig, routerMap) { ...@@ -52,7 +49,11 @@ function parseRoutes(routesConfig, routerMap) {
redirect: routeCfg.redirect || router.redirect, redirect: routeCfg.redirect || router.redirect,
meta: { meta: {
authority: authority:
routeCfg.authority || router.authority || routeCfg.meta?.authority || router.meta?.authority || "*", routeCfg.authority ||
router.authority ||
routeCfg.meta?.authority ||
router.meta?.authority ||
'*',
icon: routeCfg.icon || router.icon || routeCfg.meta?.icon || router.meta?.icon, icon: routeCfg.icon || router.icon || routeCfg.meta?.icon || router.meta?.icon,
page: routeCfg.page || router.page || routeCfg.meta?.page || router.meta?.page, page: routeCfg.page || router.page || routeCfg.meta?.page || router.meta?.page,
link: routeCfg.link || router.link || routeCfg.meta?.link || router.meta?.link, link: routeCfg.link || router.link || routeCfg.meta?.link || router.meta?.link,
...@@ -74,51 +75,26 @@ function parseRoutes(routesConfig, routerMap) { ...@@ -74,51 +75,26 @@ function parseRoutes(routesConfig, routerMap) {
* @param routesConfig {RouteConfig[]} 路由配置 * @param routesConfig {RouteConfig[]} 路由配置
*/ */
function loadRoutes(routesConfig) { function loadRoutes(routesConfig) {
// 应用配置 // 应用配置
const { router, store, i18n } = appOptions; const { router, store, i18n } = appOptions;
// 如果 routesConfig 有值,则更新到本地,否则从本地获取 // 如果 routesConfig 有值,则更新到本地,否则从本地获取
if (routesConfig) { if (routesConfig) {
store.commit("accountModule/setRoutesConfig", routesConfig); store.commit('accountModule/setRoutesConfig', routesConfig);
} else { } else {
routesConfig = store.getters["accountModule/routesConfig"]; routesConfig = store.getters['accountModule/routesConfig'];
}
// 如果开启了异步路由,则加载异步路由配置
const asyncRoutes = store.state.settingModule.asyncRoutes;
if (asyncRoutes) {
if (routesConfig && routesConfig.length > 0) {
const routes = parseRoutes(routesConfig, routerMap);
const finalRoutes = mergeRoutes(basicOptions.routes, routes);
formatRoutes(finalRoutes);
router.options = { ...router.options, routes: finalRoutes };
router.matcher = new Router({ ...router.options, routes: [] }).matcher;
router.addRoutes(finalRoutes);
}
} }
// 提取路由国际化数据 // 提取路由国际化数据
mergeI18nFromRoutes(i18n, router.options.routes); mergeI18nFromRoutes(i18n, router.options.routes);
// 初始化Admin后台菜单数据 // 初始化Admin后台菜单数据
const rootRoute = router.options.routes.find((item) => item.path === "/"); const rootRoute = router.options.routes.find(item => item.path === '/');
const menuRoutes = rootRoute && rootRoute.children; const menuRoutes = rootRoute && rootRoute.children;
if (menuRoutes) { if (menuRoutes) {
store.commit("settingModule/setMenuData", menuRoutes); store.commit('settingModule/setMenuData', menuRoutes);
} }
} }
/**
* 合并路由
* @param target {Route[]}
* @param source {Route[]}
* @returns {Route[]}
*/
function mergeRoutes(target, source) {
const routesMap = {};
target.forEach((item) => (routesMap[item.path] = item));
source.forEach((item) => (routesMap[item.path] = item));
return Object.values(routesMap);
}
/** /**
* 深度合并路由 * 深度合并路由
* @param target {Route[]} * @param target {Route[]}
...@@ -127,9 +103,9 @@ function mergeRoutes(target, source) { ...@@ -127,9 +103,9 @@ function mergeRoutes(target, source) {
*/ */
function deepMergeRoutes(target, source) { function deepMergeRoutes(target, source) {
// 映射路由数组 // 映射路由数组
const mapRoutes = (routes) => { const mapRoutes = routes => {
const routesMap = {}; const routesMap = {};
routes.forEach((item) => { routes.forEach(item => {
routesMap[item.path] = { routesMap[item.path] = {
...item, ...item,
children: item.children ? mapRoutes(item.children) : undefined, children: item.children ? mapRoutes(item.children) : undefined,
...@@ -144,8 +120,8 @@ function deepMergeRoutes(target, source) { ...@@ -144,8 +120,8 @@ function deepMergeRoutes(target, source) {
const merge = deepMerge(tarMap, srcMap); const merge = deepMerge(tarMap, srcMap);
// 转换为 routes 数组 // 转换为 routes 数组
const parseRoutesMap = (routesMap) => { const parseRoutesMap = routesMap => {
return Object.values(routesMap).map((item) => { return Object.values(routesMap).map(item => {
if (item.children) { if (item.children) {
item.children = parseRoutesMap(item.children); item.children = parseRoutesMap(item.children);
} else { } else {
...@@ -162,10 +138,10 @@ function deepMergeRoutes(target, source) { ...@@ -162,10 +138,10 @@ function deepMergeRoutes(target, source) {
* @param routes 路由配置 * @param routes 路由配置
*/ */
function formatRoutes(routes) { function formatRoutes(routes) {
routes.forEach((route) => { routes.forEach(route => {
const { path } = route; const { path } = route;
if (!path.startsWith("/") && path !== "*") { if (!path.startsWith('/') && path !== '*') {
route.path = "/" + path; route.path = '/' + path;
} }
}); });
formatAuthority(routes); formatAuthority(routes);
...@@ -177,19 +153,19 @@ function formatRoutes(routes) { ...@@ -177,19 +153,19 @@ function formatRoutes(routes) {
* @param pAuthorities 父级路由权限配置集合 * @param pAuthorities 父级路由权限配置集合
*/ */
function formatAuthority(routes, pAuthorities = []) { function formatAuthority(routes, pAuthorities = []) {
routes.forEach((route) => { routes.forEach(route => {
const meta = route.meta; const meta = route.meta;
const defaultAuthority = pAuthorities[pAuthorities.length - 1] || { permission: "*" }; const defaultAuthority = pAuthorities[pAuthorities.length - 1] || { permission: '*' };
if (meta) { if (meta) {
let authority = {}; let authority = {};
if (!meta.authority) { if (!meta.authority) {
authority = defaultAuthority; authority = defaultAuthority;
} else if (typeof meta.authority === "string") { } else if (typeof meta.authority === 'string') {
authority.permission = meta.authority; authority.permission = meta.authority;
} else if (typeof meta.authority === "object") { } else if (typeof meta.authority === 'object') {
authority = meta.authority; authority = meta.authority;
const { role } = authority; const { role } = authority;
if (typeof role === "string") { if (typeof role === 'string') {
authority.role = [role]; authority.role = [role];
} }
if (!authority.permission && !authority.role) { if (!authority.permission && !authority.role) {
...@@ -214,9 +190,9 @@ function formatAuthority(routes, pAuthorities = []) { ...@@ -214,9 +190,9 @@ function formatAuthority(routes, pAuthorities = []) {
* @returns {*} * @returns {*}
*/ */
function getI18nKey(path) { function getI18nKey(path) {
const keys = path.split("/").filter((item) => !item.startsWith(":") && item != ""); const keys = path.split('/').filter(item => !item.startsWith(':') && item != '');
keys.push("name"); keys.push('name');
return keys.join("."); return keys.join('.');
} }
/** /**
...@@ -227,13 +203,13 @@ function getI18nKey(path) { ...@@ -227,13 +203,13 @@ function getI18nKey(path) {
function loadGuards(guards, options) { function loadGuards(guards, options) {
const { beforeEach, afterEach } = guards; const { beforeEach, afterEach } = guards;
const { router } = options; const { router } = options;
beforeEach.forEach((guard) => { beforeEach.forEach(guard => {
if (guard && typeof guard === "function") { if (guard && typeof guard === 'function') {
router.beforeEach((to, from, next) => guard(to, from, next, options)); router.beforeEach((to, from, next) => guard(to, from, next, options));
} }
}); });
afterEach.forEach((guard) => { afterEach.forEach(guard => {
if (guard && typeof guard === "function") { if (guard && typeof guard === 'function') {
router.afterEach((to, from) => guard(to, from, options)); router.afterEach((to, from) => guard(to, from, options));
} }
}); });
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment