# API 接口文档 ## 基础信息 - **Base URL**: `http://127.0.0.1:5001` - **Content-Type**: `application/json` --- ## 认证接口 ### 检查登录状态 ``` GET /api/check-login ``` **响应示例**: ```json { "logged_in": true, "username": "admin", "role": "admin" } ``` ### 登录 ``` POST /api/login ``` **请求体**: ```json { "username": "admin", "password": "Admin@123" } ``` **响应示例**: ```json { "message": "登录成功" } ``` ### 登出 ``` POST /api/logout ``` ### 初始设置(首次) ``` GET /setup ``` ### 初始设置提交 ``` POST /api/setup ``` **请求体**: ```json { "username": "admin", "password": "Admin@123", "confirm_password": "Admin@123" } ``` ### 修改当前用户密码 ``` POST /api/users/change-password ``` **请求体**: ```json { "old_password": "Old@123", "new_password": "New@123", "confirm_password": "New@123" } ``` --- ## 用户管理(仅管理员) ### 获取用户列表 ``` GET /api/users ``` **响应示例**: ```json [ { "id": 1, "username": "admin", "name": "管理员", "role": "admin", "created_at": "2026-04-17 10:00" }, { "id": 2, "username": "teacher1", "name": "张老师", "role": "user", "created_at": "2026-04-18 10:00" } ] ``` ### 新增用户 ``` POST /api/users ``` **请求体**: ```json { "username": "newuser", "password": "User@123", "role": "user" } ``` **角色选项**: `admin`, `user` ### 编辑用户 ``` PUT /api/users/ ``` **请求体**: ```json { "name": "新姓名", "role": "user" } ``` > ⚠️ `username` 不可修改,密码通过单独接口修改 ### 重置用户密码 ``` POST /api/users//reset-password ``` **请求体**: ```json { "new_password": "Reset@123" } ``` ### 删除用户 ``` DELETE /api/users/ ``` --- ## 班级管理 ### 获取班级列表 ``` GET /api/classes ``` **权限**: 登录用户 **响应示例**: ```json [ { "id": 1, "name": "钢琴初级班", "level": "入门", "description": "入门学员", "teacher_id": 2, "teacher_name": "张老师", "student_count": 5, "active": true, "created_at": "2026-04-17 10:00" } ] ``` ### 新增班级 ``` POST /api/classes ``` **权限**: 管理员 **请求体**: ```json { "name": "钢琴中级班", "level": "入门", "description": "进阶学员", "teacher_id": 2 } ``` ### 编辑班级 ``` PUT /api/classes/ ``` **权限**: 管理员 **请求体**: ```json { "name": "钢琴中级班(2026)", "level": "入门", "description": "进阶学员", "teacher_id": 2, "active": true } ``` ### 删除班级 ``` DELETE /api/classes/ ``` **权限**: 管理员 ### 获取班级学员列表 ``` GET /api/classes//students ``` **权限**: 登录用户 **响应示例**: ```json [ { "id": 1, "name": "张三", "phone": "13800138000", "practice_time": "30分钟" } ] ``` ### 分配学员到班级 ``` POST /api/classes//assign ``` **权限**: 登录用户 **请求体**: ```json { "student_ids": [1, 2, 3] } ``` --- ### 批量分配目标给班级学员 ``` POST /api/classes//goals ``` **权限**: 登录用户 **请求体**: ```json { "goal_id": 1, "assessment_days": "30", "assessment_date": null, "start_date": null, "start_now": true } ``` | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | goal_id | int | 是 | 目标ID | | assessment_days | string | 否 | 评估天数(15/30/60/90/180) | | assessment_date | string | 否 | 评估日期(YYYY-MM-DD),与 assessment_days 二选一 | | start_date | string | 否 | 开始日期(YYYY-MM-DD) | | start_now | bool | 否 | 是否立即开始(默认true) | **响应示例**: ```json { "message": "成功分配 5 个学员", "assigned": 5, "skipped": ["李四", "王五"], "skipped_count": 2 } ``` --- ## 学员管理 ### 获取学员列表 ``` GET /api/students ``` **权限**: 登录用户 **响应示例**: ```json [ { "id": 1, "name": "张三", "phone": "13800138000", "wechat_nickname": "小张", "practice_time": "30分钟", "class_id": 1, "class_name": "钢琴初级班", "notes": "", "problem_count": 2, "plan_count": 1, "created_at": "2026-04-17 10:00" } ] ``` ### 创建学员 ``` POST /api/students ``` **权限**: 登录用户 **请求体**: ```json { "name": "学员姓名", "phone": "手机号", "wechat_nickname": "微信昵称", "practice_time": "30分钟", "class_id": 1, "notes": "备注信息" } ``` ### 获取学员详情 ``` GET /api/students/ ``` ### 更新学员 ``` PUT /api/students/ ``` **权限**: 登录用户 **请求体**: ```json { "name": "新姓名", "phone": "新手机号", "wechat_nickname": "新昵称", "practice_time": "45分钟", "class_id": 2, "notes": "新备注" } ``` ### 删除学员 ``` DELETE /api/students/ ``` --- ## 问题记录 ### 获取学员的问题列表 ``` GET /api/students//problems ``` ### 添加问题 ``` POST /api/students//problems ``` **请求体**: ```json { "problem_id": "01_手小", "problem_name": "手小", "severity": "中等", "level": "入门" } ``` **严重程度选项**: `轻微`, `中等`, `严重` **级别选项**: `启蒙`, `入门`, `进阶`, `熟练`, `精通` ### 删除问题 ``` DELETE /api/students//problems/ ``` --- ## 方案生成 ### 生成练习方案 ``` POST /api/generate-plan ``` **请求体**: ```json { "student_id": 1, "use_ai": true, "template_id": 1 } ``` **参数说明**: - `student_id`: 学员ID - `use_ai`: 是否使用AI生成个性化报告(默认true) - `template_id`: AI提示词模板ID(可选,不传则使用排序第一的默认模板) **AI提示词模板参数**: | 参数 | 说明 | |------|------| | `{student_name}` | 学员姓名 | | `{practice_time}` | 每日练习时间 | | `{problems}` | 学员问题列表(含严重程度、级别、建议练习时间) | | `{student_goals}` | 学员未达成的目标内容(Markdown格式) | | `{schedule_table}` | ~~每日练习安排表~~(已废弃,AI报告已包含) | **响应**: SSE 流,包含进度信息 **SSE 事件说明**: | step | 说明 | |------|------| | collecting | 收集问题数据 | | basic | 生成基础练习方案 | | basic_done | 基础方案生成完成 | | ai_config | AI配置信息 | | ai_start | 开始调用AI | | ai_problems | 发送给AI的问题摘要 | | ai_request | 等待AI响应 | | ai_prompt | AI提示词已生成(含字数) | | ai_generating | AI报告生成中 | | ai_response | AI响应已接收 | | ai_done | AI报告生成完成 | | saved | 方案已保存 | | complete | 全部完成 | **complete 事件包含**: ```json { "step": "complete", "prompt_length": 1234, "ai_report_length": 567, "plan_id": 1 } ``` --- ### 预览提示词 ``` POST /api/generate-plan/preview ``` **功能**: 根据学员ID和模板生成提示词,但不保存方案。用于在生成前预览提示词内容。 **请求体**: ```json { "student_id": 1, "template_id": 1 } ``` **响应示例**: ```json { "prompt": "根据学员张三的每日练习时间30分钟和以下问题,为其生成个性化练习方案...\n\n问题列表:\n1. 手小(中等)\n...", "prompt_length": 1234, "student_goals_length": 200, "problems_length": 150 } ``` **SSE 事件说明**: | step | 说明 | |------|------| | collecting | 收集数据 | | prompt_generated | 提示词已生成(含字数统计) | | complete | 预览完成 | --- ### 获取方案详情 ``` GET /api/plans/ ``` **响应示例**: ```json { "id": 1, "student_id": 1, "student_name": "张三", "template_name": "默认模板", "is_typical": false, "created_at": "2026-04-17 10:30", "updated_at": "2026-04-27 15:00", "updated_by_name": "管理员", "content": { "student_name": "张三", "practice_time": "30分钟", "total_daily_minutes": 30, "problems": [ {"name": "手小", "level": "入门", "severity": "中等"} ], "ai_report": "..." } } ``` > **注意**: `updated_at` 和 `updated_by_name` 仅在方案被编辑过后才会有值。 --- ### 获取学员方案列表 ``` GET /api/students//plans ``` --- ### 获取推荐方案列表 ``` GET /api/students//recommended-plans ``` **参数**: | 参数 | 类型 | 说明 | |------|------|------| | filter | string | 筛选条件:`all`(全部)或 `mine`(我的) | **响应示例**: ```json [ { "id": 5, "student_name": "李四", "template_name": "默认模板", "is_typical": true, "created_at": "2026-04-20 10:00", "problem_names": ["手小", "识谱慢"], "can_adopt": true, "adopted": false } ] ``` --- ### 采纳典型方案 ``` POST /api/plans//adopt ``` **请求体**: ```json { "student_id": 1 } ``` **响应**: ```json { "message": "方案已采纳", "plan_id": 6 } ``` --- ### 更新方案内容 ``` PUT /api/plans//content ``` **功能**: 编辑方案后保存内容 **请求体**: ```json { "content": "{\"ai_report\": \"...\", \"daily_schedule\": [...]}" } ``` **响应**: ```json { "message": "保存成功" } ``` --- ### 设为典型方案 ``` POST /api/plans//typical ``` **响应**: ```json { "success": true, "is_typical": true } ``` --- ### 删除方案 ``` DELETE /api/plans/ ``` ### 导出PDF ``` GET /api/plans//pdf ``` **参数**: | 参数 | 类型 | 说明 | |------|------|------| | template_id | int | 报告模板ID(可选,不传则使用排序第一的默认模板) | **返回**: PDF文件下载 ### 导出Markdown ``` GET /api/plans//md ``` **参数**: | 参数 | 类型 | 说明 | |------|------|------| | template_id | int | 报告模板ID(可选,不传则使用排序第一的默认模板) | **返回**: Markdown文件下载 ### 微信卡片展示 ``` GET /plans//wechat ``` **返回**: HTML页面,用于微信分享 --- ## 问题配置(仅管理员) ### 获取问题列表 ``` GET /api/problems ``` ### 获取问题详情 ``` GET /api/problems/ ``` ### 创建问题 ``` POST /api/problems ``` ### 更新问题 ``` PUT /api/problems/ ``` ### 删除问题 ``` DELETE /api/problems/ ``` --- ## API设置(仅管理员) ### 获取API配置 ``` GET /api/config ``` ### 更新API配置 ``` POST /api/config ``` ### 测试API连接 ``` POST /api/config/test ``` --- ## 目标管理 API ### GET /api/goals 获取所有目标 **响应**: ```json [ { "id": 1, "name": "掌握基本音阶", "content": "...", "created_at": "2026-04-23T10:00:00", "updated_at": "2026-04-23T10:00:00" } ] ``` ### POST /api/goals 创建新目标 **请求体**: ```json { "name": "目标名称", "content": "目标内容(Markdown)" } ``` ### GET /api/goals/{id} 获取单个目标 ### PUT /api/goals/{id} 更新目标 ### DELETE /api/goals/{id} 删除目标(仅管理员) **权限**: 仅管理员 **依赖检查**:如果存在以下依赖关系,禁止删除: - 已被学员分配的目标 - 作为父目标或子目标被其他目标关联 **错误响应示例**: ```json {"error": "无法删除:已被 3 名学员分配, 有 2 个子目标关联"} ``` ### GET /api/goals/{id}/children 获取目标的子目标 ### GET /api/goals/{id}/parents 获取目标的父目标 ### POST /api/goals/{id}/children 添加子目标关联(含循环检测) **请求体**: ```json { "child_goal_id": 2 } ``` ### DELETE /api/goals/{id}/children/{child_id} 移除子目标关联 ## 学员目标 API ### GET /api/students/{id}/goals 获取学员的所有目标 **响应**: ```json [ { "id": 1, "student_id": 1, "goal_id": 1, "goal_name": "掌握基本音阶", "goal_content": "目标详细描述内容(Markdown)...", "goal_level": "入门", "goal_category": "演奏能力", "status": "进行中", "start_date": "2026-04-01T00:00:00", "assessment_date": "2026-05-01T00:00:00", "mastery_level": 3, "achievement_date": null, "comment": null, "created_at": "2026-04-01T10:00:00" } ] ``` **排序**:按状态(进行中→未开始→已结束),再按评估日期倒序 ### POST /api/students/{id}/goals 为学员分配目标 **请求体**: ```json { "goal_id": 1, "assessment_days": 30, "assessment_date": "2026-05-01", "start_date": "2026-04-01", "start_now": true } ``` | 字段 | 类型 | 说明 | |------|------|------| | goal_id | Integer | 目标ID,必填 | | assessment_days | Integer | 评估天数(15/30/60/90/180),与 assessment_date 二选一 | | assessment_date | String | 具体评估日期(ISO格式),与 assessment_days 二选一 | | start_date | String | 开始日期(ISO格式),可选 | | start_now | Boolean | 设为 true 表示立即开始(默认当前时间) | ### PUT /api/students/{id}/goals/{goal_id} 更新学员目标 **请求体**: ```json { "start_date": "2026-04-01", "assessment_date": "2026-05-01", "mastery_level": 4, "achievement_date": "2026-05-01", "comment": "表现优秀,已掌握" } ``` | 字段 | 类型 | 说明 | |------|------|------| | start_date | String | 开始日期(ISO格式) | | assessment_date | String | 评估日期(ISO格式) | | mastery_level | Integer | 掌握程度 1-5 | | achievement_date | String | 达成日期(ISO格式) | | comment | String | 评语 | ### DELETE /api/students/{id}/goals/{goal_id} 移除学员的目标(仅管理员,会级联删除关联的评估记录) **权限**: 仅管理员 --- ## 学员目标评估 API ### GET /api/students/{id}/evaluations 获取学员的所有评估记录 **响应**: ```json [ { "id": 1, "student_goal_id": 1, "goal_name": "掌握基本音阶", "evaluator_id": 1, "evaluator_name": "管理员", "assessment_date": "2026-04-15", "mastery_level": 3, "comment": "进步明显", "is_final": false, "created_at": "2026-04-15T10:00:00" } ] ``` ### POST /api/students/{id}/evaluations 创建评估记录 **请求体**: ```json { "student_goal_id": 1, "assessment_date": "2026-04-15", "mastery_level": 3, "comment": "进步明显", "is_final": false } ``` | 字段 | 类型 | 说明 | |------|------|------| | student_goal_id | Integer | 学员目标ID | | assessment_date | String | 评估日期(YYYY-MM-DD) | | mastery_level | Integer | 掌握程度 1-5 | | comment | String | 评语 | | is_final | Boolean | 是否为最终评估 | ### PUT /api/evaluations/{id} 更新评估记录 **请求体**: ```json { "assessment_date": "2026-04-16", "mastery_level": 4, "comment": "已完全掌握", "is_final": true } ``` ### DELETE /api/evaluations/{id} 删除评估记录 --- ## 模板管理 API ### GET /templates/templates 获取所有模板(按sort_order排序) **参数**: | 参数 | 类型 | 说明 | |------|------|------| | type | string | 可选,按类型筛选(`ai_prompt`/`report`) | **响应**: ```json [ { "id": 1, "name": "AI提示词模板", "type": "ai_prompt", "description": "生成练习方案时发送给AI的提示词", "content": "...", "sort_order": 0, "created_at": "2026-04-23T10:00:00" }, { "id": 2, "name": "报告导出模板", "type": "report", "description": "导出方案时使用的Markdown模板", "content": "...", "sort_order": 0, "created_at": "2026-04-23T10:00:00" } ] ``` ### GET /templates/templates/{id} 获取单个模板 ### POST /templates/templates 创建模板 **请求体**: ```json { "name": "新模板名称", "type": "ai_prompt", "content": "模板内容...", "description": "模板描述", "sort_order": 1 } ``` | 字段 | 类型 | 说明 | |------|------|------| | name | String | 模板名称 | | type | String | 类型:`ai_prompt`(AI提示词)或 `report`(报告导出) | | content | String | 模板内容(Markdown格式) | | description | String | 描述 | | sort_order | Integer | 排序序号(越小越靠前) | ### PUT /templates/templates/{id} 更新模板 ### DELETE /templates/templates/{id} 删除模板 ### POST /templates/templates/{type}/render 渲染模板预览 **参数**: `type` 为 `ai_prompt` 或 `report` **请求体**:用于替换模板中的变量 ```json { "student_name": "张三", "practice_time": "30分钟", "problems": "...", "student_goals": "..." } ``` **响应**: ```json { "rendered": "渲染后的内容..." } ``` --- --- ## 数据统计 API ### GET /api/statistics/students 获取学员统计数据。 **权限**: 登录用户 **筛选参数**: | 参数 | 类型 | 说明 | |------|------|------| | mine | bool | 是否只看当前用户负责的班级(true/false) | | class_id | int | 筛选特定班级 | **响应示例**: ```json { "total_students": 15, "total_problems": 42, "level_distribution": {"启蒙": 3, "入门": 8, "进阶": 4, "熟练": 0, "精通": 0}, "severity_distribution": {"轻微": 12, "中等": 25, "严重": 5}, "class_student_count": [ {"class_id": 1, "class_name": "钢琴初级班", "level": "入门", "student_count": 8} ], "class_problem_count": [ {"class_id": 1, "class_name": "钢琴初级班", "problem_count": 20} ], "problem_level_matrix": { "轻微": {"启蒙": 2, "入门": 6, "进阶": 3, "熟练": 1, "精通": 0}, "中等": {"启蒙": 1, "入门": 2, "进阶": 1, "熟练": 0, "精通": 0}, "严重": {"启蒙": 0, "入门": 0, "进阶": 0, "熟练": 0, "精通": 0} }, "problem_name_distribution": {"手小": 5, "识谱慢": 8}, "classes": [{"id": 1, "name": "钢琴初级班"}] } ``` --- ## 权限说明 | 接口 | 管理员 | 普通用户 | |------|--------|----------| | 用户管理 | ✅ | ❌ | | 班级增删改 | ✅ | ❌ | | 班级查询/分配学员 | ✅ | ✅ | | 学员管理 | ✅ | ✅ | | 问题记录 | ✅ | ✅ | | 方案生成/预览 | ✅ | ✅ | | 模板管理 | ✅ | ❌ | | 系统设置 | ✅ | ❌ | | 修改自己密码 | ✅ | ✅ | --- ## 错误响应 所有接口的错误响应格式: ```json { "error": "错误信息描述" } ``` 状态码: - `400` - 请求参数错误 - `401` - 未登录或认证失败 - `403` - 权限不足 - `404` - 资源不存在 - `500` - 服务器内部错误