429 lines
12 KiB
Markdown
429 lines
12 KiB
Markdown
# 直播间管理模块接口对接分析报告
|
||
|
||
## 📋 分析概述
|
||
|
||
本报告对比了 `模块文档/02-直播间管理模块.md` 中定义的接口规范与后端实际实现,以及前端Android应用的调用情况。
|
||
|
||
---
|
||
|
||
## ✅ 已正确实现的接口
|
||
|
||
### 1. 获取直播间列表
|
||
- **文档路径**: `GET /api/front/live/public/rooms`
|
||
- **后端实现**: ✅ `LiveRoomController.publicRooms()`
|
||
- **前端调用**: ✅ `ApiService.getRooms()`
|
||
- **状态**: **完全匹配**
|
||
|
||
**后端返回字段**:
|
||
```java
|
||
- id (String)
|
||
- title (String)
|
||
- streamerName (String)
|
||
- streamKey (String)
|
||
- isLive (Boolean)
|
||
- viewerCount (Integer)
|
||
- streamUrls (StreamUrlsResponse)
|
||
- rtmp
|
||
- flv
|
||
- hls
|
||
```
|
||
|
||
**⚠️ 缺失字段对比文档**:
|
||
- ❌ `streamerId` (主播ID)
|
||
- ❌ `streamerAvatar` (主播头像)
|
||
- ❌ `coverImage` (封面图)
|
||
- ❌ `likeCount` (点赞数)
|
||
- ❌ `categoryId` (分类ID)
|
||
- ❌ `categoryName` (分类名称)
|
||
- ❌ `tags` (标签数组)
|
||
- ❌ `createTime` (创建时间)
|
||
- ❌ `startTime` (开始时间)
|
||
|
||
---
|
||
|
||
### 2. 获取直播间详情
|
||
- **文档路径**: `GET /api/front/live/public/rooms/{id}`
|
||
- **后端实现**: ✅ `LiveRoomController.publicRoom()`
|
||
- **前端调用**: ✅ `ApiService.getRoom()`
|
||
- **状态**: **部分匹配**
|
||
|
||
**⚠️ 缺失字段对比文档**:
|
||
- ❌ `description` (直播间描述)
|
||
- ❌ `streamerId` (主播ID)
|
||
- ❌ `streamerAvatar` (主播头像)
|
||
- ❌ `streamerLevel` (主播等级)
|
||
- ❌ `coverImage` (封面图)
|
||
- ❌ `likeCount` (点赞数)
|
||
- ❌ `shareCount` (分享数)
|
||
- ❌ `categoryId` (分类ID)
|
||
- ❌ `categoryName` (分类名称)
|
||
- ❌ `tags` (标签数组)
|
||
- ❌ `isFollowing` (是否已关注)
|
||
- ❌ `createTime` (创建时间)
|
||
- ❌ `startTime` (开始时间)
|
||
- ❌ `notice` (直播间公告)
|
||
|
||
---
|
||
|
||
### 3. 创建直播间
|
||
- **文档路径**: `POST /api/front/live/rooms`
|
||
- **后端实现**: ✅ `LiveRoomController.create()`
|
||
- **前端调用**: ✅ `ApiService.createRoom()`
|
||
- **状态**: **部分匹配**
|
||
|
||
**后端接收参数**:
|
||
```java
|
||
- title (String) ✅
|
||
- streamerName (String) ✅
|
||
```
|
||
|
||
**⚠️ 文档要求但后端未接收的参数**:
|
||
- ❌ `type` (直播类型)
|
||
- ❌ `categoryId` (分类ID)
|
||
- ❌ `description` (描述)
|
||
- ❌ `coverImage` (封面URL)
|
||
|
||
---
|
||
|
||
### 4. 开始直播
|
||
- **文档路径**: `POST /api/front/live/room/{id}/start`
|
||
- **后端实现**: ❌ **未实现**
|
||
- **前端调用**: ✅ `ApiService.startLiveRoom()`
|
||
- **状态**: **缺失接口**
|
||
|
||
**问题**:
|
||
- 后端没有提供 `/room/{id}/start` 端点
|
||
- 后端只有 `setLiveStatus(streamKey, boolean)` 方法,通过SRS回调自动触发
|
||
- 前端期望手动控制开始直播,但后端未提供此接口
|
||
|
||
---
|
||
|
||
### 5. 结束直播
|
||
- **文档路径**: `POST /api/front/live/room/{id}/stop`
|
||
- **后端实现**: ❌ **未实现**
|
||
- **前端调用**: ✅ `ApiService.stopLiveRoom()`
|
||
- **状态**: **缺失接口**
|
||
|
||
**问题**:
|
||
- 后端没有提供 `/room/{id}/stop` 端点
|
||
- 后端只有 `setLiveStatus(streamKey, boolean)` 方法,通过SRS回调自动触发
|
||
- 前端期望手动控制结束直播,但后端未提供此接口
|
||
|
||
---
|
||
|
||
### 6. 关注主播
|
||
- **文档路径**: `POST /api/front/live/follow`
|
||
- **后端实现**: ✅ `LiveRoomController.followStreamer()`
|
||
- **前端调用**: ✅ `ApiService.followStreamer()`
|
||
- **状态**: **完全匹配**
|
||
|
||
**后端接收参数**:
|
||
```java
|
||
- streamerId (Integer) ✅
|
||
- action (String: "follow" | "unfollow") ✅
|
||
```
|
||
|
||
**后端返回**:
|
||
```java
|
||
- success (Boolean)
|
||
- message (String)
|
||
- isFollowing (Boolean)
|
||
```
|
||
|
||
---
|
||
|
||
### 7. 获取在线人数
|
||
- **文档路径**: `GET /api/live/online/count/{roomId}`
|
||
- **后端实现**: ✅ `LiveRoomOnlineController.getRoomOnlineCount()`
|
||
- **前端调用**: ❌ 前端未直接调用此接口
|
||
- **状态**: **后端已实现,前端未使用**
|
||
|
||
**后端返回**:
|
||
```java
|
||
CommonResult<Integer> // 直接返回人数
|
||
```
|
||
|
||
**⚠️ 文档期望返回格式**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"count": 1234,
|
||
"roomId": "房间ID"
|
||
}
|
||
}
|
||
```
|
||
|
||
**问题**: 返回格式不匹配,后端直接返回Integer,文档期望返回包含count和roomId的对象
|
||
|
||
---
|
||
|
||
### 8. 获取观众列表
|
||
- **文档路径**: `GET /api/front/live/rooms/{roomId}/viewers`
|
||
- **后端实现**: ✅ `LiveRoomController.getViewers()`
|
||
- **前端调用**: ✅ `ApiService.getRoomViewers()`
|
||
- **状态**: **部分匹配**
|
||
|
||
**后端返回字段**:
|
||
```java
|
||
- userId (String)
|
||
- nickname (String)
|
||
- avatar (String)
|
||
- level (Integer)
|
||
- isVip (Boolean)
|
||
- enterTime (Date)
|
||
- isOnline (Boolean)
|
||
- clientId (String)
|
||
```
|
||
|
||
**⚠️ 文档期望但后端未返回的字段**:
|
||
- ❌ `vipLevel` (VIP等级,后端返回的是isVip布尔值)
|
||
- ❌ `isFollowing` (是否关注)
|
||
- ❌ `joinTime` (文档使用joinTime,后端使用enterTime)
|
||
|
||
**⚠️ 分页参数不匹配**:
|
||
- 文档期望: `page`, `pageSize`
|
||
- 后端接收: `limit` (只有limit参数,没有page)
|
||
- 前端调用: `page`, `pageSize`
|
||
|
||
---
|
||
|
||
### 9. 赠送礼物
|
||
- **文档路径**: `POST /api/front/live/rooms/{roomId}/gift`
|
||
- **后端实现**: ✅ `LiveRoomController.sendGift()`
|
||
- **前端调用**: ✅ `ApiService.sendRoomGift()`
|
||
- **状态**: **完全匹配**
|
||
|
||
**后端接收参数**:
|
||
```java
|
||
- roomId (路径参数) ✅
|
||
- giftId (请求体) ✅
|
||
- count (请求体) ✅
|
||
- receiverId (请求体) - 额外参数
|
||
```
|
||
|
||
**后端返回**:
|
||
```java
|
||
- success (Boolean)
|
||
- newBalance (Integer)
|
||
- giftName (String)
|
||
- totalPrice (Integer)
|
||
- message (String)
|
||
```
|
||
|
||
---
|
||
|
||
### 10. 手动广播在线人数
|
||
- **文档路径**: `POST /api/live/online/broadcast/{roomId}`
|
||
- **后端实现**: ✅ `LiveRoomOnlineController.broadcastRoomCount()`
|
||
- **前端调用**: ✅ `ApiService.broadcastOnlineCount()`
|
||
- **状态**: **完全匹配**
|
||
|
||
---
|
||
|
||
## ❌ 主要问题汇总
|
||
|
||
### 🔴 严重问题
|
||
|
||
#### 1. 缺失关键接口
|
||
- **开始直播接口**: `POST /api/front/live/room/{id}/start` - 未实现
|
||
- **结束直播接口**: `POST /api/front/live/room/{id}/stop` - 未实现
|
||
|
||
**影响**: 前端无法手动控制直播的开始和结束,只能依赖SRS推流回调自动触发
|
||
|
||
**建议**: 在 `LiveRoomController` 中添加以下方法:
|
||
|
||
```java
|
||
@ApiOperation(value = "开始直播")
|
||
@PostMapping("/room/{id}/start")
|
||
public CommonResult<Map<String, Object>> startLive(@PathVariable Integer id) {
|
||
Integer uid = frontTokenComponent.getUserId();
|
||
if (uid == null) return CommonResult.failed("未登录");
|
||
|
||
LiveRoom room = liveRoomService.getById(id);
|
||
if (room == null) return CommonResult.failed("房间不存在");
|
||
if (!uid.equals(room.getUid())) return CommonResult.failed("无权限");
|
||
|
||
boolean success = liveRoomService.setLiveStatus(room.getStreamKey(), true);
|
||
|
||
Map<String, Object> result = new HashMap<>();
|
||
result.put("success", success);
|
||
result.put("message", success ? "直播已开始" : "开始直播失败");
|
||
return CommonResult.success(result);
|
||
}
|
||
|
||
@ApiOperation(value = "结束直播")
|
||
@PostMapping("/room/{id}/stop")
|
||
public CommonResult<Map<String, Object>> stopLive(@PathVariable Integer id) {
|
||
Integer uid = frontTokenComponent.getUserId();
|
||
if (uid == null) return CommonResult.failed("未登录");
|
||
|
||
LiveRoom room = liveRoomService.getById(id);
|
||
if (room == null) return CommonResult.failed("房间不存在");
|
||
if (!uid.equals(room.getUid())) return CommonResult.failed("无权限");
|
||
|
||
boolean success = liveRoomService.setLiveStatus(room.getStreamKey(), false);
|
||
|
||
Map<String, Object> result = new HashMap<>();
|
||
result.put("success", success);
|
||
result.put("message", success ? "直播已结束" : "结束直播失败");
|
||
return CommonResult.success(result);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 🟡 中等问题
|
||
|
||
#### 2. 响应字段缺失
|
||
|
||
**LiveRoomResponse 缺失的重要字段**:
|
||
```java
|
||
// 需要在 LiveRoomResponse 类中添加:
|
||
private Integer streamerId; // 主播ID
|
||
private String streamerAvatar; // 主播头像
|
||
private String coverImage; // 封面图
|
||
private String description; // 描述
|
||
private Integer likeCount; // 点赞数
|
||
private Integer shareCount; // 分享数
|
||
private Integer categoryId; // 分类ID
|
||
private String categoryName; // 分类名称
|
||
private List<String> tags; // 标签
|
||
private Boolean isFollowing; // 是否已关注
|
||
private Date createTime; // 创建时间
|
||
private Date startTime; // 开始时间
|
||
private String notice; // 公告
|
||
private Integer streamerLevel; // 主播等级
|
||
```
|
||
|
||
**影响**: 前端无法显示完整的直播间信息,用户体验受影响
|
||
|
||
---
|
||
|
||
#### 3. 创建直播间参数不完整
|
||
|
||
**CreateLiveRoomRequest 缺失的参数**:
|
||
```java
|
||
// 需要在 CreateLiveRoomRequest 类中添加:
|
||
private String type; // 直播类型
|
||
private Integer categoryId; // 分类ID
|
||
private String description; // 描述
|
||
private String coverImage; // 封面图URL
|
||
```
|
||
|
||
**影响**: 无法创建带分类、描述、封面的直播间
|
||
|
||
---
|
||
|
||
#### 4. 在线人数接口返回格式不匹配
|
||
|
||
**当前返回**: `CommonResult<Integer>`
|
||
**文档期望**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"count": 1234,
|
||
"roomId": "房间ID"
|
||
}
|
||
}
|
||
```
|
||
|
||
**建议修改**:
|
||
```java
|
||
@GetMapping("/count/{roomId}")
|
||
public CommonResult<Map<String, Object>> getRoomOnlineCount(@PathVariable String roomId) {
|
||
try {
|
||
int count = liveRoomOnlineService.getRoomOnlineCount(roomId);
|
||
Map<String, Object> result = new HashMap<>();
|
||
result.put("count", count);
|
||
result.put("roomId", roomId);
|
||
return CommonResult.success(result);
|
||
} catch (Exception e) {
|
||
log.error("Error getting room online count for roomId: {}", roomId, e);
|
||
return CommonResult.failed("获取在线人数失败");
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 5. 观众列表分页参数不一致
|
||
|
||
**文档期望**: `page`, `pageSize`
|
||
**后端实现**: 只有 `limit` 参数
|
||
**前端调用**: `page`, `pageSize`
|
||
|
||
**建议修改**:
|
||
```java
|
||
@GetMapping("/rooms/{roomId}/viewers")
|
||
public CommonResult<Map<String, Object>> getViewers(
|
||
@PathVariable Integer roomId,
|
||
@RequestParam(defaultValue = "1") Integer page,
|
||
@RequestParam(defaultValue = "20") Integer pageSize) {
|
||
// 实现分页逻辑
|
||
// 返回包含 data, total, page, pageSize 的结果
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 🟢 轻微问题
|
||
|
||
#### 6. 字段命名不一致
|
||
- 文档使用 `joinTime`,后端使用 `enterTime`
|
||
- 文档使用 `vipLevel`,后端使用 `isVip`
|
||
|
||
**建议**: 统一字段命名,或在响应对象中做映射
|
||
|
||
---
|
||
|
||
## 📊 接口实现完整度统计
|
||
|
||
| 接口 | 文档定义 | 后端实现 | 前端调用 | 状态 |
|
||
|------|---------|---------|---------|------|
|
||
| 1. 获取直播间列表 | ✅ | ✅ | ✅ | 🟡 字段不完整 |
|
||
| 2. 获取直播间详情 | ✅ | ✅ | ✅ | 🟡 字段不完整 |
|
||
| 3. 创建直播间 | ✅ | ✅ | ✅ | 🟡 参数不完整 |
|
||
| 4. 开始直播 | ✅ | ❌ | ✅ | 🔴 接口缺失 |
|
||
| 5. 结束直播 | ✅ | ❌ | ✅ | 🔴 接口缺失 |
|
||
| 6. 关注主播 | ✅ | ✅ | ✅ | ✅ 完全匹配 |
|
||
| 7. 获取在线人数 | ✅ | ✅ | ❌ | 🟡 格式不匹配 |
|
||
| 8. 获取观众列表 | ✅ | ✅ | ✅ | 🟡 参数不一致 |
|
||
| 9. 赠送礼物 | ✅ | ✅ | ✅ | ✅ 完全匹配 |
|
||
| 10. 手动广播在线人数 | ✅ | ✅ | ✅ | ✅ 完全匹配 |
|
||
|
||
**完整度**: 6/10 完全匹配,2/10 缺失,2/10 部分匹配
|
||
|
||
---
|
||
|
||
## 🔧 修复建议优先级
|
||
|
||
### P0 - 紧急 (必须修复)
|
||
1. ✅ 添加开始直播接口 `POST /api/front/live/room/{id}/start`
|
||
2. ✅ 添加结束直播接口 `POST /api/front/live/room/{id}/stop`
|
||
|
||
### P1 - 重要 (建议修复)
|
||
3. ✅ 扩展 `LiveRoomResponse` 添加缺失字段
|
||
4. ✅ 扩展 `CreateLiveRoomRequest` 添加缺失参数
|
||
5. ✅ 修复在线人数接口返回格式
|
||
6. ✅ 修复观众列表分页参数
|
||
|
||
### P2 - 一般 (可选修复)
|
||
7. ✅ 统一字段命名规范
|
||
8. ✅ 完善API文档注释
|
||
|
||
---
|
||
|
||
## 📝 总结
|
||
|
||
后端基本实现了核心功能,但存在以下主要问题:
|
||
|
||
1. **缺少手动控制直播的接口** - 这是最严重的问题,影响前端功能
|
||
2. **响应数据不完整** - 缺少主播信息、分类、标签等重要字段
|
||
3. **参数格式不统一** - 分页参数、返回格式与文档不一致
|
||
|
||
建议按照优先级逐步修复这些问题,确保前后端接口完全对齐。
|