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
29 changes: 26 additions & 3 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ v3 编辑表单提交 `{ name, description }`,标题上限 64、更新说明
`system/shared-resources/knowledge/knowledge.ts` 使用 `/system/shared/knowledge`,维护分页、详情、
通用 / Web / 飞书 / 工作流创建、导入、删除、重新向量化、Web 同步、关联问题、分词索引、MCP
配置与三种导出。工作流创建在 Workspace 与 System 共享范围均由同一个 Knowledge API 的
`postKnowledgeWorkflow` 提交;`workspace/knowledge/workflow.ts` 仅维护已创建知识库的工作流
画布接口。System 共享范围没有工作空间文件夹、批量接口或独立的知识库工作流 API 文件。复用创建入口
`postKnowledgeWorkflow` 提交;工作流转换由各范围的 `knowledge.ts` 维护,
`workspace/knowledge/workflow.ts` 仅维护已创建知识库的画布接口。System 共享范围没有工作空间文件夹、批量接口或独立的知识库工作流 API 文件。复用创建入口
和卡片 Action 时使用完整 Workspace / System 资源管理 / System 共享知识库 API 的联合类型,由页面显式传入当前范围的 API。

### 工具代码生成
Expand Down Expand Up @@ -461,13 +461,16 @@ System 共享资源分别保留各自路径下的同名接口,不再重复封
或提交 `work_flow_template` 由服务端下载并覆盖当前工具工作流。模板覆盖后由 View 重新查询详情,
同步默认模型设置、保存时间和图快照;确认取消或请求失败不关闭模板中心。

### 知识库工作流模板与导出
### 知识库工作流模板与导入导出

`admin/store.ts` 的 `getStoreKnowledgeList(query)` 查询 `/workspace/store/knowledge_template`,
返回 `KnowledgeWorkflowStoreResponse`,其中 `apps` 使用公共 `WorkflowStoreTemplate[]`。
`putKnowledgeWorkflow` 接受互斥的 `work_flow` 保存载荷或 `work_flow_template` 覆盖载荷,覆盖成功后由 View 重载详情。
`exportKnowledgeWorkflow(knowledgeId, name)` 通过 GET `/<knowledgeId>/workflow/export` 下载 `.kbwf` 文件,
只导出工作流,不调用包含文档的知识库包导出接口。
`importKnowledgeWorkflow(knowledgeId, file)` 沿用 v2 的 POST `/<knowledgeId>/workflow/import`,
使用 FormData 的 `file` 字段上传 `.kbwf`,由服务端覆盖草稿、处理关联工具与默认模型设置。
接口结果不作为图数据使用,页面确认覆盖后调用,成功重新查询知识库详情并渲染画布。

### 工作空间首页

Expand Down Expand Up @@ -546,8 +549,28 @@ System 接口由资源管理服务提供;本地开源后端没有对应扩展
两种 System 工具 API 的 `getToolListWithShared` 查询各自 `/tool_list` 并合并 `tools`、`shared_tools`,
供画布的工具菜单及 MCP 选项使用。系统扩展接口需连接支持相应协议的部署进行联调。

### 知识库工作流转换

Workspace、System 资源管理及 System 共享资源的 `knowledge.ts` 提供
`postTransformWorkflow(knowledgeId, { work_flow })`,沿用 v2 的 POST
`/<knowledgeId>/transform_workflow`,各自使用对应知识库前缀,返回布尔值;
转换页通过可管理范围上下文的 `resourceApi.knowledge` 调用,不固定 Workspace API。
服务端转换知识库类型并创建工作流,
保留已有文档,已是工作流类型时拒绝重复转换。页面负责确认、loading、成功提示及进入画布。
默认图复用知识库创建模板,不用保存工作流接口代替转换。

### 知识库文档

