# 知识库模块 - UI 交互规范

> **版本**: v1.0  
> **最后更新**: 2026-02-25  
> **维护者**: 前端团队

> 🚧 Draft：本文件为最小占位，待与 PRD/架构确认后完善。

> **参考标准**: [设计系统（权威）](../../../.agents/skills/frontend-main/references/design-system-standards.md)

---

## 📄 页面清单

| 页面 | 路由 | 说明 | 状态 |
|------|------|------|------|
| 知识库首页/列表 | `/knowledge-base` | 搜索与列表 | 🚧 |
| 文章详情（查看） | `/knowledge-base/articles/:id` | 站内文章详情 | 🚧 |
| 文档详情（预览） | `/knowledge-base/documents/:id` | 文档详情 | ❌ |
| AI 问答面板 | `/knowledge-base/ask` | 问答入口 | 🚧 |
| Outline 编辑器 | `/knowledge-base/outline` | 嵌入式编辑器 | 🚧 |
| 同步任务列表 | `/knowledge-base/sync-tasks` | 最近同步任务 | 🚧 |
| 同步任务详情 | `/knowledge-base/sync-tasks/:taskId` | 同步任务状态与统计 | 🚧 |
| 同步跳过明细 | `/knowledge-base/sync-tasks/:taskId/skipped` | 跳过文件明细 | 🚧 |
| 同步已处理明细 | `/knowledge-base/sync-tasks/:taskId/processed` | 已处理文件明细 | 🚧 |
| 同步处理中明细 | `/knowledge-base/sync-tasks/:taskId/processing` | 处理中明细 | 🚧 |
| 同步失败明细 | `/knowledge-base/sync-tasks/:taskId/failed` | 失败文件明细 | 🚧 |

---

## 🖥️ 页面 1: 知识库首页/列表

### 基本信息

- **页面标题**: 知识库
- **URL**: `/knowledge-base`
- **权限要求**: 需要登录
- **布局模式**: 搜索 + 列表

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 页面标题 | `[data-testid="page-title"]` | 文本 | - | 显示“知识库” |
| 搜索框 | `[data-testid="kb-search-input"]` | 输入框 | ❌ | 关键词搜索 |
| 搜索按钮 | `[data-testid="kb-search-button"]` | 按钮 | - | 执行搜索 |
| 搜索建议面板 | `[data-testid="kb-search-suggestions"]` | 列表容器 | ❌ | 输入中联想建议 |
| 搜索建议项 | `[data-testid="kb-search-suggestion-item"]` | 列表项 | ❌ | 支持点击/键盘选中 |
| 结果容器 | `[data-testid="kb-results"]` | 容器 | - | 结果区域 |
| 结果列表 | `[data-testid="kb-list"]` | 列表 | - | 文档列表 |
| 文档卡片 | `[data-testid="kb-card"]` | 卡片 | - | 标题/摘要/来源 |
| 空状态 | `[data-testid="empty-state"]` | 状态 | - | 无结果提示 |
| 上传文件 | `input[type="file"]` | 输入框 | ❌ | 选择上传文件 |
| 上传按钮 | `button` | 按钮 | - | 提交上传 |
| 编辑入口 | 入口按钮 | 按钮 | ❌ | 进入编辑页面 |
| 重建索引 | `[data-testid="kb-rebuild-index"]` | 按钮 | ❌ | 仅管理员可见，触发全量重建索引 |
| 增量同步 | `[data-testid="kb-sync-delta"]` | 按钮 | ❌ | 仅管理员可见，默认触发 SharePoint 增量同步 |
| 全量同步 | `[data-testid="kb-sync-full"]` | 按钮 | ❌ | 仅管理员可见，触发 SharePoint 全量同步 |
| 同步策略提示 | `[data-testid="kb-sync-strategy"]` | 文本 | - | 展示“增量优先、必要时全量回退”策略说明 |
| 快速开始模块 | - | 卡片区块 | - | 展示 Getting Started / How to / FAQ 三个外部入口 |

### 交互行为

#### 1. 页面加载

- 显示骨架屏
- 调用列表/搜索 API
- 渲染结果列表

#### 2. 搜索操作

