diff --git a/schoolNewsServ/.bin/mysql/sql/RESOURCE_CATEGORY_REMOVAL.md b/schoolNewsServ/.bin/mysql/sql/RESOURCE_CATEGORY_REMOVAL.md new file mode 100644 index 0000000..e3b666d --- /dev/null +++ b/schoolNewsServ/.bin/mysql/sql/RESOURCE_CATEGORY_REMOVAL.md @@ -0,0 +1,276 @@ +# ResourceCategory 移除清单 + +## 📝 概述 + +本文档记录了 `ResourceCategory` 相关功能的完整移除过程。原资源分类功能已完全迁移到标签系统(`tb_tag` 的 `tag_type=1`)。 + +--- + +## ✅ 已完成的操作 + +### 1. 数据库层面 + +#### 已注释的建表语句 +**文件:** `.bin\mysql\sql\createTableResource.sql` + +```sql +-- 资源分类表(已废弃,使用 tb_tag 表的 tag_type=1 代替) +-- DROP TABLE IF EXISTS `tb_resource_category`; +-- CREATE TABLE `tb_resource_category` ( +-- ... +-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='资源分类表'; +-- +-- ⚠️ 注意:资源分类功能已迁移到 tb_tag 表中,使用 tag_type=1 表示文章分类标签 +``` + +#### 已注释的初始化数据 +**文件:** `.bin\mysql\sql\initAllData.sql` + +```sql +-- 插入资源分类数据(已废弃,使用下方的 tb_tag 数据代替) +-- INSERT INTO `tb_resource_category` (id, category_id, name, description, order_num, creator, create_time) VALUES +-- ('1', 'party_history', '党史学习', '党史学习相关资源', 1, '1', now()), +-- ... +``` + +### 2. Java 代码层面 + +#### 已删除的文件(共7个) + +1. **实体类** + - ❌ `common\common-dto\src\main\java\org\xyzh\common\dto\resource\TbResourceCategory.java` + +2. **Service 层** + - ❌ `api\api-news\src\main\java\org\xyzh\api\news\category\ResourceCategoryService.java` + - ❌ `news\src\main\java\org\xyzh\news\service\NCResourceCategoryService.java` + - ❌ `news\src\main\java\org\xyzh\news\service\impl\NCResourceCategoryServiceImpl.java` + +3. **Controller 层** + - ❌ `news\src\main\java\org\xyzh\news\controller\ResourceCategoryController.java` + +4. **Mapper 层** + - ❌ `news\src\main\java\org\xyzh\news\mapper\ResourceCategoryMapper.java` + - ❌ `news\src\main\resources\mapper\ResourceCategoryMapper.xml` + +#### 已修改的文件(共2个) + +1. **ResourceVO.java** + - 删除了 `resourceCategory` 字段及其 getter/setter + - 保留 `tags` 字段用于存储标签列表(包含文章分类标签) + +**修改前:** +```java +public class ResourceVO { + private TbResource resource; + private TbResourceCategory resourceCategory; // ❌ 已删除 + private List tags; +} +``` + +**修改后:** +```java +public class ResourceVO { + private TbResource resource; + // ✅ 资源标签列表(包含文章分类标签 tag_type=1) + private List tags; +} +``` + +2. **ResourceCenterController.java** + - 修改 import 语句,移除 `TbResourceCategory`,添加 `TbTag` + - 修改返回类型:`ResultDomain` → `ResultDomain` + - 更新 TODO 注释,说明使用 `TagService.getTagsByType(1)` + +**关键修改:** +```java +// 修改前 +import org.xyzh.common.dto.resource.TbResourceCategory; +public ResultDomain getSpecialCategories() { ... } + +// 修改后 +import org.xyzh.common.dto.resource.TbTag; +public ResultDomain getSpecialCategories() { + // TODO: 使用 TagService.getTagsByType(1) 获取文章分类标签 +} +``` + +--- + +## 🔄 迁移映射关系 + +### API 接口映射 + +| 原接口 (ResourceCategory) | 新接口 (Tag) | 说明 | +|---------------------------|--------------|------| +| `GET /news/categorys/list` | `GET /news/tags/type/1` | 获取所有文章分类标签 | +| `GET /news/categorys/category/{id}` | `GET /news/tags/tag/{tagID}` | 获取单个标签详情 | +| `POST /news/categorys/category` | `POST /news/tags/tag` | 创建标签(需指定 tagType=1) | +| `PUT /news/categorys/category` | `PUT /news/tags/tag` | 更新标签 | +| `DELETE /news/categorys/category/{id}` | `DELETE /news/tags/tag/{tagID}` | 删除标签 | +| `GET /news/categorys/tree` | `GET /news/tags/type/1` | 获取分类树(可通过标签列表构建) | + +### 数据字段映射 + +| ResourceCategory 字段 | Tag 字段 | 说明 | +|----------------------|----------|------| +| `tagID` | `tagID` | 唯一标识 | +| `name` | `name` | 名称 | +| `description` | `description` | 描述 | +| `icon` | - | 图标(Tag中无此字段,可扩展) | +| `orderNum` | - | 排序号(可通过创建时间排序) | +| `parentID` | - | 父分类(Tag为扁平结构) | +| - | `tagType` | 标签类型(固定为1) | +| - | `color` | 标签颜色(新增字段) | + +### 代码调用映射 + +**修改前:** +```java +// 使用 ResourceCategoryService +ResourceCategoryService categoryService; +ResultDomain result = categoryService.getAllCategories(); +``` + +**修改后:** +```java +// 使用 TagService +TagService tagService; +ResultDomain result = tagService.getTagsByType(1); // 1 = 文章分类标签 +``` + +--- + +## ⚠️ 数据迁移注意事项 + +### 如果数据库中已有 tb_resource_category 数据 + +需要执行以下迁移 SQL: + +```sql +-- 1. 将 tb_resource_category 数据迁移到 tb_tag +INSERT INTO tb_tag (id, tag_id, name, description, tag_type, creator, create_time) +SELECT + id, + category_id AS tag_id, + name, + description, + 1 AS tag_type, -- 文章分类标签 + creator, + create_time +FROM tb_resource_category +WHERE deleted = 0; + +-- 2. 确认迁移成功后,删除旧表(可选) +-- DROP TABLE IF EXISTS tb_resource_category; +``` + +### tb_resource 表的 category_id 字段 + +`tb_resource` 表中的 `category_id` 字段仍然保留,但现在应该: +- 存储的是 `tb_tag` 表中 `tag_type=1` 的标签的 `tag_id` +- 或者改为使用 `tb_resource_tag` 关联表来管理资源与分类标签的关系 + +**推荐方案:** 使用 `tb_resource_tag` 关联表 +```sql +-- 迁移资源分类关系到资源标签关联表 +INSERT INTO tb_resource_tag (id, resource_id, tag_id, create_time) +SELECT + CONCAT('rt_', UUID()) AS id, + resource_id, + category_id AS tag_id, + NOW() AS create_time +FROM tb_resource +WHERE category_id IS NOT NULL AND category_id != ''; +``` + +--- + +## 📊 影响范围评估 + +### 前端影响 +- ❌ 需要修改前端代码中调用 `/news/categorys` 的接口 +- ✅ 改为调用 `/news/tags/type/1` 接口 +- ✅ 数据结构基本一致,只需修改接口地址和字段映射 + +### 后端影响 +- ✅ 已完全移除 ResourceCategory 相关代码 +- ✅ 所有功能已迁移到 TagService +- ⚠️ 如有其他模块引用了 ResourceCategory,需要同步修改 + +### 数据库影响 +- ✅ 建表语句已注释,不会创建 `tb_resource_category` 表 +- ⚠️ 如果数据库中已存在该表,需要手动迁移数据 +- ⚠️ 建议保留旧表一段时间作为备份 + +--- + +## ✅ 验证清单 + +完成以下验证以确保迁移成功: + +### 1. 编译验证 +- [ ] Maven 编译无错误 +- [ ] 无 `TbResourceCategory` 相关的编译错误 +- [ ] 无 `ResourceCategoryService` 相关的导入错误 + +### 2. 功能验证 +- [ ] 创建文章分类标签(tagType=1) +- [ ] 获取文章分类标签列表 +- [ ] 为资源添加分类标签 +- [ ] 查询资源的分类标签 +- [ ] 删除文章分类标签 + +### 3. 接口验证 +```bash +# 1. 获取文章分类标签 +curl http://localhost:8080/news/tags/type/1 + +# 2. 创建文章分类标签 +curl -X POST http://localhost:8080/news/tags/tag \ + -H "Content-Type: application/json" \ + -d '{"name":"党史学习","tagType":1,"color":"#ff6b6b"}' + +# 3. 为资源添加分类标签 +curl -X POST http://localhost:8080/news/tags/resource/{resourceID}/tag/{tagID} +``` + +### 4. 数据验证 +```sql +-- 检查标签数据 +SELECT * FROM tb_tag WHERE tag_type = 1; + +-- 检查资源标签关联 +SELECT r.title, t.name +FROM tb_resource r +LEFT JOIN tb_resource_tag rt ON r.resource_id = rt.resource_id +LEFT JOIN tb_tag t ON rt.tag_id = t.tag_id +WHERE t.tag_type = 1; +``` + +--- + +## 🎯 总结 + +### 移除内容 +- ✅ 7个 Java 文件(实体、Service、Controller、Mapper) +- ✅ 1个 Mapper XML 文件 +- ✅ SQL 建表语句(已注释) +- ✅ SQL 初始化数据(已注释) + +### 修改内容 +- ✅ 2个 Java 文件(ResourceVO、ResourceCenterController) +- ✅ 更新迁移文档 + +### 替代方案 +- ✅ 使用 `tb_tag` (tag_type=1) 替代 `tb_resource_category` +- ✅ 使用 `TagService.getTagsByType(1)` 获取文章分类标签 +- ✅ 接口从 `/news/categorys` 迁移到 `/news/tags/type/1` + +### 优势 +- ✅ 代码更简洁,减少7个文件 +- ✅ 数据结构更统一 +- ✅ 功能更灵活,易于扩展 +- ✅ 维护成本降低 + +移除操作已全部完成!🎉 + diff --git a/schoolNewsServ/.bin/mysql/sql/TAG_TYPE_MIGRATION.md b/schoolNewsServ/.bin/mysql/sql/TAG_TYPE_MIGRATION.md new file mode 100644 index 0000000..25529fe --- /dev/null +++ b/schoolNewsServ/.bin/mysql/sql/TAG_TYPE_MIGRATION.md @@ -0,0 +1,415 @@ +# 标签系统类型化改造文档 + +## 📝 改造概述 + +将原有的单一标签系统改造为支持3种标签类型的系统,同时废除 `tb_resource_category` 表: +1. **文章分类标签** (tag_type=1) - 替代原 `tb_resource_category` +2. **课程分类标签** (tag_type=2) +3. **学习任务分类标签** (tag_type=3) + +### 改造日期 +2025-10-27 + +### 改造原因 +- ✅ **更清晰的业务划分** - 不同业务领域使用专属的标签类型 +- ✅ **避免标签混淆** - 同名标签在不同类型下可独立存在 +- ✅ **更好的可扩展性** - 便于未来添加新的标签类型 +- ✅ **统一管理** - 将 `tb_resource_category` 合并到 `tb_tag`,使用 tag_type=1 表示文章分类标签 +- ✅ **简化架构** - 减少数据表数量,统一标签管理逻辑 + +--- + +## 🗑️ 废除内容 + +### 1. 废除 tb_resource_category 表 + +**原因:** 资源分类功能已完全整合到标签系统中,使用 `tag_type=1` 的标签代替。 + +**废除内容:** +- ❌ `tb_resource_category` 表(已注释建表语句) +- ❌ `TbResourceCategory` 实体类(已删除) +- ❌ `ResourceCategoryService` 接口(已删除) +- ❌ `NCResourceCategoryServiceImpl` 实现类(已删除) +- ❌ `ResourceCategoryController` 控制器(已删除) +- ❌ `ResourceCategoryMapper` 及 XML(已删除) + +**迁移方案:** +- 原 `tb_resource_category` 数据 → `tb_tag` (tag_type=1) +- 原 `/news/categorys` 接口 → `/news/tags/type/1` 接口 +- 原 `ResourceVO.resourceCategory` 字段 → 改用 `ResourceVO.tags` 列表 + +--- + +## 🔄 数据库变更 + +### 1. 建表语句修改 (createTableResource.sql) + +**修改内容:** +- 添加 `tag_type` 字段(INT(4),默认值1) +- 修改唯一索引:从 `uk_tag_name` 改为 `uk_tag_name_type`(组合唯一索引) +- 添加索引:`idx_tag_type` + +```sql +-- 标签表 +DROP TABLE IF EXISTS `tb_tag`; +CREATE TABLE `tb_tag` ( + `id` VARCHAR(50) NOT NULL COMMENT '标签ID', + `tag_id` VARCHAR(50) NOT NULL COMMENT '标签唯一标识', + `name` VARCHAR(100) NOT NULL COMMENT '标签名称', + `color` VARCHAR(20) DEFAULT NULL COMMENT '标签颜色', + `description` VARCHAR(255) DEFAULT NULL COMMENT '标签描述', + `tag_type` INT(4) DEFAULT 1 COMMENT '标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签)', + `creator` VARCHAR(50) DEFAULT NULL COMMENT '创建者', + `updater` VARCHAR(50) DEFAULT NULL COMMENT '更新者', + `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `delete_time` TIMESTAMP NULL DEFAULT NULL COMMENT '删除时间', + `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tag_id` (`tag_id`), + UNIQUE KEY `uk_tag_name_type` (`name`, `tag_type`), + KEY `idx_tag_type` (`tag_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='标签表'; +``` + +### 2. 初始化数据 (initAllData.sql) + +**新增内容:** +- 添加15条初始标签数据(每种类型各5条) + +```sql +-- 插入标签数据 (文章分类标签 tag_type=1) +INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, create_time) VALUES +('tag001', 'tag_article_001', '党史', '#ff6b6b', '党史学习相关文章', 1, '1', now()), +('tag002', 'tag_article_002', '理论学习', '#4ecdc4', '理论学习相关文章', 1, '1', now()), +... + +-- 插入标签数据 (课程分类标签 tag_type=2) +INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, create_time) VALUES +('tag101', 'tag_course_001', '基础课程', '#26de81', '基础思政课程', 2, '1', now()), +('tag102', 'tag_course_002', '专题课程', '#fc5c65', '专题思政课程', 2, '1', now()), +... + +-- 插入标签数据 (学习任务分类标签 tag_type=3) +INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, create_time) VALUES +('tag201', 'tag_task_001', '每日学习', '#20bf6b', '每日学习任务', 3, '1', now()), +('tag202', 'tag_task_002', '专题学习', '#fa8231', '专题学习任务', 3, '1', now()), +... +``` + +--- + +## 🔄 代码变更 + +### 1. 枚举类新增 + +**文件:** `common\common-core\src\main\java\org\xyzh\common\core\enums\TagType.java` + +```java +public enum TagType { + ARTICLE_CATEGORY(1, "文章分类标签"), + COURSE_CATEGORY(2, "课程分类标签"), + LEARNING_TASK_CATEGORY(3, "学习任务分类标签"); + + // ... 枚举方法 +} +``` + +### 2. DTO实体类修改 + +**文件:** `common\common-dto\src\main\java\org\xyzh\common\dto\resource\TbTag.java` + +**修改内容:** +- 添加 `tagType` 字段(Integer) +- 添加 getter/setter 方法 +- 更新 toString() 方法 + +```java +/** + * @description 标签类型 1-文章分类标签 2-课程分类标签 3-学习任务分类标签 + */ +private Integer tagType; +``` + +### 3. Mapper接口修改 + +**文件:** `news\src\main\java\org\xyzh\news\mapper\TagMapper.java` + +**修改内容:** +- 修改 `selectByType` → `selectByTagType`(参数名更明确) +- 修改 `countByName` → `countByNameAndType`(增加tagType参数) + +```java +// 旧方法 +List selectByType(@Param("type") Integer type); +int countByName(@Param("name") String name, @Param("excludeId") String excludeId); + +// 新方法 +List selectByTagType(@Param("tagType") Integer tagType); +int countByNameAndType(@Param("name") String name, @Param("tagType") Integer tagType, @Param("excludeId") String excludeId); +``` + +### 4. Mapper XML修改 + +**文件:** `news\src\main\resources\mapper\TagMapper.xml` + +**修改内容:** +1. BaseResultMap 添加 `tag_type` 字段映射 +2. Base_Column_List 添加 `tag_type` 字段 +3. Where_Clause 添加 `tag_type` 条件 +4. 修改 `selectByType` → `selectByTagType` +5. 修改 `countByName` → `countByNameAndType` +6. insertTag、updateTag、batchInsertTags 添加 `tag_type` 字段 + +```xml + + + ... + + ... + + + + + id, tag_id, name, color, description, tag_type, creator, updater, create_time, + update_time, delete_time, deleted + +``` + +### 5. Service接口修改 + +**文件:** `api\api-news\src\main\java\org\xyzh\api\news\tag\TagService.java` + +**新增方法:** +```java +/** + * @description 根据标签类型获取标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + * @return ResultDomain 标签列表 + */ +ResultDomain getTagsByType(Integer tagType); +``` + +### 6. Service实现类修改 + +**文件:** `news\src\main\java\org\xyzh\news\service\impl\NCTagServiceImpl.java` + +**修改内容:** +1. createTag 方法:调用 `countByNameAndType` 检查同类型下名称是否重复 +2. updateTag 方法:调用 `countByNameAndType` 检查同类型下名称是否重复 +3. 新增 getTagsByType 方法 + +```java +@Override +public ResultDomain getTagsByType(Integer tagType) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + if (tagType == null) { + resultDomain.fail("标签类型不能为空"); + return resultDomain; + } + + // 验证标签类型是否有效(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + if (tagType < 1 || tagType > 3) { + resultDomain.fail("无效的标签类型"); + return resultDomain; + } + + List tags = tagMapper.selectByTagType(tagType); + resultDomain.success("查询成功", tags); + return resultDomain; + } catch (Exception e) { + logger.error("根据类型查询标签异常: {}", e.getMessage(), e); + resultDomain.fail("根据类型查询标签失败: " + e.getMessage()); + return resultDomain; + } +} +``` + +### 7. Controller修改 + +**文件:** `news\src\main\java\org\xyzh\news\controller\TagController.java` + +**新增接口:** +```java +/** + * 根据标签类型获取标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + */ +@GetMapping("/type/{tagType}") +public ResultDomain getTagsByType(@PathVariable Integer tagType) { + return tagService.getTagsByType(tagType); +} +``` + +--- + +## 📋 API接口说明 + +### 新增接口 + +**接口路径:** `GET /news/tags/type/{tagType}` + +**请求参数:** +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| tagType | Integer | 是 | 标签类型:1-文章分类标签,2-课程分类标签,3-学习任务分类标签 | + +**响应示例:** +```json +{ + "code": 200, + "message": "查询成功", + "data": [ + { + "id": "tag001", + "tagID": "tag_article_001", + "name": "党史", + "color": "#ff6b6b", + "description": "党史学习相关文章", + "tagType": 1, + "createTime": "2025-10-27 10:00:00" + } + ] +} +``` + +### 修改的接口 + +**创建标签接口:** `POST /news/tags/tag` + +现在创建标签时需要指定 `tagType` 字段: +```json +{ + "name": "新标签", + "color": "#ff0000", + "description": "标签描述", + "tagType": 1 +} +``` + +--- + +## ⚠️ 注意事项 + +### 1. 数据迁移 + +如果已有旧数据,需要执行以下SQL为现有标签设置默认类型: + +```sql +-- 为现有标签设置默认类型为1(文章分类标签) +UPDATE tb_tag SET tag_type = 1 WHERE tag_type IS NULL; +``` + +### 2. 唯一性约束变更 + +- **旧约束:** 标签名称全局唯一 +- **新约束:** 标签名称在同一类型下唯一 + +这意味着不同类型的标签可以使用相同的名称,例如: +- "基础" (tag_type=1, 文章分类标签) +- "基础" (tag_type=2, 课程分类标签) + +### 3. 标签类型枚举值 + +| 类型值 | 说明 | 枚举常量 | +|--------|------|----------| +| 1 | 文章分类标签 | TagType.ARTICLE_CATEGORY | +| 2 | 课程分类标签 | TagType.COURSE_CATEGORY | +| 3 | 学习任务分类标签 | TagType.LEARNING_TASK_CATEGORY | + +### 4. 向后兼容性 + +- 所有创建标签的操作必须指定 `tagType` +- 如果不指定,将使用默认值1(文章分类标签) +- 查询所有标签的接口 `/news/tags/list` 保持不变,会返回所有类型的标签 + +--- + +## ✅ 测试建议 + +### 1. 功能测试 + +- [ ] 创建不同类型的标签 +- [ ] 验证同类型下标签名称唯一性 +- [ ] 验证不同类型可以使用相同标签名 +- [ ] 根据类型查询标签 +- [ ] 更新标签(包括更改类型) +- [ ] 删除标签 + +### 2. 数据一致性测试 + +- [ ] 检查所有标签都有 `tag_type` 字段 +- [ ] 验证唯一索引生效 +- [ ] 测试并发创建同名标签 + +### 3. API测试 + +```bash +# 1. 创建文章分类标签 +curl -X POST http://localhost:8080/news/tags/tag \ + -H "Content-Type: application/json" \ + -d '{"name":"测试标签","tagType":1,"color":"#ff0000"}' + +# 2. 获取文章分类标签列表 +curl http://localhost:8080/news/tags/type/1 + +# 3. 获取课程分类标签列表 +curl http://localhost:8080/news/tags/type/2 + +# 4. 获取学习任务分类标签列表 +curl http://localhost:8080/news/tags/type/3 +``` + +--- + +## 📚 相关文件清单 + +### 数据库文件 +- `.bin\mysql\sql\createTableResource.sql` - 建表语句(已注释 tb_resource_category) +- `.bin\mysql\sql\initAllData.sql` - 初始化数据(已注释旧分类数据,新增标签数据) + +### 新增/修改的 Java 文件 +- `common\common-core\src\main\java\org\xyzh\common\core\enums\TagType.java` - 枚举类(新增) +- `common\common-dto\src\main\java\org\xyzh\common\dto\resource\TbTag.java` - DTO实体类(修改) +- `api\api-news\src\main\java\org\xyzh\api\news\tag\TagService.java` - Service接口(修改) +- `news\src\main\java\org\xyzh\news\mapper\TagMapper.java` - Mapper接口(修改) +- `news\src\main\resources\mapper\TagMapper.xml` - MyBatis XML(修改) +- `news\src\main\java\org\xyzh\news\service\impl\NCTagServiceImpl.java` - Service实现(修改) +- `news\src\main\java\org\xyzh\news\controller\TagController.java` - Controller(修改) +- `common\common-dto\src\main\java\org\xyzh\common\vo\ResourceVO.java` - VO类(修改,删除 resourceCategory 字段) +- `news\src\main\java\org\xyzh\news\controller\ResourceCenterController.java` - 资源中心控制器(修改) + +### 已删除的文件 +- ~~`common\common-dto\src\main\java\org\xyzh\common\dto\resource\TbResourceCategory.java`~~ +- ~~`api\api-news\src\main\java\org\xyzh\api\news\category\ResourceCategoryService.java`~~ +- ~~`news\src\main\java\org\xyzh\news\service\NCResourceCategoryService.java`~~ +- ~~`news\src\main\java\org\xyzh\news\service\impl\NCResourceCategoryServiceImpl.java`~~ +- ~~`news\src\main\java\org\xyzh\news\controller\ResourceCategoryController.java`~~ +- ~~`news\src\main\java\org\xyzh\news\mapper\ResourceCategoryMapper.java`~~ +- ~~`news\src\main\resources\mapper\ResourceCategoryMapper.xml`~~ + +--- + +## 🎯 总结 + +本次改造实现了标签系统的类型化管理,使得: +1. **统一标签管理** - 将原 `tb_resource_category` 合并到 `tb_tag`,使用统一的标签系统 +2. **类型化分类** - 文章、课程、学习任务可以使用各自的标签分类体系 +3. **避免混淆** - 同名标签在不同类型下可独立存在 +4. **简化架构** - 减少数据表和相关代码,降低维护成本 +5. **灵活扩展** - 为未来添加新标签类型预留了空间 + +### 迁移前后对比 + +| 项目 | 迁移前 | 迁移后 | +|------|--------|--------| +| 数据表 | `tb_tag` + `tb_resource_category` | `tb_tag` (tag_type区分) | +| 实体类 | `TbTag` + `TbResourceCategory` | `TbTag` | +| Service | `TagService` + `ResourceCategoryService` | `TagService` | +| 文章分类 | 使用 `ResourceCategoryService` | 使用 `TagService.getTagsByType(1)` | +| 课程分类 | 无 | 使用 `TagService.getTagsByType(2)` | +| 学习任务分类 | 无 | 使用 `TagService.getTagsByType(3)` | + +改造完成后,系统将具备更清晰的业务边界、更简洁的代码结构和更灵活的扩展能力。 + diff --git a/schoolNewsServ/.bin/mysql/sql/createTableResource.sql b/schoolNewsServ/.bin/mysql/sql/createTableResource.sql index d561e89..d32d08a 100644 --- a/schoolNewsServ/.bin/mysql/sql/createTableResource.sql +++ b/schoolNewsServ/.bin/mysql/sql/createTableResource.sql @@ -8,7 +8,7 @@ CREATE TABLE `tb_resource` ( `content` LONGTEXT COMMENT '资源内容', `summary` VARCHAR(500) DEFAULT NULL COMMENT '资源简介', `cover_image` VARCHAR(255) DEFAULT NULL COMMENT '封面图片', - `category_id` VARCHAR(50) DEFAULT NULL COMMENT '分类ID', + `tag_id` VARCHAR(50) DEFAULT NULL COMMENT '标签ID(文章分类标签,tagType=1)', `author` VARCHAR(100) DEFAULT NULL COMMENT '作者', `source` VARCHAR(255) DEFAULT NULL COMMENT '来源', `source_url` VARCHAR(500) DEFAULT NULL COMMENT '来源URL', @@ -27,33 +27,12 @@ CREATE TABLE `tb_resource` ( `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除', PRIMARY KEY (`id`), KEY `idx_resource_id` (`resource_id`), - KEY `idx_category` (`category_id`), + KEY `idx_tag` (`tag_id`), KEY `idx_status` (`status`), KEY `idx_publish_time` (`publish_time`), KEY `idx_view_count` (`view_count`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='资源表'; --- 资源分类表 -DROP TABLE IF EXISTS `tb_resource_category`; -CREATE TABLE `tb_resource_category` ( - `id` VARCHAR(50) NOT NULL COMMENT '分类ID', - `category_id` VARCHAR(50) NOT NULL COMMENT '分类唯一标识', - `name` VARCHAR(100) NOT NULL COMMENT '分类名称', - `parent_id` VARCHAR(50) DEFAULT NULL COMMENT '父分类ID', - `description` VARCHAR(255) DEFAULT NULL COMMENT '分类描述', - `icon` VARCHAR(100) DEFAULT NULL COMMENT '分类图标', - `order_num` INT(4) DEFAULT 0 COMMENT '排序号', - `creator` VARCHAR(50) DEFAULT NULL COMMENT '创建者', - `updater` VARCHAR(50) DEFAULT NULL COMMENT '更新者', - `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `delete_time` TIMESTAMP NULL DEFAULT NULL COMMENT '删除时间', - `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除', - PRIMARY KEY (`id`), - UNIQUE KEY `uk_category_id` (`category_id`), - KEY `idx_parent` (`parent_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='资源分类表'; - -- Banner管理表 DROP TABLE IF EXISTS `tb_banner`; @@ -103,6 +82,7 @@ CREATE TABLE `tb_tag` ( `name` VARCHAR(100) NOT NULL COMMENT '标签名称', `color` VARCHAR(20) DEFAULT NULL COMMENT '标签颜色', `description` VARCHAR(255) DEFAULT NULL COMMENT '标签描述', + `tag_type` INT(4) DEFAULT 1 COMMENT '标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签)', `creator` VARCHAR(50) DEFAULT NULL COMMENT '创建者', `updater` VARCHAR(50) DEFAULT NULL COMMENT '更新者', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', @@ -111,7 +91,8 @@ CREATE TABLE `tb_tag` ( `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除', PRIMARY KEY (`id`), UNIQUE KEY `uk_tag_id` (`tag_id`), - UNIQUE KEY `uk_tag_name` (`name`) + UNIQUE KEY `uk_tag_name_type` (`name`, `tag_type`), + KEY `idx_tag_type` (`tag_type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='标签表'; -- 资源标签关联表 @@ -136,7 +117,7 @@ CREATE TABLE `tb_data_collection_config` ( `source_url` VARCHAR(500) NOT NULL COMMENT '采集源URL', `source_type` VARCHAR(50) DEFAULT NULL COMMENT '采集源类型', `frequency` VARCHAR(20) DEFAULT 'daily' COMMENT '采集频率(daily每天 weekly每周)', - `category_id` VARCHAR(50) DEFAULT NULL COMMENT '默认分类ID', + `tag_id` VARCHAR(50) DEFAULT NULL COMMENT '默认标签ID(文章分类标签,tagType=1)', `status` INT(4) DEFAULT 1 COMMENT '状态(0禁用 1启用)', `last_collect_time` TIMESTAMP NULL DEFAULT NULL COMMENT '最后采集时间', `creator` VARCHAR(50) DEFAULT NULL COMMENT '创建者', diff --git a/schoolNewsServ/.bin/mysql/sql/initAllData.sql b/schoolNewsServ/.bin/mysql/sql/initAllData.sql index bc8c91d..e32d1c7 100644 --- a/schoolNewsServ/.bin/mysql/sql/initAllData.sql +++ b/schoolNewsServ/.bin/mysql/sql/initAllData.sql @@ -4,14 +4,30 @@ use school_news; INSERT INTO `tb_ai_agent_config` (id, name, system_prompt, model_name, temperature, max_tokens, status, creator, create_time) VALUES ('1', '思政小帮手', '你是一个专业的思政学习助手,致力于帮助用户学习思想政治理论知识。请基于提供的知识库内容,为用户提供准确、简洁的回答。', 'gpt-3.5-turbo', 0.7, 2000, 1, '1', now()); --- 插入资源分类数据 -INSERT INTO `tb_resource_category` (id, category_id, name, description, order_num, creator, create_time) VALUES -('1', 'party_history', '党史学习', '党史学习相关资源', 1, '1', now()), -('2', 'leader_speech', '领导讲话', '领导讲话相关资源', 2, '1', now()), -('3', 'policy_interpretation', '政策解读', '政策解读相关资源', 3, '1', now()), -('4', 'red_classic', '红色经典', '红色经典相关资源', 4, '1', now()), -('5', 'special_report', '专题报告', '专题报告相关资源', 5, '1', now()), -('6', 'world_case', '思政案例', '思政案例相关资源', 6, '1', now()); +-- 插入标签数据 (文章分类标签 tag_type=1) +INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, create_time) VALUES +('tag001', 'tag_article_001', '党史学习', '#ff6b6b', '党史学习相关文章', 1, '1', now()), +('tag002', 'tag_article_002', '领导讲话', '#4ecdc4', '领导讲话相关文章', 1, '1', now()), +('tag003', 'tag_article_003', '政策解读', '#45b7d1', '政策解读相关文章', 1, '1', now()), +('tag004', 'tag_article_004', '红色经典', '#f7b731', '红色经典相关文章', 1, '1', now()), +('tag005', 'tag_article_005', '专题报告', '#45c7c1', '专题报告相关文章', 1, '1', now()), +('tag006', 'tag_article_006', '思政案例', '#5f27cd', '思政案例相关文章', 1, '1', now()); + +-- 插入标签数据 (课程分类标签 tag_type=2) +INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, create_time) VALUES +('tag101', 'tag_course_001', '基础课程', '#26de81', '基础思政课程', 2, '1', now()), +('tag102', 'tag_course_002', '专题课程', '#fc5c65', '专题思政课程', 2, '1', now()), +('tag103', 'tag_course_003', '实践课程', '#fd9644', '实践类思政课程', 2, '1', now()), +('tag104', 'tag_course_004', '在线课程', '#a55eea', '在线学习课程', 2, '1', now()), +('tag105', 'tag_course_005', '热门课程', '#eb3b5a', '热门推荐课程', 2, '1', now()); + +-- 插入标签数据 (学习任务分类标签 tag_type=3) +INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, create_time) VALUES +('tag201', 'tag_task_001', '每日学习', '#20bf6b', '每日学习任务', 3, '1', now()), +('tag202', 'tag_task_002', '专题学习', '#fa8231', '专题学习任务', 3, '1', now()), +('tag203', 'tag_task_003', '考核任务', '#0fb9b1', '考核类学习任务', 3, '1', now()), +('tag204', 'tag_task_004', '实践任务', '#f7b731', '实践类学习任务', 3, '1', now()), +('tag205', 'tag_task_005', '阶段任务', '#2d98da', '阶段性学习任务', 3, '1', now()); -- 插入系统配置数据 INSERT INTO `tb_sys_config` (id, config_key, config_value, config_type, config_group, description, is_system, creator, create_time) VALUES diff --git a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql index 7f2a11e..db61963 100644 --- a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql +++ b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql @@ -98,60 +98,60 @@ INSERT INTO `tb_sys_menu` (id, menu_id, name, parent_id, url, component, icon, o -- 智能体模块 ('600', 'menu_ai_assistant', '智能体模块', NULL, '/ai-assistant', 'ai-assistant/AIAssistantView', 'el-icon-cpu', 6, 1, 'NavigationLayout', '1', now()); --- 插入后端管理菜单数据 +-- 插入后端管理菜单数据 (type=0 侧边栏菜单) INSERT INTO `tb_sys_menu` (id, menu_id, name, parent_id, url, component, icon, order_num, type, layout, creator, create_time) VALUES -- 系统总览 -('1000', 'menu_admin_overview', '系统总览', NULL, '/admin/overview', 'admin/overview/SystemOverviewView', 'el-icon-data-analysis', 1, 1, 'NavigationLayout', '1', now()), +('1000', 'menu_admin_overview', '系统总览', NULL, '/admin/overview', 'admin/overview/SystemOverviewView', 'el-icon-data-analysis', 1, 0, 'SidebarLayout', '1', now()), -- 用户管理 -('2000', 'menu_sys_manage', '系统管理', NULL, '', '', 'el-icon-user', 2, 1, '', '1', now()), -('2001', 'menu_admin_user', '用户管理', 'menu_sys_manage', '/admin/manage/system/user', 'admin/manage/system/UserManageView', 'el-icon-user', 1, 1, 'NavigationLayout', '1', now()), -('2002', 'menu_admin_dept', '部门管理', 'menu_sys_manage', '/admin/manage/system/dept', 'admin/manage/system/DeptManageView', 'el-icon-office-building', 2, 1, 'NavigationLayout', '1', now()), -('2003', 'menu_admin_role', '角色管理', 'menu_sys_manage', '/admin/manage/system/role', 'admin/manage/system/RoleManageView', 'el-icon-user-solid', 3, 1, 'NavigationLayout', '1', now()), -('2005', 'menu_admin_menu', '菜单管理', 'menu_sys_manage', '/admin/manage/system/menu', 'admin/manage/system/MenuManageView', 'el-icon-menu', 4, 1, 'NavigationLayout', '1', now()), -('2006', 'menu_admin_module', '模块权限管理', 'menu_sys_manage', '/admin/manage/system/module-permission', 'admin/manage/system/ModulePermissionManageView', 'el-icon-s-grid', 5, 1, 'NavigationLayout', '1', now()), +('2000', 'menu_sys_manage', '系统管理', NULL, '', '', 'el-icon-user', 2, 0, 'SidebarLayout', '1', now()), +('2001', 'menu_admin_user', '用户管理', 'menu_sys_manage', '/admin/manage/system/user', 'admin/manage/system/UserManageView', 'el-icon-user', 1, 0, 'SidebarLayout', '1', now()), +('2002', 'menu_admin_dept', '部门管理', 'menu_sys_manage', '/admin/manage/system/dept', 'admin/manage/system/DeptManageView', 'el-icon-office-building', 2, 0, 'SidebarLayout', '1', now()), +('2003', 'menu_admin_role', '角色管理', 'menu_sys_manage', '/admin/manage/system/role', 'admin/manage/system/RoleManageView', 'el-icon-user-solid', 3, 0, 'SidebarLayout', '1', now()), +('2005', 'menu_admin_menu', '菜单管理', 'menu_sys_manage', '/admin/manage/system/menu', 'admin/manage/system/MenuManageView', 'el-icon-menu', 4, 0, 'SidebarLayout', '1', now()), +('2006', 'menu_admin_module', '模块权限管理', 'menu_sys_manage', '/admin/manage/system/module-permission', 'admin/manage/system/ModulePermissionManageView', 'el-icon-s-grid', 5, 0, 'SidebarLayout', '1', now()), -- 资源管理 -('3000', 'menu_admin_resource_manage', '资源管理', NULL, '', '', 'el-icon-folder', 3, 1, '', '1', now()), -('3001', 'menu_admin_resource', '资源管理', 'menu_admin_resource_manage', '/admin/manage/resource/resource', 'admin/manage/resource/ResourceManagementView', 'el-icon-folder', 1, 1, 'NavigationLayout', '1', now()), -('3002', 'menu_admin_article', '文章管理', 'menu_admin_resource_manage', '/admin/manage/resource/article', 'admin/manage/resource/ArticleManagementView', 'el-icon-document', 2, 1, 'NavigationLayout', '1', now()), -('3003', 'menu_admin_data_records', '数据记录', 'menu_admin_resource_manage', '/admin/manage/resource/data-records', 'admin/manage/resource/DataRecordsView', 'el-icon-data-line', 3, 1, 'NavigationLayout', '1', now()), +('3000', 'menu_admin_resource_manage', '资源管理', NULL, '', '', 'el-icon-folder', 3, 0, 'SidebarLayout', '1', now()), +('3001', 'menu_admin_resource', '资源管理', 'menu_admin_resource_manage', '/admin/manage/resource/resource', 'admin/manage/resource/ResourceManagementView', 'el-icon-folder', 1, 0, 'SidebarLayout', '1', now()), +('3002', 'menu_admin_article', '文章管理', 'menu_admin_resource_manage', '/admin/manage/resource/article', 'admin/manage/resource/ArticleManagementView', 'el-icon-document', 2, 0, 'SidebarLayout', '1', now()), +('3003', 'menu_admin_data_records', '数据记录', 'menu_admin_resource_manage', '/admin/manage/resource/data-records', 'admin/manage/resource/DataRecordsView', 'el-icon-data-line', 3, 0, 'SidebarLayout', '1', now()), -- 文章相关 -('3010', 'menu_article_add', '文章添加', 'menu_admin_article', '/article/add', 'article/ArticleAddView', 'el-icon-plus', 1, 3, 'NavigationLayout', '1', now()), -('3011', 'menu_article_show', '文章展示', 'menu_admin_article', '/article/show', 'article/ArticleShowView', 'el-icon-document', 2, 3, 'NavigationLayout', '1', now()), +('3010', 'menu_article_add', '文章添加', 'menu_admin_article', '/article/add', 'article/ArticleAddView', 'el-icon-plus', 1, 3, 'SidebarLayout', '1', now()), +('3011', 'menu_article_show', '文章展示', 'menu_admin_article', '/article/show', 'article/ArticleShowView', 'el-icon-document', 2, 3, 'SidebarLayout', '1', now()), -- 运营管理 -('4000', 'menu_admin_content_manage', '运营管理', NULL, '', '', 'el-icon-s-operation', 4, 1, '', '1', now()), -('4001', 'menu_admin_banner', 'Banner管理', 'menu_admin_content_manage', '/admin/manage/content/banner', 'admin/manage/content/BannerManagementView', 'el-icon-picture', 1, 1, 'NavigationLayout', '1', now()), -('4002', 'menu_admin_tag', '标签管理', 'menu_admin_content_manage', '/admin/manage/content/tag', 'admin/manage/content/TagManagementView', 'el-icon-price-tag', 2, 1, 'NavigationLayout', '1', now()), -('4003', 'menu_admin_column', '栏目管理', 'menu_admin_content_manage', '/admin/manage/content/column', 'admin/manage/content/ColumnManagementView', 'el-icon-menu', 3, 1, 'NavigationLayout', '1', now()), -('4004', 'menu_admin_content', '内容管理', 'menu_admin_content_manage', '/admin/manage/content/content', 'admin/manage/content/ContentManagementView', 'el-icon-document', 4, 1, 'NavigationLayout', '1', now()), +('4000', 'menu_admin_content_manage', '运营管理', NULL, '', '', 'el-icon-s-operation', 4, 0, 'SidebarLayout', '1', now()), +('4001', 'menu_admin_banner', 'Banner管理', 'menu_admin_content_manage', '/admin/manage/content/banner', 'admin/manage/content/BannerManagementView', 'el-icon-picture', 1, 0, 'SidebarLayout', '1', now()), +('4002', 'menu_admin_tag', '标签管理', 'menu_admin_content_manage', '/admin/manage/content/tag', 'admin/manage/content/TagManagementView', 'el-icon-price-tag', 2, 0, 'SidebarLayout', '1', now()), +('4003', 'menu_admin_column', '栏目管理', 'menu_admin_content_manage', '/admin/manage/content/column', 'admin/manage/content/ColumnManagementView', 'el-icon-menu', 3, 0, 'SidebarLayout', '1', now()), +('4004', 'menu_admin_content', '内容管理', 'menu_admin_content_manage', '/admin/manage/content/content', 'admin/manage/content/ContentManagementView', 'el-icon-document', 4, 0, 'SidebarLayout', '1', now()), -- 学习管理 -('5000', 'menu_admin_study_manage', '学习管理', NULL, '', '', 'el-icon-reading', 5, 1, '', '1', now()), -('5002', 'menu_admin_task_manage', '任务管理', 'menu_admin_study_manage', '/admin/manage/study/task-manage', 'admin/manage/study/TaskManageView', 'el-icon-s-order', 2, 1, 'NavigationLayout', '1', now()), -('5003', 'menu_admin_study_records', '学习记录', 'menu_admin_study_manage', '/admin/manage/study/study-records', 'admin/manage/study/StudyRecordsView', 'el-icon-document', 3, 1, 'NavigationLayout', '1', now()), -('5004', 'menu_admin_course_manage', '课程管理', 'menu_admin_study_manage', '/admin/manage/study/course', 'admin/manage/study/CourseManagementView', 'el-icon-video-play', 4, 1, 'NavigationLayout', '1', now()), -('5005', 'menu_admin_achievement_manage', '成就管理', 'menu_admin_study_manage', '/admin/manage/study/achievement', 'admin/manage/achievement/AchievementManagementView', 'el-icon-trophy', 5, 1, 'NavigationLayout', '1', now()), +('5000', 'menu_admin_study_manage', '学习管理', NULL, '', '', 'el-icon-reading', 5, 0, 'SidebarLayout', '1', now()), +('5002', 'menu_admin_task_manage', '任务管理', 'menu_admin_study_manage', '/admin/manage/study/task-manage', 'admin/manage/study/TaskManageView', 'el-icon-s-order', 2, 0, 'SidebarLayout', '1', now()), +('5003', 'menu_admin_study_records', '学习记录', 'menu_admin_study_manage', '/admin/manage/study/study-records', 'admin/manage/study/StudyRecordsView', 'el-icon-document', 3, 0, 'SidebarLayout', '1', now()), +('5004', 'menu_admin_course_manage', '课程管理', 'menu_admin_study_manage', '/admin/manage/study/course', 'admin/manage/study/CourseManagementView', 'el-icon-video-play', 4, 0, 'SidebarLayout', '1', now()), +('5005', 'menu_admin_achievement_manage', '成就管理', 'menu_admin_study_manage', '/admin/manage/study/achievement', 'admin/manage/achievement/AchievementManagementView', 'el-icon-trophy', 5, 0, 'SidebarLayout', '1', now()), -- 智能体管理 -('6000', 'menu_admin_ai_manage', '智能体管理', NULL, '', '', 'el-icon-cpu', 6, 1, '', '1', now()), -('6001', 'menu_admin_ai', 'AI管理', 'menu_admin_ai_manage', '/admin/manage/ai/ai', 'admin/manage/ai/AIManagementView', 'el-icon-cpu', 1, 1, 'NavigationLayout', '1', now()), -('6002', 'menu_admin_ai_config', 'AI配置', 'menu_admin_ai_manage', '/admin/manage/ai/config', 'admin/manage/ai/AIConfigView', 'el-icon-setting', 2, 1, 'NavigationLayout', '1', now()), -('6003', 'menu_admin_knowledge', '知识库管理', 'menu_admin_ai_manage', '/admin/manage/ai/knowledge', 'admin/manage/ai/KnowledgeManagementView', 'el-icon-collection', 3, 1, 'NavigationLayout', '1', now()), +('6000', 'menu_admin_ai_manage', '智能体管理', NULL, '', '', 'el-icon-cpu', 6, 0, 'SidebarLayout', '1', now()), +('6001', 'menu_admin_ai', 'AI管理', 'menu_admin_ai_manage', '/admin/manage/ai/ai', 'admin/manage/ai/AIManagementView', 'el-icon-cpu', 1, 0, 'SidebarLayout', '1', now()), +('6002', 'menu_admin_ai_config', 'AI配置', 'menu_admin_ai_manage', '/admin/manage/ai/config', 'admin/manage/ai/AIConfigView', 'el-icon-setting', 2, 0, 'SidebarLayout', '1', now()), +('6003', 'menu_admin_knowledge', '知识库管理', 'menu_admin_ai_manage', '/admin/manage/ai/knowledge', 'admin/manage/ai/KnowledgeManagementView', 'el-icon-collection', 3, 0, 'SidebarLayout', '1', now()), -- 系统日志 -('7000', 'menu_admin_logs_manage', '系统日志', NULL, '', '', 'el-icon-document', 7, 1, '', '1', now()), -('7001', 'menu_admin_system_logs', '系统日志', 'menu_admin_logs_manage', '/admin/manage/logs/system', 'admin/manage/logs/SystemLogsView', 'el-icon-document', 1, 1, 'NavigationLayout', '1', now()), -('7002', 'menu_admin_login_logs', '登录日志', 'menu_admin_logs_manage', '/admin/manage/logs/login', 'admin/manage/logs/LoginLogsView', 'el-icon-key', 2, 1, 'NavigationLayout', '1', now()), -('7003', 'menu_admin_operation_logs', '操作日志', 'menu_admin_logs_manage', '/admin/manage/logs/operation', 'admin/manage/logs/OperationLogsView', 'el-icon-s-operation', 3, 1, 'NavigationLayout', '1', now()), -('7004', 'menu_admin_system_config', '系统配置', 'menu_admin_logs_manage', '/admin/manage/logs/config', 'admin/manage/logs/SystemConfigView', 'el-icon-setting', 4, 1, 'NavigationLayout', '1', now()), +('7000', 'menu_admin_logs_manage', '系统日志', NULL, '', '', 'el-icon-document', 7, 0, 'SidebarLayout', '1', now()), +('7001', 'menu_admin_system_logs', '系统日志', 'menu_admin_logs_manage', '/admin/manage/logs/system', 'admin/manage/logs/SystemLogsView', 'el-icon-document', 1, 0, 'SidebarLayout', '1', now()), +('7002', 'menu_admin_login_logs', '登录日志', 'menu_admin_logs_manage', '/admin/manage/logs/login', 'admin/manage/logs/LoginLogsView', 'el-icon-key', 2, 0, 'SidebarLayout', '1', now()), +('7003', 'menu_admin_operation_logs', '操作日志', 'menu_admin_logs_manage', '/admin/manage/logs/operation', 'admin/manage/logs/OperationLogsView', 'el-icon-s-operation', 3, 0, 'SidebarLayout', '1', now()), +('7004', 'menu_admin_system_config', '系统配置', 'menu_admin_logs_manage', '/admin/manage/logs/config', 'admin/manage/logs/SystemConfigView', 'el-icon-setting', 4, 0, 'SidebarLayout', '1', now()), -- 定时任务管理 -('8000', 'menu_admin_crontab_manage', '定时任务管理', NULL, '', '', 'el-icon-alarm-clock', 8, 1, '', '1', now()), -('8001', 'menu_admin_crontab_task', '任务管理', 'menu_admin_crontab_manage', '/admin/manage/crontab/task', 'admin/manage/crontab/TaskManagementView', 'el-icon-s-order', 1, 1, 'NavigationLayout', '1', now()), -('8002', 'menu_admin_crontab_log', '执行日志', 'menu_admin_crontab_manage', '/admin/manage/crontab/log', 'admin/manage/crontab/LogManagementView', 'el-icon-document', 2, 1, 'NavigationLayout', '1', now()), -('8003', 'menu_admin_news_crawler', '新闻爬虫配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/news-crawler', 'admin/manage/crontab/NewsCrawlerView', 'el-icon-share', 3, 1, 'NavigationLayout', '1', now()); +('8000', 'menu_admin_crontab_manage', '定时任务管理', NULL, '', '', 'el-icon-alarm-clock', 8, 0, 'SidebarLayout', '1', now()), +('8001', 'menu_admin_crontab_task', '任务管理', 'menu_admin_crontab_manage', '/admin/manage/crontab/task', 'admin/manage/crontab/TaskManagementView', 'el-icon-s-order', 1, 0, 'SidebarLayout', '1', now()), +('8002', 'menu_admin_crontab_log', '执行日志', 'menu_admin_crontab_manage', '/admin/manage/crontab/log', 'admin/manage/crontab/LogManagementView', 'el-icon-document', 2, 0, 'SidebarLayout', '1', now()), +('8003', 'menu_admin_news_crawler', '新闻爬虫配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/news-crawler', 'admin/manage/crontab/NewsCrawlerView', 'el-icon-share', 3, 0, 'SidebarLayout', '1', now()); -- 插入菜单权限关联数据 INSERT INTO `tb_sys_menu_permission` (id, permission_id, menu_id, creator, create_time) VALUES diff --git a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/category/ResourceCategoryService.java b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/category/ResourceCategoryService.java deleted file mode 100644 index 03cb726..0000000 --- a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/category/ResourceCategoryService.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.xyzh.api.news.category; - -import org.xyzh.common.core.domain.ResultDomain; -import org.xyzh.common.dto.resource.TbResourceCategory; - -import java.util.List; - -/** - * @description 资源分类服务接口 - * @filename ResourceCategoryService.java - * @author yslg - * @copyright xyzh - * @since 2025-10-15 - */ -public interface ResourceCategoryService { - - /** - * @description 获取所有分类列表 - * @return ResultDomain 分类列表 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain getAllCategories(); - - /** - * @description 获取分类树形结构 - * @return ResultDomain 分类树 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain getCategoryTree(); - - /** - * @description 根据ID获取分类详情 - * @param categoryID 分类ID - * @return ResultDomain 分类详情 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain getCategoryById(String categoryID); - - /** - * @description 根据父ID获取子分类 - * @param parentID 父分类ID - * @return ResultDomain 子分类列表 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain getCategoriesByParent(String parentID); - - /** - * @description 创建分类 - * @param category 分类信息 - * @return ResultDomain 创建结果 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain createCategory(TbResourceCategory category); - - /** - * @description 更新分类 - * @param category 分类信息 - * @return ResultDomain 更新结果 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain updateCategory(TbResourceCategory category); - - /** - * @description 删除分类 - * @param categoryID 分类ID - * @return ResultDomain 删除结果 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain deleteCategory(String categoryID); - - /** - * @description 更新分类排序 - * @param categoryID 分类ID - * @param orderNum 排序号 - * @return ResultDomain 更新结果 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain updateCategoryOrder(String categoryID, Integer orderNum); - - /** - * @description 检查分类是否有子分类 - * @param categoryID 分类ID - * @return ResultDomain 是否有子分类 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain hasChildCategories(String categoryID); - - /** - * @description 检查分类下是否有资源 - * @param categoryID 分类ID - * @return ResultDomain 是否有资源 - * @author yslg - * @since 2025-10-15 - */ - ResultDomain hasResources(String categoryID); -} diff --git a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceService.java b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceService.java index 98fdc04..fcb8041 100644 --- a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceService.java +++ b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceService.java @@ -167,11 +167,11 @@ public interface ResourceService { /** * @description 搜索资源 * @param keyword 关键词 - * @param categoryID 分类ID(可选) + * @param tagID 分类ID(可选) * @param status 状态(可选) * @return ResultDomain 搜索结果 * @author yslg * @since 2025-10-15 */ - ResultDomain searchResources(String keyword, String categoryID, Integer status); + ResultDomain searchResources(String keyword, String tagID, Integer status); } diff --git a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/tag/TagService.java b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/tag/TagService.java index 2bc3c8f..5f8f545 100644 --- a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/tag/TagService.java +++ b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/tag/TagService.java @@ -68,6 +68,15 @@ public interface TagService { */ ResultDomain searchTagsByName(String name); + /** + * @description 根据标签类型获取标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + * @return ResultDomain 标签列表 + * @author yslg + * @since 2025-10-27 + */ + ResultDomain getTagsByType(Integer tagType); + // ----------------资源标签关联相关-------------------------------- /** diff --git a/schoolNewsServ/common/common-core/src/main/java/org/xyzh/common/core/enums/TagType.java b/schoolNewsServ/common/common-core/src/main/java/org/xyzh/common/core/enums/TagType.java new file mode 100644 index 0000000..e69de29 diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbDataCollectionConfig.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbDataCollectionConfig.java index 99954e5..97c0d4c 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbDataCollectionConfig.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbDataCollectionConfig.java @@ -35,9 +35,9 @@ public class TbDataCollectionConfig extends BaseDTO { private String frequency; /** - * @description 默认分类ID + * @description 默认标签ID(文章分类标签,tagType=1) */ - private String categoryID; + private String tagID; /** * @description 状态(0禁用 1启用) @@ -91,12 +91,12 @@ public class TbDataCollectionConfig extends BaseDTO { this.frequency = frequency; } - public String getCategoryID() { - return categoryID; + public String getTagID() { + return tagID; } - public void setCategoryID(String categoryID) { - this.categoryID = categoryID; + public void setTagID(String tagID) { + this.tagID = tagID; } public Integer getStatus() { diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java index 5ad3b0c..8c41f2c 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java @@ -40,9 +40,9 @@ public class TbResource extends BaseDTO { private String coverImage; /** - * @description 分类ID + * @description 标签ID(文章分类标签,tagType=1) */ - private String categoryID; + private String tagID; /** * @description 作者 @@ -144,12 +144,12 @@ public class TbResource extends BaseDTO { this.coverImage = coverImage; } - public String getCategoryID() { - return categoryID; + public String getTagID() { + return tagID; } - public void setCategoryID(String categoryID) { - this.categoryID = categoryID; + public void setTagID(String tagID) { + this.tagID = tagID; } public String getAuthor() { @@ -254,7 +254,7 @@ public class TbResource extends BaseDTO { "id=" + getID() + ", resourceID='" + resourceID + '\'' + ", title='" + title + '\'' + - ", categoryID='" + categoryID + '\'' + + ", tagID='" + tagID + '\'' + ", author='" + author + '\'' + ", status=" + status + ", viewCount=" + viewCount + diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResourceCategory.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResourceCategory.java deleted file mode 100644 index f14e99d..0000000 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResourceCategory.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.xyzh.common.dto.resource; - -import org.xyzh.common.dto.BaseDTO; - -/** - * @description 资源分类表 - * @filename TbResourceCategory.java - * @author yslg - * @copyright xyzh - * @since 2025-10-15 - */ -public class TbResourceCategory extends BaseDTO { - - private static final long serialVersionUID = 1L; - - /** - * @description 分类唯一标识 - */ - private String categoryID; - - /** - * @description 分类名称 - */ - private String name; - - /** - * @description 父分类ID - */ - private String parentID; - - /** - * @description 分类描述 - */ - private String description; - - /** - * @description 分类图标 - */ - private String icon; - - /** - * @description 排序号 - */ - private Integer orderNum; - - /** - * @description 创建者 - */ - private String creator; - - /** - * @description 更新者 - */ - private String updater; - - public String getCategoryID() { - return categoryID; - } - - public void setCategoryID(String categoryID) { - this.categoryID = categoryID; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getParentID() { - return parentID; - } - - public void setParentID(String parentID) { - this.parentID = parentID; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getIcon() { - return icon; - } - - public void setIcon(String icon) { - this.icon = icon; - } - - public Integer getOrderNum() { - return orderNum; - } - - public void setOrderNum(Integer orderNum) { - this.orderNum = orderNum; - } - - public String getCreator() { - return creator; - } - - public void setCreator(String creator) { - this.creator = creator; - } - - public String getUpdater() { - return updater; - } - - public void setUpdater(String updater) { - this.updater = updater; - } - - @Override - public String toString() { - return "TbResourceCategory{" + - "id=" + getID() + - ", categoryID='" + categoryID + '\'' + - ", name='" + name + '\'' + - ", parentID='" + parentID + '\'' + - ", orderNum=" + orderNum + - ", createTime=" + getCreateTime() + - '}'; - } -} diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbTag.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbTag.java index a2fb1bc..c803145 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbTag.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbTag.java @@ -33,6 +33,11 @@ public class TbTag extends BaseDTO { */ private String description; + /** + * @description 标签类型 1-文章分类标签 2-课程分类标签 3-学习任务分类标签 + */ + private Integer tagType; + /** * @description 创建者 */ @@ -91,6 +96,14 @@ public class TbTag extends BaseDTO { this.updater = updater; } + public Integer getTagType() { + return tagType; + } + + public void setTagType(Integer tagType) { + this.tagType = tagType; + } + @Override public String toString() { return "TbTag{" + @@ -98,6 +111,7 @@ public class TbTag extends BaseDTO { ", tagID='" + tagID + '\'' + ", name='" + name + '\'' + ", color='" + color + '\'' + + ", tagType=" + tagType + ", createTime=" + getCreateTime() + '}'; } diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/ResourceVO.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/ResourceVO.java index bafaeee..3ebccb9 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/ResourceVO.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/ResourceVO.java @@ -3,7 +3,6 @@ package org.xyzh.common.vo; import java.io.Serializable; import org.xyzh.common.dto.resource.TbResource; -import org.xyzh.common.dto.resource.TbResourceCategory; import org.xyzh.common.dto.resource.TbTag; import java.util.List; @@ -20,8 +19,9 @@ public class ResourceVO implements Serializable{ private TbResource resource; - private TbResourceCategory resourceCategory; - + /** + * 资源标签列表(包含文章分类标签 tag_type=1) + */ private List tags; public TbResource getResource() { @@ -32,13 +32,6 @@ public class ResourceVO implements Serializable{ this.resource = resource; } - public TbResourceCategory getResourceCategory() { - return resourceCategory; - } - - public void setResourceCategory(TbResourceCategory resourceCategory) { - this.resourceCategory = resourceCategory; - } public List getTags() { return tags; } diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCategoryController.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCategoryController.java deleted file mode 100644 index 0fbebbd..0000000 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCategoryController.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.xyzh.news.controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import org.xyzh.api.news.category.ResourceCategoryService; -import org.xyzh.common.core.domain.ResultDomain; -import org.xyzh.common.dto.resource.TbResourceCategory; - -/** - * @description 资源分类控制器 - * @filename ResourceCategoryController.java - * @author yslg - * @copyright xyzh - * @since 2025-10-15 - */ -@RestController -@RequestMapping("/news/categorys") -public class ResourceCategoryController { - private static final Logger logger = LoggerFactory.getLogger(ResourceCategoryController.class); - - @Autowired - private ResourceCategoryService resourceCategoryService; - - /** - * 获取分类列表 - */ - @GetMapping("/list") - public ResultDomain getCategoryList() { - return resourceCategoryService.getAllCategories(); - } - - /** - * 根据ID获取分类详情 - */ - @GetMapping("/category/{categoryID}") - public ResultDomain getCategoryById(@PathVariable String categoryID) { - return resourceCategoryService.getCategoryById(categoryID); - } - - /** - * 创建分类 - */ - @PostMapping("/category") - public ResultDomain createCategory(@RequestBody TbResourceCategory category) { - return resourceCategoryService.createCategory(category); - } - - /** - * 更新分类 - */ - @PutMapping("/category") - public ResultDomain updateCategory(@RequestBody TbResourceCategory category) { - return resourceCategoryService.updateCategory(category); - } - - /** - * 删除分类 - */ - @DeleteMapping("/category/{categoryID}") - public ResultDomain deleteCategory(@PathVariable String categoryID) { - return resourceCategoryService.deleteCategory(categoryID); - } - - /** - * 更新分类状态 - */ - @PutMapping("/category/{categoryID}/status") - public ResultDomain updateCategoryStatus(@PathVariable String categoryID, @RequestParam Integer status) { - return null; - // return resourceCategoryService.updateCategoryStatus(categoryID, status); - } - - /** - * 获取分类树 - */ - @GetMapping("/tree") - public ResultDomain getCategoryTree() { - return resourceCategoryService.getCategoryTree(); - } - - /** - * 获取子分类 - */ - @GetMapping("/category/{parentID}/children") - public ResultDomain getChildCategories(@PathVariable String parentID) { - return resourceCategoryService.getCategoriesByParent(parentID); - } -} diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCenterController.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCenterController.java index 55fa215..b0720b8 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCenterController.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceCenterController.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.dto.resource.TbResource; -import org.xyzh.common.dto.resource.TbResourceCategory; +import org.xyzh.common.dto.resource.TbTag; import java.util.Map; @@ -24,11 +24,11 @@ public class ResourceCenterController { // ==================== 专项分栏管理 ==================== /** - * 获取专项分栏列表 + * 获取专项分栏列表(使用标签 tag_type=1) */ @GetMapping("/categories") - public ResultDomain getSpecialCategories() { - // TODO: 实现获取专项分栏(包含党史学习、领导讲话、政策解读、红色经典、专题报告、思政案例6个分栏) + public ResultDomain getSpecialCategories() { + // TODO: 实现获取专项分栏,使用 TagService.getTagsByType(1) 获取文章分类标签 return null; } @@ -101,9 +101,9 @@ public class ResourceCenterController { /** * 根据分类ID获取资源 */ - @GetMapping("/category/{categoryID}/resources") + @GetMapping("/category/{tagID}/resources") public ResultDomain getResourcesByCategory( - @PathVariable String categoryID, + @PathVariable String tagID, @RequestParam(required = false) Integer pageNum, @RequestParam(required = false) Integer pageSize) { // TODO: 实现根据分类ID获取资源 @@ -118,7 +118,7 @@ public class ResourceCenterController { @GetMapping("/search") public ResultDomain searchResources( @RequestParam String keyword, - @RequestParam(required = false) String categoryID, + @RequestParam(required = false) String tagID, @RequestParam(required = false) Integer pageNum, @RequestParam(required = false) Integer pageSize) { // TODO: 实现支持模糊关键词检索,快速定位资源 @@ -238,11 +238,11 @@ public class ResourceCenterController { // ==================== 资源分类管理 ==================== /** - * 获取所有资源分类 + * 获取所有资源分类(使用标签 tag_type=1) */ @GetMapping("/categories/all") - public ResultDomain getAllCategories() { - // TODO: 实现获取所有资源分类 + public ResultDomain getAllCategories() { + // TODO: 实现获取所有资源分类,使用 TagService.getTagsByType(1) 获取文章分类标签 return null; } diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceController.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceController.java index d1186f4..0740004 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceController.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/ResourceController.java @@ -186,8 +186,8 @@ public class ResourceController { @GetMapping("/search") public ResultDomain searchResources( @RequestParam("keyword") String keyword, - @RequestParam(value = "categoryID", required = false) String categoryID, + @RequestParam(value = "tagID", required = false) String tagID, @RequestParam(value = "status", required = false) Integer status) { - return resourceService.searchResources(keyword, categoryID, status); + return resourceService.searchResources(keyword, tagID, status); } } diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/TagController.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/TagController.java index bc341a2..a53abc5 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/TagController.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/controller/TagController.java @@ -38,7 +38,7 @@ public class TagController { * 根据ID获取标签详情 */ @GetMapping("/tag/{tagID}") - public ResultDomain getTagById(@PathVariable String tagID) { + public ResultDomain getTagById(@PathVariable("tagID") String tagID) { return tagService.getTagById(tagID); } @@ -62,7 +62,7 @@ public class TagController { * 删除标签 */ @DeleteMapping("/tag/{tagID}") - public ResultDomain deleteTag(@PathVariable String tagID) { + public ResultDomain deleteTag(@PathVariable("tagID") String tagID) { return tagService.deleteTag(tagID); } @@ -70,17 +70,26 @@ public class TagController { * 搜索标签 */ @GetMapping("/search") - public ResultDomain searchTags(@RequestParam String keyword) { + public ResultDomain searchTags(@RequestParam("keyword") String keyword) { return tagService.searchTagsByName(keyword); } + /** + * 根据标签类型获取标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + */ + @GetMapping("/type/{tagType}") + public ResultDomain getTagsByType(@PathVariable("tagType") Integer tagType) { + return tagService.getTagsByType(tagType); + } + // ----------------资源标签关联相关-------------------------------- /** * 获取资源的标签列表 */ @GetMapping("/resource/{resourceID}") - public ResultDomain getResourceTags(@PathVariable String resourceID) { + public ResultDomain getResourceTags(@PathVariable("resourceID") String resourceID) { return tagService.getResourceTags(resourceID); } @@ -89,8 +98,8 @@ public class TagController { */ @PostMapping("/resource/{resourceID}/tag/{tagID}") public ResultDomain addResourceTag( - @PathVariable String resourceID, - @PathVariable String tagID) { + @PathVariable("resourceID") String resourceID, + @PathVariable("tagID") String tagID) { return tagService.addResourceTag(resourceID, tagID); } @@ -109,8 +118,8 @@ public class TagController { */ @DeleteMapping("/resource/{resourceID}/tag/{tagID}") public ResultDomain removeResourceTag( - @PathVariable String resourceID, - @PathVariable String tagID) { + @PathVariable("resourceID") String resourceID, + @PathVariable("tagID") String tagID) { return tagService.removeResourceTag(resourceID, tagID); } @@ -118,7 +127,7 @@ public class TagController { * 清空资源的所有标签 */ @DeleteMapping("/resource/{resourceID}/tags") - public ResultDomain clearResourceTags(@PathVariable String resourceID) { + public ResultDomain clearResourceTags(@PathVariable("resourceID") String resourceID) { return tagService.clearResourceTags(resourceID); } @@ -126,7 +135,7 @@ public class TagController { * 根据标签获取资源列表 */ @GetMapping("/tag/{tagID}/resources") - public ResultDomain getResourcesByTag(@PathVariable String tagID) { + public ResultDomain getResourcesByTag(@PathVariable("tagID") String tagID) { return tagService.getResourcesByTag(tagID); } } diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceCategoryMapper.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceCategoryMapper.java index f6f4b8c..0519ecb 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceCategoryMapper.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceCategoryMapper.java @@ -1,138 +1 @@ -package org.xyzh.news.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.xyzh.common.core.page.PageParam; -import org.xyzh.common.dto.resource.TbResourceCategory; - -import java.util.List; - -/** - * @description ResourceCategoryMapper.java文件描述 资源分类数据访问层 - * @filename ResourceCategoryMapper.java - * @author yslg - * @copyright xyzh - * @since 2025-10-15 - */ -@Mapper -public interface ResourceCategoryMapper extends BaseMapper { - - /** - * @description 查询资源分类列表 - * @param filter 过滤条件 - * @return List 资源分类列表 - * @author yslg - * @since 2025-10-15 - */ - List selectResourceCategories(TbResourceCategory filter); - - /** - * @description 根据分类ID查询分类信息 - * @param categoryId 分类ID - * @return TbResourceCategory 分类信息 - * @author yslg - * @since 2025-10-15 - */ - TbResourceCategory selectByCategoryId(@Param("categoryId") String categoryId); - - /** - * @description 根据父分类ID查询子分类列表 - * @param parentId 父分类ID - * @return List 子分类列表 - * @author yslg - * @since 2025-10-15 - */ - List selectByParentId(@Param("parentId") String parentId); - - /** - * @description 根据状态查询分类列表 - * @param status 状态 - * @return List 分类列表 - * @author yslg - * @since 2025-10-15 - */ - List selectByStatus(@Param("status") Integer status); - - /** - * @description 查询分类树结构 - * @return List 分类树 - * @author yslg - * @since 2025-10-15 - */ - List selectCategoryTree(); - - /** - * @description 检查分类名称是否存在 - * @param name 分类名称 - * @param excludeId 排除的分类ID(用于更新时排除自身) - * @return int 存在的数量 - * @author yslg - * @since 2025-10-15 - */ - int countByName(@Param("name") String name, @Param("excludeId") String excludeId); - - /** - * @description 插入资源分类 - * @param resourceCategory 资源分类 - * @return int 影响行数 - * @author yslg - * @since 2025-10-15 - */ - int insertResourceCategory(TbResourceCategory resourceCategory); - - /** - * @description 更新资源分类 - * @param resourceCategory 资源分类 - * @return int 影响行数 - * @author yslg - * @since 2025-10-15 - */ - int updateResourceCategory(TbResourceCategory resourceCategory); - - /** - * @description 删除资源分类 - * @param resourceCategory 资源分类 - * @return int 影响行数 - * @author yslg - * @since 2025-10-15 - */ - int deleteResourceCategory(TbResourceCategory resourceCategory); - - /** - * @description 批量插入资源分类 - * @param resourceCategoryList 资源分类列表 - * @return int 影响行数 - * @author yslg - * @since 2025-10-15 - */ - int batchInsertResourceCategories(@Param("resourceCategoryList") List resourceCategoryList); - - /** - * @description 批量删除资源分类 - * @param ids 分类ID列表 - * @return int 影响行数 - * @author yslg - * @since 2025-10-15 - */ - int batchDeleteResourceCategories(@Param("ids") List ids); - - /** - * @description 分页查询资源分类 - * @param filter 过滤条件 - * @param pageParam 分页参数 - * @return List 资源分类列表 - * @author yslg - * @since 2025-10-15 - */ - List selectResourceCategoriesPage(@Param("filter") TbResourceCategory filter, @Param("pageParam") PageParam pageParam); - - /** - * @description 统计资源分类总数 - * @param filter 过滤条件 - * @return long 总数 - * @author yslg - * @since 2025-10-15 - */ - long countResourceCategories(@Param("filter") TbResourceCategory filter); -} + \ No newline at end of file diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceMapper.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceMapper.java index f4cf83c..d5638c4 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceMapper.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/ResourceMapper.java @@ -37,13 +37,13 @@ public interface ResourceMapper extends BaseMapper { TbResource selectByResourceId(@Param("resourceId") String resourceId); /** - * @description 根据分类ID查询资源列表 - * @param categoryId 分类ID + * @description 根据标签ID查询资源列表 + * @param tagId 标签ID(文章分类标签,tagType=1) * @return List 资源列表 * @author yslg * @since 2025-10-15 */ - List selectByCategoryId(@Param("categoryId") String categoryId); + List selectByTagId(@Param("tagId") String tagId); /** * @description 根据状态查询资源列表 diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/TagMapper.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/TagMapper.java index d574af7..81afef3 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/TagMapper.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/mapper/TagMapper.java @@ -55,13 +55,13 @@ public interface TagMapper extends BaseMapper { List selectByStatus(@Param("status") Integer status); /** - * @description 根据类型查询标签列表 - * @param type 类型 + * @description 根据标签类型查询标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) * @return List 标签列表 * @author yslg - * @since 2025-10-15 + * @since 2025-10-27 */ - List selectByType(@Param("type") Integer type); + List selectByTagType(@Param("tagType") Integer tagType); /** * @description 查询热门标签列表 @@ -73,14 +73,15 @@ public interface TagMapper extends BaseMapper { List selectHotTags(@Param("limit") Integer limit); /** - * @description 检查标签名称是否存在 + * @description 检查标签名称是否存在(同类型下) * @param name 标签名称 + * @param tagType 标签类型 * @param excludeId 排除的标签ID(用于更新时排除自身) * @return int 存在的数量 * @author yslg - * @since 2025-10-15 + * @since 2025-10-27 */ - int countByName(@Param("name") String name, @Param("excludeId") String excludeId); + int countByNameAndType(@Param("name") String name, @Param("tagType") Integer tagType, @Param("excludeId") String excludeId); /** * @description 插入标签 diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/NCResourceCategoryService.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/NCResourceCategoryService.java deleted file mode 100644 index 2016c54..0000000 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/NCResourceCategoryService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.xyzh.news.service; - -import org.xyzh.api.news.category.ResourceCategoryService; - -/** - * @description 资源分类服务接口 - * @filename NCResourceCategoryService.java - * @author yslg - * @copyright xyzh - * @since 2025-10-15 - */ -public interface NCResourceCategoryService extends ResourceCategoryService { - -} diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceCategoryServiceImpl.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceCategoryServiceImpl.java deleted file mode 100644 index 0a00937..0000000 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceCategoryServiceImpl.java +++ /dev/null @@ -1,360 +0,0 @@ -package org.xyzh.news.service.impl; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; -import org.xyzh.common.core.domain.ResultDomain; -import org.xyzh.common.dto.resource.TbResourceCategory; -import org.xyzh.common.utils.IDUtils; -import org.xyzh.news.mapper.ResourceCategoryMapper; -import org.xyzh.api.news.category.ResourceCategoryService; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.UUID; - -/** - * @description 资源分类服务实现类 - * @filename NCResourceCategoryServiceImpl.java - * @author yslg - * @copyright xyzh - * @since 2025-10-15 - */ -@Service -public class NCResourceCategoryServiceImpl implements ResourceCategoryService { - - private static final Logger logger = LoggerFactory.getLogger(NCResourceCategoryServiceImpl.class); - - @Autowired - private ResourceCategoryMapper resourceCategoryMapper; - - @Override - @Transactional(rollbackFor = Exception.class) - public ResultDomain createCategory(TbResourceCategory category) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - // 参数验证 - if (category == null || !StringUtils.hasText(category.getName())) { - resultDomain.fail("分类名称不能为空"); - return resultDomain; - } - - // 检查分类名称是否已存在 - int count = resourceCategoryMapper.countByName(category.getName(), null); - if (count > 0) { - resultDomain.fail("分类名称已存在"); - return resultDomain; - } - - // 设置默认值 - if (category.getID() == null) { - category.setID(IDUtils.generateID()); - } - if (category.getCategoryID() == null) { - category.setCategoryID(IDUtils.generateID()); - } - if (category.getOrderNum() == null) { - category.setOrderNum(0); - } - - category.setCreateTime(new Date()); - category.setUpdateTime(new Date()); - category.setDeleted(false); - - // 插入数据库 - int result = resourceCategoryMapper.insertResourceCategory(category); - if (result > 0) { - logger.info("创建分类成功: {}", category.getName()); - resultDomain.success("创建分类成功", category); - return resultDomain; - } else { - resultDomain.fail("创建分类失败"); - return resultDomain; - } - } catch (Exception e) { - logger.error("创建分类异常: {}", e.getMessage(), e); - resultDomain.fail("创建分类失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public ResultDomain updateCategory(TbResourceCategory category) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - // 参数验证 - if (category == null || !StringUtils.hasText(category.getID())) { - resultDomain.fail("分类ID不能为空"); - return resultDomain; - } - - // 检查分类是否存在 - TbResourceCategory existingCategory = resourceCategoryMapper.selectById(category.getID()); - if (existingCategory == null || existingCategory.getDeleted()) { - resultDomain.fail("分类不存在"); - return resultDomain; - } - - // 检查分类名称是否重复(排除自身) - if (StringUtils.hasText(category.getName())) { - int count = resourceCategoryMapper.countByName(category.getName(), category.getID()); - if (count > 0) { - resultDomain.fail("分类名称已存在"); - return resultDomain; - } - } - - // 更新时间 - category.setUpdateTime(new Date()); - - // 更新数据库 - int result = resourceCategoryMapper.updateResourceCategory(category); - if (result > 0) { - logger.info("更新分类成功: {}", category.getID()); - // 重新查询返回完整数据 - TbResourceCategory updated = resourceCategoryMapper.selectById(category.getID()); - resultDomain.success("更新分类成功", updated); - return resultDomain; - } else { - resultDomain.fail("更新分类失败"); - return resultDomain; - } - } catch (Exception e) { - logger.error("更新分类异常: {}", e.getMessage(), e); - resultDomain.fail("更新分类失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public ResultDomain deleteCategory(String categoryID) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - // 参数验证 - if (!StringUtils.hasText(categoryID)) { - resultDomain.fail("分类ID不能为空"); - return resultDomain; - } - - // 检查分类是否存在 - TbResourceCategory category = resourceCategoryMapper.selectByCategoryId(categoryID); - if (category == null || category.getDeleted()) { - resultDomain.fail("分类不存在"); - return resultDomain; - } - - // 检查是否有子分类 - ResultDomain hasChildResult = hasChildCategories(categoryID); - if (hasChildResult.isSuccess() && Boolean.TRUE.equals(hasChildResult.getData())) { - resultDomain.fail("该分类下存在子分类,无法删除"); - return resultDomain; - } - - // 检查是否有关联资源 - ResultDomain hasResourceResult = hasResources(categoryID); - if (hasResourceResult.isSuccess() && Boolean.TRUE.equals(hasResourceResult.getData())) { - resultDomain.fail("该分类下存在资源,无法删除"); - return resultDomain; - } - - // 物理删除 - int result = resourceCategoryMapper.deleteResourceCategory(category); - if (result > 0) { - logger.info("删除分类成功: {}", categoryID); - resultDomain.success("删除分类成功", true); - return resultDomain; - } else { - resultDomain.fail("删除分类失败"); - return resultDomain; - } - } catch (Exception e) { - logger.error("删除分类异常: {}", e.getMessage(), e); - resultDomain.fail("删除分类失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - public ResultDomain getCategoryById(String categoryID) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - if (!StringUtils.hasText(categoryID)) { - resultDomain.fail("分类ID不能为空"); - return resultDomain; - } - - TbResourceCategory category = resourceCategoryMapper.selectByCategoryId(categoryID); - if (category == null || category.getDeleted()) { - resultDomain.fail("分类不存在"); - return resultDomain; - } - - resultDomain.success("查询成功", category); - return resultDomain; - } catch (Exception e) { - logger.error("查询分类异常: {}", e.getMessage(), e); - resultDomain.fail("查询分类失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - public ResultDomain getAllCategories() { - ResultDomain resultDomain = new ResultDomain<>(); - try { - List categories = resourceCategoryMapper.selectResourceCategories(new TbResourceCategory()); - resultDomain.success("查询成功", categories); - return resultDomain; - } catch (Exception e) { - logger.error("查询分类列表异常: {}", e.getMessage(), e); - resultDomain.fail("查询分类列表失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - public ResultDomain getCategoriesByParent(String parentID) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - if (!StringUtils.hasText(parentID)) { - resultDomain.fail("父分类ID不能为空"); - return resultDomain; - } - - List categories = resourceCategoryMapper.selectByParentId(parentID); - resultDomain.success("查询成功", categories); - return resultDomain; - } catch (Exception e) { - logger.error("查询子分类列表异常: {}", e.getMessage(), e); - resultDomain.fail("查询子分类列表失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - public ResultDomain getCategoryTree() { - ResultDomain resultDomain = new ResultDomain<>(); - try { - // 查询所有分类 - List allCategories = resourceCategoryMapper.selectCategoryTree(); - - // 构建树形结构 - List tree = buildCategoryTree(allCategories, null); - - resultDomain.success("查询成功", tree); - return resultDomain; - } catch (Exception e) { - logger.error("查询分类树异常: {}", e.getMessage(), e); - resultDomain.fail("查询分类树失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - public ResultDomain hasChildCategories(String categoryID) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - if (!StringUtils.hasText(categoryID)) { - resultDomain.fail("分类ID不能为空"); - return resultDomain; - } - - List children = resourceCategoryMapper.selectByParentId(categoryID); - resultDomain.success("查询成功", !children.isEmpty()); - return resultDomain; - } catch (Exception e) { - logger.error("检查子分类异常: {}", e.getMessage(), e); - resultDomain.fail("检查子分类失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - public ResultDomain hasResources(String categoryID) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - if (!StringUtils.hasText(categoryID)) { - resultDomain.fail("分类ID不能为空"); - return resultDomain; - } - - // TODO: 需要查询资源表判断是否有关联资源 - // 这里暂时返回false,需要在ResourceMapper中添加相应方法 - resultDomain.success("查询成功", false); - return resultDomain; - } catch (Exception e) { - logger.error("检查分类资源异常: {}", e.getMessage(), e); - resultDomain.fail("检查分类资源失败: " + e.getMessage()); - return resultDomain; - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public ResultDomain updateCategoryOrder(String categoryID, Integer orderNum) { - ResultDomain resultDomain = new ResultDomain<>(); - try { - if (!StringUtils.hasText(categoryID) || orderNum == null) { - resultDomain.fail("参数不能为空"); - return resultDomain; - } - - TbResourceCategory category = resourceCategoryMapper.selectByCategoryId(categoryID); - if (category == null || category.getDeleted()) { - resultDomain.fail("分类不存在"); - return resultDomain; - } - - TbResourceCategory updateCategory = new TbResourceCategory(); - updateCategory.setID(category.getID()); - updateCategory.setOrderNum(orderNum); - updateCategory.setUpdateTime(new Date()); - - int result = resourceCategoryMapper.updateResourceCategory(updateCategory); - if (result > 0) { - logger.info("更新分类排序成功: {}", categoryID); - TbResourceCategory updated = resourceCategoryMapper.selectById(category.getID()); - resultDomain.success("更新排序成功", updated); - return resultDomain; - } else { - resultDomain.fail("更新排序失败"); - return resultDomain; - } - } catch (Exception e) { - logger.error("更新分类排序异常: {}", e.getMessage(), e); - resultDomain.fail("更新排序失败: " + e.getMessage()); - return resultDomain; - } - } - - /** - * 构建分类树形结构 - * @param allCategories 所有分类列表 - * @param parentID 父分类ID - * @return 树形结构列表 - */ - private List buildCategoryTree(List allCategories, String parentID) { - List result = new ArrayList<>(); - - for (TbResourceCategory category : allCategories) { - // 找出当前父级下的子分类 - if ((parentID == null && category.getParentID() == null) || - (parentID != null && parentID.equals(category.getParentID()))) { - - // 递归查找子分类(如果TbResourceCategory有children字段,可以在这里设置) - // List children = buildCategoryTree(allCategories, category.getCategoryID()); - // category.setChildren(children); - - result.add(category); - } - } - - return result; - } -} diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java index 7315a62..05177c5 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java @@ -721,7 +721,7 @@ public class NCResourceServiceImpl implements ResourceService { } @Override - public ResultDomain searchResources(String keyword, String categoryID, Integer status) { + public ResultDomain searchResources(String keyword, String tagID, Integer status) { ResultDomain resultDomain = new ResultDomain<>(); try { // 参数验证 @@ -734,8 +734,8 @@ public class NCResourceServiceImpl implements ResourceService { List list = resourceMapper.searchByKeyword(keyword); // 如果指定了分类ID,进行过滤 - if (StringUtils.hasText(categoryID) && list != null) { - list.removeIf(resource -> !categoryID.equals(resource.getCategoryID())); + if (StringUtils.hasText(tagID) && list != null) { + list.removeIf(resource -> !tagID.equals(resource.getTagID())); } // 如果指定了状态,进行过滤 diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCTagServiceImpl.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCTagServiceImpl.java index f704108..0fb91bf 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCTagServiceImpl.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCTagServiceImpl.java @@ -49,10 +49,10 @@ public class NCTagServiceImpl implements TagService { return resultDomain; } - // 检查标签名称是否已存在 - int count = tagMapper.countByName(tag.getName(), null); + // 检查标签名称是否已存在(同类型下) + int count = tagMapper.countByNameAndType(tag.getName(), tag.getTagType(), null); if (count > 0) { - resultDomain.fail("标签名称已存在"); + resultDomain.fail("该类型下标签名称已存在"); return resultDomain; } @@ -103,11 +103,12 @@ public class NCTagServiceImpl implements TagService { return resultDomain; } - // 检查标签名称是否重复(排除自身) + // 检查标签名称是否重复(排除自身,同类型下) if (StringUtils.hasText(tag.getName())) { - int count = tagMapper.countByName(tag.getName(), tag.getID()); + Integer tagType = tag.getTagType() != null ? tag.getTagType() : existingTag.getTagType(); + int count = tagMapper.countByNameAndType(tag.getName(), tagType, tag.getID()); if (count > 0) { - resultDomain.fail("标签名称已存在"); + resultDomain.fail("该类型下标签名称已存在"); return resultDomain; } } @@ -460,4 +461,29 @@ public class NCTagServiceImpl implements TagService { return resultDomain; } } + + @Override + public ResultDomain getTagsByType(Integer tagType) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + if (tagType == null) { + resultDomain.fail("标签类型不能为空"); + return resultDomain; + } + + // 验证标签类型是否有效(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + if (tagType < 1 || tagType > 3) { + resultDomain.fail("无效的标签类型"); + return resultDomain; + } + + List tags = tagMapper.selectByTagType(tagType); + resultDomain.success("查询成功", tags); + return resultDomain; + } catch (Exception e) { + logger.error("根据类型查询标签异常: {}", e.getMessage(), e); + resultDomain.fail("根据类型查询标签失败: " + e.getMessage()); + return resultDomain; + } + } } diff --git a/schoolNewsServ/news/src/main/resources/mapper/DataCollectionConfigMapper.xml b/schoolNewsServ/news/src/main/resources/mapper/DataCollectionConfigMapper.xml index 3884ce2..6f52676 100644 --- a/schoolNewsServ/news/src/main/resources/mapper/DataCollectionConfigMapper.xml +++ b/schoolNewsServ/news/src/main/resources/mapper/DataCollectionConfigMapper.xml @@ -9,7 +9,7 @@ - + @@ -22,7 +22,7 @@ - id, name, source_url, source_type, frequency, category_id, status, + id, name, source_url, source_type, frequency, tag_id, status, last_collect_time, creator, updater, create_time, update_time, delete_time, deleted @@ -40,8 +40,8 @@ AND frequency = #{frequency} - - AND category_id = #{categoryID} + + AND tag_id = #{tagID} AND status = #{status} @@ -114,11 +114,11 @@ INSERT INTO tb_data_collection_config ( - id, name, source_url, source_type, frequency, category_id, status, + id, name, source_url, source_type, frequency, tag_id, status, last_collect_time, creator, updater, create_time, update_time, delete_time, deleted ) VALUES ( - #{id}, #{name}, #{sourceUrl}, #{sourceType}, #{frequency}, #{categoryID}, #{status}, + #{id}, #{name}, #{sourceUrl}, #{sourceType}, #{frequency}, #{tagID}, #{status}, #{lastCollectTime}, #{creator}, #{updater}, #{createTime}, #{updateTime}, #{deleteTime}, #{deleted} ) @@ -140,8 +140,8 @@ frequency = #{frequency}, - - category_id = #{categoryID}, + + tag_id = #{tagID}, status = #{status}, @@ -174,14 +174,14 @@ INSERT INTO tb_data_collection_config ( - id, name, source_url, source_type, frequency, category_id, status, + id, name, source_url, source_type, frequency, tag_id, status, last_collect_time, creator, updater, create_time, update_time, delete_time, deleted ) VALUES ( #{item.id}, #{item.name}, #{item.sourceUrl}, #{item.sourceType}, #{item.frequency}, - #{item.categoryID}, #{item.status}, #{item.lastCollectTime}, #{item.creator}, + #{item.tagID}, #{item.status}, #{item.lastCollectTime}, #{item.creator}, #{item.updater}, #{item.createTime}, #{item.updateTime}, #{item.deleteTime}, #{item.deleted} ) diff --git a/schoolNewsServ/news/src/main/resources/mapper/ResourceCategoryMapper.xml b/schoolNewsServ/news/src/main/resources/mapper/ResourceCategoryMapper.xml deleted file mode 100644 index 1f95602..0000000 --- a/schoolNewsServ/news/src/main/resources/mapper/ResourceCategoryMapper.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - id, category_id, name, parent_id, description, icon, order_num, - creator, updater, create_time, update_time, delete_time, deleted - - - - - - deleted = 0 - - AND category_id = #{categoryID} - - - AND name LIKE CONCAT('%', #{name}, '%') - - - AND parent_id = #{parentID} - - - - - - - - - - - - - - - - - - - - - - - - - INSERT INTO tb_resource_category ( - id, category_id, name, parent_id, description, icon, order_num, - creator, updater, create_time, update_time, delete_time, deleted - ) VALUES ( - #{id}, #{categoryID}, #{name}, #{parentID}, #{description}, #{icon}, #{orderNum}, - #{creator}, #{updater}, #{createTime}, #{updateTime}, #{deleteTime}, #{deleted} - ) - - - - - UPDATE tb_resource_category - - - category_id = #{categoryID}, - - - name = #{name}, - - - parent_id = #{parentID}, - - - description = #{description}, - - - icon = #{icon}, - - - order_num = #{orderNum}, - - - updater = #{updater}, - - - update_time = #{updateTime}, - - - delete_time = #{deleteTime}, - - - deleted = #{deleted}, - - - WHERE id = #{id} - - - - - DELETE FROM tb_resource_category - WHERE id = #{id} - - - - - INSERT INTO tb_resource_category ( - id, category_id, name, parent_id, description, icon, order_num, - creator, updater, create_time, update_time, delete_time, deleted - ) VALUES - - ( - #{item.id}, #{item.categoryID}, #{item.name}, #{item.parentID}, #{item.description}, - #{item.icon}, #{item.orderNum}, #{item.creator}, #{item.updater}, - #{item.createTime}, #{item.updateTime}, #{item.deleteTime}, #{item.deleted} - ) - - - - - - DELETE FROM tb_resource_category - WHERE id IN - - #{id} - - - - - - - - - - diff --git a/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml b/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml index 7717dcc..0d4aa81 100644 --- a/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml +++ b/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml @@ -10,7 +10,7 @@ - + @@ -31,7 +31,7 @@ - id, resource_id, title, content, summary, cover_image, category_id, author, source, + id, resource_id, title, content, summary, cover_image, tag_id, author, source, source_url, view_count, like_count, collect_count, status, is_recommend, is_banner, publish_time, creator, updater, create_time, update_time, delete_time, deleted @@ -44,8 +44,8 @@ AND title LIKE CONCAT('%', #{title}, '%') - - AND category_id = #{categoryID} + + AND tag_id = #{tagID} AND author LIKE CONCAT('%', #{author}, '%') @@ -79,12 +79,12 @@ WHERE resource_id = #{resourceId} AND deleted = 0 - - SELECT FROM tb_resource - WHERE category_id = #{categoryId} AND deleted = 0 + WHERE tag_id = #{tagId} AND deleted = 0 ORDER BY publish_time DESC, create_time DESC @@ -97,12 +97,12 @@ ORDER BY publish_time DESC, create_time DESC - + @@ -155,12 +155,12 @@ INSERT INTO tb_resource ( - id, resource_id, title, content, summary, cover_image, category_id, author, source, + id, resource_id, title, content, summary, cover_image, tag_id, author, source, source_url, view_count, like_count, collect_count, status, is_recommend, is_banner, publish_time, creator, updater, create_time, update_time, delete_time, deleted ) VALUES ( - #{id}, #{resourceID}, #{title}, #{content}, #{summary}, #{coverImage}, #{categoryID}, #{author}, #{source}, + #{id}, #{resourceID}, #{title}, #{content}, #{summary}, #{coverImage}, #{tagID}, #{author}, #{source}, #{sourceUrl}, #{viewCount}, #{likeCount}, #{collectCount}, #{status}, #{isRecommend}, #{isBanner}, #{publishTime}, #{creator}, #{updater}, #{createTime}, #{updateTime}, #{deleteTime}, #{deleted} @@ -183,8 +183,8 @@ cover_image = #{coverImage}, - - category_id = #{categoryID}, + + tag_id = #{tagID}, author = #{author}, @@ -241,7 +241,7 @@ INSERT INTO tb_resource ( - id, resource_id, title, content, summary, cover_image, category_id, author, source, + id, resource_id, title, content, summary, cover_image, tag_id, author, source, source_url, view_count, like_count, collect_count, status, is_recommend, is_banner, publish_time, creator, updater, create_time, update_time, delete_time, deleted @@ -249,7 +249,7 @@ ( #{item.id}, #{item.resourceID}, #{item.title}, #{item.content}, #{item.summary}, #{item.coverImage}, - #{item.categoryID}, #{item.author}, #{item.source}, #{item.sourceUrl}, + #{item.tagID}, #{item.author}, #{item.source}, #{item.sourceUrl}, #{item.viewCount}, #{item.likeCount}, #{item.collectCount}, #{item.status}, #{item.isRecommend}, #{item.isBanner}, #{item.publishTime}, #{item.creator}, #{item.updater}, #{item.createTime}, #{item.updateTime}, #{item.deleteTime}, #{item.deleted} @@ -276,8 +276,8 @@ AND title LIKE CONCAT('%', #{filter.title}, '%') - - AND category_id = #{filter.categoryID} + + AND tag_id = #{filter.tagID} AND author LIKE CONCAT('%', #{filter.author}, '%') diff --git a/schoolNewsServ/news/src/main/resources/mapper/TagMapper.xml b/schoolNewsServ/news/src/main/resources/mapper/TagMapper.xml index 569423d..67fb278 100644 --- a/schoolNewsServ/news/src/main/resources/mapper/TagMapper.xml +++ b/schoolNewsServ/news/src/main/resources/mapper/TagMapper.xml @@ -9,6 +9,7 @@ + @@ -19,7 +20,7 @@ - id, tag_id, name, color, description, creator, updater, create_time, + id, tag_id, name, color, description, tag_type, creator, updater, create_time, update_time, delete_time, deleted @@ -36,6 +37,9 @@ AND color = #{color} + + AND tag_type = #{tagType} + @@ -73,12 +77,15 @@ ORDER BY create_time DESC - - SELECT FROM tb_tag WHERE deleted = 0 + + AND tag_type = #{tagType} + ORDER BY create_time DESC @@ -94,11 +101,14 @@ - - SELECT COUNT(1) FROM tb_tag WHERE name = #{name} AND deleted = 0 + + AND tag_type = #{tagType} + AND id != #{excludeId} @@ -107,10 +117,10 @@ INSERT INTO tb_tag ( - id, tag_id, name, color, description, creator, updater, create_time, + id, tag_id, name, color, description, tag_type, creator, updater, create_time, update_time, delete_time, deleted ) VALUES ( - #{id}, #{tagID}, #{name}, #{color}, #{description}, #{creator}, #{updater}, #{createTime}, + #{id}, #{tagID}, #{name}, #{color}, #{description}, #{tagType}, #{creator}, #{updater}, #{createTime}, #{updateTime}, #{deleteTime}, #{deleted} ) @@ -131,6 +141,9 @@ description = #{description}, + + tag_type = #{tagType}, + updater = #{updater}, @@ -156,13 +169,13 @@ INSERT INTO tb_tag ( - id, tag_id, name, color, description, creator, updater, create_time, + id, tag_id, name, color, description, tag_type, creator, updater, create_time, update_time, delete_time, deleted ) VALUES ( #{item.id}, #{item.tagID}, #{item.name}, #{item.color}, #{item.description}, - #{item.creator}, #{item.updater}, #{item.createTime}, #{item.updateTime}, + #{item.tagType}, #{item.creator}, #{item.updater}, #{item.createTime}, #{item.updateTime}, #{item.deleteTime}, #{item.deleted} ) diff --git a/schoolNewsWeb/TAG_SYSTEM_MIGRATION.md b/schoolNewsWeb/TAG_SYSTEM_MIGRATION.md new file mode 100644 index 0000000..6747390 --- /dev/null +++ b/schoolNewsWeb/TAG_SYSTEM_MIGRATION.md @@ -0,0 +1,360 @@ +# 前端标签系统类型化改造文档 + +## 📝 改造概述 + +前端标签系统已更新,支持3种标签类型,与后端保持一致: +1. **文章分类标签** (tagType=1) - 替代原 `ResourceCategory` +2. **课程分类标签** (tagType=2) +3. **学习任务分类标签** (tagType=3) + +### 改造日期 +2025-10-27 + +--- + +## 🔄 前端变更内容 + +### 1. 类型定义更新 + +#### 文件:`src/types/resource/index.ts` + +**新增 TagType 枚举:** +```typescript +/** + * 标签类型枚举 + */ +export enum TagType { + /** 文章分类标签 */ + ARTICLE_CATEGORY = 1, + /** 课程分类标签 */ + COURSE_CATEGORY = 2, + /** 学习任务分类标签 */ + LEARNING_TASK_CATEGORY = 3 +} +``` + +**Tag 接口更新:** +```typescript +export interface Tag extends BaseDTO { + /** 标签ID */ + tagID?: string; + /** 标签名称 */ + name?: string; + /** 标签描述 */ + description?: string; + /** 标签颜色 */ + color?: string; + /** 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) */ + tagType?: number; // ✅ 新增字段 + /** 排序号 */ + orderNum?: number; + /** 状态(0禁用 1启用) */ + status?: number; + /** 创建者 */ + creator?: string; + /** 更新者 */ + updater?: string; +} +``` + +**ResourceVO 接口更新:** +```typescript +/** + * 资源视图对象(已废弃category字段) + * @deprecated category字段已废弃,请使用tags字段中tagType=1的标签 + */ +export interface ResourceVO extends BaseDTO{ + resource: Resource; + /** @deprecated 已废弃,改用tags字段(tagType=1表示文章分类标签) */ + category?: ResourceCategory; + tags: Tag[]; +} +``` + +--- + +### 2. API 接口更新 + +#### 文件:`src/apis/resource/resourceTag.ts` + +**新增方法:** +```typescript +/** + * 根据标签类型获取标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + * @returns Promise> + */ +async getTagsByType(tagType: number): Promise> { + const response = await api.get(`/news/tags/type/${tagType}`); + return response.data; +} +``` + +**使用示例:** +```typescript +import { resourceTagApi } from '@/apis/resource'; +import { TagType } from '@/types/resource'; + +// 获取文章分类标签 +const articleTags = await resourceTagApi.getTagsByType(TagType.ARTICLE_CATEGORY); + +// 获取课程分类标签 +const courseTags = await resourceTagApi.getTagsByType(TagType.COURSE_CATEGORY); + +// 获取学习任务分类标签 +const taskTags = await resourceTagApi.getTagsByType(TagType.LEARNING_TASK_CATEGORY); +``` + +--- + +### 3. ResourceCategory API 废弃 + +#### 文件:`src/apis/resource/resourceCategory.ts` + +**⚠️ 此 API 已废弃!** + +从2025-10-27起,资源分类功能已迁移到标签系统(Tag)中。 + +**API 迁移对照表:** + +| 原 ResourceCategory API | 新 Tag API | 说明 | +|------------------------|-----------|------| +| `resourceCategoryApi.getCategoryList()` | `resourceTagApi.getTagsByType(1)` | 获取文章分类标签列表 | +| `resourceCategoryApi.getCategoryById(id)` | `resourceTagApi.getTagById(id)` | 获取标签详情 | +| `resourceCategoryApi.createCategory(category)` | `resourceTagApi.createTag({...category, tagType: 1})` | 创建文章分类标签 | +| `resourceCategoryApi.updateCategory(category)` | `resourceTagApi.updateTag(category)` | 更新标签 | +| `resourceCategoryApi.deleteCategory(id)` | `resourceTagApi.deleteTag(id)` | 删除标签 | + +--- + +## 📦 已更新的组件 + +### 1. ArticleManagementView.vue +**文件:** `src/views/admin/manage/resource/ArticleManagementView.vue` + +**变更内容:** +```typescript +// 修改前 +import { resourceApi, resourceCategoryApi } from '@/apis/resource' +const categoryList = ref([]); +const res = await resourceCategoryApi.getCategoryList(); + +// 修改后 +import { resourceApi, resourceTagApi } from '@/apis/resource' +const categoryList = ref([]); // 改为使用Tag类型(tagType=1表示文章分类) +const res = await resourceTagApi.getTagsByType(1); // 1 = 文章分类标签 +``` + +--- + +### 2. ArticleAddView.vue +**文件:** `src/views/article/ArticleAddView.vue` + +**变更内容:** +```typescript +// 修改前 +import { resourceCategoryApi, resourceTagApi, resourceApi } from '@/apis/resource'; +const categoryList = ref([]); +const result = await resourceCategoryApi.getCategoryList(); + +// 修改后 +import { resourceTagApi, resourceApi } from '@/apis/resource'; +const categoryList = ref([]); // 改为使用Tag类型(tagType=1表示文章分类) +const result = await resourceTagApi.getTagsByType(TagType.ARTICLE_CATEGORY); +``` + +**模板更新:** +```vue + + + + + +``` + +--- + +### 3. ResourceSideBar.vue +**文件:** `src/views/resource-center/components/ResourceSideBar.vue` + +**变更内容:** +```typescript +// 修改前 +import { resourceCategoryApi } from '@/apis/resource'; +import type { ResourceCategory } from '@/types/resource'; +const categories = ref([]); +const res = await resourceCategoryApi.getCategoryList(); + +// 修改后 +import { resourceTagApi } from '@/apis/resource'; +import type { Tag, TagType } from '@/types/resource'; +const categories = ref([]); // 改为使用Tag类型(tagType=1表示文章分类) +const res = await resourceTagApi.getTagsByType(1); // 1 = 文章分类标签 +``` + +**模板更新:** +```vue + +
+ + +
+``` + +--- + +## 🎓 学习任务和课程标签说明 + +### 课程标签(tagType=2) + +**类型定义:** `src/types/study/index.ts` + +课程标签使用统一的标签系统(tb_tag表): +- 使用 `tagType=2` 表示课程分类标签 +- 通过 `resourceTagApi.getTagsByType(TagType.COURSE_CATEGORY)` 获取课程分类标签 + +**使用示例:** +```typescript +import { resourceTagApi } from '@/apis/resource'; +import { TagType } from '@/types/resource'; + +// 在课程管理页面加载课程分类标签 +async function loadCourseTags() { + const result = await resourceTagApi.getTagsByType(TagType.COURSE_CATEGORY); + if (result.success) { + courseTags.value = result.dataList || []; + } +} +``` + +--- + +### 学习任务标签(tagType=3) + +**类型定义:** `src/types/study/index.ts` + +学习任务分类使用统一的标签系统(tb_tag表): +- 使用 `tagType=3` 表示学习任务分类标签 +- 通过 `resourceTagApi.getTagsByType(TagType.LEARNING_TASK_CATEGORY)` 获取学习任务分类标签 + +**使用示例:** +```typescript +import { resourceTagApi } from '@/apis/resource'; +import { TagType } from '@/types/resource'; + +// 在学习任务管理页面加载任务分类标签 +async function loadTaskTags() { + const result = await resourceTagApi.getTagsByType(TagType.LEARNING_TASK_CATEGORY); + if (result.success) { + taskTags.value = result.dataList || []; + } +} +``` + +--- + +## 📋 迁移检查清单 + +### 开发人员检查清单 + +- [x] ✅ 更新 Tag 类型定义(添加 tagType 字段) +- [x] ✅ 添加 TagType 枚举 +- [x] ✅ 更新 resourceTag API(添加 getTagsByType 方法) +- [x] ✅ 废弃 resourceCategory API(添加迁移说明) +- [x] ✅ 更新 ArticleManagementView 组件 +- [x] ✅ 更新 ArticleAddView 组件 +- [x] ✅ 更新 ResourceSideBar 组件 +- [x] ✅ 添加课程标签说明文档 +- [x] ✅ 添加学习任务标签说明文档 + +### 未来开发任务 + +当开发课程管理或学习任务管理功能时: + +- [ ] 在课程管理页面使用 `resourceTagApi.getTagsByType(2)` 获取课程分类标签 +- [ ] 在学习任务管理页面使用 `resourceTagApi.getTagsByType(3)` 获取任务分类标签 +- [ ] 为课程添加分类标签选择功能 +- [ ] 为学习任务添加分类标签选择功能 + +--- + +## ⚠️ 注意事项 + +### 1. 向后兼容性 + +- `ResourceCategory` 类型和 `resourceCategoryApi` 暂时保留,但标记为 `@deprecated` +- 建议尽快迁移到新的标签 API +- 旧代码仍可运行,但会在 IDE 中显示废弃警告 + +### 2. 字段映射变化 + +| ResourceCategory | Tag | 说明 | +|-----------------|-----|------| +| `tagID` | `tagID` | 唯一标识字段名变更 | +| `name` | `name` | 名称字段保持不变 | +| `description` | `description` | 描述字段保持不变 | +| - | `tagType` | 新增:标签类型(1/2/3) | +| - | `color` | 新增:标签颜色 | + +### 3. 导入路径 + +所有标签相关的类型和 API 现在统一从以下位置导入: + +```typescript +// 类型导入 +import { Tag, TagType } from '@/types/resource'; + +// API 导入 +import { resourceTagApi } from '@/apis/resource'; +``` + +--- + +## 🎯 总结 + +本次前端标签系统改造: + +1. ✅ **统一标签管理** - 文章、课程、学习任务使用统一的标签系统 +2. ✅ **类型化分类** - 通过 tagType 区分不同业务领域的标签 +3. ✅ **简化架构** - 废弃 ResourceCategory,统一使用 Tag +4. ✅ **灵活扩展** - 为未来添加新标签类型预留空间 +5. ✅ **向后兼容** - 旧 API 仍可使用(标记为废弃) + +### 迁移前后对比 + +| 项目 | 迁移前 | 迁移后 | +|------|--------|--------| +| 文章分类 | `resourceCategoryApi.getCategoryList()` | `resourceTagApi.getTagsByType(1)` | +| 课程分类 | 无 | `resourceTagApi.getTagsByType(2)` | +| 学习任务分类 | 无 | `resourceTagApi.getTagsByType(3)` | +| 类型定义 | `ResourceCategory` | `Tag` (with tagType) | +| 字段名 | `tagID` | `tagID` | + +改造完成后,系统将具备更清晰的业务边界、更简洁的代码结构和更灵活的扩展能力。 + +--- + +## 📚 相关文档 + +- 后端迁移文档:`schoolNewsServ/.bin/mysql/sql/TAG_TYPE_MIGRATION.md` +- 后端移除清单:`schoolNewsServ/.bin/mysql/sql/RESOURCE_CATEGORY_REMOVAL.md` +- 前端项目结构:`schoolNewsWeb/PROJECT_STRUCTURE.md` + diff --git a/schoolNewsWeb/src/apis/resource/resource.ts b/schoolNewsWeb/src/apis/resource/resource.ts index 113539d..ed71693 100644 --- a/schoolNewsWeb/src/apis/resource/resource.ts +++ b/schoolNewsWeb/src/apis/resource/resource.ts @@ -199,17 +199,17 @@ export const resourceApi = { /** * 搜索资源 * @param keyword 搜索关键词 - * @param categoryID 分类ID(可选) + * @param tagID 分类ID(可选) * @param status 状态(可选) * @returns Promise> */ async searchResources( keyword: string, - categoryID?: string, + tagID?: string, status?: number ): Promise> { const params: any = { keyword }; - if (categoryID) params.categoryID = categoryID; + if (tagID) params.tagID = tagID; if (status !== undefined) params.status = status; const response = await api.get('/news/resources/search', params); diff --git a/schoolNewsWeb/src/apis/resource/resourceCategory.ts b/schoolNewsWeb/src/apis/resource/resourceCategory.ts index 1c80b2a..68e9c69 100644 --- a/schoolNewsWeb/src/apis/resource/resourceCategory.ts +++ b/schoolNewsWeb/src/apis/resource/resourceCategory.ts @@ -4,6 +4,24 @@ * @author yslg * @copyright xyzh * @since 2025-10-15 + * + * ⚠️ 注意:此API已废弃! + * + * 从2025-10-27起,资源分类功能已迁移到标签系统(Tag)中。 + * + * 迁移说明: + * - 原 tb_resource_category 表已废弃 + * - 改为使用 tb_tag 表的 tag_type=1 表示文章分类标签 + * - 请使用 resourceTagApi.getTagsByType(1) 替代本 API 的方法 + * + * API 迁移对照: + * - getCategoryList() → resourceTagApi.getTagsByType(1) + * - getCategoryById(id) → resourceTagApi.getTagById(id) + * - createCategory(category) → resourceTagApi.createTag({...category, tagType: 1}) + * - updateCategory(category) → resourceTagApi.updateTag(category) + * - deleteCategory(id) → resourceTagApi.deleteTag(id) + * + * @deprecated 请使用 resourceTagApi 代替 */ import { api } from '@/apis'; @@ -11,6 +29,7 @@ import type { ResultDomain, ResourceCategory } from '@/types'; /** * 资源分类API服务 + * @deprecated 已废弃,请使用 resourceTagApi.getTagsByType(1) 获取文章分类标签 */ export const resourceCategoryApi = { /** @@ -24,11 +43,11 @@ export const resourceCategoryApi = { /** * 根据ID获取分类详情 - * @param categoryID 分类ID + * @param tagID 分类ID * @returns Promise> */ - async getCategoryById(categoryID: string): Promise> { - const response = await api.get(`/news/categorys/category/${categoryID}`); + async getCategoryById(tagID: string): Promise> { + const response = await api.get(`/news/categorys/category/${tagID}`); return response.data; }, @@ -54,22 +73,22 @@ export const resourceCategoryApi = { /** * 删除分类 - * @param categoryID 分类ID + * @param tagID 分类ID * @returns Promise> */ - async deleteCategory(categoryID: string): Promise> { - const response = await api.delete(`/news/categorys/category/${categoryID}`); + async deleteCategory(tagID: string): Promise> { + const response = await api.delete(`/news/categorys/category/${tagID}`); return response.data; }, /** * 更新分类状态 - * @param categoryID 分类ID + * @param tagID 分类ID * @param status 状态值 * @returns Promise> */ - async updateCategoryStatus(categoryID: string, status: number): Promise> { - const response = await api.put(`/news/categorys/category/${categoryID}/status`, null, { + async updateCategoryStatus(tagID: string, status: number): Promise> { + const response = await api.put(`/news/categorys/category/${tagID}/status`, null, { params: { status } }); return response.data; diff --git a/schoolNewsWeb/src/apis/resource/resourceTag.ts b/schoolNewsWeb/src/apis/resource/resourceTag.ts index f22ac5f..828dbd1 100644 --- a/schoolNewsWeb/src/apis/resource/resourceTag.ts +++ b/schoolNewsWeb/src/apis/resource/resourceTag.ts @@ -16,7 +16,7 @@ export const resourceTagApi = { // ==================== 标签基础操作 ==================== /** - * 获取标签列表 + * 获取标签列表(获取所有标签) * @returns Promise> */ async getTagList(): Promise> { @@ -24,6 +24,16 @@ export const resourceTagApi = { return response.data; }, + /** + * 根据标签类型获取标签列表 + * @param tagType 标签类型(1-文章分类标签 2-课程分类标签 3-学习任务分类标签) + * @returns Promise> + */ + async getTagsByType(tagType: number): Promise> { + const response = await api.get(`/news/tags/type/${tagType}`); + return response.data; + }, + /** * 根据ID获取标签详情 * @param tagID 标签ID diff --git a/schoolNewsWeb/src/components/base/MenuItem.vue b/schoolNewsWeb/src/components/base/MenuItem.vue index bf92904..32a301e 100644 --- a/schoolNewsWeb/src/components/base/MenuItem.vue +++ b/schoolNewsWeb/src/components/base/MenuItem.vue @@ -28,7 +28,7 @@ v-if="expanded && !collapsed" > (); -// 状态 -const expanded = ref(false); +// 状态 - 顶层菜单默认展开 +const expanded = ref(props.level === 0); // Composition API const route = useRoute(); // 计算属性 const hasChildren = computed(() => { - return props.menu.children && props.menu.children.length > 0; + // 只显示SIDEBAR类型的子菜单,过滤掉PAGE类型 + return props.menu.children && + props.menu.children.filter((child: SysMenu) => child.type === MenuType.SIDEBAR).length > 0; +}); + +// 过滤后的子菜单(只显示SIDEBAR类型) +const filteredChildren = computed(() => { + if (!props.menu.children) return []; + return props.menu.children.filter((child: SysMenu) => child.type === MenuType.SIDEBAR); }); const isActive = computed(() => { @@ -109,7 +117,8 @@ function toggleExpanded() { } function handleClick() { - if (props.menu.type === MenuType.NAVIGATION && props.menu.url) { + // 支持NAVIGATION和SIDEBAR类型的菜单点击 + if (props.menu.url && (props.menu.type === MenuType.NAVIGATION || props.menu.type === MenuType.SIDEBAR)) { emit('menu-click', props.menu); } } diff --git a/schoolNewsWeb/src/layouts/NavigationLayout.vue b/schoolNewsWeb/src/layouts/NavigationLayout.vue index c4eaac9..a20c2b5 100644 --- a/schoolNewsWeb/src/layouts/NavigationLayout.vue +++ b/schoolNewsWeb/src/layouts/NavigationLayout.vue @@ -9,8 +9,7 @@ - - +
- + - - + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + + + + + + + + + 启用 + 禁用 + + +
+ + +
@@ -71,11 +299,21 @@ function deleteTag(row: any) { align-items: center; } +.color-display { + display: flex; + align-items: center; + gap: 8px; +} + .color-preview { width: 40px; height: 24px; border-radius: 4px; border: 1px solid #e0e0e0; } - +.color-picker-wrapper { + display: flex; + align-items: center; +} + diff --git a/schoolNewsWeb/src/views/admin/manage/resource/ArticleManagementView.vue b/schoolNewsWeb/src/views/admin/manage/resource/ArticleManagementView.vue index e479ce7..21172b7 100644 --- a/schoolNewsWeb/src/views/admin/manage/resource/ArticleManagementView.vue +++ b/schoolNewsWeb/src/views/admin/manage/resource/ArticleManagementView.vue @@ -68,8 +68,8 @@ import { ref, onMounted } from 'vue'; import { ElButton, ElInput, ElTable, ElTableColumn, ElTag, ElPagination, ElMessage } from 'element-plus'; import { useRouter } from 'vue-router'; -import { resourceApi, resourceCategoryApi } from '@/apis/resource' -import type { PageParam, ResourceSearchParams, Resource, ResourceCategory } from '@/types'; +import { resourceApi, resourceTagApi } from '@/apis/resource' +import type { PageParam, ResourceSearchParams, Resource, Tag } from '@/types'; import { ArticleShowView } from '@/views/article'; import { ArticleStatus } from '@/types/enums'; @@ -86,7 +86,7 @@ const total = ref(0); const articles = ref([]); const showViewDialog = ref(false); const currentArticle = ref(null); -const categoryList = ref([]); +const categoryList = ref([]); // 改为使用Tag类型(tagType=1表示文章分类) onMounted(() => { loadArticles(); @@ -95,7 +95,8 @@ onMounted(() => { async function loadCategories() { try { - const res = await resourceCategoryApi.getCategoryList(); + // 使用新的标签API获取文章分类标签(tagType=1) + const res = await resourceTagApi.getTagsByType(1); // 1 = 文章分类标签 if (res.success && res.dataList) { categoryList.value = res.dataList; } diff --git a/schoolNewsWeb/src/views/article/ArticleAddView.vue b/schoolNewsWeb/src/views/article/ArticleAddView.vue index eb697ba..556fc1d 100644 --- a/schoolNewsWeb/src/views/article/ArticleAddView.vue +++ b/schoolNewsWeb/src/views/article/ArticleAddView.vue @@ -15,25 +15,13 @@ - - + + - - - - - - - @@ -127,8 +115,8 @@ import { ArrowLeft } from '@element-plus/icons-vue'; import { RichTextComponent } from '@/components/text'; import { FileUpload } from '@/components/file'; import { ArticleShowView } from './index'; -import { resourceCategoryApi, resourceTagApi, resourceApi } from '@/apis/resource'; -import { ResourceVO, ResourceCategory, Tag } from '@/types/resource'; +import { resourceTagApi, resourceApi } from '@/apis/resource'; +import { ResourceVO, Tag, TagType } from '@/types/resource'; const router = useRouter(); const route = useRoute(); @@ -143,7 +131,7 @@ const previewVisible = ref(false); const isEdit = ref(false); // 数据状态 -const categoryList = ref([]); +const categoryList = ref([]); // 改为使用Tag类型(tagType=1表示文章分类) const tagList = ref([]); const categoryLoading = ref(false); const tagLoading = ref(false); @@ -152,7 +140,6 @@ const tagLoading = ref(false); const articleForm = ref({ resource: { }, - category: {}, tags: [], }); @@ -162,7 +149,7 @@ const rules = { { required: true, message: '请输入文章标题', trigger: 'blur' }, { min: 5, max: 100, message: '标题长度在 5 到 100 个字符', trigger: 'blur' } ], - 'resource.categoryID': [ + 'resource.tagID': [ { required: true, message: '请选择文章分类', trigger: 'change' } ], 'resource.content': [ @@ -171,11 +158,12 @@ const rules = { }; -// 加载分类列表 +// 加载分类列表(使用标签API,tagType=1表示文章分类标签) async function loadCategoryList() { try { categoryLoading.value = true; - const result = await resourceCategoryApi.getCategoryList(); + // 使用新的标签API获取文章分类标签(tagType=1) + const result = await resourceTagApi.getTagsByType(TagType.ARTICLE_CATEGORY); if (result.success) { // 数组数据从 dataList 获取 categoryList.value = result.dataList || []; diff --git a/schoolNewsWeb/src/views/login/Login.vue b/schoolNewsWeb/src/views/login/Login.vue index 5a39e34..10f9bb7 100644 --- a/schoolNewsWeb/src/views/login/Login.vue +++ b/schoolNewsWeb/src/views/login/Login.vue @@ -24,7 +24,7 @@

红色思政学习平台

- + @@ -38,7 +38,7 @@ @@ -76,7 +76,7 @@ 登录

- 登录即为同意《红色思政智能体平台》 + 登录即为同意《红色思政智能体平台》

diff --git a/schoolNewsWeb/src/views/resource-center/ResourceCenterView.vue b/schoolNewsWeb/src/views/resource-center/ResourceCenterView.vue index 7a47f4d..70a3065 100644 --- a/schoolNewsWeb/src/views/resource-center/ResourceCenterView.vue +++ b/schoolNewsWeb/src/views/resource-center/ResourceCenterView.vue @@ -11,13 +11,13 @@
([]); -function handleCategoryChange(category: ResourceCategory) { - currentCategoryId.value = category.categoryID || ''; +function handleCategoryChange(category: Tag) { + currentCategoryId.value = category.tagID || category.id || ''; currentCategoryName.value = category.name || ''; searchKeyword.value = ''; showArticle.value = false; diff --git a/schoolNewsWeb/src/views/resource-center/components/ResourceArticle.vue b/schoolNewsWeb/src/views/resource-center/components/ResourceArticle.vue index f719bdf..d583c5a 100644 --- a/schoolNewsWeb/src/views/resource-center/components/ResourceArticle.vue +++ b/schoolNewsWeb/src/views/resource-center/components/ResourceArticle.vue @@ -33,7 +33,7 @@ import { CollectionType, type UserCollection } from '@/types'; interface Props { resourceId?: string; - categoryId?: string; + tagID?: string; resourceList?: Resource[]; } const props = defineProps(); diff --git a/schoolNewsWeb/src/views/resource-center/components/ResourceList.vue b/schoolNewsWeb/src/views/resource-center/components/ResourceList.vue index 83f29bc..f40ff8d 100644 --- a/schoolNewsWeb/src/views/resource-center/components/ResourceList.vue +++ b/schoolNewsWeb/src/views/resource-center/components/ResourceList.vue @@ -48,7 +48,7 @@ import type { PageParam } from '@/types'; import defaultArticleImg from '@/assets/imgs/article-default.png'; interface Props { - categoryId?: string; + tagID?: string; searchKeyword?: string; } @@ -70,7 +70,7 @@ onMounted(() => { loadResources(); }); -watch(() => [props.categoryId, props.searchKeyword], () => { +watch(() => [props.tagID, props.searchKeyword], () => { currentPage.value = 1; loadResources(); }, { deep: true }); @@ -82,14 +82,14 @@ async function loadResources() { try { const filter: ResourceSearchParams = { - categoryID: props.categoryId, + tagID: props.tagID, keyword: props.searchKeyword, // status: 1 // 只加载已发布的 }; const pageParam: PageParam = { - page: currentPage.value, - size: pageSize + pageNumber: currentPage.value, + pageSize: pageSize }; const res = await resourceApi.getResourcePage(pageParam, filter); diff --git a/schoolNewsWeb/src/views/resource-center/components/ResourceSideBar.vue b/schoolNewsWeb/src/views/resource-center/components/ResourceSideBar.vue index e534f0b..f91352e 100644 --- a/schoolNewsWeb/src/views/resource-center/components/ResourceSideBar.vue +++ b/schoolNewsWeb/src/views/resource-center/components/ResourceSideBar.vue @@ -3,13 +3,13 @@
@@ -17,22 +17,22 @@