基础数据对接指南

本文说明如何通过希悦开放平台 API 从平台获取基础数据,用于对接外部系统。本文覆盖以下数据能力:

  • 学年学期
  • 用户数据(学生、教师)
  • 组织架构(年级、学科组等)
  • 班级数据(行政班、教学班)
  • 教师任课(每个教师任教哪些班级)
  • 班级与学生对应关系

本文仅覆盖数据读取场景,不包含写入、删除等变更操作。

1. 接口范围

接口能力 作用 在本指南中的用途
System 获取学期列表、基础 term 字典 获取学年学期及学期类型
Reflection 获取用户身份数据 获取学生、教师、家长等用户数据
AdminClass 获取行政班数据 获取行政班及其学生、班主任
Klass 获取教学班(课程班)数据 获取教学班、任课教师、班级成员
Structure 获取架构列表与详情 获取学校架构(年级、学科组等)

2. 对接前准备

2.1 鉴权

平台使用 OAuth 2.0 Client Credentials 模式获取 access_token。详见 docs/oauth.md。

Token 接口:

POST /api/v3/oauth/tokens

业务接口请求头:

Authorization: Bearer {access_token}
X-School-Id: {school_id}

要求:

  • Authorization 用于传递访问令牌。
  • X-School-Id 按平台通用约定传递学校上下文。

2.2 权限范围(Scope)

各接口通过 OAuth Scope 鉴权,所需 Scope 如下:

接口 所需 Scope
学期列表 semester.read
通用用户数据 reflection.read_basic 或 reflection.read_all
学生数据 student.read_basic 或 student.read_all
教师数据 teacher.read_basic 或 teacher.read_all
行政班数据 admin_class.read
教学班(课程班)数据 class.read
组织架构 structure.read

说明:

  • read_basic 仅返回基础字段,read_all 返回全部字段。按需选择最低授权范围。
  • 请在申请时按需开通,遵循最小授权原则。

2.3 分页与筛选约定

分页

集合类接口均支持 paginated、page、per_page 参数,分页响应头约定详见 docs/conventions.md。

参数 类型 说明
paginated integer 是否分页,默认 1
page integer 页码,默认 1
per_page integer 每页数量,默认 20

关联展开(expand)

部分接口支持 expand 参数,用逗号分隔需要展开的关联资源,例如 expand=students,teachers。

增量同步

用户、班级、教学班、成员等接口支持 updated_at_egt(仅查询指定时间之后更新或新建的数据)与 with_trashed(是否包含软删除数据)参数,可用于实现增量同步,详见第 12 节。

3. 数据关系总览

semester(学年学期)
  ├── academic_year(学年)
  ├── category(学期类型)
  └── is_current(是否当前学期)

admin_class(行政班)
  ├── teachers(班主任)
  ├── students(班级学生)
  └── classes(关联的教学班)

class(教学班/课程班)
  ├── semester_id(所属学期)
  ├── teachers(任课教师)
  ├── students(班级学生)
  └── admin_class_ids(关联的行政班)

reflection(用户身份)
  ├── student(学生)
  ├── teacher(教师)
  └── guardian(家长)

关键关系:

  • 一个 semester 属于一个 academic_year,属于一个学期类型 category
  • 一个 admin_class 下有多个学生 students 和多个班主任 teachers
  • 一个 class 属于一个 semester,有多个任课教师 teachers 和多个学生 students
  • 一个 class 可关联多个 admin_class,一个 admin_class 可关联多个 class

4. 总体调用顺序

推荐调用顺序如下:

  1. 通过 OAuth 获取 Token
  2. 确认应用已开通所需 Scope
  3. 调用学期接口,确定目标学期 semester_id(优先使用 is_current=true 的当期学期)
  4. 调用用户数据接口,全量或增量同步学生、教师
  5. 调用行政班接口,同步行政班及其学生、班主任
  6. 调用教学班接口,同步教学班及其任课教师、成员
  7. 调用架构接口,获取架构详情(年级、学科组等)
  8. 按需使用 updated_at_egt 做增量更新

5. 获取学年学期

接口:

GET /v3/system/semesters

OpenAPI:获取学期列表