`workspace/knowledge/document.ts` 的 `getDocumentDetail(knowledgeId, documentId)` 通过 GET
`/<knowledgeId>/document/<documentId>` 查询文档详情,支持分段页刷新和直接访问。
`workspace/knowledge/paragraph.ts` 维护普通 Workspace 文档分段接口,前缀为
`/workspace/<workspaceId>/knowledge/<knowledgeId>/document/<documentId>/paragraph`。
`getParagraphList` 查询完整分段列表,支持 `title`、`content`,服务端按 `position`、创建时间排序;
`postParagraph` 提交 `title`、`content`、`is_active`,返回新增分段,默认插入首位并触发索引。
响应及载荷类型维护在 `types/paragraph.ts`,通过 `@/api/types` 导入。
标题最多 256 字符,内容必填且最多 102400 字符;loading、弹窗和成功后刷新由页面维护。
本次只接入普通 Workspace,不为其他范围推测接口或回退 Workspace。

文档地址及飞书导入也维护在 `workspace/knowledge/document.ts`:
`postWebDocument` 向 `/<knowledgeId>/document/web` 提交 `WebDocumentImportPayload`,包含
`source_url_list`、`selector` 与 `doc_strategy`。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { del, get, getExportFile, put } from '@/api/admin/core/request'
import { del, get, getExportFile, post, put } from '@/api/admin/core/request'
import type LogicFlow from '@logicflow/core'
import type { ParamsPage, ResponsePage } from '@/api/admin/core/types'
import type { Dict, KnowledgeDetail, KnowledgeItem, KnowledgeGeneratePayload, KnowledgeSyncType } from '@/api/types'

Expand Down Expand Up @@ -67,7 +68,12 @@ const getKnowledgeMcpConfig = (knowledgeId: string): Promise<string> =>
/** 提交知识库分词索引任务。 */
const putKnowledgeKeywordIndex = (knowledgeId: string) => put<undefined, void>(`${prefix}/${knowledgeId}/tokenize`)

/** 将系统资源管理知识库转换为工作流知识库,保留已有文档。 */
const postTransformWorkflow = (knowledgeId: string, payload: { work_flow: LogicFlow.GraphConfigData }) =>
post<{ work_flow: LogicFlow.GraphConfigData }, boolean>(`${prefix}/${knowledgeId}/transform_workflow`, payload)

