serv\web-侧边栏 标签统一

This commit is contained in:
2025-10-27 16:21:00 +08:00
parent e50de4a277
commit 5fa4e1cd42
47 changed files with 1933 additions and 1307 deletions

View File

@@ -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<TbTag> tags;
}
```
**修改后:**
```java
public class ResourceVO {
private TbResource resource;
// ✅ 资源标签列表(包含文章分类标签 tag_type=1
private List<TbTag> tags;
}
```
2. **ResourceCenterController.java**
- 修改 import 语句,移除 `TbResourceCategory`,添加 `TbTag`
- 修改返回类型:`ResultDomain<TbResourceCategory>``ResultDomain<TbTag>`
- 更新 TODO 注释,说明使用 `TagService.getTagsByType(1)`
**关键修改:**
```java
// 修改前
import org.xyzh.common.dto.resource.TbResourceCategory;
public ResultDomain<TbResourceCategory> getSpecialCategories() { ... }
// 修改后
import org.xyzh.common.dto.resource.TbTag;
public ResultDomain<TbTag> 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<TbResourceCategory> result = categoryService.getAllCategories();
```
**修改后:**
```java
// 使用 TagService
TagService tagService;
ResultDomain<TbTag> 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个文件
- ✅ 数据结构更统一
- ✅ 功能更灵活,易于扩展
- ✅ 维护成本降低
移除操作已全部完成!🎉

View File