说明:

  • 用于获取学年学期列表,是所有班级、教学班数据的挂载点。
  • 使用 expand=academic_year 展开学年,expand=category 展开学期类型,expand=is_current 标记是否当前学期。

请求参数:

参数 位置 类型 必填 说明
id_in query string 否 指定学期 ID,多个用逗号分隔
expand query string 否 支持 academic_year、category、is_current
paginated query integer 否 是否分页,默认 1
page query integer 否 页码,默认 1
per_page query integer 否 每页数量,默认 20

返回字段(Semester):

字段 类型 可为空 描述
id integer 否 学期 ID
school_id integer 否 学校 ID
academic_year_id integer 否 学年 ID
category_id integer 否 学期类型 ID
name string 否 学期名
start_at string 否 学期开始时间,格式 YYYY-MM-DD
end_at string 否 学期结束时间,格式 YYYY-MM-DD
is_current boolean 是 是否当前学期(需 expand)
is_temporary boolean 是 是否临时学期
current_week integer 是 当前学期对应的当前周数
grade_maps object 是 年级届别对应关系
outer_id string 是 外部 ID

同步建议:

  • 优先使用 is_current=true 的学期作为默认同步目标。
  • 若需同步历史学期数据,按 id_in 或循环逐学期拉取即可。

6. 获取用户数据

用户数据分为三类接口,均返回 Reflection 对象:

说明:

  • reflections 接口通过 role 参数可筛选 teacher、student、guardian。
  • students、teachers 接口为按角色定向获取,参数更细化。
  • 三者返回的 Reflection.id 即用户在班级成员、任课关系中的 reflection_id,是跨接口关联的关键。

请求参数:

参数 位置 类型 必填 说明
role query string 否 仅 reflections 接口,可选 teacher、student、guardian
id_in query string 否 仅 students/teachers 接口,指定用户 ID,多个用逗号分隔
name_in query string 否 仅 students/teachers 接口,按姓名精确检索,多个逗号分隔
name_like query string 否 仅 students/teachers 接口,按姓名模糊检索
phone query string 否 按手机号检索
sort query string 否 排序字段,前缀 - 表示倒序
updated_at_egt query string 否 增量时间,格式 YYYY-MM-DD HH:MM:SS
with_trashed query boolean 否 是否包含软删除记录
expand query string 否 reflections 支持 archived_type;students 支持 graduates_in、grade、archived_type;teachers 支持 discipline、archived_type、department_names

返回字段(Reflection):

字段 类型 可为空 描述
id integer 否 用户身份 ID(主键)
school_id integer 否 学校 ID
name string 否 姓名
role string 否 角色:teacher、student、guardian、staff、shadow
usin string 是 学工号
gender string 是 性别:m - 男,f - 女
phone string 是 手机号码
email string 是 电子邮箱
idcard string 是 身份证号
photo string 是 头像
status string 否 状态:normal - 正常,archived - 归档
structure_ids array<integer> 是 架构 ID 列表
graduates_in_id integer 是 届别 ID
outer_id string 是 外部系统 ID
deleted_at string 是 数据删除时间

7. 获取组织架构

接口:

GET /v3/structure/structures

OpenAPI:获取组织架构列表

说明:

  • 架构是学校基于年级、学科组等维度建立的层级结构,行政班、教学班、用户均通过 structure_ids 关联到架构。
  • 通过 expand=parent 展开父级架构,expand=children 展开子级架构,expand=managers 展开管理员列表。
  • 通过 type 可按架构类型筛选,通过 parent_id 可获取指定父级下的子级架构。

请求参数:

参数 位置 类型 必填 说明
type query string 否 架构类型:headquarters、campus、school_level、grade、subject_group
status query string 否 状态:normal、archived
parent_id query integer 否 父级架构 ID
expand query string 否 支持 parent、children、managers
sort query string 否 排序字段,前缀 - 表示倒序
fields query string 否 返回字段,多个用逗号分隔
paginated query integer 否 是否分页,默认 1
page query integer 否 页码,默认 1
per_page query integer 否 每页数量,默认 20

返回字段(Structure,数组):

