个人知识库 架构设计与实施方案
文档状态:可实施(对齐 auto-exchange 现网栈)
版本:v1.0
日期:2026-07-30
上游文档:docs/个人知识库系统-开发文档.docx(v0.1 MVP 规划)
范围:在 okx-bot + okx-trading-web 内新增知识库模块;不新建独立 monorepo。
0. 可行性结论
| 维度 | 结论 | 说明 |
|---|---|---|
| 总体 | 可行,且应合入现有工具台 | 笔记 CRUD + 分类/标签/搜索与现有模块复杂度相当或更低 |
| 后端 | 高复用 | Spring Boot 3.2、MyBatis-Plus、JWT、ApiResult、SecurityUtils、user_id 隔离均已具备 |
| 前端 | 高复用 | Vue3 + Vite + Ant Design Vue + BasicLayout / 路由守卫可直接挂载 |
| 存储 | 现成 | MySQL okx_bot;附件可复用 ObjectStoragePort(本地 / R2) |
| AI 增强 | 二期可选 | 已有 LangChain4j Chat;RAG / Agent Tool 可后挂,不阻塞 MVP |
| 小程序 | 三期可选 | 当前仓库无小程序工程;MVP 不做,API 设计保持多端兼容即可 |
| 主要风险 | 低~中 | 文档与现网约定不一致(见 §1);全文检索数据量变大时需升级方案 |
不建议:按 v0.1 文档新建 knowledge-base/{backend,admin-web,mini-program} 三仓库。那会重复造 Auth、布局、部署链路,且与 AI 对话 / 文章提取无法自然联动。
建议路径:
okx-bot/src/.../kb/ # 新后端模块
okx-bot/doc/sql/kb_*.sql # 表结构
okx-trading-web/src/views/kb/ # PC 端页面
okx-trading-web/src/api/kb.api.ts
1. 上游文档缺口与对齐修正
v0.1 文档方向正确(轻量、自用、笔记+分类+标签+搜索),但以下点与 本仓库现状冲突或过粗,实施时以本节为准。
| v0.1 原文 | 现网事实 / 修正 |
|---|---|
独立 knowledge-base 工程 | 合入 okx-bot + okx-trading-web |
| PC:Element Plus | 前端是 Ant Design Vue,沿用现有主题与 tools-ui |
自建 user 表 + 账号密码 | 复用 sys_user + JWT;邮箱注册/登录已存在,禁止再建一套用户表 |
响应 { code: 200, msg } | 统一 ApiResult:code=0 成功,message 字段 |
路径 /admin/** vs /api/** | 统一 /api/v1/kb/**;管理端超管接口才走 /api/admin/** |
| 搜索「MySQL 全文或 ES」 | MVP:MySQL FULLTEXT + 关键词 LIKE 兜底;ES/向量检索 Phase 2 |
| Redis 可选 | MVP 不引入 Redis;列表分页 + 索引即可 |
| MinIO | 附件走现有 ObjectStoragePort(local/R2),不单独上 MinIO |
| 微信小程序 MVP | 移出 MVP;API 无状态 JWT,未来小程序可直接消费 |
| 无包结构 / 无错误码 / 无索引细节 | 本文 §3~§7 补齐 |
| 无与 AI 工具联动 | Phase 2:文章提取「存入知识库」、Chat Agent Tool |
2. 产品范围
2.1 产品定位(不变)
轻量个人知识管理:记得到、找得到、整理得顺。
不做协同编辑、多维表格、完整知识图谱。
2.2 MVP(Phase 1,必须)
- 笔记 CRUD(Markdown 正文)
- 分类(树形,
parent_id,单用户内) - 标签(多对多)
- 列表筛选:分类 / 标签 / 关键词(标题+正文)+ 分页
- 软删除(
is_deleted)+ 列表默认排除 - 强制
user_id隔离(与 chat/video/article 同模式) - PC 端:列表 + 编辑器(预览)+ 分类/标签管理入口
2.3 明确不做(Phase 1)
- 小程序 / uni-app
- 附件与图片上传
- 向量检索 / RAG
- 双向链接、知识图谱
- 多人共享、团队空间
- 独立登录体系
2.4 后续迭代(Phase 2+)
| 能力 | 优先级 | 依赖 |
|---|---|---|
| 回收站恢复 / 彻底删除 | P1 | 软删除字段已预留 |
| 置顶 / 收藏 | P1 | 字段扩展 |
| 图片附件(ObjectStorage) | P1 | storage 模块 |
| 从「文章提取」一键入库 | P1 | article 结果 JSON → note |
Chat Agent:search_notes / create_note | P2 | chat.agent Tool |
| 向量分块 + 语义检索 | P2 | embedding API + 表 |
| 导出 Markdown/JSON | P2 | 纯后端 |
| 小程序只读+快记 | P3 | 新前端工程 |
3. 总体架构
3.1 在现网中的位置
┌────────────────────────────────────────────────────────────┐
│ okx-trading-web │
│ /kb 列表 │ 编辑 │ 分类/标签侧栏(Ant Design Vue) │
└───────────────────────────┬────────────────────────────────┘
│ REST JWT
┌───────────────────────────▼────────────────────────────────┐
│ okx-bot │
│ kb.controller → kb.service → mapper │
│ │ │
│ ├─ SecurityUtils.requireCurrentUserId() │
│ ├─ MySQL: kb_note / kb_category / kb_tag / kb_note_tag│
│ └─ (Phase2) ObjectStoragePort / chat.agent tools │
└────────────────────────────────────────────────────────────┘
3.2 后端包结构(对齐 article/chat)
com.dwcode.okxbot.kb
├── controller
│ ├── KbNoteController
│ ├── KbCategoryController
│ └── KbTagController
├── service
│ ├── KbNoteService
│ ├── KbCategoryService
│ └── KbTagService
├── entity
│ ├── KbNoteEntity
│ ├── KbCategoryEntity
│ ├── KbTagEntity
│ └── KbNoteTagEntity
├── mapper
│ ├── KbNoteMapper
│ ├── KbCategoryMapper
│ ├── KbTagMapper
│ └── KbNoteTagMapper
├── dto
│ ├── NoteCreateRequest / NoteUpdateRequest
│ ├── NoteResponse / NotePageResponse
│ ├── NoteQueryRequest(或 query params)
│ ├── CategoryCreateRequest / CategoryResponse
│ └── TagCreateRequest / TagResponse
└── enums(可选)
└── KbErrorCode
铁律(与 Agent/任务模块一致):
- 所有查询/写操作第一行:
Long userId = SecurityUtils.requireCurrentUserId()。 - 更新/删除必须带
user_id条件,禁止「只按 id 更新」。 - Controller 不写业务;Entity 不泄漏外部 SDK。
- 主键
IdType.ASSIGN_ID(雪花),JSON 序列化用ToStringSerializer防前端精度丢失。
3.3 前端结构
okx-trading-web/src/
├── api/kb.api.ts
├── views/kb/
│ ├── index.vue # 主工作台:左分类树 + 中列表 + 右预览(或三栏)
│ ├── NoteEditor.vue # 编辑页 / 抽屉
│ └── components/
│ ├── CategoryTree.vue
│ ├── TagFilter.vue
│ └── NoteList.vue
└── router:path `kb`,meta.group = 'tools'
导航:在 AppHeader 的「工具」分组增加 知识库 入口。
4. 数据库设计(可执行)
库名:okx_bot(与现网一致)。脚本建议:okx-bot/doc/sql/kb_tables.sql。
4.1 分类表 kb_category
CREATE TABLE IF NOT EXISTS kb_category (
id BIGINT NOT NULL COMMENT '主键',
user_id BIGINT NOT NULL COMMENT '所属用户',
name VARCHAR(64) NOT NULL COMMENT '分类名',
parent_id BIGINT NULL COMMENT '父分类,NULL 为根',
sort_order INT NOT NULL DEFAULT 0 COMMENT '同级排序,小在前',
created_at DATETIME(3) NOT NULL,
updated_at DATETIME(3) NOT NULL,
PRIMARY KEY (id),
INDEX idx_kb_cat_user_parent (user_id, parent_id),
INDEX idx_kb_cat_user_sort (user_id, sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库分类';
约束(应用层):
- 同用户下
name在同一parent_id下不重复(可加唯一索引:uk_user_parent_name (user_id, parent_id, name),注意 MySQL 对 NULL parent 的唯一行为需实测)。 - 删除分类:子分类提升为根或拒绝删除(MVP:有子分类或关联笔记时拒绝删除,返回明确错误)。
- 树深度建议上限 3 层,防脏数据。
4.2 标签表 kb_tag
CREATE TABLE IF NOT EXISTS kb_tag (
id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
name VARCHAR(64) NOT NULL,
created_at DATETIME(3) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_kb_tag_user_name (user_id, name),
INDEX idx_kb_tag_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库标签';
4.3 笔记表 kb_note
CREATE TABLE IF NOT EXISTS kb_note (
id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
title VARCHAR(200) NOT NULL DEFAULT '' COMMENT '标题',
content LONGTEXT NULL COMMENT 'Markdown 正文',
content_text MEDIUMTEXT NULL COMMENT '纯文本摘要/检索副本(可选)',
category_id BIGINT NULL COMMENT '分类,可空',
is_pinned TINYINT NOT NULL DEFAULT 0 COMMENT '置顶 0/1',
is_deleted TINYINT NOT NULL DEFAULT 0 COMMENT '软删 0/1',
deleted_at DATETIME(3) NULL,
created_at DATETIME(3) NOT NULL,
updated_at DATETIME(3) NOT NULL,
PRIMARY KEY (id),
INDEX idx_kb_note_user_updated (user_id, is_deleted, updated_at DESC),
INDEX idx_kb_note_user_cat (user_id, category_id, is_deleted),
INDEX idx_kb_note_user_pinned (user_id, is_pinned, updated_at DESC)
-- FULLTEXT 见下
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库笔记';
全文索引(MySQL 8,InnoDB):
ALTER TABLE kb_note
ADD FULLTEXT INDEX ft_kb_note_title_content (title, content) WITH PARSER ngram;
说明:
- 中文建议
ngram(innodb_ft_min_token_size/ngram_token_size在运维侧确认,常见 2)。 - 若环境不支持 ngram,MVP 退化为:
title LIKE %kw% OR content LIKE %kw%,并限制content扫描策略(分页 + 索引前缀)。 content_text:可选,存剥离 Markdown 后的纯文本,搜索更干净;Phase 1 可先不写,直接搜content。
4.4 笔记-标签关联 kb_note_tag
CREATE TABLE IF NOT EXISTS kb_note_tag (
note_id BIGINT NOT NULL,
tag_id BIGINT NOT NULL,
PRIMARY KEY (note_id, tag_id),
INDEX idx_kb_note_tag_tag (tag_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='笔记标签关联';
写操作:先校验 note/tag 同属 userId,再插关联。
4.5 与 v0.1 字段对照
| v0.1 | 本方案 |
|---|---|
user 表 | 不建,用 sys_user |
note | kb_note(加前缀防冲突) |
category | kb_category |
tag / note_tag | kb_tag / kb_note_tag |
| 无 pin / deleted_at | 预留 is_pinned、deleted_at |
5. API 设计
5.1 约定
- Base:
/api/v1/kb - 鉴权:Bearer JWT(现有过滤器)
- 响应:
ApiResult<T>(code=0成功) - 分页:与 article 一致,
page从 0 起,size默认 20,最大 100 - 时间:ISO-8601 / Jackson 默认
LocalDateTime
5.2 笔记
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/kb/notes | 列表。Query:page,size,categoryId,tagId,keyword,includeDeleted |
| POST | /api/v1/kb/notes | 创建。Body:title, content, categoryId?, tagIds? |
| GET | /api/v1/kb/notes/{id} | 详情(含标签列表) |
| PUT | /api/v1/kb/notes/{id} | 全量/部分更新 title/content/categoryId/tagIds/isPinned |
| DELETE | /api/v1/kb/notes/{id} | 软删除 |
| POST | /api/v1/kb/notes/{id}/restore | 从回收站恢复(Phase 1.1 可做) |
列表响应示例:
{
"code": 0,
"message": "success",
"success": true,
"data": {
"items": [
{
"id": "123",
"title": "LangChain4j 笔记",
"categoryId": "456",
"categoryName": "技术",
"tags": [{ "id": "7", "name": "AI" }],
"isPinned": false,
"snippet": "正文前 160 字…",
"updatedAt": "2026-07-30T12:00:00"
}
],
"page": 0,
"size": 20,
"total": 1
}
}
列表默认 不返回全文 content,只返回 snippet(截断),详情再返回 content。
5.3 分类
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/kb/categories | 树或扁平列表(推荐返回树 children[]) |
| POST | /api/v1/kb/categories | { name, parentId?, sortOrder? } |
| PUT | /api/v1/kb/categories/{id} | 改名 / 移动 / 排序 |
| DELETE | /api/v1/kb/categories/{id} | 无子节点且无笔记时可删 |
5.4 标签
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/kb/tags | 当前用户全部标签(可带 noteCount) |
| POST | /api/v1/kb/tags | { name },重名返回已有或 409 |
| PUT | /api/v1/kb/tags/{id} | 重命名 |
| DELETE | /api/v1/kb/tags/{id} | 删标签并清理关联 |
5.5 错误语义
| 场景 | code | message 示例 |
|---|---|---|
| 未登录 | 401 | 未登录或登录已过期 |
| 越权 / 不存在 | 404 | 笔记不存在 |
| 分类下有笔记 | 400 | 请先移除或移动该分类下的笔记 |
| 参数非法 | 400 | 标题不能为空 / 超过 200 字 |
| 业务异常 | 与 BusinessException 一致 | GlobalExceptionHandler 统一处理 |
6. 核心业务规则
- 隔离:任何 note/category/tag 读写必须
user_id = currentUser。 - 软删:
DELETE note→is_deleted=1, deleted_at=now;列表默认is_deleted=0。 - 标签替换:更新笔记
tagIds时,先删关联再批量插入(事务)。 - 空标题:允许临时空标题展示为「无标题笔记」,或创建时默认「未命名笔记」。推荐默认 「未命名笔记」。
- content 大小:应用层限制例如 512KB 文本,防滥用。
- 搜索:
- 有 keyword:优先
MATCH(title,content) AGAINST (:kw IN BOOLEAN MODE),失败或无 ngram 时降级 LIKE。 - 同时叠加
categoryId/tagId(tag 用 EXISTS 子查询)。
- 有 keyword:优先
- 并发:单用户编辑冲突 MVP 不做 OT;以
updated_at乐观锁为 Phase 2 可选项。
7. 前端实施方案
7.1 技术选择(对齐现网)
| 项 | 选择 |
|---|---|
| UI | Ant Design Vue(已有) |
| 路由 | /kb,meta: { title: '知识库', group: 'tools' } |
| Markdown 编辑 | 推荐 @bytemd/vue-next 或 md-editor-v3(按包体积选一个);MVP 也可用 a-textarea + 简易预览 |
| 请求 | 复用 src/api/request.ts |
| 状态 | 页面级 ref 即可;复杂再 pinia |
7.2 页面交互(MVP)
推荐布局(单页工作台):
┌──────────┬────────────────────┬─────────────────────┐
│ 分类树 │ 搜索框 + 标签筛选 │ │
│ + 全部 │ 笔记列表(置顶优先)│ 预览 / 编辑器 │
│ + 未分类 │ 新建按钮 │ 标题 + MD + 标签 │
└──────────┴────────────────────┴─────────────────────┘
移动窄屏:列表与编辑切换(路由 /kb 与 /kb/:id)。
7.3 关键验收
- 登录后进入知识库,新建一条 Markdown 笔记并保存。
- 分类树创建二级分类,笔记挂到分类后列表可筛选。
- 打 2 个标签,按标签筛选正确。
- 关键词搜到标题与正文。
- 删除后列表不可见;另一用户 id 无法访问该笔记 id。
- 刷新页面数据仍在。
8. 分阶段实施计划(可排期)
Phase 1A — 后端骨架(约 1~2 天)
| # | 任务 | 产出 |
|---|---|---|
| 1 | 写 doc/sql/kb_tables.sql 并在本地执行 | 四张表 |
| 2 | Entity + Mapper + Service 空壳 | 可编译 |
| 3 | Note CRUD + user 隔离单测/手工测 | API 可用 |
| 4 | Category / Tag CRUD | API 可用 |
| 5 | 列表筛选 + FULLTEXT/LIKE 搜索 | 搜索可用 |
建议 PR:feat(kb): backend notes categories tags
Phase 1B — 前端工作台(约 2~3 天)
| # | 任务 | 产出 |
|---|---|---|
| 1 | kb.api.ts + 路由 + Header 入口 | 可导航 |
| 2 | 三栏/双栏列表 + 详情 | 可读 |
| 3 | 新建/编辑保存 + Markdown 预览 | 可写 |
| 4 | 分类树 + 标签管理弹窗 | 可整理 |
| 5 | 搜索与筛选联调 | MVP 闭环 |
建议 PR:feat(kb): web knowledge base workspace
Phase 1C — 硬化(约 1 天)
- 参数校验、内容长度、删除分类保护
- 列表 snippet、空态、错误提示
schema.sql/ 部署文档补一行建表说明- 基础集成测试(Mapper 或 MockMvc)
Phase 2 — 与 AI 工具台联动(暂缓)
2026-07-30 决策:AI 工具链路优先级下调,暂不实施 Phase 2;直接推进 Phase 3 移动端。
- 文章 → 知识库:
ArticleTaskService结果页按钮「存入知识库」,POST note(title=文章标题,content=正文/核心摘要)。 - Agent Tool:
search_notes(READ)create_note(WRITE,走确认卡)
- 附件:笔记内图片上传走
ObjectStoragePort,存 URL 进 Markdown。 - RAG(可选):
kb_chunk表 + embedding;检索结果注入 Chat system 上下文。- 不在 Phase 1 引入向量库;优先继续用 MySQL。
Phase 3 — 移动端(已落地)
- 工程:仓库根目录
kb-miniprogram/(原生微信小程序)。 - 能力:登录、笔记列表/搜索、快记新建、详情查看/编辑/删除、服务端地址配置。
- 复用:
/api/auth/login+/api/v1/kb/*,与 PC 共用账号与数据。 - 说明:见
kb-miniprogram/README.md。
9. 与现有模块的集成点清单
| 模块 | 集成方式 | 阶段 |
|---|---|---|
auth | JWT + SecurityUtils | P1 |
common.response | ApiResult | P1 |
storage | 附件 URL | P2 |
article | 一键入库 | P2 |
chat.agent | Tool 注册 | P2 |
member | 可选:非会员笔记数量上限 | 按需,默认不做 |
| deploy | 新表 SQL 纳入 init-rds / 手工迁移说明 | P1 |
不改动:video / aigen / imggen Pipeline 内部。
10. 测试计划
| 层级 | 内容 |
|---|---|
| 单测 | Service:创建后只能被 owner 读;跨 user 404;软删后 list 不可见 |
| API | MockMvc:CRUD + 筛选 + 未登录 401 |
| 手工 | 前端完整验收 §7.3 |
| 回归 | 登录、对话、文章提取路径无回归 |
11. 运维与配置
- 无新环境变量(Phase 1)。
- 建表:部署时执行
doc/sql/kb_tables.sql。 - FULLTEXT:确认 MySQL 支持 ngram;云 RDS 若禁止,配置开关
kb.search.mode=like|fulltext。 - 备份:笔记在业务库,随现有 MySQL 备份即可。
建议 application.yml 预留(Phase 1 可写死默认):
kb:
note:
max-content-chars: 524288
search:
mode: fulltext # fulltext | like
category:
max-depth: 3
12. 工作量粗估
| 范围 | 人天(单人熟悉本仓库) |
|---|---|
| Phase 1A 后端 | 1.5~2 |
| Phase 1B 前端 | 2~3 |
| Phase 1C 硬化 | 0.5~1 |
| MVP 合计 | 约 4~6 人天 |
| Phase 2 联动 | 2~5(视 RAG 深度) |
13. 决策记录(相对 v0.1)
- 合入 monorepo 工具台,不新建独立知识库仓库。
- 复用 sys_user / JWT / ApiResult / Ant Design Vue。
- 表前缀
kb_,避免与历史/未来业务表冲突。 - 小程序移出 MVP。
- 搜索先 MySQL,向量与 ES 后置。
- 与 AI 对话/文章提取的联动作为差异化增强,写在 Phase 2,体现「基于当前项目」的价值,而非又一个孤立笔记 App。
14. 下一步(落地顺序)
若确认本方案,建议按以下顺序开工:
- 提交/合并本设计文档(本文)。
- 落地
kb_tables.sql。 - 实现后端 Note/Category/Tag。
- 实现前端工作台。
- 自用一周后,再排文章入库与 Agent Tool。
附录 A · v0.1 文档保留价值
- 产品原则「先自用、少而精」继续遵守。
- 功能优先级(笔记 → 分类标签 → 搜索 → 附件)继续遵守。
- 分阶段节奏(先主流程再体验)继续遵守。
附录 B · 参考现网代码路径
| 能力 | 参考 |
|---|---|
| 用户隔离 + CRUD | article/service/ArticleTaskService、chat/service/ChatService |
| JWT 过滤器 | auth/config/SecurityConfig |
| 统一响应 | common/response/ApiResult |
| 对象存储 | storage/ObjectStoragePort |
| 前端 API | okx-trading-web/src/api/article.api.ts |
| 导航入口 | okx-trading-web/src/layouts/AppHeader.vue |
| Agent Tool 扩展 | okx-bot/doc/AI助手_Agent架构设计与开发方案.md |
—— 文档结束 ——