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 @@