export default {
postTransformWorkflow,
putKnowledgeKeywordIndex,
exportKnowledgeExcel,
exportKnowledgeZip,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { del, get, getExportFile, post, put } from '@/api/admin/core/request'
import type LogicFlow from '@logicflow/core'
import type { ParamsPage, ResponsePage } from '@/api/admin/core/types'
import type {
Dict,
Expand Down Expand Up @@ -83,7 +84,12 @@ const getKnowledgeMcpConfig = (knowledgeId: string): Promise<string> =>
/** 提交知识库分词索引任务。 */
const putKnowledgeKeywordIndex = (knowledgeId: string) => put<undefined, void>(`${prefix}/${knowledgeId}/tokenize`)

/** 将系统共享知识库转换为工作流知识库,保留已有文档。 */
const postTransformWorkflow = (knowledgeId: string, payload: { work_flow: LogicFlow.GraphConfigData }) =>
post<{ work_flow: LogicFlow.GraphConfigData }, boolean>(`${prefix}/${knowledgeId}/transform_workflow`, payload)

export default {
postTransformWorkflow,
deleteKnowledge,
exportKnowledge,
exportKnowledgeExcel,
Expand Down
4 changes: 4 additions & 0 deletions ui/src/api/admin/workspace/knowledge/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const getPrefix = (knowledgeId: string) => `/workspace/${getWorkspaceId()}/knowl
const getDocumentPage = (knowledgeId: string, page: ParamsPage, query?: Dict<unknown>) =>
get<ResponsePage<DocumentItem>>(`${getPrefix(knowledgeId)}/${page.currentPage}/${page.pageSize}`, query)

/** 获取单个文档详情,支持直接访问分段页。 */
const getDocumentDetail = (knowledgeId: string, documentId: string) => get<DocumentItem>(`${getPrefix(knowledgeId)}/${documentId}`)

/** 批量创建空白文档或导入text文档。 */
const putBatchCreateDocuments = (knowledgeId: string, documents: DocumentQuickCreatePayload[] | DocumentImportPayload[]) =>
put<DocumentQuickCreatePayload[] | DocumentImportPayload[], DocumentItem[]>(`${getPrefix(knowledgeId)}/batch_create`, documents)
Expand Down Expand Up @@ -171,6 +174,7 @@ const putUnlinkTagDocuments = (knowledgeId: string, tagId: string, documentIds:
put(`/workspace/${getWorkspaceId()}/knowledge/${knowledgeId}/tag/${tagId}/docs_delete`, { id_list: documentIds })

export default {
getDocumentDetail,
getDocumentTags,
postAddDocumentTags,
putDeleteDocumentTags,
Expand Down
6 changes: 6 additions & 0 deletions ui/src/api/admin/workspace/knowledge/knowledge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { del, get, getExportFile, post, put } from '../../core/request'
import type LogicFlow from '@logicflow/core'
import type { ParamsPage, ResponsePage } from '../../core/types'
import type {
Dict,
Expand Down Expand Up @@ -125,6 +126,10 @@ const getKnowledgeMcpConfig = (knowledgeId: string): Promise<string> =>
/** 提交知识库分词索引任务。 */
const putKnowledgeKeywordIndex = (knowledgeId: string) => put<undefined, void>(`${getPrefix()}/${knowledgeId}/tokenize`)

/** 将现有知识库转换为工作流知识库,保留已有文档。 */
const postTransformWorkflow = (knowledgeId: string, payload: { work_flow: LogicFlow.GraphConfigData }) =>
post<{ work_flow: LogicFlow.GraphConfigData }, boolean>(`${getPrefix()}/${knowledgeId}/transform_workflow`, payload)

/** 获取知识库按标签名称分组的标签选项。 */

// TODO
Expand Down Expand Up @@ -153,4 +158,5 @@ export default {
putBatchDeleteKnowledge,
putBatchMoveKnowledge,
postKnowledgeImport,
postTransformWorkflow,
}
16 changes: 16 additions & 0 deletions ui/src/api/admin/workspace/knowledge/paragraph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { get, post } from '../../core/request'
import type { ParagraphCreatePayload, ParagraphItem, ParagraphQuery } from '@/api/types'
import { getWorkspaceId } from '@/utils/resource-context'

const getPrefix = (knowledgeId: string, documentId: string) =>
`/workspace/${getWorkspaceId()}/knowledge/${knowledgeId}/document/${documentId}/paragraph`

/** 查询文档的全部分段,按位置排序,支持标题和内容筛选。 */
const getParagraphList = (knowledgeId: string, documentId: string, query?: ParagraphQuery) =>
get<ParagraphItem[]>(getPrefix(knowledgeId, documentId), { ...query })

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

export default { getParagraphList, postParagraph }
8 changes: 8 additions & 0 deletions ui/src/api/admin/workspace/knowledge/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ const postCancelKnowledgeWorkflowAction = (knowledgeId: string, actionId: string
/** 导出知识库工作流文件,不包含知识库文档。 */
const exportKnowledgeWorkflow = (knowledgeId: string, name: string) => getExportFile(`${name}.kbwf`, `${getPrefix()}/${knowledgeId}/workflow/export`)

/** 导入知识库工作流文件,覆盖当前草稿并由服务端处理关联工具。 */
const importKnowledgeWorkflow = (knowledgeId: string, file: File) => {
const payload = new FormData()
payload.append('file', file)
return post<FormData, boolean | void>(`${getPrefix()}/${knowledgeId}/workflow/import`, payload)
}

/** 获取知识库发布历史,按发布时间倒序返回完整版本快照。 */
const getWorkflowVersions = (knowledgeId: string) => get<WorkflowVersion[]>(`${getPrefix()}/${knowledgeId}/knowledge_version`)

Expand All @@ -72,6 +79,7 @@ const getKnowledgeExecutionRecordPage = (knowledgeId: string, page: ParamsPage,
get<ResponsePage<KnowledgeExecutionRecord>>(`${getPrefix()}/${knowledgeId}/action/${page.currentPage}/${page.pageSize}`, query)

export default {
importKnowledgeWorkflow,
getKnowledgeExecutionRecordPage,
getWorkflowVersions,
putWorkflowVersion,
Expand Down
1 change: 1 addition & 0 deletions ui/src/api/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ export type * from './state'
export type * from './portal'

export type * from './document'
export type * from './paragraph'
export type * from './chat-log'
22 changes: 22 additions & 0 deletions ui/src/api/types/paragraph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/** 文档分段的查询响应与新增载荷。 */
export interface ParagraphItem {
id: string
document_id: string
title: string | null
content: string
position: number
is_active: boolean
create_time: string
update_time: string
}

export interface ParagraphQuery {
title?: string
content?: string
}

export interface ParagraphCreatePayload {
title: string
content: string
is_active: boolean
}
Binary file added ui/src/assets/workflow/workflow-demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion ui/src/components/COMPONENT_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ Dialog、Drawer、Popover、嵌套区域等其他大、小表格均禁止开启
`footer-batch-actions` 插槽,当前选择通过 `selection-change` 返回。组件暴露 `tableRef` 和
`clearSelection()`。操作栏与 `MkViewLayout` 复用 `LayoutBatchFooter`,统一全选、半选、数量和
取消行为;它在主内容滚动区域内吸附于页面底部,不随表格内容滚出可视区域。
分页表格暂不支持跨页勾选,翻页或切换每页条数时统一清空选择,选择列不配置 `reserve-selection`。
非分页表格不受此限制,可按数据刷新、搜索和懒加载需求保留选择。

`selectionGroupKey` 可按需开启同组选择,接受字段路径或返回字符串/数字的函数;不传时保持
原生逐行选择。点击复选框时,同步当前 `data` 中同组记录的选中或取消状态,遵守选择列的
Expand Down Expand Up @@ -1006,7 +1008,7 @@ Skills 场景传入 `[TOOL_TYPE.SKILL]`,并通过 `title` 指定标题。两
缺少时不挂载授权列表。`closed` 在关闭动画结束、临时状态清理后触发;当前没有对外 `refresh` 事件。

默认“按用户组”,支持名称搜索及查看成员;“按用户”支持姓名、用户名、权限及商业版本角色搜索。
两者支持跨页选择、单项和批量配置,搜索清空选择;切换标签重新挂载,保存期间禁止切换。
两者支持当前页选择、单项和批量配置,翻页和搜索清空选择;切换标签重新挂载,保存期间禁止切换。
入口统一提交,成功后关闭配置弹窗并刷新当前列表,失败保留配置。
根目录隐藏“不授权”,已有该值按“查看”展示;包含子资源时传入完整文件夹子树,
按资源所属工作空间筛选可管理的文件夹 ID,无可管理目录时禁用该范围。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const emit = defineEmits<{ configure: [subjectIds: string[], permission?: Resour
/* 根目录不提供“不授权”,按“查看”展示接口返回的该权限。 */
const canSelectNotAuth = computed(() => props.permissionOptions.some(({ value }) => value === RESOURCE_PERMISSION.NOT_AUTH))

/* 查询与跨页选择 */
/* 查询与当前页选择 */
const { auth } = useStore()
const searchPermissionOptions = computed(() => RESOURCE_PERMISSION_OPTIONS.filter(({ value }) => !auth.isCE || value !== RESOURCE_PERMISSION.ROLE))
const searchFields = computed(() => [
Expand Down Expand Up @@ -114,7 +114,7 @@ onMounted(() => loadPermissions())
@size-change="loadPermissions"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="40" reserve-selection />
<el-table-column type="selection" width="40" />
<el-table-column prop="nick_name" label="姓名" min-width="120" show-overflow-tooltip />
<el-table-column prop="username" label="用户名" min-width="120" show-overflow-tooltip />
<el-table-column v-if="auth.isEE || auth.isPE" label="角色" width="160">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const emit = defineEmits<{ configure: [subjectIds: string[], permission?: Resour
/* 根目录不提供“不授权”,按“查看”展示接口返回的该权限。 */
const canSelectNotAuth = computed(() => props.permissionOptions.some(({ value }) => value === RESOURCE_PERMISSION.NOT_AUTH))

/* 查询与跨页选择 */
/* 查询与当前页选择 */
const searchFields = [{ label: '名称', value: 'name' }]
const loading = ref(false)
const permissionGroups = ref<ResourceUserGroupPermission[]>([])
Expand Down Expand Up @@ -116,7 +116,7 @@ onMounted(() => loadPermissions())
@size-change="loadPermissions"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="40" reserve-selection />
<el-table-column type="selection" width="40" />
<el-table-column prop="name" label="用户组" min-width="160" show-overflow-tooltip />
<el-table-column label="成员数" min-width="100">
<template #default="{ row }">
Expand Down
2 changes: 2 additions & 0 deletions ui/src/components/global/mk-table/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ function handleCurrentPageChange(currentPage: number) {
return
}

clearSelection()
emit('update:paginationConfig', { ...props.paginationConfig, currentPage })
emit('current-change', currentPage)
}
Expand All @@ -142,6 +143,7 @@ function handlePageSizeChange(pageSize: number) {
return
}

clearSelection()
emit('update:paginationConfig', { ...props.paginationConfig, currentPage: 1, pageSize })
emit('size-change', pageSize)
}
Expand Down
16 changes: 13 additions & 3 deletions ui/src/router/ROUTE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Chat 导航守卫(`chat/index.ts`):
| `resourceScope` | `'workspace' \| 'workspace-shared' \| 'system-resource' \| 'system-shared'` | 标记页面使用的资源范围,由对应资源父路由配置并向下继承 |
| `activeIcon` | `string` | 菜单激活状态的 iconfont Symbol ID |
| `activeMenu` | `string` | 进入子页面时需要保持激活的侧栏菜单路径 |
| `resourceDetailRoot` | `boolean` | 标记资源详情导航根,仅在详情容器路由自身配置 |
| `resourceDetailRoot` | `boolean` | 标记资源详情根,详情容器和独立文档分段页配置,用于目录与工作空间切换 |
| `detailActiveMenu` | `string` | 更深层详情页面需要保持激活的二级菜单路由名称 |
| `title` | `string` | 页面标题,同时作为导航名称 |
| `icon` | `string` | iconfont Symbol ID,子目录通常可以不配置 |
Expand Down Expand Up @@ -404,8 +404,18 @@ Web 展示“设置 → 基础设置、文档处理策略、定时同步”;
列表设置按钮按知识库类型直接进入通用设置或基础设置。
`workspace-knowledge-settings` 仅提供菜单分组层级,
命名访问时重定向到基础设置,保留参数、query 和 hash。`workflow-entry`
仅作为目录跳转入口,重定向到独立的 `workflow-knowledge` 全屏画布。画布返回知识库详情。
文档详情路由当前尚未启用;后续接入时通过 `detailActiveMenu` 高亮“文档”。
(`workspace-knowledge-workflow`)直接挂载 `knowledge-detail/workflow-transform/index.vue`,
保留“工作流”菜单。路由 `beforeEnter` 按 `type` 参数判断:工作流类型重定向至独立的
`workflow-knowledge` 全屏画布,其他类型挂载转换页。转换成功后进入画布;直接访问画布时也查询真实
知识库类型,非工作流类型先返回转换页。画布返回知识库详情。
普通 Workspace 文档分段页使用 `workspace-knowledge-paragraph`,地址为
`/admin/workspace/:workspaceId/knowledge/:knowledgeId/:type/document/:documentId`,
在 `knowledge.ts` 中与知识库详情容器同级注册,复用 Workspace AppLayout,保持知识库一级菜单激活。
页面位于 `views/knowledge-detail/paragraph/index.vue`,使用自身的分段目录,不挂载
`ResourceDetailLayout`。配置 `hidden` 与 `resourceDetailRoot`,使工作空间切换继续返回知识库列表;
返回按钮进入 `workspace-knowledge-document-list`,保留知识库类型和 query。
文档行点击进入分段页,选择列、名称编辑和操作按钮不触发跳转。
Workspace 共享及 System 文档分段入口暂未注册,等待各范围接口接入,不回退普通 Workspace。

智能体工作流返回通过 `views/workflow/application/navigation.ts` 动态读取详情父路由的 `children`。
Workspace 父路由为 `workspace-application-detail-layout`;System 详情实现时使用
Expand Down
Loading
Loading