# 礼物打赏模块 ## 模块概述 礼物打赏模块负责处理直播间内的虚拟礼物赠送功能,包括礼物列表、用户余额、礼物赠送、充值等功能。 ## 相关文件 - `RoomDetailActivity.java` - 直播间详情(礼物赠送) - `Gift.java` - 礼物模型 - `GiftAdapter.java` - 礼物列表适配器 - `GiftResponse.java` - 礼物响应模型 - `SendGiftRequest.java` - 赠送礼物请求模型 - `SendGiftResponse.java` - 赠送礼物响应模型 - `UserBalanceResponse.java` - 用户余额响应模型 - `RechargeOption.java` - 充值选项模型 - `RechargeAdapter.java` - 充值选项适配器 --- ## 接口列表 ### 1. 获取礼物列表 **接口地址**: `GET /api/front/gift/list` **请求参数**: 无 **返回数据**: ```json { "code": 200, "msg": "success", "data": [ { "id": "integer", // 礼物ID "name": "string", // 礼物名称 "price": "integer", // 礼物价格(金币) "icon": "string", // 礼物图标URL "level": "integer", // 礼物等级(1-5) "description": "string", // 礼物描述 "animation": "string", // 动画效果URL "sort": "integer" // 排序 } ] } ``` --- ### 2. 获取用户余额 **接口地址**: `GET /api/front/gift/balance` **请求参数**: 无 **返回数据** (UserBalanceResponse): ```json { "code": 200, "msg": "success", "data": { "userId": "integer", // 用户ID "coinBalance": "integer", // 金币余额 "totalRecharge": "integer",// 累计充值金币 "totalConsume": "integer", // 累计消费金币 "vipLevel": "integer" // VIP等级 } } ``` --- ### 3. 赠送礼物 **接口地址**: `POST /api/front/gift/send` **请求参数** (SendGiftRequest): ```json { "giftId": "integer", // 礼物ID(必填) "receiverId": "integer", // 接收者ID(必填) "roomId": "string", // 直播间ID(必填) "count": "integer", // 赠送数量(必填) "message": "string" // 附加消息(可选) } ``` **返回数据** (SendGiftResponse): ```json { "code": 200, "msg": "赠送成功", "data": { "giftRecordId": "long", // 礼物记录ID "giftId": "integer", // 礼物ID "giftName": "string", // 礼物名称 "count": "integer", // 赠送数量 "totalPrice": "integer", // 总价格 "newBalance": "integer", // 赠送后的余额 "sendTime": "long" // 赠送时间戳 } } ``` --- ### 4. 获取充值选项 **接口地址**: `GET /api/front/gift/recharge/options` **请求参数**: 无 **返回数据**: ```json { "code": 200, "msg": "success", "data": [ { "id": "string", // 选项ID "coinAmount": "integer", // 金币数量 "price": "number", // 价格(元) "discountLabel": "string",// 优惠标签(可选) "isHot": "boolean", // 是否热门 "sort": "integer" // 排序 } ] } ``` --- ### 5. 创建充值订单 **接口地址**: `POST /api/front/gift/recharge/create` **请求参数** (CreateRechargeRequest): ```json { "optionId": "string", // 充值选项ID(必填) "coinAmount": "integer", // 金币数量(必填) "price": "number" // 价格(必填) } ``` **返回数据** (CreateRechargeResponse): ```json { "code": 200, "msg": "订单创建成功", "data": { "orderId": "string", // 订单ID "orderNo": "string", // 订单号 "coinAmount": "integer", // 金币数量 "price": "number", // 价格 "paymentUrl": "string", // 支付URL "createTime": "long" // 创建时间 } } ``` --- ## 功能说明 ### 礼物等级 | 等级 | 价格范围 | 说明 | |------|---------|------| | 1 | 1-50金币 | 普通礼物 | | 2 | 51-100金币 | 精美礼物 | | 3 | 101-500金币 | 豪华礼物 | | 4 | 501-1000金币 | 贵族礼物 | | 5 | 1000+金币 | 至尊礼物 | ### 赠送流程 1. 用户点击礼物按钮 2. 显示礼物列表和当前余额 3. 选择礼物和数量 4. 检查余额是否足够 5. 调用赠送接口 6. 扣除金币,更新余额 7. 在直播间显示礼物动画 8. 通过WebSocket推送给其他观众 ### 充值流程 1. 用户点击充值按钮 2. 显示充值选项列表 3. 选择充值金额 4. 创建充值订单 5. 选择支付方式(支付宝/微信) 6. 调用支付接口 7. 支付成功后更新余额 --- ## 使用场景 ### 1. 加载礼物列表 ```java private void loadGiftsFromBackend() { ApiService apiService = ApiClient.getService(getApplicationContext()); Call>> call = apiService.getGiftList(); call.enqueue(new Callback>>() { @Override public void onResponse(Call>> call, Response>> response) { if (response.isSuccessful() && response.body() != null) { ApiResponse> apiResponse = response.body(); if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { availableGifts = new ArrayList<>(); for (GiftResponse giftResponse : apiResponse.getData()) { Gift gift = new Gift( String.valueOf(giftResponse.getId()), giftResponse.getName(), giftResponse.getPrice().intValue(), R.drawable.ic_gift_rose, giftResponse.getLevel() != null ? giftResponse.getLevel() : 1 ); availableGifts.add(gift); } } } } @Override public void onFailure(Call>> call, Throwable t) { Log.e("Gift", "加载礼物列表失败: " + t.getMessage()); } }); } ``` ### 2. 获取用户余额 ```java private void loadUserBalance(TextView coinBalanceView) { ApiService apiService = ApiClient.getService(getApplicationContext()); Call> call = apiService.getUserBalance(); call.enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.isSuccessful() && response.body() != null) { ApiResponse apiResponse = response.body(); if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { userCoinBalance = apiResponse.getData().getCoinBalance().intValue(); coinBalanceView.setText(String.valueOf(userCoinBalance)); } } } @Override public void onFailure(Call> call, Throwable t) { Log.e("Gift", "获取余额失败: " + t.getMessage()); } }); } ``` ### 3. 赠送礼物 ```java private void sendGiftToBackend(Gift selectedGift, int count, int totalPrice) { // 检查余额 if (userCoinBalance < totalPrice) { Toast.makeText(this, "金币不足,请先充值", Toast.LENGTH_SHORT).show(); showRechargeDialog(); return; } ApiService apiService = ApiClient.getService(getApplicationContext()); SendGiftRequest request = new SendGiftRequest(); request.setGiftId(Integer.parseInt(selectedGift.getId())); request.setReceiverId(room.getStreamerId()); request.setRoomId(roomId); request.setCount(count); Call> call = apiService.sendGift(request); call.enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.isSuccessful() && response.body() != null) { ApiResponse apiResponse = response.body(); if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { SendGiftResponse giftResponse = apiResponse.getData(); // 更新余额 userCoinBalance = giftResponse.getNewBalance().intValue(); // 显示赠送消息 String giftMessage = String.format("送出了 %d 个 %s", count, selectedGift.getName()); addChatMessage(new ChatMessage("我", giftMessage, true)); Toast.makeText(RoomDetailActivity.this, "赠送成功!", Toast.LENGTH_SHORT).show(); } } } @Override public void onFailure(Call> call, Throwable t) { Toast.makeText(RoomDetailActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); } ``` ### 4. 创建充值订单 ```java private void createRechargeOrder(RechargeOption selectedOption) { ApiService apiService = ApiClient.getService(getApplicationContext()); CreateRechargeRequest request = new CreateRechargeRequest(); request.setOptionId(selectedOption.getId()); request.setCoinAmount(selectedOption.getCoinAmount()); request.setPrice(selectedOption.getPrice()); Call> call = apiService.createRecharge(request); call.enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.isSuccessful() && response.body() != null) { ApiResponse apiResponse = response.body(); if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { CreateRechargeResponse rechargeResponse = apiResponse.getData(); String orderId = rechargeResponse.getOrderId(); // 显示支付选择对话框 showPaymentMethodDialog(orderId, selectedOption); } } } @Override public void onFailure(Call> call, Throwable t) { Toast.makeText(RoomDetailActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); } ``` --- ## WebSocket推送 礼物赠送后会通过WebSocket推送给直播间内的所有用户,用于显示礼物动画。 **推送消息格式**: ```json { "type": "gift", "giftId": 1, "giftName": "玫瑰", "count": 10, "senderId": 123, "senderNickname": "张三", "receiverId": 456, "receiverNickname": "主播", "roomId": "room123" } ``` --- ## 默认礼物列表 如果接口加载失败,可以使用以下默认礼物: | ID | 名称 | 价格 | 等级 | |----|------|------|------| | 1 | 玫瑰 | 10 | 1 | | 2 | 爱心 | 20 | 1 | | 3 | 蛋糕 | 50 | 2 | | 4 | 星星 | 100 | 2 | | 5 | 钻石 | 200 | 3 | | 6 | 皇冠 | 500 | 4 | | 7 | 跑车 | 1000 | 5 | | 8 | 火箭 | 2000 | 5 | --- ## 注意事项 1. 所有接口都需要登录认证 2. 赠送礼物前必须检查余额是否足够 3. 礼物价格以金币为单位,不是人民币 4. 充值需要集成第三方支付SDK(支付宝/微信) 5. 礼物动画效果需要前端实现 6. 建议缓存礼物列表,减少网络请求 7. 余额变化后及时更新UI显示 8. 赠送失败时不扣除金币