- 删除重复文件:components/ui/use-toast.ts 和 components/ui/use-mobile.tsx - 统一 getAuthToken() 函数,在 api-client.ts 中导入并删除重复定义 - 创建 clearAllTokens() 工具函数,统一 token 清除逻辑 - 修复 Toast 延迟时间(从 1000000ms 改为 5000ms) - 修复 TypeScript 类型错误:在 applicationForm 中添加 providerId 字段 - 修复登录路径:使用 super_admin 角色登录超级管理员 - 移除登录前的后端可达性检查(避免浏览器环境问题) - 在管理用户对话框中添加租户角色修改功能(租户/计费管理员/运营管理员) - 移除管理用户对话框中的用户数字段(用户层面不应显示用户数) - 在设置页面添加当前渠道管理员列表显示功能 - 添加获取和创建渠道管理员的 API 方法 - 更新登录方法的角色类型定义,支持所有角色类型
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import { NextResponse } from 'next/server'
|
||
import type { NextRequest } from 'next/server'
|
||
|
||
// 需要认证的路径
|
||
const protectedPaths = [
|
||
'/', // 主页也需要认证
|
||
'/agent-factory',
|
||
'/data-tools',
|
||
'/model-gateway',
|
||
'/orchestration',
|
||
'/billing',
|
||
'/admin/dashboard',
|
||
'/channel/dashboard',
|
||
]
|
||
|
||
// 公开路径(不需要认证)
|
||
const publicPaths = [
|
||
'/login',
|
||
'/admin/login',
|
||
'/channel/login',
|
||
]
|
||
|
||
export function middleware(request: NextRequest) {
|
||
const { pathname } = request.nextUrl
|
||
|
||
// 登录页面不需要检查认证(精确匹配)
|
||
if (publicPaths.includes(pathname)) {
|
||
return NextResponse.next()
|
||
}
|
||
|
||
// 检查是否是受保护的路径
|
||
const isProtected = protectedPaths.some(path => {
|
||
if (path === '/') {
|
||
return pathname === '/'
|
||
}
|
||
return pathname.startsWith(path)
|
||
})
|
||
|
||
if (isProtected) {
|
||
// 从 cookie 或 localStorage 检查 token(这里只能检查 cookie)
|
||
const authToken = request.cookies.get('auth_token')?.value
|
||
const adminToken = request.cookies.get('admin_token')?.value
|
||
const channelToken = request.cookies.get('channel_token')?.value
|
||
|
||
// 根据路径类型检查对应的 token
|
||
let hasValidToken = false
|
||
|
||
if (pathname.startsWith('/admin')) {
|
||
hasValidToken = !!adminToken
|
||
} else if (pathname.startsWith('/channel')) {
|
||
hasValidToken = !!channelToken
|
||
} else {
|
||
hasValidToken = !!authToken
|
||
}
|
||
|
||
if (!hasValidToken) {
|
||
// 未登录,重定向到登录页
|
||
const loginUrl = getLoginUrl(pathname)
|
||
const redirectUrl = new URL(loginUrl, request.url)
|
||
redirectUrl.searchParams.set('redirect', pathname)
|
||
return NextResponse.redirect(redirectUrl)
|
||
}
|
||
}
|
||
|
||
return NextResponse.next()
|
||
}
|
||
|
||
function getLoginUrl(pathname: string): string {
|
||
if (pathname.startsWith('/admin')) {
|
||
return '/admin/login'
|
||
}
|
||
if (pathname.startsWith('/channel')) {
|
||
return '/channel/login'
|
||
}
|
||
return '/login'
|
||
}
|
||
|
||
export const config = {
|
||
matcher: [
|
||
/*
|
||
* 匹配所有路径除了:
|
||
* - api (API routes)
|
||
* - _next/static (static files)
|
||
* - _next/image (image optimization files)
|
||
* - favicon.ico (favicon file)
|
||
* - public folder
|
||
*/
|
||
'/((?!api|_next/static|_next/image|favicon.ico|.*\\..*$).*)',
|
||
],
|
||
}
|