feat: 新增工作流组件

This commit is contained in:
xlsea 2024-05-31 10:59:31 +08:00
parent 3ebca5bcfc
commit d52b787de8
11 changed files with 298 additions and 179 deletions

View File

@ -4,7 +4,13 @@ import type { DataTableColumn } from 'naive-ui';
import { NButton, NTag } from 'naive-ui';
import { useFlowStore } from '../stores';
import { fetchBatchDetail, fetchJobDetail, fetchTaskList, fetchWorkflowNodeRetry } from '../api';
import { executorTypeRecord, operationReasonRecord, taskBatchStatusRecord } from '../constants/business';
import {
jobExecutorEnum,
jobOperationReasonEnum,
jobStatusEnum,
taskBatchStatusEnum,
taskBatchStatusRecord
} from '../constants/business';
import { $t } from '../locales';
import { isNotNull } from '../utils/common';
import LogDrawer from './log-drawer.vue';
@ -234,20 +240,12 @@ const columns = ref<DataTableColumn<Flow.JobBatchType>[]>([
}
]);
function tagColor(tagIndex: number) {
const tagMap: Record<number, ThemeColor> = {
0: 'error',
1: 'info',
2: 'success',
3: 'warning',
4: 'primary'
function getTagColor(color: string) {
return {
color: `${color}18`,
textColor: color,
borderColor: `${color}58`
};
if (tagIndex === null || tagIndex < 0) {
return tagMap[1];
}
return tagMap[tagIndex % 5];
}
const onUpdatePage = (page: number) => {
@ -263,40 +261,54 @@ const onUpdatePage = (page: number) => {
<NDrawerContent title="任务批次详情" closable>
<NTabs v-if="idList && idList.length > 0" v-model:value="currentIndex" type="segment" animated>
<NTabPane v-for="(item, index) in idList" :key="index" :name="index + 1" :tab="item">
<NDescriptions label-placement="top" bordered :column="2">
<NDescriptionsItem :label="$t('snail.jobBatch.groupName')">{{ jobData?.groupName }}</NDescriptionsItem>
<NSpin :show="spinning">
<NDescriptions label-placement="left" bordered :column="2">
<NDescriptionsItem :label="$t('snail.jobBatch.groupName')">{{ jobData?.groupName }}</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.jobName')">{{ jobData?.jobName }}</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.jobName')">{{ jobData?.jobName }}</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.taskBatchStatus')">
<NTag v-if="isNotNull(jobData.taskBatchStatus)" :type="tagColor(jobData.taskBatchStatus!)">
{{ $t(taskBatchStatusRecord[jobData.taskBatchStatus!]) }}
</NTag>
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.taskBatchStatus')">
<NTag
v-if="isNotNull(jobData.taskBatchStatus)"
:color="getTagColor(taskBatchStatusEnum[jobData.taskBatchStatus!].color )"
>
{{ taskBatchStatusEnum[jobData.taskBatchStatus!].title }}
</NTag>
<NTag v-if="isNotNull(jobData.jobStatus)" :color="getTagColor(jobStatusEnum[jobData.jobStatus!].color)">
{{ $t(jobStatusEnum[jobData.jobStatus!].name) }}
</NTag>
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.executionAt')">
{{ jobData?.executionAt }}
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.executionAt')">
{{ jobData?.executionAt }}
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.operationReason')">
<NTag v-if="isNotNull(jobData.operationReason)" :type="tagColor(jobData.operationReason!)">
{{ $t(operationReasonRecord[jobData.operationReason!]) }}
</NTag>
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.operationReason')">
<NTag
v-if="isNotNull(jobData.operationReason)"
:color="getTagColor(jobOperationReasonEnum[jobData.operationReason!].color)"
>
{{ $t(jobOperationReasonEnum[jobData.operationReason!].name) }}
</NTag>
</NDescriptionsItem>
<NDescriptionsItem v-if="!slots.default" :label="$t('snail.jobBatch.executorType')">
<NTag v-if="isNotNull(jobData.executorType)" :type="tagColor(jobData.executorType!)">
{{ $t(executorTypeRecord[jobData.executorType!]) }}
</NTag>
</NDescriptionsItem>
<NDescriptionsItem v-if="!slots.default" :label="$t('snail.jobBatch.executorType')">
<NTag
v-if="isNotNull(jobData.executorType)"
:color="getTagColor(jobExecutorEnum[jobData.executorType!].color)"
>
{{ $t(jobExecutorEnum[jobData.executorType!].name) }}
</NTag>
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.executorInfo')" :span="2">
{{ jobData?.executorInfo }}
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.createDt')" :span="2">
{{ jobData?.createDt }}
</NDescriptionsItem>
</NDescriptions>
<NDescriptionsItem :label="$t('snail.jobBatch.executorInfo')" :span="2">
{{ jobData?.executorInfo }}
</NDescriptionsItem>
<NDescriptionsItem :label="$t('snail.jobBatch.createDt')" :span="2">
{{ jobData?.createDt }}
</NDescriptionsItem>
</NDescriptions>
</NSpin>
<slot></slot>
<NCard
:bordered="false"

View File

@ -52,6 +52,17 @@ export const workFlowNodeStatusRecord: Record<Flow.WorkFlowNodeStatus, FlowI18n.
export const workFlowNodeStatusOptions = transformRecordToOption(workFlowNodeStatusRecord);
export const jobStatusEnum: Flow.JobTagType = {
0: {
name: 'snail.enum.workFlowNodeStatus.close',
color: '#dc3f41'
},
1: {
name: 'snail.enum.workFlowNodeStatus.open',
color: '#1b7ee5'
}
};
export const taskBatchStatusEnum: Record<Flow.TaskBatchStatus, Flow.TaskBatchStatusType> = {
1: {
title: $t('snail.enum.taskBatchStatus.waiting'),
@ -103,19 +114,13 @@ export const taskBatchStatusEnum: Record<Flow.TaskBatchStatus, Flow.TaskBatchSta
}
};
export const taskBatchStatusRecord: Record<Flow.TaskBatchStatus, FlowI18n.I18nKey> = {
1: 'snail.enum.taskBatchStatus.waiting',
2: 'snail.enum.taskBatchStatus.running',
3: 'snail.enum.taskBatchStatus.success',
4: 'snail.enum.taskBatchStatus.fail',
5: 'snail.enum.taskBatchStatus.stop',
6: 'snail.enum.taskBatchStatus.cancel',
98: 'snail.enum.taskBatchStatus.decisionFailed',
99: 'snail.enum.taskBatchStatus.skip'
export const jobExecutorEnum: Flow.JobTagType = {
1: {
name: 'snail.enum.executorType.java',
color: '#d06892'
}
};
export const taskBatchStatusOptions = transformRecordToOption(taskBatchStatusRecord);
export const operationReasonRecord: Record<Flow.OperationReason, FlowI18n.I18nKey> = {
0: 'snail.enum.jobOperationReason.none',
1: 'snail.enum.jobOperationReason.taskExecutionTimeout',
@ -133,8 +138,85 @@ export const operationReasonRecord: Record<Flow.OperationReason, FlowI18n.I18nKe
13: 'snail.enum.jobOperationReason.workflowNodeClosedSkipExecution',
14: 'snail.enum.jobOperationReason.workflowDecisionFailed'
};
export const operationReasonOptions = transformRecordToOption(operationReasonRecord);
export const jobOperationReasonEnum: Flow.JobTagType = {
0: {
name: operationReasonRecord[0],
color: '#f5f5f5'
},
1: {
name: operationReasonRecord[1],
color: '#64a6ea'
},
2: {
name: operationReasonRecord[2],
color: '#1b7ee5'
},
3: {
name: operationReasonRecord[3],
color: '#087da1'
},
4: {
name: operationReasonRecord[4],
color: '#3a2f81'
},
5: {
name: operationReasonRecord[5],
color: '#c2238a'
},
6: {
name: operationReasonRecord[6],
color: '#23c28a'
},
7: {
name: operationReasonRecord[7],
color: '#bdc223'
},
8: {
name: operationReasonRecord[8],
color: '#23c28a'
},
9: {
name: operationReasonRecord[9],
color: '#23c28a'
},
10: {
name: operationReasonRecord[10],
color: '#bdc223'
},
11: {
name: operationReasonRecord[11],
color: '#bdc223'
},
12: {
name: operationReasonRecord[12],
color: '#23c28a'
},
13: {
name: operationReasonRecord[13],
color: '#3a2f81'
},
14: {
name: operationReasonRecord[14],
color: '#b63f1a'
}
};
export const taskBatchStatusRecord: Record<Flow.TaskBatchStatus, FlowI18n.I18nKey> = {
1: 'snail.enum.taskBatchStatus.waiting',
2: 'snail.enum.taskBatchStatus.running',
3: 'snail.enum.taskBatchStatus.success',
4: 'snail.enum.taskBatchStatus.fail',
5: 'snail.enum.taskBatchStatus.stop',
6: 'snail.enum.taskBatchStatus.cancel',
98: 'snail.enum.taskBatchStatus.decisionFailed',
99: 'snail.enum.taskBatchStatus.skip'
};
export const taskBatchStatusOptions = transformRecordToOption(taskBatchStatusRecord);
export const executorTypeRecord: Record<Flow.ExecutorType, FlowI18n.I18nKey> = {
1: 'snail.enum.executorType.java'
};

View File

@ -0,0 +1,87 @@
<script setup lang="ts">
import { nextTick, onMounted, ref } from 'vue';
import CodeMirror from 'vue-codemirror6';
import { oneDark } from '@codemirror/theme-one-dark';
import { javascript } from '@codemirror/lang-javascript';
import { expressionRecord, logicalConditionRecord } from '../constants/business';
defineOptions({
name: 'BranchDesc'
});
interface Props {
modelValue?: Flow.ConditionNodeType;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: () => ({})
});
const nodeExpression = ref('');
const theme = ref({
'.cm-line': {
fontSize: '18px'
},
'.cm-scroller': {
height: '520px',
overflowY: 'auto',
overflowX: 'hidden'
}
});
const createDocument = () => {
const desc = document.getElementById('branch-desc');
const descriptions = desc?.querySelector('.n-descriptions-table');
const body = descriptions?.querySelector('tbody');
const tr = document.createElement('tr');
tr.className = 'n-descriptions-table-row';
const th = document.createElement('th');
th.className = 'n-descriptions-table-header';
th.innerHTML = '条件表达式';
th.setAttribute('colspan', '4');
tr.appendChild(th);
body?.insertBefore(tr, body?.childNodes[4]);
const rows: HTMLCollectionOf<Element> = body!.getElementsByClassName('n-descriptions-table-row')!;
const element = rows[3] as HTMLElement;
element.querySelector('.n-descriptions-table-header')?.remove();
const content = element.querySelector('.n-descriptions-table-content') as HTMLElement;
content.setAttribute('style', 'padding: 0');
content?.setAttribute('colspan', '4');
};
onMounted(() => {
nextTick(() => {
createDocument();
});
if (props.modelValue.decision?.nodeExpression) {
nodeExpression.value = props.modelValue.decision.nodeExpression;
}
});
</script>
<template>
<NDescriptions id="branch-desc" :column="2" label-placement="left" bordered :label-style="{ width: '120px' }">
<NDescriptionsItem label="节点名称" :span="2">{{ modelValue.nodeName }}</NDescriptionsItem>
<NDescriptionsItem label="判定逻辑">
{{ logicalConditionRecord[modelValue.decision?.logicalCondition!] }}
</NDescriptionsItem>
<NDescriptionsItem label="表达式类型">
{{ expressionRecord[modelValue.decision?.expressionType!] }}
</NDescriptionsItem>
<NDescriptionsItem label="条件表达式" :span="2" :content-style="{ padding: 0 }">
<CodeMirror
v-model="nodeExpression"
readonly
disabled
:theme="theme"
basic
:lang="javascript()"
:extensions="[oneDark]"
/>
</NDescriptionsItem>
</NDescriptions>
</template>

View File

@ -1,9 +1,6 @@
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue';
import CodeMirror from 'vue-codemirror6';
import { oneDark } from '@codemirror/theme-one-dark';
import { javascript } from '@codemirror/lang-javascript';
import { expressionRecord, logicalConditionRecord } from '../constants/business';
import { ref, watch } from 'vue';
import BranchDesc from './branch-desc.vue';
defineOptions({
name: 'BranchDetail'
@ -26,58 +23,15 @@ interface Emits {
const emit = defineEmits<Emits>();
const visible = ref(false);
const nodeExpression = ref('');
const theme = ref({
'.cm-line': {
fontSize: '18px'
},
'.cm-scroller': {
height: '520px',
overflowY: 'auto',
overflowX: 'hidden'
}
});
const onClose = () => {
emit('update:open', false);
};
const createDocument = () => {
const desc = document.getElementById('branch-desc');
const descriptions = desc?.querySelector('.n-descriptions-table');
const body = descriptions?.querySelector('tbody');
const tr = document.createElement('tr');
tr.className = 'n-descriptions-table-row';
const th = document.createElement('th');
th.className = 'n-descriptions-table-header';
th.innerHTML = '条件表达式';
th.setAttribute('colspan', '4');
tr.appendChild(th);
body?.insertBefore(tr, body?.childNodes[4]);
const rows: HTMLCollectionOf<Element> = body!.getElementsByClassName('n-descriptions-table-row')!;
const element = rows[3] as HTMLElement;
element.querySelector('.n-descriptions-table-header')?.remove();
const content = element.querySelector('.n-descriptions-table-content') as HTMLElement;
content.setAttribute('style', 'padding: 0');
content?.setAttribute('colspan', '4');
};
watch(
() => props.open,
val => {
visible.value = val;
if (val) {
nextTick(() => {
createDocument();
});
if (props.modelValue.decision?.nodeExpression) {
nodeExpression.value = props.modelValue.decision.nodeExpression;
}
}
},
{ immediate: true }
);
@ -86,26 +40,7 @@ watch(
<template>
<NDrawer v-model:show="visible" placement="right" :width="500" display-directive="if" @after-leave="onClose">
<NDrawerContent title="决策详情">
<NDescriptions id="branch-desc" :column="2" label-placement="left" bordered :label-style="{ width: '120px' }">
<NDescriptionsItem label="节点名称" :span="2">{{ modelValue.nodeName }}</NDescriptionsItem>
<NDescriptionsItem label="判定逻辑">
{{ logicalConditionRecord[modelValue.decision?.logicalCondition!] }}
</NDescriptionsItem>
<NDescriptionsItem label="表达式类型">
{{ expressionRecord[modelValue.decision?.expressionType!] }}
</NDescriptionsItem>
<NDescriptionsItem label="条件表达式" :span="2" :content-style="{ padding: 0 }">
<CodeMirror
v-model="nodeExpression"
readonly
disabled
:theme="theme"
basic
:lang="javascript()"
:extensions="[oneDark]"
/>
</NDescriptionsItem>
</NDescriptions>
<BranchDesc v-if="visible" :model-value="modelValue" />
</NDrawerContent>
</NDrawer>
</template>

View File

@ -40,7 +40,7 @@ const onClose = () => {
<template>
<NDrawer v-model:show="visible" placement="right" :width="500" display-directive="if" @after-leave="onClose">
<NDrawerContent title="工作流详情">
<NDescriptions :column="1" bordered :label-style="{ width: '120px' }">
<NDescriptions :column="1" label-placement="left" bordered :label-style="{ width: '120px' }">
<NDescriptionsItem label="节点名称">{{ modelValue.nodeName }}</NDescriptionsItem>
<NDescriptionsItem label="webhook">{{ modelValue.callback?.webhook }}</NDescriptionsItem>
<NDescriptionsItem label="请求类型">

View File

@ -41,7 +41,7 @@ const onClose = () => {
<template>
<NDrawer v-model:show="visible" placement="right" :width="500" display-directive="if" @after-leave="onClose">
<NDrawerContent title="工作流详情">
<NDescriptions :column="1" bordered :label-style="{ width: '120px' }">
<NDescriptions :column="1" label-placement="left" bordered :label-style="{ width: '120px' }">
<NDescriptionsItem label="工作流名称">{{ modelValue.workflowName }}</NDescriptionsItem>
<NDescriptionsItem label="组名称">{{ modelValue.groupName }}</NDescriptionsItem>
<NDescriptionsItem label="触发类型">{{ $t(triggerTypeRecord[modelValue.triggerType!]) }}</NDescriptionsItem>

View File

@ -48,7 +48,7 @@ const getTaskName = (id: string) => {
<template>
<NDrawer v-model:show="visible" placement="right" :width="500" display-directive="if" @after-leave="onClose">
<NDrawerContent title="工作流详情">
<NDescriptions :column="1" bordered :label-style="{ width: '120px' }">
<NDescriptions :column="1" label-placement="left" bordered :label-style="{ width: '120px' }">
<NDescriptionsItem label="节点名称">{{ modelValue.nodeName }}</NDescriptionsItem>
<NDescriptionsItem label="任务 ID">{{ modelValue.jobTask?.jobId }}</NDescriptionsItem>
<NDescriptionsItem label="任务名称">{{ getTaskName(modelValue.jobTask?.jobId!) }}</NDescriptionsItem>

View File

@ -5,6 +5,8 @@ import { useFlowStore } from '../stores';
import { expressionRecord, logicalConditionRecord, taskBatchStatusEnum } from '../constants/business';
import BranchDrawer from '../drawer/branch-drawer.vue';
import BranchDetail from '../detail/branch-detail.vue';
import DetailCard from '../components/detail-card.vue';
import BranchDesc from '../detail/branch-desc.vue';
import AddNode from './add-node.vue';
defineOptions({
@ -139,6 +141,7 @@ const detailIds = ref<string[]>([]);
const showDetail = (item: Flow.ConditionNodeType, index: number) => {
detailIds.value = [];
if (item.nodeName !== $t('node.condition.conditionNodes.otherNodeName')) {
if (store.type === 2) {
item.jobBatchList?.forEach(job => {
@ -204,12 +207,10 @@ const getClass = (item: Flow.ConditionNodeType) => {
<NBadge processing color="#52c41a" />
{{ item.nodeName }}
<NTooltip v-if="item.nodeName === $t('node.condition.conditionNodes.otherNodeName')">
<template #header>
{{ $t('node.condition.conditionNodes.otherTip') }}
</template>
<template #trigger>
<icon-ant-design:info-circle-outlined class="ml-3px" />
<icon-ant-design:info-circle-outlined class="ml-3px text-16px" />
</template>
{{ $t('node.condition.conditionNodes.otherTip') }}
</NTooltip>
</span>
<span class="priority-title">
@ -228,17 +229,17 @@ const getClass = (item: Flow.ConditionNodeType) => {
>
<icon-ant-design:right-outlined />
</div>
<NTooltip v-if="store.type === 2 && item.taskBatchStatus">
<template #header>{{ taskBatchStatusEnum[item.taskBatchStatus].title }}</template>
<template #trigger>
<SvgIcon
class="error-tip"
:color="taskBatchStatusEnum[item.taskBatchStatus].color"
size="24px"
:icon="taskBatchStatusEnum[item.taskBatchStatus].icon"
@click.stop="() => {}"
/>
<div
class="error-tip text-24px"
:style="{ color: taskBatchStatusEnum[item.taskBatchStatus].color }"
>
<SvgIcon :icon="taskBatchStatusEnum[item.taskBatchStatus].icon" />
</div>
</template>
{{ taskBatchStatusEnum[item.taskBatchStatus].title }}
</NTooltip>
</div>
<AddNode v-model="item.childNode!" :disabled="disabled"></AddNode>
@ -249,25 +250,14 @@ const getClass = (item: Flow.ConditionNodeType) => {
<div v-if="index == 0" class="bottom-left-cover-line"></div>
<div v-if="index == nodeConfig.conditionNodes!.length - 1" class="top-right-cover-line"></div>
<div v-if="index == nodeConfig.conditionNodes!.length - 1" class="bottom-right-cover-line"></div>
<BranchDetail
v-if="store.type !== 0"
v-model:open="detailDrawer[index]"
v-model="nodeConfig.conditionNodes![index]"
/>
<BranchDetail v-model:open="detailDrawer[index]" v-model="nodeConfig.conditionNodes![index]" />
<!--
<DetailCard
v-if="store.type !== 0 && cardDrawer[index]"
:id="detailId"
v-model:open="cardDrawer[index]"
:ids="detailIds"
>
<div class="mb-20px mt-20px border-l-5px border-l-#f5222d border-l-solid font-bold font-medium">
<span class="pl-18">决策节点详情</span>
<DetailCard :id="detailId" v-model:show="cardDrawer[index]" :ids="detailIds">
<div class="header-border">
<span class="pl-12px">决策节点详情</span>
</div>
<BranchDesc v-model="nodeConfig.conditionNodes![index]" />
<BranchDesc :model-value="nodeConfig.conditionNodes![index]" />
</DetailCard>
-->
</div>
</div>
<AddNode v-model="nodeConfig.childNode!" :disabled="disabled"></AddNode>
@ -291,6 +281,7 @@ const getClass = (item: Flow.ConditionNodeType) => {
.auto-judge {
white-space: pre;
min-height: 132px !important;
}
.top-tips {
@ -407,9 +398,22 @@ const getClass = (item: Flow.ConditionNodeType) => {
.title .node-title {
color: #8f959e !important;
}
.node-title {
display: flex !important;
align-items: center;
justify-content: flex-start;
}
}
.node-disabled:hover {
cursor: default;
}
.header-border {
margin: 20px 0;
border-left: #1366ff 5px solid;
font-size: medium;
font-weight: bold;
}
</style>

View File

@ -30,7 +30,6 @@ const emit = defineEmits<Emits>();
const store = useFlowStore();
const nodeConfig = ref<Flow.NodeModelType>({});
const popoverVisible = ref<Record<number, boolean>>({});
watch(
() => props.modelValue,
@ -126,20 +125,20 @@ const getClass = (item: Flow.ConditionNodeType) => {
<div v-for="(item, index) in nodeConfig.conditionNodes" :key="index" class="col-box">
<div class="condition-node min-h-230px">
<div class="condition-node-box pt-0px">
<NPopover
:show="popoverVisible[index] && store.type === 2"
@update:show="(visible: boolean) => (popoverVisible[index] = visible)"
>
<NPopover :disabled="store.type !== 2">
<div class="popover">
<NDivider vertical />
<NButton text class="popover-item">
<icon-ant-design:redo-outlined />
<span>{{ $t('snail.retry') }}</span>
<NButton text>
<span class="popover-item">
<icon-ant-design:redo-outlined class="mb-3px text-24px font-bold" />
{{ $t('snail.retry') }}
</span>
</NButton>
<NDivider vertical />
<NButton text class="popover-item">
<icon-ant-design:dash-outlined />
<span>{{ $t('snail.ignore') }}</span>
<NButton text>
<span class="popover-item">
<icon-ant-design:dash-outlined class="mb-3px text-24px font-bold" />
<span>{{ $t('snail.ignore') }}</span>
</span>
</NButton>
</div>
<template #trigger>
@ -168,14 +167,15 @@ const getClass = (item: Flow.ConditionNodeType) => {
</template>
</div>
<NTooltip v-if="store.type === 2 && item.taskBatchStatus">
<template #title>{{ taskBatchStatusEnum[item.taskBatchStatus].title }}</template>
<SvgIcon
class="error-tip"
:color="taskBatchStatusEnum[item.taskBatchStatus].color"
size="24px"
:icon="taskBatchStatusEnum[item.taskBatchStatus].icon"
@click.stop="() => {}"
/>
<template #trigger>
<div
class="error-tip text-24px"
:style="{ color: taskBatchStatusEnum[item.taskBatchStatus].color }"
>
<SvgIcon :icon="taskBatchStatusEnum[item.taskBatchStatus].icon" />
</div>
</template>
{{ taskBatchStatusEnum[item.taskBatchStatus].title }}
</NTooltip>
</div>
</template>
@ -193,9 +193,10 @@ const getClass = (item: Flow.ConditionNodeType) => {
<AddNode v-if="nodeConfig.conditionNodes!.length > 1" v-model="nodeConfig.childNode!" :disabled="disabled" />
<CallbackDetail v-if="store.type !== 0" v-model:open="detailDrawer" v-model="nodeConfig.conditionNodes![0]" />
<CallbackDrawer v-model:open="drawer" v-model="form" @save="save" />
<!--
<DetailCard v-if="store.TYPE !== 0 && cardDrawer" :id="detailId" v-model:open="cardDrawer" :ids="detailIds">
<div style="margin: 20px 0; border-left: #f5222d 5px solid; font-size: medium; font-weight: bold">
<DetailCard v-if="store.TYPE !== 0 && cardDrawer" :id="detailId" v-model:show="cardDrawer" :ids="detailIds">
<div style="margin: 20px 0; border-left: #1366ff 5px solid; font-size: medium; font-weight: bold">
<span style="padding-left: 18px">回调节点详情</span>
</div>
<ADescriptions :column="1" bordered :label-style="{ width: '120px' }">

View File

@ -199,7 +199,7 @@ const isShow = (taskBatchStatus: number) => {
{{ $t('snail.retry') }}
</span>
</NButton>
<NDivider v-if="isStop(item.taskBatchStatus!)" vertical />
<NDivider v-if="isStop(item.taskBatchStatus!) && isRetry(item.taskBatchStatus!)" vertical />
<NButton v-if="isStop(item.taskBatchStatus!)" text class="popover-item" @click="stop(item!)">
<icon-ant-design:stop-outlined />
<span>{{ $t('snail.stop') }}</span>

View File

@ -106,7 +106,7 @@ const { columns, columnChecks, data, getData, loading, mobilePagination, searchP
{$t('common.detail')}
</NButton>
{row?.taskBatchStatus === 1 || row?.taskBatchStatus === 2 ? (
<NPopconfirm onPositiveClick={() => handleStop(row.id!)} v-if="">
<NPopconfirm onPositiveClick={() => handleStop(row.id!)}>
{{
default: () => $t('common.confirmStop'),
trigger: () => (
@ -132,9 +132,7 @@ const {
} = useTableOperate(data, getData);
async function handleBatchDelete() {
// request
console.log(checkedRowKeys.value);
// requestd
onBatchDeleted();
}