@@ -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<TbTag> selectByType(@Param("type") Integer type);
int countByName(@Param("name") String name, @Param("excludeId") String excludeId);
// 新方法
List<TbTag> 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
<!-- 基础结果映射 -->
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.resource.TbTag">
...
<result column="tag_type" property="tagType" jdbcType="INTEGER"/>
...
</resultMap>
<!-- 基础字段 -->
<sql id="Base_Column_List">
id, tag_id, name, color, description, tag_type, creator, updater, create_time,
update_time, delete_time, deleted
</sql>
```
### 5. Service接口修改
**文件:** `api\api-news\src\main\java\org\xyzh\api\news\tag\TagService.java`
**新增方法:**
```java
/**
* @description 根据标签类型获取标签列表
* @param tagType 标签类型1-文章分类标签 2-课程分类标签 3-学习任务分类标签)
* @return ResultDomain<TbTag> 标签列表
*/
ResultDomain<TbTag> 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<TbTag> getTagsByType(Integer tagType) {
ResultDomain<TbTag> resultDomain = new ResultDomain<>();
try {
if (tagType == null) {
resultDomain.fail("标签类型不能为空");
return resultDomain;
}
// 验证标签类型是否有效1-文章分类标签 2-课程分类标签 3-学习任务分类标签)
if (tagType < 1 || tagType > 3) {
resultDomain.fail("无效的标签类型");
return resultDomain;
}
List<TbTag> 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<TbTag> 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)` |
改造完成后,系统将具备更清晰的业务边界、更简洁的代码结构和更灵活的扩展能力。

View File

@@ -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 '创建者',

View File

@@ -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

View File

@@ -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

View File

@@ -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<TbResourceCategory> 分类列表
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> getAllCategories();
/**
* @description 获取分类树形结构
* @return ResultDomain<TbResourceCategory> 分类树
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> getCategoryTree();
/**
* @description 根据ID获取分类详情
* @param categoryID 分类ID
* @return ResultDomain<TbResourceCategory> 分类详情
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> getCategoryById(String categoryID);
/**
* @description 根据父ID获取子分类
* @param parentID 父分类ID
* @return ResultDomain<TbResourceCategory> 子分类列表
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> getCategoriesByParent(String parentID);
/**
* @description 创建分类
* @param category 分类信息
* @return ResultDomain<TbResourceCategory> 创建结果
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> createCategory(TbResourceCategory category);
/**
* @description 更新分类
* @param category 分类信息
* @return ResultDomain<TbResourceCategory> 更新结果
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> updateCategory(TbResourceCategory category);
/**
* @description 删除分类
* @param categoryID 分类ID
* @return ResultDomain<Boolean> 删除结果
* @author yslg
* @since 2025-10-15
*/
ResultDomain<Boolean> deleteCategory(String categoryID);
/**
* @description 更新分类排序
* @param categoryID 分类ID
* @param orderNum 排序号
* @return ResultDomain<TbResourceCategory> 更新结果
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResourceCategory> updateCategoryOrder(String categoryID, Integer orderNum);
/**
* @description 检查分类是否有子分类
* @param categoryID 分类ID
* @return ResultDomain<Boolean> 是否有子分类
* @author yslg
* @since 2025-10-15
*/
ResultDomain<Boolean> hasChildCategories(String categoryID);
/**
* @description 检查分类下是否有资源
* @param categoryID 分类ID
* @return ResultDomain<Boolean> 是否有资源
* @author yslg
* @since 2025-10-15
*/
ResultDomain<Boolean> hasResources(String categoryID);
}

View File

@@ -167,11 +167,11 @@ public interface ResourceService {
/**
* @description 搜索资源
* @param keyword 关键词
* @param categoryID 分类ID可选
* @param tagID 分类ID可选
* @param status 状态(可选)
* @return ResultDomain<TbResource> 搜索结果
* @author yslg
* @since 2025-10-15
*/
ResultDomain<TbResource> searchResources(String keyword, String categoryID, Integer status);
ResultDomain<TbResource> searchResources(String keyword, String tagID, Integer status);
}

View File

@@ -68,6 +68,15 @@ public interface TagService {
*/
ResultDomain<TbTag> searchTagsByName(String name);
/**
* @description 根据标签类型获取标签列表
* @param tagType 标签类型1-文章分类标签 2-课程分类标签 3-学习任务分类标签)
* @return ResultDomain<TbTag> 标签列表
* @author yslg
* @since 2025-10-27
*/
ResultDomain<TbTag> getTagsByType(Integer tagType);
// ----------------资源标签关联相关--------------------------------
/**

View File

@@ -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() {

View File

@@ -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 +

View File

@@ -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() +
'}';
}
}

View File

@@ -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() +
'}';
}

View File

@@ -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<TbTag> 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<TbTag> getTags() {
return tags;
}

View File

@@ -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<TbResourceCategory> getCategoryList() {
return resourceCategoryService.getAllCategories();
}
/**
* 根据ID获取分类详情
*/
@GetMapping("/category/{categoryID}")
public ResultDomain<TbResourceCategory> getCategoryById(@PathVariable String categoryID) {
return resourceCategoryService.getCategoryById(categoryID);
}
/**
* 创建分类
*/
@PostMapping("/category")
public ResultDomain<TbResourceCategory> createCategory(@RequestBody TbResourceCategory category) {
return resourceCategoryService.createCategory(category);
}
/**
* 更新分类
*/
@PutMapping("/category")
public ResultDomain<TbResourceCategory> updateCategory(@RequestBody TbResourceCategory category) {
return resourceCategoryService.updateCategory(category);
}
/**
* 删除分类
*/
@DeleteMapping("/category/{categoryID}")
public ResultDomain<Boolean> deleteCategory(@PathVariable String categoryID) {
return resourceCategoryService.deleteCategory(categoryID);
}
/**
* 更新分类状态
*/
@PutMapping("/category/{categoryID}/status")
public ResultDomain<TbResourceCategory> updateCategoryStatus(@PathVariable String categoryID, @RequestParam Integer status) {
return null;
// return resourceCategoryService.updateCategoryStatus(categoryID, status);
}
/**
* 获取分类树
*/
@GetMapping("/tree")
public ResultDomain<TbResourceCategory> getCategoryTree() {
return resourceCategoryService.getCategoryTree();
}
/**
* 获取子分类
*/
@GetMapping("/category/{parentID}/children")
public ResultDomain<TbResourceCategory> getChildCategories(@PathVariable String parentID) {
return resourceCategoryService.getCategoriesByParent(parentID);
}
}

View File

@@ -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<TbResourceCategory> getSpecialCategories() {
// TODO: 实现获取专项分栏包含党史学习、领导讲话、政策解读、红色经典、专题报告、思政案例6个分栏
public ResultDomain<TbTag> 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<TbResource> 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<TbResource> 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<TbResourceCategory> getAllCategories() {
// TODO: 实现获取所有资源分类
public ResultDomain<TbTag> getAllCategories() {
// TODO: 实现获取所有资源分类,使用 TagService.getTagsByType(1) 获取文章分类标签
return null;
}

View File

@@ -186,8 +186,8 @@ public class ResourceController {
@GetMapping("/search")
public ResultDomain<TbResource> 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);
}
}

View File

@@ -38,7 +38,7 @@ public class TagController {
* 根据ID获取标签详情
*/
@GetMapping("/tag/{tagID}")
public ResultDomain<TbTag> getTagById(@PathVariable String tagID) {
public ResultDomain<TbTag> getTagById(@PathVariable("tagID") String tagID) {
return tagService.getTagById(tagID);
}
@@ -62,7 +62,7 @@ public class TagController {
* 删除标签
*/
@DeleteMapping("/tag/{tagID}")
public ResultDomain<Boolean> deleteTag(@PathVariable String tagID) {
public ResultDomain<Boolean> deleteTag(@PathVariable("tagID") String tagID) {
return tagService.deleteTag(tagID);
}
@@ -70,17 +70,26 @@ public class TagController {
* 搜索标签
*/
@GetMapping("/search")
public ResultDomain<TbTag> searchTags(@RequestParam String keyword) {
public ResultDomain<TbTag> searchTags(@RequestParam("keyword") String keyword) {
return tagService.searchTagsByName(keyword);
}
/**
* 根据标签类型获取标签列表
* @param tagType 标签类型1-文章分类标签 2-课程分类标签 3-学习任务分类标签)
*/
@GetMapping("/type/{tagType}")
public ResultDomain<TbTag> getTagsByType(@PathVariable("tagType") Integer tagType) {
return tagService.getTagsByType(tagType);
}
// ----------------资源标签关联相关--------------------------------
/**
* 获取资源的标签列表
*/
@GetMapping("/resource/{resourceID}")
public ResultDomain<TbTag> getResourceTags(@PathVariable String resourceID) {
public ResultDomain<TbTag> getResourceTags(@PathVariable("resourceID") String resourceID) {
return tagService.getResourceTags(resourceID);
}
@@ -89,8 +98,8 @@ public class TagController {
*/
@PostMapping("/resource/{resourceID}/tag/{tagID}")
public ResultDomain<TbResourceTag> 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<Boolean> 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<Boolean> clearResourceTags(@PathVariable String resourceID) {
public ResultDomain<Boolean> clearResourceTags(@PathVariable("resourceID") String resourceID) {
return tagService.clearResourceTags(resourceID);
}
@@ -126,7 +135,7 @@ public class TagController {
* 根据标签获取资源列表
*/
@GetMapping("/tag/{tagID}/resources")
public ResultDomain<String> getResourcesByTag(@PathVariable String tagID) {
public ResultDomain<String> getResourcesByTag(@PathVariable("tagID") String tagID) {
return tagService.getResourcesByTag(tagID);
}
}

View File

@@ -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<TbResourceCategory> {
/**
* @description 查询资源分类列表
* @param filter 过滤条件
* @return List<TbResourceCategory> 资源分类列表
* @author yslg
* @since 2025-10-15
*/
List<TbResourceCategory> 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<TbResourceCategory> 子分类列表
* @author yslg
* @since 2025-10-15
*/
List<TbResourceCategory> selectByParentId(@Param("parentId") String parentId);
/**
* @description 根据状态查询分类列表
* @param status 状态
* @return List<TbResourceCategory> 分类列表
* @author yslg
* @since 2025-10-15
*/
List<TbResourceCategory> selectByStatus(@Param("status") Integer status);
/**
* @description 查询分类树结构
* @return List<TbResourceCategory> 分类树
* @author yslg
* @since 2025-10-15
*/
List<TbResourceCategory> 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<TbResourceCategory> resourceCategoryList);
/**
* @description 批量删除资源分类
* @param ids 分类ID列表
* @return int 影响行数
* @author yslg
* @since 2025-10-15
*/
int batchDeleteResourceCategories(@Param("ids") List<String> ids);
/**
* @description 分页查询资源分类
* @param filter 过滤条件
* @param pageParam 分页参数
* @return List<TbResourceCategory> 资源分类列表
* @author yslg
* @since 2025-10-15
*/
List<TbResourceCategory> 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);
}

View File

@@ -37,13 +37,13 @@ public interface ResourceMapper extends BaseMapper<TbResource> {
TbResource selectByResourceId(@Param("resourceId") String resourceId);
/**
* @description 根据分类ID查询资源列表
* @param categoryId 分类ID
* @description 根据标签ID查询资源列表
* @param tagId 标签ID文章分类标签tagType=1
* @return List<TbResource> 资源列表
* @author yslg
* @since 2025-10-15
*/
List<TbResource> selectByCategoryId(@Param("categoryId") String categoryId);
List<TbResource> selectByTagId(@Param("tagId") String tagId);
/**
* @description 根据状态查询资源列表

View File

@@ -55,13 +55,13 @@ public interface TagMapper extends BaseMapper<TbTag> {
List<TbTag> selectByStatus(@Param("status") Integer status);
/**
* @description 根据类型查询标签列表
* @param type 类型
* @description 根据标签类型查询标签列表
* @param tagType 标签类型1-文章分类标签 2-课程分类标签 3-学习任务分类标签)
* @return List<TbTag> 标签列表
* @author yslg
* @since 2025-10-15
* @since 2025-10-27
*/
List<TbTag> selectByType(@Param("type") Integer type);
List<TbTag> selectByTagType(@Param("tagType") Integer tagType);
/**
* @description 查询热门标签列表
@@ -73,14 +73,15 @@ public interface TagMapper extends BaseMapper<TbTag> {
List<TbTag> 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 插入标签

View File

@@ -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 {
}

View File

@@ -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<TbResourceCategory> createCategory(TbResourceCategory category) {
ResultDomain<TbResourceCategory> 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<TbResourceCategory> updateCategory(TbResourceCategory category) {
ResultDomain<TbResourceCategory> 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<Boolean> deleteCategory(String categoryID) {
ResultDomain<Boolean> 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<Boolean> hasChildResult = hasChildCategories(categoryID);
if (hasChildResult.isSuccess() && Boolean.TRUE.equals(hasChildResult.getData())) {
resultDomain.fail("该分类下存在子分类,无法删除");
return resultDomain;
}
// 检查是否有关联资源
ResultDomain<Boolean> 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<TbResourceCategory> getCategoryById(String categoryID) {
ResultDomain<TbResourceCategory> 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<TbResourceCategory> getAllCategories() {
ResultDomain<TbResourceCategory> resultDomain = new ResultDomain<>();
try {
List<TbResourceCategory> 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<TbResourceCategory> getCategoriesByParent(String parentID) {
ResultDomain<TbResourceCategory> resultDomain = new ResultDomain<>();
try {
if (!StringUtils.hasText(parentID)) {
resultDomain.fail("父分类ID不能为空");
return resultDomain;
}
List<TbResourceCategory> 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<TbResourceCategory> getCategoryTree() {
ResultDomain<TbResourceCategory> resultDomain = new ResultDomain<>();
try {
// 查询所有分类
List<TbResourceCategory> allCategories = resourceCategoryMapper.selectCategoryTree();
// 构建树形结构
List<TbResourceCategory> 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<Boolean> hasChildCategories(String categoryID) {
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
try {
if (!StringUtils.hasText(categoryID)) {
resultDomain.fail("分类ID不能为空");
return resultDomain;
}
List<TbResourceCategory> 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<Boolean> hasResources(String categoryID) {
ResultDomain<Boolean> 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<TbResourceCategory> updateCategoryOrder(String categoryID, Integer orderNum) {
ResultDomain<TbResourceCategory> 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<TbResourceCategory> buildCategoryTree(List<TbResourceCategory> allCategories, String parentID) {
List<TbResourceCategory> result = new ArrayList<>();
for (TbResourceCategory category : allCategories) {
// 找出当前父级下的子分类
if ((parentID == null && category.getParentID() == null) ||
(parentID != null && parentID.equals(category.getParentID()))) {
// 递归查找子分类如果TbResourceCategory有children字段可以在这里设置
// List<TbResourceCategory> children = buildCategoryTree(allCategories, category.getCategoryID());
// category.setChildren(children);
result.add(category);
}
}
return result;
}
}

View File

@@ -721,7 +721,7 @@ public class NCResourceServiceImpl implements ResourceService {
}
@Override
public ResultDomain<TbResource> searchResources(String keyword, String categoryID, Integer status) {
public ResultDomain<TbResource> searchResources(String keyword, String tagID, Integer status) {
ResultDomain<TbResource> resultDomain = new ResultDomain<>();
try {
// 参数验证
@@ -734,8 +734,8 @@ public class NCResourceServiceImpl implements ResourceService {
List<TbResource> 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()));
}
// 如果指定了状态,进行过滤

View File

@@ -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<TbTag> getTagsByType(Integer tagType) {
ResultDomain<TbTag> resultDomain = new ResultDomain<>();
try {
if (tagType == null) {
resultDomain.fail("标签类型不能为空");
return resultDomain;
}
// 验证标签类型是否有效1-文章分类标签 2-课程分类标签 3-学习任务分类标签)
if (tagType < 1 || tagType > 3) {
resultDomain.fail("无效的标签类型");
return resultDomain;
}
List<TbTag> tags = tagMapper.selectByTagType(tagType);
resultDomain.success("查询成功", tags);
return resultDomain;
} catch (Exception e) {
logger.error("根据类型查询标签异常: {}", e.getMessage(), e);
resultDomain.fail("根据类型查询标签失败: " + e.getMessage());
return resultDomain;
}
}
}

View File

@@ -9,7 +9,7 @@
<result column="source_url" property="sourceUrl" jdbcType="VARCHAR"/>
<result column="source_type" property="sourceType" jdbcType="VARCHAR"/>
<result column="frequency" property="frequency" jdbcType="VARCHAR"/>
<result column="category_id" property="categoryID" jdbcType="VARCHAR"/>
<result column="tag_id" property="tagID" jdbcType="VARCHAR"/>
<result column="status" property="status" jdbcType="INTEGER"/>
<result column="last_collect_time" property="lastCollectTime" jdbcType="TIMESTAMP"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
@@ -22,7 +22,7 @@
<!-- 基础字段 -->
<sql id="Base_Column_List">
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
</sql>
@@ -40,8 +40,8 @@
<if test="frequency != null and frequency != ''">
AND frequency = #{frequency}
</if>
<if test="categoryID != null and categoryID != ''">
AND category_id = #{categoryID}
<if test="tagID != null and tagID != ''">
AND tag_id = #{tagID}
</if>
<if test="status != null">
AND status = #{status}
@@ -114,11 +114,11 @@
<!-- 插入数据采集配置 -->
<insert id="insertDataCollectionConfig" parameterType="org.xyzh.common.dto.resource.TbDataCollectionConfig">
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 @@
<if test="frequency != null and frequency != ''">
frequency = #{frequency},
</if>
<if test="categoryID != null and categoryID != ''">
category_id = #{categoryID},
<if test="tagID != null and tagID != ''">
tag_id = #{tagID},
</if>
<if test="status != null">
status = #{status},
@@ -174,14 +174,14 @@
<!-- 批量插入数据采集配置 -->
<insert id="batchInsertDataCollectionConfigs" parameterType="java.util.List">
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
<foreach collection="dataCollectionConfigList" item="item" separator=",">
(
#{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}
)
</foreach>

View File

@@ -1,194 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xyzh.news.mapper.ResourceCategoryMapper">
<!-- 基础结果映射 -->
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.resource.TbResourceCategory">
<id column="id" property="id" jdbcType="VARCHAR"/>
<result column="category_id" property="categoryID" jdbcType="VARCHAR"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="parent_id" property="parentID" jdbcType="VARCHAR"/>
<result column="description" property="description" jdbcType="VARCHAR"/>
<result column="icon" property="icon" jdbcType="VARCHAR"/>
<result column="order_num" property="orderNum" jdbcType="INTEGER"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="updater" property="updater" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
<result column="delete_time" property="deleteTime" jdbcType="TIMESTAMP"/>
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
</resultMap>
<!-- 基础字段 -->
<sql id="Base_Column_List">
id, category_id, name, parent_id, description, icon, order_num,
creator, updater, create_time, update_time, delete_time, deleted
</sql>
<!-- 通用条件 -->
<sql id="Where_Clause">
<where>
deleted = 0
<if test="categoryID != null and categoryID != ''">
AND category_id = #{categoryID}
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="parentID != null and parentID != ''">
AND parent_id = #{parentID}
</if>
</where>
</sql>
<!-- selectResourceCategories -->
<select id="selectResourceCategories" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM tb_resource_category
<include refid="Where_Clause"/>
ORDER BY order_num ASC, create_time ASC
</select>
<!-- 根据分类ID查询分类信息 -->
<select id="selectByCategoryId" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_resource_category
WHERE category_id = #{categoryId} AND deleted = 0
</select>
<!-- 根据父分类ID查询子分类列表 -->
<select id="selectByParentId" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_resource_category
WHERE parent_id = #{parentId} AND deleted = 0
ORDER BY order_num ASC, create_time ASC
</select>
<!-- 根据状态查询分类列表 -->
<select id="selectByStatus" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_resource_category
WHERE deleted = 0
ORDER BY order_num ASC, create_time ASC
</select>
<!-- 查询分类树结构 -->
<select id="selectCategoryTree" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_resource_category
WHERE deleted = 0
ORDER BY order_num ASC, create_time ASC
</select>
<!-- 检查分类名称是否存在 -->
<select id="countByName" resultType="int">
SELECT COUNT(1)
FROM tb_resource_category
WHERE name = #{name} AND deleted = 0
<if test="excludeId != null and excludeId != ''">
AND id != #{excludeId}
</if>
</select>
<!-- 插入资源分类 -->
<insert id="insertResourceCategory" parameterType="org.xyzh.common.dto.resource.TbResourceCategory">
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}
)
</insert>
<!-- 更新资源分类 -->
<update id="updateResourceCategory" parameterType="org.xyzh.common.dto.resource.TbResourceCategory">
UPDATE tb_resource_category
<set>
<if test="categoryID != null and categoryID != ''">
category_id = #{categoryID},
</if>
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="parentID != null and parentID != ''">
parent_id = #{parentID},
</if>
<if test="description != null and description != ''">
description = #{description},
</if>
<if test="icon != null and icon != ''">
icon = #{icon},
</if>
<if test="orderNum != null">
order_num = #{orderNum},
</if>
<if test="updater != null and updater != ''">
updater = #{updater},
</if>
<if test="updateTime != null">
update_time = #{updateTime},
</if>
<if test="deleteTime != null">
delete_time = #{deleteTime},
</if>
<if test="deleted != null">
deleted = #{deleted},
</if>
</set>
WHERE id = #{id}
</update>
<!-- 删除资源分类 -->
<delete id="deleteResourceCategory" parameterType="org.xyzh.common.dto.resource.TbResourceCategory">
DELETE FROM tb_resource_category
WHERE id = #{id}
</delete>
<!-- 批量插入资源分类 -->
<insert id="batchInsertResourceCategories" parameterType="java.util.List">
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
<foreach collection="resourceCategoryList" item="item" separator=",">
(
#{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}
)
</foreach>
</insert>
<!-- 批量删除资源分类 -->
<delete id="batchDeleteResourceCategories">
DELETE FROM tb_resource_category
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 分页查询资源分类 -->
<select id="selectResourceCategoriesPage" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_resource_category
<include refid="Where_Clause" />
ORDER BY order_num ASC, create_time ASC
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
</select>
<!-- 统计资源分类总数 -->
<select id="countResourceCategories" resultType="long">
SELECT COUNT(1)
FROM tb_resource_category
<include refid="Where_Clause" />
</select>
</mapper>

View File

@@ -10,7 +10,7 @@
<result column="content" property="content" jdbcType="LONGVARCHAR"/>
<result column="summary" property="summary" jdbcType="VARCHAR"/>
<result column="cover_image" property="coverImage" jdbcType="VARCHAR"/>
<result column="category_id" property="categoryID" jdbcType="VARCHAR"/>
<result column="tag_id" property="tagID" jdbcType="VARCHAR"/>
<result column="author" property="author" jdbcType="VARCHAR"/>
<result column="source" property="source" jdbcType="VARCHAR"/>
<result column="source_url" property="sourceUrl" jdbcType="VARCHAR"/>
@@ -31,7 +31,7 @@
<!-- 基础字段 -->
<sql id="Base_Column_List">
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 @@
<if test="title != null and title != ''">
AND title LIKE CONCAT('%', #{title}, '%')
</if>
<if test="categoryID != null and categoryID != ''">
AND category_id = #{categoryID}
<if test="tagID != null and tagID != ''">
AND tag_id = #{tagID}
</if>
<if test="author != null and author != ''">
AND author LIKE CONCAT('%', #{author}, '%')
@@ -79,12 +79,12 @@
WHERE resource_id = #{resourceId} AND deleted = 0
</select>
<!-- 根据分类ID查询资源列表 -->
<select id="selectByCategoryId" resultMap="BaseResultMap">
<!-- 根据标签ID查询资源列表 -->
<select id="selectByTagId" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
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
</select>
@@ -97,12 +97,12 @@
ORDER BY publish_time DESC, create_time DESC
</select>
<!-- 根据类型查询资源列表 -->
<!-- 根据标签类型查询资源列表 -->
<select id="selectByType" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_resource
WHERE category_id = #{type} AND deleted = 0
WHERE tag_id = #{type} AND deleted = 0
ORDER BY publish_time DESC, create_time DESC
</select>
@@ -155,12 +155,12 @@
<!-- 插入资源 -->
<insert id="insertResource" parameterType="org.xyzh.common.dto.resource.TbResource">
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 @@
<if test="coverImage != null and coverImage != ''">
cover_image = #{coverImage},
</if>
<if test="categoryID != null and categoryID != ''">
category_id = #{categoryID},
<if test="tagID != null and tagID != ''">
tag_id = #{tagID},
</if>
<if test="author != null and author != ''">
author = #{author},
@@ -241,7 +241,7 @@
<!-- 批量插入资源 -->
<insert id="batchInsertResources" parameterType="java.util.List">
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 @@
<foreach collection="resourceList" item="item" separator=",">
(
#{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 @@
<if test="filter.title != null and filter.title != ''">
AND title LIKE CONCAT('%', #{filter.title}, '%')
</if>
<if test="filter.categoryID != null and filter.categoryID != ''">
AND category_id = #{filter.categoryID}
<if test="filter.tagID != null and filter.tagID != ''">
AND tag_id = #{filter.tagID}
</if>
<if test="filter.author != null and filter.author != ''">
AND author LIKE CONCAT('%', #{filter.author}, '%')

View File

@@ -9,6 +9,7 @@
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="color" property="color" jdbcType="VARCHAR"/>
<result column="description" property="description" jdbcType="VARCHAR"/>
<result column="tag_type" property="tagType" jdbcType="INTEGER"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="updater" property="updater" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
@@ -19,7 +20,7 @@
<!-- 基础字段 -->
<sql id="Base_Column_List">
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
</sql>
@@ -36,6 +37,9 @@
<if test="color != null and color != ''">
AND color = #{color}
</if>
<if test="tagType != null">
AND tag_type = #{tagType}
</if>
</where>
</sql>
@@ -73,12 +77,15 @@
ORDER BY create_time DESC
</select>
<!-- 根据类型查询标签列表 -->
<select id="selectByType" resultMap="BaseResultMap">
<!-- 根据标签类型查询标签列表 -->
<select id="selectByTagType" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM tb_tag
WHERE deleted = 0
<if test="tagType != null">
AND tag_type = #{tagType}
</if>
ORDER BY create_time DESC
</select>
@@ -94,11 +101,14 @@
</if>
</select>
<!-- 检查标签名称是否存在 -->
<select id="countByName" resultType="int">
<!-- 检查标签名称是否存在(同类型下) -->
<select id="countByNameAndType" resultType="int">
SELECT COUNT(1)
FROM tb_tag
WHERE name = #{name} AND deleted = 0
<if test="tagType != null">
AND tag_type = #{tagType}
</if>
<if test="excludeId != null and excludeId != ''">
AND id != #{excludeId}
</if>
@@ -107,10 +117,10 @@
<!-- 插入标签 -->
<insert id="insertTag" parameterType="org.xyzh.common.dto.resource.TbTag">
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}
)
</insert>
@@ -131,6 +141,9 @@
<if test="description != null and description != ''">
description = #{description},
</if>
<if test="tagType != null">
tag_type = #{tagType},
</if>
<if test="updater != null and updater != ''">
updater = #{updater},
</if>
@@ -156,13 +169,13 @@
<!-- 批量插入标签 -->
<insert id="batchInsertTags" parameterType="java.util.List">
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
<foreach collection="tagList" item="item" separator=",">
(
#{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}
)
</foreach>