Files

1141 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/<id>
```
**请求体**:
```json
{
"name": "新姓名",
"role": "user"
}
```
> ⚠️ `username` 不可修改,密码通过单独接口修改
### 重置用户密码
```
POST /api/users/<id>/reset-password
```
**请求体**:
```json
{
"new_password": "Reset@123"
}
```
### 删除用户
```
DELETE /api/users/<id>
```
---
## 班级管理
### 获取班级列表
```
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/<id>
```
**权限**: 管理员
**请求体**:
```json
{
"name": "钢琴中级班(2026",
"level": "入门",
"description": "进阶学员",
"teacher_id": 2,
"active": true
}
```
### 删除班级
```
DELETE /api/classes/<id>
```
**权限**: 管理员
### 获取班级学员列表
```
GET /api/classes/<id>/students
```
**权限**: 登录用户
**响应示例**:
```json
[
{
"id": 1,
"name": "张三",
"phone": "13800138000",
"practice_time": "30分钟"
}
]
```
### 分配学员到班级
```
POST /api/classes/<id>/assign
```
**权限**: 登录用户
**请求体**:
```json
{
"student_ids": [1, 2, 3]
}
```
---
### 批量分配目标给班级学员
```
POST /api/classes/<id>/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/<id>
```
### 更新学员
```
PUT /api/students/<id>
```
**权限**: 登录用户
**请求体**:
```json
{
"name": "新姓名",
"phone": "新手机号",
"wechat_nickname": "新昵称",
"practice_time": "45分钟",
"class_id": 2,
"notes": "新备注"
}
```
### 删除学员
```
DELETE /api/students/<id>
```
---
## 问题记录
### 获取学员的问题列表
```
GET /api/students/<student_id>/problems
```
### 添加问题
```
POST /api/students/<student_id>/problems
```
**请求体**:
```json
{
"problem_id": "01_手小",
"problem_name": "手小",
"severity": "中等",
"level": "入门"
}
```
**严重程度选项**: `轻微`, `中等`, `严重`
**级别选项**: `启蒙`, `入门`, `进阶`, `熟练`, `精通`
### 删除问题
```
DELETE /api/students/<student_id>/problems/<problem_id>
```
---
## 方案生成
### 生成练习方案
```
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/<plan_id>
```
**响应示例**:
```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/<student_id>/plans
```
---
### 获取推荐方案列表
```
GET /api/students/<student_id>/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/<plan_id>/adopt
```
**请求体**:
```json
{
"student_id": 1
}
```
**响应**:
```json
{
"message": "方案已采纳",
"plan_id": 6
}
```
---
### 更新方案内容
```
PUT /api/plans/<plan_id>/content
```
**功能**: 编辑方案后保存内容
**请求体**:
```json
{
"content": "{\"ai_report\": \"...\", \"daily_schedule\": [...]}"
}
```
**响应**:
```json
{
"message": "保存成功"
}
```
---
### 设为典型方案
```
POST /api/plans/<plan_id>/typical
```
**响应**:
```json
{
"success": true,
"is_typical": true
}
```
---
### 删除方案
```
DELETE /api/plans/<plan_id>
```
### 导出PDF
```
GET /api/plans/<plan_id>/pdf
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| template_id | int | 报告模板ID(可选,不传则使用排序第一的默认模板) |
**返回**: PDF文件下载
### 导出Markdown
```
GET /api/plans/<plan_id>/md
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| template_id | int | 报告模板ID(可选,不传则使用排序第一的默认模板) |
**返回**: Markdown文件下载
### 微信卡片展示
```
GET /plans/<plan_id>/wechat
```
**返回**: HTML页面,用于微信分享
---
## 问题配置(仅管理员)
### 获取问题列表
```
GET /api/problems
```
### 获取问题详情
```
GET /api/problems/<problem_id>
```
### 创建问题
```
POST /api/problems
```
### 更新问题
```
PUT /api/problems/<problem_id>
```
### 删除问题
```
DELETE /api/problems/<problem_id>
```
---
## 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` - 服务器内部错误