1. 课程学习进度追踪
- 新增 UserCourseProgress 和 UserMaterialProgress 模型
- 新增 /api/v1/progress/* 进度追踪 API
- 更新 admin.py 使用真实课程完成率数据
2. 路由权限检查完善
- 新增前端 permissionChecker.ts 权限检查工具
- 更新 router/guard.ts 实现团队和课程权限验证
- 新增后端 permission_service.py
3. AI 陪练音频转文本
- 新增 speech_recognition.py 语音识别服务
- 新增 /api/v1/speech/* API
- 更新 ai-practice-coze.vue 支持语音输入
4. 双人对练报告生成
- 更新 practice_room_service.py 添加报告生成功能
- 新增 /rooms/{room_code}/report API
- 更新 duo-practice-report.vue 调用真实 API
5. 学习提醒推送
- 新增 notification_service.py 通知服务
- 新增 scheduler_service.py 定时任务服务
- 支持钉钉、企微、站内消息推送
6. 智能学习推荐
- 新增 recommendation_service.py 推荐服务
- 新增 /api/v1/recommendations/* API
- 支持错题、能力、进度、热门多维度推荐
7. 安全问题修复
- DEBUG 默认值改为 False
- 添加 SECRET_KEY 安全警告
- 新增 check_security_settings() 检查函数
8. 证书 PDF 生成
- 更新 certificate_service.py 添加 PDF 生成
- 添加 weasyprint、Pillow、qrcode 依赖
- 更新下载 API 支持 PDF 和 PNG 格式
This commit is contained in:
@@ -7,6 +7,7 @@ import { Router, RouteLocationNormalized, NavigationGuardNext } from 'vue-router
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { authManager } from '@/utils/auth'
|
||||
import { loadingManager } from '@/utils/loadingManager'
|
||||
import { checkTeamMembership, checkCourseAccess, clearPermissionCache } from '@/utils/permissionChecker'
|
||||
|
||||
// 白名单路由(不需要登录)
|
||||
const WHITE_LIST = ['/login', '/register', '/404']
|
||||
@@ -109,13 +110,21 @@ async function handleRouteGuard(
|
||||
return
|
||||
}
|
||||
|
||||
// 检查特殊路由规则
|
||||
// 检查特殊路由规则(先进行同步检查)
|
||||
if (!checkSpecialRouteRules(to)) {
|
||||
ElMessage.error('访问被拒绝')
|
||||
next(authManager.getDefaultRoute())
|
||||
return
|
||||
}
|
||||
|
||||
// 异步权限检查(团队和课程权限)
|
||||
const hasSpecialAccess = await checkSpecialRouteRulesAsync(to)
|
||||
if (!hasSpecialAccess) {
|
||||
ElMessage.error('您没有访问此资源的权限')
|
||||
next(authManager.getDefaultRoute())
|
||||
return
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
@@ -142,9 +151,9 @@ function checkRoutePermission(path: string): boolean {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查特殊路由规则
|
||||
* 检查特殊路由规则(异步版本)
|
||||
*/
|
||||
function checkSpecialRouteRules(to: RouteLocationNormalized): boolean {
|
||||
async function checkSpecialRouteRulesAsync(to: RouteLocationNormalized): Promise<boolean> {
|
||||
const { path, params } = to
|
||||
|
||||
// 检查用户ID参数权限(只能访问自己的数据,管理员除外)
|
||||
@@ -157,14 +166,41 @@ function checkSpecialRouteRules(to: RouteLocationNormalized): boolean {
|
||||
|
||||
// 检查团队ID参数权限
|
||||
if (params.teamId && !authManager.isAdmin()) {
|
||||
// 这里可以添加团队权限检查逻辑
|
||||
// 暂时允许通过,实际项目中需要检查用户是否属于该团队
|
||||
const teamId = Number(params.teamId)
|
||||
if (!isNaN(teamId)) {
|
||||
const isMember = await checkTeamMembership(teamId)
|
||||
if (!isMember) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查课程访问权限
|
||||
if (path.includes('/course/') && params.courseId) {
|
||||
// 这里可以添加课程访问权限检查
|
||||
// 例如检查课程是否分配给用户的岗位
|
||||
const courseId = Number(params.courseId)
|
||||
if (!isNaN(courseId)) {
|
||||
const hasAccess = await checkCourseAccess(courseId)
|
||||
if (!hasAccess) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查特殊路由规则(同步版本,用于简单检查)
|
||||
*/
|
||||
function checkSpecialRouteRules(to: RouteLocationNormalized): boolean {
|
||||
const { params } = to
|
||||
|
||||
// 检查用户ID参数权限(只能访问自己的数据,管理员除外)
|
||||
if (params.userId && !authManager.isAdmin()) {
|
||||
const currentUser = authManager.getCurrentUser()
|
||||
if (currentUser && String(params.userId) !== String(currentUser.id)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user