This commit is contained in:
Chuck1sn
2025-05-14 10:16:48 +08:00
commit 3cd59337e7
220 changed files with 23768 additions and 0 deletions

View 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",
}

View 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);
};

View 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;

View 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;

View 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;

View 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;

View 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;