support self-check

This commit is contained in:
锦恢 2025-07-03 13:48:58 +08:00
parent 9294275874
commit dcabd47a20
11 changed files with 104 additions and 89 deletions

View File

@ -1,15 +1,15 @@
<template> <template>
<el-dialog v-model="showDiagram" width="800px" append-to-body class="no-padding-dialog"> <el-dialog v-model="showDiagram" width="800px" append-to-body class="no-padding-dialog">
<template #title> <template #header>
<div style="display: flex; align-items: center;"> <div style="display: flex; align-items: center;">
<span>Tool Diagram</span> <span>Tool Diagram</span>
&ensp; &ensp;
<el-button size="small" type="primary" @click="() => context.reset()">重置</el-button> <el-button size="small" type="primary" @click="() => context.reset()">{{ t("reset") }}</el-button>
<!-- 自检程序弹出表单 --> <!-- 自检程序弹出表单 -->
<el-popover placement="top" width="350" trigger="click" v-model:visible="testFormVisible"> <el-popover placement="top" width="350" trigger="click" v-model:visible="testFormVisible">
<template #reference> <template #reference>
<el-button size="small" type="primary"> <el-button size="small" type="primary">
开启自检程序 {{ t('start-auto-detect') }}
</el-button> </el-button>
</template> </template>
@ -20,9 +20,9 @@
<span style="opacity: 0.7;">enableXmlWrapper</span> <span style="opacity: 0.7;">enableXmlWrapper</span>
</div> </div>
<div style="text-align: right;"> <div style="text-align: right;">
<el-button size="small" @click="testFormVisible = false">取消</el-button> <el-button size="small" @click="testFormVisible = false">{{ t("cancel") }}</el-button>
<el-button size="small" type="primary" @click="onTestConfirm"> <el-button size="small" type="primary" @click="onTestConfirm">
确认 {{ t("confirm") }}
</el-button> </el-button>
</div> </div>
</el-popover> </el-popover>
@ -44,8 +44,10 @@ import { nextTick, provide, ref } from 'vue';
import Diagram from './diagram.vue'; import Diagram from './diagram.vue';
import { makeNodeTest, topoSortParallel, type DiagramContext, type DiagramState } from './diagram'; import { makeNodeTest, topoSortParallel, type DiagramContext, type DiagramState } from './diagram';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n';
const showDiagram = ref(true); const showDiagram = ref(true);
const { t } = useI18n();
const caption = ref(''); const caption = ref('');
const showCaption = ref(false); const showCaption = ref(false);

View File

