feat: 实现完整用户管理系统和LDAP认证集成

- 新增LDAP认证服务支持用户登录验证
- 实现用户服务包含会话管理和权限控制
- 添加用户专用路由和API端点
- 扩展认证中间件支持用户和管理员双重身份
- 新增用户仪表板、API密钥管理和使用统计界面
- 完善前端用户管理组件和路由配置
- 支持用户自助API密钥创建和管理
- 添加管理员用户管理功能包含角色权限控制

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Feng Yue
2025-08-13 11:30:00 +08:00
parent 1224ade5a7
commit eb150b4937
21 changed files with 4596 additions and 3 deletions

View File

@@ -1,9 +1,13 @@
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { useUserStore } from '@/stores/user'
import { APP_CONFIG } from '@/config/app'
// 路由懒加载
const LoginView = () => import('@/views/LoginView.vue')
const UserLoginView = () => import('@/views/UserLoginView.vue')
const UserDashboardView = () => import('@/views/UserDashboardView.vue')
const UserManagementView = () => import('@/views/UserManagementView.vue')
const MainLayout = () => import('@/components/layout/MainLayout.vue')
const DashboardView = () => import('@/views/DashboardView.vue')
const ApiKeysView = () => import('@/views/ApiKeysView.vue')
@@ -35,6 +39,22 @@ const routes = [
component: LoginView,
meta: { requiresAuth: false }
},
{
path: '/admin-login',
redirect: '/login'
},
{
path: '/user-login',
name: 'UserLogin',
component: UserLoginView,
meta: { requiresAuth: false, userAuth: true }
},
{
path: '/user-dashboard',
name: 'UserDashboard',
component: UserDashboardView,
meta: { requiresUserAuth: true }
},
{
path: '/api-stats',
name: 'ApiStats',
@@ -101,6 +121,18 @@ const routes = [
}
]
},
{
path: '/user-management',
component: MainLayout,
meta: { requiresAuth: true },
children: [
{
path: '',
name: 'UserManagement',
component: UserManagementView
}
]
},
// 捕获所有未匹配的路由
{
path: '/:pathMatch(.*)*',
@@ -114,15 +146,18 @@ const router = createRouter({
})
// 路由守卫
router.beforeEach((to, from, next) => {
router.beforeEach(async (to, from, next) => {
const authStore = useAuthStore()
const userStore = useUserStore()
console.log('路由导航:', {
to: to.path,
from: from.path,
fullPath: to.fullPath,
requiresAuth: to.meta.requiresAuth,
isAuthenticated: authStore.isAuthenticated
requiresUserAuth: to.meta.requiresUserAuth,
isAuthenticated: authStore.isAuthenticated,
isUserAuthenticated: userStore.isAuthenticated
})
// 防止重定向循环:如果已经在目标路径,直接放行
@@ -130,9 +165,28 @@ router.beforeEach((to, from, next) => {
return next()
}
// 检查用户认证状态
if (to.meta.requiresUserAuth) {
if (!userStore.isAuthenticated) {
// 尝试检查本地存储的认证信息
const isUserLoggedIn = await userStore.checkAuth()
if (!isUserLoggedIn) {
return next('/user-login')
}
}
return next()
}
// API Stats 页面不需要认证,直接放行
if (to.path === '/api-stats' || to.path.startsWith('/api-stats')) {
next()
} else if (to.path === '/user-login') {
// 如果已经是用户登录状态,重定向到用户仪表板
if (userStore.isAuthenticated) {
next('/user-dashboard')
} else {
next()
}
} else if (to.meta.requiresAuth && !authStore.isAuthenticated) {
next('/login')
} else if (to.path === '/login' && authStore.isAuthenticated) {