11 changed files with 597 additions and 2822 deletions
File diff suppressed because it is too large
@ -1,574 +0,0 @@ |
|||||
# 学员端知识库模块详细开发任务 |
|
||||
|
|
||||
## 📋 **功能需求分析** |
|
||||
|
|
||||
基于 `pages-student/knowledge/index.vue` 页面分析,知识库模块需要实现以下功能: |
|
||||
|
|
||||
### **前端页面功能** |
|
||||
1. **知识文章列表展示**:支持分页加载 |
|
||||
2. **分类筛选**:按知识库类型筛选内容 |
|
||||
3. **推荐文章**:首页推荐优质内容 |
|
||||
4. **搜索功能**:关键词搜索文章 |
|
||||
5. **收藏功能**:收藏/取消收藏文章 |
|
||||
6. **阅读状态**:标记文章已读 |
|
||||
7. **统计信息**:总文章数、收藏数统计 |
|
||||
8. **文章详情**:跳转到详情页面查看 |
|
||||
|
|
||||
### **数据表结构** |
|
||||
- **主表**:`school_lesson_course_teaching` - 知识库内容表 |
|
||||
- **权限控制**:通过 `student_ids` 字段(逗号分割)控制访问权限 |
|
||||
- **分类字段**:`table_type` 字段区分不同类型的知识内容 |
|
||||
|
|
||||
### **实际数据库字段** |
|
||||
基于 `school_lesson_course_teaching` 表的实际结构: |
|
||||
- `id` - 主键ID |
|
||||
- `title` - 标题 |
|
||||
- `image` - 图片/封面 |
|
||||
- `type` - 类型 |
|
||||
- `url` - 链接地址 |
|
||||
- `content` - 内容(富文本) |
|
||||
- `status` - 状态 |
|
||||
- `create_time` - 创建时间 |
|
||||
- `update_time` - 更新时间 |
|
||||
- `delete_time` - 删除时间(软删除) |
|
||||
- `table_type` - 分类类型(1-29枚举值) |
|
||||
- `user_permission` - 用户权限 |
|
||||
- `exam_papers_id` - 试卷ID |
|
||||
- `student_ids` - 学员权限控制(逗号分割) |
|
||||
|
|
||||
### **table_type 枚举值详细说明** |
|
||||
根据数据库字段注释,`table_type` 包含以下29种类型: |
|
||||
|
|
||||
**教案库类型(1-8)**: |
|
||||
- `1`:课程教学大纲 |
|
||||
- `2`:跳绳教案库 |
|
||||
- `3`:增高教案库 |
|
||||
- `4`:篮球教案库 |
|
||||
- `5`:强化教案库 |
|
||||
- `6`:空中忍者教案库 |
|
||||
- `7`:少儿安防教案库 |
|
||||
- `8`:体能教案库 |
|
||||
|
|
||||
**动作库类型(9-12, 17-22)**: |
|
||||
- `9`:热身动作库 |
|
||||
- `10`:体能动作库 |
|
||||
- `11`:趣味游戏库 |
|
||||
- `12`:放松动作库 |
|
||||
- `17`:空中忍者动作 |
|
||||
- `18`:篮球动作 |
|
||||
- `19`:跳绳动作 |
|
||||
- `20`:跑酷动作 |
|
||||
- `21`:安防动作 |
|
||||
- `22`:标准化动作 |
|
||||
|
|
||||
**训练内容类型(13-16)**: |
|
||||
- `13`:训练内容 |
|
||||
- `14`:训练视频 |
|
||||
- `15`:课后作业 |
|
||||
- `16`:优秀一堂课 |
|
||||
|
|
||||
**体测相关类型(23-26)**: |
|
||||
- `23`:3-6岁体测 |
|
||||
- `24`:7+体测 |
|
||||
- `25`:3-6岁体测讲解—解读 |
|
||||
- `26`:7+岁体测讲解—解读 |
|
||||
|
|
||||
**游戏互动类型(27-29)**: |
|
||||
- `27`:互动游戏 |
|
||||
- `28`:套圈游戏 |
|
||||
- `29`:鼓励方式 |
|
||||
|
|
||||
## 🔧 **后端开发任务细化** |
|
||||
|
|
||||
### **任务1:知识库基础接口开发** |
|
||||
**负责人**:后端开发者 |
|
||||
**工期**:1天 |
|
||||
**优先级**:高 |
|
||||
|
|
||||
#### **1.1 获取知识文章列表接口** |
|
||||
```php |
|
||||
GET /api/student/knowledge/list/{student_id} |
|
||||
``` |
|
||||
|
|
||||
**请求参数**: |
|
||||
- `student_id` (必填): 学员ID |
|
||||
- `category` (可选): 分类筛选,对应 table_type 字段 |
|
||||
- `page` (可选): 页码,默认1 |
|
||||
- `limit` (可选): 每页数量,默认10 |
|
||||
- `keyword` (可选): 搜索关键词 |
|
||||
|
|
||||
**响应格式**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"msg": "获取成功", |
|
||||
"data": { |
|
||||
"list": [ |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"title": "少儿体适能训练的核心要素", |
|
||||
"image": "https://example.com/cover.jpg", |
|
||||
"content": "富文本内容", |
|
||||
"table_type": "1", |
|
||||
"category_name": "课程教学大纲", |
|
||||
"type": 1, |
|
||||
"url": "", |
|
||||
"status": 1, |
|
||||
"create_time": 1705294800, |
|
||||
"update_time": 1705294800, |
|
||||
"user_permission": "1,2,3", |
|
||||
"is_read": false, |
|
||||
"is_favorite": false |
|
||||
} |
|
||||
], |
|
||||
"current_page": 1, |
|
||||
"last_page": 5, |
|
||||
"total": 45, |
|
||||
"per_page": 10 |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
**核心业务逻辑**: |
|
||||
```php |
|
||||
// 1. 权限验证:检查 student_ids 字段是否包含当前学员ID |
|
||||
$where[] = ['student_ids', 'like', "%,{$student_id},%"]; |
|
||||
// 或者使用 FIND_IN_SET 函数 |
|
||||
$where[] = ['', 'exp', "FIND_IN_SET({$student_id}, student_ids)"]; |
|
||||
|
|
||||
// 2. 状态筛选:只查询启用状态的内容 |
|
||||
$where[] = ['status', '=', 1]; |
|
||||
|
|
||||
// 3. 软删除筛选:排除已删除的内容 |
|
||||
$where[] = ['delete_time', '=', 0]; |
|
||||
|
|
||||
// 4. 分类筛选 |
|
||||
if (!empty($category)) { |
|
||||
$where[] = ['table_type', '=', $category]; |
|
||||
} |
|
||||
|
|
||||
// 5. 关键词搜索(只搜索标题和内容) |
|
||||
if (!empty($keyword)) { |
|
||||
$where[] = ['title|content', 'like', "%{$keyword}%"]; |
|
||||
} |
|
||||
|
|
||||
// 6. 查询收藏状态和阅读状态(需要关联查询) |
|
||||
// 7. 分页查询 |
|
||||
// 8. 数据格式化(时间戳转换等) |
|
||||
``` |
|
||||
|
|
||||
#### **1.2 获取知识分类列表接口** |
|
||||
```php |
|
||||
GET /api/student/knowledge/categories |
|
||||
``` |
|
||||
|
|
||||
**响应格式**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"msg": "获取成功", |
|
||||
"data": [ |
|
||||
{ |
|
||||
"value": "1", |
|
||||
"text": "课程教学大纲", |
|
||||
"icon": "📖", |
|
||||
"count": 12 |
|
||||
}, |
|
||||
{ |
|
||||
"value": "2", |
|
||||
"text": "跳绳教案库", |
|
||||
"icon": "🏃", |
|
||||
"count": 8 |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
#### **1.3 获取推荐文章接口** |
|
||||
```php |
|
||||
GET /api/student/knowledge/recommend/{student_id} |
|
||||
``` |
|
||||
|
|
||||
**业务逻辑**: |
|
||||
- 返回热门文章(按阅读量排序) |
|
||||
- 或者返回最新发布的文章 |
|
||||
- 限制返回数量(如5篇) |
|
||||
|
|
||||
### **任务2:知识库交互功能开发** |
|
||||
**负责人**:后端开发者 |
|
||||
**工期**:1天 |
|
||||
**优先级**:中 |
|
||||
|
|
||||
#### **2.1 文章详情接口** |
|
||||
```php |
|
||||
GET /api/student/knowledge/detail/{id} |
|
||||
``` |
|
||||
|
|
||||
**请求参数**: |
|
||||
- `id` (必填): 文章ID |
|
||||
- `student_id` (必填): 学员ID(权限验证) |
|
||||
|
|
||||
**响应格式**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"msg": "获取成功", |
|
||||
"data": { |
|
||||
"id": 1, |
|
||||
"title": "少儿体适能训练的核心要素", |
|
||||
"image": "https://example.com/cover.jpg", |
|
||||
"content": "<p>富文本内容...</p>", |
|
||||
"table_type": "1", |
|
||||
"category_name": "课程教学大纲", |
|
||||
"type": 1, |
|
||||
"url": "", |
|
||||
"status": 1, |
|
||||
"create_time": 1705294800, |
|
||||
"update_time": 1705294800, |
|
||||
"user_permission": "1,2,3", |
|
||||
"exam_papers_id": "", |
|
||||
"is_read": true, |
|
||||
"is_favorite": false |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
#### **2.2 标记文章已读接口** |
|
||||
```php |
|
||||
POST /api/student/knowledge/mark-read |
|
||||
``` |
|
||||
|
|
||||
**请求参数**: |
|
||||
```json |
|
||||
{ |
|
||||
"article_id": 1, |
|
||||
"student_id": 31 |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
**业务逻辑**: |
|
||||
- 需要创建阅读记录表或在现有表中添加字段 |
|
||||
- 更新文章的阅读次数 |
|
||||
- 防止重复标记 |
|
||||
|
|
||||
#### **2.3 收藏/取消收藏接口** |
|
||||
```php |
|
||||
POST /api/student/knowledge/toggle-favorite |
|
||||
``` |
|
||||
|
|
||||
**请求参数**: |
|
||||
```json |
|
||||
{ |
|
||||
"article_id": 1, |
|
||||
"student_id": 31, |
|
||||
"action": "add" // add-收藏, remove-取消收藏 |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
**业务逻辑**: |
|
||||
- 需要创建收藏表 `school_student_favorites` |
|
||||
- 支持收藏和取消收藏操作 |
|
||||
- 返回当前收藏状态 |
|
||||
|
|
||||
### **任务3:统计和搜索功能开发** |
|
||||
**负责人**:后端开发者 |
|
||||
**工期**:0.5天 |
|
||||
**优先级**:低 |
|
||||
|
|
||||
#### **3.1 获取知识库统计接口** |
|
||||
```php |
|
||||
GET /api/student/knowledge/stats/{student_id} |
|
||||
``` |
|
||||
|
|
||||
**响应格式**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"msg": "获取成功", |
|
||||
"data": { |
|
||||
"total_articles": 45, |
|
||||
"favorites": 12, |
|
||||
"read_articles": 28, |
|
||||
"categories_count": { |
|
||||
"1": 12, |
|
||||
"2": 8, |
|
||||
"3": 6 |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
#### **3.2 搜索文章接口** |
|
||||
```php |
|
||||
GET /api/student/knowledge/search/{student_id} |
|
||||
``` |
|
||||
|
|
||||
**请求参数**: |
|
||||
- `keyword` (必填): 搜索关键词 |
|
||||
- `category` (可选): 分类筛选 |
|
||||
- `page` (可选): 页码 |
|
||||
|
|
||||
**搜索范围**: |
|
||||
- 文章标题(title字段) |
|
||||
- 文章内容(content字段) |
|
||||
|
|
||||
## 🗄️ **数据库设计补充** |
|
||||
|
|
||||
### **需要新增的表** |
|
||||
|
|
||||
#### **1. 学员文章阅读记录表** |
|
||||
```sql |
|
||||
CREATE TABLE `school_student_article_reads` ( |
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|
||||
`student_id` int(11) NOT NULL COMMENT '学员ID', |
|
||||
`article_id` int(11) NOT NULL COMMENT '文章ID', |
|
||||
`read_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '阅读时间', |
|
||||
`read_duration` int(11) DEFAULT 0 COMMENT '阅读时长(秒)', |
|
||||
PRIMARY KEY (`id`), |
|
||||
UNIQUE KEY `uk_student_article` (`student_id`, `article_id`), |
|
||||
KEY `idx_student_id` (`student_id`), |
|
||||
KEY `idx_article_id` (`article_id`) |
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学员文章阅读记录表'; |
|
||||
``` |
|
||||
|
|
||||
#### **2. 学员收藏表** |
|
||||
```sql |
|
||||
CREATE TABLE `school_student_favorites` ( |
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|
||||
`student_id` int(11) NOT NULL COMMENT '学员ID', |
|
||||
`target_type` varchar(50) NOT NULL COMMENT '收藏类型:article-文章', |
|
||||
`target_id` int(11) NOT NULL COMMENT '目标ID', |
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收藏时间', |
|
||||
PRIMARY KEY (`id`), |
|
||||
UNIQUE KEY `uk_student_target` (`student_id`, `target_type`, `target_id`), |
|
||||
KEY `idx_student_id` (`student_id`), |
|
||||
KEY `idx_target` (`target_type`, `target_id`) |
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学员收藏表'; |
|
||||
``` |
|
||||
|
|
||||
### **现有表字段补充** |
|
||||
|
|
||||
#### **school_lesson_course_teaching 表优化** |
|
||||
```sql |
|
||||
-- 注意:school_lesson_course_teaching 表已有完整字段结构 |
|
||||
-- 现有字段已足够支持知识库功能,无需添加额外字段 |
|
||||
-- 如果需要统计功能,通过关联查询其他表实现 |
|
||||
``` |
|
||||
|
|
||||
## 🔗 **前后端联调任务** |
|
||||
|
|
||||
### **阶段1:基础功能联调** |
|
||||
**负责人**:前端+后端 |
|
||||
**工期**:0.5天 |
|
||||
|
|
||||
#### **联调内容**: |
|
||||
1. **文章列表接口联调** |
|
||||
- 验证分页功能 |
|
||||
- 验证分类筛选 |
|
||||
- 验证权限控制 |
|
||||
- 验证数据格式 |
|
||||
|
|
||||
2. **分类列表接口联调** |
|
||||
- 验证分类数据正确性 |
|
||||
- 验证统计数量准确性 |
|
||||
|
|
||||
3. **推荐文章接口联调** |
|
||||
- 验证推荐算法 |
|
||||
- 验证数据格式 |
|
||||
|
|
||||
#### **测试用例**: |
|
||||
```javascript |
|
||||
// 1. 测试文章列表 |
|
||||
const listResponse = await apiRoute.getKnowledgeArticles({ |
|
||||
student_id: 31, |
|
||||
category: '', |
|
||||
page: 1, |
|
||||
limit: 10 |
|
||||
}); |
|
||||
|
|
||||
// 2. 测试分类筛选 |
|
||||
const categoryResponse = await apiRoute.getKnowledgeArticles({ |
|
||||
student_id: 31, |
|
||||
category: '1', // 课程教学大纲 |
|
||||
page: 1, |
|
||||
limit: 10 |
|
||||
}); |
|
||||
|
|
||||
// 3. 测试权限控制 |
|
||||
const unauthorizedResponse = await apiRoute.getKnowledgeArticles({ |
|
||||
student_id: 999, // 无权限的学员ID |
|
||||
page: 1, |
|
||||
limit: 10 |
|
||||
}); |
|
||||
``` |
|
||||
|
|
||||
### **阶段2:交互功能联调** |
|
||||
**负责人**:前端+后端 |
|
||||
**工期**:0.5天 |
|
||||
|
|
||||
#### **联调内容**: |
|
||||
1. **文章详情接口联调** |
|
||||
- 验证富文本内容渲染 |
|
||||
- 验证权限控制 |
|
||||
- 验证阅读状态 |
|
||||
|
|
||||
2. **阅读标记功能联调** |
|
||||
- 验证阅读记录创建 |
|
||||
- 验证阅读次数更新 |
|
||||
- 验证重复标记处理 |
|
||||
|
|
||||
3. **收藏功能联调** |
|
||||
- 验证收藏/取消收藏 |
|
||||
- 验证收藏状态同步 |
|
||||
- 验证收藏统计更新 |
|
||||
|
|
||||
#### **测试用例**: |
|
||||
```javascript |
|
||||
// 1. 测试文章详情 |
|
||||
const detailResponse = await apiRoute.getKnowledgeDetail({ |
|
||||
id: 1, |
|
||||
student_id: 31 |
|
||||
}); |
|
||||
|
|
||||
// 2. 测试标记已读 |
|
||||
const readResponse = await apiRoute.markArticleRead({ |
|
||||
article_id: 1, |
|
||||
student_id: 31 |
|
||||
}); |
|
||||
|
|
||||
// 3. 测试收藏功能 |
|
||||
const favoriteResponse = await apiRoute.toggleArticleFavorite({ |
|
||||
article_id: 1, |
|
||||
student_id: 31, |
|
||||
action: 'add' |
|
||||
}); |
|
||||
``` |
|
||||
|
|
||||
### **阶段3:搜索和统计功能联调** |
|
||||
**负责人**:前端+后端 |
|
||||
**工期**:0.5天 |
|
||||
|
|
||||
#### **联调内容**: |
|
||||
1. **搜索功能联调** |
|
||||
- 验证关键词搜索 |
|
||||
- 验证搜索结果准确性 |
|
||||
- 验证搜索性能 |
|
||||
|
|
||||
2. **统计功能联调** |
|
||||
- 验证文章总数统计 |
|
||||
- 验证收藏数统计 |
|
||||
- 验证分类统计 |
|
||||
|
|
||||
#### **测试用例**: |
|
||||
```javascript |
|
||||
// 1. 测试搜索功能 |
|
||||
const searchResponse = await apiRoute.searchKnowledgeArticles({ |
|
||||
student_id: 31, |
|
||||
keyword: '体适能', |
|
||||
category: '', |
|
||||
page: 1, |
|
||||
limit: 10 |
|
||||
}); |
|
||||
|
|
||||
// 2. 测试统计功能 |
|
||||
const statsResponse = await apiRoute.getKnowledgeStats({ |
|
||||
student_id: 31 |
|
||||
}); |
|
||||
``` |
|
||||
|
|
||||
## 📊 **开发进度安排** |
|
||||
|
|
||||
### **第1天:基础接口开发** |
|
||||
- 上午:文章列表接口开发 |
|
||||
- 下午:分类列表和推荐文章接口开发 |
|
||||
|
|
||||
### **第2天:交互功能开发** |
|
||||
- 上午:文章详情和阅读标记接口开发 |
|
||||
- 下午:收藏功能接口开发 |
|
||||
|
|
||||
### **第3天:搜索统计和联调** |
|
||||
- 上午:搜索和统计接口开发 |
|
||||
- 下午:前后端联调测试 |
|
||||
|
|
||||
**总工期:2.5天** |
|
||||
|
|
||||
## ✅ **验收标准** |
|
||||
|
|
||||
### **功能验收** |
|
||||
- [ ] 文章列表正确显示,支持分页 |
|
||||
- [ ] 分类筛选功能正常 |
|
||||
- [ ] 权限控制严格(只能看到有权限的文章) |
|
||||
- [ ] 搜索功能准确 |
|
||||
- [ ] 收藏功能正常 |
|
||||
- [ ] 阅读状态正确标记 |
|
||||
- [ ] 统计数据准确 |
|
||||
|
|
||||
### **性能验收** |
|
||||
- [ ] 文章列表加载时间 < 1秒 |
|
||||
- [ ] 搜索响应时间 < 2秒 |
|
||||
- [ ] 富文本内容渲染正常 |
|
||||
- [ ] 图片加载优化 |
|
||||
|
|
||||
### **安全验收** |
|
||||
- [ ] 权限控制严格 |
|
||||
- [ ] 防止SQL注入 |
|
||||
- [ ] 防止XSS攻击 |
|
||||
- [ ] 敏感数据过滤 |
|
||||
|
|
||||
### **兼容性验收** |
|
||||
- [ ] 富文本内容在小程序中正常显示 |
|
||||
- [ ] 图片在不同设备上正常显示 |
|
||||
- [ ] 分页功能在不同网络环境下正常 |
|
||||
|
|
||||
## 🔧 **技术实现要点** |
|
||||
|
|
||||
### **权限控制实现** |
|
||||
```php |
|
||||
// 使用 FIND_IN_SET 函数检查权限(推荐) |
|
||||
$where[] = ['', 'exp', "FIND_IN_SET({$student_id}, student_ids)"]; |
|
||||
|
|
||||
// 或者使用 LIKE 查询(需要确保 student_ids 格式为 ",1,2,3,") |
|
||||
$where[] = ['student_ids', 'like', "%,{$student_id},%"]; |
|
||||
|
|
||||
// 同时确保只查询启用状态的内容 |
|
||||
$where[] = ['status', '=', 1]; |
|
||||
$where[] = ['delete_time', '=', 0]; |
|
||||
``` |
|
||||
|
|
||||
### **富文本内容处理** |
|
||||
```php |
|
||||
// 过滤危险标签 |
|
||||
$content = strip_tags($content, '<p><br><strong><em><u><img><a>'); |
|
||||
|
|
||||
// 处理图片路径(如果需要) |
|
||||
$content = str_replace('src="/', 'src="' . $domain . '/', $content); |
|
||||
|
|
||||
// 处理时间戳格式化 |
|
||||
$create_time_formatted = date('Y-m-d H:i:s', $create_time); |
|
||||
$update_time_formatted = date('Y-m-d H:i:s', $update_time); |
|
||||
``` |
|
||||
|
|
||||
### **搜索优化** |
|
||||
```php |
|
||||
// 使用全文索引提高搜索性能 |
|
||||
ALTER TABLE `school_lesson_course_teaching` |
|
||||
ADD FULLTEXT KEY `ft_title_content` (`title`, `content`); |
|
||||
|
|
||||
// 全文搜索查询 |
|
||||
$where[] = ['', 'exp', "MATCH(title, content) AGAINST('{$keyword}' IN NATURAL LANGUAGE MODE)"]; |
|
||||
``` |
|
||||
|
|
||||
### **缓存策略** |
|
||||
```php |
|
||||
// 分类列表缓存(1小时) |
|
||||
$categories = Cache::remember('knowledge_categories', 3600, function() { |
|
||||
return $this->getCategoriesFromDB(); |
|
||||
}); |
|
||||
|
|
||||
// 推荐文章缓存(30分钟) |
|
||||
$recommend = Cache::remember("knowledge_recommend_{$student_id}", 1800, function() use ($student_id) { |
|
||||
return $this->getRecommendArticles($student_id); |
|
||||
}); |
|
||||
``` |
|
||||
|
|
||||
这个详细的开发任务文档涵盖了知识库模块的完整开发流程,包括后端接口开发、数据库设计、前后端联调和验收标准,可以作为开发团队的具体执行指南。 |
|
||||
Loading…
Reference in new issue