mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-03-26 05:13:45 +08:00
init
This commit is contained in:
63
frontend/src/router/constants.ts
Normal file
63
frontend/src/router/constants.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
export enum RoutePath {
|
||||
HOME = "/",
|
||||
LOGIN = "/login",
|
||||
DASHBOARD = "/dashboard",
|
||||
GLOBAL_NOTFOUND = "/:pathMatch(.*)*",
|
||||
NOTFOUND = ":pathMatch(.*)*",
|
||||
OVERVIEW = "overview",
|
||||
USERVIEW = "users",
|
||||
ROLEVIEW = "roles",
|
||||
BINDROLEVIEW = "bind-roles/:userId",
|
||||
BINDPERMISSIONVIEW = "bind-permissions/:roleId",
|
||||
BINDDEPARTMENTVIEW = "bind-departments/:userId",
|
||||
BINDPOSITIONVIEW = "bind-positions/:userId",
|
||||
PERMISSIONVIEW = "permissions",
|
||||
DEPARTMENTVIEW = "departments",
|
||||
POSITIONVIEW = "positions",
|
||||
CREATEUSERVIEW = "create-user",
|
||||
SCHEDULERVIEW = "scheduler",
|
||||
UPSERTUSERVIEW = "upsert-user",
|
||||
UPSERTROLEVIEW = "upsert-role",
|
||||
UPSERTPERMISSIONVIEW = "upsert-permission",
|
||||
UPSERTDEPARTMENTVIEW = "upsert-department",
|
||||
UPSERTPOSITIONVIEW = "upsert-position",
|
||||
SETTINGS = "settings",
|
||||
}
|
||||
|
||||
export enum RouteName {
|
||||
HOME = "home",
|
||||
LOGIN = "login",
|
||||
DASHBOARD = "dashboard",
|
||||
OVERVIEW = "overview",
|
||||
USERVIEW = "users",
|
||||
ROLEVIEW = "roles",
|
||||
BINDROLEVIEW = "bind-roles",
|
||||
BINDPERMISSIONVIEW = "bind-permissions",
|
||||
BINDDEPARTMENTVIEW = "bind-departments",
|
||||
BINDPOSITIONVIEW = "bind-positions",
|
||||
PERMISSIONVIEW = "permissions",
|
||||
DEPARTMENTVIEW = "departments",
|
||||
POSITIONVIEW = "positions",
|
||||
CREATEUSERVIEW = "create-user",
|
||||
SCHEDULERVIEW = "scheduler",
|
||||
UPSERTUSERVIEW = "upsert-user",
|
||||
UPSERTROLEVIEW = "upsert-role",
|
||||
UPSERTPERMISSIONVIEW = "upsert-permission",
|
||||
UPSERTDEPARTMENTVIEW = "upsert-department",
|
||||
UPSERTPOSITIONVIEW = "upsert-position",
|
||||
SETTINGS = "settings",
|
||||
NOTFOUND = "notfound",
|
||||
GLOBAL_NOTFOUND = "global-notfound",
|
||||
}
|
||||
|
||||
export enum ROLE {
|
||||
ADMIN = "ADMIN",
|
||||
USER = "USER",
|
||||
}
|
||||
|
||||
export enum PERMISSION {
|
||||
USER_VIEW = "user:view",
|
||||
USER_ADD = "user:add",
|
||||
USER_EDIT = "user:edit",
|
||||
USER_DELETE = "user:delete",
|
||||
}
|
||||
47
frontend/src/router/guards.ts
Normal file
47
frontend/src/router/guards.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import useUserStore from "@/composables/store/useUserStore";
|
||||
import type { NavigationGuard, Router } from "vue-router";
|
||||
import type { RouteMeta } from "../types/router";
|
||||
import { RoutePath } from "./constants";
|
||||
|
||||
export const authGuard: NavigationGuard = (to) => {
|
||||
const userStore = useUserStore();
|
||||
if (to.meta.requiresAuth && !userStore.user) {
|
||||
return {
|
||||
path: RoutePath.LOGIN,
|
||||
query: { redirect: to.fullPath },
|
||||
};
|
||||
}
|
||||
if (to.path === RoutePath.LOGIN && userStore.user) {
|
||||
return { path: `${RoutePath.DASHBOARD}/${RoutePath.USERVIEW}` };
|
||||
}
|
||||
};
|
||||
|
||||
export const permissionGuard: NavigationGuard = (to) => {
|
||||
const userStore = useUserStore();
|
||||
const routeMeta: RouteMeta = to.meta;
|
||||
if (routeMeta.hasPermission) {
|
||||
const hasPermission = userStore.permissionCodes?.includes(
|
||||
routeMeta.hasPermission,
|
||||
);
|
||||
if (!hasPermission) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const roleGuard: NavigationGuard = (to) => {
|
||||
const userStore = useUserStore();
|
||||
const routeMeta: RouteMeta = to.meta;
|
||||
if (routeMeta.hasRole) {
|
||||
const hasRole = userStore.roleCodes?.includes(routeMeta.hasRole);
|
||||
if (!hasRole) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const setupGuards = (router: Router) => {
|
||||
router.beforeEach(authGuard);
|
||||
router.beforeEach(permissionGuard);
|
||||
router.beforeEach(roleGuard);
|
||||
};
|
||||
29
frontend/src/router/index.ts
Normal file
29
frontend/src/router/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import { setupGuards } from "./guards";
|
||||
|
||||
import authRoutes from "./modules/auth";
|
||||
import dashboardRoutes from "./modules/dashboard";
|
||||
import errorRoutes from "./modules/error";
|
||||
import { RouteName } from "./constants";
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
dashboardRoutes,
|
||||
...authRoutes,
|
||||
...errorRoutes,
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes,
|
||||
});
|
||||
|
||||
router.onError((err) => {
|
||||
console.error("router err:", err);
|
||||
// TODO 增加一个错误页面
|
||||
router.push(RouteName.USERVIEW);
|
||||
return false;
|
||||
});
|
||||
setupGuards(router);
|
||||
|
||||
export default router;
|
||||
19
frontend/src/router/modules/auth.ts
Normal file
19
frontend/src/router/modules/auth.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import { RouteName, RoutePath } from "../constants";
|
||||
|
||||
const authRoutes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: RoutePath.HOME,
|
||||
name: RouteName.HOME,
|
||||
redirect: {
|
||||
name: RouteName.LOGIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.LOGIN,
|
||||
name: RouteName.LOGIN,
|
||||
component: () => import("../../views/LoginView.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
export default authRoutes;
|
||||
67
frontend/src/router/modules/dashboard.ts
Normal file
67
frontend/src/router/modules/dashboard.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import Dashboard from "../../components/Dashboard.vue";
|
||||
import OverView from "../../views/OverView.vue";
|
||||
import { ROLE, RouteName, RoutePath } from "../constants";
|
||||
import userManagementRoutes from "./user";
|
||||
|
||||
const dashboardRoutes: RouteRecordRaw = {
|
||||
path: RoutePath.DASHBOARD,
|
||||
name: RouteName.DASHBOARD,
|
||||
component: Dashboard,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: RoutePath.OVERVIEW,
|
||||
name: RouteName.OVERVIEW,
|
||||
component: () => import("@/views/OverView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.SETTINGS,
|
||||
name: RouteName.SETTINGS,
|
||||
component: () => import("@/views/SettingsView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
...userManagementRoutes,
|
||||
{
|
||||
path: RoutePath.NOTFOUND,
|
||||
name: RouteName.NOTFOUND,
|
||||
component: () => import("@/views/NotFound.vue"),
|
||||
},
|
||||
{
|
||||
path: RoutePath.SCHEDULERVIEW,
|
||||
name: RouteName.SCHEDULERVIEW,
|
||||
component: () => import("@/views/SchedulerView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.DEPARTMENTVIEW,
|
||||
name: RouteName.DEPARTMENTVIEW,
|
||||
component: () => import("@/views/DepartmentView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.POSITIONVIEW,
|
||||
name: RouteName.POSITIONVIEW,
|
||||
component: () => import("@/views/PositionView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default dashboardRoutes;
|
||||
12
frontend/src/router/modules/error.ts
Normal file
12
frontend/src/router/modules/error.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import { RouteName, RoutePath } from "../constants";
|
||||
|
||||
const errorRoutes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: RoutePath.GLOBAL_NOTFOUND,
|
||||
name: RouteName.GLOBAL_NOTFOUND,
|
||||
component: () => import("../../views/NotFound.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
export default errorRoutes;
|
||||
70
frontend/src/router/modules/user.ts
Normal file
70
frontend/src/router/modules/user.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import { ROLE, RouteName, RoutePath } from "../constants";
|
||||
|
||||
const userManagementRoutes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: RoutePath.USERVIEW,
|
||||
name: RouteName.USERVIEW,
|
||||
component: () => import("@/views/UserView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.ROLEVIEW,
|
||||
name: RouteName.ROLEVIEW,
|
||||
component: () => import("@/views/RoleView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.BINDROLEVIEW,
|
||||
name: RouteName.BINDROLEVIEW,
|
||||
component: () => import("@/views/BindRoleView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.BINDDEPARTMENTVIEW,
|
||||
name: RouteName.BINDDEPARTMENTVIEW,
|
||||
component: () => import("@/views/BindDepartmentView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.BINDPERMISSIONVIEW,
|
||||
name: RouteName.BINDPERMISSIONVIEW,
|
||||
component: () => import("@/views/BindPermissionView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.PERMISSIONVIEW,
|
||||
name: RouteName.PERMISSIONVIEW,
|
||||
component: () => import("@/views/PermissionView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: RoutePath.BINDPOSITIONVIEW,
|
||||
name: RouteName.BINDPOSITIONVIEW,
|
||||
component: () => import("@/views/BindPositionView.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hasRole: ROLE.ADMIN,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default userManagementRoutes;
|
||||
Reference in New Issue
Block a user