zhibo/点赞功能完整实现指南.md

416 lines
13 KiB
Markdown
Raw Normal View History

2026-01-03 15:32:31 +08:00
# 点赞功能完整实现指南
## ✅ 已完成的后端部分
### 1. 数据库
- ✅ 创建点赞表SQL脚本`live_room_like_tables.sql`
- ✅ 添加直播间点赞数字段
### 2. 后端代码
- ✅ LiveRoomLike实体类
- ✅ LiveRoomLikeDao接口和XML映射
- ✅ LiveRoomLikeService接口和实现
- ✅ LiveRoomLikeController控制器
- ✅ 后端代码编译成功
### 3. 后端API接口
#### 点赞接口
```
POST /api/front/live/like/room/{roomId}
Body: { "count": 1 } // 可选默认1
```
#### 获取直播间点赞数
```
GET /api/front/live/like/room/{roomId}/count
```
#### 获取我的点赞次数
```
GET /api/front/live/like/room/{roomId}/my-count
```
#### 获取我点赞过的直播间列表
```
GET /api/front/live/like/my-liked-rooms?page=1&pageSize=20
```
#### 获取主播总获赞数
```
GET /api/front/live/like/streamer/{streamerId}/total
```
## 🔄 需要完成的Android端部分
由于Android端修改较多我已经准备好了所有后端代码。现在需要你完成以下Android端的修改
### 1. 修改直播间详情页(添加点赞按钮)
**文件**: `android-app/app/src/main/res/layout/activity_room_detail.xml`
在聊天输入框的LinearLayout中添加点赞按钮
```xml
<LinearLayout
android:id="@+id/chatInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chatRecyclerView">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/chatInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="发送弹幕..."
android:inputType="text"
android:maxLines="1" />
<!-- 新增:点赞按钮 -->
<ImageButton
android:id="@+id/likeButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="4dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_like_24"
android:contentDescription="点赞" />
<!-- 新增:点赞数显示 -->
<TextView
android:id="@+id/likeCountText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="4dp"
android:text="0"
android:textSize="14sp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="发送" />
</LinearLayout>
```
**文件**: `android-app/app/src/main/java/com/example/livestreaming/RoomDetailActivity.java`
添加点赞功能代码在onCreate方法中
```java
// 点赞按钮
ImageButton likeButton = findViewById(R.id.likeButton);
TextView likeCountText = findViewById(R.id.likeCountText);
// 加载点赞数
loadLikeCount();
// 点赞按钮点击事件
likeButton.setOnClickListener(v -> {
if (!AuthHelper.isLoggedIn(this)) {
Toast.makeText(this, "请先登录", Toast.LENGTH_SHORT).show();
return;
}
// 点赞动画
likeButton.animate()
.scaleX(1.3f)
.scaleY(1.3f)
.setDuration(100)
.withEndAction(() -> {
likeButton.animate()
.scaleX(1.0f)
.scaleY(1.0f)
.setDuration(100)
.start();
})
.start();
// 调用点赞API
likeRoom();
});
// 添加这两个方法:
private void loadLikeCount() {
ApiClient.getService(this)
.getRoomLikeCount(roomId)
.enqueue(new Callback<ApiResponse<Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<Map<String, Object>>> call,
Response<ApiResponse<Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
Map<String, Object> data = response.body().getData();
if (data != null && data.containsKey("likeCount")) {
int likeCount = ((Number) data.get("likeCount")).intValue();
TextView likeCountText = findViewById(R.id.likeCountText);
likeCountText.setText(String.valueOf(likeCount));
}
}
}
@Override
public void onFailure(Call<ApiResponse<Map<String, Object>>> call, Throwable t) {
// 忽略错误
}
});
}
private void likeRoom() {
Map<String, Object> request = new HashMap<>();
request.put("count", 1);
ApiClient.getService(this)
.likeRoom(roomId, request)
.enqueue(new Callback<ApiResponse<Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<Map<String, Object>>> call,
Response<ApiResponse<Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
Map<String, Object> data = response.body().getData();
if (data != null && data.containsKey("likeCount")) {
int likeCount = ((Number) data.get("likeCount")).intValue();
TextView likeCountText = findViewById(R.id.likeCountText);
likeCountText.setText(String.valueOf(likeCount));
// 显示点赞成功提示
Toast.makeText(RoomDetailActivity.this, "点赞成功 ❤️", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onFailure(Call<ApiResponse<Map<String, Object>>> call, Throwable t) {
Toast.makeText(RoomDetailActivity.this, "点赞失败", Toast.LENGTH_SHORT).show();
}
});
}
```
### 2. 修改首页直播间卡片(显示点赞数)
**文件**: `android-app/app/src/main/res/layout/item_room_waterfall.xml`
找到右下角的星星图标,替换为点赞数显示:
```xml
<!-- 原来的星星图标,删除或注释掉 -->
<!-- <ImageView ... /> -->
<!-- 新增:点赞数显示 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="8dp"
android:background="#80000000"
android:orientation="horizontal"
android:padding="4dp"
android:gravity="center_vertical">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_like_filled_24"
android:tint="#FF4081" />
<TextView
android:id="@+id/likeCountText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="0"
android:textColor="@android:color/white"
android:textSize="12sp" />
</LinearLayout>
```
**文件**: `android-app/app/src/main/java/com/example/livestreaming/WaterfallRoomsAdapter.java`
在bind方法中添加点赞数绑定
```java
TextView likeCountText = itemView.findViewById(R.id.likeCountText);
if (likeCountText != null && room.getLikeCount() != null) {
likeCountText.setText(String.valueOf(room.getLikeCount()));
}
```
### 3. 修改个人中心布局
**文件**: `android-app/app/src/main/res/layout/activity_profile.xml`
调整布局,将按钮分为两行:
```xml
<!-- 第一行:我的关注、我的点赞、观看历史 -->
<LinearLayout
android:id="@+id/firstRowButtons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/someView">
<com.google.android.material.card.MaterialCardView
android:id="@+id/myFollowingCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
app:cardElevation="2dp">
<!-- 我的关注内容 -->
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/myLikesCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
app:cardElevation="2dp">
<!-- 我的点赞内容 -->
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/watchHistoryCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:cardElevation="2dp">
<!-- 观看历史内容 -->
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<!-- 第二行:公园勋章、我的挚友 -->
<LinearLayout
android:id="@+id/secondRowButtons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/firstRowButtons">
<com.google.android.material.card.MaterialCardView
android:id="@+id/parkBadgeCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
app:cardElevation="2dp">
<!-- 公园勋章内容 -->
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/myBestFriendsCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:cardElevation="2dp">
<!-- 我的挚友内容 -->
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
```
### 4. 创建"我的点赞"页面
这个页面类似于观看历史页面,显示用户点赞过的直播间列表。
### 5. 修改主播中心(显示获赞数)
**文件**: `android-app/app/src/main/res/layout/activity_streamer_center.xml`
添加获赞数显示:
```xml
<TextView
android:id="@+id/totalLikesText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获赞: 0"
android:textSize="16sp" />
```
**文件**: `android-app/app/src/main/java/com/example/livestreaming/StreamerCenterActivity.java`
加载获赞数:
```java
private void loadStreamerStats() {
Integer streamerId = AuthHelper.getUserId(this);
if (streamerId == null) return;
ApiClient.getService(this)
.getStreamerTotalLikes(streamerId)
.enqueue(new Callback<ApiResponse<Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<Map<String, Object>>> call,
Response<ApiResponse<Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
Map<String, Object> data = response.body().getData();
if (data != null && data.containsKey("totalLikes")) {
long totalLikes = ((Number) data.get("totalLikes")).longValue();
TextView totalLikesText = findViewById(R.id.totalLikesText);
totalLikesText.setText("获赞: " + totalLikes);
}
}
}
@Override
public void onFailure(Call<ApiResponse<Map<String, Object>>> call, Throwable t) {
// 忽略错误
}
});
}
```
## 📋 部署步骤
### 1. 部署后端
```bash
# 1. 执行数据库脚本
mysql -u root -p zhibo < live_room_like_tables.sql
# 2. 部署后端代码jar文件已编译好
cd /root/zhibo/Zhibo/zhibo-h/crmeb-front
cp target/Crmeb-front.jar ./
./restart.sh
```
### 2. 修改Android端
按照上面的说明修改Android端代码然后重新编译安装。
## 🎯 测试清单
- [ ] 直播间详情页能点赞
- [ ] 点赞后数字实时更新
- [ ] 点赞有动画效果
- [ ] 首页卡片显示点赞数
- [ ] 个人中心布局正确(两行)
- [ ] "我的点赞"页面能打开
- [ ] "我的点赞"显示点赞过的直播间
- [ ] 主播中心显示获赞总数
## 📝 注意事项
1. 点赞功能需要登录
2. 点赞是无限次的,每次点击+1
3. 点赞有防刷限制100次/分钟)
4. 所有图标资源已创建ic_like_24.xml, ic_like_filled_24.xml
5. 后端API已全部实现并编译成功
由于Android端修改较多且涉及UI调整建议你按照上面的指南逐步完成。如果遇到问题可以随时询问