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
2 changes: 2 additions & 0 deletions ui/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ Keep these behaviors:
why the current implementation exists. If the requested change is likely to remove a requirement
or introduce a regression, pause before editing, explain the risk, recommend a safer approach,
and wait for confirmation.
- 表单创建、保存和提交使用页面/弹窗内容 loading 或按钮 loading,不逐项禁用表单字段;
详细规则见 `src/views/VIEW_README.md`。
- Keep UI code typed and data-driven.
- Use Lodash `cloneDeep` for deep cloning; do not use `structuredClone`.
- Explicitly import APIs used from Vue, Vue Router, and Pinia; do not restore API auto import.
Expand Down
20 changes: 19 additions & 1 deletion ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ API 枚举与类型统一在 `src/api` 范围内管理,相关规则由本文
`TOOL_TYPE` 从 `@/api/enums` 导入,`ToolType` 从 `@/api/types` 导入。

触发器参数来源、间隔单位和请求字段类型直接在对应接口字段中声明字符串联合类型,
不单独导出运行时枚举;表单选项使用对应字符串值。触发周期继续复用 `TRIGGER_SCHEDULE_TYPE`。
不单独导出运行时枚举;表单选项使用对应字符串值。触发周期继续复用 `SCHEDULE_TYPE`。

新增或移动类型时按以下顺序判断:

Expand Down Expand Up @@ -617,3 +617,21 @@ Workspace 共享知识库详情由 `resourceScope: 'workspace-shared'` 选择上

Web 知识库创建的 `WebKnowledgeCreatePayload.doc_strategy` 使用公共 `DocumentStrategy` 类型,
包含 `split`、`visual` 和 `index`,字段与后端文档处理策略协议一致。

Web 知识库详情及更新响应的顶层 `doc_strategy` 使用 `DocumentStrategy | null`,由
`KnowledgeItem` 声明;非 Web 类型返回 null。文档处理策略设置通过 `putKnowledge` 仅提交
`{ doc_strategy }`,服务端合并到知识库 meta,保留其他来源配置,保存不立即发起同步。

### 知识库定时同步

下列接口定义暂时保留,`setting/scheduled-sync/` 页面尚不调用查询、保存或日志接口。

`workspace/knowledge/sync.ts` 提供 `getKnowledgeSyncSetting`、`putKnowledgeSyncSetting`,
分别通过 GET、PUT `/<knowledgeId>/sync_setting` 查询和保存 Web、飞书及工作流知识库同步设置。
`KnowledgeSyncSetting` 定义在 `types/knowledge-sync.ts`,包含 `enabled`、`schedule_type`、
`sync_type` 及当前周期的时间、日期、间隔或 Cron 字段;`time` 为 HH:mm 数组,
每周日期为 1–7,每月日期为 1–31。服务端校验至少 5 分钟的频率,保存不立即发起同步。
`getKnowledgeSyncLogPage(knowledgeId, page)` 查询 `/<knowledgeId>/sync_log/<currentPage>/<pageSize>`,
使用 `ResponsePage<KnowledgeSyncLog>`,返回文档计数、消息、四种执行状态、毫秒及秒数耗时,
包含手动和定时任务。周期类型统一复用 `enums/schedule.ts` 的 `SCHEDULE_TYPE`,
触发器、长期记忆及知识库同步共享同一协议值;日志状态仍维护在 `enums/knowledge.ts`,均经 `@/api/enums` 导入。
19 changes: 19 additions & 0 deletions ui/src/api/admin/workspace/knowledge/sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { get, put } from '../../core/request'
import type { ParamsPage, ResponsePage } from '../../core/types'
import type { KnowledgeSyncLog, KnowledgeSyncSetting } from '@/api/types'
import { getWorkspaceId } from '@/utils/resource-context'

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

/** 获取知识库定时同步设置。 */
const getKnowledgeSyncSetting = (knowledgeId: string) => get<KnowledgeSyncSetting>(`${getPrefix(knowledgeId)}/sync_setting`)

/** 保存知识库定时同步设置。 */
const putKnowledgeSyncSetting = (knowledgeId: string, setting: KnowledgeSyncSetting) =>
put<KnowledgeSyncSetting, KnowledgeSyncSetting>(`${getPrefix(knowledgeId)}/sync_setting`, setting)