- 输入关键词可触发联想建议（输入长度 >= 2）
- 按回车或点击搜索按钮触发正式搜索
- 结果列表刷新
- 无结果显示空状态
- 搜索结果需展示内容状态标签（如 Draft/Published），明确可检索但状态不同
- 搜索结果左侧图标需按文档文件类型区分，采用“`mimeType` 优先、扩展名兜底、未知回退”的识别策略
- 类型分类至少覆盖：Word、Excel、PPT、PDF、图片、视频、音频、压缩包、文本/代码、CAD/设计；无法识别类型时回退为通用文档图标
- 结果卡片“内容”一行必须展示与当前关键词相关的上下文片段（优先命中位置附近）
- 标题与内容片段中的命中关键词必须高亮显示
- 片段过长时允许前后裁剪，并使用省略号表示被裁剪内容
- 结果卡片元信息需展示创建人（`createdBy`），用于标识文档所有者（谁创建）
- 搜索结果操作分离：
  - 左侧“标题/内容/元信息”区域可点击，作为主动作跳转原文
  - 右侧按钮文案为“预览”，点击只打开预览面板，不跳转页面
- 结果分组展示顺序固定：
  - 文件结果（文档 + 文章）在上
  - 文件夹结果在下
- 文件夹结果卡片仅展示：文件夹名、路径、更新时间
- 文件夹结果卡片整体可点击并直接打开 SharePoint 文件夹，不提供单独“打开”按钮
- 文件夹结果不显示“预览”按钮
- 每条结果的相关度需常显，样式使用小号弱化文本，并固定展示在“预览”按钮左侧（靠左下角）
- 左侧可点击区域在 hover 状态显示手型光标（`cursor-pointer`），并保留 focus 可见态

#### 2.1 输入联想建议（新增）

- 触发时机：
  - 输入框聚焦且输入长度 >= 2 时触发建议请求
  - 输入变化使用 200ms 防抖，避免频繁请求
- 候选来源：
  - 个人最近搜索（优先）
  - 团队热门搜索
  - 文档/文章标题匹配
- 展示规则：
  - 默认最多展示 8 条建议
  - 建议分组展示顺序固定为（文档与文章 / 最近搜索 / 热门搜索）
  - 无建议时显示空状态提示，不影响后续正式搜索
- 最近搜索管理：
  - 在“最近搜索”分组标题区域提供“清空”入口
  - 每条“最近搜索”建议提供“删除”入口（仅该分组显示）
  - 删除后建议列表即时刷新，不影响“文档与文章/热门搜索”分组
- 交互规则：
  - `ArrowDown` / `ArrowUp`：切换高亮项
  - `Enter`：选中高亮项并执行正式搜索
  - `Esc`：关闭建议面板
- 点击建议项：回填输入框并执行正式搜索
- 点击“删除”或“清空”时只执行历史管理操作，不触发正式搜索
- 无障碍规则：
  - 输入框使用 `role="combobox"`、`aria-expanded`、`aria-controls`
  - 建议容器使用 `role="listbox"`
  - 建议项使用 `role="option"`，并通过 `aria-selected` 标识当前高亮项

#### 3. 跳转文档

- 点击结果左侧信息区（主动作）：
  - 站内文章 → 跳转 `/knowledge-base/articles/:id`
  - SharePoint 文档 → 新窗口打开 SharePoint 预览

#### 3.1 结果预览（新增）

- 点击右侧“预览”按钮，打开右侧预览面板（保持在当前搜索页）
- 预览面板需按文件类型兼容展示：
  - 站内文章：展示可提取的完整正文文本
  - SharePoint/外部文档：展示检索可用文本内容，并保留原文打开入口
- 预览正文区域采用单块展示，不得同时出现多个“预览内容块”导致重复或冲突
- 预览内容应尽量完整展示，不做固定长度裁剪；仅在数据源本身受限时展示可用最大内容
- 预览面板中的命中关键词与结果列表保持一致的高亮样式
- 预览面板需展示“内容来源 + 内容长度 + 创建人（有值时）”元信息，帮助用户理解当前预览是否来自文章正文或检索分片聚合，并识别文档所有者
- 面板支持关闭按钮与 `Esc` 关闭

#### 4. 文章保存与索引

- 保存/更新文章后，后台自动触发单条文章增量同步
- 不再要求手动全量同步即可参与搜索

#### 5. 重建索引（管理员）

- 点击“重建索引”按钮
- 弹出二次确认
- 确认后调用 `POST /knowledge-base/index/rebuild-all`
- 成功提示“重建任务已触发”
- 失败提示错误信息，按钮恢复可点击

#### 6. 全量同步（管理员）

- 点击“全量同步”按钮
- 弹出二次确认
- 确认后调用 `POST /knowledge-base/sync/full`
- 成功提示“全量同步任务已触发”
- 失败提示错误信息，按钮恢复可点击
- 同步范围支持路径白名单（配置 `KB_SP_INCLUDED_PATHS`）

