Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ui/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ ui/
│ │ ├── application/ # Application list and creation
│ │ ├── application-detail/ # Application overview and settings
│ │ ├── knowledge/ # Knowledge base list and cards
│ │ ├── knowledge-detail/ # Knowledge base and document details
│ │ ├── knowledge-detail/ # Knowledge base details, document lists, and settings
│ │ ├── document-detail/ # Document details and paragraph management
│ │ ├── model/ # Model list, creation, and settings
│ │ ├── tool/ # Tool list, forms, and tool store
│ │ ├── trigger/ # Workspace trigger list
Expand Down
5 changes: 5 additions & 0 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -568,9 +568,14 @@ Workspace、System 资源管理及 System 共享资源的 `knowledge.ts` 提供
`getParagraphList` 查询完整分段列表,支持 `title`、`content`,服务端按 `position`、创建时间排序;
`postParagraph` 提交 `title`、`content`、`is_active` 和可选的 `problem_list: [{ content }]`,
返回新增分段详情,默认插入首位并触发索引。
新增载荷可传 `position`,在目标位置插入,用于当前分段上方添加。
`getParagraphDetail` 查询 `/<paragraphId>`,返回 `ParagraphDetail`,包含 `problem_list`、
`hit_num` 和 `last_hit_time`。`putParagraph` 向同一路径提交标题和正文,解包后端三元素编辑响应的
首项为最新详情;不提交 `problem_list`,关联关系通过专属接口维护。
编辑载荷使用 `ParagraphEditPayload`,允许仅传 `is_active` 更新启用状态,正文表单仍使用
必填标题及正文的 `ParagraphUpdatePayload`。`deleteParagraph` DELETE `/<paragraphId>` 删除单个分段。
`putParagraphPosition` PUT `/adjust_position`,查询参数为 `paragraph_id`、`new_position`,
不传请求体,由服务端调整当前分段及受影响分段的位置。
`postParagraphProblem` 向 `/<paragraphId>/problem` 提交 `{ content }`,创建或复用问题并关联分段;
`getParagraphProblems` GET 同一路径,返回当前分段的 `ParagraphProblem[]`,用于关联变更后刷新。
`putAssociateParagraphProblem` PUT 到 `/association`,通过查询参数传递 `paragraph_id`、`problem_id`,
Expand Down
30 changes: 21 additions & 9 deletions ui/src/api/admin/workspace/knowledge/paragraph.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { get, post, put } from '../../core/request'
import { del, get, post, put } from '../../core/request'
import type {
ParagraphCreatePayload,
ParagraphDetail,
ParagraphEditPayload,
ParagraphGeneratePayload,
ParagraphItem,
ParagraphProblem,
ParagraphQuery,
ParagraphUpdatePayload,
} from '@/api/types'
import { getWorkspaceId } from '@/utils/resource-context'

Expand All @@ -17,20 +17,19 @@ const getPrefix = (knowledgeId: string, documentId: string) =>
const getParagraphList = (knowledgeId: string, documentId: string, query?: ParagraphQuery) =>
get<ParagraphItem[]>(getPrefix(knowledgeId, documentId), { ...query })

/** 在文档首位新增分段,由服务端触发索引。 */
/** 在指定位置新增分段,默认首位,由服务端触发索引。 */
const postParagraph = (knowledgeId: string, documentId: string, payload: ParagraphCreatePayload) =>
post<ParagraphCreatePayload, ParagraphDetail>(getPrefix(knowledgeId, documentId), payload)

/** 查询分段正文、召回统计及关联问题。 */
const getParagraphDetail = (knowledgeId: string, documentId: string, paragraphId: string) =>
get<ParagraphDetail>(`${getPrefix(knowledgeId, documentId)}/${paragraphId}`)

