From e7dc89d6aa73a188ba533dd673b6257905d1aecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cls=5F=E5=AE=81=E6=B3=A2=E6=9C=AC=E6=9C=BA?= <908705107@qq.com> Date: Tue, 9 Jun 2026 22:29:53 +0800 Subject: [PATCH] Improve lightweight AI design preview dialog --- .../ai-chat-panel/DesignPreviewDialog.vue | 208 +++++++++++++++--- 1 file changed, 172 insertions(+), 36 deletions(-) diff --git a/web/apps/web-ele/src/components/ai-chat-panel/DesignPreviewDialog.vue b/web/apps/web-ele/src/components/ai-chat-panel/DesignPreviewDialog.vue index 9db5168..3f23525 100644 --- a/web/apps/web-ele/src/components/ai-chat-panel/DesignPreviewDialog.vue +++ b/web/apps/web-ele/src/components/ai-chat-panel/DesignPreviewDialog.vue @@ -10,11 +10,11 @@ import { } from '@element-plus/icons-vue'; import { + ElAlert, ElButton, ElDescriptions, ElDescriptionsItem, ElDialog, - ElDivider, ElInput, ElMessage, ElScrollbar, @@ -39,6 +39,7 @@ const emit = defineEmits<{ }>(); const draftText = ref('{}'); +const contentText = ref(''); const sourceData = computed(() => { return ( @@ -52,7 +53,16 @@ const sourceData = computed(() => { ); }); -const payload = computed(() => { +const sourceType = computed(() => { + const source = sourceData.value as Record; + if (source.type) return String(source.type); + if (props.settings) return 'app_settings'; + if (props.publishData) return 'dashboard_publish'; + if (props.basicInfo) return 'dashboard_basic_info'; + return 'design'; +}); + +const payload = computed>(() => { const source = sourceData.value as Record; if ('data' in source && source.data && typeof source.data === 'object') { return source.data; @@ -60,30 +70,80 @@ const payload = computed(() => { return source; }); +const typeLabelMap: Record = { + app_design: '应用设计方案', + app_settings: '应用设置方案', + dashboard_basic_info: '仪表盘基础信息', + dashboard_design: '仪表盘设计方案', + dashboard_publish: '仪表盘发布配置', + database_design: '数据库设计方案', + form_basic_info: '表单基础信息', + form_ui_design: '表单界面设计', + list_config: '列表配置方案', + system_summary: '系统生成总结', +}; + const dialogTitle = computed(() => { const source = sourceData.value as Record; - return source.title || props.title || 'AI 方案确认'; + return ( + source.title || + props.title || + typeLabelMap[sourceType.value] || + 'AI 方案确认' + ); +}); + +const primaryText = computed(() => { + const source = payload.value; + return ( + source.content || + source.design_suggestion || + source.summary || + source.description || + '' + ); }); const summaryItems = computed(() => { - const source = payload.value as Record; - const keys = ['name', 'title', 'description', 'code', 'type', 'category']; - return keys - .filter((key) => source[key] !== undefined && source[key] !== null) - .map((key) => ({ key, value: String(source[key]) })); + const source = payload.value; + const candidates: Array<[string, any]> = [ + ['名称', source.name || source.title || source.design_title], + ['编码', source.code || source.dashboard_code || source.form_code], + ['类型', source.type || source.category], + ['路由', source.route_path || source.path], + ['菜单', source.menu_name], + ['图标', source.menu_icon], + ['排序', source.menu_order], + ['说明', source.description], + ]; + + return candidates + .filter(([, value]) => value !== undefined && value !== null && value !== '') + .map(([label, value]) => ({ label, value: String(value) })); }); const fieldItems = computed(() => { - const source = payload.value as Record; + const source = payload.value; const fields = - source.schema_fields || source.form_fields || source.fields || source.schema?.fields; - return Array.isArray(fields) ? fields.slice(0, 12) : []; + source.schema_fields || + source.form_fields || + source.fields || + source.schema?.fields; + return Array.isArray(fields) ? fields.slice(0, 16) : []; }); const tableItems = computed(() => { - const source = payload.value as Record; + const source = payload.value; const tables = source.data_sources || source.table_configs || source.tables; - return Array.isArray(tables) ? tables.slice(0, 8) : []; + return Array.isArray(tables) ? tables.slice(0, 10) : []; +}); + +const routePreview = computed(() => { + const source = payload.value; + if (source.route_path) return source.route_path; + if (source.dashboard_code) return `/dashboard/${source.dashboard_code}`; + if (source.form_code) return `/form-render/${source.form_code}`; + return ''; }); watch( @@ -91,11 +151,24 @@ watch( () => { if (props.visible) { draftText.value = JSON.stringify(payload.value || {}, null, 2); + contentText.value = primaryText.value; } }, { immediate: true }, ); +function mergedDraft() { + const data = JSON.parse(draftText.value || '{}'); + if ( + contentText.value && + (sourceType.value === 'app_design' || sourceType.value === 'dashboard_design') + ) { + if ('content' in data) data.content = contentText.value; + else data.design_suggestion = contentText.value; + } + return data && typeof data === 'object' ? data : { value: data }; +} + function handleClose() { emit('update:visible', false); emit('close'); @@ -103,11 +176,10 @@ function handleClose() { function handleConfirm() { try { - const data = JSON.parse(draftText.value || '{}'); - emit('confirm', data && typeof data === 'object' ? data : { value: data }); + emit('confirm', mergedDraft()); emit('update:visible', false); } catch { - ElMessage.error('JSON 格式不正确'); + ElMessage.error('JSON 格式不正确,请检查后再确认'); } } @@ -125,7 +197,7 @@ function handleVisibleChange(visible: boolean) {
-
方案概要
+
+
+
{{ typeLabelMap[sourceType] || '方案预览' }}
+
确认后将把当前结构化配置回传给工作流继续执行
+
+ {{ sourceType }} +
+ + + + + {{ item.value }}
当前方案未提供概要字段
- +