Skip to content

Commit 8a3583f

Browse files
committed
feat: system shared knoeledge
1 parent 7be572a commit 8a3583f

27 files changed

Lines changed: 395 additions & 97 deletions

‎ui/src/api/API_README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,15 @@ v3 编辑表单提交 `{ name, description }`,标题上限 64、更新说明
170170
共享工具 API 不提供工作空间文件夹移动或批量接口;复用卡片、Action 和表单接收完整 Workspace
171171
与 System 共享 API 的联合类型,不补造接口以匹配 Workspace 方法集合。
172172

173+
### System 共享知识库
174+
175+
`system/shared-resources/knowledge/knowledge.ts` 使用 `/system/shared/knowledge`,维护分页、详情、
176+
通用 / Web / 飞书 / 工作流创建、导入、删除、重新向量化、Web 同步、关联问题、分词索引、MCP
177+
配置与三种导出。工作流创建在 Workspace 与 System 共享范围均由同一个 Knowledge API 的
178+
`postKnowledgeWorkflow` 提交;`workspace/knowledge/workflow.ts` 仅维护已创建知识库的工作流
179+
画布接口。System 共享范围没有工作空间文件夹、批量接口或独立的知识库工作流 API 文件。复用创建入口
180+
和卡片 Action 时使用完整 Workspace / System 资源管理 / System 共享知识库 API 的联合类型,由页面显式传入当前范围的 API。
181+
173182
### 工具代码生成
174183

