Files
012-kaopeilian/backend/app/api/v1/endpoints/dashboard.py
yuliang_guo 64f5d567fa
Some checks failed
continuous-integration/drone/push Build is failing
feat: 实现 KPL 系统功能改进计划
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 格式
2026-01-30 14:22:35 +08:00

231 lines
6.0 KiB
Python

"""
数据大屏 API 端点
提供企业级和团队级数据大屏接口
"""
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.deps import get_db, get_current_user
from app.models.user import User
from app.services.dashboard_service import DashboardService
router = APIRouter()
@router.get("/enterprise/overview")
async def get_enterprise_overview(
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取企业级数据概览
需要管理员或企业管理员权限
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
data = await service.get_enterprise_overview()
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/enterprise/departments")
async def get_department_comparison(
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取部门/团队学习对比数据
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
data = await service.get_department_comparison()
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/enterprise/trend")
async def get_learning_trend(
days: int = Query(7, ge=1, le=30),
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取学习趋势数据
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
data = await service.get_learning_trend(days)
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/enterprise/level-distribution")
async def get_level_distribution(
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取等级分布数据
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
data = await service.get_level_distribution()
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/enterprise/activities")
async def get_realtime_activities(
limit: int = Query(20, ge=1, le=100),
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取实时动态
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
data = await service.get_realtime_activities(limit)
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/enterprise/course-ranking")
async def get_course_ranking(
limit: int = Query(10, ge=1, le=50),
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取课程热度排行
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
data = await service.get_course_ranking(limit)
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/team")
async def get_team_dashboard(
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取团队级数据大屏
面向团队负责人,显示其管理团队的数据
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要团队负责人权限"
)
service = DashboardService(db)
data = await service.get_team_dashboard(current_user.id)
return {
"code": 200,
"message": "success",
"data": data
}
@router.get("/all")
async def get_all_dashboard_data(
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取完整的大屏数据(一次性获取所有数据)
用于大屏初始化加载
"""
if current_user.role not in ["admin", "enterprise_admin", "manager"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="需要管理员权限"
)
service = DashboardService(db)
# 并行获取所有数据
overview = await service.get_enterprise_overview()
departments = await service.get_department_comparison()
trend = await service.get_learning_trend(7)
level_dist = await service.get_level_distribution()
activities = await service.get_realtime_activities(20)
course_ranking = await service.get_course_ranking(10)
return {
"code": 200,
"message": "success",
"data": {
"overview": overview,
"departments": departments,
"trend": trend,
"level_distribution": level_dist,
"activities": activities,
"course_ranking": course_ranking,
}
}