init
This commit is contained in:
83
src/router/frontEnd.js
Normal file
83
src/router/frontEnd.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import router from "./index.js";
|
||||
import { staticRoutes, asyncRoutes } from "@/router/routes.js";
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
import { useUser } from "@/store/user.js";
|
||||
|
||||
/**
|
||||
* @description: 初始化路由
|
||||
* @param {Array} roles: 用户权限
|
||||
*/
|
||||
export async function initFrontEndRoutes() {
|
||||
const storeUser = useUser();
|
||||
|
||||
// 触发初始化用户信息
|
||||
await storeUser.setUserInfo();
|
||||
const roles = [storeUser.userInfo.userType]; // 权限
|
||||
// if (roles?.length <= 0) {}; 无权限时的处理
|
||||
|
||||
let addRoutes;
|
||||
if (roles.includes("MG")) {
|
||||
// 管理员权限包含所有的路由权限
|
||||
addRoutes = asyncRoutes || [];
|
||||
} else {
|
||||
addRoutes = filterAsyncRoutes(asyncRoutes, roles);
|
||||
}
|
||||
setAddRoute(addRoutes);
|
||||
const storeRoutes = useRoutes();
|
||||
storeRoutes.setRoutesList([...staticRoutes[0].children, ...addRoutes]);
|
||||
storeRoutes.setAllRoutes(router.getRoutes());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 通过递归过滤异步路由表
|
||||
* @param {Array} routes: 异步路由
|
||||
* @param {Array} roles: 用户的所有权限
|
||||
* @return {Array} 符合权限的异步路由
|
||||
*/
|
||||
function filterAsyncRoutes(routes, roles) {
|
||||
const res = [];
|
||||
routes.forEach((route) => {
|
||||
if (hasPermission(route, roles)) {
|
||||
if (route.children) {
|
||||
route.children = filterAsyncRoutes(route.children, roles);
|
||||
}
|
||||
res.push(route);
|
||||
}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* @description: 判断路由 `meta.roles` 中是否包含当前登录用户权限字段
|
||||
* @param {Array} route: 路由
|
||||
* @param {Array} roles: 用户的所有权限
|
||||
* @return {Boolean} 是否有权限
|
||||
*/
|
||||
function hasPermission(route, roles) {
|
||||
if (route.meta && route.meta.roles) {
|
||||
return roles.some((role) => route.meta.roles.includes(role));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 添加动态路由
|
||||
* @param {Array} addRoutes: 要添加的路由列表
|
||||
*/
|
||||
function setAddRoute(addRoutes) {
|
||||
addRoutes.forEach((route) => {
|
||||
// 添加嵌套路由
|
||||
router.addRoute("/", route);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 重置路由
|
||||
* @param {Array} roles: 用户权限
|
||||
*/
|
||||
export function resetFrontEndRoute(roles) {
|
||||
// 获取用户可以访问的权限路由后
|
||||
const routes = filterAsyncRoutes(asyncRoutes, roles);
|
||||
// 通过重新添加路由来覆盖
|
||||
setAddRoute(routes);
|
||||
}
|
||||
48
src/router/index.js
Normal file
48
src/router/index.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { notFoundAndNoPower, fullScreenRouting, staticRoutes } from "./routes.js";
|
||||
import { initFrontEndRoutes } from "./frontEnd.js";
|
||||
import _hook from "@/hooks/index.js";
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
import NProgress from "nprogress";
|
||||
import "nprogress/nprogress.css";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [...notFoundAndNoPower, ...fullScreenRouting, ...staticRoutes],
|
||||
});
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start();
|
||||
const token = _hook.useLocalStorage.get("token");
|
||||
if (to.path === "/login" && !token) {
|
||||
next();
|
||||
NProgress.done();
|
||||
} else {
|
||||
if (!token) {
|
||||
next("/login");
|
||||
_hook.useLocalStorage.clear();
|
||||
} else if (token && to.path === "/login") {
|
||||
next("/home");
|
||||
NProgress.done();
|
||||
} else {
|
||||
const storeRoutes = useRoutes();
|
||||
if (storeRoutes.routesList.length === 0) {
|
||||
await initFrontEndRoutes(); // 初始化前端路由
|
||||
storeRoutes.setNavbar("/home"); // 每次初始化时都添加首页
|
||||
next({ path: to.path, query: to.query });
|
||||
NProgress.done();
|
||||
} else {
|
||||
storeRoutes.setNavbar(to.path);
|
||||
next();
|
||||
NProgress.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
router.afterEach((to, from, next) => {
|
||||
NProgress.done();
|
||||
});
|
||||
|
||||
export default router;
|
||||
524
src/router/routes.js
Normal file
524
src/router/routes.js
Normal file
@@ -0,0 +1,524 @@
|
||||
import bridge from "@/views/layout/bridge.vue"; // 多级路由
|
||||
import layout from "@/views/layout/layout.vue" // 只需要展示一页
|
||||
|
||||
/**
|
||||
* 路由参数说明
|
||||
*
|
||||
* path: !!! 路由 path 路径需完整,因为菜单中所有路由跳转均使用 path 跳转。
|
||||
* 如:
|
||||
* 父路由 path:'/home'
|
||||
* 子路由 path:'/home/page'
|
||||
* 孙路由 path:'/home/page/index'
|
||||
* 首页 path 必须为 '/home'
|
||||
* path 路径作为菜单唯一标识不可重复, 且在没有配置 meta.title 时使用 path 作为标题.
|
||||
* meta: {
|
||||
* title: 菜单的标题 ( 缺少 title 时会使用路由的 path 作为标题)
|
||||
* isHide: 是否隐藏此路由
|
||||
* isKeepAlive: 是否缓存路由
|
||||
* roles: 当前路由权限标识,取角色管理。控制路由显示、隐藏。
|
||||
* icon: 图标 elementUI
|
||||
* activeMenu: 需要保持高亮的菜单
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* 定义404、401界面
|
||||
*/
|
||||
export const notFoundAndNoPower = [
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
name: "notFound",
|
||||
component: () => import("@/views/error/404.vue"),
|
||||
meta: {
|
||||
title: "404",
|
||||
isHide: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/401",
|
||||
name: "noPower",
|
||||
component: () => import("@/views/error/401.vue"),
|
||||
meta: {
|
||||
title: "401",
|
||||
isHide: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 全屏路由页面
|
||||
* 此处的页面会占满浏览器的整个屏幕
|
||||
*/
|
||||
export const fullScreenRouting = [
|
||||
{
|
||||
path: "/login",
|
||||
name: "login",
|
||||
component: () => import("@/views/login/login.vue"),
|
||||
meta: {
|
||||
title: "登录",
|
||||
isHide: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 静态路由
|
||||
* 没有权限要求的基本页面
|
||||
* 所有角色都可以访问
|
||||
*/
|
||||
export const staticRoutes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "/",
|
||||
component: layout,
|
||||
redirect: "/home",
|
||||
meta: {
|
||||
isHide: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/home",
|
||||
component: () => import("@/views/home.vue"),
|
||||
meta: {
|
||||
title: "首页",
|
||||
icon: "House",
|
||||
// isKeepAlive: true,
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: "/makes",
|
||||
// component: bridge,
|
||||
// redirect: "/makes/svgIcon",
|
||||
// meta: {
|
||||
// title: "组件封装",
|
||||
// icon: "Edit",
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "/makes/svgIcon",
|
||||
// component: () => import("@/views/makes/svgIcon.vue"),
|
||||
// meta: {
|
||||
// title: "SvgIcon",
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: "/tools",
|
||||
// component: bridge,
|
||||
// redirect: "/tools/editor",
|
||||
// meta: {
|
||||
// title: "工具",
|
||||
// icon: "Flag",
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "/tools/editor",
|
||||
// component: () => import("@/views/tools/editor.vue"),
|
||||
// meta: {
|
||||
// title: "编辑器",
|
||||
// icon: "Edit",
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: "/other",
|
||||
// component: bridge,
|
||||
// redirect: "/other/watermark",
|
||||
// meta: {
|
||||
// title: "其他",
|
||||
// icon: "Box",
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "/other/watermark",
|
||||
// component: () => import("@/views/other/watermark.vue"),
|
||||
// meta: {
|
||||
// title: "水印",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/other/resize",
|
||||
// component: () => import("@/views/other/resize.vue"),
|
||||
// meta: {
|
||||
// title: "监控元素尺寸变化",
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 异步路由
|
||||
* 需要根据用户角色动态加载的路由
|
||||
*/
|
||||
export const asyncRoutes = [
|
||||
// {
|
||||
// path: "/demo",
|
||||
// component: bridge,
|
||||
// redirect: "/demo/demo1/demo11",
|
||||
// meta: {
|
||||
// title: "权限路由",
|
||||
// icon: "Edit",
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "demo1",
|
||||
// component: bridge,
|
||||
// meta: {
|
||||
// title: "用户1路由-1",
|
||||
// icon: "Edit",
|
||||
// roles: ["yonghu1"],
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "/demo/demo1/demo11",
|
||||
// component: () => import("@/views/demo/demo11.vue"),
|
||||
// name: "demo11",
|
||||
// meta: {
|
||||
// title: "用户1路由-11",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/demo/demo1/demo12",
|
||||
// component: () => import("@/views/demo/demo12.vue"),
|
||||
// name: "demo12",
|
||||
// meta: {
|
||||
// title: "用户1路由-12",
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "/demo/demo1/demo121",
|
||||
// component: () => import("@/views/demo/demo121.vue"),
|
||||
// name: "demo121",
|
||||
// meta: {
|
||||
// title: "用户1路由-121",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/demo/demo1/demo122",
|
||||
// component: () => import("@/views/demo/demo122.vue"),
|
||||
// name: "demo122",
|
||||
// meta: {
|
||||
// title: "用户1路由-122",
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: "/demo/demo1/demo13",
|
||||
// component: () => import("@/views/demo/demo13.vue"),
|
||||
// name: "demo13",
|
||||
// meta: {
|
||||
// title: "用户1路由-13",
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: "/demo/demo2",
|
||||
// component: bridge,
|
||||
// meta: {
|
||||
// title: "用户2路由-2",
|
||||
// icon: "Edit",
|
||||
// roles: ["yonghu2"],
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: "/demo/demo2/demo21",
|
||||
// component: () => import("@/views/demo/demo21.vue"),
|
||||
// meta: {
|
||||
// title: "用户2路由-21",
|
||||
// icon: "Edit",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/demo/demo2/demo22",
|
||||
// component: () => import("@/views/demo/demo22.vue"),
|
||||
// meta: {
|
||||
// title: "用户2路由-22",
|
||||
// icon: "Edit",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/demo/demo2/demo23",
|
||||
// component: () => import("@/views/demo/demo23.vue"),
|
||||
// meta: {
|
||||
// title: "用户2路由-23",
|
||||
// icon: "Edit",
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: '/system',
|
||||
// component: bridge,
|
||||
// redirect: '/system/menu_manage',
|
||||
// meta: {
|
||||
// title: '系统管理',
|
||||
// icon: 'Setting',
|
||||
// roles: ['FO']
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: '/system/menu_manage',
|
||||
// component: () => import('@/views/system/menuMange.vue'),
|
||||
// meta: {
|
||||
// title: '菜单管理',
|
||||
// icon: 'Stopwatch'
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
path: '/organization',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '大机构管理',
|
||||
roles: ['MG'],
|
||||
isHide: true
|
||||
},
|
||||
redirect: '/organization/big_organization',
|
||||
children: [
|
||||
{
|
||||
path: '/organization/big_organization',
|
||||
component: () => import('@/views/organization/big_organization.vue'),
|
||||
meta: {
|
||||
title: '大机构',
|
||||
icon: 'Tickets'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/mini_organization_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '小机构管理',
|
||||
roles: ['FO'],
|
||||
isHide: true
|
||||
},
|
||||
redirect: '/mini_organization_manage/mini_organization',
|
||||
children: [
|
||||
{
|
||||
path: '/mini_organization/mini_organization',
|
||||
component: () => import('@/views/organization/mini_organization.vue'),
|
||||
meta: {
|
||||
title: '小机构',
|
||||
icon: 'SetUp'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/agent_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '大代理管理',
|
||||
roles: ['FO', 'SO'],
|
||||
isHide: true
|
||||
},
|
||||
redirect: '/agent_manage/agent_list',
|
||||
children: [
|
||||
{
|
||||
path: '/agent_manage/agent_list',
|
||||
component: () => import('@/views/organization/agent_list.vue'),
|
||||
meta: {
|
||||
title: '大代理',
|
||||
icon: 'Discount'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/promotion_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '代理',
|
||||
icon: 'Connection',
|
||||
},
|
||||
redirect: '/promotion_manage/one_promotion_list',
|
||||
children: [
|
||||
{
|
||||
path: '/promotion_manage/one_promotion_list',
|
||||
component: () => import('@/views/organization/one_promotion_list.vue'),
|
||||
meta: {
|
||||
title: '一级代理',
|
||||
icon: 'User',
|
||||
roles: ['FO', 'SO', 'AG']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/promotion_manage/two_promotion_list',
|
||||
component: () => import('@/views/organization/two_promotion_list.vue'),
|
||||
meta: {
|
||||
title: '二级代理',
|
||||
icon: 'User',
|
||||
roles: ['FO', 'SO', 'AG', 'FB']
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/shop_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '商家管理',
|
||||
roles: ['FO', 'SO', 'AG', 'FB', 'SB'],
|
||||
icon: 'Handbag'
|
||||
},
|
||||
redirect: '/shop_manage/shop_list',
|
||||
children: [
|
||||
{
|
||||
path: '/shop_manage/shop_list',
|
||||
name: 'shop_list',
|
||||
component: () => import('@/views/organization/shop_list.vue'),
|
||||
meta: {
|
||||
title: '商家列表',
|
||||
icon: 'Tickets'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/shop_manage/shop_detail',
|
||||
name: 'shop_detail',
|
||||
component: () => import('@/views/organization/shop_detail.vue'),
|
||||
meta: {
|
||||
title: '详情',
|
||||
isHide: true,
|
||||
activeMenu: '/shop_manage/shop_list'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/shop_manage/maker_apply',
|
||||
component: () => import('@/views/organization/maker_apply.vue'),
|
||||
meta: {
|
||||
title: '创客申请',
|
||||
icon: 'User'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/withdraw_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '提现管理',
|
||||
roles: ['FO', 'SO'],
|
||||
isHide: true
|
||||
},
|
||||
redirect: '/withdraw_manage/withdraw_list',
|
||||
children: [
|
||||
{
|
||||
path: '/withdraw_manage/withdraw_list',
|
||||
component: () => import('@/views/withdraw/withdraw_list.vue'),
|
||||
meta: {
|
||||
title: '提现申请',
|
||||
icon: 'CreditCard'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/device_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '设备管理',
|
||||
isHide: true
|
||||
},
|
||||
redirect: '/device_manage/device_list',
|
||||
children: [
|
||||
{
|
||||
path: '/device_manage/device_list',
|
||||
component: () => import('@/views/device/device_list.vue'),
|
||||
meta: {
|
||||
title: '设备列表',
|
||||
icon: 'TakeawayBox'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/total_earnings',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '累计收益管理',
|
||||
isHide: true
|
||||
},
|
||||
redirect: '/total_earnings/total_earnings_list',
|
||||
children: [
|
||||
{
|
||||
path: '/total_earnings/total_earnings_list',
|
||||
component: () => import('@/views/total_earnings/total_earnings_list.vue'),
|
||||
meta: {
|
||||
title: '累计收益',
|
||||
icon: 'Coin'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/promotion',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '推广图片管理',
|
||||
isHide: true,
|
||||
roles: ['MG']
|
||||
},
|
||||
redirect: '/promotion/promotion_list',
|
||||
children: [
|
||||
{
|
||||
path: '/promotion/promotion_list',
|
||||
component: () => import('@/views/promotion/promotion_list.vue'),
|
||||
meta: {
|
||||
title: '推广图片',
|
||||
icon: 'PictureRounded'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/app_manage',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: 'APP管理',
|
||||
icon: 'Iphone',
|
||||
roles: ['MG']
|
||||
},
|
||||
redirect: '/app_manage/menu_list',
|
||||
children: [
|
||||
{
|
||||
path: '/app_manage/menu_list',
|
||||
component: () => import('@/views/app_manage/menu_list.vue'),
|
||||
meta: {
|
||||
title: '菜单管理',
|
||||
icon: 'Tickets'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/setting',
|
||||
component: layout,
|
||||
meta: {
|
||||
title: '系统设置',
|
||||
icon: 'Setting',
|
||||
roles: ['MG']
|
||||
},
|
||||
redirect: '/setting/appid_manage',
|
||||
children: [
|
||||
{
|
||||
path: '/setting/appid_manage',
|
||||
component: () => import('@/views/setting/appid_manage.vue'),
|
||||
meta: {
|
||||
title: 'Appid管理',
|
||||
icon: 'Tickets'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
Reference in New Issue
Block a user