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
9 changes: 9 additions & 0 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ v3 编辑表单提交 `{ name, description }`,标题上限 64、更新说明
共享工具 API 不提供工作空间文件夹移动或批量接口;复用卡片、Action 和表单接收完整 Workspace
与 System 共享 API 的联合类型,不补造接口以匹配 Workspace 方法集合。

### System 共享知识库

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

### 工具代码生成

三个范围的 `tool/tool.ts` 均提供 `postToolGenerateCode(payload)`,沿用 v2 的
Expand Down
104 changes: 104 additions & 0 deletions ui/src/api/admin/system/shared-resources/knowledge/knowledge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { del, get, getExportFile, post, put } from '@/api/admin/core/request'
import type { ParamsPage, ResponsePage } from '@/api/admin/core/types'
import type {
Dict,
KnowledgeCreatePayload,
KnowledgeDetail,
KnowledgeGeneratePayload,
KnowledgeItem,
KnowledgeSyncType,
KnowledgeWorkflowCreatePayload,
LarkKnowledgeCreatePayload,
WebKnowledgeCreatePayload,
} from '@/api/types'

const prefix = '/system/shared/knowledge'

/** 获取 System 共享知识库分页列表。 */
const getKnowledgePage = (page: ParamsPage, query?: Dict<unknown>) => {
return get<ResponsePage<KnowledgeItem>>(`${prefix}/${page.currentPage}/${page.pageSize}`, query)
}

/** 获取 System 共享知识库详情。 */
const getKnowledgeDetail = (knowledgeId: string) => get<KnowledgeDetail>(`${prefix}/${knowledgeId}`)

/** 创建 System 共享通用知识库。 */
const postKnowledge = (payload: KnowledgeCreatePayload) => post<KnowledgeCreatePayload, KnowledgeItem>(`${prefix}/base`, payload)

/** 创建 System 共享 Web 知识库。 */
const postWebKnowledge = (payload: WebKnowledgeCreatePayload) => post<WebKnowledgeCreatePayload, KnowledgeItem>(`${prefix}/web`, payload)

/** 创建 System 共享飞书知识库。 */
const postLarkKnowledge = (payload: LarkKnowledgeCreatePayload) => post<LarkKnowledgeCreatePayload, KnowledgeItem>(`${prefix}/lark/save`, payload)

/** 创建 System 共享工作流知识库。 */
const postKnowledgeWorkflow = (payload: KnowledgeWorkflowCreatePayload) =>
post<KnowledgeWorkflowCreatePayload, KnowledgeItem>(`${prefix}/workflow`, payload)

/** 导入知识库压缩包并创建 System 共享知识库。 */
const postKnowledgeImport = (file: File, folderId: string) => {
const payload = new FormData()
payload.append('file', file)
payload.append('folder_id', folderId)
return post<FormData, { knowledge_id: string; type: KnowledgeItem['type'] }>(`${prefix}/import_knowledge`, payload)
}

/** 更新 System 共享知识库信息。 */
const putKnowledge = (knowledgeId: string, payload: Partial<KnowledgeItem>) =>
put<Partial<KnowledgeItem>, KnowledgeItem>(`${prefix}/${knowledgeId}`, payload)

/** 删除 System 共享知识库。 */
const deleteKnowledge = (knowledgeId: string) => del<boolean>(`${prefix}/${knowledgeId}`)

/** 根据知识库中的分段生成关联问题。 */
const putGenerateKnowledgeQuestions = (knowledgeId: string, payload: KnowledgeGeneratePayload) => {
return put(`${prefix}/${knowledgeId}/generate_related`, payload)
}

/** 对知识库中的文档重新向量化。 */
const putReEmbeddingKnowledge = (knowledgeId: string) => put<undefined, boolean>(`${prefix}/${knowledgeId}/embedding`)

/** 同步 System 共享 Web 知识库。 */
const putSyncWebKnowledge = (knowledgeId: string, syncType: KnowledgeSyncType) => {
return put<undefined, boolean>(`${prefix}/${knowledgeId}/sync`, undefined, { sync_type: syncType })
}

/** 将知识库文档导出为 Excel。 */
const exportKnowledgeExcel = (knowledgeId: string, knowledgeName: string) => getExportFile(`${knowledgeName}.xlsx`, `${prefix}/${knowledgeId}/export`)

