diff --git a/android-app/app/src/main/java/com/example/livestreaming/LikesListActivity.java b/android-app/app/src/main/java/com/example/livestreaming/LikesListActivity.java index d65eb2d7..28c4f7f4 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/LikesListActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/LikesListActivity.java @@ -3,19 +3,32 @@ package com.example.livestreaming; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.util.Log; +import android.view.View; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import com.example.livestreaming.databinding.ActivityLikesListBinding; +import com.example.livestreaming.net.ApiClient; +import com.example.livestreaming.net.ApiResponse; +import com.example.livestreaming.net.PageResponse; +import com.example.livestreaming.net.WorksResponse; import java.util.ArrayList; import java.util.List; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; public class LikesListActivity extends AppCompatActivity { + private static final String TAG = "LikesListActivity"; private ActivityLikesListBinding binding; + private ConversationsAdapter adapter; public static void start(Context context) { Intent intent = new Intent(context, LikesListActivity.class); @@ -30,28 +43,99 @@ public class LikesListActivity extends AppCompatActivity { binding.backButton.setOnClickListener(v -> finish()); - ConversationsAdapter adapter = new ConversationsAdapter(item -> { + adapter = new ConversationsAdapter(item -> { if (item == null) return; - Toast.makeText(this, "查看获赞:" + item.getTitle(), Toast.LENGTH_SHORT).show(); + // 点击跳转到作品详情 + if (item.getId() != null && !item.getId().isEmpty()) { + WorkDetailActivity.start(this, item.getId(), false); + } }); - // TODO: 接入后端接口 - 获取获赞列表 - // 接口路径: GET /api/likes - // 请求参数: - // - userId: 当前用户ID(从token中获取) - // - page (可选): 页码 - // - pageSize (可选): 每页数量 - // 返回数据格式: ApiResponse> - // LikeItem对象应包含: id, userId, username, avatarUrl, targetType (room/work), targetId, targetTitle, likeTime等字段 - // 列表应按点赞时间倒序排列(最新点赞的在前面) binding.likesRecyclerView.setLayoutManager(new LinearLayoutManager(this)); binding.likesRecyclerView.setAdapter(adapter); - adapter.submitList(buildDemoLikes()); + + // 加载获赞数据 + loadLikesData(); } - private List buildDemoLikes() { - List list = new ArrayList<>(); - // 不再使用模拟数据,只从后端接口获取真实点赞数据 - return list; + private void loadLikesData() { + if (!AuthHelper.isLoggedIn(this)) { + showEmptyState(); + return; + } + + // 获取当前用户ID + String userIdStr = com.example.livestreaming.net.AuthStore.getUserId(this); + if (userIdStr == null || userIdStr.isEmpty()) { + showEmptyState(); + return; + } + + int userId; + try { + userId = Integer.parseInt(userIdStr); + } catch (NumberFormatException e) { + showEmptyState(); + return; + } + + // 获取用户的所有作品及其点赞信息 + ApiClient.getService(this).getUserWorks(userId, 1, 100) + .enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, + Response>> response) { + if (response.isSuccessful() && response.body() != null && response.body().isOk()) { + PageResponse pageData = response.body().getData(); + if (pageData != null && pageData.getList() != null && !pageData.getList().isEmpty()) { + List items = convertWorksToLikeItems(pageData.getList()); + if (!items.isEmpty()) { + adapter.submitList(items); + showContent(); + return; + } + } + } + showEmptyState(); + } + + @Override + public void onFailure(Call>> call, Throwable t) { + Log.e(TAG, "加载获赞数据失败: " + t.getMessage()); + showEmptyState(); + } + }); + } + + /** + * 将作品列表转换为点赞项列表(只显示有点赞的作品) + */ + private List convertWorksToLikeItems(List works) { + List items = new ArrayList<>(); + for (WorksResponse work : works) { + Integer likeCount = work.getLikeCount(); + if (likeCount != null && likeCount > 0) { + ConversationItem item = new ConversationItem(); + item.setId(String.valueOf(work.getId())); + item.setTitle(work.getTitle() != null ? work.getTitle() : "作品"); + item.setLastMessage(likeCount + "人点赞了这个作品"); + item.setAvatarUrl(work.getCoverImage()); + item.setUnreadCount(likeCount); + items.add(item); + } + } + return items; + } + + private void showEmptyState() { + // 显示空状态 + adapter.submitList(new ArrayList<>()); + binding.likesRecyclerView.setVisibility(View.GONE); + binding.emptyView.setVisibility(View.VISIBLE); + } + + private void showContent() { + binding.likesRecyclerView.setVisibility(View.VISIBLE); + binding.emptyView.setVisibility(View.GONE); } } diff --git a/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java b/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java index bfa93d29..00ab75bb 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java @@ -440,11 +440,11 @@ public class ProfileActivity extends AppCompatActivity { startActivity(new Intent(this, FollowingActivity.class)); }); binding.action2.setOnClickListener(v -> { - // 我的点赞(作品+直播间) - if (!AuthHelper.requireLogin(this, "查看点赞需要登录")) { + // 我的好友 + if (!AuthHelper.requireLogin(this, "查看好友列表需要登录")) { return; } - MyLikesActivity.start(this); + startActivity(new Intent(this, MyFriendsActivity.class)); }); binding.action3.setOnClickListener(v -> { // 我的收藏(作品+直播间) @@ -453,13 +453,6 @@ public class ProfileActivity extends AppCompatActivity { } MyCollectionsActivity.start(this); }); - binding.action4.setOnClickListener(v -> { - // 我的记录 - 跳转到统一记录页面 - if (!AuthHelper.requireLogin(this, "查看记录需要登录")) { - return; - } - MyRecordsActivity.start(this); - }); binding.editProfile.setOnClickListener(v -> { // 检查登录状态,编辑资料需要登录 @@ -573,6 +566,29 @@ public class ProfileActivity extends AppCompatActivity { binding.myWorksRecycler.setLayoutManager(new GridLayoutManager(this, 2)); binding.myWorksRecycler.setAdapter(myWorksAdapter); + // 设置赞过列表 + likedWorksAdapter = new WorksAdapter(work -> { + if (work != null && work.getId() != null) { + WorkDetailActivity.start(this, String.valueOf(work.getId()), false); + } + }); + binding.likedWorksRecycler.setLayoutManager(new GridLayoutManager(this, 2)); + binding.likedWorksRecycler.setAdapter(likedWorksAdapter); + + // 设置收藏列表 + collectedWorksAdapter = new WorksAdapter(work -> { + if (work != null && work.getId() != null) { + WorkDetailActivity.start(this, String.valueOf(work.getId()), false); + } + }); + binding.collectedWorksRecycler.setLayoutManager(new GridLayoutManager(this, 2)); + binding.collectedWorksRecycler.setAdapter(collectedWorksAdapter); + + // Tab切换点击事件 + binding.tabWorks.setOnClickListener(v -> switchToTab(0)); + binding.tabLiked.setOnClickListener(v -> switchToTab(1)); + binding.tabCollected.setOnClickListener(v -> switchToTab(2)); + // 发布按钮点击事件 binding.myWorksPublishBtn.setOnClickListener(v -> { if (!AuthHelper.requireLogin(this, "发布作品需要登录")) { @@ -581,7 +597,119 @@ public class ProfileActivity extends AppCompatActivity { PublishCenterActivity.start(this); }); - loadMyWorks(); + // 默认显示作品Tab + switchToTab(0); + } + + private int currentWorksTab = 0; + private WorksAdapter likedWorksAdapter; + private WorksAdapter collectedWorksAdapter; + + private void switchToTab(int tabIndex) { + currentWorksTab = tabIndex; + + // 更新Tab样式 + binding.tabWorks.setTextColor(tabIndex == 0 ? 0xFF111111 : 0xFF999999); + binding.tabWorks.setTypeface(null, tabIndex == 0 ? android.graphics.Typeface.BOLD : android.graphics.Typeface.NORMAL); + binding.tabLiked.setTextColor(tabIndex == 1 ? 0xFF111111 : 0xFF999999); + binding.tabLiked.setTypeface(null, tabIndex == 1 ? android.graphics.Typeface.BOLD : android.graphics.Typeface.NORMAL); + binding.tabCollected.setTextColor(tabIndex == 2 ? 0xFF111111 : 0xFF999999); + binding.tabCollected.setTypeface(null, tabIndex == 2 ? android.graphics.Typeface.BOLD : android.graphics.Typeface.NORMAL); + + // 隐藏所有列表 + binding.myWorksRecycler.setVisibility(View.GONE); + binding.likedWorksRecycler.setVisibility(View.GONE); + binding.collectedWorksRecycler.setVisibility(View.GONE); + binding.myWorksEmptyState.setVisibility(View.GONE); + + // 根据Tab加载数据 + switch (tabIndex) { + case 0: + loadMyWorks(); + break; + case 1: + loadLikedWorks(); + break; + case 2: + loadCollectedWorks(); + break; + } + } + + private void loadLikedWorks() { + if (!AuthHelper.isLoggedIn(this)) { + showEmptyState("赞过", "还没有点赞作品", false); + return; + } + + // 调用获取我点赞的作品列表API + ApiClient.getService(this).getMyLikedWorks(1, 50).enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, + Response>> response) { + if (response.isSuccessful() && response.body() != null && response.body().isOk()) { + PageResponse pageData = response.body().getData(); + if (pageData != null && pageData.getList() != null && !pageData.getList().isEmpty()) { + List likedWorks = pageData.getList(); + binding.likedWorksRecycler.setVisibility(View.VISIBLE); + binding.myWorksEmptyState.setVisibility(View.GONE); + binding.myWorksCount.setText(likedWorks.size() + "个赞过"); + likedWorksAdapter.submitList(likedWorks); + return; + } + } + showEmptyState("赞过", "还没有点赞作品", false); + } + + @Override + public void onFailure(Call>> call, Throwable t) { + Log.e(TAG, "加载点赞作品失败: " + t.getMessage()); + showEmptyState("赞过", "还没有点赞作品", false); + } + }); + } + + private void loadCollectedWorks() { + if (!AuthHelper.isLoggedIn(this)) { + showEmptyState("收藏", "还没有收藏作品", false); + return; + } + + // 调用获取我收藏的作品列表API + ApiClient.getService(this).getMyCollectedWorks(1, 50).enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, + Response>> response) { + if (response.isSuccessful() && response.body() != null && response.body().isOk()) { + PageResponse pageData = response.body().getData(); + if (pageData != null && pageData.getList() != null && !pageData.getList().isEmpty()) { + List collectedWorks = pageData.getList(); + binding.collectedWorksRecycler.setVisibility(View.VISIBLE); + binding.myWorksEmptyState.setVisibility(View.GONE); + binding.myWorksCount.setText(collectedWorks.size() + "个收藏"); + collectedWorksAdapter.submitList(collectedWorks); + return; + } + } + showEmptyState("收藏", "还没有收藏作品", false); + } + + @Override + public void onFailure(Call>> call, Throwable t) { + Log.e(TAG, "加载收藏作品失败: " + t.getMessage()); + showEmptyState("收藏", "还没有收藏作品", false); + } + }); + } + + private void showEmptyState(String tabName, String message, boolean showPublishBtn) { + binding.myWorksRecycler.setVisibility(View.GONE); + binding.likedWorksRecycler.setVisibility(View.GONE); + binding.collectedWorksRecycler.setVisibility(View.GONE); + binding.myWorksEmptyState.setVisibility(View.VISIBLE); + binding.emptyStateText.setText(message); + binding.myWorksPublishBtn.setVisibility(showPublishBtn ? View.VISIBLE : View.GONE); + binding.myWorksCount.setText("0个" + tabName); } private void loadMyWorks() { @@ -642,7 +770,11 @@ public class ProfileActivity extends AppCompatActivity { private void showMyWorksEmpty() { binding.myWorksRecycler.setVisibility(View.GONE); + binding.likedWorksRecycler.setVisibility(View.GONE); + binding.collectedWorksRecycler.setVisibility(View.GONE); binding.myWorksEmptyState.setVisibility(View.VISIBLE); + binding.emptyStateText.setText("还没有发布作品"); + binding.myWorksPublishBtn.setVisibility(View.VISIBLE); binding.myWorksCount.setText("0个作品"); } @@ -675,9 +807,9 @@ public class ProfileActivity extends AppCompatActivity { // - pageSize (可选): 每页数量 // 返回数据格式: ApiResponse> // 标签页顺序:0-作品, 1-收藏, 2-赞过 - binding.tabWorks.setVisibility(index == 0 ? View.VISIBLE : View.GONE); + binding.tabWorksContent.setVisibility(index == 0 ? View.VISIBLE : View.GONE); binding.tabFavorites.setVisibility(index == 1 ? View.VISIBLE : View.GONE); - binding.tabLiked.setVisibility(index == 2 ? View.VISIBLE : View.GONE); + binding.tabLikedContent.setVisibility(index == 2 ? View.VISIBLE : View.GONE); // 当切换到作品标签页时,重新加载作品列表 if (index == 0) { @@ -1030,11 +1162,175 @@ public class ProfileActivity extends AppCompatActivity { } }); - // 加载收藏数(点赞的直播间数量) + // 加载点赞的直播间数量 loadLikedRoomsCount(); // 加载好友数量 loadFriendsCount(); + + // 加载收藏数量 + loadCollectionsCount(); + + // 加载获赞数量(作品点赞总数) + loadTotalLikesCount(); + } + + /** + * 加载收藏数(点赞的直播间数量) + */ + private void loadLikedRoomsCount() { + com.example.livestreaming.net.ApiService apiService = + com.example.livestreaming.net.ApiClient.getService(this); + retrofit2.Call>>> call = + apiService.getMyLikedRooms(1, 1); // 只获取第一页,用于获取总数 + + call.enqueue(new retrofit2.Callback>>>() { + @Override + public void onResponse(retrofit2.Call>>> call, + retrofit2.Response>>> response) { + if (response.isSuccessful() && response.body() != null) { + com.example.livestreaming.net.ApiResponse>> apiResponse = response.body(); + if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { + com.example.livestreaming.net.PageResponse> pageData = apiResponse.getData(); + Long total = pageData.getTotal(); + // 保存点赞数量供其他地方使用 + likedRoomsTotal = total != null ? total : 0; + } + } + } + + @Override + public void onFailure(retrofit2.Call>>> call, Throwable t) { + // 忽略错误,使用默认显示 + } + }); + } + + // 保存点赞直播间数量 + private long likedRoomsTotal = 0; + + // 保存收藏数量 + private long collectedWorksCount = 0; + private long collectedRoomsCount = 0; + + /** + * 加载收藏数量(作品+直播间) + */ + private void loadCollectionsCount() { + if (!AuthHelper.isLoggedIn(this)) { + return; + } + + // 重置计数 + collectedWorksCount = 0; + collectedRoomsCount = 0; + + // 加载收藏的作品数量 + ApiClient.getService(this).getMyCollectedWorks(1, 1) + .enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, + Response>> response) { + if (response.isSuccessful() && response.body() != null && response.body().isOk()) { + PageResponse pageData = response.body().getData(); + if (pageData != null) { + Long total = pageData.getTotal(); + collectedWorksCount = total != null ? total : 0; + } + } + // 更新总收藏数量显示 + updateCollectionsCountDisplay(); + } + + @Override + public void onFailure(Call>> call, Throwable t) { + Log.e(TAG, "加载收藏作品数量失败: " + t.getMessage()); + updateCollectionsCountDisplay(); + } + }); + + // 加载收藏的直播间数量(使用点赞的直播间作为收藏) + ApiClient.getService(this).getMyLikedRooms(1, 1) + .enqueue(new Callback>>>() { + @Override + public void onResponse(Call>>> call, + Response>>> response) { + if (response.isSuccessful() && response.body() != null && response.body().isOk()) { + PageResponse> pageData = response.body().getData(); + if (pageData != null) { + Long total = pageData.getTotal(); + collectedRoomsCount = total != null ? total : 0; + } + } + // 更新总收藏数量显示 + updateCollectionsCountDisplay(); + } + + @Override + public void onFailure(Call>>> call, Throwable t) { + Log.e(TAG, "加载收藏直播间数量失败: " + t.getMessage()); + updateCollectionsCountDisplay(); + } + }); + } + + /** + * 更新收藏数量显示 + */ + private void updateCollectionsCountDisplay() { + long totalCount = collectedWorksCount + collectedRoomsCount; + if (binding.collectionsCount != null) { + binding.collectionsCount.setText(totalCount + "个"); + } + } + + /** + * 加载获赞数量(统计所有作品的点赞总数) + */ + private void loadTotalLikesCount() { + if (!AuthHelper.isLoggedIn(this)) { + return; + } + + // 获取当前用户ID + String userIdStr = com.example.livestreaming.net.AuthStore.getUserId(this); + if (userIdStr == null || userIdStr.isEmpty()) { + return; + } + + int userId; + try { + userId = Integer.parseInt(userIdStr); + } catch (NumberFormatException e) { + return; + } + + // 获取用户的所有作品,然后统计点赞总数 + ApiClient.getService(this).getUserWorks(userId, 1, 100) + .enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, + Response>> response) { + if (response.isSuccessful() && response.body() != null && response.body().isOk()) { + PageResponse pageData = response.body().getData(); + if (pageData != null && pageData.getList() != null) { + long totalLikes = 0; + for (WorksResponse work : pageData.getList()) { + if (work.getLikeCount() != null) { + totalLikes += work.getLikeCount(); + } + } + // 更新获赞数量显示 + binding.likes.setText(totalLikes + "\n获赞"); + } + } + } + + @Override + public void onFailure(Call>> call, Throwable t) { + Log.e(TAG, "加载获赞数量失败: " + t.getMessage()); + } + }); } /** @@ -1089,41 +1385,6 @@ public class ProfileActivity extends AppCompatActivity { }); } - /** - * 加载收藏数(点赞的直播间数量) - */ - private void loadLikedRoomsCount() { - com.example.livestreaming.net.ApiService apiService = - com.example.livestreaming.net.ApiClient.getService(this); - retrofit2.Call>>> call = - apiService.getMyLikedRooms(1, 1); // 只获取第一页,用于获取总数 - - call.enqueue(new retrofit2.Callback>>>() { - @Override - public void onResponse(retrofit2.Call>>> call, - retrofit2.Response>>> response) { - if (response.isSuccessful() && response.body() != null) { - com.example.livestreaming.net.ApiResponse>> apiResponse = response.body(); - if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { - com.example.livestreaming.net.PageResponse> pageData = apiResponse.getData(); - Long total = pageData.getTotal(); - - // 更新快捷操作区域的收藏数 - android.widget.TextView likedRoomsCountText = findViewById(R.id.likedRoomsCount); - if (likedRoomsCountText != null) { - likedRoomsCountText.setText((total != null ? total : 0) + "个直播间"); - } - } - } - } - - @Override - public void onFailure(retrofit2.Call>>> call, Throwable t) { - // 忽略错误,使用默认显示 - } - }); - } - /** * 加载钱包余额 */ diff --git a/android-app/app/src/main/res/layout/activity_likes_list.xml b/android-app/app/src/main/res/layout/activity_likes_list.xml index 7cf4c6a0..c778503c 100644 --- a/android-app/app/src/main/res/layout/activity_likes_list.xml +++ b/android-app/app/src/main/res/layout/activity_likes_list.xml @@ -57,4 +57,29 @@ android:paddingBottom="16dp" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + + + + + + + + diff --git a/android-app/app/src/main/res/layout/activity_profile.xml b/android-app/app/src/main/res/layout/activity_profile.xml index d5d6af97..a9b9205d 100644 --- a/android-app/app/src/main/res/layout/activity_profile.xml +++ b/android-app/app/src/main/res/layout/activity_profile.xml @@ -212,7 +212,7 @@ android:layout_height="wrap_content" android:layout_marginStart="0dp" android:layout_marginEnd="0dp" - android:layout_marginTop="-58dp" + android:layout_marginTop="-80dp" android:background="@drawable/bg_white_16" android:padding="14dp" app:layout_constraintEnd_toEndOf="parent" @@ -224,7 +224,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:orientation="horizontal" - android:visibility="gone" + android:paddingBottom="12dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> @@ -265,7 +265,7 @@ android:id="@+id/bioText" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="12dp" + android:layout_marginTop="0dp" android:text="填写个人签名更容易获得关注,点击此处添加" android:textColor="#999999" android:textSize="12sp" @@ -340,19 +340,6 @@ android:textColor="#666666" android:textSize="11sp" /> - - @@ -366,215 +353,157 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tagScrollView"> - + android:orientation="horizontal" + app:layout_constraintTop_toTopOf="parent"> - + - + - - - - - - - - - - - - - + + android:layout_height="wrap_content" + android:layout_marginStart="6dp" + android:orientation="vertical"> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -701,7 +630,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/walletButton"> - + + android:textStyle="bold" + android:paddingEnd="16dp" /> + + + + + + + + + + + + @@ -882,7 +852,7 @@