From b6a838acaa968e17f3439abc30212d5fca5ea676 Mon Sep 17 00:00:00 2001 From: xiao12feng8 <16507319+xiao12feng8@user.noreply.gitee.com> Date: Sun, 4 Jan 2026 17:07:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E4=BB=8E=E5=90=8E=E5=8F=B0=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../front/controller/CategoryController.java | 42 ++++++-- .../front/controller/LiveRoomController.java | 11 +- .../livestreaming/CategoryFilterManager.java | 8 +- .../example/livestreaming/MainActivity.java | 79 +++++++++++--- deploy-category-fix.bat | 68 ++++++++++++ 直播间分类功能修复说明.md | 101 ++++++++++++++++++ 6 files changed, 280 insertions(+), 29 deletions(-) create mode 100644 deploy-category-fix.bat create mode 100644 直播间分类功能修复说明.md diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/CategoryController.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/CategoryController.java index 05cad5a4..87591c4f 100644 --- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/CategoryController.java +++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/CategoryController.java @@ -2,8 +2,10 @@ package com.zbkj.front.controller; import com.zbkj.common.constants.CategoryConstants; import com.zbkj.common.model.category.Category; +import com.zbkj.common.model.live.LiveRoomCategory; import com.zbkj.common.result.CommonResult; import com.zbkj.service.service.CategoryService; +import com.zbkj.service.service.LiveRoomCategoryService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -33,17 +35,30 @@ public class CategoryController { @Autowired private CategoryService categoryService; + @Autowired + private LiveRoomCategoryService liveRoomCategoryService; + @ApiOperation(value = "获取直播间分类列表") - @GetMapping("/live-room") + @GetMapping("/live") public CommonResult> getLiveRoomCategories() { - List categories = categoryService.getList( - new com.zbkj.common.request.CategorySearchRequest() - .setType(CategoryConstants.CATEGORY_TYPE_LIVE_ROOM) - .setStatus(CategoryConstants.CATEGORY_STATUS_NORMAL) - ); + // 从 eb_live_room_category 表获取直播间分类 + List categories = liveRoomCategoryService.getEnabledList(); List response = categories.stream() - .map(this::toCategoryResponse) + .map(this::toLiveRoomCategoryResponse) + .collect(Collectors.toList()); + + return CommonResult.success(response); + } + + @ApiOperation(value = "获取直播间分类列表(兼容旧接口)") + @GetMapping("/live-room") + public CommonResult> getLiveRoomCategoriesOld() { + // 从 eb_live_room_category 表获取直播间分类 + List categories = liveRoomCategoryService.getEnabledList(); + + List response = categories.stream() + .map(this::toLiveRoomCategoryResponse) .collect(Collectors.toList()); return CommonResult.success(response); @@ -165,6 +180,19 @@ public class CategoryController { return response; } + /** + * 转换直播间分类为响应对象 + */ + private CategoryResponse toLiveRoomCategoryResponse(LiveRoomCategory category) { + CategoryResponse response = new CategoryResponse(); + response.setId(category.getId()); + response.setName(category.getName()); + response.setPid(0); // 直播间分类没有父级 + response.setSort(category.getSort()); + response.setExtra(category.getIcon()); // 使用icon作为extra + return response; + } + /** * 分类响应对象 */ diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/LiveRoomController.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/LiveRoomController.java index 99a7cbed..8a043646 100644 --- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/LiveRoomController.java +++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/LiveRoomController.java @@ -45,6 +45,9 @@ public class LiveRoomController { @Autowired private com.zbkj.service.service.CategoryService categoryService; + @Autowired + private com.zbkj.service.service.LiveRoomCategoryService liveRoomCategoryService; + @Autowired private com.zbkj.service.service.FollowRecordService followRecordService; @@ -610,12 +613,12 @@ public class LiveRoomController { } } - // 获取分类名称 + // 获取分类名称(从 eb_live_room_category 表) if (room.getCategoryId() != null) { try { - com.zbkj.common.model.category.Category category = categoryService.getById(room.getCategoryId()); - if (category != null) { - resp.setCategoryName(category.getName()); + com.zbkj.common.model.live.LiveRoomCategory liveCategory = liveRoomCategoryService.getById(room.getCategoryId()); + if (liveCategory != null) { + resp.setCategoryName(liveCategory.getName()); } } catch (Exception e) { // 忽略错误 diff --git a/android-app/app/src/main/java/com/example/livestreaming/CategoryFilterManager.java b/android-app/app/src/main/java/com/example/livestreaming/CategoryFilterManager.java index 99d5e2ba..672b3612 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/CategoryFilterManager.java +++ b/android-app/app/src/main/java/com/example/livestreaming/CategoryFilterManager.java @@ -180,8 +180,12 @@ public class CategoryFilterManager { List filtered = new ArrayList<>(); for (Room r : allRooms) { if (r == null) continue; - String roomType = r.getType(); - if (c.equals(roomType)) { + // 优先使用 categoryName 筛选,如果没有则使用 type + String roomCategory = r.getCategoryName(); + if (roomCategory == null || roomCategory.isEmpty()) { + roomCategory = r.getType(); + } + if (c.equals(roomCategory)) { filtered.add(r); } } diff --git a/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java b/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java index f6dcad45..4d8d8c59 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java @@ -90,6 +90,9 @@ public class MainActivity extends AppCompatActivity { private String currentTopTab = "发现"; // 当前选中的顶部标签:关注、发现、附近 private CategoryFilterManager filterManager; private int filterRequestId = 0; // 用于防止旧的筛选结果覆盖新的结果 + + // 缓存后端返回的所有直播间分类 + private final List allBackendCategories = new ArrayList<>(); private final Handler handler = new Handler(Looper.getMainLooper()); private Runnable pollRunnable; @@ -1488,7 +1491,7 @@ public class MainActivity extends AppCompatActivity { */ private void applyCategoryFilterSync(String category) { String c = category != null ? category : "推荐"; - if ("推荐".equals(c)) { + if ("推荐".equals(c) || "全部".equals(c)) { // 添加淡入动画,保持与其他筛选场景的一致性 binding.roomsRecyclerView.animate() .alpha(0.7f) @@ -1509,8 +1512,12 @@ public class MainActivity extends AppCompatActivity { List filtered = new ArrayList<>(); for (Room r : allRooms) { if (r == null) continue; - String roomType = r.getType(); - if (c.equals(roomType)) { + // 优先使用 categoryName 筛选,如果没有则使用 type + String roomCategory = r.getCategoryName(); + if (roomCategory == null || roomCategory.isEmpty()) { + roomCategory = r.getType(); + } + if (c.equals(roomCategory)) { filtered.add(r); } } @@ -1682,6 +1689,10 @@ public class MainActivity extends AppCompatActivity { private void updateCategoryTabs(List categories) { if (binding == null || binding.categoryTabs == null) return; + // 缓存后端分类数据,供频道管理对话框使用 + allBackendCategories.clear(); + allBackendCategories.addAll(categories); + runOnUiThread(() -> { // 清空现有标签 binding.categoryTabs.removeAllTabs(); @@ -3185,6 +3196,18 @@ public class MainActivity extends AppCompatActivity { // 从SharedPreferences加载 android.content.SharedPreferences prefs = getSharedPreferences("channel_prefs", MODE_PRIVATE); + + // 检查是否需要迁移到新版本(使用后端分类) + int savedVersion = prefs.getInt("channel_version", 0); + if (savedVersion < 2) { + // 旧版本数据,清除并使用后端分类 + prefs.edit() + .remove("my_channels") + .putInt("channel_version", 2) + .apply(); + Log.d(TAG, "loadMyChannels() 清除旧版本频道数据,使用后端分类"); + } + String savedChannels = prefs.getString("my_channels", null); if (savedChannels != null && !savedChannels.isEmpty()) { @@ -3194,12 +3217,27 @@ public class MainActivity extends AppCompatActivity { String.valueOf(i), channelNames[i], i < 4)); } } else { - // 默认频道:推荐、直播、视频、音乐、游戏 - channels.add(new ChannelManagerAdapter.ChannelItem("0", "推荐", true)); - channels.add(new ChannelManagerAdapter.ChannelItem("1", "直播", true)); - channels.add(new ChannelManagerAdapter.ChannelItem("2", "视频", true)); - channels.add(new ChannelManagerAdapter.ChannelItem("3", "音乐", true)); - channels.add(new ChannelManagerAdapter.ChannelItem("4", "游戏", false)); + // 使用后端分类作为默认频道(如果有的话) + if (!allBackendCategories.isEmpty()) { + // 添加"推荐"作为第一个固定频道 + channels.add(new ChannelManagerAdapter.ChannelItem("0", "推荐", true)); + // 添加后端分类(最多取前4个作为默认) + int count = Math.min(allBackendCategories.size(), 4); + for (int i = 0; i < count; i++) { + com.example.livestreaming.net.CategoryResponse cat = allBackendCategories.get(i); + if (cat != null && cat.getName() != null) { + channels.add(new ChannelManagerAdapter.ChannelItem( + String.valueOf(cat.getId()), cat.getName(), true)); + } + } + } else { + // 后端分类未加载,使用硬编码默认值 + channels.add(new ChannelManagerAdapter.ChannelItem("0", "推荐", true)); + channels.add(new ChannelManagerAdapter.ChannelItem("1", "娱乐", true)); + channels.add(new ChannelManagerAdapter.ChannelItem("2", "游戏", true)); + channels.add(new ChannelManagerAdapter.ChannelItem("3", "音乐", true)); + channels.add(new ChannelManagerAdapter.ChannelItem("4", "户外", true)); + } } return channels; @@ -3226,20 +3264,29 @@ public class MainActivity extends AppCompatActivity { * 加载推荐频道列表(排除已添加的) */ private List loadRecommendChannels(List myChannels) { - // 所有可用频道 - String[] allChannels = {"推荐", "直播", "视频", "音乐", "游戏", "才艺", "户外", "美食", "舞蹈", "聊天", "二次元", "体育"}; - // 获取已添加的频道名称 java.util.Set addedNames = new java.util.HashSet<>(); for (ChannelManagerAdapter.ChannelItem item : myChannels) { addedNames.add(item.getName()); } - // 过滤出未添加的频道 List recommendList = new ArrayList<>(); - for (int i = 0; i < allChannels.length; i++) { - if (!addedNames.contains(allChannels[i])) { - recommendList.add(new ChannelManagerAdapter.ChannelItem(String.valueOf(i), allChannels[i])); + + // 优先使用后端分类 + if (!allBackendCategories.isEmpty()) { + for (com.example.livestreaming.net.CategoryResponse cat : allBackendCategories) { + if (cat != null && cat.getName() != null && !addedNames.contains(cat.getName())) { + recommendList.add(new ChannelManagerAdapter.ChannelItem( + String.valueOf(cat.getId()), cat.getName())); + } + } + } else { + // 后端分类未加载,使用硬编码默认值 + String[] defaultChannels = {"娱乐", "游戏", "音乐", "户外", "聊天"}; + for (int i = 0; i < defaultChannels.length; i++) { + if (!addedNames.contains(defaultChannels[i])) { + recommendList.add(new ChannelManagerAdapter.ChannelItem(String.valueOf(i), defaultChannels[i])); + } } } diff --git a/deploy-category-fix.bat b/deploy-category-fix.bat new file mode 100644 index 00000000..78cabad8 --- /dev/null +++ b/deploy-category-fix.bat @@ -0,0 +1,68 @@ +@echo off +chcp 65001 >nul +echo ======================================== +echo 部署直播间分类功能修复 +echo ======================================== + +echo. +echo 此脚本将部署以下修改: +echo 1. 后端 CategoryController - 从 eb_live_room_category 表获取分类 +echo 2. 后端 LiveRoomController - 正确设置直播间的 categoryName +echo 3. Android 端分类筛选逻辑 - 使用 categoryName 筛选 +echo. + +echo ======================================== +echo 步骤1: 编译后端代码 +echo ======================================== +cd Zhibo\zhibo-h +call mvn clean package -DskipTests -pl crmeb-front -am +if %errorlevel% neq 0 ( + echo 编译失败! + pause + exit /b 1 +) + +echo. +echo ======================================== +echo 步骤2: 部署到服务器 +echo ======================================== +echo 请手动将以下文件上传到服务器: +echo - Zhibo\zhibo-h\crmeb-front\target\crmeb-front.jar +echo. +echo 然后在服务器上重启后端服务: +echo systemctl restart zhibo-backend +echo 或 +echo docker restart zhibo-backend +echo. + +echo ======================================== +echo 步骤3: 重新编译 Android 应用 +echo ======================================== +cd ..\..\android-app +call gradlew assembleDebug +if %errorlevel% neq 0 ( + echo Android 编译失败! + pause + exit /b 1 +) + +echo. +echo ======================================== +echo 部署完成! +echo ======================================== +echo. +echo 修改说明: +echo - 后端 /api/front/category/live 接口现在从 eb_live_room_category 表获取分类 +echo - 直播间列表接口现在正确返回 categoryName 字段 +echo - Android 端分类筛选现在使用 categoryName 而不是 type +echo. +echo 数据库中的分类数据: +echo 1. 娱乐 +echo 2. 游戏 +echo 3. 音乐 +echo 4. 户外 +echo 5. 聊天 +echo. +echo 如果直播间没有设置分类,将显示在"推荐"标签下。 +echo. +pause diff --git a/直播间分类功能修复说明.md b/直播间分类功能修复说明.md new file mode 100644 index 00000000..15b9e347 --- /dev/null +++ b/直播间分类功能修复说明.md @@ -0,0 +1,101 @@ +# 直播间分类功能修复说明 + +## 问题描述 +1. App首页的分类标签(推荐、直播、视频、音乐、游戏)是硬编码的,没有从后台数据库动态获取 +2. 频道管理对话框中的"我的频道"和"推荐频道"也是硬编码的 + +## 数据库分类数据 +```sql +SELECT * FROM eb_live_room_category ORDER BY sort; +-- 结果: +-- id=1, name=娱乐, icon=el-icon-video-camera, sort=1 +-- id=2, name=游戏, icon=el-icon-coordinate, sort=2 +-- id=3, name=音乐, icon=el-icon-headset, sort=3 +-- id=4, name=户外, icon=el-icon-location, sort=4 +-- id=5, name=聊天, icon=el-icon-chat-dot-round, sort=5 +``` + +## 修改内容 + +### 1. 后端 CategoryController +**文件**: `Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/CategoryController.java` + +**修改**: +- 注入 `LiveRoomCategoryService` +- 修改 `/api/front/category/live` 接口,从 `eb_live_room_category` 表获取分类 +- 添加兼容旧接口 `/api/front/category/live-room` + +### 2. 后端 LiveRoomController +**文件**: `Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/LiveRoomController.java` + +**修改**: +- 注入 `LiveRoomCategoryService` +- 修改 `toResponse` 方法,从 `eb_live_room_category` 表获取分类名称设置到 `categoryName` 字段 + +### 3. Android MainActivity +**文件**: `android-app/app/src/main/java/com/example/livestreaming/MainActivity.java` + +**修改**: +- 添加 `allBackendCategories` 成员变量缓存后端分类数据 +- `updateCategoryTabs` 方法:缓存后端分类数据 +- `loadMyChannels` 方法:使用后端分类作为默认频道(推荐 + 前4个后端分类) +- `loadRecommendChannels` 方法:从后端分类中过滤出未添加的频道 +- `applyCategoryFilterSync` 方法:优先使用 `categoryName` 筛选 + +### 4. Android CategoryFilterManager +**文件**: `android-app/app/src/main/java/com/example/livestreaming/CategoryFilterManager.java` + +**修改**: +- `filterRoomsSync` 方法:优先使用 `categoryName` 筛选 + +## 工作流程 + +1. **App启动时**: + - `MainActivity.loadCategoriesFromBackend()` 调用 `/api/front/category/live` 接口 + - 后端从 `eb_live_room_category` 表获取启用的分类列表 + - App缓存分类数据到 `allBackendCategories` + - App动态创建分类标签(推荐 + 后端返回的分类) + +2. **打开频道管理对话框时**: + - "我的频道":从 SharedPreferences 加载用户已选择的频道,如果没有则使用默认值(推荐 + 前4个后端分类) + - "推荐频道":从 `allBackendCategories` 中过滤出未添加到"我的频道"的分类 + +3. **获取直播间列表时**: + - 调用 `/api/front/live/public/rooms` 接口 + - 后端返回直播间数据,包含 `categoryId` 和 `categoryName` + - `categoryName` 从 `eb_live_room_category` 表获取 + +4. **分类筛选时**: + - 用户点击分类标签 + - App根据 `categoryName` 筛选直播间 + - 如果直播间没有设置分类(`categoryName` 为空),则只在"推荐"标签下显示 + +## 部署步骤 + +1. **编译后端**: + ```bash + cd Zhibo/zhibo-h + mvn clean package -DskipTests -pl crmeb-front -am + ``` + +2. **部署后端**: + - 上传 `crmeb-front.jar` 到服务器 + - 重启后端服务 + +3. **编译Android**: + ```bash + cd android-app + gradlew assembleDebug + ``` + +4. **安装测试**: + - 安装新的APK + - 检查分类标签是否显示为:推荐、娱乐、游戏、音乐、户外、聊天 + - 点击展开箭头,检查频道管理对话框是否显示后端分类 + +## 注意事项 + +- 如果直播间没有设置 `category_id`,该直播间只会在"推荐"标签下显示 +- 创建直播间时需要选择分类,分类ID会保存到 `eb_live_room.category_id` 字段 +- 后台管理可以在"直播管理 > 直播分类"中管理分类 +- 新添加的分类会自动出现在"推荐频道"列表中