10 KiB
10 KiB
知识库模块(knowledge)
证据来源:[SRC-FEAT-01] [SRC-FEAT-02] [SRC-SQL-01] [SRC-SQL-02] [SRC-API-01] [SRC-CODE-01:module/knowledge/]
1. 模块定位
- 模块目标:管理企业的结构化知识资产,支持文档和视频两种内容类型的上传、分类管理、状态发布,并记录学员的个人学习进度。
- 解决问题:解决救援知识依赖口口相传的问题;同时为培训计划提供可引用的学习内容,并跟踪学员是否真实完成学习(防刷机制)。
2. 功能清单
[SRC-FEAT-01:模块二] [SRC-FEAT-02:3.2 知识学习]
| 功能名称 | 功能描述 | 输入 | 输出 | 依赖模块 |
|---|---|---|---|---|
| 知识分类管理 | 创建/修改/删除多级分类树,按部门隔离 | CategoryDTO(name, parent_id, department_id) | CategoryVO | system(部门) |
| 知识分类树查询 | 返回树形结构的分类目录 | department_id | List(树) | - |
| 知识内容 CRUD | 创建/修改/删除知识(文档/视频),状态为草稿时可修改 | KnowledgeDTO(title, type, file_url, category_id…) | KnowledgeVO | system |
| 文件上传 | 上传 PDF/Word/Excel/PPT/视频文件,返回文件 URL | MultipartFile | FileDTO(url, fileName, size, type) | 文件存储服务 |
| 知识发布/下架 | 变更知识状态(草稿→发布/发布→下架/下架→再发布) | knowledgeId, action | - | - |
| 知识列表查询(讲师端) | 管理端分页查询,可查所有状态,含草稿 | KnowledgeQueryDTO(category_id, status, keyword) | PageResult | - |
| 知识列表查询(学员端) | 只查 PUBLISHED 状态,携带个人学习状态 | department_id, KnowledgeQueryDTO | PageResult<KnowledgeVO + 学习状态> | auth |
| 知识在线预览 | 文档在线预览(PDF/Word等)、视频在线播放 | knowledgeId | 文件 URL / 预览链接 | 文件存储/文档预览服务 |
| 开始学习 | 创建或获取学习进度记录,记录首次学习时间 | knowledgeId, [source, planId] | - | auth |
| 更新学习进度 | 定时上报学习进度(每60秒),累加时长,判断完成 | ProgressUpdateDTO(duration, progress, videoPosition, source, planId) | - | training(若来源=TRAINING) |
| 完成学习 | 前端显式标记完成(文档) | knowledgeId | - | - |
| 查询学习进度 | 查询学员对某知识/某批知识的学习状态 | userId/knowledgeIds | List | - |
| 引用保护检查 | 检查知识是否被培训计划引用,下架前警告 | knowledgeId | Boolean + 引用计划数 | training |
3. 核心逻辑
3.1 业务规则
[SRC-FEAT-01:4.5 引用保护规则] [SRC-API-01:5.1 学习进度更新流程]
内容状态规则:
- 草稿(DRAFT=0):只有讲师和管理员可见,可自由修改
- 已发布(PUBLISHED=1):全部门学员可见,处于此状态时不可修改内容(需先下架)
- 已下架(OFFLINE=2):学员不可见,可重新上架或继续修改后再发布
学习进度完成判定规则:
- 视频类:播放进度 ≥ 90% 时,status 自动变更为 COMPLETED
- 文档类:累计学习时长 ≥ 预估阅读时间(按文件大小估算,具体算法在
calculateEstimatedTime())时,status 变更为 COMPLETED - 两种类型均支持多次学习,完成后不会重置;时长可继续累加
防刷机制(活跃检测):
- 前端 ActivityDetector 监听 mousemove/click/scroll/keypress 事件
- 60秒无活动判定为非活跃,停止本地计时器,不上报进度
- 恢复活跃后重新计时
多标签页防重:
- BroadcastChannel API 实现:同一知识在多个 Tab 打开时,检测到重复后关闭后来的 Tab [SRC-API-01:6.2]
部门数据隔离:
- 所有知识查询一律追加
WHERE department_id = [当前用户部门] - 分类也按 department_id 隔离
引用保护:
- 知识下架前,需检查
tr_plan_knowledge中是否有关联;若有,提示警告,用户确认后方可下架
3.2 校验逻辑
| 校验项 | 规则 | 失败响应 |
|---|---|---|
| 文件类型 | 文档:PDF/Word/Excel/PPT;视频:MP4等常见格式 | 400:不支持的文件格式 |
| 文件大小 | [ASSUMPTION] PRD 提及限制大文件,具体上限需配置,建议文档 ≤100MB,视频 ≤2GB | 400:文件超出大小限制 |
| 知识状态变更 | PUBLISHED 状态下不允许修改内容字段(标题/文件),只允许下架操作 | 400:已发布知识不可修改,请先下架 |
| 学习进度上报频率 | 前端每60秒上报一次,后端不做频率限制(允许补报) | - |
| 视频播放进度合理性 | video_position ≤ 视频总时长([ASSUMPTION] 后端当前未做服务端校验,PRD 明确属于风险项) |
暂无服务端拦截 |
| 分类隶属 | 知识的 category_id 必须属于同一 department_id 的分类 | 400:分类不存在或无权限 |
3.3 状态流转
stateDiagram-v2
[*] --> DRAFT : 创建知识(可新增/修改/删除)
DRAFT --> PUBLISHED : 讲师发布
PUBLISHED --> OFFLINE : 讲师下架(引用警告确认)
OFFLINE --> PUBLISHED : 讲师重新上架
OFFLINE --> DRAFT : 重新编辑后回到草稿 [ASSUMPTION]
DRAFT --> [*] : 逻辑删除
note right of PUBLISHED : 学员可见\n不可修改内容
note right of DRAFT : 仅讲师/管理员可见
note right of OFFLINE : 学员不可见\n可编辑
学习进度状态流转:
stateDiagram-v2
[*] --> NOT_STARTED : 知识发布,学员尚未打开
NOT_STARTED --> IN_PROGRESS : 调用"开始学习"接口
IN_PROGRESS --> IN_PROGRESS : 每次上报进度(时长累加)
IN_PROGRESS --> COMPLETED : 视频≥90% 或 文档时长达标
COMPLETED --> IN_PROGRESS : 再次学习(时长继续累加,状态不回退)
4. 数据结构
[SRC-SQL-01:二、知识库模块] [SRC-SQL-02]
4.1 涉及数据表
km_category
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| name | VARCHAR(100) NOT NULL | 分类名称 |
| parent_id | BIGINT DEFAULT 0 | 父分类(0=顶级) |
| department_id | BIGINT NOT NULL | 所属部门(部门隔离键) |
| sort_order | INT | 排序 |
| deleted | TINYINT | 逻辑删除 |
km_knowledge
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| title | VARCHAR(200) NOT NULL | 标题 |
| description | TEXT | 描述/摘要 |
| category_id | BIGINT | 所属分类(可空) |
| type | TINYINT NOT NULL | 0-文档 / 1-视频 |
| file_name | VARCHAR(255) | 文件名 |
| file_url | VARCHAR(500) | 文件 URL |
| file_size | BIGINT | 文件大小(字节) |
| file_type | VARCHAR(20) | 文件后缀(pdf/mp4…) |
| department_id | BIGINT NOT NULL | 所属部门(隔离键,有 idx) |
| status | TINYINT DEFAULT 0 | 0-草稿 / 1-已发布 / 2-已下架 |
| creator_id | BIGINT NOT NULL | 创建人 |
| publish_time | DATETIME | 发布时间 |
| view_count | INT | 浏览次数 |
| deleted | TINYINT | 逻辑删除 |
km_knowledge_progress(学员学习进度)[SRC-SQL-02]
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| user_id | BIGINT NOT NULL | 学员ID |
| knowledge_id | BIGINT NOT NULL | 知识ID |
| department_id | BIGINT NOT NULL | 部门(冗余,用于分区查询) |
| status | VARCHAR(20) | NOT_STARTED / IN_PROGRESS / COMPLETED |
| progress | INT | 进度百分比(0~100) |
| duration | BIGINT | 累计学习时长(秒) |
| video_position | BIGINT | 视频播放位置(秒,仅视频) |
| source | VARCHAR(20) | FREE / TRAINING |
| plan_id | BIGINT | 关联培训计划(source=TRAINING 时有值) |
| start_time | DATETIME | 首次学习时间 |
| complete_time | DATETIME | 完成时间 |
| 唯一约束 | uk_user_knowledge | (user_id, knowledge_id) 唯一 |
4.2 数据关联
km_knowledge.category_id→km_category.idkm_knowledge.department_id=km_category.department_id(同部门隔离)km_knowledge_progress.user_id→sys_user.idkm_knowledge_progress.plan_id→tr_plan.id(可空)
5. 对外接口
[SRC-API-01:4.3 知识学习接口] [SRC-CODE-01:module/knowledge/controller/]
| API 名称 | 方法 | 路径 | 权限 |
|---|---|---|---|
| 查询知识分类树 | GET | /api/knowledge/category/tree | LECTURER/ADMIN |
| 创建分类 | POST | /api/knowledge/category | LECTURER/ADMIN |
| 修改分类 | PUT | /api/knowledge/category/{id} | LECTURER/ADMIN |
| 删除分类 | DELETE | /api/knowledge/category/{id} | LECTURER/ADMIN |
| 查询知识列表(管理端) | GET | /api/knowledge | LECTURER/ADMIN |
| 创建知识 | POST | /api/knowledge | LECTURER/ADMIN |
| 修改知识 | PUT | /api/knowledge/{id} | LECTURER/ADMIN |
| 发布/下架知识 | PUT | /api/knowledge/{id}/status | LECTURER/ADMIN |
| 删除知识 | DELETE | /api/knowledge/{id} | LECTURER/ADMIN |
| 文件上传 | POST | /api/knowledge/upload | LECTURER/ADMIN |
| 学员-知识列表 | GET | /api/student/knowledge | STUDENT |
| 学员-知识详情 | GET | /api/student/knowledge/{id} | STUDENT |
| 学员-开始学习 | POST | /api/student/knowledge/{id}/start | STUDENT |
| 学员-更新进度 | POST | /api/student/knowledge/{id}/progress | STUDENT |
| 学员-标记完成 | POST | /api/student/knowledge/{id}/complete | STUDENT |
6. 异常与边界处理
| 场景 | 处理方式 |
|---|---|
| 已发布知识被下架,同时培训计划正引用 | 弹出确认警告,显示引用该知识的培训计划数量,用户确认后方可下架 |
| 文件上传失败(存储服务不可用) | 返回 503,前端提示"文件上传失败,请稍后重试" |
| 学员学习已下架的知识(在培训计划中) | [ASSUMPTION] PRD 未明确,建议:关联进培训计划的知识下架后,学员仍可查看历史进度但不可重新打开 |
| km_knowledge_progress 并发 UPSERT(同一学员多标签页) | 唯一约束 uk_user_knowledge 防止重复插入;多标签页同步由前端 BroadcastChannel 控制关闭重复 Tab |
| 视频播放中途退出 | 下次进入从 video_position 断点续播 |
| 学习进度上报时网络中断 | 前端重试,后端幂等(UPSERT 语义,重复上报取最大值或继续累加) |
| 分类下有知识时删除分类 | 检查该分类下是否有 deleted=0 的知识,若有则拒绝:400 请先移除分类下的知识 |