/** 将知识库文档及图片导出为 ZIP。 */
const exportKnowledgeZip = (knowledgeId: string, knowledgeName: string) =>
getExportFile(`${knowledgeName}.zip`, `${prefix}/${knowledgeId}/export_zip`)

/** 导出可用于导入创建的知识库压缩包。 */
const exportKnowledge = (knowledgeId: string, knowledgeName: string) =>
getExportFile(`${knowledgeName}.zip`, `${prefix}/${knowledgeId}/export_knowledge`)

/** 获取知识库外部检索服务生成的 MCP 连接配置。 */
const getKnowledgeMcpConfig = (knowledgeId: string): Promise<string> =>
get<{ mcp_config: Record<string, unknown> }>(`${prefix}/${knowledgeId}/external_service`).then(({ mcp_config }) =>
JSON.stringify(mcp_config, null, 2),
)

/** 提交知识库分词索引任务。 */
const putKnowledgeKeywordIndex = (knowledgeId: string) => put<undefined, void>(`${prefix}/${knowledgeId}/tokenize`)

export default {
deleteKnowledge,
exportKnowledge,
exportKnowledgeExcel,
exportKnowledgeZip,
getKnowledgeDetail,
getKnowledgeMcpConfig,
getKnowledgePage,
postKnowledge,
postKnowledgeImport,
postKnowledgeWorkflow,
postLarkKnowledge,
postWebKnowledge,
putGenerateKnowledgeQuestions,
putKnowledge,
putKnowledgeKeywordIndex,
putReEmbeddingKnowledge,
putSyncWebKnowledge,
}
7 changes: 7 additions & 0 deletions ui/src/api/admin/workspace/knowledge/knowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
KnowledgeGeneratePayload,
KnowledgeSyncType,
KnowledgeCreatePayload,
KnowledgeWorkflowCreatePayload,
WebKnowledgeCreatePayload,
LarkKnowledgeCreatePayload,
} from '@/api/types'
Expand Down Expand Up @@ -47,6 +48,11 @@ const postLarkKnowledge = (payload: LarkKnowledgeCreatePayload) => {
return post<LarkKnowledgeCreatePayload, KnowledgeItem>(`${getPrefix()}/lark/save`, payload)
}

/** 创建工作流知识库。 */
const postKnowledgeWorkflow = (payload: KnowledgeWorkflowCreatePayload) => {
return post<KnowledgeWorkflowCreatePayload, KnowledgeItem>(`${getPrefix()}/workflow`, payload)
}

