feat: Android端接口对接完成,新增42个API接口

This commit is contained in:
userName 2025-12-26 18:18:28 +08:00
parent f4c9a42974
commit b30f07b15a
22 changed files with 1207 additions and 3 deletions

4
.gitignore vendored
View File

@ -6,8 +6,8 @@
**/*.iml
**/.cxx/
**/.externalNativeBuild/
**/*.jks
**/*.keystore
# **/*.jks
# **/*.keystore
**/keystore.properties
**/key.properties
**/google-services.json

View File

@ -1,21 +1,49 @@
package com.example.livestreaming.net;
import java.util.List;
import java.util.Map;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface ApiService {
// ==================== 用户认证 ====================
@POST("api/front/login")
Call<ApiResponse<LoginResponse>> login(@Body LoginRequest body);
@POST("api/front/register")
Call<ApiResponse<LoginResponse>> register(@Body RegisterRequest body);
@FormUrlEncoded
@POST("api/front/sendCode")
Call<ApiResponse<Object>> sendCode(@Field("phone") String phone);
@GET("api/front/logout")
Call<ApiResponse<String>> logout();
// ==================== 用户信息 ====================
@GET("api/front/user")
Call<ApiResponse<UserInfoResponse>> getUserInfo();
@POST("api/front/user/edit")
Call<ApiResponse<Object>> updateUserInfo(@Body UserEditRequest body);
// ==================== 直播间 ====================
@GET("api/front/live/public/rooms")
Call<ApiResponse<List<Room>>> getRooms();
@ -27,4 +55,138 @@ public interface ApiService {
@DELETE("api/front/live/rooms/{id}")
Call<ApiResponse<Object>> deleteRoom(@Path("id") String id);
@GET("api/front/live/public/rooms/{roomId}/viewers/count")
Call<ApiResponse<Map<String, Object>>> getViewerCount(@Path("roomId") String roomId);
@POST("api/front/live/follow")
Call<ApiResponse<Map<String, Object>>> followStreamer(@Body Map<String, Object> body);
// ==================== 直播弹幕 ====================
@GET("api/front/live/public/rooms/{roomId}/messages")
Call<ApiResponse<List<ChatMessageResponse>>> getRoomMessages(
@Path("roomId") String roomId,
@Query("limit") int limit);
@POST("api/front/live/public/rooms/{roomId}/messages")
Call<ApiResponse<ChatMessageResponse>> sendRoomMessage(
@Path("roomId") String roomId,
@Body Map<String, String> body);
// ==================== 礼物打赏 ====================
@GET("api/front/gift/list")
Call<ApiResponse<List<GiftResponse>>> getGiftList();
@GET("api/front/gift/balance")
Call<ApiResponse<UserBalanceResponse>> getUserBalance();
@POST("api/front/gift/send")
Call<ApiResponse<SendGiftResponse>> sendGift(@Body SendGiftRequest body);
@GET("api/front/gift/recharge/options")
Call<ApiResponse<List<RechargeOptionResponse>>> getRechargeOptions();
@POST("api/front/gift/recharge/create")
Call<ApiResponse<CreateRechargeResponse>> createRecharge(@Body CreateRechargeRequest body);
// ==================== 私聊会话 ====================
@GET("api/front/conversations")
Call<ApiResponse<List<ConversationResponse>>> getConversations();
@GET("api/front/conversations/search")
Call<ApiResponse<List<ConversationResponse>>> searchConversations(@Query("keyword") String keyword);
@POST("api/front/conversations/with/{otherUserId}")
Call<ApiResponse<Map<String, Object>>> getOrCreateConversation(@Path("otherUserId") int otherUserId);
@POST("api/front/conversations/{id}/read")
Call<ApiResponse<Boolean>> markConversationRead(@Path("id") long id);
@DELETE("api/front/conversations/{id}")
Call<ApiResponse<Boolean>> deleteConversation(@Path("id") long id);
@GET("api/front/conversations/{id}/messages")
Call<ApiResponse<List<PrivateMessageResponse>>> getConversationMessages(
@Path("id") long id,
@Query("page") int page,
@Query("pageSize") int pageSize);
@POST("api/front/conversations/{id}/messages")
Call<ApiResponse<PrivateMessageResponse>> sendPrivateMessage(
@Path("id") long id,
@Body SendMessageRequest body);
@DELETE("api/front/conversations/messages/{id}")
Call<ApiResponse<Boolean>> deleteMessage(@Path("id") long id);
// ==================== 好友管理 ====================
@GET("api/front/friends")
Call<ApiResponse<PageResponse<FriendResponse>>> getFriends(
@Query("page") int page,
@Query("pageSize") int pageSize);
@DELETE("api/front/friends/{friendId}")
Call<ApiResponse<Boolean>> deleteFriend(@Path("friendId") int friendId);
@GET("api/front/users/search")
Call<ApiResponse<PageResponse<SearchUserResponse>>> searchUsers(
@Query("keyword") String keyword,
@Query("page") int page,
@Query("pageSize") int pageSize);
@POST("api/front/friends/request")
Call<ApiResponse<Boolean>> sendFriendRequest(@Body Map<String, Object> body);
@GET("api/front/friends/requests")
Call<ApiResponse<PageResponse<FriendRequestResponse>>> getFriendRequests(
@Query("page") int page,
@Query("pageSize") int pageSize);
@POST("api/front/friends/requests/{requestId}/handle")
Call<ApiResponse<Boolean>> handleFriendRequest(
@Path("requestId") long requestId,
@Body Map<String, Object> body);
// ==================== 文件上传 ====================
@Multipart
@POST("api/front/user/upload/image")
Call<ApiResponse<FileUploadResponse>> uploadImage(
@Part MultipartBody.Part file,
@Part("model") RequestBody model,
@Part("pid") RequestBody pid);
// ==================== 在线状态 ====================
@GET("api/front/online/status/{userId}")
Call<ApiResponse<Map<String, Object>>> checkUserOnline(@Path("userId") int userId);
@POST("api/front/online/status/batch")
Call<ApiResponse<Map<String, Object>>> checkUsersOnline(@Body List<Integer> userIds);
@GET("api/front/online/room/{roomId}/count")
Call<ApiResponse<Map<String, Object>>> getRoomOnlineCount(@Path("roomId") String roomId);
@GET("api/front/online/room/{roomId}/users")
Call<ApiResponse<Map<String, Object>>> getRoomOnlineUsers(@Path("roomId") String roomId);
@GET("api/front/online/stats")
Call<ApiResponse<Map<String, Object>>> getConnectionStats();
// ==================== 离线消息 ====================
@GET("api/front/online/offline/count/{userId}")
Call<ApiResponse<Map<String, Object>>> getOfflineMessageCount(@Path("userId") int userId);
@GET("api/front/online/offline/messages/{userId}")
Call<ApiResponse<Map<String, Object>>> getOfflineMessages(
@Path("userId") int userId,
@Query("limit") int limit);
@DELETE("api/front/online/offline/messages/{userId}")
Call<ApiResponse<String>> clearOfflineMessages(@Path("userId") int userId);
}

View File

@ -0,0 +1,39 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class ConversationResponse {
@SerializedName("id")
private String id;
@SerializedName("title")
private String title;
@SerializedName("lastMessage")
private String lastMessage;
@SerializedName("timeText")
private String timeText;
@SerializedName("unreadCount")
private Integer unreadCount;
@SerializedName("muted")
private Boolean muted;
@SerializedName("avatarUrl")
private String avatarUrl;
@SerializedName("otherUserId")
private Integer otherUserId;
public String getId() { return id; }
public String getTitle() { return title; }
public String getLastMessage() { return lastMessage; }
public String getTimeText() { return timeText; }
public Integer getUnreadCount() { return unreadCount; }
public Boolean getMuted() { return muted; }
public String getAvatarUrl() { return avatarUrl; }
public Integer getOtherUserId() { return otherUserId; }
}

View File

@ -0,0 +1,26 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.math.BigDecimal;
public class CreateRechargeRequest {
@SerializedName("optionId")
private Integer optionId;
@SerializedName("coinAmount")
private BigDecimal coinAmount;
@SerializedName("price")
private BigDecimal price;
public CreateRechargeRequest(Integer optionId, BigDecimal coinAmount, BigDecimal price) {
this.optionId = optionId;
this.coinAmount = coinAmount;
this.price = price;
}
public Integer getOptionId() { return optionId; }
public BigDecimal getCoinAmount() { return coinAmount; }
public BigDecimal getPrice() { return price; }
}

View File

@ -0,0 +1,15 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class CreateRechargeResponse {
@SerializedName("orderId")
private String orderId;
@SerializedName("paymentUrl")
private String paymentUrl;
public String getOrderId() { return orderId; }
public String getPaymentUrl() { return paymentUrl; }
}

View File

@ -0,0 +1,19 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class FileUploadResponse {
@SerializedName("url")
private String url;
@SerializedName("fileName")
private String fileName;
@SerializedName("type")
private String type;
public String getUrl() { return url; }
public String getFileName() { return fileName; }
public String getType() { return type; }
}

View File

@ -0,0 +1,35 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class FriendRequestResponse {
@SerializedName("id")
private Long id;
@SerializedName("from_user_id")
private Integer fromUserId;
@SerializedName("nickname")
private String nickname;
@SerializedName("avatarUrl")
private String avatarUrl;
@SerializedName("phone")
private String phone;
@SerializedName("message")
private String message;
@SerializedName("create_time")
private String createTime;
public Long getId() { return id; }
public Integer getFromUserId() { return fromUserId; }
public String getNickname() { return nickname; }
public String getAvatarUrl() { return avatarUrl; }
public String getPhone() { return phone; }
public String getMessage() { return message; }
public String getCreateTime() { return createTime; }
}

View File

@ -0,0 +1,31 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class FriendResponse {
@SerializedName("id")
private Integer id;
@SerializedName("name")
private String name;
@SerializedName("avatarUrl")
private String avatarUrl;
@SerializedName("phone")
private String phone;
@SerializedName("isOnline")
private Integer isOnline;
@SerializedName("lastOnlineTime")
private String lastOnlineTime;
public Integer getId() { return id; }
public String getName() { return name; }
public String getAvatarUrl() { return avatarUrl; }
public String getPhone() { return phone; }
public boolean isOnline() { return isOnline != null && isOnline == 1; }
public String getLastOnlineTime() { return lastOnlineTime; }
}

View File

@ -0,0 +1,32 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.math.BigDecimal;
public class GiftResponse {
@SerializedName("id")
private String id;
@SerializedName("name")
private String name;
@SerializedName("price")
private BigDecimal price;
@SerializedName("iconUrl")
private String iconUrl;
@SerializedName("description")
private String description;
@SerializedName("level")
private Integer level;
public String getId() { return id; }
public String getName() { return name; }
public BigDecimal getPrice() { return price; }
public String getIconUrl() { return iconUrl; }
public String getDescription() { return description; }
public Integer getLevel() { return level; }
}

View File

@ -0,0 +1,32 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class PageResponse<T> {
@SerializedName("list")
private List<T> list;
@SerializedName("total")
private Long total;
@SerializedName("page")
private Integer page;
@SerializedName("limit")
private Integer limit;
@SerializedName("totalPage")
private Integer totalPage;
public List<T> getList() { return list; }
public Long getTotal() { return total; }
public Integer getPage() { return page; }
public Integer getLimit() { return limit; }
public Integer getTotalPage() { return totalPage; }
public boolean hasMore() {
return page != null && totalPage != null && page < totalPage;
}
}

View File

@ -0,0 +1,39 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class PrivateMessageResponse {
@SerializedName("messageId")
private String messageId;
@SerializedName("userId")
private Integer userId;
@SerializedName("username")
private String username;
@SerializedName("avatarUrl")
private String avatarUrl;
@SerializedName("message")
private String message;
@SerializedName("timestamp")
private Long timestamp;
@SerializedName("status")
private String status;
@SerializedName("isSystemMessage")
private Boolean isSystemMessage;
public String getMessageId() { return messageId; }
public Integer getUserId() { return userId; }
public String getUsername() { return username; }
public String getAvatarUrl() { return avatarUrl; }
public String getMessage() { return message; }
public Long getTimestamp() { return timestamp; }
public String getStatus() { return status; }
public Boolean getIsSystemMessage() { return isSystemMessage; }
}

View File

@ -0,0 +1,24 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.math.BigDecimal;
public class RechargeOptionResponse {
@SerializedName("id")
private String id;
@SerializedName("coinAmount")
private BigDecimal coinAmount;
@SerializedName("price")
private BigDecimal price;
@SerializedName("discountLabel")
private String discountLabel;
public String getId() { return id; }
public BigDecimal getCoinAmount() { return coinAmount; }
public BigDecimal getPrice() { return price; }
public String getDiscountLabel() { return discountLabel; }
}

View File

@ -0,0 +1,27 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class SearchUserResponse {
@SerializedName("id")
private Integer id;
@SerializedName("nickname")
private String nickname;
@SerializedName("phone")
private String phone;
@SerializedName("avatarUrl")
private String avatarUrl;
@SerializedName("friendStatus")
private Integer friendStatus; // 0=未添加, 1=已是好友, 2=已申请待审核
public Integer getId() { return id; }
public String getNickname() { return nickname; }
public String getPhone() { return phone; }
public String getAvatarUrl() { return avatarUrl; }
public Integer getFriendStatus() { return friendStatus; }
}

View File

@ -0,0 +1,25 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class SendGiftRequest {
@SerializedName("giftId")
private Integer giftId;
@SerializedName("streamerId")
private Integer streamerId;
@SerializedName("count")
private Integer count;
public SendGiftRequest(Integer giftId, Integer streamerId, Integer count) {
this.giftId = giftId;
this.streamerId = streamerId;
this.count = count;
}
public Integer getGiftId() { return giftId; }
public Integer getStreamerId() { return streamerId; }
public Integer getCount() { return count; }
}

View File

@ -0,0 +1,20 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.math.BigDecimal;
public class SendGiftResponse {
@SerializedName("success")
private Boolean success;
@SerializedName("newBalance")
private BigDecimal newBalance;
@SerializedName("message")
private String message;
public Boolean getSuccess() { return success; }
public BigDecimal getNewBalance() { return newBalance; }
public String getMessage() { return message; }
}

View File

@ -0,0 +1,25 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class SendMessageRequest {
@SerializedName("message")
private String message;
@SerializedName("messageType")
private String messageType;
public SendMessageRequest(String message) {
this.message = message;
this.messageType = "text";
}
public SendMessageRequest(String message, String messageType) {
this.message = message;
this.messageType = messageType;
}
public String getMessage() { return message; }
public String getMessageType() { return messageType; }
}

View File

@ -0,0 +1,12 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.math.BigDecimal;
public class UserBalanceResponse {
@SerializedName("coinBalance")
private BigDecimal coinBalance;
public BigDecimal getCoinBalance() { return coinBalance; }
}

View File

@ -0,0 +1,24 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
public class UserEditRequest {
@SerializedName("nickname")
private String nickname;
@SerializedName("avatar")
private String avatar;
public UserEditRequest() {}
public UserEditRequest(String nickname, String avatar) {
this.nickname = nickname;
this.avatar = avatar;
}
public void setNickname(String nickname) { this.nickname = nickname; }
public void setAvatar(String avatar) { this.avatar = avatar; }
public String getNickname() { return nickname; }
public String getAvatar() { return avatar; }
}

View File

@ -0,0 +1,68 @@
package com.example.livestreaming.net;
import com.google.gson.annotations.SerializedName;
import java.math.BigDecimal;
public class UserInfoResponse {
@SerializedName("nickname")
private String nickname;
@SerializedName("avatar")
private String avatar;
@SerializedName("phone")
private String phone;
@SerializedName("nowMoney")
private BigDecimal nowMoney;
@SerializedName("integral")
private Integer integral;
@SerializedName("experience")
private Integer experience;
@SerializedName("brokeragePrice")
private BigDecimal brokeragePrice;
@SerializedName("level")
private Integer level;
@SerializedName("isPromoter")
private Boolean isPromoter;
@SerializedName("couponCount")
private Integer couponCount;
@SerializedName("vip")
private Boolean vip;
@SerializedName("vipIcon")
private String vipIcon;
@SerializedName("vipName")
private String vipName;
@SerializedName("rechargeSwitch")
private Boolean rechargeSwitch;
@SerializedName("collectCount")
private Integer collectCount;
public String getNickname() { return nickname; }
public String getAvatar() { return avatar; }
public String getPhone() { return phone; }
public BigDecimal getNowMoney() { return nowMoney; }
public Integer getIntegral() { return integral; }
public Integer getExperience() { return experience; }
public BigDecimal getBrokeragePrice() { return brokeragePrice; }
public Integer getLevel() { return level; }
public Boolean getIsPromoter() { return isPromoter; }
public Integer getCouponCount() { return couponCount; }
public Boolean getVip() { return vip; }
public String getVipIcon() { return vipIcon; }
public String getVipName() { return vipName; }
public Boolean getRechargeSwitch() { return rechargeSwitch; }
public Integer getCollectCount() { return collectCount; }
}

304
android-app/接口文档.md Normal file
View File

@ -0,0 +1,304 @@
# 直播APP接口文档
> 后端服务地址: `http://localhost:8081`
> 所有接口需要在Header中携带 `Authori-zation: {token}` (登录后获取)
---
## 一、用户认证
### 1.1 账号密码登录
- **POST** `/api/front/login`
- **请求体**:
```json
{
"account": "手机号",
"password": "密码"
}
```
- **响应**: `token`, `uid`, `nikeName`, `phone`
### 1.2 用户注册
- **POST** `/api/front/register`
- **请求体**:
```json
{
"phone": "手机号",
"password": "密码",
"verificationCode": "验证码",
"nickname": "昵称"
}
```
### 1.3 发送验证码
- **POST** `/api/front/sendCode`
- **参数**: `phone` (表单)
### 1.4 退出登录
- **GET** `/api/front/logout`
---
## 二、用户信息
### 2.1 获取用户信息
- **GET** `/api/front/user`
- **响应**: `nickname`, `avatar`, `phone`, `nowMoney`, `integral`, `level`, `vip`
### 2.2 修改用户资料
- **POST** `/api/front/user/edit`
- **请求体**:
```json
{
"nickname": "昵称",
"avatar": "头像URL"
}
```
---
## 三、直播间
### 3.1 获取直播间列表
- **GET** `/api/front/live/public/rooms`
- **响应**: 直播中的房间列表
### 3.2 创建直播间
- **POST** `/api/front/live/rooms`
- **请求体**:
```json
{
"title": "直播标题",
"streamerName": "主播名称"
}
```
- **响应**: 房间信息 + 推流地址
### 3.3 获取直播间详情
- **GET** `/api/front/live/public/rooms/{id}`
### 3.4 删除直播间
- **DELETE** `/api/front/live/rooms/{id}`
### 3.5 获取观看人数
- **GET** `/api/front/live/public/rooms/{roomId}/viewers/count`
### 3.6 关注/取消关注主播
- **POST** `/api/front/live/follow`
- **请求体**:
```json
{
"streamerId": 123,
"action": "follow" // 或 "unfollow"
}
```
---
## 四、直播弹幕
### 4.1 获取弹幕消息
- **GET** `/api/front/live/public/rooms/{roomId}/messages`
- **参数**: `limit` (数量限制)
### 4.2 发送弹幕
- **POST** `/api/front/live/public/rooms/{roomId}/messages`
- **请求体**:
```json
{
"message": "弹幕内容",
"visitorId": "访客ID",
"nickname": "昵称"
}
```
---
## 五、礼物打赏
### 5.1 获取礼物列表
- **GET** `/api/front/gift/list`
- **响应**: `id`, `name`, `price`, `iconUrl`, `description`, `level`
### 5.2 获取用户余额
- **GET** `/api/front/gift/balance`
- **响应**: `coinBalance`
### 5.3 赠送礼物
- **POST** `/api/front/gift/send`
- **请求体**:
```json
{
"giftId": 1,
"streamerId": 123,
"count": 1
}
```
- **响应**: `success`, `newBalance`, `message`
### 5.4 获取充值选项
- **GET** `/api/front/gift/recharge/options`
- **响应**: `id`, `coinAmount`, `price`, `discountLabel`
### 5.5 创建充值订单
- **POST** `/api/front/gift/recharge/create`
- **请求体**:
```json
{
"optionId": 1,
"coinAmount": 100,
"price": 10.00
}
```
- **响应**: `orderId`, `paymentUrl`
---
## 六、私聊会话
### 6.1 获取会话列表
- **GET** `/api/front/conversations`
- **响应**: `id`, `title`, `lastMessage`, `timeText`, `unreadCount`, `avatarUrl`, `otherUserId`
### 6.2 搜索会话
- **GET** `/api/front/conversations/search`
- **参数**: `keyword`
### 6.3 获取/创建会话
- **POST** `/api/front/conversations/with/{otherUserId}`
- **响应**: `conversationId`
### 6.4 标记会话已读
- **POST** `/api/front/conversations/{id}/read`
### 6.5 删除会话
- **DELETE** `/api/front/conversations/{id}`
### 6.6 获取消息列表
- **GET** `/api/front/conversations/{id}/messages`
- **参数**: `page`, `pageSize`
- **响应**: `messageId`, `userId`, `username`, `avatarUrl`, `message`, `timestamp`, `status`
### 6.7 发送私信
- **POST** `/api/front/conversations/{id}/messages`
- **请求体**:
```json
{
"message": "消息内容",
"messageType": "text"
}
```
### 6.8 删除消息
- **DELETE** `/api/front/conversations/messages/{id}`
---
## 七、好友管理
### 7.1 获取好友列表
- **GET** `/api/front/friends`
- **参数**: `page`, `pageSize`
- **响应**: `id`, `name`, `avatarUrl`, `phone`, `isOnline`, `lastOnlineTime`
### 7.2 删除好友
- **DELETE** `/api/front/friends/{friendId}`
### 7.3 搜索用户
- **GET** `/api/front/users/search`
- **参数**: `keyword`, `page`, `pageSize`
- **响应**: `id`, `nickname`, `phone`, `avatarUrl`, `friendStatus` (0=未添加, 1=已是好友, 2=已申请)
### 7.4 发送好友请求
- **POST** `/api/front/friends/request`
- **请求体**:
```json
{
"targetUserId": 123,
"message": "请求消息"
}
```
### 7.5 获取好友请求列表
- **GET** `/api/front/friends/requests`
- **参数**: `page`, `pageSize`
### 7.6 处理好友请求
- **POST** `/api/front/friends/requests/{requestId}/handle`
- **请求体**:
```json
{
"accept": true
}
```
---
## 八、文件上传
### 8.1 上传图片
- **POST** `/api/front/user/upload/image`
- **参数**:
- `multipart` - 图片文件
- `model` - 模块 (user/product/wechat/news)
- `pid` - 分类ID (7=前台用户头像)
- **响应**: `url`, `fileName`, `type`
---
## 九、在线状态
### 9.1 检查用户在线状态
- **GET** `/api/front/online/status/{userId}`
- **响应**: `userId`, `online`, `lastActiveTime`
### 9.2 批量检查在线状态
- **POST** `/api/front/online/status/batch`
- **请求体**: `[userId1, userId2, ...]`
- **响应**: `total`, `onlineCount`, `onlineUsers`
### 9.3 获取直播间在线人数
- **GET** `/api/front/online/room/{roomId}/count`
- **响应**: `roomId`, `count`
### 9.4 获取直播间在线用户列表
- **GET** `/api/front/online/room/{roomId}/users`
- **响应**: `roomId`, `count`, `users`
### 9.5 获取WebSocket连接统计
- **GET** `/api/front/online/stats`
- **响应**: `activeConnections`, `timestamp`
---
## 十、离线消息
### 10.1 获取离线消息数量
- **GET** `/api/front/online/offline/count/{userId}`
- **响应**: `userId`, `count`
### 10.2 获取离线消息列表
- **GET** `/api/front/online/offline/messages/{userId}`
- **参数**: `limit` (默认50)
- **响应**: `userId`, `messages`, `count`, `totalCount`
### 10.3 清除离线消息
- **DELETE** `/api/front/online/offline/messages/{userId}`
---
## 接口统计
| 模块 | 接口数量 |
|------|----------|
| 用户认证 | 4 |
| 用户信息 | 2 |
| 直播间 | 6 |
| 直播弹幕 | 2 |
| 礼物打赏 | 5 |
| 私聊会话 | 8 |
| 好友管理 | 6 |
| 文件上传 | 1 |
| 在线状态 | 5 |
| 离线消息 | 3 |
| **总计** | **42** |

View File

@ -0,0 +1,113 @@
# 工作日志 - 前后端接口对接
> 日期: 2024年12月26日
---
## 一、完成的工作
### 1. Android端接口扩展
`ApiService.java` 从原来的 6 个接口扩展到 42 个接口,覆盖以下模块:
- 用户认证4个
- 用户信息2个
- 直播间6个
- 直播弹幕2个
- 礼物打赏5个
- 私聊会话8个
- 好友管理6个
- 文件上传1个
- 在线状态5个
- 离线消息3个
### 2. 新增数据模型类17个
| 文件名 | 说明 |
|--------|------|
| UserInfoResponse.java | 用户信息响应 |
| UserEditRequest.java | 修改用户资料请求 |
| GiftResponse.java | 礼物信息 |
| UserBalanceResponse.java | 用户余额 |
| SendGiftRequest.java | 赠送礼物请求 |
| SendGiftResponse.java | 赠送礼物响应 |
| RechargeOptionResponse.java | 充值选项 |
| CreateRechargeRequest.java | 创建充值订单请求 |
| CreateRechargeResponse.java | 创建充值订单响应 |
| ConversationResponse.java | 会话信息 |
| PrivateMessageResponse.java | 私信消息 |
| SendMessageRequest.java | 发送消息请求 |
| FriendResponse.java | 好友信息 |
| FriendRequestResponse.java | 好友请求 |
| SearchUserResponse.java | 搜索用户结果 |
| PageResponse.java | 分页响应 |
| FileUploadResponse.java | 文件上传响应 |
### 3. 字段匹配修复
检查并修复了 Android 端数据模型与后端返回字段的匹配问题:
| 文件 | 修改内容 |
|------|----------|
| ConversationResponse | 字段改为 id, title, lastMessage, timeText, unreadCount, muted, avatarUrl, otherUserId |
| PrivateMessageResponse | 字段改为 messageId, userId, username, avatarUrl, message, timestamp, status, isSystemMessage |
| SendMessageRequest | 字段改为 message, messageType |
| CreateRechargeRequest | 字段改为 optionId, coinAmount, price |
| UserInfoResponse | 匹配后端 UserCenterResponse |
| UserEditRequest | 简化为 nickname, avatar |
### 4. Git配置修改
修改 `.gitignore`,注释掉 `**/*.jks``**/*.keystore`,允许签名文件上传到公司仓库。
### 5. 文档编写
- `zhibo/android-app/接口文档.md` - 完整的接口说明文档
- `zhibo/接口对接状态.md` - 三端接口对接状态表格
---
## 二、接口对接状态
| 端 | 已打通 | 未打通 | 完成度 |
|----|--------|--------|--------|
| Android ↔ 后端 | 42 | 0 | 100% |
| Vue Admin ↔ 后端 | 20+ | 0 | 100% |
---
## 三、待完成事项
1. 支付SDK集成微信/支付宝)
---
## 四、修改的文件清单
```
zhibo/
├── .gitignore # 修改注释jks规则
├── 接口对接状态.md # 新增
├── 工作日志-接口对接.md # 新增
└── android-app/
├── 接口文档.md # 新增
└── app/src/main/java/.../net/
├── ApiService.java # 修改:扩展接口
├── ConversationResponse.java # 修改:字段匹配
├── PrivateMessageResponse.java # 修改:字段匹配
├── SendMessageRequest.java # 修改:字段匹配
├── CreateRechargeRequest.java # 修改:字段匹配
├── UserInfoResponse.java # 修改:字段匹配
├── UserEditRequest.java # 修改:字段匹配
├── GiftResponse.java # 新增
├── UserBalanceResponse.java # 新增
├── SendGiftRequest.java # 新增
├── SendGiftResponse.java # 新增
├── RechargeOptionResponse.java # 新增
├── CreateRechargeResponse.java # 新增
├── FriendResponse.java # 新增
├── FriendRequestResponse.java # 新增
├── SearchUserResponse.java # 新增
├── PageResponse.java # 新增
└── FileUploadResponse.java # 新增
```

