对话记录和工作空间链路确认
This commit is contained in:
@@ -86,22 +86,16 @@ export interface CreationTreeItem {
|
||||
|
||||
// 新的执行列表数据结构
|
||||
export interface ExecutionItem {
|
||||
id: string;
|
||||
timestamp: string;
|
||||
content: string;
|
||||
label: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface ExecutionFlowItem {
|
||||
flowName: string;
|
||||
Id?: number | string;
|
||||
sessionId?: string;
|
||||
items: ExecutionItem[];
|
||||
}
|
||||
|
||||
export interface ExecutionTreeItem {
|
||||
createDate: string;
|
||||
flows: ExecutionFlowItem[];
|
||||
items: ExecutionItem[];
|
||||
}
|
||||
|
||||
export interface CreationListData {
|
||||
@@ -351,7 +345,7 @@ export function executeFlow(data: ExecuteFlowParams | FormData, requestOptions?:
|
||||
});
|
||||
}
|
||||
/** 删除工作空间结果(单个文件) */
|
||||
export function deleteExecutionResult(data: { id: string | number }, requestOptions?: RequestOptions) {
|
||||
export function deleteExecutionResult(data: { id: string; content: string }, requestOptions?: RequestOptions) {
|
||||
return request({
|
||||
url: '/ai-agent/flow/execution/deleteResult',
|
||||
method: 'delete',
|
||||
@@ -384,10 +378,11 @@ export interface SessionListItem {
|
||||
}
|
||||
|
||||
/** 获取会话记录列表 */
|
||||
export function getSessionList(requestOptions?: RequestOptions) {
|
||||
export function getSessionList(params?: Record<string, any>, requestOptions?: RequestOptions) {
|
||||
return request({
|
||||
url: '/ai-agent/flow/execution/sessionList',
|
||||
method: 'get',
|
||||
params,
|
||||
requestOptions,
|
||||
}) as Promise<SessionListResponse>;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
<div class="toolbar-right">
|
||||
<span class="hint-text">Shift+Enter 换行</span>
|
||||
<button class="send-btn" :disabled="!message.trim() && selectedWorkflowId === null" @click="handleSend">
|
||||
<button class="send-btn" :disabled="selectedWorkflowId === null" @click="handleSend">
|
||||
<el-icon><Top /></el-icon>
|
||||
</button>
|
||||
</div>
|
||||
@@ -100,8 +100,8 @@ const fetchWorkflows = async () => {
|
||||
};
|
||||
|
||||
const handleSend = () => {
|
||||
if (selectedWorkflowId.value === null) return;
|
||||
const msg = message.value.trim();
|
||||
if (!msg && selectedWorkflowId.value === null) return;
|
||||
emit('send', msg || '');
|
||||
message.value = '';
|
||||
selectedWorkflowId.value = null;
|
||||
@@ -133,7 +133,7 @@ onMounted(() => {
|
||||
fetchWorkflows();
|
||||
});
|
||||
|
||||
defineExpose({ resetAll, clearWorkflow, selectedWorkflowId });
|
||||
defineExpose({ resetAll, clearWorkflow, selectedWorkflowId, commonWorkflows });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -395,7 +395,10 @@ watch(
|
||||
Object.keys(formValues).forEach((key) => delete formValues[key]);
|
||||
Object.keys(fieldFiles).forEach((key) => delete fieldFiles[key]);
|
||||
Object.keys(uploadingFields).forEach((key) => delete uploadingFields[key]);
|
||||
templates.value = [];
|
||||
// 尝试从执行详情恢复贴片模板
|
||||
const ext = (detail as any)?.extension;
|
||||
const restoredTemplates = ext?.templates || (detail as any)?.templates || detail?.flowContent?.templates || [];
|
||||
templates.value = Array.isArray(restoredTemplates) ? restoredTemplates : [];
|
||||
|
||||
if (!detail?.nodeInputParams) return;
|
||||
detail.nodeInputParams.forEach((node: any) => {
|
||||
@@ -419,14 +422,15 @@ watch(
|
||||
}
|
||||
|
||||
const key = getFieldKey(node, field);
|
||||
const hasValue = field.value !== undefined && field.value !== null;
|
||||
if (field.type === 'number' || field.type === 'inputNumber') {
|
||||
formValues[key] = field.default ?? null;
|
||||
formValues[key] = hasValue ? Number(field.value) : (field.default ?? null);
|
||||
} else if (field.type === 'switch') {
|
||||
formValues[key] = field.default ?? false;
|
||||
formValues[key] = hasValue ? Boolean(field.value) : (field.default ?? false);
|
||||
} else if (field.type === 'upload' || field.type === 'uploadMultiple' || field.type === 'fileUpload') {
|
||||
formValues[key] = field.default ?? (field.type === 'upload' ? '' : []);
|
||||
formValues[key] = hasValue ? field.value : (field.default ?? (field.type === 'upload' ? '' : []));
|
||||
} else {
|
||||
formValues[key] = field.default ?? '';
|
||||
formValues[key] = hasValue ? field.value : (field.default ?? '');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,21 +58,15 @@
|
||||
<div v-else class="panel-list">
|
||||
<div v-for="dateNode in treeNodes" :key="dateNode.id" class="tree-date-group">
|
||||
<div class="tree-date-label">{{ dateNode.label }}</div>
|
||||
<div v-for="flowNode in dateNode.children" :key="flowNode.id" class="tree-flow-group">
|
||||
<div class="tree-flow-label">
|
||||
<el-icon><Promotion /></el-icon>
|
||||
<span>{{ flowNode.label }}</span>
|
||||
</div>
|
||||
<div v-for="fileNode in flowNode.children" :key="fileNode.id" class="tree-file-item">
|
||||
<el-icon class="file-type-icon">
|
||||
<component :is="getFileIcon(fileNode.fileType)" />
|
||||
</el-icon>
|
||||
<span class="file-name">{{ fileNode.label }}</span>
|
||||
<div v-if="fileNode.fileUrl" class="file-actions">
|
||||
<button class="file-action-btn" @click.stop="handlePreviewNode(fileNode)">预览</button>
|
||||
<button class="file-action-btn" @click.stop="handleDownloadNode(fileNode)">下载</button>
|
||||
<button class="file-action-btn file-action-btn--del" @click.stop="handleDeleteNode(fileNode)">删除</button>
|
||||
</div>
|
||||
<div v-for="fileNode in dateNode.children" :key="fileNode.id" class="tree-file-item">
|
||||
<el-icon class="file-type-icon">
|
||||
<component :is="getFileIcon(fileNode.fileType)" />
|
||||
</el-icon>
|
||||
<span class="file-name">{{ fileNode.label }}</span>
|
||||
<div v-if="fileNode.fileUrl" class="file-actions">
|
||||
<button class="file-action-btn" @click.stop="handlePreviewNode(fileNode)">预览</button>
|
||||
<button class="file-action-btn" @click.stop="handleDownloadNode(fileNode)">下载</button>
|
||||
<button class="file-action-btn file-action-btn--del" @click.stop="handleDeleteNode(fileNode)">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,7 +81,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Delete, ChatDotRound, ChatLineRound, EditPen, ArrowDown, Promotion, Document, VideoPlay, Headset, Picture, FolderOpened } from '@element-plus/icons-vue';
|
||||
import { Delete, ChatDotRound, ChatLineRound, EditPen, ArrowDown, Document, VideoPlay, Headset, Picture, FolderOpened } from '@element-plus/icons-vue';
|
||||
|
||||
interface TreeNode {
|
||||
id: string;
|
||||
@@ -414,33 +408,6 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.tree-flow-group {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.tree-flow-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #475569;
|
||||
|
||||
.el-icon {
|
||||
font-size: 13px;
|
||||
color: #7c3aed;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-file-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
+111
-64
@@ -17,7 +17,13 @@
|
||||
@delete-node="handleDeleteNode"
|
||||
/>
|
||||
<div class="main-wrapper">
|
||||
<MainContent ref="mainContentRef" :active-menu="activeMenu" :workflow-detail="selectedWorkflowDetail" :active-history-id="activeHistoryId" @close-workflow="handleCloseWorkflow" />
|
||||
<MainContent
|
||||
ref="mainContentRef"
|
||||
:active-menu="activeMenu"
|
||||
:workflow-detail="selectedWorkflowDetail"
|
||||
:active-history-id="activeHistoryId"
|
||||
@close-workflow="handleCloseWorkflow"
|
||||
/>
|
||||
<InputBar ref="inputBarRef" @send="handleSend" @workflow-select="handleWorkflowSelect" />
|
||||
</div>
|
||||
|
||||
@@ -46,8 +52,16 @@ import Sidebar from './components/Sidebar.vue';
|
||||
import MainContent from './components/MainContent.vue';
|
||||
import InputBar from './components/InputBar.vue';
|
||||
import type { ExecutionTreeItem } from '/@/api/settings/creation';
|
||||
import { getExecutionList, getWorkflowDetail, getExecutionDetail, deleteExecutionResult, deleteExecutionSession, getSessionList, downloadToFile, executeFlow } from '/@/api/settings/creation';
|
||||
|
||||
import {
|
||||
getExecutionList,
|
||||
getWorkflowDetail,
|
||||
getExecutionDetail,
|
||||
deleteExecutionResult,
|
||||
deleteExecutionSession,
|
||||
getSessionList,
|
||||
downloadToFile,
|
||||
executeFlow,
|
||||
} from '/@/api/settings/creation';
|
||||
|
||||
interface HistoryItem {
|
||||
id: string;
|
||||
@@ -70,9 +84,8 @@ interface TreeNode {
|
||||
nodeType: string;
|
||||
children?: TreeNode[];
|
||||
fileUrl?: string;
|
||||
workflowId?: number | string;
|
||||
fileType?: string;
|
||||
sessionId?: string;
|
||||
backendId?: string;
|
||||
}
|
||||
|
||||
const activeMenu = ref('chat');
|
||||
@@ -101,27 +114,18 @@ const buildAssetUrl = (p?: string) =>
|
||||
? joinUrl(joinUrl(apiBaseUrl, imgAddressPrefix.value), p)
|
||||
: joinUrl(apiBaseUrl, p);
|
||||
|
||||
|
||||
const buildTreeNodes = (tree: ExecutionTreeItem[]): TreeNode[] =>
|
||||
tree.map((d, di) => ({
|
||||
id: 'date-' + di,
|
||||
label: d.createDate,
|
||||
nodeType: 'date',
|
||||
children: (d.flows || []).map((f, fi) => ({
|
||||
id: 'flow-' + di + '-' + fi,
|
||||
label: f.flowName || '未命名工作流',
|
||||
nodeType: 'contentType',
|
||||
workflowId: f.Id,
|
||||
sessionId: f.sessionId,
|
||||
children: (f.items || []).map((item, ii) => ({
|
||||
id: 'item-' + di + '-' + fi + '-' + ii,
|
||||
label: item.label || '作品' + (ii + 1),
|
||||
nodeType: 'title',
|
||||
fileUrl: item.content,
|
||||
fileType: item.type,
|
||||
workflowId: f.Id,
|
||||
sessionId: f.sessionId,
|
||||
})),
|
||||
children: (d.items || []).map((item, ii) => ({
|
||||
id: 'item-' + di + '-' + ii,
|
||||
label: item.label || '作品' + (ii + 1),
|
||||
nodeType: 'title',
|
||||
fileUrl: item.content,
|
||||
fileType: item.type,
|
||||
backendId: item.id,
|
||||
})),
|
||||
}));
|
||||
|
||||
@@ -180,9 +184,9 @@ const handleDeleteNode = async (data: TreeNode) => {
|
||||
return;
|
||||
}
|
||||
// 调后端接口删除
|
||||
if (data.fileUrl && data.workflowId) {
|
||||
if (data.backendId && data.fileUrl) {
|
||||
try {
|
||||
await deleteExecutionResult({ id: data.workflowId });
|
||||
await deleteExecutionResult({ id: data.backendId, content: data.fileUrl });
|
||||
} catch {
|
||||
// 后端已提示错误,继续本地删除
|
||||
}
|
||||
@@ -216,13 +220,11 @@ const getList = async () => {
|
||||
hasMoreWorkspace.value = true;
|
||||
treeLoading.value = true;
|
||||
try {
|
||||
const [execRes, sessionRes] = await Promise.all([
|
||||
getExecutionList(),
|
||||
getSessionList(),
|
||||
]);
|
||||
const [execRes, sessionRes] = await Promise.all([getExecutionList({ pageSize: 5 }), getSessionList({ pageSize: 10 })]);
|
||||
imgAddressPrefix.value = execRes.data?.imgAddressPrefix || '';
|
||||
treeNodes.value = buildTreeNodes(execRes.data?.tree || []);
|
||||
const d = new Date(); const todayStr = d.getFullYear() + '-' + String(d.getMonth()+1).padStart(2,'0') + '-' + String(d.getDate()).padStart(2,'0');
|
||||
const d = new Date();
|
||||
const todayStr = d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
|
||||
const sessions = getSessionData(sessionRes).map((s) => {
|
||||
const rawTime = s.createdAt || s.createDate || '';
|
||||
let displayTime = rawTime;
|
||||
@@ -262,6 +264,7 @@ const mainContentRef = ref<any>(null);
|
||||
const workspacePage = ref(1);
|
||||
const hasMoreWorkspace = ref(true);
|
||||
const workspaceLoading = ref(false);
|
||||
const isSending = ref(false);
|
||||
const inputBarRef = ref<any>(null);
|
||||
|
||||
const getSessionId = () => {
|
||||
@@ -312,8 +315,7 @@ const handleMenuChange = (menu: string) => {
|
||||
activeMenu.value = menu;
|
||||
};
|
||||
|
||||
const formatTime = (d: Date) =>
|
||||
String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');
|
||||
const formatTime = (d: Date) => String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');
|
||||
|
||||
const addMessage = (msg: ChatMessage) => {
|
||||
const id = activeHistoryId.value;
|
||||
@@ -324,18 +326,30 @@ const addMessage = (msg: ChatMessage) => {
|
||||
};
|
||||
|
||||
const handleSend = async (message: string) => {
|
||||
if (isSending.value) return;
|
||||
isSending.value = true;
|
||||
if (!selectedWorkflowDetail.value) {
|
||||
ElMessage.warning('请先选择一个工作流');
|
||||
isSending.value = false;
|
||||
return;
|
||||
}
|
||||
const mc = mainContentRef.value;
|
||||
if (!mc) return;
|
||||
if (!mc) {
|
||||
isSending.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mc.validateFormFields()) return;
|
||||
if (!mc.validateFormFields()) {
|
||||
isSending.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前会话的 sessionId
|
||||
const curSession = historyList.value.find((h) => h.id === activeHistoryId.value);
|
||||
if (!curSession) return;
|
||||
if (!curSession) {
|
||||
isSending.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加用户消息
|
||||
addMessage({
|
||||
@@ -351,36 +365,37 @@ const handleSend = async (message: string) => {
|
||||
|
||||
try {
|
||||
// 1. 构建节点输入参数
|
||||
const nodeInputParams = selectedWorkflowDetail.value.nodeInputParams?.map((node: any) => {
|
||||
const nodeParam: any = { ...node };
|
||||
const nodeInputParams =
|
||||
selectedWorkflowDetail.value.nodeInputParams?.map((node: any) => {
|
||||
const nodeParam: any = { ...node };
|
||||
|
||||
if (node.formConfig && Array.isArray(node.formConfig)) {
|
||||
nodeParam.formConfig = node.formConfig.map((field: any) => {
|
||||
// HTTP body 处理
|
||||
if (String(node.nodeCode || '').toLowerCase() === 'http' && field.field === 'body' && field.value && typeof field.value === 'object') {
|
||||
const bodyValue = { ...field.value };
|
||||
Object.entries(bodyValue).forEach(([bodyKey, bodyItem]: [string, any]) => {
|
||||
if (!bodyItem || bodyItem.showInForm !== true) return;
|
||||
const bodyFieldKey = `${node.id}_body_${bodyKey}`;
|
||||
const userVal = mc.formValues[bodyFieldKey];
|
||||
bodyValue[bodyKey] = {
|
||||
...bodyItem,
|
||||
value: userVal !== undefined ? userVal : bodyItem.value,
|
||||
};
|
||||
});
|
||||
return { ...field, value: bodyValue };
|
||||
}
|
||||
if (node.formConfig && Array.isArray(node.formConfig)) {
|
||||
nodeParam.formConfig = node.formConfig.map((field: any) => {
|
||||
// HTTP body 处理
|
||||
if (String(node.nodeCode || '').toLowerCase() === 'http' && field.field === 'body' && field.value && typeof field.value === 'object') {
|
||||
const bodyValue = { ...field.value };
|
||||
Object.entries(bodyValue).forEach(([bodyKey, bodyItem]: [string, any]) => {
|
||||
if (!bodyItem || bodyItem.showInForm !== true) return;
|
||||
const bodyFieldKey = `${node.id}_body_${bodyKey}`;
|
||||
const userVal = mc.formValues[bodyFieldKey];
|
||||
bodyValue[bodyKey] = {
|
||||
...bodyItem,
|
||||
value: userVal !== undefined ? userVal : bodyItem.value,
|
||||
};
|
||||
});
|
||||
return { ...field, value: bodyValue };
|
||||
}
|
||||
|
||||
const fieldKey = `${node.id}_${field.field || field.label}`;
|
||||
return {
|
||||
...field,
|
||||
value: mc.formValues[fieldKey] !== undefined ? mc.formValues[fieldKey] : field.value,
|
||||
};
|
||||
});
|
||||
}
|
||||
const fieldKey = `${node.id}_${field.field || field.label}`;
|
||||
return {
|
||||
...field,
|
||||
value: mc.formValues[fieldKey] !== undefined ? mc.formValues[fieldKey] : field.value,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return nodeParam;
|
||||
}) || [];
|
||||
return nodeParam;
|
||||
}) || [];
|
||||
|
||||
// 2. 构建 flowContent
|
||||
const updatedFlowContent = {
|
||||
@@ -422,10 +437,34 @@ const handleSend = async (message: string) => {
|
||||
});
|
||||
ElMessage.success('执行完成');
|
||||
// 刷新工作空间树
|
||||
getExecutionList().then((res) => {
|
||||
getExecutionList({ pageSize: 5 }).then((res) => {
|
||||
imgAddressPrefix.value = res.data?.imgAddressPrefix || '';
|
||||
treeNodes.value = buildTreeNodes(res.data?.tree || []);
|
||||
});
|
||||
// 虚拟会话执行成功后,刷新会话列表替换真实条目
|
||||
if (curSession.id.startsWith('virtual_')) {
|
||||
getSessionList().then((sessionRes) => {
|
||||
const freshList = getSessionData(sessionRes).map((s: any) => ({
|
||||
id: s.id,
|
||||
sessionId: s.sessionId,
|
||||
title: s.flowName || '未命名会话',
|
||||
time: s.createDate?.substring(0, 10) || '',
|
||||
}));
|
||||
const match = freshList.find((s: any) => s.sessionId === curSession.sessionId);
|
||||
if (match) {
|
||||
const idx = historyList.value.findIndex((h) => h.id === curSession.id);
|
||||
if (idx >= 0) {
|
||||
const msgs = sessionMessages.value.get(curSession.id);
|
||||
sessionMessages.value.delete(curSession.id);
|
||||
sessionMessages.value.set(match.id, msgs || []);
|
||||
historyList.value[idx] = match;
|
||||
if (activeHistoryId.value === curSession.id) {
|
||||
activeHistoryId.value = match.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
const failSession = historyList.value.find((h) => h.id === activeHistoryId.value);
|
||||
if (failSession) failSession.status = 'failed';
|
||||
@@ -435,6 +474,8 @@ const handleSend = async (message: string) => {
|
||||
time: formatTime(new Date()),
|
||||
isUser: false,
|
||||
});
|
||||
} finally {
|
||||
isSending.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -448,6 +489,12 @@ const handleSelectHistory = async (id: string) => {
|
||||
const res = await getExecutionDetail(session.id);
|
||||
if (res.data) {
|
||||
selectedWorkflowDetail.value = res.data;
|
||||
// 同步回显 InputBar 的工作流选择
|
||||
const ib = inputBarRef.value as any;
|
||||
if (ib?.commonWorkflows && res.data.flowName) {
|
||||
const match = ib.commonWorkflows.find((w: any) => w.name === res.data.flowName);
|
||||
if (match) ib.selectedWorkflowId = match.id;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 无关联执行数据,仅展示消息
|
||||
@@ -473,7 +520,7 @@ const createNewSession = () => {
|
||||
activeMenu.value = 'chat';
|
||||
selectedWorkflowDetail.value = null;
|
||||
inputBarRef.value?.resetAll();
|
||||
sessionMessages.value.set(sessionId, []); // 清空消息
|
||||
sessionMessages.value.set(sessionId, []); // 清空消息
|
||||
};
|
||||
|
||||
const handleCreateHistory = () => {
|
||||
@@ -532,7 +579,7 @@ onMounted(() => {
|
||||
radial-gradient(1200px 600px at 0% 0%, rgba(59, 130, 246, 0.18) 0%, rgba(59, 130, 246, 0) 45%),
|
||||
radial-gradient(1000px 500px at 100% 0%, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0) 50%),
|
||||
radial-gradient(800px 400px at 0% 100%, rgba(236, 72, 153, 0.12) 0%, rgba(236, 72, 153, 0) 55%),
|
||||
radial-gradient(600px 300px at 100% 100%, rgba(16, 185, 129, 0.10) 0%, rgba(16, 185, 129, 0) 60%),
|
||||
radial-gradient(600px 300px at 100% 100%, rgba(16, 185, 129, 0.1) 0%, rgba(16, 185, 129, 0) 60%),
|
||||
linear-gradient(135deg, #f8fbff 0%, #e6f0ff 60%, #f0f4fa 100%);
|
||||
}
|
||||
|
||||
@@ -564,4 +611,4 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
min-height: 60vh;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1401,21 +1401,12 @@ const buildTreeNodes = (tree: ExecutionTreeItem[]): TreeNode[] =>
|
||||
id: `date-${di}`,
|
||||
label: d.createDate,
|
||||
nodeType: 'date',
|
||||
children: (d.flows || []).map((f, fi) => ({
|
||||
id: `flow-${di}-${fi}`,
|
||||
label: f.flowName || '未命名工作流',
|
||||
nodeType: 'contentType',
|
||||
workflowId: f.Id,
|
||||
sessionId: f.sessionId,
|
||||
children: (f.items || []).map((item, ii) => ({
|
||||
id: `item-${di}-${fi}-${ii}`,
|
||||
label: item.label || `作品${ii + 1}`,
|
||||
nodeType: 'title',
|
||||
fileUrl: item.content,
|
||||
fileType: item.type,
|
||||
workflowId: f.Id,
|
||||
sessionId: f.sessionId,
|
||||
})),
|
||||
children: (d.items || []).map((item, ii) => ({
|
||||
id: `item-${di}-${ii}`,
|
||||
label: item.label || `作品${ii + 1}`,
|
||||
nodeType: 'title',
|
||||
fileUrl: item.content,
|
||||
fileType: item.type,
|
||||
})),
|
||||
}));
|
||||
const getList = async () => {
|
||||
|
||||
Reference in New Issue
Block a user