Initial commit: One Pipe System
完整的管理系统,包含账户管理、卡片管理、套餐管理、财务管理等功能模块。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
128
src/router/guards/permission.ts
Normal file
128
src/router/guards/permission.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* 权限验证相关工具函数
|
||||
*/
|
||||
|
||||
import type { RouteLocationNormalized } from 'vue-router'
|
||||
import type { UserInfo } from '@/types/api'
|
||||
|
||||
/**
|
||||
* 不需要登录的路由白名单
|
||||
*/
|
||||
export const LOGIN_WHITE_LIST = [
|
||||
'/auth/login',
|
||||
'/auth/register',
|
||||
'/auth/forget-password',
|
||||
'/exception/403',
|
||||
'/exception/404',
|
||||
'/exception/500'
|
||||
]
|
||||
|
||||
/**
|
||||
* 检查路由是否在白名单中
|
||||
*/
|
||||
export const isInWhiteList = (path: string): boolean => {
|
||||
return LOGIN_WHITE_LIST.some((whitePath) => {
|
||||
if (whitePath.endsWith('*')) {
|
||||
// 支持通配符匹配
|
||||
const prefix = whitePath.slice(0, -1)
|
||||
return path.startsWith(prefix)
|
||||
}
|
||||
return path === whitePath
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否有权限访问路由
|
||||
*/
|
||||
export const hasRoutePermission = (
|
||||
route: RouteLocationNormalized,
|
||||
userInfo: Partial<UserInfo>
|
||||
): boolean => {
|
||||
const { roles = [], permissions = [] } = userInfo
|
||||
|
||||
// 如果路由没有设置权限要求,直接通过
|
||||
if (!route.meta?.roles && !route.meta?.permissions) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 检查角色权限
|
||||
if (route.meta.roles) {
|
||||
const routeRoles = route.meta.roles as string[]
|
||||
const hasRole = routeRoles.some((role) => roles.includes(role as any))
|
||||
if (!hasRole) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查操作权限
|
||||
if (route.meta.permissions) {
|
||||
const routePermissions = route.meta.permissions as string[]
|
||||
const hasPermission = routePermissions.some((permission) => {
|
||||
// 支持通配符权限 *:*:*
|
||||
if (permissions.includes('*:*:*')) {
|
||||
return true
|
||||
}
|
||||
// 精确匹配或前缀匹配
|
||||
return permissions.some((userPermission) => {
|
||||
if (userPermission.endsWith('*')) {
|
||||
const prefix = userPermission.slice(0, -1)
|
||||
return permission.startsWith(prefix)
|
||||
}
|
||||
return userPermission === permission
|
||||
})
|
||||
})
|
||||
if (!hasPermission) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 Token 是否有效
|
||||
* 简单检查,真实项目中应该验证 JWT 或者调用后端接口
|
||||
*/
|
||||
export const isTokenValid = (token: string): boolean => {
|
||||
if (!token) return false
|
||||
|
||||
// Mock Token 格式: mock_token_{key}_{timestamp}
|
||||
if (token.startsWith('mock_token_')) {
|
||||
// Mock Token 永不过期(开发环境)
|
||||
return true
|
||||
}
|
||||
|
||||
// 真实 Token 可以在这里添加 JWT 解析和过期检查
|
||||
// 例如:
|
||||
// try {
|
||||
// const decoded = jwt_decode(token)
|
||||
// const isExpired = decoded.exp * 1000 < Date.now()
|
||||
// return !isExpired
|
||||
// } catch {
|
||||
// return false
|
||||
// }
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取重定向路径
|
||||
* 登录后跳转到之前访问的页面
|
||||
*/
|
||||
export const getRedirectPath = (route: RouteLocationNormalized): string => {
|
||||
const redirect = route.query.redirect as string
|
||||
if (redirect && !isInWhiteList(redirect)) {
|
||||
return redirect
|
||||
}
|
||||
return '/'
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建登录重定向 URL
|
||||
*/
|
||||
export const buildLoginRedirect = (currentPath: string): string => {
|
||||
if (isInWhiteList(currentPath)) {
|
||||
return '/auth/login'
|
||||
}
|
||||
return `/auth/login?redirect=${encodeURIComponent(currentPath)}`
|
||||
}
|
||||
Reference in New Issue
Block a user