Files
1818web-hoduan/docs/course-video-api.md
2025-11-14 17:41:15 +08:00

7.1 KiB
Raw Blame History

课程视频接口文档

概述

本文档描述了新增的两个课程视频相关接口:

  1. 课程视频详情接口 - 所有用户都可以访问,获取课程和视频的基本信息
  2. 课程视频播放凭证接口 - 需要权限验证,根据用户会员级别控制播放权限

权限等级说明

系统中的用户权限等级:

  • 0 - 游客: 未登录用户或普通游客
  • 1 - 普通用户: 已注册的普通用户
  • 2 - VIP用户: VIP会员用户
  • 3 - SVIP用户: SVIP会员用户

课程的访问权限规则:

  • 免费课程level=0所有用户都可以观看
  • 普通课程level=1普通用户及以上可以观看
  • VIP课程level=2VIP用户及以上可以观看
  • SVIP课程level=3仅SVIP用户可以观看

接口详情

1. 获取课程视频详情

接口路径: GET /user/course/{courseId}/video-detail

接口描述: 获取课程的视频详情信息,包含章节和视频列表。所有用户都可以访问此接口,但会根据用户权限显示不同的播放权限信息。

路径参数:

  • courseId: 课程ID必需

请求头:

  • Authorization: Bearer token可选未登录用户也可以访问

响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "course": {
      "id": 1,
      "title": "AI图像处理入门课程",
      "description": "学习AI图像处理的基础知识和实践技巧",
      "coverUrl": "https://example.com/cover.jpg",
      "price": 29.99,
      "level": 2,
      "category": "人工智能",
      "isFree": false,
      "levelName": "VIP用户",
      "createTime": "2024-01-15T10:30:00",
      "updateTime": "2024-01-15T10:30:00",
      "creator": {
        "id": "1",
        "username": "teacher01",
        "avatarUrl": "https://example.com/avatar.jpg"
      }
    },
    "chapters": [
      {
        "id": 1,
        "title": "第一章:基础概念",
        "description": "介绍AI图像处理的基础概念",
        "orderNum": 1,
        "videos": [
          {
            "id": 1,
            "chapterId": 1,
            "title": "1.1 什么是AI图像处理",
            "vodVideoId": "abc123def456",
            "durationSec": 1800,
            "durationFormatted": "30:00",
            "orderNum": 1,
            "canPlay": false,
            "lockReason": "需要VIP用户及以上权限"
          }
        ]
      }
    ],
    "userPermission": {
      "userRole": 1,
      "userRoleName": "普通用户",
      "requiredLevel": 2,
      "requiredLevelName": "VIP用户",
      "hasAccess": false,
      "accessDeniedReason": "您当前是普通用户用户该课程需要VIP用户及以上权限",
      "membershipExpiresAt": null
    }
  }
}

未登录用户响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "course": { /* 课程信息 */ },
    "chapters": [ /* 章节列表所有视频的canPlay都为false */ ],
    "userPermission": {
      "userRole": 0,
      "userRoleName": "游客",
      "requiredLevel": 2,
      "requiredLevelName": "VIP用户",
      "hasAccess": false,
      "accessDeniedReason": "请先登录该课程需要VIP用户及以上权限",
      "membershipExpiresAt": null
    }
  }
}

2. 获取课程视频播放凭证

接口路径: POST /user/course/{courseId}/video/{videoId}/play-auth

接口描述: 根据用户权限获取课程视频的播放凭证。需要用户登录和权限验证,只有满足课程要求权限级别的用户才能获取播放凭证。

路径参数:

  • courseId: 课程ID必需
  • videoId: 视频ID必需

请求头:

  • Authorization: Bearer token必需

请求体:

{
  "chapterId": 1,
  "authInfoTimeout": 3600
}

请求参数说明:

  • chapterId: 章节ID必需
  • authInfoTimeout: 播放凭证过期时间默认3600秒

成功响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "playAuth": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "requestId": "req-123456789",
    "videoMeta": {
      "vodVideoId": "abc123def456",
      "title": "1.1 什么是AI图像处理",
      "duration": 1800.0,
      "coverURL": "https://example.com/video-cover.jpg",
      "status": "Normal",
      "size": 104857600
    },
    "userPermission": {
      "userRole": 2,
      "userRoleName": "VIP用户",
      "requiredLevel": 2,
      "hasPermission": true,
      "checkTime": "2024-01-15T10:30:00"
    }
  }
}

权限不足响应示例:

{
  "code": 403,
  "msg": "权限不足您当前是普通用户用户该课程需要VIP用户及以上权限",
  "data": null
}

未登录响应示例:

{
  "code": 401,
  "msg": "请先登录",
  "data": null
}

业务逻辑说明

课程视频详情接口逻辑

  1. 无权限验证: 所有用户(包括未登录用户)都可以访问此接口
  2. 基础信息展示: 显示课程的基本信息、章节结构和视频列表
  3. 权限状态指示: 根据用户当前权限级别,标识每个视频是否可播放
  4. 友好提示: 对于无权限播放的视频,提供明确的权限要求说明

播放凭证接口逻辑

  1. 登录验证: 必须是已登录用户才能访问
  2. 权限验证: 验证用户的会员级别是否满足课程要求
  3. 章节视频验证: 验证视频与章节的关联关系
  4. 播放凭证生成: 调用阿里云VOD服务生成播放凭证
  5. 权限记录: 记录用户的权限验证信息

权限验证规则

  • 游客level=0只能观看免费课程
  • 普通用户level=1可以观看免费课程和普通课程
  • VIP用户level=2可以观看免费、普通和VIP课程
  • SVIP用户level=3可以观看所有课程

错误码说明

错误码 说明
200 成功
400 请求参数错误或课程不存在
401 未登录
403 权限不足
500 服务器内部错误

使用建议

  1. 前端实现: 建议先调用视频详情接口获取课程信息和用户权限状态,再根据权限决定是否显示播放按钮
  2. 用户体验: 对于权限不足的用户,可以显示升级提示或购买链接
  3. 缓存策略: 课程详情信息可以适当缓存,但播放凭证应该实时获取
  4. 错误处理: 播放凭证获取失败时,应该给用户友好的错误提示

数据库变更

为了支持这些接口,在 CourseVideoMapper 中新增了 selectById 方法:

<select id="selectById" resultMap="CourseVideoResultMap">
    SELECT id, chapter_id, title, video_id, duration_sec, order_num, create_time, update_time, is_deleted
    FROM course_video
    WHERE id = #{id} AND is_deleted = 0
</select>

新增文件

  1. CourseVideoDetailDto.java - 课程视频详情响应DTO
  2. CourseVideoPlayDto.java - 播放凭证相关DTO
  3. docs/course-video-api.md - 本API文档

修改文件

  1. CourseController.java - 新增两个接口端点
  2. CourseService.java - 新增两个服务方法接口
  3. CourseServiceImpl.java - 实现两个服务方法
  4. CourseVideoMapper.java - 新增selectById方法
  5. CourseVideoMapper.xml - 新增selectById查询SQL