/** 获取知识库同步日志分页。 */
const getKnowledgeSyncLogPage = (knowledgeId: string, page: ParamsPage) =>
get<ResponsePage<KnowledgeSyncLog>>(`${getPrefix(knowledgeId)}/sync_log/${page.currentPage}/${page.pageSize}`)

export default { getKnowledgeSyncSetting, putKnowledgeSyncSetting, getKnowledgeSyncLogPage }
1 change: 1 addition & 0 deletions ui/src/api/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './resource-authorization'
export * from './tool'
export * from './knowledge'
export * from './trigger'
export * from './schedule'
export * from './file'
export * from './state'

Expand Down
2 changes: 2 additions & 0 deletions ui/src/api/enums/schedule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** 触发器、长期记忆和知识库定时同步共用的周期类型。 */
export const SCHEDULE_TYPE = { DAILY: 'daily', WEEKLY: 'weekly', MONTHLY: 'monthly', INTERVAL: 'interval', CRON: 'cron' } as const
3 changes: 0 additions & 3 deletions ui/src/api/enums/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@ export const TRIGGER_TYPE = {
SCHEDULED: 'SCHEDULED',
EVENT: 'EVENT',
} as const

/** 定时触发周期。 */
export const TRIGGER_SCHEDULE_TYPE = { DAILY: 'daily', WEEKLY: 'weekly', MONTHLY: 'monthly', INTERVAL: 'interval', CRON: 'cron' } as const
1 change: 1 addition & 0 deletions ui/src/api/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type * from './resource-authorization'
export type * from './folder'
export type * from './tool'
export type * from './knowledge'
export type * from './knowledge-sync'
export type * from './trigger'
export type * from './related-resources'
export type * from './workflow-version'
Expand Down
34 changes: 34 additions & 0 deletions ui/src/api/types/knowledge-sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { SCHEDULE_TYPE } from '@/api/enums'
import type { KnowledgeSyncType } from './knowledge'

export type KnowledgeSyncScheduleType = (typeof SCHEDULE_TYPE)[keyof typeof SCHEDULE_TYPE]

/** 知识库定时同步设置,时间为 HH:mm,周日期使用 1(周一)至 7(周日)。 */
export interface KnowledgeSyncSetting {
enabled: boolean
schedule_type: KnowledgeSyncScheduleType
sync_type: KnowledgeSyncType
time?: string[]
days?: number[]
interval_unit?: 'minutes' | 'hours'
interval_value?: number
cron_expression?: string
}