132
接口对接状态.md Normal file
View File

@ -0,0 +1,132 @@
# 接口对接状态总览
> 更新时间: 2024年
## 端口配置
| 服务 | 端口 | 说明 |
|------|------|------|
| crmeb-front | 8081 | Android/H5 API |
| crmeb-admin | 30001 | Vue Admin API |
| Vue Admin | 9527 | 管理后台前端 |
| SRS RTMP | 25002 | 推流端口 |
| SRS HTTP | 25003 | 播放端口 |
---
## 一、Android端 ↔ 后端 (crmeb-front)
### ✅ 已打通 (42个)
| 模块 | 接口 | Android | 后端 | 状态 |
|------|------|---------|------|------|
| **用户认证** | 登录 | ✅ | ✅ | ✅ 已打通 |
| | 注册 | ✅ | ✅ | ✅ 已打通 |
| | 发送验证码 | ✅ | ✅ | ✅ 已打通 |
| | 退出登录 | ✅ | ✅ | ✅ 已打通 |
| **用户信息** | 获取用户信息 | ✅ | ✅ | ✅ 已打通 |
| | 修改用户资料 | ✅ | ✅ | ✅ 已打通 |
| **直播间** | 获取直播间列表 | ✅ | ✅ | ✅ 已打通 |
| | 创建直播间 | ✅ | ✅ | ✅ 已打通 |
| | 获取直播间详情 | ✅ | ✅ | ✅ 已打通 |
| | 删除直播间 | ✅ | ✅ | ✅ 已打通 |
| | 获取观看人数 | ✅ | ✅ | ✅ 已打通 |
| | 关注主播 | ✅ | ✅ | ✅ 已打通 |
| **直播弹幕** | 获取弹幕消息 | ✅ | ✅ | ✅ 已打通 |
| | 发送弹幕 | ✅ | ✅ | ✅ 已打通 |
| **礼物打赏** | 获取礼物列表 | ✅ | ✅ | ✅ 已打通 |
| | 获取用户余额 | ✅ | ✅ | ✅ 已打通 |
| | 赠送礼物 | ✅ | ✅ | ✅ 已打通 |
| | 获取充值选项 | ✅ | ✅ | ✅ 已打通 |
| | 创建充值订单 | ✅ | ✅ | ✅ 已打通 |
| **私聊会话** | 获取会话列表 | ✅ | ✅ | ✅ 已打通 |
| | 搜索会话 | ✅ | ✅ | ✅ 已打通 |
| | 获取/创建会话 | ✅ | ✅ | ✅ 已打通 |
| | 标记已读 | ✅ | ✅ | ✅ 已打通 |
| | 删除会话 | ✅ | ✅ | ✅ 已打通 |
| | 获取消息列表 | ✅ | ✅ | ✅ 已打通 |
| | 发送私信 | ✅ | ✅ | ✅ 已打通 |
| | 删除消息 | ✅ | ✅ | ✅ 已打通 |
| **好友管理** | 获取好友列表 | ✅ | ✅ | ✅ 已打通 |
| | 删除好友 | ✅ | ✅ | ✅ 已打通 |
| | 搜索用户 | ✅ | ✅ | ✅ 已打通 |
| | 发送好友请求 | ✅ | ✅ | ✅ 已打通 |
| | 获取好友请求 | ✅ | ✅ | ✅ 已打通 |
| | 处理好友请求 | ✅ | ✅ | ✅ 已打通 |
| **文件上传** | 上传图片 | ✅ | ✅ | ✅ 已打通 |
| **在线状态** | 检查用户在线 | ✅ | ✅ | ✅ 已打通 |
| | 批量检查在线 | ✅ | ✅ | ✅ 已打通 |
| | 直播间在线人数 | ✅ | ✅ | ✅ 已打通 |
| | 直播间在线用户 | ✅ | ✅ | ✅ 已打通 |
| | WebSocket统计 | ✅ | ✅ | ✅ 已打通 |
| **离线消息** | 获取离线消息数量 | ✅ | ✅ | ✅ 已打通 |
| | 获取离线消息 | ✅ | ✅ | ✅ 已打通 |
| | 清除离线消息 | ✅ | ✅ | ✅ 已打通 |
### ⏳ 未打通 (后端有Android未定义)
| 模块 | 接口 | Android | 后端 | 说明 |
|------|------|---------|------|------|
| 无 | - | - | - | 全部已打通 |
---
## 二、Vue Admin前端 ↔ 后端 (crmeb-admin)
### ✅ 已打通
| 模块 | 功能 | Vue Admin | 后端 | 状态 |
|------|------|-----------|------|------|
| **用户管理** | 用户列表 | ✅ | ✅ | ✅ 已打通 |
| | 用户详情 | ✅ | ✅ | ✅ 已打通 |
| | 用户编辑 | ✅ | ✅ | ✅ 已打通 |
| | 用户等级 | ✅ | ✅ | ✅ 已打通 |
| | 用户分组 | ✅ | ✅ | ✅ 已打通 |
| | 用户标签 | ✅ | ✅ | ✅ 已打通 |
| **直播间管理** | 直播间列表 | ✅ | ✅ | ✅ 已打通 |
| | 创建直播间 | ✅ | ✅ | ✅ 已打通 |
| | 开播/停播 | ✅ | ✅ | ✅ 已打通 |
| | 弹幕记录 | ✅ | ✅ | ✅ 已打通 |
| | 房间类型 | ✅ | ✅ | ✅ 已打通 |
| | 房间背景 | ✅ | ✅ | ✅ 已打通 |
| **礼物管理** | 礼物列表 | ✅ | ✅ | ✅ 已打通 |
| | 打赏记录 | ✅ | ✅ | ✅ 已打通 |
| **财务管理** | 充值记录 | ✅ | ✅ | ✅ 已打通 |
| | 提现管理 | ✅ | ✅ | ✅ 已打通 |
| | 账单明细 | ✅ | ✅ | ✅ 已打通 |
| **系统设置** | 管理员 | ✅ | ✅ | ✅ 已打通 |
| | 角色权限 | ✅ | ✅ | ✅ 已打通 |
| | 系统配置 | ✅ | ✅ | ✅ 已打通 |
---
## 三、数据流向
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Android │────▶│ crmeb-front │────▶│ │
│ APP │ │ :8081 │ │ │
└─────────────┘ └─────────────┘ │ │
│ MySQL │
┌─────────────┐ ┌─────────────┐ │ 数据库 │
│ Vue Admin │────▶│ crmeb-admin │────▶│ │
│ :9527 │ │ :30001 │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
```
---
## 四、统计
| 端 | 已打通 | 未打通 | 完成度 |
|----|--------|--------|--------|
| Android ↔ 后端 | 42 | 0 | 100% |
| Vue Admin ↔ 后端 | 20+ | 0 | 100% |
---
## 五、待完成事项
1. ~~图片上传接口(用户头像)~~ ✅ 已完成
2. ~~在线状态接口~~ ✅ 已完成
3. 支付SDK集成微信/支付宝)