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
17 changes: 17 additions & 0 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ Action、Drawer 或 Dialog。复用方直接使用 `typeof XxxApi` 约束完整
额外维护逐方法接口,例如 `ModelActionApi`,也不要使用不断扩展的 `Pick<typeof XxxApi, ...>`。
仅展示数据的组件不接收 API。

### 知识库维护

`workspace/knowledge/knowledge.ts` 与 `workspace/shared.ts` 的 `getAllKnowledge(query)`
分别查询工作空间及共享知识库的非分页列表,返回 `KnowledgeItem[]`,用于关联知识库选择等
需要全量选项的场景。原有 `getKnowledgePage` 继续用于分页列表。

`workspace/knowledge/knowledge.ts` 的 `putKnowledge` 更新普通知识库,`putLarkKnowledge`
更新飞书知识库;单项转移提交 `folder_id`。`putBatchMoveKnowledge` 将知识库 ID 数组和目标目录
组装为 `{ id_list, folder_id }`,`putBatchDeleteKnowledge` 将 ID 数组组装为 `{ id_list }`,
分别使用 PUT 请求 `batch_move` 和 `batch_delete`。页面和 Action 负责类型判断及 loading。

### 知识库文档标签

`workspace/knowledge/knowledge.ts` 的 `getKnowledgeTags(knowledgeIds)` 查询所选知识库的全部文档
标签,返回按标签名称分组的 `KnowledgeTagGroup[]`。工作流页面将查询方法提供给文档标签检索
节点,节点负责本地搜索和最多 100 项的展示。

## 枚举与类型组织

API 枚举与类型统一在 `src/api` 范围内管理,相关规则由本文档统一维护。
Expand Down
42 changes: 40 additions & 2 deletions ui/src/api/admin/workspace/knowledge/knowledge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { del, get } from '../../core/request'
import { del, get, post, put } from '../../core/request'
import type { ParamsPage, ResponsePage } from '../../core/types'
import type { Dict, KnowledgeItem } from '@/api/types'
import { getWorkspaceId } from '@/utils/resource-context'
Expand All @@ -8,6 +8,10 @@ const getPrefix = () => {
return `/workspace/${workspaceId}/knowledge`
}