175184
三个范围的 `tool/tool.ts` 均提供 `postToolGenerateCode(payload)`,沿用 v2 的
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { del, get, getExportFile, post, put } from '@/api/admin/core/request'
2+
import type { ParamsPage, ResponsePage } from '@/api/admin/core/types'
3+
import type {
4+
Dict,
5+
KnowledgeCreatePayload,
6+
KnowledgeDetail,
7+
KnowledgeGeneratePayload,
8+
KnowledgeItem,
9+
KnowledgeSyncType,
10+
KnowledgeWorkflowCreatePayload,
11+
LarkKnowledgeCreatePayload,
12+
WebKnowledgeCreatePayload,
13+
} from '@/api/types'
14+
15+
const prefix = '/system/shared/knowledge'
16+
17+
/** 获取 System 共享知识库分页列表。 */
18+
const getKnowledgePage = (page: ParamsPage, query?: Dict<unknown>) => {
19+
return get<ResponsePage<KnowledgeItem>>(`${prefix}/${page.currentPage}/${page.pageSize}`, query)
20+
}
21+
22+
/** 获取 System 共享知识库详情。 */
23+
const getKnowledgeDetail = (knowledgeId: string) => get<KnowledgeDetail>(`${prefix}/${knowledgeId}`)
24+
25+
/** 创建 System 共享通用知识库。 */
26+
const postKnowledge = (payload: KnowledgeCreatePayload) => post<KnowledgeCreatePayload, KnowledgeItem>(`${prefix}/base`, payload)
27+
28+
/** 创建 System 共享 Web 知识库。 */
29+
const postWebKnowledge = (payload: WebKnowledgeCreatePayload) => post<WebKnowledgeCreatePayload, KnowledgeItem>(`${prefix}/web`, payload)
30+
31+
/** 创建 System 共享飞书知识库。 */
32+
const postLarkKnowledge = (payload: LarkKnowledgeCreatePayload) => post<LarkKnowledgeCreatePayload, KnowledgeItem>(`${prefix}/lark/save`, payload)
33+
34+
/** 创建 System 共享工作流知识库。 */
35+
const postKnowledgeWorkflow = (payload: KnowledgeWorkflowCreatePayload) =>
36+
post<KnowledgeWorkflowCreatePayload, KnowledgeItem>(`${prefix}/workflow`, payload)
37+
38+
/** 导入知识库压缩包并创建 System 共享知识库。 */
39+
const postKnowledgeImport = (file: File, folderId: string) => {
40+
const payload = new FormData()
41+
payload.append('file', file)
42+
payload.append('folder_id', folderId)
43+
return post<FormData, { knowledge_id: string; type: KnowledgeItem['type'] }>(`${prefix}/import_knowledge`, payload)
44+
}
45+
46+
/** 更新 System 共享知识库信息。 */
47+
const putKnowledge = (knowledgeId: string, payload: Partial<KnowledgeItem>) =>
48+
put<Partial<KnowledgeItem>, KnowledgeItem>(`${prefix}/${knowledgeId}`, payload)
49+
50+
/** 删除 System 共享知识库。 */
51+
const deleteKnowledge = (knowledgeId: string) => del<boolean>(`${prefix}/${knowledgeId}`)
52+
53+
/** 根据知识库中的分段生成关联问题。 */
54+
const putGenerateKnowledgeQuestions = (knowledgeId: string, payload: KnowledgeGeneratePayload) => {
55+
return put(`${prefix}/${knowledgeId}/generate_related`, payload)
56+
}
57+
58+
/** 对知识库中的文档重新向量化。 */
59+
const putReEmbeddingKnowledge = (knowledgeId: string) => put<undefined, boolean>(`${prefix}/${knowledgeId}/embedding`)
60+
61+
/** 同步 System 共享 Web 知识库。 */
62+
const putSyncWebKnowledge = (knowledgeId: string, syncType: KnowledgeSyncType) => {
63+
return put<undefined, boolean>(`${prefix}/${knowledgeId}/sync`, undefined, { sync_type: syncType })
64+
}
65+
66+
/** 将知识库文档导出为 Excel。 */
67+
const exportKnowledgeExcel = (knowledgeId: string, knowledgeName: string) => getExportFile(`${knowledgeName}.xlsx`, `${prefix}/${knowledgeId}/export`)
68+
69+
/** 将知识库文档及图片导出为 ZIP。 */
70+
const exportKnowledgeZip = (knowledgeId: string, knowledgeName: string) =>
71+
getExportFile(`${knowledgeName}.zip`, `${prefix}/${knowledgeId}/export_zip`)
72+
73+
/** 导出可用于导入创建的知识库压缩包。 */
74+
const exportKnowledge = (knowledgeId: string, knowledgeName: string) =>
75+
getExportFile(`${knowledgeName}.zip`, `${prefix}/${knowledgeId}/export_knowledge`)
76+
77+
/** 获取知识库外部检索服务生成的 MCP 连接配置。 */
78+
const getKnowledgeMcpConfig = (knowledgeId: string): Promise<string> =>
79+
get<{ mcp_config: Record<string, unknown> }>(`${prefix}/${knowledgeId}/external_service`).then(({ mcp_config }) =>
80+
JSON.stringify(mcp_config, null, 2),
81+
)
82+
83+
/** 提交知识库分词索引任务。 */
84+
const putKnowledgeKeywordIndex = (knowledgeId: string) => put<undefined, void>(`${prefix}/${knowledgeId}/tokenize`)
85+
86+
export default {
87+
deleteKnowledge,
88+
exportKnowledge,
89+
exportKnowledgeExcel,
90+
exportKnowledgeZip,
91+
getKnowledgeDetail,
92+
getKnowledgeMcpConfig,
93+
getKnowledgePage,
94+
postKnowledge,
95+
postKnowledgeImport,
96+
postKnowledgeWorkflow,
97+
postLarkKnowledge,
98+
postWebKnowledge,
99+
putGenerateKnowledgeQuestions,
100+
putKnowledge,
101+
putKnowledgeKeywordIndex,
102+
putReEmbeddingKnowledge,
103+
putSyncWebKnowledge,
104+
}

