Skip to content

09_用户与账号管理 API 设计(学生/老师/学校管理员/平台管理员)

目标:提供统一的用户与账号管理接口,满足"平台管理员 > 学校管理员 > 老师 > 学生"的分级权限要求。

  • 学生:不能创建/删除/修改账号(仅允许补充个人展示信息如头像、真实姓名)。
  • 老师:管理自己班级学生(增删班级成员、重置学生密码、查看学生信息),不能越权到其他班级或学校。
  • 学校管理员:管理本校老师与学生账号(创建、禁用、启用、重置密码、分配班级、指派班主任/授课老师)。
  • 平台管理员:管理全平台账号及学校、跨校迁移等高级操作。

1. 角色与术语

  • 角色(与 app/models/user.py 对齐):

    • student:学生
    • teacher:教师
    • school_admin:学校管理员
    • platform_admin:平台管理员
  • 组织对象

    • schools:学校
    • classes:教学班(隶属学校)
  • 关系对象

    • class_members:学生-班级关系
    • class_teachers:教师-班级关系

2. 资源与命名

  • 主资源users
  • 子资源
    • /users/{user_id}/profile:用户可维护的少量自我信息(头像、真实姓名)
    • /schools/{school_id}/users:作用域内的用户管理(学校管理员)
    • 班级与学校管理接口已迁移:详见《13_School_API》《14_Class_API》

2.1 学生个人成就(新增)

  • GET /users/{user_id}/achievements
    • 说明:统计学生个人成就
    • 口径
      • total_assignments_submitted:该学生提交过的不同作业数量(按 assignment 去重)
      • completed_courses:对该学生所在班级发布的某课程,若该课程所有已发布作业均已提交,则该课程计为完成
    • 权限:学生本人/管理员可查(老师权限可按需细化)
    • 响应示例
      json
      {
        "total_assignments_submitted": 23,
        "completed_courses": 4
      }