/** 保存分段标题和内容,提取后端编辑响应中的最新详情。 */
const putParagraph = (knowledgeId: string, documentId: string, paragraphId: string, payload: ParagraphUpdatePayload) =>
put<ParagraphUpdatePayload, [ParagraphDetail, ParagraphUpdatePayload, string]>(
`${getPrefix(knowledgeId, documentId)}/${paragraphId}`,
payload,
).then(([paragraph]) => paragraph)
/** 更新分段正文或启用状态,提取后端编辑响应中的最新详情。 */
const putParagraph = (knowledgeId: string, documentId: string, paragraphId: string, payload: ParagraphEditPayload) =>
put<ParagraphEditPayload, [ParagraphDetail, ParagraphEditPayload, string]>(`${getPrefix(knowledgeId, documentId)}/${paragraphId}`, payload).then(
([paragraph]) => paragraph,
)

/** 新增问题并关联到当前分段。 */
const postParagraphProblem = (knowledgeId: string, documentId: string, paragraphId: string, content: string) =>
Expand Down Expand Up @@ -62,6 +61,17 @@ const putGenerateParagraphQuestions = (knowledgeId: string, documentId: string,
const putBatchDeleteParagraphs = (knowledgeId: string, documentId: string, paragraphIds: string[]) =>
put<{ id_list: string[] }, boolean>(`${getPrefix(knowledgeId, documentId)}/batch_delete`, { id_list: paragraphIds })

/** 删除当前文档的单个分段及其关联数据。 */
const deleteParagraph = (knowledgeId: string, documentId: string, paragraphId: string) =>
del<undefined, boolean>(`${getPrefix(knowledgeId, documentId)}/${paragraphId}`)

/** 调整分段顺序,由服务端同步更新受影响的分段位置。 */
const putParagraphPosition = (knowledgeId: string, documentId: string, paragraphId: string, position: number) =>
put<undefined, void>(`${getPrefix(knowledgeId, documentId)}/adjust_position`, undefined, {
paragraph_id: paragraphId,
new_position: position,
})

export default {
getParagraphList,
postParagraph,
Expand All @@ -74,4 +84,6 @@ export default {
putMigrateParagraphs,
putGenerateParagraphQuestions,
putBatchDeleteParagraphs,
deleteParagraph,
putParagraphPosition,
}
2 changes: 1 addition & 1 deletion ui/src/api/types/knowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export interface KnowledgeWorkflowCreatePayload extends KnowledgeCreatePayload {

/** Web 文档分段、视觉处理和索引策略。 */
export interface DocumentStrategy {
split: { mode: 'smart' | 'advanced'; patterns: string[] | null; min_length: number; max_length: number; child_length: number; auto_clean: boolean }
split: { mode: 'smart' | 'advanced'; patterns: string[] | null; limit: number; child_length: number; auto_clean: boolean }
visual: { enabled: boolean; strategy: 'model' | 'tool'; model_id: string | null; tool_id: string | null }
index: { title_as_question: boolean }
}
Expand Down
4 changes: 4 additions & 0 deletions ui/src/api/types/paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export interface ParagraphUpdatePayload {
content: string
}

/** 保存正文或单独更新分段启用状态。 */
export type ParagraphEditPayload = Partial<ParagraphUpdatePayload & Pick<ParagraphItem, 'is_active'>>

export interface ParagraphQuery {
title?: string
content?: string
Expand All @@ -38,6 +41,7 @@ export interface ParagraphCreatePayload {
title: string
content: string
is_active: boolean
position?: number
problem_list?: { content: string }[]
}

Expand Down
23 changes: 23 additions & 0 deletions ui/src/components/global/markdown-editor/md-editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,29 @@

table {
display: block;
max-width: 100%;
overflow-x: auto;
width: fit-content;

td,
th {
max-width: calc(var(--spacing) * 100);
min-width: calc(var(--spacing) * 30);
overflow-wrap: break-word;
word-break: normal;
}

th {
white-space: nowrap;
}

tbody tr:hover {
background-color: var(--md-theme-table-tr-bg-color);
}

tbody tr:nth-child(2n):hover {
background-color: var(--md-theme-table-stripe-color);
}
}

ul {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/router/ROUTE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ Web 展示“设置 → 基础设置、文档处理策略、定时同步”;
普通 Workspace 文档分段页使用 `workspace-knowledge-paragraph`,地址为
`/admin/workspace/:workspaceId/knowledge/:knowledgeId/:type/document/:documentId`,
在 `knowledge.ts` 中与知识库详情容器同级注册,复用 Workspace AppLayout,保持知识库一级菜单激活。
页面位于 `views/knowledge-detail/paragraph/index.vue`,使用自身的分段目录,不挂载
页面位于 `views/document-detail/index.vue`,使用自身的分段目录,不挂载
`ResourceDetailLayout`。配置 `hidden` 与 `resourceDetailRoot`,使工作空间切换继续返回知识库列表;
返回按钮进入 `workspace-knowledge-document-list`,保留知识库类型和 query。
文档行点击进入分段页,选择列、名称编辑和操作按钮不触发跳转。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export const systemResourceKnowledgeRoutes: RouteRecordRaw[] = [
{
path: '/system/resource/knowledge/:knowledgeId/:type/document/:documentId',
name: 'system-resource-knowledge-paragraph',
component: () => import('@/views/knowledge-detail/paragraph/index.vue'),
component: () => import('@/views/document-detail/index.vue'),
meta: { resourceScope: 'system-resource', scope: 'system', hideSidebar: true, title: '文档分段', hidden: true, resourceDetailRoot: true },
},
]
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export const systemSharedKnowledgeRoutes: RouteRecordRaw[] = [
{
path: '/system/shared/knowledge/:knowledgeId/:type/document/:documentId',
name: 'system-shared-knowledge-paragraph',
component: () => import('@/views/knowledge-detail/paragraph/index.vue'),
component: () => import('@/views/document-detail/index.vue'),
meta: { resourceScope: 'system-shared', scope: 'system', hideSidebar: true, title: '文档分段', hidden: true, resourceDetailRoot: true },
},
]
2 changes: 1 addition & 1 deletion ui/src/router/admin/workspace/modules/knowledge-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export const sharedKnowledgeRoutes: RouteRecordRaw[] = [
{
path: 'shared/knowledge/:knowledgeId/:type/document/:documentId',
name: 'workspace-shared-knowledge-paragraph',
component: () => import('@/views/knowledge-detail/paragraph/index.vue'),
component: () => import('@/views/document-detail/index.vue'),
meta: { resourceScope: 'workspace-shared', activeMenu: 'workspace-knowledge', title: '文档分段', hidden: true, resourceDetailRoot: true },
},
]
2 changes: 1 addition & 1 deletion ui/src/router/admin/workspace/modules/knowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const knowledgeRoutes: RouteRecordRaw[] = [
{
path: ':knowledgeId/:type/document/:documentId',
name: 'workspace-knowledge-paragraph',
component: () => import('@/views/knowledge-detail/paragraph/index.vue'),
component: () => import('@/views/document-detail/index.vue'),
meta: { title: '文档分段', hidden: true, resourceDetailRoot: true },
},
],
Expand Down
9 changes: 9 additions & 0 deletions ui/src/styles/STYLE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ Admin 和 Chat 共用。组件不单独恢复焦点 `outline`,包括通过隐

这类规则会破坏 Element Plus 组件的默认间距。仅设置必要的基础规则,例如统一 `box-sizing`、清除 `body` 默认外边距和定义应用级布局。

## Markdown 表格

`src/components/global/markdown-editor/md-editor.scss` 的预览 table 样式统一维护
`.mk-markdown-editor .md-editor-preview table`,由同目录 `config.ts` 引入,
覆盖 `MdPreview` 与 `MdEditor` 的渲染预览。表格使用块级容器和 `overflow-x: auto`,
宽度限制在正文区域内,宽表格单独横向滚动,不让整段正文横向滚动。
单元格最小宽度为 120px、最大宽度为 400px,正文正常换行并允许长链接折行;表头不换行,
避免多列时标题和正文被压缩成逐字纵向排列。滚动条沿用 Markdown 主题已有样式。

## 默认字号

项目正文和大部分界面文字默认使用 `14px / 22px`(字号/行高),统一由 `variables.scss` 中的 `--mk-font-size-base` 和 `--mk-line-height-base` 提供,`body` 直接使用这两个变量。
Expand Down
22 changes: 15 additions & 7 deletions ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ Dialog。新增或重命名文件时,应同步更新所有导入和页面功
| `knowledge-detail/index.vue` | 知识库详情页面 |
| `knowledge-detail/library/tags/index.vue` | 标签分组查询、创建、重命名、单值编辑、删除与关联文档管理 |
| `knowledge-detail/workflow-transform/index.vue` | 非工作流知识库转换说明、确认与进入画布 |
| `knowledge-detail/paragraph/index.vue` | 普通 Workspace 文档分段查询、目录定位、批量操作、新增、编辑与详情 |
| `document-detail/index.vue` | 普通 Workspace 文档分段查询、目录定位、批量操作、新增、编辑与详情 |

|
| `knowledge-detail/setting/base/index.vue` | 知识库基本信息、来源配置与上传限制设置 |
Expand Down Expand Up @@ -886,29 +886,30 @@ Workspace 普通资源、System 资源管理和 System 共享资源允许打开
`MkDropdown` 单选筛选全部、成功、失败、索引中、分词索引中、排队中和生成中;查询组合
`status` 与可选的 `task_type`,切换选项清除旧任务类型并回到第一页,保留名称和创建者条件。

普通 Workspace 文档行点击进入 `knowledge-detail/paragraph/index.vue`,选择列、名称编辑及行操作
文档详情页面及其专属组件统一放在 `views/document-detail/`,与 `knowledge/`、`knowledge-detail/` 平级。
普通 Workspace 文档行点击进入 `document-detail/index.vue`,选择列、名称编辑及行操作
保留自身交互。分段页与知识库详情容器路由同级,复用 `MkViewLayout` 的顶部栏、侧栏和主区滚动;
顶部展示接口查询的文档名称、标题/内容搜索、批量选择和添加分段,侧栏按服务端位置排列全部
查询结果,点击定位正文,滚动同步高亮。正文使用 `MdPreview`;空文档展示空态。
批量选择支持点击整张卡片或复选框切换勾选、全选、取消、“迁移至”、“生成问题”和“删除”;
复选框阻止点击冒泡,避免重复切换。`paragraph/migrate/` 集中维护
复选框阻止点击冒泡,避免重复切换。`document-detail/migrate/` 集中维护
`ButtonMigrateParagraph` 和 `ParagraphMigrateDialog`,沿用 chat-log 添加知识库的知识库/文档
选择样式,保留知识库和文档图标;迁移 API 由分段页传入完整 Paragraph API 对象。
打开时固定所选分段 ID,选择知识库后查询全部文档并排除当前文档,允许迁移至同知识库其他文档。
知识库和文档必选,成功关闭动画结束后通过 `success(paragraphIds)` 返回本次迁移的固定 ID,
页面从本地列表移除对应分段、清空勾选并更新目录定位,不重新查询分段接口,失败保留表单。
`paragraph/components/ButtonGenerateQuestions.vue` 封装批量生成入口,
`document-detail/components/ButtonGenerateQuestions.vue` 封装批量生成入口,
接收页面传入的完整 Paragraph API,打开时固定知识库、文档和勾选分段。复用公共
`GenerateQuestionsDialog` 并传入 `showParagraphScope=false`,仅提交生成配置和所选分段 ID,
不传 `state_list`;请求成功关闭后重新查询当前筛选结果并清空选择,失败保留配置。
批量删除按钮和请求逻辑直接维护在 `paragraph/index.vue`,不单独拆分组件。
批量删除按钮和请求逻辑直接维护在 `document-detail/index.vue`,不单独拆分组件。
确认前固定所选分段与所属文档,确认后提交批量删除接口;成功从本地列表移除本次删除的分段、
清空勾选并更新目录定位,不重新查询分段接口。
取消或失败保留选择,确认及请求期间阻止重复操作。
`paragraph/paragraph-dialog/` 维护两个独立弹窗,以本地组件组合左右布局:
`document-detail/paragraph-dialog/` 维护两个独立弹窗,以本地组件组合左右布局:

- `CreateParagraphDialog.vue` 组合 `components/ParagraphForm.vue` 与 `components/ParagraphQuestions.vue`,
管理添加请求,底部提供取消和添加。
管理添加请求,底部提供取消和添加;`open(position?)` 可指定插入位置,默认添加到文档首位。
- `EditParagraphDialog.vue` 组合 `ParagraphForm`、`ParagraphPreview` 与 `ParagraphQuestions`,
支持 `open(paragraph, initialMode?)`,初始模式默认为 `detail`,也可传入 `edit`。
详情点击编辑进入表单;取消编辑回到原详情,保存成功回到更新后的详情。
Expand Down Expand Up @@ -936,6 +937,13 @@ Workspace 普通资源、System 资源管理和 System 共享资源允许打开
避免覆盖并行的问题操作;取消编辑不撤销即时保存的问题关联。
新增成功关闭弹窗并通知页面清空搜索、重新查询服务端排序;编辑成功通知页面刷新当前筛选结果。
分段卡片在非批量模式点击打开详情弹窗,批量模式点击切换勾选;批量生成问题继续使用 `components/ButtonGenerateQuestions.vue`。
非批量卡片右上角使用与文档导入预览相同的 sticky 悬浮操作区和白色阴影 Card,
提供启停、直接编辑及上方插入;更多菜单提供单段生成问题、迁移、移动位置与删除。
`ButtonGenerateQuestions` 和 `ButtonMigrateParagraph` 的默认插槽暴露 `open`、`disabled`,
供单段菜单复用既有流程,默认仍渲染批量按钮;更多菜单使用 `persistent` 保留其中的业务弹窗。
启停仅提交 `is_active`,成功后更新当前卡片;单段删除确认后调用独立 DELETE 接口并从本地移除。
位置菜单包含置于顶部、上移、下移、置于底部,先查询完整文档分段顺序再调整位置,
不按搜索结果计算相邻位置;调整成功后刷新当前筛选结果并保留主区滚动位置。
Workspace 共享及 System 分段路由已注册并保持来源导航;各范围分段 API 接入暂缓。

System 资源管理与共享资源已注册共用知识库详情路由,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const props = defineProps<{
disabled?: boolean
}>()
const emit = defineEmits<{ refresh: [] }>()
defineSlots<{ default?(props: { open: () => unknown; disabled: boolean }): unknown }>()

// 打开时固定本次生成问题的分段与所属文档。
const loading = ref(false)
Expand Down Expand Up @@ -69,8 +70,10 @@ function handleClosed() {
</script>

<template>
<!-- 批量生成分段关联问题 -->
<el-button type="primary" plain :disabled="disabled || loading || !paragraphIds.length" @click="handleOpenDialog">生成问题</el-button>
<slot :open="handleOpenDialog" :disabled="disabled || loading || !paragraphIds.length">
<!-- 批量生成分段关联问题 -->
<el-button type="primary" plain :disabled="disabled || loading || !paragraphIds.length" @click="handleOpenDialog">生成问题</el-button>
</slot>
<GenerateQuestionsDialog
v-if="dialogMounted"
ref="dialogRef"
Expand Down
Loading
Loading