‎ui/src/api/admin/workspace/knowledge/knowledge.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
KnowledgeGeneratePayload,
99
KnowledgeSyncType,
1010
KnowledgeCreatePayload,
11+
KnowledgeWorkflowCreatePayload,
1112
WebKnowledgeCreatePayload,
1213
LarkKnowledgeCreatePayload,
1314
} from '@/api/types'
@@ -47,6 +48,11 @@ const postLarkKnowledge = (payload: LarkKnowledgeCreatePayload) => {
4748
return post<LarkKnowledgeCreatePayload, KnowledgeItem>(`${getPrefix()}/lark/save`, payload)
4849
}
4950

51+
/** 创建工作流知识库。 */
52+
const postKnowledgeWorkflow = (payload: KnowledgeWorkflowCreatePayload) => {
53+
return post<KnowledgeWorkflowCreatePayload, KnowledgeItem>(`${getPrefix()}/workflow`, payload)
54+
}
55+
5056
/** 删除工作空间知识库。 */
5157
const deleteKnowledge = (knowledgeId: string) => {
5258
return del<boolean>(`${getPrefix()}/${knowledgeId}`)
@@ -132,6 +138,7 @@ export default {
132138
postKnowledge,
133139
postWebKnowledge,
134140
postLarkKnowledge,
141+
postKnowledgeWorkflow,
135142
deleteKnowledge,
136143
getAllKnowledge,
137144
getKnowledgeDetail,

‎ui/src/api/admin/workspace/knowledge/workflow.ts‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import { get, post, put, getExportFile } from '../../core/request'
44
import type {
55
DefaultModelSettingPayload,
66
Dict,
7-
KnowledgeItem,
87
KnowledgeExecutionRecord,
9-
KnowledgeCreatePayload,
10-
KnowledgeWorkflowTemplate,
118
KnowledgeWorkflowAction,
129
KnowledgeWorkflowDebugPayload,
1310
KnowledgeWorkflowDetail,
@@ -21,21 +18,11 @@ type KnowledgeWorkflowPayload =
2118
| { default_model_setting?: DefaultModelSettingPayload; work_flow: LogicFlow.GraphConfigData; work_flow_template?: never }
2219
| { work_flow_template: WorkflowStoreTemplate; work_flow?: never }
2320

24-
interface CreateKnowledgeWorkflowPayload extends KnowledgeCreatePayload {
25-
work_flow: LogicFlow.GraphConfigData
26-
work_flow_template?: KnowledgeWorkflowTemplate
27-
}
28-
2921
const getPrefix = () => {
3022
const workspaceId = getWorkspaceId()
3123
return `/workspace/${workspaceId}/knowledge`
3224
}
3325

34-
/** 创建工作流知识库。 */
35-
const postKnowledgeWorkflow = (payload: CreateKnowledgeWorkflowPayload) => {
36-
return post<CreateKnowledgeWorkflowPayload, KnowledgeItem>(`${getPrefix()}/workflow`, payload)
37-
}
38-
3926
/** 保存知识库工作流。 */
4027
const putKnowledgeWorkflow = (knowledgeId: string, payload: KnowledgeWorkflowPayload) => {
4128
return put<KnowledgeWorkflowPayload, KnowledgeWorkflowDetail>(`${getPrefix()}/${knowledgeId}/workflow`, payload)
@@ -85,7 +72,6 @@ export default {
8572
getWorkflowVersions,
8673
putWorkflowVersion,
8774
exportKnowledgeWorkflow,
88-
postKnowledgeWorkflow,
8975
putKnowledgeWorkflow,
9076
putKnowledgeWorkflowPublish,
9177
getKnowledgeWorkflowFormList,

‎ui/src/api/types/knowledge.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ export interface KnowledgeCreatePayload {
104104
type: KnowledgeType
105105
}
106106

107+
/** 创建工作流知识库的请求参数。 */
108+
export interface KnowledgeWorkflowCreatePayload extends KnowledgeCreatePayload {
109+
work_flow: LogicFlow.GraphConfigData
110+
work_flow_template?: KnowledgeWorkflowTemplate
111+
}
112+
107113
/** Web 文档分段、视觉处理和索引策略。 */
108114
export interface DocumentStrategy {
109115
split: { mode: 'smart' | 'advanced'; patterns: string[] | null; min_length: number; max_length: number; child_length: number; auto_clean: boolean }

‎ui/src/router/ROUTE_README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ System 共享资源页面:
255255
/admin/system/share/tools
256256
```
257257

258-
`system-shared-tools` 渲染 `views/system/shared-resources/tool/index.vue`,提供共享工具管理页面。
258+
`system-shared-knowledge` 渲染 `views/system/shared-resources/knowledge/index.vue`,提供共享知识库
259+
卡片管理页面;`system-shared-tools` 渲染 `views/system/shared-resources/tool/index.vue`,提供共享工具管理页面。
259260

260261
共享资源路由是 System 导航的一部分,继续在 `admin/system/index.ts` 的 `share` 子路由中维护。
261262
已实现的共享资源页面放在 `views/system/shared-resources/`,由页面处理 System 范围的查询和操作,

‎ui/src/router/admin/system/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export const systemRoutes: RouteRecordRaw = {
200200
{
201201
path: 'knowledge',
202202
name: 'system-shared-knowledge',
203-
component: () => import('@/views/system/index.vue'),
203+
component: () => import('@/views/system/shared-resources/knowledge/index.vue'),
204204
meta: { title: '知识库', order: 10, permission: perm.knowledge.share.read, next: 'system-shared-tools' },
205205
},
206206

‎ui/src/views/VIEW_README.md‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ src/views/knowledge/
214214
```
215215

216216
`KnowledgeCard` 只负责展示、选择状态和 `action-dropdown` 插槽;页面传入完整 Knowledge API,
217-
组合单项转移、删除 Action,并管理批量选择、全选、批量转移与批量删除。共享知识库不展示这些操作。
217+
组合单项转移、删除 Action,并管理批量选择、全选、批量转移与批量删除。工作空间共享知识库保持只读,
218+
不传操作插槽并传入 `disabled`;System 共享知识库页传入 `shared`、不传 `disabled`,保留共享标识,
219+
并组合同步、向量化、生成问题、分词索引、MCP 配置、关联资源、导出及删除等菜单操作。
218220
`GenerateQuestionsAction` 在非共享知识库菜单提供“生成问题”,复用公共
219221
`GenerateQuestionsDialog`,打开时固定知识库 ID,提交知识库生成接口;共用页面 loading,
220222
成功提示并关闭,失败保留表单。不新增权限判断。
@@ -257,7 +259,10 @@ MCP 配置沿用工具的只读文本与悬浮复制交互,专属弹窗按需
257259
通过 `isSystemResource()`、`isSystemSharedResource()` 判断,供应商继续使用共用 Provider API。
258260

259261
`ButtonCreateKnowledge` 内聚四类创建浮层 Ref 和打开动作,列表页传入目标 `folderId`,通过
260-
`refresh` 刷新列表。入口支持 `trigger` 插槽替换默认创建按钮,下拉使用 `persistent`。
262+
`refresh` 刷新列表。入口支持 `trigger` 插槽替换默认创建按钮,下拉使用 `persistent`。默认使用
263+
Workspace 知识库 API;System 共享知识库页传入完整 System 共享知识库 API,创建、导入与工作流创建
264+
均不读取工作空间 ID。创建入口及模板中心只接收一个完整 Knowledge API,工作流创建也使用该对象的
265+
`postKnowledgeWorkflow`;已创建知识库的工作流画布接口仍由 `workspace/knowledge/workflow.ts` 维护。
261266
各创建浮层接收 `folderId`,通过 `open()` 打开;工作流额外接受可选的商店模板。共用的
262267
`KnowledgeBaseForm` 负责名称、描述、Embedding 模型必填校验以及工作空间和共享模型查询,
263268
根据 `isSystemSharedResource()` 选择 System 共享 Model API 或 Workspace Model API,
@@ -267,7 +272,8 @@ MCP 配置沿用工具的只读文本与悬浮复制交互,专属弹窗按需
267272
刷新选项不覆盖用户选择或设置页回填的模型。
268273
创建前校验表单,提交期间禁止重复提交和关闭;成功后刷新用户基础资料并通知列表刷新,
269274
普通类型将接口返回的 `knowledge.type` 通过 `KNOWLEDGE_TYPE_MAP` 转为字符串后进入文档列表,工作流进入画布。常驻弹窗在关闭动画结束后清理表单,打开时只回填本次模板与显示,工作流模板使用
270-
`cloneDeep` 隔离;创建流程使用 Workspace API,不通过路由字符串推测 System 范围。
275+
`cloneDeep` 隔离;创建流程默认使用 Workspace API,不通过路由字符串推测 System 范围;System
276+
共享页通过入口显式传入对应 API,创建成功后仅刷新共享列表,不进入工作空间详情或工作流路由。
271277
飞书创建沿用扩展接口 `/lark/save`,部署环境需要提供该接口。
272278
“导入创建”沿用智能体和工具的菜单文件选择交互,调用 `postKnowledgeImport` 上传文件及当前
273279
`folderId`,导入成功后先刷新用户基础资料,再通知知识库列表刷新。上传期间禁止重复导入,
@@ -382,6 +388,8 @@ Action 放入 `views/system/shared-resources/<card-name>/action-dropdown/`。Act
382388

383389
```text
384390
src/views/system/shared-resources/
391+
├── knowledge/
392+
│ └── index.vue
385393
├── model/
386394
│ └── index.vue
387395
└── tool/
@@ -395,6 +403,12 @@ src/views/system/shared-resources/
395403
共享页开启工作流创建,创建后进入 `system-shared-workflow-tool`。共享页支持普通工具、Skills、MCP、数据源及
396404
导入创建,工作流卡片点击进入画布(支持 Ctrl / Command 新标签页),编辑菜单仍修改基础信息。共享页不组合工作空间专用的移动、授权和触发器入口。
397405

406+
`KnowledgeSharedView` 使用 System 共享知识库 API,复用 `KnowledgeCard`、创建入口和模板中心。
407+
卡片点击绑定页面的 `handleOpenKnowledge`,详情路由暂未接入,方法内保留 `router.push` 的 TODO。
408+
创建、模板创建和导入均使用 System 共享接口;Web 同步、向量化、关联问题、分词索引、
409+
MCP 配置、关联资源、导出与删除通过复用 Action 组合,授权工作空间暂保留 TODO,不组合工作空间专用的设置、
410+
文件夹移动或批量操作。
411+
398412
System 用户页面按业务流程归拢操作入口和专属 Dialog。入口组件管理弹窗 Ref、打开动作并转发
399413
`refresh`;列表页负责查询、批量选择和刷新策略,创建与编辑共用的 `UserFromDrawer` 仍由页面管理。
400414

‎ui/src/views/knowledge/components/ButtonCreateKnowledge.vue‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { computed, ref, useTemplateRef, type CSSProperties } from 'vue'
33
import type { UploadFile, UploadInstance } from 'element-plus'
44
import KnowledgeApi from '@/api/admin/workspace/knowledge/knowledge'
5+
import type SystemSharedKnowledgeApi from '@/api/admin/system/shared-resources/knowledge/knowledge'
56
import { KNOWLEDGE_TYPE } from '@/api/enums'
67
import { useStore } from '@/stores'
78
import { MsgSuccess } from '@/utils/message'
@@ -14,13 +15,14 @@ defineOptions({ name: 'ButtonCreateKnowledge' })
1415
1516
const props = withDefaults(
1617
defineProps<{
18+
api?: typeof KnowledgeApi | typeof SystemSharedKnowledgeApi
1719
folderId: string
1820
trigger?: 'click' | 'hover' | 'contextmenu'
1921
popperStyle?: CSSProperties
2022
popperClass?: string
2123
fitTriggerWidth?: boolean
2224
}>(),
23-
{ trigger: 'click', fitTriggerWidth: false },
25+
{ api: () => KnowledgeApi, trigger: 'click', fitTriggerWidth: false },
2426
)
2527
const { auth } = useStore()
2628
@@ -76,7 +78,7 @@ const importing = ref(false)
7678
function handleImportCreate(file: UploadFile) {
7779
if (!file.raw || importing.value) return
7880
importing.value = true
79-
return KnowledgeApi.postKnowledgeImport(file.raw, props.folderId)
81+
return props.api.postKnowledgeImport(file.raw, props.folderId)
8082
.then(() => {
8183
// 先刷新新资源权限,再通知列表加载导入的知识库。
8284
return auth.loadAuthBaseProfile().then(() => {
@@ -164,8 +166,8 @@ function handleImportCreate(file: UploadFile) {
164166
</template>
165167
</MkDropdown>
166168

167-
<CreateBaseKnowledgeDialog ref="createBaseKnowledgeDialogRef" :folder-id="folderId" @refresh="emit('refresh')" />
168-
<CreateWebKnowledgeDrawer ref="createWebKnowledgeDrawerRef" :folder-id="folderId" @refresh="emit('refresh')" />
169-
<CreateLarkKnowledgeDialog ref="createLarkKnowledgeDialogRef" :folder-id="folderId" @refresh="emit('refresh')" />
170-
<CreateWorkflowKnowledgeDialog ref="createWorkflowKnowledgeDialogRef" :folder-id="folderId" @refresh="emit('refresh')" />
169+
<CreateBaseKnowledgeDialog ref="createBaseKnowledgeDialogRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
170+
<CreateWebKnowledgeDrawer ref="createWebKnowledgeDrawerRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
171+
<CreateLarkKnowledgeDialog ref="createLarkKnowledgeDialogRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
172+
<CreateWorkflowKnowledgeDialog ref="createWorkflowKnowledgeDialogRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
171173
</template>

‎ui/src/views/knowledge/components/ButtonTemplateStore.vue‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
<script setup lang="ts">
22
import { nextTick, ref, useTemplateRef } from 'vue'
33
import StoreApi from '@/api/admin/store'
4+
import KnowledgeApi from '@/api/admin/workspace/knowledge/knowledge'
5+
import type SystemSharedKnowledgeApi from '@/api/admin/system/shared-resources/knowledge/knowledge'
46
import type { WorkflowStoreTemplate } from '@/api/types'
57
import TemplateStoreDialog from '@/views/workflow/components/template-store/TemplateStoreDialog.vue'
68
import WorkflowKnowledgeDialog from '../create-knowledge/WorkflowKnowledgeDialog.vue'
79
import { MsgError } from '@/utils/message'
810
911
defineOptions({ name: 'ButtonTemplateStore' })
10-
const props = defineProps<{ folderId: string }>()
12+
const props = withDefaults(
13+
defineProps<{ api?: typeof KnowledgeApi | typeof SystemSharedKnowledgeApi; folderId: string }>(),
14+
{ api: () => KnowledgeApi },
15+
)
1116
const templateStoreDialogRef = useTemplateRef<InstanceType<typeof TemplateStoreDialog>>('templateStoreDialogRef')
1217
const emit = defineEmits<{ refresh: [] }>()
1318
@@ -71,6 +76,7 @@ function handleCreated() {
7176
<WorkflowKnowledgeDialog
7277
v-if="createDialogMounted"
7378
ref="createDialogRef"
79+
:api="api"
7480
:folder-id="targetFolderId"
7581
@closed="createDialogMounted = false"
7682
@refresh="handleCreated"

0 commit comments

Comments
 (0)