#### 7. 增量同步（管理员）

- 点击“增量同步”按钮
- 默认调用 `POST /knowledge-base/sync/delta`
- **自动切换逻辑**：
  - 若检测到增量游标缺失/失效，则自动回退为全量同步
  - UI 以提示文案说明“已自动切换为全量同步”
- 增量同步优先用于日常更新，全量同步用于首次接入/配置变更/游标失效

#### 8. 同步任务列表（管理员）

- 列表展示“触发方式”字段
  - 手动全量 / 手动增量 / 增量回退全量 / 定时全量

#### 9. 快速开始（所有登录用户）

- 首页展示“快速开始”模块，固定三张卡片：
  - Getting Started
  - How to
  - FAQ
- 点击任一卡片，在新标签页打开对应 SharePoint 文档链接

---

## 🖥️ 页面 2: 文档详情（预览）

> MVP 阶段可简化为“跳转 SharePoint 预览”，本页为 Phase 2+ 预留。

---

## 🖥️ 页面 3: AI 问答面板

### 基本信息

- **页面标题**: AI 问答
- **URL**: `/knowledge-base/ask`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 问题输入框 | `textarea[name="question"]` | 输入框 | ✅ | 输入问题 |
| 提交按钮 | `button[data-action="ask"]` | 按钮 | ✅ | 触发问答 |
| 答案区域 | `[data-testid="answer"]` | 文本 | - | 显示回答 |
| 引用列表 | `[data-testid="sources"]` | 列表 | - | 标题/链接/片段 |

### 交互行为

#### 1. 提交问答

- 点击提交后展示加载状态
- 结果返回后显示答案与引用
- 引用列表需展示来源状态标签（如 Draft/Published）

#### 2. 引用跳转

- 点击引用链接
- 打开 SharePoint 预览

---

## 🖥️ 页面 4: 同步任务详情

### 基本信息

- **页面标题**: 同步任务详情
- **URL**: `/knowledge-base/sync-tasks/:taskId`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 任务标题 | - | 文本 | - | 显示同步任务详情标题 |
| 任务状态 | - | 标签 | - | PENDING / SYNCING / COMPLETED / FAILED |
| 统计卡片 | - | 卡片 | - | 总数/已处理/失败/跳过 |
| 错误信息 | - | 文本 | ❌ | 任务级错误（若存在） |
| 刷新按钮 | - | 按钮 | ❌ | 重新拉取任务状态 |
| 已处理明细入口 | - | 按钮 | ❌ | 已处理明细入口 |
| 处理中明细入口 | - | 按钮 | ❌ | 处理中明细入口 |
| 失败明细入口 | - | 按钮 | ❌ | 失败明细入口 |
| 跳过明细入口 | - | 按钮 | ❌ | 跳过明细入口 |

### 交互行为

#### 1. 页面加载

- 调用 `GET /knowledge-base/sync/tasks/:taskId`
- 显示任务状态与统计

#### 2. 刷新状态

- 点击刷新按钮重新拉取状态

#### 3. 查看跳过明细

- 显示“跳过明细”入口（无跳过项时置灰）
- 点击跳转 `/knowledge-base/sync-tasks/:taskId/skipped`

#### 4. 查看已处理明细

- 显示“已处理明细”入口（无记录时置灰）
- 点击跳转 `/knowledge-base/sync-tasks/:taskId/processed`

#### 5. 查看处理中明细

- 显示“处理中明细”入口（无记录时置灰）
- 点击跳转 `/knowledge-base/sync-tasks/:taskId/processing`

#### 6. 查看失败明细

- 显示“失败明细”入口（无记录时置灰）
- 点击跳转 `/knowledge-base/sync-tasks/:taskId/failed`

---

## 🖥️ 页面 5: 同步任务列表

### 基本信息

- **页面标题**: 同步任务
- **URL**: `/knowledge-base/sync-tasks`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 列表表格 | - | 表格 | - | 展示任务 ID/状态/统计/时间 |
| 刷新按钮 | - | 按钮 | ❌ | 重新拉取任务列表 |
| 空状态 | - | 状态 | ❌ | 无任务时提示 |

### 交互行为

#### 1. 页面加载

- 调用 `GET /knowledge-base/sync/tasks`
- 显示最近任务列表

#### 2. 进入详情

- 点击某行任务跳转 `/knowledge-base/sync-tasks/:taskId`

---

## 🖥️ 页面 6: 同步跳过明细

### 基本信息