/** 获取工作空间不分页的知识库列表。 */
const getAllKnowledge = (query?: Dict<unknown>) => {
return get<KnowledgeItem[]>(getPrefix(), query)
}
/** 获取工作空间知识库分页列表。 */
const getKnowledgePage = (page: ParamsPage, query?: Dict<unknown>) => {
return get<ResponsePage<KnowledgeItem>>(`${getPrefix()}/${page.currentPage}/${page.pageSize}`, query)
Expand All @@ -18,4 +22,38 @@ const deleteKnowledge = (knowledgeId: string) => {
return del<boolean>(`${getPrefix()}/${knowledgeId}`)
}

export default { deleteKnowledge, getKnowledgePage }
/** 更新工作空间知识库信息。 */
const putKnowledge = (knowledgeId: string, payload: Partial<KnowledgeItem>) => {
return put<Partial<KnowledgeItem>, KnowledgeItem>(`${getPrefix()}/${knowledgeId}`, payload)
}

/** 更新飞书知识库信息。 */
const putLarkKnowledge = (knowledgeId: string, payload: Partial<KnowledgeItem>) => {
return put<Partial<KnowledgeItem>, KnowledgeItem>(`${getPrefix()}/lark/${knowledgeId}`, payload)
}

/** 批量删除工作空间知识库。 */
const putBatchDeleteKnowledge = (knowledgeIds: string[]) => {
return put<{ id_list: string[] }, boolean>(`${getPrefix()}/batch_delete`, { id_list: knowledgeIds })
}

/** 批量转移工作空间知识库。 */
const putBatchMoveKnowledge = (knowledgeIds: string[], folderId: string) => {
return put<{ id_list: string[]; folder_id: string }, boolean>(`${getPrefix()}/batch_move`, { id_list: knowledgeIds, folder_id: folderId })
}

/** 导入知识库文件。 */
const importKnowledgeBundle = (payload: FormData) => {
return post<FormData, unknown>(`${getPrefix()}/import_knowledge`, payload)
}

export default {
deleteKnowledge,
getAllKnowledge,
getKnowledgePage,
putKnowledge,
putLarkKnowledge,
putBatchDeleteKnowledge,
putBatchMoveKnowledge,
importKnowledgeBundle,
}
7 changes: 6 additions & 1 deletion ui/src/api/admin/workspace/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ const getKnowledgePage = (page: ParamsPage, query?: Dict<unknown>) => {
return get<ResponsePage<KnowledgeItem>>(`${getPrefix()}/knowledge/${page.currentPage}/${page.pageSize}`, query)
}

export default { getKnowledgePage, getModelList, getToolPage, getAllTool }
/** 获取工作空间共享的不分页知识库列表。 */
const getAllKnowledge = (query?: Dict<unknown>) => {
return get<KnowledgeItem[]>(`${getPrefix()}/knowledge`, query)
}

export default { getAllKnowledge, getKnowledgePage, getModelList, getToolPage, getAllTool }
1 change: 0 additions & 1 deletion ui/src/api/enums/knowledge.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** 后端知识库类型。 */
// TODO v3不再用数字表示 待修改
export const KNOWLEDGE_TYPE = { BASE: 0, WEB: 1, LARK: 2, YUQUE: 3, WORKFLOW: 4 } as const

/** 知识库分段检索模式。 */
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 @@ -25,3 +25,9 @@ export interface KnowledgeItem {
user_id?: string | null
workspace_id: string
}

/** 按标签名称分组的知识库标签。 */
export interface KnowledgeTagGroup {
key: string
values: { id: string; value: string; create_time: string; update_time: string }[]
}
48 changes: 32 additions & 16 deletions ui/src/components/COMPONENT_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ src/components/
│ │ ├── MoveToDialog.vue
│ │ ├── VirtualizedTree.vue
│ │ └── types.ts
│ ├── knowledge-selection-dialog/
│ │ ├── index.vue # 关联知识库选择、文件夹与共享资源查询
│ │ └── types.ts # 已选知识库快照类型
│ ├── model-select/
│ ├── select-knowledge-dialog/
│ │ └── index.vue # 关联知识库选择、文件夹与共享资源查询
│ ├── select-model/
│ │ ├── index.vue # 按供应商分组的模型选择器与可选参数按钮
│ │ └── ModelParamsDialog.vue # 模型参数动态表单弹窗
│ ├── workspace-dropdown/
Expand Down Expand Up @@ -145,7 +144,7 @@ import JsonInput from '@/components/codemirror-editor/Json.vue'
import MkSourceCard from '@/components/mk-source-card/index.vue'
import FolderTree from '@/components/business/folder-tree/index.vue'
import MoveToDialog from '@/components/business/folder-tree/MoveToDialog.vue'
import ModelSelect from '@/components/business/model-select/index.vue'
import SelectModel from '@/components/business/select-model/index.vue'
import WorkspaceDropdown from '@/components/business/workspace-dropdown/index.vue'
import WorkspaceRelationTags from '@/components/business/workspace-relation-tags/index.vue'
```
Expand Down Expand Up @@ -282,6 +281,10 @@ Element Plus 使用 `ElOnlyChild` 处理浮层触发器。`el-tooltip`、`el-pop
`mt-2 text-N600` 样式;仅使用 `subtitle` 时,组件仍会按照 Element Plus 原生的标题 ID 和样式类
渲染 `title`。内容区域超出最大高度后显示滚动条。

Dialog 外壳仅在首次打开时挂载;默认在关闭动画结束、触发 `closed` 后整体卸载,
避免未打开的弹窗生成隐藏 DOM。设置 `destroy-on-close="false"` 时,首次打开后保留实例和内容。
业务侧无需额外使用 `v-if="visible"`,以免跳过关闭动画及 `closed` 清理。

```vue
<MkDialog v-model="visible" title="创建工作空间" width="600">
<template #subtitle>创建后可继续添加工作空间成员。</template>
Expand Down Expand Up @@ -514,6 +517,10 @@ Prop,未传入时读取当前路由的 `meta.title`;显式传入 `title=""`
智能体、知识库和工具的资源图标分别使用自动注册的 `ApplicationIcon`、`KnowledgeIcon` 和
`ToolIcon`。`ApplicationIcon` 在未传入 `icon` 时会回退到系统默认图标。

`KnowledgeIcon` 的 `type` 接收接口数字类型 `KnowledgeType`,内部通过
`constants/knowledge.ts` 的 `KNOWLEDGE_TYPE_MAP` 转换为字符串后选择图标。自定义 `icon`
优先;`BASE`、`YUQUE` 以及未提供或未知类型时沿用默认知识库图标。

```vue
<ApplicationIcon :icon="application.icon" :size="24" />
```
Expand Down Expand Up @@ -826,6 +833,9 @@ function validateJson(rule: unknown, value: unknown, callback: (error?: Error) =

### MkSourceCard

`disabled` 默认为 `false`;传入 `true` 时不添加 `cursor-pointer`,并将卡片 `shadow` 从
`hover` 改为 `always`。该属性仅控制卡片样式,不拦截点击或选择事件。

用于模型、工具等带来源信息的等高资源卡片。`title` 提供默认标题,`nick_name` 和 `create_time`
提供固定样式的创建信息;`subtitle` 插槽也始终应用 `text-sm text-N600`。默认插槽放置资源详情,
`footer` 插槽作为左侧常驻内容并始终贴在卡片底部;无论是否传入内容,底部都会保留固定位置。
Expand Down Expand Up @@ -1098,12 +1108,12 @@ const formValue = ref<Dict<DynamicFormValue>>({})
初始化、空配置回填和切回自定义赋值时保留一行空白选项。卡片单选仅在存在完整选项时显示默认值卡片区。
引用变量模式继续保留变量路径,不应用自定义选项过滤。

动态表单的 Model 字段使用 `ModelSelect`,将 `attrs.provider_list` 中的模型快照映射为
动态表单的 Model 字段使用 `SelectModel`,将 `attrs.provider_list` 中的模型快照映射为
扁平 `ModelItem[]`,由选择器统一分组和展示供应商。旧快照未保存状态时保留可选行为,已保存的
状态按 `ModelSelect` 的可用性规则处理。切换模型一次性回写 `model_id` 和深拷贝后的
状态按 `SelectModel` 的可用性规则处理。切换模型一次性回写 `model_id` 和深拷贝后的
`model_params_setting`;清空时回写空 ID 和空参数,避免修改原配置中的参数对象。

Model 配置器的默认模型也使用 `ModelSelect`,仅展示已选的可选模型,不开启参数设置入口。
Model 配置器的默认模型也使用 `SelectModel`,仅展示已选的可选模型,不开启参数设置入口。
选择时将模型 ID 转换为包含已配置参数的 `default_value` 对象,清空时重置为空对象。

## 跨页面业务组件
Expand Down Expand Up @@ -1148,16 +1158,22 @@ import FolderTree from '@/components/business/folder-tree/index.vue'
<MoveToDialog ref="moveToDialogRef" :loading="submitting" :source="RESOURCE_TYPE.TOOL" @submit="handleMoveFolder" />
```

### KnowledgeSelectionDialog
### SelectKnowledgeDialog

关联知识库选择弹窗,手动导入 `@/components/business/knowledge-selection-dialog/index.vue`。
关联知识库选择弹窗,手动导入 `@/components/business/select-knowledge-dialog/index.vue`。
通过 `open(knowledge)` 传入已选知识库快照,确认后通过 `submit` 返回新的选择;取消不修改调用方
数据,关闭后统一清理临时状态。`KnowledgeSelection` 类型允许仅包含 ID,以兼容缺少详情的旧数据。
组件复用只读 `FolderTree` 和 `MkInfiniteScroll` 查询工作空间及共享知识库,支持按名称搜索,
跨文件夹、搜索和分页保留选择,并限制新选知识库使用相同的 Embedding 模型。固定业务请求由
数据,关闭后统一清理临时状态。选择数据直接基于 `KnowledgeItem` 声明为
`(Partial<KnowledgeItem> & { id: string })[]`,保留必需的 ID 并兼容缺少详情的旧数据,
不再维护弹窗专用类型文件。
组件采用 `MkViewLayout` 左右布局,搜索栏位于内容区右上角,刷新位于弹窗标题栏。
选项使用紧凑三列布局(窄屏减少列数),左侧图标与省略名称、右侧复选框。点击卡片或复选框
切换选择,选中后仅展示相同 Embedding 模型的选项,清空后恢复;悬停展示知识库详情。
复用只读 `FolderTree`,通过工作空间及共享 API 的 `getAllKnowledge` 一次加载当前查询的全部
知识库,不使用滚动分页。支持按名称搜索,跨文件夹和搜索保留选择,并限制新选知识库使用
相同的 Embedding 模型。固定业务请求由
该组件负责,调用方维护最终关联 ID 和快照。

### ModelSelect
### SelectModel

按供应商分组展示模型,通过 `v-model` 控制模型 ID,并在选择变化时触发 `change`。`options` 为
`ModelItem[]`,`providerOptions` 为 `ModelProviderItem[]`,模型列表和供应商列表均由使用方查询。
Expand All @@ -1180,10 +1196,10 @@ import FolderTree from '@/components/business/folder-tree/index.vue'

```vue
<script setup lang="ts">
import ModelSelect from '@/components/business/model-select/index.vue'
import SelectModel from '@/components/business/select-model/index.vue'
</script>

<ModelSelect
<SelectModel
v-model="selectedModelId"
v-model:model-params="modelParams"
can-edit-params
Expand Down
154 changes: 0 additions & 154 deletions ui/src/components/business/knowledge-selection-dialog/index.vue

This file was deleted.

This file was deleted.

Loading
Loading