字段 类型 可为空 描述
id integer 否 架构 ID
school_id integer 否 学校 ID
name string 否 结构名称
type string 否 结构类型:headquarters、campus、school_level、grade、subject_group
path string 否 结构路径
depth integer 否 结构深度
seq integer 否 序号
weight integer 否 排序权重
status string 否 状态:normal、archived
subject_ids array<integer> 是 科目 ID 列表
manager_ids array<integer> 是 管理员用户 ID 列表
parent object 是 父级结构(需 expand)
children array<object> 是 子级结构(需 expand)
managers array<object> 是 管理员列表(需 expand)
outer_id string 是 外部系统 ID

补充说明:

  • 如需获取整个架构树,可先拉取列表,再通过 expand=children 或按 parent_id 逐层展开。
  • 如需获取单个架构的详情,可调用 GET /v3/structure/structures/{id}(OpenAPI:获取架构详情)。
  • 架构类型 type 主要用于区分校区、学段、年级、学科组等层级。

8. 获取班级数据

8.1 行政班

接口:

GET /v3/admin_class/admin_classes

OpenAPI:获取行政班接口

说明:

  • 行政班是学校按年级、班级划分的固定班制单位。
  • 通过 expand=students 获取班级学生,expand=teachers 获取班主任,expand=classes 获取关联的教学班。
  • status 为 archived 时表示历史行政班(已归档),同步时应过滤,仅保留 status=normal 的行政班。

请求参数:

参数 位置 类型 必填 说明
id query integer 否 行政班 ID
id_in query string 否 行政班 ID 列表,逗号分隔
name_like query string 否 名称模糊搜索
name_in query string 否 名称精确搜索,逗号分隔
teacher_id query integer 否 教师 ID,即 reflection_id
place_id query integer 否 空间 ID
status query string 否 状态:normal、archived
outer_id query string 否 外部 ID
outer_id_in query string 否 外部 ID 列表,多个用逗号分隔
expand query string 否 支持 students、teachers、classes、structures

返回字段(AdminClass):

字段 类型 可为空 描述
id integer 否 行政班 ID
school_id integer 否 学校 ID
name string 否 行政班名称
graduates_in_id integer 否 届别 Term ID
place_id integer 是 教室 ID
student_nums integer 否 学生数量
status string 否 状态:normal - 正常,archived - 归档(历史行政班,需过滤)
teacher_ids array<integer> 是 班主任 ID 列表
teachers array<Reflection> 是 班主任列表(需 expand)
students array<AdminClassMember> 是 学生列表(需 expand)
classes array<ClassRelation> 是 关联的教学班(需 expand)
outer_id string 是 外部 ID

8.2 教学班(课程班)

教学班数据包含教学班列表与教学班成员两部分。

教学班列表

接口:

GET /v3/klass/classes

OpenAPI:获取课程班列表

说明:

  • 教学班(课程班)隶属于某个学期,是选课走班后的授课单位。
  • 推荐按 semester_id 拉取指定学期的教学班。
  • 通过 expand=teachers 获取任课教师,expand=students 获取班级学生,expand=admin_class_ids 获取关联的行政班。

请求参数:

参数 位置 类型 必填 说明
id_in query string 否 指定教学班 ID,多个逗号分隔
semester_id query integer 否 学期 ID
admin_class_id query integer 否 行政班 ID
updated_at_egt query string 否 增量时间,格式 YYYY-MM-DD HH:MM:SS
with_trashed query integer 否 是否包含已删除数据
expand query string 否 支持 teachers、students、class_lessons、places、grades、structures、subject、domain、admin_class_ids 等

返回字段(Class):

字段 类型 可为空 描述
id integer 否 教学班 ID
school_id integer 否 学校 ID
semester_id integer 否 学期 ID
class_name string 否 课程班名称
name string 否 名称
subject_id integer 是 科目 ID(term id, type=course.subject)
domain_id integer 是 领域 ID(term id, type=course.domain)
teachers array<ClassSelection> 是 任课教师(需 expand)
students array<ClassSelection> 是 班级学生(需 expand)
admin_class_ids array<integer> 是 关联的行政班 ID(需 expand)
capacity integer 是 容量
updated_at string 否 更新时间