3. 权限原则(概览)

  • 学生(student)

    • 仅能读自己的信息
    • 不可创建/删除/修改账号
    • 可编辑 real_nameavatar_url(若系统策略允许)
    • 上级为教师或学校管理员(parent_user_id 指向创建者)
  • 老师(teacher)

    • 可管理自己任教班级内学生(添加/移除班级成员、重置学生密码、查看学生信息)
    • 不可在非任教班级或其他学校执行写操作
    • 上级为学校管理员(parent_user_id 指向学校管理员)
  • 学校管理员(school_admin)

    • 可在本学校范围创建/更新/禁用老师与学生账号
    • 可为老师/学生分配班级
    • 可重置密码
    • 不可跨校操作
    • 不可授予平台管理员角色
    • 上级为平台管理员(parent_user_id 指向平台管理员)
  • 平台管理员(platform_admin)

    • 可管理所有学校与所有用户
    • 可执行跨校迁移、删除账号、角色调整
    • 可授予/撤销学校管理员角色
    • 可管理学校信息
    • 没有上级(parent_user_idnull

4. 权限矩阵

资源/操作匿名学生老师学校管理员平台管理员
列表用户 /users××限本班学生本校范围全平台
获取用户 /users/{id}×仅本人本班学生本校用户全平台
创建学生 /schools/{id}/users:student×××✓(本校)✓(任意校)
创建老师 /schools/{id}/users:teacher×××✓(本校)✓(任意校)
创建学校管理员 /schools/{id}/users:school_admin××××✓(任意校)
更新用户基础字段×仅本人profile本班学生受限本校用户全平台
重置密码 /users/{id}:reset_password××本班学生本校用户全平台
禁用/启用 /users/{id}:status×××本校用户全平台
删除账号 /users/{id}×××本校用户(可配置仅停用)全平台
班级成员管理 /classes/{id}/members××✓(任教班)本校全平台
班级教师管理 /classes/{id}/teachers××仅本人查看/退出本校全平台
学校管理 /schools×××仅查看本校全平台

注:实际实现中,删除账号通常建议采用"软删除/停用(disabled)"以保留历史关联数据。


5. 数据模型(对齐现有模型)

  • usersid, username, password_hash, role, school_id, parent_user_id?, real_name?, avatar_url?, created_at
  • schoolsid, name, region?, logo_url?, created_at
  • classesid, school_id, name, edu_year?, created_at
  • class_membersid, class_id, user_id, joined_at
  • class_teachersid, class_id, teacher_id, role

扩展建议

  • users.disabled: bool(是否停用)
  • users.require_password_reset: bool(下次登录需改密)

上级关系说明

  • parent_user_id 表示用户的直接上级账号ID,用于权限继承和管理关系
  • 权限层级:学生 → 教师 → 学校管理员 → 平台管理员
  • 每个用户只能有一个直接上级,形成树状权限结构
  • 平台管理员没有上级,parent_user_idnull

6. 路由设计

6.1 用户查询接口

6.1.1 通用用户查询

  • GET /users

    • 权限
      • 老师:默认返回自己任教班级学生,支持 class_id 精确过滤;禁止跨校
      • 学校管理员:本校范围用户;支持 roleq(用户名/真实名模糊)、分页
      • 平台管理员:全平台;同上
    • 查询参数
      • role?=student|teacher|school_admin
      • school_id?
      • class_id?
      • q?(搜索关键词)
      • page?=1
      • size?=20
    • 响应示例
      json
      {
        "items": [
          {
            "id": 1,
            "username": "stu_001",
            "real_name": "张三",
            "role": "student",
            "school_id": 1,
            "avatar_url": null,
            "created_at": "2025-01-01T00:00:00Z",
            "parent_user_id": 15
          }
        ],
        "total": 100,
        "page": 1,
        "size": 20
      }
  • GET /users/{user_id}

    • 权限:本人/本班(老师)/本校(学校管理员)/全平台(平台管理员)
    • 响应:单个用户详细信息(脱敏)

6.1.2 专门的角色列表接口

  • GET /users/students

    • 权限:老师(本班学生)/学校管理员(本校)/平台管理员(全平台)
    • 查询参数
      • school_id?:学校ID(老师必填,管理员可选)
      • class_id?:班级ID(老师必填,管理员可选)
      • q?:搜索关键词
      • page?=1
      • size?=20
    • 说明:专门用于获取学生列表,支持按学校、班级筛选
  • GET /users/teachers

    • 权限:学校管理员(本校)/平台管理员(全平台)
    • 查询参数
      • school_id?:学校ID(学校管理员必填,平台管理员可选)
      • class_id?:班级ID(可选,查看某班级的任课教师)
      • q?:搜索关键词
      • page?=1
      • size?=20
    • 说明:专门用于获取教师列表
  • GET /users/school_admins

    • 权限:平台管理员
    • 查询参数
      • school_id?:学校ID(可选)
      • q?:搜索关键词
      • page?=1
      • size?=20
    • 说明:专门用于获取学校管理员列表
  • GET /users/platform_admins

    • 权限:平台管理员
    • 查询参数
      • q?:搜索关键词
      • page?=1
      • size?=20
    • 说明:专门用于获取平台管理员列表

6.2 用户创建接口(限制自助注册)

6.2.1 创建学生账号

  • POST /schools/{school_id}/users:student
    • 说明:创建本校学生账号;禁止学生自建
    • 权限:学校管理员/平台管理员
    • 请求示例
      json
      {
        "username": "stu_001",
        "password": "Init@123",
        "real_name": "张三",
        "class_ids": [101, 102]
      }
    • 说明parent_user_id 由系统自动设置为当前创建者(学校管理员或平台管理员)的ID
    • 响应:201 + 用户对象(脱敏)

6.2.2 创建教师账号

  • POST /schools/{school_id}/users:teacher
    • 说明:创建本校教师账号;支持指定任教班级
    • 权限:学校管理员/平台管理员
    • 请求示例
      json
      {
        "username": "t_zhang",
        "password": "Init@123",
        "real_name": "张老师",
        "class_ids": [101]
      }
    • 说明parent_user_id 由系统自动设置为当前创建者(学校管理员或平台管理员)的ID
    • 响应:201 + 用户对象(脱敏)

6.2.3 创建学校管理员账号

  • POST /schools/{school_id}/users:school_admin
    • 说明:创建学校管理员账号
    • 权限:仅平台管理员
    • 请求示例
      json
      {
        "username": "admin_001",
        "password": "Admin@123",
        "real_name": "李主任"
      }
    • 说明parent_user_id 由系统自动设置为当前创建者(平台管理员)的ID
    • 响应:201 + 用户对象(脱敏)

6.3 用户更新与状态管理

6.3.1 更新用户信息

  • PUT /users/{user_id}
    • 权限
      • 学生:仅本人且字段限于 real_name, avatar_url
      • 老师:仅本班学生有限字段(例如 real_name),不含 role/school_id/username
      • 学校管理员:本校用户,可更新基础字段,不含 role=platform_admin
      • 平台管理员:无限制
    • 请求示例
      json
      {
        "real_name": "张三丰",
        "avatar_url": "/static/avatars/001.jpg"
      }

6.3.2 重置用户密码

  • POST /users/{user_id}:reset_password
    • 权限:老师(本班学生)、学校管理员(本校用户)、平台管理员
    • 入参
      json
      {
        "new_password": "NewPass@123"
      }
    • :空参数(系统生成并返回临时密码)

6.3.3 启用/禁用账号

  • POST /users/{user_id}:status
    • 作用:启用/禁用账号(软删除)
    • 权限:学校管理员(本校用户)/平台管理员
    • 入参
      json
      {
        "disabled": true,
        "reason": "违反校规"
      }

6.3.4 删除账号

  • DELETE /users/{user_id}
    • 权限:建议仅平台管理员可硬删除;学校管理员默认以停用代替
    • 说明:删除前会检查关联数据,如有课程、作业等关联则拒绝删除

6.4 班级成员与教师管理

6.4.1 班级成员管理

  • GET /classes/{class_id}/members

    • 权限:任教老师/学校管理员/平台管理员
    • 响应:班级学生列表
  • POST /classes/{class_id}/members

    • 说明:添加学生到班级(批量)
    • 权限:任教老师(限本班)/学校管理员(本校)/平台管理员
    • 入参
      json
      {
        "user_ids": [1, 2, 3]
      }
    • json
      {
        "username_list": ["stu_1", "stu_2"]
      }
  • DELETE /classes/{class_id}/members/{user_id}

    • 权限:同上;用于移除班级学生

6.4.2 班级教师管理

  • GET /classes/{class_id}/teachers

    • 权限:任教老师/学校管理员/平台管理员
    • 响应:班级教师列表
  • POST /classes/{class_id}/teachers

    • 说明:指派老师到班级
    • 权限:学校管理员/平台管理员
    • 入参
      json
      {
        "teacher_id": 7,
        "role": "instructor"
      }
  • DELETE /classes/{class_id}/teachers/{teacher_id}

    • 权限:学校管理员/平台管理员 或 教师本人退出本班(仅影响映射关系)

6.5 学校管理接口(平台管理员专用)

6.5.1 学校管理

  • GET /schools

    • 权限:学校管理员(仅本校)/平台管理员(全平台)
    • 查询参数
      • q?:学校名称搜索
      • region?:地区筛选
      • page?=1
      • size?=20
  • POST /schools

    • 说明:创建新学校
    • 权限:仅平台管理员
    • 请求示例
      json
      {
        "name": "新希望中学",
        "region": "北京市朝阳区"
      }
  • PUT /schools/{school_id}

    • 说明:更新学校信息
    • 权限:学校管理员(本校)/平台管理员(全平台)
  • DELETE /schools/{school_id}

    • 说明:删除学校(需检查是否有关联用户)
    • 权限:仅平台管理员

6.5.2 学校管理员管理

  • GET /schools/{school_id}/admins

    • 说明:获取指定学校的管理员列表
    • 权限:平台管理员
    • 响应:学校管理员列表
  • POST /schools/{school_id}/admins

    • 说明:为学校指派管理员
    • 权限:仅平台管理员
    • 请求示例
      json
      {
        "user_id": 123,
        "role": "school_admin"
      }
  • DELETE /schools/{school_id}/admins/{user_id}

    • 说明:撤销学校管理员权限
    • 权限:仅平台管理员
  • GET /branding/me

    • 说明:返回当前登录用户所属学校的品牌信息
    • 权限:登录用户
    • 响应示例
      json
      { "school_id": 3, "logo_url": "/static/images/schools/3/a1b2c3.png" }
  • GET /schools/{school_id}/branding

    • 说明:读取指定学校品牌信息
    • 权限:学校管理员(本校)/平台管理员
    • 响应示例
      json
      { "school_id": 3, "logo_url": "/static/images/schools/3/a1b2c3.png" }
  • PUT /schools/{school_id}/branding

    • 说明:更新品牌信息(当前仅支持 logo_url);通常用于“先上传图片得到 URL,再回写”场景
    • 权限:学校管理员(本校)/平台管理员
    • 请求示例
      json
      { "logo_url": "/static/images/schools/3/a1b2c3.png" }
    • 响应:同上
  • POST /schools/{school_id}/branding/logo

    • 说明:一体化上传并设置学校 Logo(multipart 上传图片,服务端保存后直接写入 schools.logo_url
    • 权限:学校管理员(本校)/平台管理员
    • 请求multipart/form-data,字段名 file,支持 .png/.jpg/.jpeg/.webp/.gif/.bmp
    • 响应示例
      json
      { "school_id": 3, "logo_url": "/static/images/schools/3/fe21ac.png" }

7. 响应与脱敏

7.1 用户对象脱敏

  • 用户对象对外统一脱敏:不返回 password_hash
  • 建议统一返回:{"id","username","real_name","avatar_url","role","school_id","parent_user_id","created_at"}
  • 敏感操作(如重置密码)返回临时密码时需特殊处理
  • parent_user_id 字段用于显示用户的上级关系,有助于权限管理

7.2 错误码规范

  • 401:未认证
  • 403:权限不足
  • 404:资源不存在
  • 400:参数错误
  • 409:冲突(用户名已存在/关系已存在)
  • 422:数据验证失败

8. 安全与审计建议

8.1 密码安全

  • 强制密码复杂度与最小长度(建议:8位以上,包含大小写字母、数字、特殊字符)
  • 重置密码默认 require_password_reset = true
  • 密码历史记录(防止重复使用)

8.2 操作审计

  • 所有敏感操作(创建/重置密码/禁用/删除)写入 token_log 或审计日志表
  • 记录操作人、操作时间、操作类型、操作对象、操作结果

8.3 接口安全

  • 接口速率限制与防暴力破解:登录/重置密码相关接口需限流与告警
  • 敏感操作需要二次确认(如删除账号)
  • 跨域访问控制

9. 请求/响应示例

9.1 创建学生账号

bash
# 学校管理员创建学生
curl -X POST http://localhost:8000/schools/3/users:student \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "s001",
    "password": "Init@123",
    "real_name": "张三",
    "class_ids": [101]
  }'

响应(201)

json
{
  "id": 201,
  "username": "s001",
  "real_name": "张三",
  "role": "student",
  "school_id": 3,
  "avatar_url": null,
  "created_at": "2025-01-01T10:00:00Z",
  "parent_user_id": 15
}

9.2 获取学生列表

bash
# 老师获取本班学生列表
curl -X GET "http://localhost:8000/users/students?class_id=101&page=1&size=20" \
  -H 'Authorization: Bearer TOKEN'

响应

json
{
  "items": [
    {
      "id": 201,
      "username": "s001",
      "real_name": "张三",
      "role": "student",
      "school_id": 3,
      "avatar_url": null,
      "created_at": "2025-01-01T10:00:00Z",
      "parent_user_id": 15
    }
  ],
  "total": 1,
  "page": 1,
  "size": 20
}

9.3 重置学生密码

bash
# 老师重置本班学生密码
curl -X POST http://localhost:8000/users/201:reset_password \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"new_password": "New@12345"}'

响应

json
{
  "message": "密码重置成功",
  "user_id": 201,
  "reset_at": "2025-01-01T11:00:00Z"
}

9.4 平台管理员创建学校管理员

bash
# 平台管理员创建学校管理员
curl -X POST http://localhost:8000/schools/3/users:school_admin \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "admin_001",
    "password": "Admin@123",
    "real_name": "李主任"
  }'