@ -327,20 +327,24 @@ function renderSvg() {
.attr('font-weight', 600) .attr('font-weight', 600)
.text(d => d.labels?.[0]?.text || 'Tool'); .text(d => d.labels?.[0]?.text || 'Tool');
// nodeGroupEnter.append('g').attr('class', 'node-status');
nodeGroupEnter.append('g')
.attr('class', 'node-status') // enter+update
.each(function (d) { const nodeStatusGroup = nodeGroup.merge(nodeGroupEnter).select('.node-status');
const status = state.dataView.get(d.id)?.status || 'waiting';
//
nodeStatusGroup.each(function (d) {
const g = d3.select(this); const g = d3.select(this);
g.selectAll('*').remove(); //
const status = state.dataView.get(d.id)?.status || 'waiting';
if (status === 'running') { if (status === 'running') {
// +
g.append('circle') g.append('circle')
.attr('cx', d.width / 2 - 32) .attr('cx', d.width / 2 - 32)
.attr('cy', d.height - 16) .attr('cy', d.height - 16)
.attr('r', 6) // .attr('r', 6)
.attr('fill', 'none') .attr('fill', 'none')
.attr('stroke', 'var(--main-color)') // 使 .attr('stroke', 'var(--main-color)')
.attr('stroke-width', 3) .attr('stroke-width', 3)
.attr('stroke-dasharray', 20) .attr('stroke-dasharray', 20)
.attr('stroke-dashoffset', 0) .attr('stroke-dashoffset', 0)
@ -376,7 +380,7 @@ function renderSvg() {
g.append('circle') g.append('circle')
.attr('cx', d.width / 2 - 32) .attr('cx', d.width / 2 - 32)
.attr('cy', d.height - 16) .attr('cy', d.height - 16)
.attr('r', 6) // waiting .attr('r', 6)
.attr('fill', 'none') .attr('fill', 'none')
.attr('stroke', '#4caf50') .attr('stroke', '#4caf50')
.attr('stroke-width', 3); .attr('stroke-width', 3);
@ -390,7 +394,7 @@ function renderSvg() {
g.append('circle') g.append('circle')
.attr('cx', d.width / 2 - 32) .attr('cx', d.width / 2 - 32)
.attr('cy', d.height - 16) .attr('cy', d.height - 16)
.attr('r', 6) // waiting .attr('r', 6)
.attr('fill', 'none') .attr('fill', 'none')
.attr('stroke', '#f44336') .attr('stroke', '#f44336')
.attr('stroke-width', 3); .attr('stroke-width', 3);

View File

@ -184,5 +184,6 @@
"export-filename": "اسم ملف التصدير", "export-filename": "اسم ملف التصدير",
"how-to-use": "كيفية الاستخدام؟", "how-to-use": "كيفية الاستخدام؟",
"is-required": "هو حقل مطلوب", "is-required": "هو حقل مطلوب",
"edit-ai-mook-prompt": "تحرير إشارات AI Mook" "edit-ai-mook-prompt": "تحرير إشارات AI Mook",
"start-auto-detect": "بدء عملية الفحص الذاتي"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "Exportdateiname", "export-filename": "Exportdateiname",
"how-to-use": "Wie benutzt man?", "how-to-use": "Wie benutzt man?",
"is-required": "ist ein Pflichtfeld", "is-required": "ist ein Pflichtfeld",
"edit-ai-mook-prompt": "AI Mook-Prompts bearbeiten" "edit-ai-mook-prompt": "AI Mook-Prompts bearbeiten",
"start-auto-detect": "Selbsttest starten"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "Export filename", "export-filename": "Export filename",
"how-to-use": "How to use?", "how-to-use": "How to use?",
"is-required": "is a required field", "is-required": "is a required field",
"edit-ai-mook-prompt": "Edit AI Mook prompts" "edit-ai-mook-prompt": "Edit AI Mook prompts",
"start-auto-detect": "Start self-check"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "Nom du fichier d'exportation", "export-filename": "Nom du fichier d'exportation",
"how-to-use": "Comment utiliser ?", "how-to-use": "Comment utiliser ?",
"is-required": "est un champ obligatoire", "is-required": "est un champ obligatoire",
"edit-ai-mook-prompt": "Modifier les invites AI Mook" "edit-ai-mook-prompt": "Modifier les invites AI Mook",
"start-auto-detect": "Démarrer l'autovérification"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "エクスポートファイル名", "export-filename": "エクスポートファイル名",
"how-to-use": "使用方法", "how-to-use": "使用方法",
"is-required": "は必須フィールドです", "is-required": "は必須フィールドです",
"edit-ai-mook-prompt": "AI Mookプロンプトを編集" "edit-ai-mook-prompt": "AI Mookプロンプトを編集",
"start-auto-detect": "自己診断を開始"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "내보내기 파일 이름", "export-filename": "내보내기 파일 이름",
"how-to-use": "사용 방법?", "how-to-use": "사용 방법?",
"is-required": "는 필수 필드입니다", "is-required": "는 필수 필드입니다",
"edit-ai-mook-prompt": "AI Mook 프롬프트 편집" "edit-ai-mook-prompt": "AI Mook 프롬프트 편집",
"start-auto-detect": "자체 점검 시작"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "Имя файла экспорта", "export-filename": "Имя файла экспорта",
"how-to-use": "Как использовать?", "how-to-use": "Как использовать?",
"is-required": "является обязательным полем", "is-required": "является обязательным полем",
"edit-ai-mook-prompt": "Редактировать подсказки AI Mook" "edit-ai-mook-prompt": "Редактировать подсказки AI Mook",
"start-auto-detect": "Запустить самопроверку"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "导出文件名", "export-filename": "导出文件名",
"how-to-use": "如何使用?", "how-to-use": "如何使用?",
"is-required": "是必填字段", "is-required": "是必填字段",
"edit-ai-mook-prompt": "编辑 AI Mook 提示词" "edit-ai-mook-prompt": "编辑 AI Mook 提示词",
"start-auto-detect": "开启自检程序"
} }

View File

@ -184,5 +184,6 @@
"export-filename": "導出文件名", "export-filename": "導出文件名",
"how-to-use": "如何使用?", "how-to-use": "如何使用?",
"is-required": "是必填欄位", "is-required": "是必填欄位",
"edit-ai-mook-prompt": "編輯AI Mook提示詞" "edit-ai-mook-prompt": "編輯AI Mook提示詞",
"start-auto-detect": "開啟自檢程序"
} }