/** 删除工作空间知识库。 */
const deleteKnowledge = (knowledgeId: string) => {
return del<boolean>(`${getPrefix()}/${knowledgeId}`)
Expand Down Expand Up @@ -132,6 +138,7 @@ export default {
postKnowledge,
postWebKnowledge,
postLarkKnowledge,
postKnowledgeWorkflow,
deleteKnowledge,
getAllKnowledge,
getKnowledgeDetail,
Expand Down
14 changes: 0 additions & 14 deletions ui/src/api/admin/workspace/knowledge/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { get, post, put, getExportFile } from '../../core/request'
import type {
DefaultModelSettingPayload,
Dict,
KnowledgeItem,
KnowledgeExecutionRecord,
KnowledgeCreatePayload,
KnowledgeWorkflowTemplate,
KnowledgeWorkflowAction,
KnowledgeWorkflowDebugPayload,
KnowledgeWorkflowDetail,
Expand All @@ -21,21 +18,11 @@ type KnowledgeWorkflowPayload =
| { default_model_setting?: DefaultModelSettingPayload; work_flow: LogicFlow.GraphConfigData; work_flow_template?: never }
| { work_flow_template: WorkflowStoreTemplate; work_flow?: never }

interface CreateKnowledgeWorkflowPayload extends KnowledgeCreatePayload {
work_flow: LogicFlow.GraphConfigData
work_flow_template?: KnowledgeWorkflowTemplate
}

const getPrefix = () => {
const workspaceId = getWorkspaceId()
return `/workspace/${workspaceId}/knowledge`
}

/** 创建工作流知识库。 */
const postKnowledgeWorkflow = (payload: CreateKnowledgeWorkflowPayload) => {
return post<CreateKnowledgeWorkflowPayload, KnowledgeItem>(`${getPrefix()}/workflow`, payload)
}

/** 保存知识库工作流。 */
const putKnowledgeWorkflow = (knowledgeId: string, payload: KnowledgeWorkflowPayload) => {
return put<KnowledgeWorkflowPayload, KnowledgeWorkflowDetail>(`${getPrefix()}/${knowledgeId}/workflow`, payload)
Expand Down Expand Up @@ -85,7 +72,6 @@ export default {
getWorkflowVersions,
putWorkflowVersion,
exportKnowledgeWorkflow,
postKnowledgeWorkflow,
putKnowledgeWorkflow,
putKnowledgeWorkflowPublish,
getKnowledgeWorkflowFormList,
Expand Down
6 changes: 6 additions & 0 deletions ui/src/api/types/knowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ export interface KnowledgeCreatePayload {
type: KnowledgeType
}

/** 创建工作流知识库的请求参数。 */
export interface KnowledgeWorkflowCreatePayload extends KnowledgeCreatePayload {
work_flow: LogicFlow.GraphConfigData
work_flow_template?: KnowledgeWorkflowTemplate
}

/** Web 文档分段、视觉处理和索引策略。 */
export interface DocumentStrategy {
split: { mode: 'smart' | 'advanced'; patterns: string[] | null; min_length: number; max_length: number; child_length: number; auto_clean: boolean }
Expand Down
3 changes: 2 additions & 1 deletion ui/src/router/ROUTE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ System 共享资源页面:
/admin/system/share/tools
```

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

共享资源路由是 System 导航的一部分,继续在 `admin/system/index.ts` 的 `share` 子路由中维护。
已实现的共享资源页面放在 `views/system/shared-resources/`,由页面处理 System 范围的查询和操作,
Expand Down
2 changes: 1 addition & 1 deletion ui/src/router/admin/system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export const systemRoutes: RouteRecordRaw = {
{
path: 'knowledge',
name: 'system-shared-knowledge',
component: () => import('@/views/system/index.vue'),
component: () => import('@/views/system/shared-resources/knowledge/index.vue'),
meta: { title: '知识库', order: 10, permission: perm.knowledge.share.read, next: 'system-shared-tools' },
},

Expand Down
20 changes: 17 additions & 3 deletions ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ src/views/knowledge/
```

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

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

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

`KnowledgeSharedView` 使用 System 共享知识库 API,复用 `KnowledgeCard`、创建入口和模板中心。
卡片点击绑定页面的 `handleOpenKnowledge`,详情路由暂未接入,方法内保留 `router.push` 的 TODO。
创建、模板创建和导入均使用 System 共享接口;Web 同步、向量化、关联问题、分词索引、
MCP 配置、关联资源、导出与删除通过复用 Action 组合,授权工作空间暂保留 TODO,不组合工作空间专用的设置、
文件夹移动或批量操作。

System 用户页面按业务流程归拢操作入口和专属 Dialog。入口组件管理弹窗 Ref、打开动作并转发
`refresh`;列表页负责查询、批量选择和刷新策略,创建与编辑共用的 `UserFromDrawer` 仍由页面管理。

Expand Down
14 changes: 8 additions & 6 deletions ui/src/views/knowledge/components/ButtonCreateKnowledge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { computed, ref, useTemplateRef, type CSSProperties } from 'vue'
import type { UploadFile, UploadInstance } from 'element-plus'
import KnowledgeApi from '@/api/admin/workspace/knowledge/knowledge'
import type SystemSharedKnowledgeApi from '@/api/admin/system/shared-resources/knowledge/knowledge'
import { KNOWLEDGE_TYPE } from '@/api/enums'
import { useStore } from '@/stores'
import { MsgSuccess } from '@/utils/message'
Expand All @@ -14,13 +15,14 @@ defineOptions({ name: 'ButtonCreateKnowledge' })

const props = withDefaults(
defineProps<{
api?: typeof KnowledgeApi | typeof SystemSharedKnowledgeApi
folderId: string
trigger?: 'click' | 'hover' | 'contextmenu'
popperStyle?: CSSProperties
popperClass?: string
fitTriggerWidth?: boolean
}>(),
{ trigger: 'click', fitTriggerWidth: false },
{ api: () => KnowledgeApi, trigger: 'click', fitTriggerWidth: false },
)
const { auth } = useStore()

Expand Down Expand Up @@ -76,7 +78,7 @@ const importing = ref(false)
function handleImportCreate(file: UploadFile) {
if (!file.raw || importing.value) return
importing.value = true
return KnowledgeApi.postKnowledgeImport(file.raw, props.folderId)
return props.api.postKnowledgeImport(file.raw, props.folderId)
.then(() => {
// 先刷新新资源权限,再通知列表加载导入的知识库。
return auth.loadAuthBaseProfile().then(() => {
Expand Down Expand Up @@ -164,8 +166,8 @@ function handleImportCreate(file: UploadFile) {
</template>
</MkDropdown>

<CreateBaseKnowledgeDialog ref="createBaseKnowledgeDialogRef" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateWebKnowledgeDrawer ref="createWebKnowledgeDrawerRef" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateLarkKnowledgeDialog ref="createLarkKnowledgeDialogRef" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateWorkflowKnowledgeDialog ref="createWorkflowKnowledgeDialogRef" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateBaseKnowledgeDialog ref="createBaseKnowledgeDialogRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateWebKnowledgeDrawer ref="createWebKnowledgeDrawerRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateLarkKnowledgeDialog ref="createLarkKnowledgeDialogRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
<CreateWorkflowKnowledgeDialog ref="createWorkflowKnowledgeDialogRef" :api="api" :folder-id="folderId" @refresh="emit('refresh')" />
</template>
8 changes: 7 additions & 1 deletion ui/src/views/knowledge/components/ButtonTemplateStore.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<script setup lang="ts">
import { nextTick, ref, useTemplateRef } from 'vue'
import StoreApi from '@/api/admin/store'
import KnowledgeApi from '@/api/admin/workspace/knowledge/knowledge'
import type SystemSharedKnowledgeApi from '@/api/admin/system/shared-resources/knowledge/knowledge'
import type { WorkflowStoreTemplate } from '@/api/types'
import TemplateStoreDialog from '@/views/workflow/components/template-store/TemplateStoreDialog.vue'
import WorkflowKnowledgeDialog from '../create-knowledge/WorkflowKnowledgeDialog.vue'
import { MsgError } from '@/utils/message'

defineOptions({ name: 'ButtonTemplateStore' })
const props = defineProps<{ folderId: string }>()
const props = withDefaults(
defineProps<{ api?: typeof KnowledgeApi | typeof SystemSharedKnowledgeApi; folderId: string }>(),
{ api: () => KnowledgeApi },
)
const templateStoreDialogRef = useTemplateRef<InstanceType<typeof TemplateStoreDialog>>('templateStoreDialogRef')
const emit = defineEmits<{ refresh: [] }>()

Expand Down Expand Up @@ -71,6 +76,7 @@ function handleCreated() {
<WorkflowKnowledgeDialog
v-if="createDialogMounted"
ref="createDialogRef"
:api="api"
:folder-id="targetFolderId"
@closed="createDialogMounted = false"
@refresh="handleCreated"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { ref, useTemplateRef } from 'vue'
import { KNOWLEDGE_TYPE_MAP } from '@/constants/knowledge'
import { useRoute, useRouter } from 'vue-router'
import KnowledgeApi from '@/api/admin/workspace/knowledge/knowledge'
import type SystemSharedKnowledgeApi from '@/api/admin/system/shared-resources/knowledge/knowledge'
import { KNOWLEDGE_TYPE } from '@/api/enums'
import { useStore } from '@/stores'
import { MsgSuccess } from '@/utils/message'
import KnowledgeBaseForm from './components/KnowledgeBaseForm.vue'

defineOptions({ name: 'CreateBaseKnowledgeDialog' })
const props = defineProps<{ folderId: string }>()
const props = defineProps<{ api: typeof KnowledgeApi | typeof SystemSharedKnowledgeApi; folderId: string }>()
const emit = defineEmits<{ refresh: [] }>()
const { auth } = useStore()
const route = useRoute()
Expand Down Expand Up @@ -37,7 +38,7 @@ function submit() {
.then((validationResults) => {
if (!validationResults.every(Boolean) || !baseFormRef.value) return
const baseForm = baseFormRef.value.form
return KnowledgeApi.postKnowledge({
return props.api.postKnowledge({
name: baseForm.name.trim(),
desc: baseForm.desc.trim(),
embedding_model_id: baseForm.embedding_model_id,
Expand Down
Loading
Loading