10. 与现有代码的对接点

10.1 鉴权依赖

  • app/api/deps.pyget_current_userget_teacher_or_admin
  • 可新增 require_roles(*roles) 辅助函数
  • 可新增 require_school_scope(school_id) 学校作用域校验

10.2 模型复用

  • app/models/user.pyUserRole 已覆盖四类角色
  • 结合 SchoolClassClassMemberClassTeacher 完成范围校验
  • 元数据:/meta/schools/meta/classes 可复用现有端点作为选择器

10.3 服务层设计

  • 新建 app/services/user_management_service.py
  • 新建 app/services/school_management_service.py
  • 实现权限校验、范围控制、批量操作等核心逻辑

11. 后续实现顺序(建议)

11.1 第一阶段:基础用户管理

  1. 补充用户路由模块 app/api/users.pyschemas
  2. 实现基础的 CRUD 操作(创建、查询、更新、删除)
  3. 实现权限校验中间件

11.2 第二阶段:角色与范围管理

  1. 实现学校作用域创建账号与班级成员管理 Service(含越权校验)
  2. 实现班级成员和教师的增删改查
  3. 实现用户角色管理
  4. 实现基于 parent_user_id 的权限继承校验
  5. 实现上级用户管理下级用户的权限控制

11.3 第三阶段:高级功能

  1. 增加 users.disabledusers.require_password_reset 字段的迁移(可选)
  2. 接入审计日志与限流(登录/重置密码)
  3. 实现学校管理功能(平台管理员专用)

11.4 第四阶段:测试与优化

  1. 添加测试:角色越权、班级边界、跨校限制、脱敏字段校验
  2. 测试基于 parent_user_id 的权限继承逻辑
  3. 测试上级用户管理下级用户的权限边界
  4. 性能优化:索引优化、查询优化
  5. 文档完善:API 文档、使用示例

12. 注意事项

12.1 数据一致性

  • 删除用户前检查关联数据(课程、作业、班级关系等)
  • 删除上级用户前检查是否有下级用户依赖(parent_user_id 引用)
  • 批量操作时使用事务确保数据一致性
  • 软删除优先于硬删除
  • 维护 parent_user_id 的引用完整性,避免悬空引用

12.2 性能考虑

  • 大量用户查询时使用分页
  • 复杂查询使用数据库索引优化
  • 缓存常用数据(如学校列表、班级列表)