/** 知识库同步执行日志,涵盖手动与定时任务。 */
export interface KnowledgeSyncLog {
id: string
create_time: string
update_time: string
sync_type: KnowledgeSyncType
trigger_type: 'manual' | 'scheduled'
status: boolean
total_count: number
synced_count: number
skipped_count: number
deleted_count: number
failed_count: number
duration_ms: number
duration_seconds: number
message: string
}
1 change: 1 addition & 0 deletions ui/src/api/types/knowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface KnowledgeItem {
char_length?: number | null
create_time?: string
desc?: string | null
doc_strategy?: DocumentStrategy | null
document_count?: number | null
embedding_model_id?: string | null
file_count_limit?: number
Expand Down
4 changes: 2 additions & 2 deletions ui/src/api/types/trigger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { State } from './state'
import type { RESOURCE_TYPE, TRIGGER_SCHEDULE_TYPE, TRIGGER_TYPE } from '@/api/enums'
import type { RESOURCE_TYPE, SCHEDULE_TYPE, TRIGGER_TYPE } from '@/api/enums'

export type TriggerType = (typeof TRIGGER_TYPE)[keyof typeof TRIGGER_TYPE]

Expand Down Expand Up @@ -44,7 +44,7 @@ export interface TriggerBodyField {
required?: boolean
}
export interface TriggerSetting {
schedule_type?: (typeof TRIGGER_SCHEDULE_TYPE)[keyof typeof TRIGGER_SCHEDULE_TYPE]
schedule_type?: (typeof SCHEDULE_TYPE)[keyof typeof SCHEDULE_TYPE]
interval_unit?: 'minutes' | 'hours'
interval_value?: number
days?: (number | string)[]
Expand Down
6 changes: 5 additions & 1 deletion ui/src/constants/CONSTANT_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ const knowledgeTypeLabel = KNOWLEDGE_TYPE_LABELS[knowledgeType]
`resource-authorization.ts` 的 `RESOURCE_PERMISSION_OPTIONS` 统一维护权限标签和说明;
资源授权页面与资源用户授权抽屉按版本和根目录约束筛选选项。

`trigger.ts` 的 `TRIGGER_SCHEDULE_OPTIONS` 统一提供触发器与长期记忆的周期级联选项,
`knowledge.ts` 的 `KNOWLEDGE_SYNC_OPTIONS` 统一维护增量同步、替换同步和整体同步的值、文案及说明,
手动同步弹窗与定时同步设置直接复用,日志同步方式标签也从这些选项读取。

`schedule.ts` 的 `SCHEDULE_OPTION` 统一提供触发器、长期记忆与知识库定时同步的周期级联选项,
包含周期文案、执行时间和间隔数值;使用方只读,配置回填与校验仍由各自组件维护。
周期类型统一使用 `api/enums/schedule.ts` 的 `SCHEDULE_TYPE`,经 `@/api/enums` 导入。

`state.ts` 的 `EXECUTION_STATUS_OPTIONS` 维护触发器、工具和知识库工作流执行记录共用的
中文文案与图标类型,仅包含 `PENDING`、`STARTED`、`SUCCESS`、`FAILURE`、`REVOKE`、
Expand Down
9 changes: 8 additions & 1 deletion ui/src/constants/knowledge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KNOWLEDGE_TYPE } from '@/api/enums'
import { KNOWLEDGE_TYPE, KNOWLEDGE_SYNC_TYPE } from '@/api/enums'
import type { KnowledgeType } from '@/api/types'

/** 前端知识库类型标识。 */
Expand All @@ -24,3 +24,10 @@ export const KNOWLEDGE_TYPE_LABELS = {
[KNOWLEDGE_TYPE_KEY.LARK]: '飞书类型',
[KNOWLEDGE_TYPE_KEY.WORKFLOW]: '工作流类型',
} as const satisfies Record<(typeof KNOWLEDGE_TYPE_MAP)[KnowledgeType], string>

/** 手动同步与定时同步共用的同步方式选项。 */
export const KNOWLEDGE_SYNC_OPTIONS = [
{ value: KNOWLEDGE_SYNC_TYPE.INCREMENTAL, label: '增量同步', description: '文档内容无更新时跳过,有更新时则更新文档的分段' },
{ value: KNOWLEDGE_SYNC_TYPE.REPLACE, label: '替换同步', description: '重新获取 Web 站点文档,替换本地知识库中相同URL的文档' },
{ value: KNOWLEDGE_SYNC_TYPE.COMPLETE, label: '整体同步', description: '先删除知识库中所有文档,重新从Web站点获取文档' },
] as const
14 changes: 7 additions & 7 deletions ui/src/constants/trigger.ts → ui/src/constants/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import type { CascaderOption } from 'element-plus'
import { TRIGGER_SCHEDULE_TYPE } from '@/api/enums'
import { SCHEDULE_TYPE } from '@/api/enums'

const scheduleTimes = Array.from({ length: 24 }, (_, hour) => {
const time = `${String(hour).padStart(2, '0')}:00`
return { label: time, value: time }
})
/** 触发器与长期记忆共用的周期级联选项;使用方只读。 */
export const TRIGGER_SCHEDULE_OPTIONS: CascaderOption[] = [
{ label: '每日', value: TRIGGER_SCHEDULE_TYPE.DAILY, children: scheduleTimes },
/** 触发器、长期记忆与知识库定时同步共用的周期级联选项;使用方只读。 */
export const SCHEDULE_OPTION: CascaderOption[] = [
{ label: '每日', value: SCHEDULE_TYPE.DAILY, children: scheduleTimes },
{
label: '每周',
value: TRIGGER_SCHEDULE_TYPE.WEEKLY,
value: SCHEDULE_TYPE.WEEKLY,
children: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'].map((label, index) => ({ label, value: index + 1, children: scheduleTimes })),
},
{
label: '每月',
value: TRIGGER_SCHEDULE_TYPE.MONTHLY,
value: SCHEDULE_TYPE.MONTHLY,
children: Array.from({ length: 31 }, (_, index) => ({ label: `${index + 1} 日`, value: String(index + 1), children: scheduleTimes })),
},
{
label: '按间隔',
value: TRIGGER_SCHEDULE_TYPE.INTERVAL,
value: SCHEDULE_TYPE.INTERVAL,
children: [
{
label: '小时',
Expand Down
2 changes: 1 addition & 1 deletion ui/src/layout/sidebar/ResourceDetailMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ watch(
</script>

<template>
<div class="space-y-1 px-4">
<div class="space-y-1 px-4 pb-3">
<template v-for="menuItem in props.menuItems" :key="menuItem.name">
<!-- 展开或收起菜单分组 -->
<MkCollapse
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 @@ -355,7 +355,8 @@ Web 展示“设置 → 基础设置、文档处理策略、定时同步”;
`/setting/base`、`/setting/document-strategy`、`/setting/scheduled-sync`,路由名分别为
`workspace-knowledge-base-setting`、`workspace-knowledge-document-strategy`、
`workspace-knowledge-scheduled-sync`。基础设置与通用设置复用
`knowledge-detail/setting/base/index.vue` 和容器提供的详情,其他两个设置页暂为占位。
`knowledge-detail/setting/base/index.vue` 和容器提供的详情。文档处理策略页复用
`DocumentStrategyForm` 回填及保存策略,定时同步页提供同步设置与分页日志。
设置路由不配置类型访问守卫,菜单显隐由 `detailMenuVisible` 控制。
列表设置按钮按知识库类型直接进入通用设置或基础设置。
`workspace-knowledge-settings` 仅提供菜单分组层级,
Expand Down
30 changes: 25 additions & 5 deletions ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

## 放置规则

- 创建、保存或提交表单时,使用页面/弹窗内容容器的 loading 遮罩,或仅使用提交按钮的 loading,
不使用 `el-form.disabled` 或给每个字段、子表单逐项传入提交状态的 `disabled`。
方法入口保留重复提交保护,关闭、取消及步骤切换仍可按提交状态禁用;权限、只读、字段联动和
选项加载等业务禁用条件继续保留,不与提交 loading 混用。

- 当前新增功能暂不接入前端权限判断,包括按权限隐藏入口、禁用控件或拦截操作,等待用户明确
指令后再增加。已有功能的权限逻辑不随新功能开发移除;导入或创建后的用户资料刷新继续保留。
- `views/<feature>/` 是页面功能边界。每个独立功能页面使用自己的目录,路由页面和该页面专用
Expand Down Expand Up @@ -454,8 +459,8 @@ Dialog。新增或重命名文件时,应同步更新所有导入和页面功
| `knowledge/index.vue` | 工作空间知识库目录与知识库卡片页面 |
| `knowledge-detail/index.vue` | 知识库详情页面 |
| `knowledge-detail/setting/base/index.vue` | 知识库基本信息、来源配置与上传限制设置 |
| `knowledge-detail/setting/document-strategy/index.vue` | Web 知识库文档处理策略占位页面 |
| `knowledge-detail/setting/scheduled-sync/index.vue` | Web、飞书与工作流知识库定时同步占位页面 |
| `knowledge-detail/setting/document-strategy/index.vue` | Web 知识库文档处理策略回填、校验与保存 |
| `knowledge-detail/setting/scheduled-sync/index.vue` | Web、飞书与工作流知识库定时同步设置与日志 |
| `login/index.vue` | Admin 登录页面 |
| `login/forgot-password/index.vue` | 忘记密码页面 |
| `model/index.vue` | 工作空间模型目录与模型卡片页面 |
Expand Down Expand Up @@ -547,7 +552,7 @@ Dialog。新增或重命名文件时,应同步更新所有导入和页面功
通过 `open(version)` 回填;`mode="publish"` 显示“发布内容”,通过 `open()` 打开空白表单。通过
`submit(payload)` 提交、`close()` 关闭,外部传入 `saving`。标题必填且最多 64 字,更新说明最多
1000 字,标题拒绝纯空白;两种模式的提交按钮均显示“发布”。编辑请求由业务组件执行,
不创建新发布;提交期间禁止编辑表单和关闭弹窗。
不创建新发布;提交期间使用表单内容 loading 遮罩,保留关闭保护,不设置表单 disabled。
`DescriptionDialog.vue` 通过 `open(content)` 展示纯文本更新说明并保留换行,空内容显示
“暂无更新说明”。两个弹窗均不依赖业务 API,复用 `MkDialog` 的延迟挂载和关闭销毁能力。

Expand Down Expand Up @@ -703,8 +708,23 @@ Workspace API 内部通过 `getWorkspaceId()` 读取当前路由工作空间。
更新容器数据,同步名称等展示。基本信息复用创建流程的 `KnowledgeBaseForm`,类型配置和校验留在
`setting/base/index.vue` 中,通用知识库标题为“设置”,其他类型为“基础设置”。
通用知识库只有单个设置菜单;Web 的设置分组包含基础设置、文档处理策略、定时同步,
飞书和工作流包含基础设置、定时同步。`setting/document-strategy/` 与
`setting/scheduled-sync/` 分别承接文档处理策略和定时同步,当前仅展示占位内容。
飞书和工作流包含基础设置、定时同步。`setting/document-strategy/` 复用
`DocumentStrategyForm`,通过 `setStrategy()` 回填详情的 `doc_strategy` 为独立草稿,
通过 `validate()` 和 `getStrategy()` 校验并单独保存该字段。保存成功合并接口返回数据到详情上下文,
失败保留草稿,保存期间使用内容容器 loading 遮罩和按钮 loading,不禁用表单字段。
方法入口防止重复提交。标题栏通过 Teleport 展示下次同步生效说明,
保存不立即发起同步。智能分段回填时保留高级分段的编辑默认值,提交仍使用智能分段的固定策略。
`setting/scheduled-sync/` 维护“同步设置”和“同步日志”两个页签,暂不调用同步设置和日志接口。
设置使用关闭定时同步、每日 00:00、增量同步的默认草稿,切换知识库时重置。
同步周期直接使用与触发器定时触发一致的 `el-cascader` 和 `SCHEDULE_OPTION`,
支持每日、每周、每月和按间隔,并通过切换按钮使用 Cron 输入,不再维护独立周期浮层组件。
周期校验与触发器保持相同的组织方式,直接写在页面 `FormRules` 中;同步方式卡片和日志标签
复用 `constants/knowledge.ts` 的 `KNOWLEDGE_SYNC_OPTIONS`,与手动同步弹窗保持一致,不单独维护 `sync-setting.ts`。
周日期使用 1(周一)至 7(周日),同步间隔至少 5 分钟,完整 Cron 校验待接口接入后由服务端完成。
页面维护启用开关和三种同步方式,同步说明与手动同步共用。
保存入口只校验周期并提示配置仅保留在页面中,不提交请求或更新详情 meta。
`components/SyncLogTable.vue` 在日志页签按需挂载,复用 MkTable 保留日志列、状态及分页,
当前展示空数据,不查询或生成模拟日志。
设置菜单的类型筛选由路由维护,不在 View 中重复维护菜单。
当前设置页仅接入 Workspace 路由和 API,暂不增加前端权限判断。
更换向量模型需确认,先保存再重新向量化,整条流程禁止重复提交;向量化失败时保留原模型比较基准,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ defineExpose({ open })
ref="applicationFormRef"
:model="applicationForm"
:rules="rules"
:disabled="submitting"
v-loading="submitting"
label-position="top"
require-asterisk-position="right"
@submit.prevent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ defineExpose({ open })
ref="applicationFormRef"
:model="applicationForm"
:rules="applicationFormRules"
:disabled="loading"
v-loading="loading"
label-position="top"
require-asterisk-position="right"
@submit.prevent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,9 @@ function handleClosed() {
@click="handleOpenDialog"
/>
<MkDialog v-model="visible" :title="manage ? '标签设置' : '添加标签'" :show-close="!loading && !optionLoading" @closed="handleClosed">
<el-form label-position="top" require-asterisk-position="right" @submit.prevent>
<el-form v-loading="loading || optionLoading" label-position="top" require-asterisk-position="right" @submit.prevent>
<el-form-item label="标签">
<el-select
v-model="selectedTagIds"
multiple
filterable
placeholder="请选择标签"
:loading="optionLoading"
:disabled="loading || optionLoading"
>
<el-select v-model="selectedTagIds" multiple filterable placeholder="请选择标签" :loading="optionLoading">
<template v-for="group in tagGroups" :key="group.key">
<el-option-group :label="group.key">
<template v-for="tag in group.values" :key="tag.id">
Expand Down
Loading
Loading