14 KiB
14 KiB
新增接口文档
创建时间: 2024-12-29
版本: v1.0
状态: ✅ 已完成
📋 接口概览
本次开发完成了4个待开发接口:
| 序号 | 接口路径 | 方法 | 功能 | 状态 |
|---|---|---|---|---|
| 1 | /api/upload/work/video |
POST | 视频上传 | ✅ 已完成 |
| 2 | /api/upload/chat/voice |
POST | 语音上传 | ✅ 已完成 |
| 3 | /api/rooms/{roomId}/viewers |
GET | 观众列表 | ✅ 已完成 |
| 4 | /api/rooms/{roomId}/gift |
POST | 赠送礼物 | ✅ 已完成 |
1️⃣ 视频上传接口
基本信息
- 接口路径:
POST /api/upload/work/video - 功能描述: 上传作品视频文件
- 需要登录: 否(公开接口)
- 限流: 无
请求参数
Content-Type: multipart/form-data
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| multipart | File | 是 | 视频文件 | video.mp4 |
| model | String | 否 | 模块名称 | works(默认) |
| pid | Integer | 否 | 分类ID | 0(默认) |
文件限制
- 支持格式: MP4, MOV, AVI, FLV
- 文件大小: 最大 500MB
- 存储路径:
video/{model}/yyyy/MM/dd/
响应示例
{
"code": 200,
"message": "操作成功",
"data": {
"fileName": "my_video.mp4",
"fileSize": 52428800,
"extName": "mp4",
"url": "video/public/works/2024/12/29/abc123.mp4",
"type": "video/mp4"
}
}
错误码
| 错误码 | 说明 |
|---|---|
| 400 | 视频格式不支持 |
| 400 | 文件大小超过限制 |
| 500 | 上传失败 |
使用示例
// JavaScript示例
const formData = new FormData();
formData.append('multipart', videoFile);
formData.append('model', 'works');
formData.append('pid', 0);
fetch('/api/upload/work/video', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data));
2️⃣ 语音上传接口
基本信息
- 接口路径:
POST /api/upload/chat/voice - 功能描述: 上传语音消息文件
- 需要登录: 否(公开接口)
- 限流: 无
请求参数
Content-Type: multipart/form-data
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| multipart | File | 是 | 语音文件 | voice.mp3 |
| model | String | 否 | 模块名称 | chat(默认) |
| pid | Integer | 否 | 分类ID | 0(默认) |
文件限制
- 支持格式: MP3, AAC, WAV, M4A
- 文件大小: 最大 10MB
- 存储路径:
voice/{model}/yyyy/MM/dd/
响应示例
{
"code": 200,
"message": "操作成功",
"data": {
"fileName": "voice_message.mp3",
"fileSize": 1048576,
"extName": "mp3",
"url": "voice/public/chat/2024/12/29/xyz789.mp3",
"type": "audio/mp3"
}
}
错误码
| 错误码 | 说明 |
|---|---|
| 400 | 语音格式不支持 |
| 400 | 文件大小超过限制 |
| 500 | 上传失败 |
使用示例
// JavaScript示例
const formData = new FormData();
formData.append('multipart', voiceFile);
formData.append('model', 'chat');
formData.append('pid', 0);
fetch('/api/upload/chat/voice', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data));
3️⃣ 观众列表接口
基本信息
- 接口路径:
GET /api/rooms/{roomId}/viewers - 功能描述: 获取直播间在线观众列表
- 需要登录: 否(公开接口)
- 限流: 无
请求参数
URL参数:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| roomId | Integer | 是 | 直播间ID | 123 |
Query参数:
| 参数名 | 类型 | 必填 | 说明 | 默认值 |
|---|---|---|---|---|
| limit | Integer | 否 | 返回数量限制 | 50 |
响应示例
{
"code": 200,
"message": "操作成功",
"data": [
{
"userId": 1001,
"nickname": "用户1001",
"avatar": "https://example.com/avatar/1001.jpg",
"level": 5,
"isVip": true,
"enterTime": 1703836800000,
"isOnline": true,
"clientId": "user_1001_1703836800000"
},
{
"userId": null,
"nickname": "游客",
"avatar": "",
"level": 0,
"isVip": false,
"enterTime": 1703836900000,
"isOnline": true,
"clientId": "guest_abc123_1703836900000"
}
]
}
响应字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
| userId | Integer | 用户ID(游客为null) |
| nickname | String | 用户昵称 |
| avatar | String | 用户头像URL |
| level | Integer | 用户等级 |
| isVip | Boolean | 是否VIP |
| enterTime | Long | 进入时间(时间戳) |
| isOnline | Boolean | 是否在线 |
| clientId | String | 客户端唯一标识 |
错误码
| 错误码 | 说明 |
|---|---|
| 400 | 房间ID不能为空 |
| 500 | 获取观众列表失败 |
使用示例
// JavaScript示例
fetch('/api/rooms/123/viewers?limit=50')
.then(response => response.json())
.then(data => {
console.log('在线观众:', data.data);
});
4️⃣ 赠送礼物接口
基本信息
- 接口路径:
POST /api/rooms/{roomId}/gift - 功能描述: 在直播间赠送礼物给主播
- 需要登录: ✅ 是(需要Token)
- 限流: 建议添加(防止刷礼物)
请求参数
URL参数:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| roomId | Integer | 是 | 直播间ID | 123 |
Body参数 (JSON):
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| giftId | Integer | 是 | 礼物ID | 1 |
| giftCount | Integer | 是 | 礼物数量(≥1) | 1 |
| receiverId | Integer | 是 | 接收者用户ID(主播ID) | 100 |
请求示例
{
"giftId": 1,
"giftCount": 5,
"receiverId": 100
}
响应示例
{
"code": 200,
"message": "操作成功",
"data": {
"recordId": 1001,
"giftName": "玫瑰花",
"giftCount": 5,
"totalDiamond": 50.00,
"remainingDiamond": 450.00,
"intimacy": 50,
"sendTime": 1703836800000
}
}
响应字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
| recordId | Long | 礼物记录ID |
| giftName | String | 礼物名称 |
| giftCount | Integer | 礼物数量 |
| totalDiamond | BigDecimal | 消耗钻石总数 |
| remainingDiamond | BigDecimal | 剩余钻石数 |
| intimacy | Integer | 增加的亲密度 |
| sendTime | Long | 赠送时间(时间戳) |
业务逻辑
- 验证礼物: 检查礼物是否存在且启用
- 验证用户: 检查赠送者和接收者是否存在
- 计算总价: 单价 × 数量
- 检查余额: 验证赠送者钻石余额是否充足
- 扣除钻石: 从赠送者账户扣除钻石
- 增加收益: 给接收者(主播)增加钻石(70%分成)
- 创建记录: 保存礼物赠送记录
- 返回结果: 返回赠送详情
错误码
| 错误码 | 说明 |
|---|---|
| 400 | 房间ID不能为空 |
| 400 | 礼物ID不能为空 |
| 400 | 礼物数量至少为1 |
| 400 | 接收者用户ID不能为空 |
| 400 | 不能给自己赠送礼物 |
| 404 | 礼物不存在 |
| 404 | 用户不存在 |
| 404 | 接收者不存在 |
| 404 | 直播间不存在 |
| 400 | 礼物已下架 |
| 400 | 钻石余额不足 |
| 401 | 请先登录 |
| 500 | 扣除钻石失败 |
| 500 | 赠送礼物失败 |
使用示例
// JavaScript示例
fetch('/api/rooms/123/gift', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
},
body: JSON.stringify({
giftId: 1,
giftCount: 5,
receiverId: 100
})
})
.then(response => response.json())
.then(data => {
if (data.code === 200) {
console.log('赠送成功:', data.data);
} else {
console.error('赠送失败:', data.message);
}
});
📦 数据库表结构
eb_gift_record - 礼物赠送记录表
CREATE TABLE `eb_gift_record` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`room_id` INT NOT NULL COMMENT '直播间ID',
`gift_id` INT NOT NULL COMMENT '礼物ID',
`gift_name` VARCHAR(100) COMMENT '礼物名称',
`gift_image` VARCHAR(255) COMMENT '礼物图片',
`sender_id` INT NOT NULL COMMENT '赠送者用户ID',
`sender_nickname` VARCHAR(50) COMMENT '赠送者昵称',
`sender_avatar` VARCHAR(255) COMMENT '赠送者头像',
`receiver_id` INT NOT NULL COMMENT '接收者用户ID(主播)',
`receiver_nickname` VARCHAR(50) COMMENT '接收者昵称',
`gift_count` INT NOT NULL DEFAULT 1 COMMENT '礼物数量',
`diamond_price` DECIMAL(10,2) DEFAULT 0.00 COMMENT '单价(钻石)',
`total_diamond` DECIMAL(10,2) DEFAULT 0.00 COMMENT '总价(钻石)',
`intimacy` INT DEFAULT 0 COMMENT '增加的亲密度',
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除 0=未删除 1=已删除',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`ext_field1` VARCHAR(100) COMMENT '扩展字段1:特效类型',
`ext_field2` INT COMMENT '扩展字段2:连击次数',
`ext_field3` VARCHAR(50) COMMENT '扩展字段3:活动标识',
`ext_field4` BIGINT COMMENT '扩展字段4:关联订单ID',
`ext_field5` TEXT COMMENT '扩展字段5:JSON扩展数据',
PRIMARY KEY (`id`),
INDEX `idx_room_id` (`room_id`),
INDEX `idx_sender_id` (`sender_id`),
INDEX `idx_receiver_id` (`receiver_id`),
INDEX `idx_gift_id` (`gift_id`),
INDEX `idx_create_time` (`create_time`),
INDEX `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='礼物赠送记录表';
🔧 技术实现
1. 文件上传实现
核心类:
UploadService- 上传服务接口UploadServiceImpl- 上传服务实现UserUploadController- 前端上传控制器
技术特点:
- 支持多种文件格式验证
- 文件大小限制
- 自动生成唯一文件名
- 按日期分目录存储
- 支持本地存储和云存储(七牛云、OSS、COS等)
2. 观众列表实现
核心类:
LiveRoomOnlineService- 在线服务接口LiveRoomOnlineServiceImpl- 在线服务实现LiveRoomController- 直播间控制器LiveRoomOnlineUser- 观众信息实体
技术特点:
- 基于WebSocket实时连接
- 使用ConcurrentHashMap保证线程安全
- 支持用户去重(同一用户多标签页只计1人)
- 实时更新在线状态
3. 礼物赠送实现
核心类:
GiftRecordService- 礼物记录服务接口GiftRecordServiceImpl- 礼物记录服务实现GiftRecord- 礼物记录实体SendGiftRequest- 赠送请求对象SendGiftResponse- 赠送响应对象
技术特点:
- 使用事务保证数据一致性
- 余额检查和扣除
- 主播收益分成(70%)
- 完整的错误处理
- 礼物记录持久化
🧪 测试建议
1. 视频上传测试
# 测试正常上传
curl -X POST http://localhost:8080/api/upload/work/video \
-F "multipart=@test_video.mp4" \
-F "model=works" \
-F "pid=0"
# 测试大文件(应该失败)
curl -X POST http://localhost:8080/api/upload/work/video \
-F "multipart=@large_video.mp4"
# 测试错误格式(应该失败)
curl -X POST http://localhost:8080/api/upload/work/video \
-F "multipart=@test.txt"
2. 语音上传测试
# 测试正常上传
curl -X POST http://localhost:8080/api/upload/chat/voice \
-F "multipart=@test_voice.mp3" \
-F "model=chat" \
-F "pid=0"
3. 观众列表测试
# 获取观众列表
curl -X GET "http://localhost:8080/api/rooms/123/viewers?limit=50"
4. 赠送礼物测试
# 赠送礼物
curl -X POST http://localhost:8080/api/rooms/123/gift \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"giftId": 1,
"giftCount": 5,
"receiverId": 100
}'
📝 注意事项
1. 安全性
- ✅ 视频和语音上传接口建议添加登录验证
- ✅ 赠送礼物接口已添加登录验证
- ⚠️ 建议添加限流防刷(特别是礼物接口)
- ⚠️ 建议添加文件内容安全检查
2. 性能优化
- 视频上传建议使用分片上传
- 大文件上传建议使用云存储
- 观众列表建议添加缓存
- 礼物记录建议异步处理
3. 扩展性
- 所有实体类都预留了5个扩展字段
- 支持后续功能扩展
- 使用JPA自动建表,便于维护
📊 接口统计
完成情况
| 模块 | 接口数量 | 完成度 |
|---|---|---|
| 文件上传 | 2 | ✅ 100% |
| 直播间功能 | 2 | ✅ 100% |
| 总计 | 4 | ✅ 100% |
新增文件
| 类型 | 文件数量 | 说明 |
|---|---|---|
| 实体类 | 2 | GiftRecord, LiveRoomOnlineUser扩展 |
| 请求对象 | 1 | SendGiftRequest |
| 响应对象 | 2 | SendGiftResponse, LiveRoomViewerResponse |
| DAO层 | 2 | GiftRecordDao, GiftRecordDao.xml |
| Service层 | 2 | GiftRecordService, GiftRecordServiceImpl |
| Controller层 | 2 | LiveRoomController扩展, UserUploadController扩展 |
| 总计 | 11 | - |
🎯 后续优化建议
短期优化(1-2周)
- 添加限流: 使用@RateLimit注解保护接口
- 添加日志: 完善操作日志记录
- 添加监控: 接入监控系统
- 性能测试: 压力测试和优化
中期优化(1个月)
- 分片上传: 实现大文件分片上传
- 云存储: 集成七牛云/OSS/COS
- CDN加速: 视频和语音文件CDN加速
- 缓存优化: Redis缓存观众列表
长期优化(3个月)
- 实时推送: WebSocket推送礼物动画
- 数据分析: 礼物消费统计和分析
- 活动系统: 礼物活动和促销
- AI审核: 视频和语音内容审核
文档版本: v1.0
最后更新: 2024-12-29
维护人员: Kiro AI Assistant