Trim frontend build for lightweight AI agent admin
This commit is contained in:
@@ -815,7 +815,8 @@ onBeforeUnmount(() => {
|
||||
class="w-full"
|
||||
type="textarea"
|
||||
:placeholder="$t('announcement.formContentPlaceholder')"
|
||||
:rows="12"
|
||||
:autosize="{ minRows: 8, maxRows: 16 }"
|
||||
resize="vertical"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
<script lang="ts" setup>
|
||||
import type { WorkflowRunListItem } from '#/api/ai-platform/ai-platform';
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Eye } from '@vben/icons';
|
||||
import { Eye, RefreshCw, Search } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { ElButton, ElTag } from 'element-plus';
|
||||
import {
|
||||
ElButton,
|
||||
ElCard,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElOption,
|
||||
ElPagination,
|
||||
ElSelect,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
ElTag,
|
||||
} from 'element-plus';
|
||||
|
||||
import { getAllWorkflowRunsApi } from '#/api/ai-platform/ai-platform';
|
||||
import { useZqTable } from '#/components/zq-table';
|
||||
import {
|
||||
getAllWorkflowRunsApi,
|
||||
getWorkflowListApi,
|
||||
} from '#/api/ai-platform/ai-platform';
|
||||
|
||||
import RunStatusTag from './components/RunStatusTag.vue';
|
||||
import {
|
||||
@@ -18,97 +31,245 @@ import {
|
||||
formatTime,
|
||||
getTagLabel,
|
||||
getTagType,
|
||||
getStatusOptions,
|
||||
getTriggerOptions,
|
||||
useSearchFormSchema,
|
||||
useZqTableColumns,
|
||||
} from './data';
|
||||
import DetailDialog from './modules/detail-dialog.vue';
|
||||
|
||||
defineOptions({ name: 'WorkflowRunHistory' });
|
||||
|
||||
const detailRef = ref<InstanceType<typeof DetailDialog>>();
|
||||
const triggerOptions = getTriggerOptions();
|
||||
|
||||
const fetchRunList = async (params: any) => {
|
||||
const res = await getAllWorkflowRunsApi({
|
||||
page: params.page.currentPage,
|
||||
pageSize: params.page.pageSize,
|
||||
workflowId: params.form?.workflowId || undefined,
|
||||
status: params.form?.status || undefined,
|
||||
triggerType: params.form?.triggerType || undefined,
|
||||
});
|
||||
return {
|
||||
items: res.items,
|
||||
total: res.total,
|
||||
};
|
||||
};
|
||||
|
||||
const [Grid] = useZqTable({
|
||||
gridOptions: {
|
||||
columns: useZqTableColumns(),
|
||||
border: true,
|
||||
stripe: true,
|
||||
showIndex: true,
|
||||
proxyConfig: {
|
||||
autoLoad: true,
|
||||
ajax: {
|
||||
query: fetchRunList,
|
||||
},
|
||||
},
|
||||
pagerConfig: {
|
||||
enabled: true,
|
||||
pageSize: 20,
|
||||
},
|
||||
toolbarConfig: {
|
||||
search: true,
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
custom: true,
|
||||
},
|
||||
},
|
||||
formOptions: {
|
||||
schema: useSearchFormSchema(),
|
||||
showCollapseButton: true,
|
||||
submitOnChange: true,
|
||||
},
|
||||
const loading = ref(false);
|
||||
const rows = ref<WorkflowRunListItem[]>([]);
|
||||
const total = ref(0);
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(20);
|
||||
const workflowOptions = ref<Array<{ label: string; value: string }>>([]);
|
||||
const filters = ref({
|
||||
workflowId: '',
|
||||
status: '',
|
||||
triggerType: '',
|
||||
});
|
||||
const statusOptions = getStatusOptions();
|
||||
const triggerOptions = getTriggerOptions();
|
||||
const rowIndex = computed(() => (currentPage.value - 1) * pageSize.value);
|
||||
|
||||
async function loadWorkflowOptions() {
|
||||
const res = await getWorkflowListApi({ page: 1, pageSize: 200 });
|
||||
workflowOptions.value = (res.items || []).map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
}
|
||||
|
||||
async function loadRuns() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getAllWorkflowRunsApi({
|
||||
page: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
workflowId: filters.value.workflowId || undefined,
|
||||
status: filters.value.status || undefined,
|
||||
triggerType: filters.value.triggerType || undefined,
|
||||
});
|
||||
rows.value = res.items || [];
|
||||
total.value = res.total || 0;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
currentPage.value = 1;
|
||||
loadRuns();
|
||||
}
|
||||
|
||||
function handleSizeChange(size: number) {
|
||||
pageSize.value = size;
|
||||
currentPage.value = 1;
|
||||
loadRuns();
|
||||
}
|
||||
|
||||
function handlePageChange(page: number) {
|
||||
currentPage.value = page;
|
||||
loadRuns();
|
||||
}
|
||||
|
||||
function openDetail(row: WorkflowRunListItem) {
|
||||
detailRef.value?.open(row.id);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadWorkflowOptions();
|
||||
loadRuns();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<DetailDialog ref="detailRef" />
|
||||
|
||||
<Grid>
|
||||
<template #cell-status="{ row }">
|
||||
<RunStatusTag :status="row.status" />
|
||||
</template>
|
||||
<ElCard shadow="never" class="h-full">
|
||||
<ElForm :model="filters" inline class="mb-3">
|
||||
<ElFormItem :label="$t('ai-platform.workflowRuns.filters.workflow')">
|
||||
<ElSelect
|
||||
v-model="filters.workflowId"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 220px"
|
||||
:placeholder="$t('ai-platform.workflowRuns.filters.allWorkflows')"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in workflowOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem :label="$t('ai-platform.workflowRuns.filters.status')">
|
||||
<ElSelect
|
||||
v-model="filters.status"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
:placeholder="$t('ai-platform.workflowRuns.filters.allStatus')"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem :label="$t('ai-platform.workflowRuns.filters.trigger')">
|
||||
<ElSelect
|
||||
v-model="filters.triggerType"
|
||||
clearable
|
||||
style="width: 160px"
|
||||
:placeholder="$t('ai-platform.workflowRuns.filters.allTriggers')"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in triggerOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem>
|
||||
<ElButton type="primary" :icon="Search" @click="handleSearch">
|
||||
{{ $t('common.search') }}
|
||||
</ElButton>
|
||||
<ElButton :icon="RefreshCw" @click="loadRuns">
|
||||
{{ $t('common.refresh') }}
|
||||
</ElButton>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
|
||||
<template #cell-trigger_type="{ row }">
|
||||
<ElTag
|
||||
:type="getTagType(row.trigger_type, triggerOptions)"
|
||||
size="small"
|
||||
<ElTable
|
||||
v-loading="loading"
|
||||
:data="rows"
|
||||
border
|
||||
stripe
|
||||
height="calc(100vh - 285px)"
|
||||
>
|
||||
<ElTableColumn type="index" width="60" :index="rowIndex + 1" />
|
||||
<ElTableColumn
|
||||
prop="workflow_name"
|
||||
:label="$t('ai-platform.workflowRuns.columns.workflow')"
|
||||
min-width="160"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<ElTableColumn
|
||||
:label="$t('ai-platform.workflowRuns.columns.status')"
|
||||
width="110"
|
||||
align="center"
|
||||
>
|
||||
{{ getTagLabel(row.trigger_type, triggerOptions) }}
|
||||
</ElTag>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<RunStatusTag :status="row.status" />
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
:label="$t('ai-platform.workflowRuns.columns.trigger')"
|
||||
width="140"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<ElTag
|
||||
:type="getTagType(row.trigger_type, triggerOptions)"
|
||||
size="small"
|
||||
>
|
||||
{{ getTagLabel(row.trigger_type, triggerOptions) }}
|
||||
</ElTag>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
prop="total_steps"
|
||||
:label="$t('ai-platform.workflowRuns.columns.steps')"
|
||||
width="80"
|
||||
align="center"
|
||||
/>
|
||||
<ElTableColumn
|
||||
prop="total_tokens"
|
||||
:label="$t('ai-platform.workflowRuns.columns.tokens')"
|
||||
width="90"
|
||||
align="center"
|
||||
/>
|
||||
<ElTableColumn
|
||||
:label="$t('ai-platform.workflowRuns.columns.duration')"
|
||||
width="100"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatDuration(row.elapsed_time) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
:label="$t('ai-platform.workflowRuns.columns.startedAt')"
|
||||
width="180"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.started_at) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
prop="error_message"
|
||||
:label="$t('ai-platform.workflowRuns.columns.error')"
|
||||
min-width="180"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<ElTableColumn
|
||||
:label="$t('ai-platform.workflowRuns.columns.actions')"
|
||||
width="120"
|
||||
fixed="right"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<ElButton
|
||||
link
|
||||
type="primary"
|
||||
:icon="Eye"
|
||||
@click.stop="openDetail(row)"
|
||||
>
|
||||
{{ $t('common.view') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
|
||||
<template #cell-elapsed_time="{ row }">
|
||||
{{ formatDuration(row.elapsed_time) }}
|
||||
</template>
|
||||
|
||||
<template #cell-started_at="{ row }">
|
||||
{{ formatTime(row.started_at) }}
|
||||
</template>
|
||||
|
||||
<template #cell-actions="{ row }">
|
||||
<ElButton link type="primary" :icon="Eye" @click.stop="openDetail(row)">
|
||||
{{ $t('common.view') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</Grid>
|
||||
<div class="mt-4 flex justify-end">
|
||||
<ElPagination
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="total"
|
||||
@current-change="handlePageChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</ElCard>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { WorkflowStreamEvent } from '#/api/ai-platform/ai-platform';
|
||||
import type { ChatMessage, ReasoningStep } from '#/components/ChatBox/index';
|
||||
import type {
|
||||
AppDesignData,
|
||||
AppSettingsData,
|
||||
DashboardBasicInfoData,
|
||||
DashboardDesignData,
|
||||
DashboardPublishData,
|
||||
DesignData,
|
||||
SystemSummaryData,
|
||||
} from '#/components/form-editor';
|
||||
|
||||
import { computed, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
import { Settings2, X } from '@vben/icons';
|
||||
@@ -20,6 +30,15 @@ import {
|
||||
runWorkflowStreamApi,
|
||||
} from '#/api/ai-platform/ai-platform';
|
||||
import { ChatBox } from '#/components/ChatBox/index';
|
||||
import {
|
||||
AppDesignPanel,
|
||||
AppSettingsPanel,
|
||||
DashboardBasicInfoConfirmPanel,
|
||||
DashboardDesignConfirmPanel,
|
||||
DashboardPublishConfirmPanel,
|
||||
DesignEditorPanel,
|
||||
SystemSummaryConfirmPanel,
|
||||
} from '#/components/form-editor';
|
||||
|
||||
const props = defineProps<{
|
||||
nodes: any[];
|
||||
@@ -52,12 +71,37 @@ const waitingConfig = ref<any>(null);
|
||||
const currentRunId = ref('');
|
||||
|
||||
// 设计预览编辑面板状态
|
||||
const showDesignPanel = ref(false);
|
||||
const currentDesign = ref<DesignData | undefined>(undefined);
|
||||
|
||||
// 应用设计面板状态
|
||||
const showAppDesignPanel = ref(false);
|
||||
const currentAppDesign = ref<AppDesignData | undefined>(undefined);
|
||||
|
||||
// 应用设置面板状态
|
||||
const showAppSettingsPanel = ref(false);
|
||||
const currentAppSettings = ref<AppSettingsData | undefined>(undefined);
|
||||
|
||||
// 仪表盘基础信息面板状态
|
||||
const showDashboardBasicInfoPanel = ref(false);
|
||||
const currentDashboardBasicInfo = ref<DashboardBasicInfoData | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
// 仪表盘设计面板状态
|
||||
const showDashboardDesignPanel = ref(false);
|
||||
const currentDashboardDesign = ref<DashboardDesignData | undefined>(undefined);
|
||||
|
||||
// 仪表盘发布面板状态
|
||||
const showDashboardPublishPanel = ref(false);
|
||||
const currentDashboardPublish = ref<DashboardPublishData | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
// 系统总结面板状态
|
||||
const showSystemSummaryPanel = ref(false);
|
||||
const currentSystemSummary = ref<SystemSummaryData | undefined>(undefined);
|
||||
|
||||
// 查找 Start 节点并提取变量
|
||||
const startNode = computed(() => props.nodes.find((n) => n.type === 'start'));
|
||||
const variables = computed(() => startNode.value?.data?.variables || []);
|
||||
@@ -546,13 +590,126 @@ const handleStreamEvent = (event: WorkflowStreamEvent, msgId: string) => {
|
||||
}
|
||||
|
||||
case 'waiting_input': {
|
||||
// 等待用户输入(对话流节点或设计预览)
|
||||
waitingForInput.value = true;
|
||||
waitingConfig.value = event.waiting_config || event.config;
|
||||
|
||||
const configData = event.waiting_config || (event as any).config;
|
||||
|
||||
// 检查是否是设计预览类型
|
||||
if (configData?.type === 'design_preview') {
|
||||
const waitingContent = `**${configData.title}**\n\n${configData.message || $t('ai-platform.workflow.editor.chatPanel.designPreviewHint')}\n\n????????/??/??????????`;
|
||||
// 检查是否是应用设计类型
|
||||
switch (configData.preview_type) {
|
||||
case 'app_design': {
|
||||
// 应用设计:打开专用的应用设计面板
|
||||
currentAppDesign.value = {
|
||||
type: 'app_design',
|
||||
title:
|
||||
configData.title ||
|
||||
$t('ai-platform.workflow.editor.chatPanel.appDesignTitle'),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
};
|
||||
showAppDesignPanel.value = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'app_settings': {
|
||||
// 应用设置:打开专用的应用设置面板
|
||||
currentAppSettings.value = {
|
||||
type: 'app_settings',
|
||||
title:
|
||||
configData.title ||
|
||||
$t('ai-platform.workflow.editor.chatPanel.appSettingsTitle'),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
layoutOptions: configData.layoutOptions || [],
|
||||
themeOptions: configData.themeOptions || [],
|
||||
};
|
||||
showAppSettingsPanel.value = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'dashboard_basic_info': {
|
||||
// 仪表盘基础信息:打开专用面板(在聊天框右侧)
|
||||
currentDashboardBasicInfo.value = {
|
||||
type: 'dashboard_basic_info',
|
||||
title:
|
||||
configData.title ||
|
||||
$t(
|
||||
'ai-platform.workflow.editor.chatPanel.dashboardBasicInfoTitle',
|
||||
),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
};
|
||||
showDashboardBasicInfoPanel.value = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'dashboard_design': {
|
||||
// 仪表盘设计:打开设计器面板(在聊天框右侧)
|
||||
currentDashboardDesign.value = {
|
||||
type: 'dashboard_design',
|
||||
title:
|
||||
configData.title ||
|
||||
$t(
|
||||
'ai-platform.workflow.editor.chatPanel.dashboardDesignTitle',
|
||||
),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
};
|
||||
showDashboardDesignPanel.value = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'dashboard_publish': {
|
||||
// 仪表盘发布:打开发布确认面板(在聊天框右侧)
|
||||
currentDashboardPublish.value = {
|
||||
type: 'dashboard_publish',
|
||||
title:
|
||||
configData.title ||
|
||||
$t(
|
||||
'ai-platform.workflow.editor.chatPanel.dashboardPublishTitle',
|
||||
),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
};
|
||||
showDashboardPublishPanel.value = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'system_summary': {
|
||||
// 系统总结:打开总结展示面板
|
||||
currentSystemSummary.value = {
|
||||
type: 'system_summary',
|
||||
title:
|
||||
configData.title ||
|
||||
$t('ai-platform.workflow.editor.chatPanel.systemSummaryTitle'),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
};
|
||||
showSystemSummaryPanel.value = true;
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// 其他设计预览:打开通用设计编辑面板
|
||||
currentDesign.value = {
|
||||
type: configData.preview_type,
|
||||
title:
|
||||
configData.title ||
|
||||
$t('ai-platform.workflow.editor.chatPanel.designPreviewTitle'),
|
||||
data: configData.data || {},
|
||||
nodeId: event.node_id || '',
|
||||
form_fields: configData.form_fields || [], // 传递表单字段列表(用于列表设计)
|
||||
table_configs: configData.table_configs || [], // 传递数据表配置(用于表单设计)
|
||||
};
|
||||
showDesignPanel.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示提示消息
|
||||
const waitingContent = `**${configData.title}**\n\n${configData.message || $t('ai-platform.workflow.editor.chatPanel.designPreviewHint')}`;
|
||||
const initialMsg = messages.value.find((m) => m.id === msgId);
|
||||
if (initialMsg && !initialMsg.content?.trim()) {
|
||||
updateAssistantMessage(msgId, {
|
||||
@@ -570,15 +727,20 @@ const handleStreamEvent = (event: WorkflowStreamEvent, msgId: string) => {
|
||||
messages.value.push(newMsg);
|
||||
}
|
||||
} else {
|
||||
// 普通对话流交互
|
||||
const waitingContent = getWaitingPrompt(configData);
|
||||
|
||||
// 检查初始消息是否还是 typing indicator(没有内容)
|
||||
const initialMsg = messages.value.find((m) => m.id === msgId);
|
||||
if (initialMsg && !initialMsg.content?.trim()) {
|
||||
// 更新初始消息为等待输入的内容
|
||||
updateAssistantMessage(msgId, {
|
||||
status: 'completed',
|
||||
content: waitingContent,
|
||||
interaction: configData as any,
|
||||
});
|
||||
} else {
|
||||
// 已有内容,创建新的助手消息
|
||||
const newMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'assistant',
|
||||
@@ -590,7 +752,7 @@ const handleStreamEvent = (event: WorkflowStreamEvent, msgId: string) => {
|
||||
messages.value.push(newMsg);
|
||||
}
|
||||
}
|
||||
|
||||
running.value = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -789,6 +951,209 @@ const handleUpdateMessage = (
|
||||
};
|
||||
|
||||
// 处理设计预览确认
|
||||
const handleDesignConfirm = (data: Record<string, any>) => {
|
||||
showDesignPanel.value = false;
|
||||
currentDesign.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t('ai-platform.workflow.editor.chatPanel.confirmDesign'),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递编辑后的数据
|
||||
resumeWorkflow(JSON.stringify(data));
|
||||
};
|
||||
|
||||
// 处理设计预览关闭
|
||||
const handleDesignClose = () => {
|
||||
showDesignPanel.value = false;
|
||||
currentDesign.value = undefined;
|
||||
};
|
||||
|
||||
// 处理应用设计确认
|
||||
const handleAppDesignConfirm = (data: Record<string, any>) => {
|
||||
showAppDesignPanel.value = false;
|
||||
currentAppDesign.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t('ai-platform.workflow.editor.chatPanel.confirmAppDesign'),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递编辑后的数据
|
||||
resumeWorkflow(JSON.stringify(data));
|
||||
};
|
||||
|
||||
// 处理应用设计面板关闭
|
||||
const handleAppDesignClose = () => {
|
||||
showAppDesignPanel.value = false;
|
||||
currentAppDesign.value = undefined;
|
||||
};
|
||||
|
||||
// 处理应用设置确认
|
||||
const handleAppSettingsConfirm = (data: Record<string, any>) => {
|
||||
showAppSettingsPanel.value = false;
|
||||
currentAppSettings.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t('ai-platform.workflow.editor.chatPanel.confirmAppSettings'),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递编辑后的数据
|
||||
resumeWorkflow(JSON.stringify(data));
|
||||
};
|
||||
|
||||
// 处理应用设置面板关闭
|
||||
const handleAppSettingsClose = () => {
|
||||
showAppSettingsPanel.value = false;
|
||||
currentAppSettings.value = undefined;
|
||||
};
|
||||
|
||||
// 处理仪表盘基础信息确认
|
||||
const handleDashboardBasicInfoConfirm = (data: Record<string, any>) => {
|
||||
showDashboardBasicInfoPanel.value = false;
|
||||
currentDashboardBasicInfo.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t(
|
||||
'ai-platform.workflow.editor.chatPanel.confirmDashboardBasicInfo',
|
||||
),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递编辑后的数据
|
||||
resumeWorkflow(JSON.stringify(data));
|
||||
};
|
||||
|
||||
// 处理仪表盘基础信息面板关闭
|
||||
const handleDashboardBasicInfoClose = () => {
|
||||
showDashboardBasicInfoPanel.value = false;
|
||||
currentDashboardBasicInfo.value = undefined;
|
||||
};
|
||||
|
||||
// 处理仪表盘设计确认
|
||||
const handleDashboardDesignConfirm = (data: Record<string, any>) => {
|
||||
showDashboardDesignPanel.value = false;
|
||||
currentDashboardDesign.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t('ai-platform.workflow.editor.chatPanel.confirmDashboardDesign'),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递编辑后的数据
|
||||
resumeWorkflow(JSON.stringify(data));
|
||||
};
|
||||
|
||||
// 处理仪表盘设计面板关闭
|
||||
const handleDashboardDesignClose = () => {
|
||||
showDashboardDesignPanel.value = false;
|
||||
currentDashboardDesign.value = undefined;
|
||||
};
|
||||
|
||||
// 处理仪表盘发布确认
|
||||
const handleDashboardPublishConfirm = (data: Record<string, any>) => {
|
||||
console.log('[ChatPanel] 接收到发布确认数据:', data);
|
||||
showDashboardPublishPanel.value = false;
|
||||
currentDashboardPublish.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t('ai-platform.workflow.editor.chatPanel.publishToMenu', {
|
||||
name: data.menu_name,
|
||||
}),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递发布数据
|
||||
const userInputStr = JSON.stringify(data);
|
||||
console.log('[ChatPanel] 传递给 resumeWorkflow 的数据:', userInputStr);
|
||||
resumeWorkflow(userInputStr);
|
||||
};
|
||||
|
||||
// 处理仪表盘发布面板关闭
|
||||
const handleDashboardPublishClose = () => {
|
||||
showDashboardPublishPanel.value = false;
|
||||
currentDashboardPublish.value = undefined;
|
||||
};
|
||||
|
||||
// 处理系统总结确认
|
||||
const handleSystemSummaryConfirm = (data: Record<string, any>) => {
|
||||
showSystemSummaryPanel.value = false;
|
||||
currentSystemSummary.value = undefined;
|
||||
|
||||
// 添加用户确认消息
|
||||
const userMsg: ChatMessage = {
|
||||
id: generateId(),
|
||||
role: 'user',
|
||||
content: $t('ai-platform.workflow.editor.chatPanel.complete'),
|
||||
timestamp: new Date(),
|
||||
};
|
||||
messages.value.push(userMsg);
|
||||
|
||||
// 重置等待状态
|
||||
waitingForInput.value = false;
|
||||
waitingConfig.value = null;
|
||||
|
||||
// 恢复工作流,传递确认数据
|
||||
resumeWorkflow(JSON.stringify(data));
|
||||
};
|
||||
|
||||
// 处理系统总结面板关闭
|
||||
const handleSystemSummaryClose = () => {
|
||||
showSystemSummaryPanel.value = false;
|
||||
currentSystemSummary.value = undefined;
|
||||
};
|
||||
|
||||
// 组件卸载时取消流
|
||||
onUnmounted(() => {
|
||||
cancelStream?.();
|
||||
});
|
||||
@@ -884,17 +1249,66 @@ onUnmounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- 设计编辑面板 -->
|
||||
<DesignEditorPanel
|
||||
:visible="showDesignPanel"
|
||||
:design="currentDesign"
|
||||
@update:visible="showDesignPanel = $event"
|
||||
@confirm="handleDesignConfirm"
|
||||
@close="handleDesignClose"
|
||||
/>
|
||||
|
||||
<!-- 应用设计面板 -->
|
||||
<AppDesignPanel
|
||||
:visible="showAppDesignPanel"
|
||||
:design="currentAppDesign"
|
||||
@update:visible="showAppDesignPanel = $event"
|
||||
@confirm="handleAppDesignConfirm"
|
||||
@close="handleAppDesignClose"
|
||||
/>
|
||||
|
||||
<!-- 应用设置面板 -->
|
||||
<AppSettingsPanel
|
||||
:visible="showAppSettingsPanel"
|
||||
:settings="currentAppSettings"
|
||||
@update:visible="showAppSettingsPanel = $event"
|
||||
@confirm="handleAppSettingsConfirm"
|
||||
@close="handleAppSettingsClose"
|
||||
/>
|
||||
|
||||
<!-- 仪表盘基础信息面板 -->
|
||||
<DashboardBasicInfoConfirmPanel
|
||||
:visible="showDashboardBasicInfoPanel"
|
||||
:basic-info="currentDashboardBasicInfo"
|
||||
@update:visible="showDashboardBasicInfoPanel = $event"
|
||||
@confirm="handleDashboardBasicInfoConfirm"
|
||||
@close="handleDashboardBasicInfoClose"
|
||||
/>
|
||||
|
||||
<!-- 仪表盘设计面板 -->
|
||||
<DashboardDesignConfirmPanel
|
||||
:visible="showDashboardDesignPanel"
|
||||
:design="currentDashboardDesign"
|
||||
@update:visible="showDashboardDesignPanel = $event"
|
||||
@confirm="handleDashboardDesignConfirm"
|
||||
@close="handleDashboardDesignClose"
|
||||
/>
|
||||
|
||||
<!-- 仪表盘发布面板 -->
|
||||
<DashboardPublishConfirmPanel
|
||||
:visible="showDashboardPublishPanel"
|
||||
:publish-data="currentDashboardPublish"
|
||||
@update:visible="showDashboardPublishPanel = $event"
|
||||
@confirm="handleDashboardPublishConfirm"
|
||||
@close="handleDashboardPublishClose"
|
||||
/>
|
||||
|
||||
<!-- 系统总结面板 -->
|
||||
<SystemSummaryConfirmPanel
|
||||
:visible="showSystemSummaryPanel"
|
||||
:data="currentSystemSummary"
|
||||
@update:visible="showSystemSummaryPanel = $event"
|
||||
@confirm="handleSystemSummaryConfirm"
|
||||
@close="handleSystemSummaryClose"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+418
@@ -2,16 +2,20 @@
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import {
|
||||
AppWindow,
|
||||
BookOpen,
|
||||
Bot,
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
CircleHelp,
|
||||
ClipboardCheck,
|
||||
Code,
|
||||
Combine,
|
||||
Database,
|
||||
FileText,
|
||||
Globe,
|
||||
HelpCircle,
|
||||
LayoutDashboard,
|
||||
LayoutTemplate,
|
||||
ListChecks,
|
||||
MessageSquareText,
|
||||
@@ -61,9 +65,21 @@ const icons: any = {
|
||||
// 合并节点
|
||||
merge: Combine,
|
||||
// 表单节点
|
||||
form_basic_info: FileText,
|
||||
form_database_design: Database,
|
||||
form_database_create: Database,
|
||||
// 应用节点
|
||||
app_create: AppWindow,
|
||||
app_design: LayoutDashboard,
|
||||
app_settings: LayoutDashboard,
|
||||
app_update: LayoutDashboard,
|
||||
// 仪表盘节点
|
||||
dashboard_basic_info: LayoutDashboard,
|
||||
dashboard_design: LayoutDashboard,
|
||||
dashboard_create: LayoutDashboard,
|
||||
dashboard_publish: LayoutDashboard,
|
||||
// 系统总结节点
|
||||
system_summary: ClipboardCheck,
|
||||
// 子流程节点
|
||||
subflow: Play,
|
||||
// 知识库检索节点
|
||||
@@ -123,6 +139,92 @@ const availableNodes = computed(() => {
|
||||
|
||||
// 根据节点类型获取输出变量 schema
|
||||
switch (node.type) {
|
||||
case 'app_create': {
|
||||
variables = [
|
||||
{
|
||||
key: 'app_id',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.appId'),
|
||||
},
|
||||
{
|
||||
key: 'app_code',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.appCode'),
|
||||
},
|
||||
{
|
||||
key: 'app_name',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.appName'),
|
||||
},
|
||||
{
|
||||
key: 'success',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.createSuccess',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'app_design': {
|
||||
variables = [
|
||||
{
|
||||
key: 'design_content',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.designContent',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'design_title',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.designTitle',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'confirmed',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.isConfirmed',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'app_settings': {
|
||||
variables = [
|
||||
{
|
||||
key: 'settings',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.appSettings',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'confirmed',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.isConfirmed',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'app_update': {
|
||||
variables = [
|
||||
{
|
||||
key: 'update_success',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.updateSuccess',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'config_id',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.configId',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'update_message',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.updateMessage',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'choice': {
|
||||
const choiceVar = node.data.variable_name || 'user_choice';
|
||||
variables = [
|
||||
@@ -178,6 +280,96 @@ const availableNodes = computed(() => {
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'dashboard_basic_info': {
|
||||
variables = [
|
||||
{
|
||||
key: 'dashboard_basic_info',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.dashboardBasicInfo',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'dashboard_name',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.dashboardName',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'dashboard_code',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.dashboardCode',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'dashboard_create': {
|
||||
variables = [
|
||||
{
|
||||
key: 'dashboard_id',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.dashboardId',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'dashboard_code',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.dashboardCode',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'page_meta',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.pageMeta',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'dashboard_design': {
|
||||
variables = [
|
||||
{
|
||||
key: 'page_config',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.pageConfig',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'design_title',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.designTitle',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'confirmed',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.isConfirmed',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'dashboard_publish': {
|
||||
variables = [
|
||||
{
|
||||
key: 'menu_id',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.menuId'),
|
||||
},
|
||||
{
|
||||
key: 'route_path',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.routePath',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'publish_result',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.publishResult',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'db_delete': {
|
||||
const deleteOutputVar = node.data.output_variable || 'delete_result';
|
||||
variables = [
|
||||
@@ -268,6 +460,205 @@ const availableNodes = computed(() => {
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_basic_info': {
|
||||
variables = [
|
||||
{
|
||||
key: 'form_basic_info',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formBasicInfoObj',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_name',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formName',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_code',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formCode',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_type',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formType',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_description',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formDescription',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_sort',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formSort',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_create': {
|
||||
variables = [
|
||||
{
|
||||
key: 'form_id',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.formId'),
|
||||
},
|
||||
{
|
||||
key: 'form_code',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formCode',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_meta',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formMeta',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_database_create': {
|
||||
variables = [
|
||||
{
|
||||
key: 'creation_result',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.creationResult',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'all_tables_ready',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.allTablesReady',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'created_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.createdCount',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'error_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.errorCount',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'schema_name',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.schemaName',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'table_name',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.tableName',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_database_design': {
|
||||
variables = [
|
||||
{
|
||||
key: 'database_design',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.dbDesignObj',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'table_name',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.tableName',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'field_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.fieldCount',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_list_design': {
|
||||
variables = [
|
||||
{
|
||||
key: 'list_config',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.listConfig',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'query_field_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.queryFieldCount',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'column_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.columnCount',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_publish': {
|
||||
variables = [
|
||||
{
|
||||
key: 'menu_id',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.menuId'),
|
||||
},
|
||||
{
|
||||
key: 'route_path',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.routePath',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'publish_result',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.publishResult',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'form_ui_design': {
|
||||
variables = [
|
||||
{
|
||||
key: 'form_ui_design',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formUiDesign',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'form_code',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.formCode',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'field_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.fieldCount',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'group_count',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.groupCount',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'http': {
|
||||
variables = [
|
||||
{
|
||||
@@ -574,6 +965,33 @@ const availableNodes = computed(() => {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'system_summary': {
|
||||
variables = [
|
||||
{
|
||||
key: 'summary',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.summaryData',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'total_forms',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.totalForms',
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'has_app',
|
||||
label: $t('ai-platform.workflow.editor.variableSelector.hasApp'),
|
||||
},
|
||||
{
|
||||
key: 'has_dashboard',
|
||||
label: $t(
|
||||
'ai-platform.workflow.editor.variableSelector.hasDashboard',
|
||||
),
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
case 'template': {
|
||||
const templateOutputVar =
|
||||
node.data.output_variable || 'template_result';
|
||||
|
||||
Reference in New Issue
Block a user