教学班成员

接口:

GET /v3/klass/class-selections

OpenAPI:获取课程班成员

说明:

  • 教学班成员接口通过 class_id_in 指定一个或多个教学班,返回这些教学班的成员,type 区分成员类型,type=teacher 为任课教师,type=student 为班级学生。
  • 必须指定 semester_id。
  • 每个成员包含 class_id 标识所属教学班,class_id 与 reflection_id 组合即构成“用户属于哪些教学班”的映射。

请求参数:

参数 位置 类型 必填 说明
semester_id query integer 是 学期 ID
type query string 否 成员类型:teacher、student,默认 student
class_id_in query string 否 指定教学班 ID,多个逗号分隔
updated_at_egt query string 否 增量时间,格式 YYYY-MM-DD HH:MM:SS
with_trashed query integer 否 是否包含已删除数据

返回字段(ClassSelection):

字段 类型 可为空 描述
class_id integer 否 教学班 ID
reflection_id integer 否 用户身份 ID
type string 否 成员类型:teacher、student
class_together boolean 是 是否可以同时上多节课
created_at string 否 创建时间
updated_at string 否 更新时间
deleted_at string 是 删除时间,未删除为 null

9. 获取教师任课

教师任课关系指每个教师任教哪些班级。有两种方式:

方式一:教学班列表展开任课教师(推荐)

调用 GET /v3/klass/classes 并传 expand=teachers,返回的每个 Class 自带 id 与 teachers 数组(成员含 class_id、reflection_id),type=teacher 的成员即为该教学班的任课教师。可直接按 Class.id 得到每个班级的任课教师,适合需要一并获取班级属性的场景。

方式二:教学班成员接口

通过教学班成员接口按 type=teacher 获取,接口定义详见 §8.2 教学班成员。返回的成员含 class_id,按 class_id 分组即可得到每个教师任教的班级列表。

同步建议:

  • 若需构建“教师 → 任教班级列表”映射,推荐使用 §8.2 教学班列表的 expand=teachers,按 Class.id 与 teachers[].reflection_id 组合即可。
  • 也可通过教学班成员接口按 type=teacher 获取,按返回的 class_id 分组。

10. 获取班级与学生对应关系

10.1 行政班-学生

调用 GET /v3/admin_class/admin_classes 并传 expand=students,返回 students 数组(AdminClassMember),每个元素即行政班与学生的对应关系。

AdminClassMember 字段:

字段 类型 可为空 描述
class_id integer 否 行政班 ID
reflection_id integer 否 学生 ID(Reflection.id)
entered_at string 否 进班时间
leaved_at string 是 退班时间
status string 否 状态:entered、leaved

10.2 教学班-学生

推荐调用 GET /v3/klass/classes 传 expand=students,返回的每个 Class 自带 id,students 数组(成员含 class_id、reflection_id)即教学班与学生的对应关系。也可通过教学班成员接口按 type=student 获取(接口定义详见 §8.2 教学班成员),返回的成员含 class_id,class_id 与 reflection_id 组合即教学班与学生的对应关系。

10.3 行政班-教学班关联

  • 行政班侧:GET /v3/admin_class/admin_classes 传 expand=classes,返回 ClassRelation(class_id、admin_class_id)。
  • 教学班侧:GET /v3/klass/classes 传 expand=admin_class_ids,返回 admin_class_ids 数组。

11. 增量同步机制

以下接口支持增量拉取,用于降低全量同步成本:

接口 增量参数 说明
用户数据 updated_at_egt 获取指定时间之后更新或新建的用户
行政班 无(按 outer_id 或全量) 行政班数据量通常不大,可全量拉取
教学班 updated_at_egt 课程班属性变化会更新 updated_at
教学班成员 updated_at_egt 成员增删会更新 updated_at

增量同步建议:

  1. 首次全量拉取,记录时间戳 last_sync_at。
  2. 后续传入 updated_at_egt={last_sync_at} 拉取增量。
  3. 配合 with_trashed=1 获取软删除数据,用于同步删除标记。
  4. 每次同步成功后更新 last_sync_at 为本次拉取到的最大 updated_at。

results matching ""

    No results matching ""