Files
CN_Tool_client/frontend/src/views/tools/addData/components/AddDataTaskStatusCard.vue
yexb 0dc0e4ecdc feat(tools): 新增数据补数功能模块
- 实现补数任务面板组件,支持监测点ID输入、时间范围选择和时间步长设置
- 添加任务状态卡片组件,实时展示任务执行进度和结果统计
- 集成参数规则表格组件,显示后端配置的模板规则信息
- 实现补数API接口服务,包括预估写入量、创建任务和查询状态功能
- 添加磁盘监控策略对话框组件,支持全局监控配置管理
- 完成补数功能页面布局设计,集成左右双栏界面结构
- 实现任务轮询机制,自动更新任务执行状态直到完成
- 添加表单验证逻辑,确保输入参数符合业务规则要求
2026-04-30 09:04:52 +08:00

194 lines
5.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>