From c1658380a7d26e05fcdabab981602d861b65d256 Mon Sep 17 00:00:00 2001 From: 2910410219 <2910410219@qq.com> Date: Thu, 20 Aug 2026 00:38:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=BA=93=20outputField=20=E5=BC=95=E7=94=A8=20+=20totalDuratio?= =?UTF-8?q?n=20=E5=AD=97=E6=AE=B5=E7=BA=A7=E5=BC=95=E7=94=A8=EF=BC=9B?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E9=80=89=E9=A1=B9=E5=8D=A1=E6=8B=86=E5=88=86?= =?UTF-8?q?/=E6=87=92=E5=8A=A0=E8=BD=BD=E3=80=81=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E7=BB=93=E6=9E=9C=E6=8E=A5=E5=8F=A3=20result?= =?UTF-8?q?List=EF=BC=9B=E5=BC=95=E7=94=A8=E6=A0=87=E7=AD=BE=E4=B8=8E=20Ke?= =?UTF-8?q?yValue=20prop=20=E6=A0=A1=E9=AA=8C=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 节点库 outputField 作为可引用输出项:NodeLibraryItem 补类型、getNodeOutputFields 优先返回、upstreamNodes 来源扩展 - script_transcribe 视频总时长支持引用上级输出/手动输入:NodeConfigPanel 引用按钮 + valueSource 存 formConfig 条目,buildOutputConfig 序列化、buildNodeFormConfigFromDsl 回显 - 首页工作空间结果接口切 /ai-agent/session/resultList,会话列表/结果树选项卡拆分独立容错与按需懒加载 - ChatList 滚底感知;引用标签 ElTag type 空值、KeyValueEditor modelValue 空值兜底修复 Co-Authored-By: Claude --- src/api/settings/workflow/index.ts | 2 + src/api/settings/workflow/session.ts | 36 +++ src/views/home/components/ChatList.vue | 12 +- src/views/home/components/InputBar.vue | 22 +- src/views/home/components/Sidebar.vue | 14 +- src/views/home/index.vue | 46 ++- .../workflow/component/ModelField.vue | 2 +- .../workflow/component/NodeConfigPanel.vue | 282 ++++++++++++++---- src/views/settings/workflow/index.vue | 64 ++-- 9 files changed, 382 insertions(+), 98 deletions(-) diff --git a/src/api/settings/workflow/index.ts b/src/api/settings/workflow/index.ts index 7c0c9a9..70e1b9a 100644 --- a/src/api/settings/workflow/index.ts +++ b/src/api/settings/workflow/index.ts @@ -36,6 +36,8 @@ export interface NodeLibraryItem { isSaveFileOption: boolean; formConfigOption: boolean; modelConfigOption: boolean; + // 节点自带输出项([{ field, label }]):空/null 表示无输出;非空时该节点可作为下游节点的引用来源 + outputField?: { field: string; label: string }[] | null; presetOption: NodeLibraryPresetOption[] | null; } diff --git a/src/api/settings/workflow/session.ts b/src/api/settings/workflow/session.ts index d74f6a8..3e09b56 100644 --- a/src/api/settings/workflow/session.ts +++ b/src/api/settings/workflow/session.ts @@ -64,3 +64,39 @@ export function deleteSessionRecord(ids: { id: string; type: string }[], request requestOptions, }); } + +// ===== 工作空间结果列表(/ai-agent/session/resultList)===== +// 与内容创作 execution/list 同结构:data.tree(按 createDate 分组)+ data.imgAddressPrefix +export interface ExecutionItem { + id: string; + timestamp: string; + content: string; + label: string; + type?: string; +} + +export interface ExecutionTreeItem { + createDate: string; + items: ExecutionItem[]; +} + +export interface ExecutionListData { + tree: ExecutionTreeItem[]; + imgAddressPrefix: string; +} + +export interface ExecutionListResponse { + code: number; + message: string; + data: ExecutionListData; +} + +/** 获取工作空间结果列表(结果树) */ +export function getWorkspaceResultList(params?: Record, requestOptions?: RequestOptions) { + return request({ + url: '/ai-agent/session/resultList', + method: 'get', + params, + requestOptions, + }) as Promise; +} diff --git a/src/views/home/components/ChatList.vue b/src/views/home/components/ChatList.vue index 5193cf6..1ff1f55 100644 --- a/src/views/home/components/ChatList.vue +++ b/src/views/home/components/ChatList.vue @@ -206,6 +206,10 @@ const thinkingTitle = (msg: ChatMessage): string => { return msg.thinkingSeconds != null ? `已深度思考(用时 ${msg.thinkingSeconds} 秒)` : '已深度思考'; }; +// 距底部小于该阈值(px)视为"正在查看最新":新消息到达自动滚底;用户上滑阅读历史(超过阈值)则不强制拉回 +const NEAR_BOTTOM_THRESHOLD = 120; +// 是否处于"查看最新"状态:初始为真(挂载即定位最新),由用户真实滚动(isTrusted)更新 +let isAtBottom = true; // autoLoading 标记本次 load-more 是否由"自动续载"触发:自动续载不保持位置(落在最新),用户上滑保持视口 let autoLoading = false; // 自动续载累计次数上限:连续自动加载超过上限即停,防止异常数据(如 hasMore 恒 true 且视口不满) @@ -224,7 +228,8 @@ watch( nextTick(() => { const el = chatListRef.value; if (!el) return; - el.scrollTop = el.scrollHeight; + // 仅当用户贴近底部(isAtBottom)时才滚底;上滑阅读历史期间新消息不打断阅读位置 + if (isAtBottom) el.scrollTop = el.scrollHeight; if (props.messages.length > 0 && props.hasMore && el.scrollHeight <= el.clientHeight) { if (canAutoLoad()) { autoLoading = true; @@ -284,7 +289,10 @@ const handleScroll = (e: Event) => { // 自动续载/滚底时 scrollTop 不满屏被钳制为 0,会被误判为"用户上滑"而清空 autoLoading、破坏自动定位到最新 if (!e.isTrusted) return; const el = chatListRef.value; - if (!el || !props.hasMore || props.loadingMore) return; + if (!el) return; + // 感知用户阅读位置:贴近底部视为"正在查看最新"(新消息自动滚底),上滑阅读历史则不再强制拉回 + isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < NEAR_BOTTOM_THRESHOLD; + if (!props.hasMore || props.loadingMore) return; if (el.scrollTop <= 4) { // 用户主动上滑加载更早:重置自动续载计数,使用户操作不受自动续载上限约束 autoLoading = false; diff --git a/src/views/home/components/InputBar.vue b/src/views/home/components/InputBar.vue index 99f90c6..11aaf69 100644 --- a/src/views/home/components/InputBar.vue +++ b/src/views/home/components/InputBar.vue @@ -51,7 +51,7 @@