From 6a588015d08c483caa9e4804b158bf49b53e11ed Mon Sep 17 00:00:00 2001 From: 2910410219 <2910410219@qq.com> Date: Tue, 7 Jul 2026 11:31:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=BB=E9=A1=B5=E5=AF=B9=E8=AF=9D?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84=20=E2=80=94=20=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=88=97=E8=A1=A8=E3=80=81=E5=B7=A5=E4=BD=9C=E6=B5=81?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E3=80=81=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增会话列表 API(getSessionList)及类型定义 - 修复对话记录为空:兼容 API 返回 data.list 结构 - 删除接口改为 DELETE 方法,参数统一使用 id - 实现工作流执行逻辑,与内容创作对齐(含表单参数、文件上传、flowContent) - 动态表单样式优化:三段式布局防溢出、上传区支持拖拽、节点分组显示 - 对话记录时间格式化:当天显示 HH:mm,非当天显示日期 - 对话记录默认展示全部,移除分页展开 - 发送按钮支持选中工作流时空文本可点击 - 默认占位展示引导提示,替代空状态 - 添加对话记录删除确认弹窗 - 下载改用后端代理,避免跨域问题 --- src/api/settings/creation/index.ts | 42 ++ .../patchTemplate/PatchTemplateEditor.vue | 9 +- src/views/home/components/InputBar.vue | 31 +- src/views/home/components/MainContent.vue | 608 ++++++++++++++++-- src/views/home/components/Sidebar.vue | 34 +- src/views/home/index.vue | 231 ++++++- 6 files changed, 843 insertions(+), 112 deletions(-) diff --git a/src/api/settings/creation/index.ts b/src/api/settings/creation/index.ts index eeeb9f7..277a3be 100644 --- a/src/api/settings/creation/index.ts +++ b/src/api/settings/creation/index.ts @@ -349,3 +349,45 @@ export function executeFlow(data: ExecuteFlowParams | FormData, requestOptions?: requestOptions, }); } +/** 删除工作空间结果(单个文件) */ +export function deleteExecutionResult(data: { id: string | number }, requestOptions?: RequestOptions) { + return request({ + url: '/ai-agent/flow/execution/deleteResult', + method: 'delete', + data, + requestOptions, + }); +} + +/** 删除会话记录 */ +export function deleteExecutionSession(data: { id: string }, requestOptions?: RequestOptions) { + return request({ + url: '/ai-agent/flow/execution/deleteSession', + method: 'delete', + data, + requestOptions, + }); +} + +export interface SessionListResponse { + code: number; + message: string; + data: SessionListItem[]; +} + +export interface SessionListItem { + id: string; + flowName: string; + sessionId: string; + createDate: string; +} + +/** 获取会话记录列表 */ +export function getSessionList(requestOptions?: RequestOptions) { + return request({ + url: '/ai-agent/flow/execution/sessionList', + method: 'get', + requestOptions, + }) as Promise; +} + diff --git a/src/components/patchTemplate/PatchTemplateEditor.vue b/src/components/patchTemplate/PatchTemplateEditor.vue index e22d3a2..fd9c3d3 100644 --- a/src/components/patchTemplate/PatchTemplateEditor.vue +++ b/src/components/patchTemplate/PatchTemplateEditor.vue @@ -300,24 +300,25 @@ const handleDownload = (_e?: Event) => { width: 100%; .template-card { - background: #f8fafc; + background: #fff; border: 1px solid #e2e8f0; border-radius: 8px; margin-bottom: 12px; overflow: hidden; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); .template-card-header { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; - background: #f1f5f9; - border-bottom: 1px solid #e2e8f0; + background: #fafbfc; + border-bottom: 1px solid #f1f5f9; .template-card-title { font-weight: 600; font-size: 13px; - color: #334155; + color: #1e293b; } } diff --git a/src/views/home/components/InputBar.vue b/src/views/home/components/InputBar.vue index 5bc9245..8158043 100644 --- a/src/views/home/components/InputBar.vue +++ b/src/views/home/components/InputBar.vue @@ -6,7 +6,7 @@
{{ commonWorkflows.find((w) => w.id === selectedWorkflowId)?.name }} - +
@@ -39,7 +39,7 @@
Shift+Enter 换行 -
@@ -70,10 +70,11 @@ import { getWorkflowList } from '/@/api/settings/creation'; interface Emits { (e: 'send', message: string): void; + (e: 'workflow-select', workflowId: string | null): void; } interface Workflow { - id: number; + id: string; name: string; prefix: string; } @@ -81,7 +82,7 @@ interface Workflow { const emit = defineEmits(); const message = ref(''); const isFocused = ref(false); -const selectedWorkflowId = ref(null); +const selectedWorkflowId = ref(null); const commonWorkflows = ref([]); const fetchWorkflows = async () => { @@ -89,7 +90,7 @@ const fetchWorkflows = async () => { const res = await getWorkflowList(); const workflows = res.data?.listFlowUserRes?.list || []; commonWorkflows.value = workflows.map((w) => ({ - id: Number(w.id), + id: String(w.id), name: w.flowName || '未命名', prefix: '[工作流] ' + (w.flowName || '') + ':\n', })); @@ -100,22 +101,26 @@ const fetchWorkflows = async () => { const handleSend = () => { const msg = message.value.trim(); - if (!msg) return; - const workflowPrefix = selectedWorkflowId.value !== null - ? commonWorkflows.value.find((w) => w.id === selectedWorkflowId.value)?.prefix || '' - : ''; - const finalMessage = (workflowPrefix + msg).trim(); - emit('send', finalMessage); + if (!msg && selectedWorkflowId.value === null) return; + emit('send', msg || ''); message.value = ''; selectedWorkflowId.value = null; + emit('workflow-select', null); }; const handleAttachment = () => { ElMessage.info('附件上传功能开发中...'); }; -const toggleWorkflow = (id: number) => { - selectedWorkflowId.value = selectedWorkflowId.value === id ? null : id; +const toggleWorkflow = (id: string) => { + const newId = selectedWorkflowId.value === id ? null : id; + selectedWorkflowId.value = newId; + emit('workflow-select', newId); +}; + +const clearWorkflow = () => { + selectedWorkflowId.value = null; + emit('workflow-select', null); }; onMounted(() => { diff --git a/src/views/home/components/MainContent.vue b/src/views/home/components/MainContent.vue index fc5dc31..29a7582 100644 --- a/src/views/home/components/MainContent.vue +++ b/src/views/home/components/MainContent.vue @@ -1,88 +1,596 @@ - +.w100 { width: 100%; } +.chat-container { width: min(1060px, 82%); margin: 0 auto; padding: 20px 0 130px; } + +.placeholder-body { display: flex; align-items: center; justify-content: center; } +.placeholder-content { text-align: center; padding: 40px 20px; max-width: 400px; } +.placeholder-icon { margin-bottom: 24px; display: flex; justify-content: center; } +.placeholder-title { font-size: 20px; font-weight: 700; color: #1e293b; margin: 0 0 8px; letter-spacing: -0.3px; } +.placeholder-desc { font-size: 14px; color: #94a3b8; margin: 0 0 28px; line-height: 1.6; } +.placeholder-hints { display: flex; flex-direction: column; gap: 10px; align-items: center; } +.hint-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #64748b; } +.hint-dot { width: 6px; height: 6px; border-radius: 50%; background: #cbd5e1; flex-shrink: 0; } + \ No newline at end of file diff --git a/src/views/home/components/Sidebar.vue b/src/views/home/components/Sidebar.vue index 44499c5..66cb2a3 100644 --- a/src/views/home/components/Sidebar.vue +++ b/src/views/home/components/Sidebar.vue @@ -29,7 +29,7 @@
- +
暂无对话记录
@@ -71,6 +68,7 @@
+
@@ -100,14 +98,14 @@ interface TreeNode { } interface HistoryItem { - id: number; + id: string; title: string; time: string; } interface Props { activeMenu: string; - activeHistoryId: number; + activeHistoryId: string | null; historyList: HistoryItem[]; treeNodes: TreeNode[]; treeLoading: boolean; @@ -116,23 +114,22 @@ interface Props { interface Emits { (e: 'menu-change', key: string): void; (e: 'new-chat'): void; - (e: 'select-history', id: number): void; - (e: 'delete-history', id: number): void; + (e: 'select-history', id: string): void; + (e: 'delete-history', id: string): void; (e: 'preview-node', data: TreeNode): void; (e: 'download-node', data: TreeNode): void; + (e: 'delete-node', data: TreeNode): void; } const props = defineProps(); const emit = defineEmits(); -const HISTORY_PAGE = 10; const WORKSPACE_PAGE = 5; const activeTab = ref<'history' | 'workspace'>('history'); -const historyShowCount = ref(HISTORY_PAGE); const workspaceShowCount = ref(WORKSPACE_PAGE); -const visibleHistory = computed(() => props.historyList.slice(0, historyShowCount.value)); +const visibleHistory = computed(() => props.historyList); const visibleWorkspace = computed(() => props.treeNodes.slice(0, workspaceShowCount.value)); const getFileIcon = (fileType?: string) => { @@ -145,10 +142,11 @@ const getFileIcon = (fileType?: string) => { }; const handleNewChat = () => emit('new-chat'); -const handleSelectHistory = (id: number) => emit('select-history', id); -const handleDeleteHistory = (id: number) => emit('delete-history', id); +const handleSelectHistory = (id: string) => emit('select-history', id); +const handleDeleteHistory = (id: string) => emit('delete-history', id); const handlePreviewNode = (data: TreeNode) => emit('preview-node', data); const handleDownloadNode = (data: TreeNode) => emit('download-node', data); +const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);