mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	feat: 模拟后台返回不同角色路由生成动态路由
This commit is contained in:
		
							parent
							
								
									b554356ba1
								
							
						
					
					
						commit
						07aff1fcfc
					
				
							
								
								
									
										52
									
								
								mock/asyncRoutes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								mock/asyncRoutes.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					// 根据角色动态生成路由
 | 
				
			||||||
 | 
					import { MockMethod } from "vite-plugin-mock";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// http://mockjs.com/examples.html#Object
 | 
				
			||||||
 | 
					const systemRouter = {
 | 
				
			||||||
 | 
					  path: "/system",
 | 
				
			||||||
 | 
					  name: "system",
 | 
				
			||||||
 | 
					  // component: Layout,
 | 
				
			||||||
 | 
					  redirect: "/system/user",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    icon: "el-icon-setting",
 | 
				
			||||||
 | 
					    title: "message.hssysManagement",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: true,
 | 
				
			||||||
 | 
					    rank: 6,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  children: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/system/user",
 | 
				
			||||||
 | 
					      name: "user",
 | 
				
			||||||
 | 
					      // component: () => import("/@/views/system/user/index.vue"),
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: "message.hsBaseinfo",
 | 
				
			||||||
 | 
					        showLink: false,
 | 
				
			||||||
 | 
					        savedPosition: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/system/dict",
 | 
				
			||||||
 | 
					      name: "dict",
 | 
				
			||||||
 | 
					      // component: () => import("/@/views/system/dict/index.vue"),
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: "message.hsDict",
 | 
				
			||||||
 | 
					        showLink: false,
 | 
				
			||||||
 | 
					        savedPosition: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    url: "/getAsyncRoutes",
 | 
				
			||||||
 | 
					    method: "get",
 | 
				
			||||||
 | 
					    response: () => {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        code: 0,
 | 
				
			||||||
 | 
					        info: systemRouter,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					] as MockMethod[];
 | 
				
			||||||
							
								
								
									
										5
									
								
								src/api/routes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/api/routes.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					import { http } from "../utils/http";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getAsyncRoutes = (data?: object): any => {
 | 
				
			||||||
 | 
					  return http.request("get", "/getAsyncRoutes", data);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -130,7 +130,7 @@ export default defineComponent({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const noSecret = (): void => {
 | 
					    const noSecret = (): void => {
 | 
				
			||||||
      storageSession.setItem("info", {
 | 
					      storageSession.setItem("info", {
 | 
				
			||||||
        username: "测试用户",
 | 
					        username: "admin",
 | 
				
			||||||
        accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
 | 
					        accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      router.push("/");
 | 
					      router.push("/");
 | 
				
			||||||
 | 
				
			|||||||
@ -198,14 +198,14 @@ export default defineComponent({
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    .el-dropdown-link {
 | 
					    .el-dropdown-link {
 | 
				
			||||||
      width: 80px;
 | 
					      width: 70px;
 | 
				
			||||||
      display: flex;
 | 
					      display: flex;
 | 
				
			||||||
      align-items: center;
 | 
					      align-items: center;
 | 
				
			||||||
      justify-content: space-around;
 | 
					      justify-content: space-around;
 | 
				
			||||||
      margin-right: 10px;
 | 
					      margin-right: 10px;
 | 
				
			||||||
      cursor: pointer;
 | 
					      cursor: pointer;
 | 
				
			||||||
      p {
 | 
					      p {
 | 
				
			||||||
        font-size: 13px;
 | 
					        font-size: 14px;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      img {
 | 
					      img {
 | 
				
			||||||
        width: 22px;
 | 
					        width: 22px;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.ts
									
									
									
									
									
								
							@ -49,12 +49,10 @@ export const getServerConfig = async (): Promise<any> => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
getServerConfig().then(() => {
 | 
					getServerConfig().then(async () => {
 | 
				
			||||||
  app
 | 
					  app.use(router).use(store).use(useElementPlus).use(useTable).use(usI18n);
 | 
				
			||||||
    .use(router)
 | 
					
 | 
				
			||||||
    .use(store)
 | 
					  await router.isReady();
 | 
				
			||||||
    .use(useElementPlus)
 | 
					
 | 
				
			||||||
    .use(useTable)
 | 
					  app.mount("#app");
 | 
				
			||||||
    .use(usI18n)
 | 
					 | 
				
			||||||
    .mount("#app");
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,10 @@
 | 
				
			|||||||
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
 | 
					import { createProdMockServer } from "vite-plugin-mock/es/createProdMockServer";
 | 
				
			||||||
import mapMock from '../mock/map'
 | 
					import mapMock from "../mock/map";
 | 
				
			||||||
import echartsMock from '../mock/echarts'
 | 
					import echartsMock from "../mock/echarts";
 | 
				
			||||||
 | 
					import asyncRoutesMock from "../mock/asyncRoutes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const mockModules = [...mapMock, ...echartsMock]
 | 
					export const mockModules = [...mapMock, ...echartsMock, ...asyncRoutesMock];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setupProdMockServer() {
 | 
					export function setupProdMockServer() {
 | 
				
			||||||
  createProdMockServer(mockModules)
 | 
					  createProdMockServer(mockModules);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -38,6 +38,9 @@ export const menusConfig = {
 | 
				
			|||||||
      "hsmenu1-2-2": "菜单1-2-2",
 | 
					      "hsmenu1-2-2": "菜单1-2-2",
 | 
				
			||||||
      "hsmenu1-3": "菜单1-3",
 | 
					      "hsmenu1-3": "菜单1-3",
 | 
				
			||||||
      hsmenu2: "菜单2",
 | 
					      hsmenu2: "菜单2",
 | 
				
			||||||
 | 
					      permission: "权限管理",
 | 
				
			||||||
 | 
					      permissionPage: "页面权限",
 | 
				
			||||||
 | 
					      permissionButton: "按钮权限",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  en: {
 | 
					  en: {
 | 
				
			||||||
@ -70,6 +73,9 @@ export const menusConfig = {
 | 
				
			|||||||
      "hsmenu1-2-2": "Menu1-2-2",
 | 
					      "hsmenu1-2-2": "Menu1-2-2",
 | 
				
			||||||
      "hsmenu1-3": "Menu1-3",
 | 
					      "hsmenu1-3": "Menu1-3",
 | 
				
			||||||
      hsmenu2: "Menu2",
 | 
					      hsmenu2: "Menu2",
 | 
				
			||||||
 | 
					      permission: "Permission Manage",
 | 
				
			||||||
 | 
					      permissionPage: "Page Permission",
 | 
				
			||||||
 | 
					      permissionButton: "Button Permission",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -5,27 +5,53 @@ import flowChartRouter from "./modules/flowchart";
 | 
				
			|||||||
import editorRouter from "./modules/editor";
 | 
					import editorRouter from "./modules/editor";
 | 
				
			||||||
import componentsRouter from "./modules/components";
 | 
					import componentsRouter from "./modules/components";
 | 
				
			||||||
import nestedRouter from "./modules/nested";
 | 
					import nestedRouter from "./modules/nested";
 | 
				
			||||||
import systemRouter from "./modules/system";
 | 
					 | 
				
			||||||
import errorRouter from "./modules/error";
 | 
					import errorRouter from "./modules/error";
 | 
				
			||||||
import remainingRouter from "./modules/remaining";
 | 
					import permissionRouter from "./modules/permission";
 | 
				
			||||||
 | 
					import remainingRouter from "./modules/remaining"; //静态路由
 | 
				
			||||||
 | 
					import Layout from "/@/layout/index.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { getAsyncRoutes } from "/@/api/routes";
 | 
				
			||||||
import { storageSession } from "../utils/storage";
 | 
					import { storageSession } from "../utils/storage";
 | 
				
			||||||
import { i18n } from "/@/plugins/i18n/index";
 | 
					import { i18n } from "/@/plugins/i18n/index";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const routes: Array<RouteRecordRaw> = [
 | 
					const constantRoutes: Array<RouteRecordRaw> = [
 | 
				
			||||||
  homeRouter,
 | 
					  homeRouter,
 | 
				
			||||||
  flowChartRouter,
 | 
					  flowChartRouter,
 | 
				
			||||||
  editorRouter,
 | 
					  editorRouter,
 | 
				
			||||||
  componentsRouter,
 | 
					  componentsRouter,
 | 
				
			||||||
  nestedRouter,
 | 
					  nestedRouter,
 | 
				
			||||||
  systemRouter,
 | 
					  permissionRouter,
 | 
				
			||||||
  errorRouter,
 | 
					  errorRouter,
 | 
				
			||||||
  ...remainingRouter,
 | 
					 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 过滤后端传来的动态路由重新生成规范路由
 | 
				
			||||||
 | 
					const addAsyncRoutes = (arrRoutes: Array<string>) => {
 | 
				
			||||||
 | 
					  if (!arrRoutes || !arrRoutes.length) return;
 | 
				
			||||||
 | 
					  arrRoutes.forEach((v: any) => {
 | 
				
			||||||
 | 
					    if (v.redirect) {
 | 
				
			||||||
 | 
					      v.component = Layout;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      // https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
 | 
				
			||||||
 | 
					      v.component = () =>
 | 
				
			||||||
 | 
					        import(/* @vite-ignore */ `/@/views${v.path}/index.vue`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (v.children) {
 | 
				
			||||||
 | 
					      addAsyncRoutes(v.children);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  return arrRoutes;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 按照路由中meta下的rank等级升序来排序路由
 | 
				
			||||||
 | 
					function ascending(arr) {
 | 
				
			||||||
 | 
					  return arr.sort((a: any, b: any) => {
 | 
				
			||||||
 | 
					    return a?.meta?.rank - b?.meta?.rank;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = createRouter({
 | 
					const router = createRouter({
 | 
				
			||||||
  history: createWebHashHistory(),
 | 
					  history: createWebHashHistory(),
 | 
				
			||||||
  routes,
 | 
					  routes: ascending(constantRoutes).concat(...remainingRouter),
 | 
				
			||||||
  scrollBehavior(to, from, savedPosition) {
 | 
					  scrollBehavior(to, from, savedPosition) {
 | 
				
			||||||
    return new Promise((resolve, reject) => {
 | 
					    return new Promise((resolve, reject) => {
 | 
				
			||||||
      if (savedPosition) {
 | 
					      if (savedPosition) {
 | 
				
			||||||
@ -46,13 +72,31 @@ import NProgress from "../utils/progress";
 | 
				
			|||||||
const whiteList = ["/login", "/register"];
 | 
					const whiteList = ["/login", "/register"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.beforeEach((to, _from, next) => {
 | 
					router.beforeEach((to, _from, next) => {
 | 
				
			||||||
 | 
					  let isLogin = storageSession.getItem("info");
 | 
				
			||||||
 | 
					  // _from?.name;
 | 
				
			||||||
 | 
					  if (isLogin && isLogin.username === "admin") {
 | 
				
			||||||
 | 
					    // 异步路由
 | 
				
			||||||
 | 
					    getAsyncRoutes().then(({ info }) => {
 | 
				
			||||||
 | 
					      addAsyncRoutes([info]).forEach((v: any) => {
 | 
				
			||||||
 | 
					        // 防止重复添加路由
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					          router.options.routes.findIndex((value) => value.path === v.path) !==
 | 
				
			||||||
 | 
					          -1
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        // 切记将路由push到routes后还需要使用addRoute,这样路由才能正常跳转
 | 
				
			||||||
 | 
					        router.options.routes.push(v);
 | 
				
			||||||
 | 
					        // 最终路由进行升序
 | 
				
			||||||
 | 
					        ascending(router.options.routes);
 | 
				
			||||||
 | 
					        router.addRoute(v.name, v);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  NProgress.start();
 | 
					  NProgress.start();
 | 
				
			||||||
  const { t } = i18n.global;
 | 
					  const { t } = i18n.global;
 | 
				
			||||||
  // @ts-ignore
 | 
					  // @ts-ignore
 | 
				
			||||||
  to.meta.title ? (document.title = t(to.meta.title)) : ""; // 动态title
 | 
					  to.meta.title ? (document.title = t(to.meta.title)) : ""; // 动态title
 | 
				
			||||||
  whiteList.indexOf(to.path) !== -1 || storageSession.getItem("info")
 | 
					  whiteList.indexOf(to.path) !== -1 || isLogin ? next() : next("/login"); // 全部重定向到登录页
 | 
				
			||||||
    ? next()
 | 
					 | 
				
			||||||
    : next("/login"); // 全部重定向到登录页
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.afterEach(() => {
 | 
					router.afterEach(() => {
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,17 @@ const componentsRouter = {
 | 
				
			|||||||
  name: "components",
 | 
					  name: "components",
 | 
				
			||||||
  component: Layout,
 | 
					  component: Layout,
 | 
				
			||||||
  redirect: "/components/split-pane",
 | 
					  redirect: "/components/split-pane",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    icon: "el-icon-menu",
 | 
				
			||||||
 | 
					    title: "message.hscomponents",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: true,
 | 
				
			||||||
 | 
					    rank: 4,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/video",
 | 
					      path: "/components/video",
 | 
				
			||||||
 | 
					      name: "video",
 | 
				
			||||||
      component: () => import("/@/views/components/video/index.vue"),
 | 
					      component: () => import("/@/views/components/video/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsvideo",
 | 
					        title: "message.hsvideo",
 | 
				
			||||||
@ -17,6 +25,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/map",
 | 
					      path: "/components/map",
 | 
				
			||||||
 | 
					      name: "map",
 | 
				
			||||||
      component: () => import("/@/views/components/map/index.vue"),
 | 
					      component: () => import("/@/views/components/map/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsmap",
 | 
					        title: "message.hsmap",
 | 
				
			||||||
@ -26,6 +35,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/draggable",
 | 
					      path: "/components/draggable",
 | 
				
			||||||
 | 
					      name: "draggable",
 | 
				
			||||||
      component: () => import("/@/views/components/draggable/index.vue"),
 | 
					      component: () => import("/@/views/components/draggable/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsdraggable",
 | 
					        title: "message.hsdraggable",
 | 
				
			||||||
@ -33,8 +43,10 @@ const componentsRouter = {
 | 
				
			|||||||
        savedPosition: true,
 | 
					        savedPosition: true,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/split-pane",
 | 
					      path: "/components/splitPane",
 | 
				
			||||||
 | 
					      name: "splitPane",
 | 
				
			||||||
      component: () => import("/@/views/components/split-pane/index.vue"),
 | 
					      component: () => import("/@/views/components/split-pane/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hssplitPane",
 | 
					        title: "message.hssplitPane",
 | 
				
			||||||
@ -44,6 +56,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/button",
 | 
					      path: "/components/button",
 | 
				
			||||||
 | 
					      name: "button",
 | 
				
			||||||
      component: () => import("/@/views/components/button/index.vue"),
 | 
					      component: () => import("/@/views/components/button/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsbutton",
 | 
					        title: "message.hsbutton",
 | 
				
			||||||
@ -53,6 +66,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/cropping",
 | 
					      path: "/components/cropping",
 | 
				
			||||||
 | 
					      name: "cropping",
 | 
				
			||||||
      component: () => import("/@/views/components/cropping/index.vue"),
 | 
					      component: () => import("/@/views/components/cropping/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hscropping",
 | 
					        title: "message.hscropping",
 | 
				
			||||||
@ -62,6 +76,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/countTo",
 | 
					      path: "/components/countTo",
 | 
				
			||||||
 | 
					      name: "countTo",
 | 
				
			||||||
      component: () => import("/@/views/components/count-to/index.vue"),
 | 
					      component: () => import("/@/views/components/count-to/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hscountTo",
 | 
					        title: "message.hscountTo",
 | 
				
			||||||
@ -71,6 +86,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/selector",
 | 
					      path: "/components/selector",
 | 
				
			||||||
 | 
					      name: "selector",
 | 
				
			||||||
      component: () => import("/@/views/components/selector/index.vue"),
 | 
					      component: () => import("/@/views/components/selector/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsselector",
 | 
					        title: "message.hsselector",
 | 
				
			||||||
@ -80,6 +96,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/seamlessScroll",
 | 
					      path: "/components/seamlessScroll",
 | 
				
			||||||
 | 
					      name: "seamlessScroll",
 | 
				
			||||||
      component: () => import("/@/views/components/seamless-scroll/index.vue"),
 | 
					      component: () => import("/@/views/components/seamless-scroll/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsseamless",
 | 
					        title: "message.hsseamless",
 | 
				
			||||||
@ -89,6 +106,7 @@ const componentsRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/contextmenu",
 | 
					      path: "/components/contextmenu",
 | 
				
			||||||
 | 
					      name: "contextmenu",
 | 
				
			||||||
      component: () => import("/@/views/components/contextmenu/index.vue"),
 | 
					      component: () => import("/@/views/components/contextmenu/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hscontextmenu",
 | 
					        title: "message.hscontextmenu",
 | 
				
			||||||
@ -97,12 +115,6 @@ const componentsRouter = {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  meta: {
 | 
					 | 
				
			||||||
    icon: "el-icon-menu",
 | 
					 | 
				
			||||||
    title: "message.hscomponents",
 | 
					 | 
				
			||||||
    showLink: true,
 | 
					 | 
				
			||||||
    savedPosition: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default componentsRouter;
 | 
					export default componentsRouter;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,17 @@ const editorRouter = {
 | 
				
			|||||||
  name: "editor",
 | 
					  name: "editor",
 | 
				
			||||||
  component: Layout,
 | 
					  component: Layout,
 | 
				
			||||||
  redirect: "/editor/index",
 | 
					  redirect: "/editor/index",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    icon: "el-icon-edit-outline",
 | 
				
			||||||
 | 
					    title: "message.hseditor",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: true,
 | 
				
			||||||
 | 
					    rank: 2,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/editor/index",
 | 
					      path: "/editor/index",
 | 
				
			||||||
 | 
					      name: "editor",
 | 
				
			||||||
      component: () => import("/@/views/editor/index.vue"),
 | 
					      component: () => import("/@/views/editor/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hseditor",
 | 
					        title: "message.hseditor",
 | 
				
			||||||
@ -16,12 +24,6 @@ const editorRouter = {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  meta: {
 | 
					 | 
				
			||||||
    icon: "el-icon-edit-outline",
 | 
					 | 
				
			||||||
    title: "message.hseditor",
 | 
					 | 
				
			||||||
    showLink: true,
 | 
					 | 
				
			||||||
    savedPosition: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default editorRouter;
 | 
					export default editorRouter;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,17 @@ const errorRouter = {
 | 
				
			|||||||
  name: "error",
 | 
					  name: "error",
 | 
				
			||||||
  component: Layout,
 | 
					  component: Layout,
 | 
				
			||||||
  redirect: "/error/401",
 | 
					  redirect: "/error/401",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    icon: "el-icon-position",
 | 
				
			||||||
 | 
					    title: "message.hserror",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: true,
 | 
				
			||||||
 | 
					    rank: 7,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/error/401",
 | 
					      path: "/error/401",
 | 
				
			||||||
 | 
					      name: "401",
 | 
				
			||||||
      component: () => import("/@/views/error/401.vue"),
 | 
					      component: () => import("/@/views/error/401.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsfourZeroOne",
 | 
					        title: "message.hsfourZeroOne",
 | 
				
			||||||
@ -17,6 +25,7 @@ const errorRouter = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/error/404",
 | 
					      path: "/error/404",
 | 
				
			||||||
 | 
					      name: "404",
 | 
				
			||||||
      component: () => import("/@/views/error/404.vue"),
 | 
					      component: () => import("/@/views/error/404.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsfourZeroFour",
 | 
					        title: "message.hsfourZeroFour",
 | 
				
			||||||
@ -25,12 +34,6 @@ const errorRouter = {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  meta: {
 | 
					 | 
				
			||||||
    icon: "el-icon-position",
 | 
					 | 
				
			||||||
    title: "message.hserror",
 | 
					 | 
				
			||||||
    showLink: true,
 | 
					 | 
				
			||||||
    savedPosition: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default errorRouter;
 | 
					export default errorRouter;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,17 @@ const flowChartRouter = {
 | 
				
			|||||||
  name: "flowChart",
 | 
					  name: "flowChart",
 | 
				
			||||||
  component: Layout,
 | 
					  component: Layout,
 | 
				
			||||||
  redirect: "/flowChart/index",
 | 
					  redirect: "/flowChart/index",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    icon: "el-icon-set-up",
 | 
				
			||||||
 | 
					    title: "message.hsflowChart",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: true,
 | 
				
			||||||
 | 
					    rank: 1,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/flowChart/index",
 | 
					      path: "/flowChart/index",
 | 
				
			||||||
 | 
					      name: "flowChart",
 | 
				
			||||||
      component: () => import("/@/views/flow-chart/index.vue"),
 | 
					      component: () => import("/@/views/flow-chart/index.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: "message.hsflowChart",
 | 
					        title: "message.hsflowChart",
 | 
				
			||||||
@ -16,12 +24,6 @@ const flowChartRouter = {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  meta: {
 | 
					 | 
				
			||||||
    icon: "el-icon-set-up",
 | 
					 | 
				
			||||||
    title: "message.hsflowChart",
 | 
					 | 
				
			||||||
    showLink: true,
 | 
					 | 
				
			||||||
    savedPosition: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default flowChartRouter;
 | 
					export default flowChartRouter;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,12 @@ const homeRouter = {
 | 
				
			|||||||
  name: "home",
 | 
					  name: "home",
 | 
				
			||||||
  component: Layout,
 | 
					  component: Layout,
 | 
				
			||||||
  redirect: "/welcome",
 | 
					  redirect: "/welcome",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    icon: "el-icon-s-home",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: false,
 | 
				
			||||||
 | 
					    rank: 0,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/welcome",
 | 
					      path: "/welcome",
 | 
				
			||||||
@ -17,11 +23,6 @@ const homeRouter = {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  meta: {
 | 
					 | 
				
			||||||
    icon: "el-icon-s-home",
 | 
					 | 
				
			||||||
    showLink: true,
 | 
					 | 
				
			||||||
    savedPosition: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default homeRouter;
 | 
					export default homeRouter;
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@ const nestedRouter = {
 | 
				
			|||||||
    icon: "el-icon-s-data",
 | 
					    icon: "el-icon-s-data",
 | 
				
			||||||
    showLink: true,
 | 
					    showLink: true,
 | 
				
			||||||
    savedPosition: false,
 | 
					    savedPosition: false,
 | 
				
			||||||
 | 
					    rank: 5,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										39
									
								
								src/router/modules/permission.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/router/modules/permission.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					import Layout from "/@/layout/index.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const permissionRouter = {
 | 
				
			||||||
 | 
					  path: "/permission",
 | 
				
			||||||
 | 
					  component: Layout,
 | 
				
			||||||
 | 
					  redirect: "/permission/page",
 | 
				
			||||||
 | 
					  name: "permission",
 | 
				
			||||||
 | 
					  meta: {
 | 
				
			||||||
 | 
					    title: "message.permission",
 | 
				
			||||||
 | 
					    icon: "el-icon-lollipop",
 | 
				
			||||||
 | 
					    showLink: true,
 | 
				
			||||||
 | 
					    savedPosition: false,
 | 
				
			||||||
 | 
					    rank: 3,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  children: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/permission/page",
 | 
				
			||||||
 | 
					      component: () => import("/@/views/permission/page.vue"),
 | 
				
			||||||
 | 
					      name: "permissionPage",
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: "message.permissionPage",
 | 
				
			||||||
 | 
					        showLink: true,
 | 
				
			||||||
 | 
					        savedPosition: false,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/permission/button",
 | 
				
			||||||
 | 
					      component: () => import("/@/views/permission/button.vue"),
 | 
				
			||||||
 | 
					      name: "permissionButton",
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: "message.permissionButton",
 | 
				
			||||||
 | 
					        showLink: true,
 | 
				
			||||||
 | 
					        savedPosition: false,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default permissionRouter;
 | 
				
			||||||
@ -8,6 +8,7 @@ const remainingRouter = [
 | 
				
			|||||||
    meta: {
 | 
					    meta: {
 | 
				
			||||||
      title: "message.hslogin",
 | 
					      title: "message.hslogin",
 | 
				
			||||||
      showLink: false,
 | 
					      showLink: false,
 | 
				
			||||||
 | 
					      rank: 101,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@ -17,11 +18,13 @@ const remainingRouter = [
 | 
				
			|||||||
    meta: {
 | 
					    meta: {
 | 
				
			||||||
      title: "message.hsregister",
 | 
					      title: "message.hsregister",
 | 
				
			||||||
      showLink: false,
 | 
					      showLink: false,
 | 
				
			||||||
 | 
					      rank: 102,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // 找不到路由重定向到404页面
 | 
					    // 找不到路由重定向到404页面
 | 
				
			||||||
    path: "/:pathMatch(.*)",
 | 
					    path: "/:pathMatch(.*)",
 | 
				
			||||||
 | 
					    name: "pathMatch",
 | 
				
			||||||
    component: Layout,
 | 
					    component: Layout,
 | 
				
			||||||
    redirect: "/error/404",
 | 
					    redirect: "/error/404",
 | 
				
			||||||
    meta: {
 | 
					    meta: {
 | 
				
			||||||
@ -29,14 +32,24 @@ const remainingRouter = [
 | 
				
			|||||||
      title: "message.hshome",
 | 
					      title: "message.hshome",
 | 
				
			||||||
      showLink: false,
 | 
					      showLink: false,
 | 
				
			||||||
      savedPosition: false,
 | 
					      savedPosition: false,
 | 
				
			||||||
 | 
					      rank: 103,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    path: "/redirect",
 | 
					    path: "/redirect",
 | 
				
			||||||
 | 
					    name: "redirect",
 | 
				
			||||||
    component: Layout,
 | 
					    component: Layout,
 | 
				
			||||||
 | 
					    meta: {
 | 
				
			||||||
 | 
					      icon: "el-icon-s-home",
 | 
				
			||||||
 | 
					      title: "message.hshome",
 | 
				
			||||||
 | 
					      showLink: false,
 | 
				
			||||||
 | 
					      savedPosition: false,
 | 
				
			||||||
 | 
					      rank: 104,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    children: [
 | 
					    children: [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: "/redirect/:path(.*)",
 | 
					        path: "/redirect/:path(.*)",
 | 
				
			||||||
 | 
					        name: "redirect",
 | 
				
			||||||
        component: () => import("/@/views/redirect.vue"),
 | 
					        component: () => import("/@/views/redirect.vue"),
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
				
			|||||||
@ -1,36 +0,0 @@
 | 
				
			|||||||
import Layout from "/@/layout/index.vue";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const systemRouter = {
 | 
					 | 
				
			||||||
  path: "/system",
 | 
					 | 
				
			||||||
  name: "system",
 | 
					 | 
				
			||||||
  component: Layout,
 | 
					 | 
				
			||||||
  redirect: "/system/base",
 | 
					 | 
				
			||||||
  children: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      path: "/system/base",
 | 
					 | 
				
			||||||
      component: () => import("/@/views/system/user.vue"),
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        title: "message.hsBaseinfo",
 | 
					 | 
				
			||||||
        showLink: false,
 | 
					 | 
				
			||||||
        savedPosition: true,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      path: "/system/dict",
 | 
					 | 
				
			||||||
      component: () => import("/@/views/system/dict/index.vue"),
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        title: "message.hsDict",
 | 
					 | 
				
			||||||
        showLink: false,
 | 
					 | 
				
			||||||
        savedPosition: true,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  meta: {
 | 
					 | 
				
			||||||
    icon: "el-icon-setting",
 | 
					 | 
				
			||||||
    title: "message.hssysManagement",
 | 
					 | 
				
			||||||
    showLink: true,
 | 
					 | 
				
			||||||
    savedPosition: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default systemRouter;
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								src/views/permission/button.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/views/permission/button.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div>button</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang='ts'>
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  name: "permissionButton",
 | 
				
			||||||
 | 
					  setup() {
 | 
				
			||||||
 | 
					    return {};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										45
									
								
								src/views/permission/page.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/views/permission/page.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="app-container">
 | 
				
			||||||
 | 
					    <h4>
 | 
				
			||||||
 | 
					      当前角色:
 | 
				
			||||||
 | 
					      <span style="font-size:26px">{{ purview }}</span>
 | 
				
			||||||
 | 
					      <p style="color:	#FFA500">查看左侧菜单变化(系统管理),模拟后台根据不同角色返回对应路由</p>
 | 
				
			||||||
 | 
					    </h4>
 | 
				
			||||||
 | 
					    <el-button type="primary" @click="changRole">切换角色</el-button>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang='ts'>
 | 
				
			||||||
 | 
					import { ref, unref } from "vue";
 | 
				
			||||||
 | 
					import { storageSession } from "/@/utils/storage";
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  name: "permissionPage",
 | 
				
			||||||
 | 
					  setup() {
 | 
				
			||||||
 | 
					    let purview: string = ref(storageSession.getItem("info").username);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function changRole() {
 | 
				
			||||||
 | 
					      if (unref(purview) === "admin") {
 | 
				
			||||||
 | 
					        storageSession.setItem("info", {
 | 
				
			||||||
 | 
					          username: "test",
 | 
				
			||||||
 | 
					          accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        window.location.reload();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        storageSession.setItem("info", {
 | 
				
			||||||
 | 
					          username: "admin",
 | 
				
			||||||
 | 
					          accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        window.location.reload();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      purview,
 | 
				
			||||||
 | 
					      changRole
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -96,6 +96,7 @@ import {
 | 
				
			|||||||
import Config from "./config.vue";
 | 
					import Config from "./config.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
 | 
					  name: "dict",
 | 
				
			||||||
  components: {
 | 
					  components: {
 | 
				
			||||||
    Config
 | 
					    Config
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
				
			|||||||
@ -35,7 +35,8 @@
 | 
				
			|||||||
    "types/**/*.ts",
 | 
					    "types/**/*.ts",
 | 
				
			||||||
    "types/global.d.ts",
 | 
					    "types/global.d.ts",
 | 
				
			||||||
    "types/shims-tsx.d.ts",
 | 
					    "types/shims-tsx.d.ts",
 | 
				
			||||||
    "types/shims-vue.d.ts"
 | 
					    "types/shims-vue.d.ts",
 | 
				
			||||||
 | 
					    "mock/asyncRoutes.ts"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "exclude": ["node_modules", "dist", "**/*.js"]
 | 
					  "exclude": ["node_modules", "dist", "**/*.js"]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user