Some checks failed
continuous-integration/drone/push Build is failing
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 格式
8.7 KiB
8.7 KiB
KPL 考培练系统 功能迭代更新日志
日期: 2026-01-29
版本: v1.5.0
一、奖章条件优化
修复内容
- 修复
badge_service.py中统计查询的 SQL 语法问题 - 将非标准
func.if_替换为 SQLAlchemy 标准case语句 - 优化考试统计逻辑:通过数、满分数、优秀数分开查询
- 添加
func.coalesce处理空值
新增功能
check_badges_by_category()- 按类别检查奖章check_exam_badges()- 考试后触发check_practice_badges()- 练习后触发check_streak_badges()- 签到后触发check_level_badges()- 等级变化后触发
文件变更
backend/app/services/badge_service.py
二、移动端适配
适配页面
| 页面 | 文件 | 适配要点 |
|---|---|---|
| 登录页 | views/login/index.vue |
表单全宽、背景动画隐藏、钉钉安全区域 |
| 课程中心 | views/trainee/course-center.vue |
单列卡片、分类横向滚动、操作按钮网格化 |
| 课程详情 | views/trainee/course-detail.vue |
侧边栏折叠、视频自适应、工具栏响应式 |
| 考试页面 | views/exam/practice.vue |
选项垂直排列、按钮放大、弹窗全屏 |
| 成长路径 | views/trainee/growth-path.vue |
雷达图缩放、卡片堆叠、统计区折叠 |
| 排行榜 | views/trainee/leaderboard.vue |
列表简化、签到按钮全宽 |
技术方案
- 使用
@media (max-width: 768px)和@media (max-width: 480px)断点 - 钉钉环境使用
env(safe-area-inset-*)适配安全区域
三、证书系统
数据库设计
-- 证书模板表
CREATE TABLE certificate_templates (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
type ENUM('course', 'exam', 'achievement') NOT NULL,
background_url VARCHAR(500),
template_html TEXT,
template_style TEXT,
is_active BOOLEAN DEFAULT TRUE,
...
);
-- 用户证书表
CREATE TABLE user_certificates (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
template_id INT NOT NULL,
certificate_no VARCHAR(50) UNIQUE NOT NULL,
title VARCHAR(200) NOT NULL,
...
);
后端实现
- 模型:
CertificateTemplate,UserCertificate,CertificateType - 服务:
CertificateServiceissue_course_certificate()- 颁发课程证书issue_exam_certificate()- 颁发考试证书issue_achievement_certificate()- 颁发成就证书generate_certificate_image()- 生成分享图片get_certificate_by_no()- 验证证书
API 端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /certificates/me |
我的证书列表 |
| GET | /certificates/{id} |
证书详情 |
| GET | /certificates/{id}/image |
获取分享图片 |
| GET | /certificates/{id}/download |
下载证书 |
| GET | /certificates/verify/{no} |
验证证书(无需登录) |
| POST | /certificates/issue/course |
颁发课程证书 |
| POST | /certificates/issue/exam |
颁发考试证书 |
前端实现
- API:
frontend/src/api/certificate.ts - 页面:
frontend/src/views/trainee/my-certificates.vue - 功能: 证书列表、分类筛选、预览、分享、下载
文件变更
backend/migrations/add_certificate_system.sql(新增)backend/app/models/certificate.py(新增)backend/app/services/certificate_service.py(新增)backend/app/api/v1/endpoints/certificate.py(新增)backend/app/models/__init__.py(修改)backend/app/api/v1/__init__.py(修改)frontend/src/api/certificate.ts(新增)frontend/src/views/trainee/my-certificates.vue(新增)frontend/src/router/index.ts(修改)
四、数据大屏
数据指标
| 类别 | 指标 |
|---|---|
| 概览 | 总学员数、今日活跃、周活跃、月活跃、总学习时长、签到率 |
| 考试 | 总次数、通过率、平均分、满分人数 |
| 部门 | 成员数、通过率、平均学习时长、平均等级 |
| 趋势 | 近7天活跃用户、学习时长、考试次数 |
| 分布 | 1-10级用户数量分布 |
| 动态 | 最新学习活动实时滚动 |
后端实现
- 服务:
DashboardServiceget_enterprise_overview()- 企业级概览get_department_comparison()- 部门对比get_learning_trend()- 学习趋势get_level_distribution()- 等级分布get_realtime_activities()- 实时动态get_team_dashboard()- 团队级数据get_course_ranking()- 课程热度排行
API 端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /dashboard/enterprise/overview |
企业概览 |
| GET | /dashboard/enterprise/departments |
部门对比 |
| GET | /dashboard/enterprise/trend |
学习趋势 |
| GET | /dashboard/enterprise/level-distribution |
等级分布 |
| GET | /dashboard/enterprise/activities |
实时动态 |
| GET | /dashboard/enterprise/course-ranking |
课程排行 |
| GET | /dashboard/team |
团队数据 |
| GET | /dashboard/all |
完整数据(一次性) |
前端实现
- API:
frontend/src/api/dashboard.ts - 页面:
frontend/src/views/admin/data-dashboard.vue - 图表: ECharts (横向柱状图、折线图、仪表盘、饼图)
- 功能: 全屏模式、5分钟自动刷新、响应式布局
文件变更
backend/app/services/dashboard_service.py(新增)backend/app/api/v1/endpoints/dashboard.py(新增)backend/app/api/v1/__init__.py(修改)frontend/src/api/dashboard.ts(新增)frontend/src/views/admin/data-dashboard.vue(新增)frontend/src/router/index.ts(修改)
部署说明
数据库迁移
需执行以下 SQL 脚本:
# 证书系统迁移
mysql -u root -p kaopeilian < backend/migrations/add_certificate_system.sql
依赖安装
后端新增依赖(用于证书图片生成):
pip install Pillow qrcode
路由变更
新增前端路由:
/trainee/my-certificates- 我的证书/manager/data-dashboard- 数据大屏
五、错误提示优化(下午更新)
课程名重复错误优化
问题:创建课程时名称重复返回 409 错误,前端提示不明确
修复内容:
- 后端
course_service.py:课程名重复时返回existing_id和existing_name - 前端
edit-course.vue:检测 409 错误后弹出确认框- "查看已有课程" → 跳转到已存在的课程
- "修改名称" → 留在当前页面
通用错误处理增强
errorHandler.ts新增 409 冲突错误处理- 新增工具函数:
isConflictError(),getConflictDetail(),getConflictMessage()
其他页面错误提示优化
position-management.vue:岗位创建/编辑错误提取详细信息user-management.vue:用户编辑错误提取详细信息
文件变更
backend/app/services/course_service.py(修改)frontend/src/utils/errorHandler.ts(修改)frontend/src/views/manager/edit-course.vue(修改)frontend/src/views/admin/position-management.vue(修改)frontend/src/views/admin/user-management.vue(修改)
六、部署问题修复(下午更新)
后端导入路径修复
certificate.py模型:from app.core.database import Base→from app.models.base import Basecertificate.pyAPI:from app.core.database import get_db→from app.core.deps import get_dbdashboard.pyAPI:同上- 合并
get_current_user导入到app.core.deps
依赖安装
docker exec kpl-backend-dev pip install Pillow qrcode
前端构建同步问题
- 问题:构建输出到
/root/aiedu/frontend/dist/,但容器挂载的是/root/aiedu/dist-test/ - 解决:构建后需手动同步
cp -r /root/aiedu/frontend/dist/* /root/aiedu/dist-test/
七、钉钉免密登录问题修复(下午更新)
问题现象
- 钉钉环境打开应用后显示"没有访问此页面的权限"
- 后端日志显示登录实际成功
问题原因
登录成功后读取 URL 中的 redirect 参数跳转,但该参数指向用户无权限的页面(如 /admin/*)
修复内容
login/index.vue:登录成功后检查 redirect 目标是否有权限
// 检查 redirect 目标是否有权限访问
if ((redirect.startsWith('/admin') && userRole !== 'admin') ||
(redirect.startsWith('/manager') && !['admin', 'manager'].includes(userRole))) {
redirect = defaultRoute // 改为跳转到默认页面
}
调试工具
- 钉钉环境自动启用 vConsole(
main.ts中根据 UA 判断) - 依赖:
npm install vconsole
待办事项
- 证书 PDF 生成(需安装 weasyprint)
- 课程完成进度追踪(user_course_progress 表)
- 数据大屏数据缓存优化
- 钉钉环境下底部导航适配
- 移除 vConsole 调试代码(问题确认解决后)