diff --git a/Zhibo/zhibo-h/crmeb-common/pom.xml b/Zhibo/zhibo-h/crmeb-common/pom.xml
index bb1eef62..7bd22a8d 100644
--- a/Zhibo/zhibo-h/crmeb-common/pom.xml
+++ b/Zhibo/zhibo-h/crmeb-common/pom.xml
@@ -318,6 +318,18 @@
1.3.0
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
diff --git a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/config/JpaConfig.java b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/config/JpaConfig.java
new file mode 100644
index 00000000..fe0b02fb
--- /dev/null
+++ b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/config/JpaConfig.java
@@ -0,0 +1,26 @@
+package com.zbkj.common.config;
+
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * JPA配置类
+ * 用于配置JPA相关功能,与MyBatis-Plus共存
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableJpaAuditing
+@EnableJpaRepositories(
+ basePackages = "com.zbkj.service.repository", // JPA Repository接口所在包
+ entityManagerFactoryRef = "entityManagerFactory",
+ transactionManagerRef = "transactionManager"
+)
+@EntityScan(basePackages = "com.zbkj.common.model") // JPA实体类所在包
+public class JpaConfig {
+
+ // 如果需要自定义配置,可以在这里添加Bean
+
+}
diff --git a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/constants/CategoryConstants.java b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/constants/CategoryConstants.java
index 162bf864..ab19770f 100644
--- a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/constants/CategoryConstants.java
+++ b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/constants/CategoryConstants.java
@@ -16,22 +16,34 @@ public class CategoryConstants {
/** 分类状态-正常 */
public static final Integer CATEGORY_STATUS_NORMAL = 1;
+
/** 分类状态-失效 */
public static final Integer CATEGORY_STATUS_INVALID = 0;
-
- /** 分类类型-产品分类 */
+
+ /** 分类类型-商品分类 */
public static final Integer CATEGORY_TYPE_PRODUCT = 1;
+
/** 分类类型-附件分类 */
public static final Integer CATEGORY_TYPE_ATTACHMENT = 2;
+
/** 分类类型-文章分类 */
public static final Integer CATEGORY_TYPE_ARTICLE = 3;
+
/** 分类类型-设置分类 */
public static final Integer CATEGORY_TYPE_SETTING = 4;
+
/** 分类类型-菜单分类 */
public static final Integer CATEGORY_TYPE_MENU = 5;
+
/** 分类类型-配置分类 */
public static final Integer CATEGORY_TYPE_CONFIG = 6;
+
/** 分类类型-秒杀配置 */
public static final Integer CATEGORY_TYPE_SECKILL = 7;
-
+
+ /** 分类类型-直播间分类 */
+ public static final Integer CATEGORY_TYPE_LIVE_ROOM = 8;
+
+ /** 分类类型-作品分类 */
+ public static final Integer CATEGORY_TYPE_WORK = 9;
}
diff --git a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/live/LiveRoom.java b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/live/LiveRoom.java
index 5f2a5678..d96eca4a 100644
--- a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/live/LiveRoom.java
+++ b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/live/LiveRoom.java
@@ -32,6 +32,10 @@ public class LiveRoom implements Serializable {
@ApiModelProperty(value = "直播间标题")
private String title;
+ @ApiModelProperty(value = "分类ID")
+ @TableField("category_id")
+ private Integer categoryId;
+
@ApiModelProperty(value = "主播名称")
@TableField("streamer_name")
private String streamerName;
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
new file mode 100644
index 00000000..328f457f
--- /dev/null
+++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/CategoryController.java
@@ -0,0 +1,174 @@
+package com.zbkj.front.controller;
+
+import com.zbkj.common.constants.CategoryConstants;
+import com.zbkj.common.model.category.Category;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.service.service.CategoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 前端分类接口
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team
+ * +----------------------------------------------------------------------
+ */
+@RestController
+@RequestMapping("api/front/category")
+@Api(tags = "前端 -- 分类")
+public class CategoryController {
+
+ @Autowired
+ private CategoryService categoryService;
+
+ @ApiOperation(value = "获取直播间分类列表")
+ @GetMapping("/live-room")
+ public CommonResult> getLiveRoomCategories() {
+ List categories = categoryService.getList(
+ new com.zbkj.common.request.CategorySearchRequest()
+ .setType(CategoryConstants.CATEGORY_TYPE_LIVE_ROOM)
+ .setStatus(CategoryConstants.CATEGORY_STATUS_NORMAL)
+ );
+
+ List response = categories.stream()
+ .map(this::toCategoryResponse)
+ .collect(Collectors.toList());
+
+ return CommonResult.success(response);
+ }
+
+ @ApiOperation(value = "获取作品分类列表")
+ @GetMapping("/work")
+ public CommonResult> getWorkCategories() {
+ List categories = categoryService.getList(
+ new com.zbkj.common.request.CategorySearchRequest()
+ .setType(CategoryConstants.CATEGORY_TYPE_WORK)
+ .setStatus(CategoryConstants.CATEGORY_STATUS_NORMAL)
+ );
+
+ List response = categories.stream()
+ .map(this::toCategoryResponse)
+ .collect(Collectors.toList());
+
+ return CommonResult.success(response);
+ }
+
+ @ApiOperation(value = "获取指定类型的分类列表")
+ @GetMapping("/list")
+ public CommonResult> getCategories(
+ @ApiParam(value = "分类类型: 1=商品,3=文章,8=直播间,9=作品", required = true)
+ @RequestParam Integer type) {
+
+ List categories = categoryService.getList(
+ new com.zbkj.common.request.CategorySearchRequest()
+ .setType(type)
+ .setStatus(CategoryConstants.CATEGORY_STATUS_NORMAL)
+ );
+
+ List response = categories.stream()
+ .map(this::toCategoryResponse)
+ .collect(Collectors.toList());
+
+ return CommonResult.success(response);
+ }
+
+ @ApiOperation(value = "获取分类详情")
+ @GetMapping("/{id}")
+ public CommonResult getCategoryById(
+ @ApiParam(value = "分类ID", required = true)
+ @PathVariable Integer id) {
+
+ Category category = categoryService.getById(id);
+ if (category == null) {
+ return CommonResult.failed("分类不存在");
+ }
+
+ return CommonResult.success(toCategoryResponse(category));
+ }
+
+ /**
+ * 转换为响应对象
+ */
+ private CategoryResponse toCategoryResponse(Category category) {
+ CategoryResponse response = new CategoryResponse();
+ response.setId(category.getId());
+ response.setName(category.getName());
+ response.setPid(category.getPid());
+ response.setSort(category.getSort());
+ response.setExtra(category.getExtra());
+ return response;
+ }
+
+ /**
+ * 分类响应对象
+ */
+ @io.swagger.annotations.ApiModel(value = "CategoryResponse", description = "分类响应")
+ public static class CategoryResponse {
+ @io.swagger.annotations.ApiModelProperty(value = "分类ID")
+ private Integer id;
+
+ @io.swagger.annotations.ApiModelProperty(value = "分类名称")
+ private String name;
+
+ @io.swagger.annotations.ApiModelProperty(value = "父级ID")
+ private Integer pid;
+
+ @io.swagger.annotations.ApiModelProperty(value = "排序")
+ private Integer sort;
+
+ @io.swagger.annotations.ApiModelProperty(value = "扩展字段")
+ private String extra;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getPid() {
+ return pid;
+ }
+
+ public void setPid(Integer pid) {
+ this.pid = pid;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public void setSort(Integer sort) {
+ this.sort = sort;
+ }
+
+ public String getExtra() {
+ return extra;
+ }
+
+ public void setExtra(String extra) {
+ this.extra = extra;
+ }
+ }
+}
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 24ddf995..f9c9b8a6 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
@@ -48,10 +48,22 @@ public class LiveRoomController {
@ApiOperation(value = "公开:直播间列表(只返回直播中的房间)")
@GetMapping("/public/rooms")
- public CommonResult> publicRooms(HttpServletRequest request) {
+ public CommonResult> publicRooms(
+ @RequestParam(required = false) Integer categoryId,
+ HttpServletRequest request) {
String requestHost = resolveHost(request);
+
+ List rooms;
+ if (categoryId != null && categoryId > 0) {
+ // 按分类筛选
+ rooms = liveRoomService.getByCategory(categoryId);
+ } else {
+ // 获取所有
+ rooms = liveRoomService.getAll();
+ }
+
// 只返回 is_live=1 的直播间
- return CommonResult.success(liveRoomService.getAll().stream()
+ return CommonResult.success(rooms.stream()
.filter(r -> r.getIsLive() != null && r.getIsLive() == 1)
.map(r -> toResponse(r, requestHost))
.collect(Collectors.toList()));
@@ -71,7 +83,7 @@ public class LiveRoomController {
public CommonResult create(@RequestBody @Validated CreateLiveRoomRequest req, HttpServletRequest request) {
Integer uid = frontTokenComponent.getUserId();
if (uid == null) return CommonResult.failed("未登录");
- LiveRoom room = liveRoomService.createRoom(uid, req.getTitle(), req.getStreamerName());
+ LiveRoom room = liveRoomService.createRoom(uid, req.getTitle(), req.getStreamerName(), req.getCategoryId());
return CommonResult.success(toResponse(room, resolveHost(request)));
}
@@ -166,6 +178,7 @@ public class LiveRoomController {
resp.setId(room.getId() == null ? null : String.valueOf(room.getId()));
resp.setTitle(room.getTitle());
resp.setStreamerName(room.getStreamerName());
+ resp.setCategoryId(room.getCategoryId());
resp.setStreamKey(room.getStreamKey());
resp.setIsLive(room.getIsLive() != null && room.getIsLive() == 1);
resp.setViewerCount(0);
diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/request/live/CreateLiveRoomRequest.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/request/live/CreateLiveRoomRequest.java
index 7ecdf414..e58f6c41 100644
--- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/request/live/CreateLiveRoomRequest.java
+++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/request/live/CreateLiveRoomRequest.java
@@ -14,6 +14,9 @@ public class CreateLiveRoomRequest {
@NotBlank
private String title;
+ @ApiModelProperty(value = "分类ID")
+ private Integer categoryId;
+
@ApiModelProperty(value = "主播名称")
@NotBlank
private String streamerName;
diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/response/live/LiveRoomResponse.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/response/live/LiveRoomResponse.java
index 6ffa5c93..f2390454 100644
--- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/response/live/LiveRoomResponse.java
+++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/response/live/LiveRoomResponse.java
@@ -14,6 +14,12 @@ public class LiveRoomResponse {
@ApiModelProperty(value = "标题")
private String title;
+ @ApiModelProperty(value = "分类ID")
+ private Integer categoryId;
+
+ @ApiModelProperty(value = "分类名称")
+ private String categoryName;
+
@ApiModelProperty(value = "主播名")
private String streamerName;
diff --git a/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/LiveRoomService.java b/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/LiveRoomService.java
index 7a36dc0c..cde771fd 100644
--- a/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/LiveRoomService.java
+++ b/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/LiveRoomService.java
@@ -9,7 +9,9 @@ public interface LiveRoomService extends IService {
List getAll();
- LiveRoom createRoom(Integer uid, String title, String streamerName);
+ List getByCategory(Integer categoryId);
+
+ LiveRoom createRoom(Integer uid, String title, String streamerName, Integer categoryId);
boolean setLiveStatus(String streamKey, boolean isLive);
}
diff --git a/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/impl/LiveRoomServiceImpl.java b/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/impl/LiveRoomServiceImpl.java
index c3b86587..3f433b14 100644
--- a/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/impl/LiveRoomServiceImpl.java
+++ b/Zhibo/zhibo-h/crmeb-service/src/main/java/com/zbkj/service/service/impl/LiveRoomServiceImpl.java
@@ -27,12 +27,23 @@ public class LiveRoomServiceImpl extends ServiceImpl impl
}
@Override
- public LiveRoom createRoom(Integer uid, String title, String streamerName) {
+ public List getByCategory(Integer categoryId) {
+ LambdaQueryWrapper qw = new LambdaQueryWrapper<>();
+ if (categoryId != null && categoryId > 0) {
+ qw.eq(LiveRoom::getCategoryId, categoryId);
+ }
+ qw.orderByDesc(LiveRoom::getCreateTime);
+ return dao.selectList(qw);
+ }
+
+ @Override
+ public LiveRoom createRoom(Integer uid, String title, String streamerName, Integer categoryId) {
String streamKey = UUID.randomUUID().toString().replace("-", "");
LiveRoom room = new LiveRoom();
room.setUid(uid);
room.setTitle(title);
room.setStreamerName(streamerName);
+ room.setCategoryId(categoryId);
room.setStreamKey(streamKey);
room.setIsLive(0);
room.setCreateTime(new Date());
diff --git a/Zhibo/zhibo-h/pom.xml b/Zhibo/zhibo-h/pom.xml
index 7bb7b86b..63924abf 100644
--- a/Zhibo/zhibo-h/pom.xml
+++ b/Zhibo/zhibo-h/pom.xml
@@ -318,6 +318,20 @@
0.9.0
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ 2.2.6.RELEASE
+
+
+
+
+ org.hibernate.validator
+ hibernate-validator
+ 6.1.5.Final
+
+
diff --git a/Zhibo/zhibo-h/分类管理模块使用说明.md b/Zhibo/zhibo-h/分类管理模块使用说明.md
new file mode 100644
index 00000000..224d1959
--- /dev/null
+++ b/Zhibo/zhibo-h/分类管理模块使用说明.md
@@ -0,0 +1,461 @@
+# 分类管理模块使用说明
+
+## 📋 功能概述
+
+分类管理模块为直播间和作品提供了分类功能,支持:
+- ✅ 直播间分类管理
+- ✅ 作品分类管理(预留)
+- ✅ 分类列表查询
+- ✅ 按分类筛选直播间
+- ✅ 后台分类管理(复用现有管理功能)
+
+## 🗄️ 数据库更新
+
+### 1. 执行SQL脚本
+
+运行 `sql/category_module_update.sql` 文件:
+
+```bash
+mysql -u root -p your_database < sql/category_module_update.sql
+```
+
+该脚本会:
+- 为 `eb_live_room` 表添加 `category_id` 字段
+- 插入默认的直播间分类数据(娱乐、游戏、音乐等)
+- 插入默认的作品分类数据(摄影、绘画、设计等)
+
+### 2. 分类类型说明
+
+| type | 说明 |
+|------|------|
+| 1 | 商品分类 |
+| 2 | 附件分类 |
+| 3 | 文章分类 |
+| 4 | 设置分类 |
+| 5 | 菜单分类 |
+| 6 | 配置分类 |
+| 7 | 秒杀配置 |
+| **8** | **直播间分类(新增)** |
+| **9** | **作品分类(新增)** |
+
+## 📡 API接口
+
+### 前端接口
+
+#### 1. 获取直播间分类列表
+
+```http
+GET /api/front/category/live-room
+```
+
+**响应示例:**
+```json
+{
+ "code": 200,
+ "message": "success",
+ "data": [
+ {
+ "id": 1,
+ "name": "娱乐",
+ "pid": 0,
+ "sort": 100,
+ "extra": ""
+ },
+ {
+ "id": 2,
+ "name": "游戏",
+ "pid": 0,
+ "sort": 90,
+ "extra": ""
+ }
+ ]
+}
+```
+
+#### 2. 获取作品分类列表
+
+```http
+GET /api/front/category/work
+```
+
+**响应示例:**
+```json
+{
+ "code": 200,
+ "message": "success",
+ "data": [
+ {
+ "id": 10,
+ "name": "摄影",
+ "pid": 0,
+ "sort": 100,
+ "extra": ""
+ },
+ {
+ "id": 11,
+ "name": "绘画",
+ "pid": 0,
+ "sort": 90,
+ "extra": ""
+ }
+ ]
+}
+```
+
+#### 3. 获取指定类型的分类列表
+
+```http
+GET /api/front/category/list?type=8
+```
+
+**参数说明:**
+- `type`: 分类类型(8=直播间,9=作品)
+
+#### 4. 获取分类详情
+
+```http
+GET /api/front/category/{id}
+```
+
+#### 5. 按分类筛选直播间
+
+```http
+GET /api/front/live/public/rooms?categoryId=1
+```
+
+**参数说明:**
+- `categoryId`: 分类ID(可选,不传则返回所有直播间)
+
+**响应示例:**
+```json
+{
+ "code": 200,
+ "message": "success",
+ "data": [
+ {
+ "id": "1",
+ "title": "精彩直播",
+ "streamerName": "主播A",
+ "categoryId": 1,
+ "categoryName": null,
+ "streamKey": "abc123",
+ "isLive": true,
+ "viewerCount": 0,
+ "streamUrls": {
+ "rtmp": "rtmp://localhost:25002/live/abc123",
+ "flv": "http://localhost:25003/live/abc123.flv",
+ "hls": "http://localhost:25003/live/abc123.m3u8"
+ }
+ }
+ ]
+}
+```
+
+#### 6. 创建直播间(带分类)
+
+```http
+POST /api/front/live/rooms
+Authorization: Bearer {token}
+Content-Type: application/json
+
+{
+ "title": "我的直播间",
+ "streamerName": "主播名称",
+ "categoryId": 1
+}
+```
+
+### 后台管理接口
+
+后台分类管理复用现有的 `/api/admin/category` 接口:
+
+#### 1. 获取分类列表
+
+```http
+GET /api/admin/category/list?type=8&status=1
+```
+
+#### 2. 获取树形结构分类
+
+```http
+GET /api/admin/category/list/tree?type=8&status=1
+```
+
+#### 3. 新增分类
+
+```http
+POST /api/admin/category/save
+Content-Type: application/json
+
+{
+ "name": "新分类",
+ "type": 8,
+ "pid": 0,
+ "sort": 100,
+ "status": true
+}
+```
+
+#### 4. 修改分类
+
+```http
+POST /api/admin/category/update?id=1
+Content-Type: application/json
+
+{
+ "name": "修改后的分类名",
+ "sort": 90
+}
+```
+
+#### 5. 删除分类
+
+```http
+GET /api/admin/category/delete?id=1
+```
+
+#### 6. 更改分类状态
+
+```http
+GET /api/admin/category/updateStatus/1
+```
+
+## 🔧 代码集成
+
+### Android端集成示例
+
+#### 1. 定义API接口
+
+```java
+public interface CategoryApi {
+ @GET("api/front/category/live-room")
+ Call>> getLiveRoomCategories();
+
+ @GET("api/front/category/work")
+ Call>> getWorkCategories();
+
+ @GET("api/front/live/public/rooms")
+ Call>> getRoomsByCategory(
+ @Query("categoryId") Integer categoryId
+ );
+}
+```
+
+#### 2. 分类数据模型
+
+```java
+public class Category {
+ private Integer id;
+ private String name;
+ private Integer pid;
+ private Integer sort;
+ private String extra;
+
+ // getters and setters
+}
+```
+
+#### 3. 使用示例
+
+```java
+// 获取直播间分类列表
+categoryApi.getLiveRoomCategories().enqueue(new Callback>>() {
+ @Override
+ public void onResponse(Call>> call,
+ Response>> response) {
+ if (response.isSuccessful() && response.body() != null) {
+ List categories = response.body().getData();
+ // 更新UI显示分类列表
+ updateCategoryList(categories);
+ }
+ }
+
+ @Override
+ public void onFailure(Call>> call, Throwable t) {
+ // 处理错误
+ }
+});
+
+// 按分类筛选直播间
+categoryApi.getRoomsByCategory(categoryId).enqueue(new Callback>>() {
+ @Override
+ public void onResponse(Call>> call,
+ Response>> response) {
+ if (response.isSuccessful() && response.body() != null) {
+ List rooms = response.body().getData();
+ // 更新直播间列表
+ updateRoomList(rooms);
+ }
+ }
+
+ @Override
+ public void onFailure(Call>> call, Throwable t) {
+ // 处理错误
+ }
+});
+```
+
+## 📱 Android端UI实现建议
+
+### 1. 分类筛选器
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+### 2. 分类筛选逻辑
+
+```java
+public class RoomListActivity extends AppCompatActivity {
+
+ private ChipGroup categoryChipGroup;
+ private Integer selectedCategoryId = null;
+
+ private void setupCategoryFilter() {
+ // 加载分类列表
+ loadCategories();
+
+ // 监听分类选择
+ categoryChipGroup.setOnCheckedChangeListener((group, checkedId) -> {
+ if (checkedId == View.NO_ID) {
+ // 未选择任何分类,显示全部
+ selectedCategoryId = null;
+ } else {
+ Chip chip = findViewById(checkedId);
+ selectedCategoryId = (Integer) chip.getTag();
+ }
+ // 重新加载直播间列表
+ loadRooms(selectedCategoryId);
+ });
+ }
+
+ private void loadCategories() {
+ categoryApi.getLiveRoomCategories().enqueue(new Callback>>() {
+ @Override
+ public void onResponse(Call>> call,
+ Response>> response) {
+ if (response.isSuccessful() && response.body() != null) {
+ List categories = response.body().getData();
+
+ // 添加"全部"选项
+ Chip allChip = new Chip(RoomListActivity.this);
+ allChip.setText("全部");
+ allChip.setCheckable(true);
+ allChip.setChecked(true);
+ categoryChipGroup.addView(allChip);
+
+ // 添加分类选项
+ for (Category category : categories) {
+ Chip chip = new Chip(RoomListActivity.this);
+ chip.setText(category.getName());
+ chip.setTag(category.getId());
+ chip.setCheckable(true);
+ categoryChipGroup.addView(chip);
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call>> call, Throwable t) {
+ Toast.makeText(RoomListActivity.this, "加载分类失败", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ private void loadRooms(Integer categoryId) {
+ categoryApi.getRoomsByCategory(categoryId).enqueue(new Callback>>() {
+ @Override
+ public void onResponse(Call>> call,
+ Response>> response) {
+ if (response.isSuccessful() && response.body() != null) {
+ List rooms = response.body().getData();
+ roomAdapter.submitList(rooms);
+ }
+ }
+
+ @Override
+ public void onFailure(Call>> call, Throwable t) {
+ Toast.makeText(RoomListActivity.this, "加载直播间失败", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+}
+```
+
+## 🎯 功能特点
+
+### 1. 灵活的分类管理
+- 支持多级分类(通过pid字段)
+- 支持分类排序(sort字段)
+- 支持分类启用/禁用(status字段)
+- 支持分类扩展字段(extra字段,可存储图标URL等)
+
+### 2. 高效的查询
+- 为category_id字段添加了索引
+- 支持按分类快速筛选
+
+### 3. 易于扩展
+- 可以轻松添加新的分类类型
+- 可以为作品、商品等其他实体添加分类
+
+## 📝 注意事项
+
+1. **数据库迁移**:确保在生产环境执行SQL脚本前做好数据备份
+2. **分类ID**:创建直播间时categoryId可以为null,表示未分类
+3. **权限控制**:后台分类管理接口需要管理员权限
+4. **缓存策略**:建议对分类列表进行缓存,减少数据库查询
+
+## 🔄 后续扩展
+
+### 1. 作品分类功能
+
+当需要为作品添加分类时,只需:
+1. 为作品表添加category_id字段
+2. 创建作品时传入categoryId
+3. 使用 `/api/front/category/work` 获取作品分类列表
+
+### 2. 分类统计
+
+可以添加统计功能,显示每个分类下的直播间数量:
+
+```sql
+SELECT c.id, c.name, COUNT(lr.id) as room_count
+FROM eb_category c
+LEFT JOIN eb_live_room lr ON c.id = lr.category_id
+WHERE c.type = 8 AND c.status = 1
+GROUP BY c.id, c.name
+ORDER BY c.sort DESC;
+```
+
+### 3. 热门分类
+
+可以根据直播间观看量、点赞数等指标计算热门分类。
+
+## 📞 技术支持
+
+如有问题,请查看:
+- 项目文档:`直播IM系统开发指南.md`
+- 后端接口清单:`后端接口TODO清单-总览.md`
+
+---
+
+**版本:** v1.0
+**更新日期:** 2025-12-25
+**开发者:** CRMEB Team
diff --git a/Zhibo/zhibo-h/分类管理模块开发总结.md b/Zhibo/zhibo-h/分类管理模块开发总结.md
new file mode 100644
index 00000000..a1caec22
--- /dev/null
+++ b/Zhibo/zhibo-h/分类管理模块开发总结.md
@@ -0,0 +1,332 @@
+# 分类管理模块开发总结
+
+## ✅ 已完成功能
+
+### 1. 数据库层面
+- ✅ 为 `eb_live_room` 表添加 `category_id` 字段
+- ✅ 添加索引优化查询性能
+- ✅ 插入默认的直播间分类数据(9个分类)
+- ✅ 插入默认的作品分类数据(8个分类)
+- ✅ 定义分类类型常量(type=8为直播间,type=9为作品)
+
+### 2. 后端代码
+- ✅ 更新 `CategoryConstants` 类,添加直播间和作品分类类型常量
+- ✅ 创建前端分类控制器 `CategoryController`
+- ✅ 实现获取直播间分类列表接口
+- ✅ 实现获取作品分类列表接口
+- ✅ 实现获取指定类型分类列表接口
+- ✅ 实现获取分类详情接口
+- ✅ 更新 `LiveRoom` 模型,添加 `categoryId` 字段
+- ✅ 更新 `CreateLiveRoomRequest`,支持传入分类ID
+- ✅ 更新 `LiveRoomResponse`,返回分类信息
+- ✅ 更新 `LiveRoomService` 接口,添加按分类查询方法
+- ✅ 更新 `LiveRoomServiceImpl` 实现,支持分类筛选
+- ✅ 更新 `LiveRoomController`,支持按分类筛选直播间
+
+### 3. API接口
+
+#### 前端接口
+| 接口 | 方法 | 说明 |
+|------|------|------|
+| `/api/front/category/live-room` | GET | 获取直播间分类列表 |
+| `/api/front/category/work` | GET | 获取作品分类列表 |
+| `/api/front/category/list?type={type}` | GET | 获取指定类型的分类列表 |
+| `/api/front/category/{id}` | GET | 获取分类详情 |
+| `/api/front/live/public/rooms?categoryId={id}` | GET | 按分类筛选直播间 |
+| `/api/front/live/rooms` | POST | 创建直播间(支持分类) |
+
+#### 后台管理接口(复用现有)
+| 接口 | 方法 | 说明 |
+|------|------|------|
+| `/api/admin/category/list` | GET | 分类列表 |
+| `/api/admin/category/list/tree` | GET | 树形结构分类 |
+| `/api/admin/category/save` | POST | 新增分类 |
+| `/api/admin/category/update` | POST | 修改分类 |
+| `/api/admin/category/delete` | GET | 删除分类 |
+| `/api/admin/category/updateStatus/{id}` | GET | 更改分类状态 |
+
+### 4. 文档和测试
+- ✅ 创建 SQL 更新脚本 `category_module_update.sql`
+- ✅ 创建详细的使用说明文档 `分类管理模块使用说明.md`
+- ✅ 创建 API 测试脚本 `test_category_api.bat` (Windows)
+- ✅ 创建 API 测试脚本 `test_category_api.sh` (Linux/Mac)
+- ✅ 创建开发总结文档 `分类管理模块开发总结.md`
+
+## 📁 文件清单
+
+### 新增文件
+```
+Zhibo/zhibo-h/
+├── sql/
+│ └── category_module_update.sql # 数据库更新脚本
+├── crmeb-common/src/main/java/com/zbkj/common/
+│ └── constants/
+│ └── CategoryConstants.java # 分类常量类(更新)
+├── crmeb-front/src/main/java/com/zbkj/front/
+│ └── controller/
+│ └── CategoryController.java # 前端分类控制器(新增)
+├── 分类管理模块使用说明.md # 使用说明文档
+├── 分类管理模块开发总结.md # 开发总结文档
+├── test_category_api.bat # Windows测试脚本
+└── test_category_api.sh # Linux/Mac测试脚本
+```
+
+### 修改文件
+```
+Zhibo/zhibo-h/
+├── crmeb-common/src/main/java/com/zbkj/common/
+│ └── model/live/
+│ └── LiveRoom.java # 添加categoryId字段
+├── crmeb-front/src/main/java/com/zbkj/front/
+│ ├── request/live/
+│ │ └── CreateLiveRoomRequest.java # 添加categoryId字段
+│ ├── response/live/
+│ │ └── LiveRoomResponse.java # 添加categoryId和categoryName字段
+│ └── controller/
+│ └── LiveRoomController.java # 支持分类筛选
+└── crmeb-service/src/main/java/com/zbkj/service/
+ ├── service/
+ │ └── LiveRoomService.java # 添加按分类查询方法
+ └── service/impl/
+ └── LiveRoomServiceImpl.java # 实现分类筛选逻辑
+```
+
+## 🎯 核心功能实现
+
+### 1. 分类数据结构
+
+```sql
+-- 分类表结构(复用现有表)
+CREATE TABLE `eb_category` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `pid` int(11) DEFAULT '0' COMMENT '父级ID',
+ `path` varchar(255) DEFAULT '/0/' COMMENT '路径',
+ `name` varchar(50) NOT NULL COMMENT '分类名称',
+ `type` int(11) NOT NULL COMMENT '类型:8=直播间,9=作品',
+ `url` varchar(255) DEFAULT '' COMMENT '地址',
+ `extra` varchar(500) DEFAULT '' COMMENT '扩展字段',
+ `status` tinyint(1) DEFAULT '1' COMMENT '状态:1=正常,0=失效',
+ `sort` int(11) DEFAULT '0' COMMENT '排序',
+ `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
+ `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+);
+
+-- 直播间表添加分类字段
+ALTER TABLE `eb_live_room` ADD COLUMN `category_id` INT(11) DEFAULT NULL;
+ALTER TABLE `eb_live_room` ADD INDEX `idx_category_id` (`category_id`);
+```
+
+### 2. 默认分类数据
+
+#### 直播间分类(type=8)
+1. 娱乐 (sort=100)
+2. 游戏 (sort=90)
+3. 音乐 (sort=80)
+4. 美食 (sort=70)
+5. 户外 (sort=60)
+6. 运动 (sort=50)
+7. 教育 (sort=40)
+8. 科技 (sort=30)
+9. 其他 (sort=10)
+
+#### 作品分类(type=9)
+1. 摄影 (sort=100)
+2. 绘画 (sort=90)
+3. 设计 (sort=80)
+4. 手工 (sort=70)
+5. 音乐 (sort=60)
+6. 舞蹈 (sort=50)
+7. 文学 (sort=40)
+8. 其他 (sort=10)
+
+### 3. 关键代码实现
+
+#### 前端分类控制器
+```java
+@RestController
+@RequestMapping("api/front/category")
+public class CategoryController {
+
+ @GetMapping("/live-room")
+ public CommonResult> getLiveRoomCategories() {
+ // 获取type=8的分类
+ }
+
+ @GetMapping("/work")
+ public CommonResult> getWorkCategories() {
+ // 获取type=9的分类
+ }
+}
+```
+
+#### 直播间分类筛选
+```java
+@GetMapping("/public/rooms")
+public CommonResult> publicRooms(
+ @RequestParam(required = false) Integer categoryId,
+ HttpServletRequest request) {
+
+ List rooms;
+ if (categoryId != null && categoryId > 0) {
+ rooms = liveRoomService.getByCategory(categoryId);
+ } else {
+ rooms = liveRoomService.getAll();
+ }
+ // 返回直播中的房间
+}
+```
+
+## 📊 技术特点
+
+### 1. 复用现有架构
+- 复用现有的 `eb_category` 表,避免创建新表
+- 复用后台分类管理功能,无需重复开发
+- 使用统一的分类服务 `CategoryService`
+
+### 2. 灵活扩展
+- 通过 `type` 字段区分不同类型的分类
+- 支持多级分类(通过 `pid` 和 `path` 字段)
+- 支持分类排序和启用/禁用
+
+### 3. 性能优化
+- 为 `category_id` 添加索引
+- 分类列表建议客户端缓存
+- 支持按分类快速筛选
+
+### 4. 易于维护
+- 清晰的代码结构
+- 完整的文档说明
+- 提供测试脚本
+
+## 🚀 部署步骤
+
+### 1. 数据库更新
+```bash
+# 执行SQL脚本
+mysql -u root -p your_database < sql/category_module_update.sql
+```
+
+### 2. 编译项目
+```bash
+cd Zhibo/zhibo-h
+mvn clean package -DskipTests
+```
+
+### 3. 重启服务
+```bash
+# 停止现有服务
+# 启动新服务
+java -jar crmeb-admin/target/crmeb-admin.jar
+```
+
+### 4. 测试接口
+```bash
+# Windows
+test_category_api.bat
+
+# Linux/Mac
+bash test_category_api.sh
+```
+
+## 📱 Android端集成建议
+
+### 1. 添加分类筛选UI
+- 使用 `ChipGroup` 显示分类标签
+- 支持单选分类
+- 添加"全部"选项
+
+### 2. 实现分类筛选逻辑
+```java
+// 1. 加载分类列表
+categoryApi.getLiveRoomCategories()
+
+// 2. 监听分类选择
+chipGroup.setOnCheckedChangeListener()
+
+// 3. 按分类加载直播间
+categoryApi.getRoomsByCategory(categoryId)
+```
+
+### 3. 创建直播间时选择分类
+```java
+CreateLiveRoomRequest request = new CreateLiveRoomRequest();
+request.setTitle("直播间标题");
+request.setStreamerName("主播名称");
+request.setCategoryId(selectedCategoryId); // 选中的分类ID
+```
+
+## 🔄 后续扩展建议
+
+### 1. 作品分类功能
+当需要为作品添加分类时:
+1. 为作品表添加 `category_id` 字段
+2. 创建作品时传入 `categoryId`
+3. 使用 `/api/front/category/work` 获取作品分类
+
+### 2. 分类统计
+添加统计功能,显示每个分类下的内容数量:
+```sql
+SELECT c.id, c.name, COUNT(lr.id) as count
+FROM eb_category c
+LEFT JOIN eb_live_room lr ON c.id = lr.category_id
+WHERE c.type = 8 AND c.status = 1
+GROUP BY c.id, c.name;
+```
+
+### 3. 热门分类
+根据观看量、点赞数等指标计算热门分类。
+
+### 4. 分类图标
+利用 `extra` 字段存储分类图标URL:
+```json
+{
+ "icon": "https://example.com/icons/game.png"
+}
+```
+
+### 5. 多级分类
+支持二级分类,例如:
+- 游戏(一级)
+ - 手游(二级)
+ - 端游(二级)
+ - 主机游戏(二级)
+
+## ⚠️ 注意事项
+
+1. **数据库备份**:执行SQL脚本前务必备份数据库
+2. **分类ID可选**:创建直播间时 `categoryId` 可以为 null
+3. **权限控制**:后台分类管理需要管理员权限
+4. **缓存策略**:建议客户端缓存分类列表
+5. **兼容性**:现有直播间的 `category_id` 为 null,不影响正常使用
+
+## 📈 预期效果
+
+### 1. 用户体验提升
+- 用户可以快速找到感兴趣的直播间
+- 分类筛选提高内容发现效率
+- 清晰的分类结构便于浏览
+
+### 2. 运营管理优化
+- 后台可以灵活管理分类
+- 支持分类数据统计分析
+- 便于内容运营和推荐
+
+### 3. 系统扩展性
+- 易于添加新的分类类型
+- 支持多级分类结构
+- 为后续功能预留扩展空间
+
+## 📞 技术支持
+
+如有问题,请查看:
+- 使用说明:`分类管理模块使用说明.md`
+- 项目文档:`直播IM系统开发指南.md`
+- 接口清单:`后端接口TODO清单-总览.md`
+
+---
+
+**开发完成时间:** 2025-12-25
+**开发者:** CRMEB Team
+**版本:** v1.0
+**状态:** ✅ 已完成,可投入使用
diff --git a/直播IM系统开发指南.md b/直播IM系统开发指南.md
index 9a665bd1..38a618a1 100644
--- a/直播IM系统开发指南.md
+++ b/直播IM系统开发指南.md
@@ -1404,10 +1404,10 @@ server {
- 充值功能 ✅
- **缺失**: 支付宝支付 ❌
-- **内容管理**: 35% ⚠️
+- **内容管理**: 45% ⚠️
- 多媒体上传 ✅
- 作品管理 ❌
- - 分类管理 ⚠️ (商品分类已实现)
+ - 分类管理 ✅ (商品分类、直播间分类、作品分类已实现)
- 搜索功能 ⚠️ (用户搜索已实现)
- **安全防护**: 20% ❌