# 课程视频接口文档 ## 概述 本文档描述了新增的两个课程视频相关接口: 1. 课程视频详情接口 - 所有用户都可以访问,获取课程和视频的基本信息 2. 课程视频播放凭证接口 - 需要权限验证,根据用户会员级别控制播放权限 ## 权限等级说明 系统中的用户权限等级: - **0 - 游客**: 未登录用户或普通游客 - **1 - 普通用户**: 已注册的普通用户 - **2 - VIP用户**: VIP会员用户 - **3 - SVIP用户**: SVIP会员用户 课程的访问权限规则: - 免费课程(level=0):所有用户都可以观看 - 普通课程(level=1):普通用户及以上可以观看 - VIP课程(level=2):VIP用户及以上可以观看 - SVIP课程(level=3):仅SVIP用户可以观看 ## 接口详情 ### 1. 获取课程视频详情 **接口路径**: `GET /user/course/{courseId}/video-detail` **接口描述**: 获取课程的视频详情信息,包含章节和视频列表。所有用户都可以访问此接口,但会根据用户权限显示不同的播放权限信息。 **路径参数**: - `courseId`: 课程ID(必需) **请求头**: - `Authorization`: Bearer token(可选,未登录用户也可以访问) **响应示例**: ```json { "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 } } } ``` **未登录用户响应示例**: ```json { "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(必需) **请求体**: ```json { "chapterId": 1, "authInfoTimeout": 3600 } ``` **请求参数说明**: - `chapterId`: 章节ID(必需) - `authInfoTimeout`: 播放凭证过期时间(秒),默认3600秒 **成功响应示例**: ```json { "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" } } } ``` **权限不足响应示例**: ```json { "code": 403, "msg": "权限不足:您当前是普通用户用户,该课程需要VIP用户及以上权限", "data": null } ``` **未登录响应示例**: ```json { "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` 方法: ```xml ``` ## 新增文件 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