Files
CN_Tool_client/frontend/src/views/tools/addData/components/AddDataTaskStatusCard.vue

194 lines
5.4 KiB
Vue
Raw Normal View History

<template>
<section class="card add-data-card">
<div class="card-header">
<div>
<div class="section-title">任务状态</div>
<div class="section-description">创建任务后自动轮询状态直到任务成功或失败</div>
</div>
<el-tag v-if="status" :type="statusMeta.type" effect="light">{{ statusMeta.label }}</el-tag>
</div>
<div v-loading="loading" class="card-body">
<div v-if="status" class="status-content">
<el-descriptions :column="2" border size="small">
<el-descriptions-item label="任务 ID">{{ taskId || status.taskId || '--' }}</el-descriptions-item>
<el-descriptions-item label="当前状态">{{ statusMeta.label }}</el-descriptions-item>
<el-descriptions-item label="当前表名">{{ status.currentTableName || '--' }}</el-descriptions-item>
<el-descriptions-item label="当前批次">{{ status.currentBatchInfo || '--' }}</el-descriptions-item>
<el-descriptions-item label="已写入数量">{{ status.insertedCount }}</el-descriptions-item>
<el-descriptions-item label="已跳过数量">{{ status.skippedCount }}</el-descriptions-item>
<el-descriptions-item label="失败数量">{{ status.failedCount }}</el-descriptions-item>
<el-descriptions-item label="失败原因">
<span class="failure-text">{{ status.failureReason || '--' }}</span>
</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ status.startTime || '--' }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ status.endTime || '--' }}</el-descriptions-item>
</el-descriptions>
<div class="hourly-block">
<div class="hourly-title">业务时刻</div>
<div v-if="status.hourlyTimeResults.length" class="hourly-scroll">
<div class="hourly-list">
<el-tag v-for="item in status.hourlyTimeResults" :key="item" effect="plain" type="info">
{{ item }}
</el-tag>
</div>
</div>
<div v-else class="hourly-empty">当前接口未返回业务时刻</div>
</div>
</div>
<div v-else class="empty-block">暂无补数任务创建任务后会在这里持续展示执行进度</div>
</div>
</section>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { AddData } from '@/api/tools/addData/interface'
defineOptions({
name: 'AddDataTaskStatusCard'
})
const props = defineProps<{
status: AddData.NormalizedTaskStatus | null
taskId: string
loading: boolean
}>()
const statusMeta = computed(() => {
const status = props.status?.status
if (status === 'SUCCESS') {
return { label: '成功', type: 'success' as const }
}
if (status === 'FAILED') {
return { label: '失败', type: 'danger' as const }
}
if (status === 'RUNNING') {
return { label: '执行中', type: 'warning' as const }
}
if (status === 'WAITING') {
return { label: '等待中', type: 'info' as const }
}
return {
label: status || '未知状态',
type: 'info' as const
}
})
</script>
<style scoped lang="scss">
.add-data-card {
display: flex;
flex: 1;
flex-direction: column;
min-height: 0;
background: var(--el-bg-color);
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 16px 16px 12px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
.section-title {
font-size: 15px;
font-weight: 600;
color: var(--el-text-color-primary);
}
.section-description {
margin-top: 6px;
font-size: 13px;
line-height: 1.7;
color: var(--el-text-color-regular);
}
.card-body {
display: flex;
flex: 1;
min-height: 0;
padding: 16px;
overflow: hidden;
}
.status-content {
display: flex;
flex: 1;
flex-direction: column;
gap: 12px;
min-height: 0;
width: 100%;
}
.failure-text {
word-break: break-all;
color: var(--el-color-danger);
}
.hourly-block {
display: flex;
flex: 1;
flex-direction: column;
min-height: 0;
padding: 12px;
background: var(--cn-color-canvas-bg);
border: 1px dashed var(--el-border-color);
border-radius: 4px;
}
.hourly-title {
margin-bottom: 10px;
font-size: 13px;
font-weight: 600;
color: var(--el-text-color-primary);
}
.hourly-scroll {
flex: 1;
min-height: 0;
overflow-y: auto;
padding-right: 4px;
}
.hourly-list {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
gap: 8px;
}
.hourly-empty {
font-size: 12px;
color: var(--el-text-color-secondary);
}
.empty-block {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
width: 100%;
min-height: 0;
padding: 16px;
color: var(--el-text-color-secondary);
background: var(--cn-color-canvas-bg);
border: 1px dashed var(--el-border-color);
border-radius: 4px;
text-align: center;
}
</style>