- **页面标题**: 跳过明细
- **URL**: `/knowledge-base/sync-tasks/:taskId/skipped`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 列表表格 | - | 表格 | - | 展示来源/文件名/扩展名/MIME/原因/时间 |
| 刷新按钮 | - | 按钮 | ❌ | 重新拉取跳过明细 |
| 空状态 | - | 状态 | ❌ | 无跳过记录时提示 |

### 交互行为

#### 1. 页面加载

- 调用 `GET /knowledge-base/sync/tasks/:taskId/skipped`
- 显示跳过记录列表

#### 2. 返回任务详情

- 点击返回跳转 `/knowledge-base/sync-tasks/:taskId`

---

## 🖥️ 页面 7: 同步已处理明细

### 基本信息

- **页面标题**: 已处理明细
- **URL**: `/knowledge-base/sync-tasks/:taskId/processed`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 列表表格 | - | 表格 | - | 展示来源/文件名/扩展名/MIME/RAGFlow 文档 ID/文件大小/Tokens/Chunks/时间 |
| 刷新按钮 | - | 按钮 | ❌ | 重新拉取已处理明细 |
| 空状态 | - | 状态 | ❌ | 无记录时提示 |

### 交互行为

#### 1. 页面加载

- 调用 `GET /knowledge-base/sync/tasks/:taskId/processed`
- 显示已处理记录列表

#### 2. 返回任务详情

- 点击返回跳转 `/knowledge-base/sync-tasks/:taskId`

---

## 🖥️ 页面 8: 同步处理中明细

### 基本信息

- **页面标题**: 处理中明细
- **URL**: `/knowledge-base/sync-tasks/:taskId/processing`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 列表表格 | - | 表格 | - | 展示来源/文件名/扩展名/MIME/RAGFlow 文档 ID/文件大小/Tokens/Chunks/时间 |
| 刷新按钮 | - | 按钮 | ❌ | 重新拉取处理中明细 |
| 空状态 | - | 状态 | ❌ | 无记录时提示 |

### 交互行为

#### 1. 页面加载

- 调用 `GET /knowledge-base/sync/tasks/:taskId/processing`
- 显示处理中记录列表

#### 2. 返回任务详情

- 点击返回跳转 `/knowledge-base/sync-tasks/:taskId`

---

## 🖥️ 页面 9: 同步失败明细

### 基本信息

- **页面标题**: 失败明细
- **URL**: `/knowledge-base/sync-tasks/:taskId/failed`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 列表表格 | - | 表格 | - | 展示来源/文件名/扩展名/MIME/错误/时间 |
| 刷新按钮 | - | 按钮 | ❌ | 重新拉取失败明细 |
| 空状态 | - | 状态 | ❌ | 无记录时提示 |

### 交互行为

#### 1. 页面加载

- 调用 `GET /knowledge-base/sync/tasks/:taskId/failed`
- 显示失败记录列表

#### 2. 返回任务详情

- 点击返回跳转 `/knowledge-base/sync-tasks/:taskId`

---

## 🖥️ 页面 4: 原生文章编辑（单人）

### 基本信息

- **页面标题**: 知识库文章编辑
- **URL**: `/knowledge-base/editor`
- **权限要求**: 需要登录

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 标题输入 | `input` | 输入框 | ✅ | 文章标题 |
| 正文编辑 | 富文本编辑器 | 编辑器 | ✅ | Outline 风格编辑器（ProseMirror） |
| 保存按钮 | `button` | 按钮 | ✅ | 保存文章 |

### 交互行为

#### 1. 保存文章

- 触发保存
- 成功后提示“文章已保存”
- 显示文章 ID（可用于后续编辑）
- 内容格式：ProseMirror 文档 JSON（序列化字符串）

---

## 🖥️ 页面 5: Outline 编辑器（试运行）

### 基本信息

- **页面标题**: Outline 编辑器（试运行）
- **URL**: `/knowledge-base/outline`
- **权限要求**: 需要登录
- **布局模式**: 说明 + 嵌入式 iframe

### 页面元素清单

| 元素名称 | 选择器 | 类型 | 必填 | 说明 |
|---------|--------|------|------|------|
| 页面标题 | `h1` | 文本 | - | 显示页面标题 |
| 外链按钮 | `button` | 按钮 | ❌ | 新标签打开 Outline |
| 嵌入容器 | `iframe` | 容器 | ❌ | Outline 嵌入展示 |
| 未配置提示 | 文本块 | 文本 | - | 未配置 URL 的提示 |

### 交互行为

#### 1. 页面加载

- 若未配置 Outline URL，显示提示文案
- 若可配置，展示 iframe

#### 2. 外链打开

- 点击按钮在新标签打开 Outline
