Skip to content

课程学习接口

接口总览

名称方法路径
获取课程目录GET/api/app/course/{courseId}/outline
获取课程任务学习信息GET/api/app/course/{courseId}/task/{taskId}/learning
下载任务资料GET/api/app/course/{courseId}/task/{taskId}/material/{materialId}/download
播放任务资料GET/api/app/course/{courseId}/task/{taskId}/material/{materialId}/play
学习事件上报POST/api/app/course/{courseId}/task/{taskId}/trigger/doing
完成事件上报POST/api/app/course/{courseId}/task/{taskId}/trigger/finish
观看事件上报POST/api/app/course/{courseId}/task/{taskId}/trigger/watching

获取课程目录(GET /api/app/course/{courseId}/outline

请求参数

参数类型必填说明
courseIdnumber课程ID

返回

json
{
  "outline": [
    {
      "outlineType": "chapter",
      "seq": 1,
      "title": "第一章",
      "children": [
        {
          "outlineType": "task",
          "seq": 1,
          "taskId": 10001,
          "title": "任务1",
          "type": "text",
          "isOptional": false,
          "status": "finished"
        }
      ]
    }
  ],
  "setting": {
    "customChapterEnabled": true
  }
}

字段说明

顶层字段:

字段类型说明
outlinearray课程目录节点列表
settingobject课程目录设置

setting 字段:

字段类型说明
customChapterEnabledboolean是否允许自定义章节

outline 节点字段(章节类型 outlineType=chapter):

字段类型说明
outlineTypestring节点类型:chapter
seqnumber序号
titlestring章节标题
childrenarray子节点列表(任务节点)

outline 节点字段(任务类型 outlineType=task):

字段类型说明
outlineTypestring节点类型:task
seqnumber序号
taskIdnumber任务ID
titlestring任务标题
typestring任务类型:text(图文)/download(下载)/ppt(PPT)/video(视频)/audio(音频)/doc(文档)/discuss(讨论)
isOptionalboolean是否是选修任务
statusstring任务状态:none/start/finished

课程详情页目录接口(GET /api/app/course/{courseId}/detail/outline)返回结构与本节一致,但任务节点不包含学习状态(learningStatus),供未加入学员查看目录。


获取课程任务学习信息(GET /api/app/course/{courseId}/task/{taskId}/learning

请求参数

参数类型必填说明
courseIdnumber课程ID
taskIdnumber任务ID

返回

返回示例

不同任务类型的 activity.media 字段结构不同:

图文任务(mediaType=text):

json
{
  "isProhibitDownload": false,
  "content": "<p>图文内容</p><img src=\"https://cdn.example.com/image.png\" />",
  "playerWatermarkTxt": ["用户名", "2025-01-01"],
  "playerWatermarkColor": "#000000",
  "playerWatermarkAlpha": 80
}

下载任务(mediaType=download):

json
{
  "mediaCount": 3,
  "materials": [
    {
      "id": 20001,
      "name": "课程资料.pdf",
      "description": "第一章学习资料",
      "size": 1024000,
      "type": "pdf",
      "ext": "pdf",
      "convertStatus": "success",
      "globalId": "abc123def456"
    }
  ]
}

PPT任务(mediaType=ppt):

json
{
  "url": "https://cdn.example.com/file.ppt",
  "resNo": "abc123def456",
  "token": "token123456",
  "images": ["https://cdn.example.com/image1.jpg"],
  "playMode": "auto",
  "fileStorage": "cloud",
  "fileConvertStatus": "success",
  "playerWatermarkTxt": ["用户名", "2025-01-01"],
  "playerWatermarkColor": "#000000",
  "playerWatermarkAlpha": 80,
  "cloudSdkBaseUri": "https://sdk.example.com"
}

视频任务(mediaType=video):

json
{
  "url": "https://cdn.example.com/video.mp4",
  "resNo": "abc123def456",
  "token": "token123456",
  "mediaSource": "self",
  "fileStorage": "cloud",
  "fileConvertStatus": "success",
  "playerWatermarkTxt": ["用户名", "2025-01-01"],
  "playerWatermarkColor": "#000000",
  "playerWatermarkAlpha": 80,
  "enablePlaybackRates": true,
  "cloudSdkBaseUri": "https://sdk.example.com",
  "watchTimeReportCycle": 60
}

音频任务(mediaType=audio):

json
{
  "url": "https://cdn.example.com/audio.mp3",
  "resNo": "abc123def456",
  "token": "token123456",
  "fileConvertStatus": "success",
  "playerWatermarkTxt": ["用户名", "2025-01-01"],
  "playerWatermarkColor": "#000000",
  "playerWatermarkAlpha": 80,
  "enablePlaybackRates": true,
  "cloudSdkBaseUri": "https://sdk.example.com",
  "watchTimeReportCycle": 60
}

文档任务(mediaType=doc):

json
{
  "url": "https://cdn.example.com/doc.pdf",
  "resNo": "abc123def456",
  "token": "token123456",
  "fileStorage": "cloud",
  "fileConvertStatus": "success",
  "playerWatermarkTxt": ["用户名", "2025-01-01"],
  "playerWatermarkColor": "#000000",
  "playerWatermarkAlpha": 80,
  "cloudSdkBaseUri": "https://sdk.example.com"
}

字段说明

顶层字段

字段类型说明
settingobject课程学习设置
courseobject课程信息
taskobject任务信息(含 prevTaskId、nextTaskId)
activityobject活动信息
taskResultobject任务学习结果信息

setting 字段

字段类型说明
rewardPointNamestring积分名称

course 字段

字段类型说明
idnumber课程ID
titlestring课程标题
categoryIdnumber分类ID
serializeModestring连载方式
creditnumber完成课程奖励的学分数量
rewardPointnumber课程奖励积分
learnTimeReportCyclenumber学习时长上报周期/秒
learnTimeAntiBrushEnabledboolean是否开启学习防刷

task 字段

字段类型说明
idnumber任务ID
courseIdnumber课程ID
typestring任务类型:text(图文)/download(下载)/ppt(PPT)/video(视频)/audio(音频)/doc(文档)/discuss(讨论)
numbernumber任务编号
titlestring任务标题
statusstring任务状态:create/publish/unpublish
isOptionalboolean是否是选修任务
seqnumber任务序号
lengthnumber/null任务时长/分钟(图文/视频/音频/文档任务表示需要学习的时长,PPT任务表示页数,下载/讨论任务为null)
rewardPointnumber完成任务奖励积分
prevTaskIdnumber/null上一任务ID
nextTaskIdnumber/null下一任务ID
finishConditionobject完成条件

finishCondition 字段

字段类型说明
finishTypestring完成类型:time(学习时长)/download(下载)/end(学习到最后一页)/join_discuss(参与讨论)
finishDetailnumber/null完成详情:time类型为需要学习的时长(分钟),end/download/join_discuss类型为null

activity 字段

字段类型说明
idnumber活动ID
titlestring活动标题
remarkstring备注
mediaIdnumber教学活动详细信息Id
mediaTypestring教学活动详细信息类型:text(图文)/download(下载)/ppt(PPT)/video(视频)/audio(音频)/doc(文档)/discuss(讨论)
lengthnumber/null活动时长/分钟(PPT任务表示页数,下载/讨论任务为null)
taskIdnumber/null任务ID,用于视频类型查询弹题标记
mediaobject教学活动详细信息(结构因 mediaType 而异,详见下方说明)

activity.media 字段说明

图文任务(mediaType=text):

字段类型说明
isProhibitDownloadboolean是否禁止下载
contentstring图文内容(HTML格式,已处理图片地址为绝对URL)
playerWatermarkTxtarray播放器水印文本列表
playerWatermarkColorstring播放器水印颜色
playerWatermarkAlphanumber播放器水印透明度

下载任务(mediaType=download):

字段类型说明
mediaCountnumber资料数量
materialsarray下载资料列表

materials 数组项字段:

字段类型说明
idnumber资料ID
namestring资料名称
descriptionstring/null资料描述
sizenumber资料大小(字节)
typestring/null文件类型
extstring/null文件扩展名
convertStatusstring/null文件转换状态
globalIdstring/null文件全局ID

PPT任务(mediaType=ppt):

字段类型说明
urlstring本地资源地址
resNostring资源编号
tokenstring访问token
imagesarrayPPT图片列表
playModestring播放模式
fileStoragestring文件存储类型
fileConvertStatusstring文件转换状态
playerWatermarkTxtarray播放器水印文本列表
playerWatermarkColorstring播放器水印颜色
playerWatermarkAlphanumber播放器水印透明度
cloudSdkBaseUristring云SDK基础地址

视频任务(mediaType=video):

字段类型说明
urlstring本地资源地址
resNostring资源编号
tokenstring访问token
mediaSourcestring视频源(self/livereplay/segment/外链)
fileStoragestring文件存储类型
fileConvertStatusstring文件转换状态
playerWatermarkTxtarray播放器水印文本列表
playerWatermarkColorstring播放器水印颜色
playerWatermarkAlphanumber播放器水印透明度
enablePlaybackRatesboolean是否开启倍速播放
cloudSdkBaseUristring云SDK基础地址
watchTimeReportCyclenumber观看时长上报周期/秒
startAtnumber/null分段起始时间(毫秒),智萃分段视频时返回,详见 api-course-learning-segment-video
endAtnumber/null分段结束时间(毫秒),智萃分段视频时返回
segmentIdnumber/null分段 ID,智萃分段视频时返回
hasMarkerboolean是否有弹题驻点(仅视频任务有效)

音频任务(mediaType=audio):

字段类型说明
urlstring本地资源地址
resNostring资源编号
tokenstring访问token
fileConvertStatusstring文件转换状态
playerWatermarkTxtarray播放器水印文本列表
playerWatermarkColorstring播放器水印颜色
playerWatermarkAlphanumber播放器水印透明度
enablePlaybackRatesboolean是否开启倍速播放
cloudSdkBaseUristring云SDK基础地址
watchTimeReportCyclenumber观看时长上报周期/秒

文档任务(mediaType=doc):

字段类型说明
urlstring本地资源地址
resNostring资源编号
tokenstring访问token
fileStoragestring文件存储类型
fileConvertStatusstring文件转换状态
playerWatermarkTxtarray播放器水印文本列表
playerWatermarkColorstring播放器水印颜色
playerWatermarkAlphanumber播放器水印透明度
cloudSdkBaseUristring云SDK基础地址

讨论任务(mediaType=discuss):

字段类型说明
contentstring讨论内容(HTML格式,已处理图片地址为绝对URL)
playerWatermarkTxtarray播放器水印文本列表
playerWatermarkColorstring播放器水印颜色
playerWatermarkAlphanumber播放器水印透明度

taskResult 字段

字段类型说明
idnumber任务结果ID
activityIdnumber活动ID
courseIdnumber课程ID
courseTaskIdnumber课程任务ID
statusstring状态:none(未开始)/start(学习中)/finished(已完成)
maxLearnTimenumber最大学习时间/秒
lastLearnTimenumber最后学习时间时间戳
learnUuidstring学习的UUID
finishedTimenumber/null完成时间时间戳
timenumber任务进行时长/秒
watchTimenumber观看时间/秒
remainTimenumber剩余时间/秒
currentTimenumber当前时间时间戳

异常

错误码HTTP状态码错误信息说明
COURSE_NOT_FOUND404课程不存在courseId 无效或已删除
COURSE_TASK_NOT_FOUND404课程任务不存在taskId 无效或已删除
COURSE_MEMBER_NOT_FOUND403学员未加入课程当前登录用户不是该课程成员

下载任务资料(GET /api/app/course/{courseId}/task/{taskId}/material/{materialId}/download

请求参数

路径参数:

参数类型必填说明
courseIdnumber课程ID
taskIdnumber任务ID
materialIdnumber资料ID

返回

json
{
  "downloadUrl": "https://play.qiqiuyun.net/sdk_api/download?resNo=abc123def456&token=eyJ0eXAiOiJKV1QiLCJhbGc..."
}

字段说明

字段类型说明
downloadUrlstring下载URL(云存储返回带Token的URL,本地存储返回文件下载路径)

异常

错误码HTTP状态码错误信息说明
COURSE_NOT_FOUND404课程不存在courseId 无效或已删除
COURSE_TASK_NOT_FOUND404课程任务不存在taskId 无效或已删除
COURSE_MEMBER_NOT_FOUND403学员未加入课程当前登录用户不是该课程成员
COURSE_TASK_UNPUBLISHED403课程任务未发布任务状态为 create
COURSE_TASK_CANCEL_PUBLISHED403课程任务已取消发布任务状态为 unpublish
COURSE_TASK_LOCKED403课程任务未解锁前置任务未完成(锁定模式)
COURSE_MATERIAL_NOT_FOUND404课程资料不存在materialId 无效或已删除
COURSE_MATERIAL_NOT_BELONG_TO_TASK403课程资料不属于该任务资料不属于指定的下载任务

说明

  1. 权限校验:接口会校验用户是否为课程学员、课程是否已发布、任务是否已发布等。
  2. 任务锁定:如果课程为锁定模式,会校验前置任务是否已完成。
  3. 资料归属:会校验资料是否属于指定的下载任务。
  4. 下载URL
    • 云存储:返回带JWT Token的下载URL,有效期5分钟
    • 本地存储:返回本地文件下载路径
  5. SSL协议:系统会根据请求自动判断使用 httphttps 协议。

播放任务资料(GET /api/app/course/{courseId}/task/{taskId}/material/{materialId}/play

请求参数

路径参数:

参数类型必填说明
courseIdnumber课程ID
taskIdnumber任务ID
materialIdnumber资料ID

返回

云存储示例:

json
{
  "url": null,
  "resNo": "abc123def456",
  "token": "token123456",
  "fileStorage": "cloud",
  "fileConvertStatus": "success",
  "cloudSdkBaseUri": "https://sdk.example.com"
}

本地存储示例:

json
{
  "url": "//example.com/player/20001/file/abc123def456.pdf",
  "resNo": null,
  "token": "abc123def456",
  "fileStorage": "local",
  "fileConvertStatus": "success",
  "cloudSdkBaseUri": null
}

字段说明

字段类型说明
urlstring/null播放URL(本地存储返回文件播放路径,云存储为null,需要通过SDK生成)
resNostring资源编号
tokenstring访问token
fileStoragestring文件存储类型:cloud(云存储)/local(本地存储)
fileConvertStatusstring文件转换状态
cloudSdkBaseUristring云SDK基础地址

异常

错误码HTTP状态码错误信息说明
COURSE_NOT_FOUND404课程不存在courseId 无效或已删除
COURSE_TASK_NOT_FOUND404课程任务不存在taskId 无效或已删除
COURSE_MEMBER_NOT_FOUND403学员未加入课程当前登录用户不是该课程成员
COURSE_TASK_UNPUBLISHED403课程任务未发布任务状态为 create
COURSE_TASK_CANCEL_PUBLISHED403课程任务已取消发布任务状态为 unpublish
COURSE_TASK_LOCKED403课程任务未解锁前置任务未完成(锁定模式)
COURSE_MATERIAL_NOT_FOUND404课程资料不存在materialId 无效或已删除
COURSE_MATERIAL_NOT_BELONG_TO_TASK403课程资料不属于该任务资料不属于指定的任务

说明

  1. 权限校验:接口会校验用户是否为课程学员、课程是否已发布、任务是否已发布等。
  2. 任务锁定:如果课程为锁定模式,会校验前置任务是否已完成。
  3. 资料归属:会校验资料是否属于指定的任务。
  4. 播放URL
    • 云存储url 字段为 null,需要客户端使用 resNotokencloudSdkBaseUri 通过云SDK生成播放URL
    • 本地存储url 字段返回本地文件播放路径,格式为 //{host}/player/{fileId}/file/{token}.{ext}
  5. 与下载接口的区别
    • 下载接口直接返回完整的下载URL(云存储和本地存储都返回完整URL)
    • 播放接口的云存储不返回完整URL,需要客户端通过SDK生成
  6. 适用场景:用于在线播放任务资料,适用于视频、音频、文档等可播放类型的资料。

学习事件上报(POST /api/app/course/{courseId}/task/{taskId}/trigger/doing

请求参数

路径参数:

参数类型必填说明
courseIdnumber课程ID
taskIdnumber任务ID

请求体:

json
{
  "lastAt": 1735660800,
  "learnUuid": "6b8029e83003401ab0b796be594ad37a",
  "lastLearnTime": 120.5,
  "trigger": "play",
  "watchTime": 120
}
参数类型必填说明
lastAtnumber上次学习请求时间时间戳
learnUuidstring学习的UUID
lastLearnTimenumber上次学习进度(单位秒)
triggerstring触发点来源:play
watchTimenumber观看时长/秒

返回

json
{
  "taskId": 10001,
  "nextTaskId": 10002,
  "event": "doing",
  "type": "text",
  "lastLearnAt": 1735660800,
  "remainingLearnTime": 480,
  "learnUuid": "6b8029e83003401ab0b796be594ad37a",
  "maxLearnTime": 600,
  "learnTime": 120.5,
  "finishedTime": null,
  "doingTime": 120,
  "watchTime": 120,
  "currentTime": 1735660920,
  "taskStatus": "start",
  "firstTaskFinished": false,
  "firstCourseFinished": false
}

字段说明

字段类型说明
taskIdnumber任务ID
nextTaskIdnumber/null下一个任务ID
eventstring触发事件:doing
typestring任务类型:text(图文)/download(下载)/ppt(PPT)/video(视频)/audio(音频)/doc(文档)/discuss(讨论)
lastLearnAtnumber上次学习时间时间戳
remainingLearnTimenumber剩余学习时间/秒
learnUuidstring学习的UUID
maxLearnTimenumber最大学习时间/秒
learnTimenumber上次学习进度(单位秒)
finishedTimenumber/null完成时间时间戳
doingTimenumber任务进行时长/秒
watchTimenumber观看时间/秒
currentTimenumber当前时间时间戳
taskStatusstring任务完成状态:none(未开始)/start(学习中)/finished(已完成)
firstTaskFinishedboolean是否是第一次任务完成
firstCourseFinishedboolean是否是第一次课程完成

异常

错误码HTTP状态码错误信息说明
COURSE_NOT_FOUND404课程不存在courseId 无效或已删除
COURSE_TASK_NOT_FOUND404课程任务不存在taskId 无效或已删除
COURSE_MEMBER_NOT_FOUND403学员未加入课程当前登录用户不是该课程成员
COURSE_TASK_RESULT_NOT_FOUND404任务学习结果不存在需要先调用学习信息接口

完成事件上报(POST /api/app/course/{courseId}/task/{taskId}/trigger/finish

请求参数

路径参数:

参数类型必填说明
courseIdnumber课程ID
taskIdnumber任务ID

请求体:

json
{
  "lastAt": 1735660800,
  "learnUuid": "6b8029e83003401ab0b796be594ad37a",
  "lastLearnTime": 600.0
}
参数类型必填说明
lastAtnumber上次学习请求时间时间戳
learnUuidstring学习的UUID
lastLearnTimenumber上次学习进度(单位秒)

返回

json
{
  "taskId": 10001,
  "nextTaskId": 10002,
  "event": "finish",
  "type": "text",
  "lastLearnAt": 1735660800,
  "remainingLearnTime": 0,
  "learnUuid": "6b8029e83003401ab0b796be594ad37a",
  "maxLearnTime": 600,
  "learnTime": 600.0,
  "finishedTime": 1735660920,
  "doingTime": 600,
  "watchTime": 600,
  "currentTime": 1735660920,
  "taskStatus": "finished",
  "firstTaskFinished": true,
  "firstCourseFinished": false
}

字段说明

返回字段与学习事件上报相同,主要区别:

字段类型说明
eventstring触发事件:finish
taskStatusstring任务完成状态:finished(已完成)
finishedTimenumber完成时间时间戳
remainingLearnTimenumber剩余学习时间/秒(通常为0)

其他字段说明参见学习事件上报接口。

异常

错误码HTTP状态码错误信息说明
COURSE_NOT_FOUND404课程不存在courseId 无效或已删除
COURSE_TASK_NOT_FOUND404课程任务不存在taskId 无效或已删除
COURSE_MEMBER_NOT_FOUND403学员未加入课程当前登录用户不是该课程成员
COURSE_TASK_RESULT_NOT_FOUND404任务学习结果不存在需要先调用学习信息接口

观看事件上报(POST /api/app/course/{courseId}/task/{taskId}/trigger/watching

请求参数

路径参数:

参数类型必填说明
courseIdnumber课程ID
taskIdnumber任务ID

请求体:

json
{
  "lastAt": 1735660800,
  "learnUuid": "6b8029e83003401ab0b796be594ad37a",
  "lastLearnTime": 120.5,
  "watchTime": 120
}
参数类型必填说明
lastAtnumber上次学习请求时间时间戳
learnUuidstring学习的UUID
lastLearnTimenumber上次学习进度(单位秒)
watchTimenumber观看时长/秒

返回

返回格式与学习事件上报相同,主要区别:

字段类型说明
eventstring触发事件:watching

字段说明

返回字段与学习事件上报相同,参见学习事件上报接口字段说明。

异常

错误码HTTP状态码错误信息说明
COURSE_NOT_FOUND404课程不存在courseId 无效或已删除
COURSE_TASK_NOT_FOUND404课程任务不存在taskId 无效或已删除
COURSE_MEMBER_NOT_FOUND403学员未加入课程当前登录用户不是该课程成员
COURSE_TASK_RESULT_NOT_FOUND404任务学习结果不存在需要先调用学习信息接口

任务学习流程说明

1. 获取课程目录

学员进入课程学习页面时,首先调用获取课程目录接口,获取课程的任务列表和目录结构。

2. 获取任务学习信息

学员点击某个任务时,调用获取课程任务学习信息接口,获取任务的详细信息,包括:

  • 任务基本信息(标题、类型、完成条件等)
  • 活动信息(内容、媒体资源等)
  • 学习进度信息(已学习时长、剩余时长等)

3. 学习事件上报

学员在学习任务过程中,需要定期调用学习事件上报接口(doing),用于记录学习进度。建议上报频率:

  • 每隔一定时间(如30秒)上报一次
  • 页面可见性变化时上报
  • 页面关闭前上报

4. 完成事件上报

当学员完成任务要求后,调用完成事件上报接口(finish),系统会:

  • 更新任务完成状态
  • 记录完成时间
  • 发放任务奖励(积分等)
  • 更新课程进度

5. 观看事件上报(可选)

对于视频、音频等媒体类型,可以调用观看事件上报接口(watching),用于精确记录观看时长。


任务完成条件

不同任务类型的完成条件:

任务类型完成类型完成条件
图文time累计学习时长(秒) >= finishDetail * 60
视频time累计学习时长(秒) >= finishDetail * 60
音频time累计学习时长(秒) >= finishDetail * 60
文档time累计学习时长(秒) >= finishDetail * 60
PPTend学习到最后一页
PPTtime累计学习时长(秒) >= finishDetail * 60
下载download下载任意资料
讨论join_discuss参与讨论

注意事项

  1. 学习UUID:每次开始学习任务时,系统会生成一个唯一的学习UUID(learnUuid),后续所有事件上报都需要携带此UUID,用于防刷和进度追踪。

  2. 学习时长计算:任务的学习时长通过 doingfinish 事件上报来累计,系统会根据上报的时间间隔和时长计算累计学习时间。

  3. 防刷机制:如果课程开启了学习防刷(learnTimeAntiBrushEnabled=true),系统会校验学习UUID的有效性和学习时长的合理性。

  4. 完成条件:需要学习时长的任务必须满足学习时长要求才能完成,学员需要持续学习达到指定时长后才能调用完成事件上报接口。

  5. 任务状态:任务状态包括:

    • none:未开始
    • start:学习中
    • finished:已完成
  6. 选修任务:如果任务为选修任务(isOptional=true),完成与否不影响课程完成进度。

  7. 水印字段:所有任务类型的播放器水印字段统一使用 playerWatermarkTxtplayerWatermarkColorplayerWatermarkAlpha 命名。

  8. 下载任务:下载任务的资料列表字段为 materials,每个资料项包含 id(资料ID)、name(资料名称)、ext(文件扩展名)等字段。下载资料时需要使用资料ID调用下载接口。