弹窗改为跳转链接
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 6m41s

This commit is contained in:
sexygoat
2026-03-07 11:41:15 +08:00
parent 8fbc321a5e
commit e73992d253
11 changed files with 1238 additions and 245 deletions

View File

@@ -2,58 +2,19 @@
<ArtTableFullScreen>
<div class="task-detail-page" id="table-full-screen">
<ElCard shadow="never" class="art-table-card">
<!-- 返回按钮 -->
<div class="back-button-wrapper">
<ElButton @click="goBack" icon="ArrowLeft">返回</ElButton>
<!-- 页面头部 -->
<div class="detail-header">
<ElButton @click="goBack">
<template #icon>
<ElIcon><ArrowLeft /></ElIcon>
</template>
返回
</ElButton>
<h2 class="detail-title">任务详情</h2>
</div>
<!-- 任务基本信息 -->
<ElDescriptions title="任务基本信息" :column="3" border class="task-info">
<ElDescriptionsItem label="任务编号">{{ taskDetail?.task_no || '-' }}</ElDescriptionsItem>
<ElDescriptionsItem label="任务类型">
<ElTag :type="taskType === 'device' ? 'warning' : 'primary'" size="small">
{{ taskType === 'device' ? '设备导入' : 'ICCID导入' }}
</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="批次号">{{ taskDetail?.batch_no || '-' }}</ElDescriptionsItem>
<ElDescriptionsItem label="运营商" v-if="taskType === 'card'">
{{ (taskDetail as IotCardImportTaskDetail)?.carrier_name || '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="文件名">{{ taskDetail?.file_name || '-' }}</ElDescriptionsItem>
<ElDescriptionsItem label="任务状态">
<ElTag :type="getStatusType(taskDetail?.status)" v-if="taskDetail">
{{ taskDetail.status_text }}
</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="创建时间">
{{ taskDetail?.created_at ? formatDateTime(taskDetail.created_at) : '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="开始处理时间">
{{ taskDetail?.started_at ? formatDateTime(taskDetail.started_at) : '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="完成时间">
{{ taskDetail?.completed_at ? formatDateTime(taskDetail.completed_at) : '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="错误信息" v-if="taskDetail?.error_message">
<span class="error-message">{{ taskDetail.error_message }}</span>
</ElDescriptionsItem>
</ElDescriptions>
<!-- 统计信息 -->
<ElDescriptions title="统计信息" :column="4" border class="statistics-info">
<ElDescriptionsItem label="总数">
<span class="count-text">{{ taskDetail?.total_count || 0 }}</span>
</ElDescriptionsItem>
<ElDescriptionsItem label="成功数">
<ElTag type="success">{{ taskDetail?.success_count || 0 }}</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="失败数">
<ElTag type="danger">{{ taskDetail?.fail_count || 0 }}</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="跳过数">
<ElTag type="warning">{{ taskDetail?.skip_count || 0 }}</ElTag>
</ElDescriptionsItem>
</ElDescriptions>
<!-- 使用 DetailPage 组件显示任务信息 -->
<DetailPage v-if="taskDetail" :sections="detailSections" :data="taskDetail" />
<!-- 失败记录 -->
<div class="failure-section" v-if="taskDetail?.fail_count && taskDetail.fail_count > 0">
@@ -86,20 +47,16 @@
</template>
<script setup lang="ts">
import { h, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { CardService, DeviceService } from '@/api/modules'
import {
ElMessage,
ElTag,
ElDescriptions,
ElDescriptionsItem,
ElDivider,
ElTable,
ElTableColumn
} from 'element-plus'
import { ElMessage, ElTag, ElDivider, ElTable, ElTableColumn, ElIcon } from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import { formatDateTime } from '@/utils/business/format'
import type { IotCardImportTaskDetail, IotCardImportTaskStatus } from '@/types/api/card'
import type { DeviceImportTaskDetail } from '@/types/api/device'
import DetailPage from '@/components/common/DetailPage.vue'
import type { DetailSection } from '@/components/common/DetailPage.vue'
defineOptions({ name: 'TaskDetail' })
@@ -130,6 +87,118 @@
}
}
// 详情页配置
const detailSections = computed((): DetailSection[] => {
const sections: DetailSection[] = [
{
title: '任务基本信息',
fields: [
{ label: '任务编号', prop: 'task_no', formatter: (value) => value || '-' },
{
label: '任务类型',
render: () => {
return h(
ElTag,
{ type: taskType.value === 'device' ? 'warning' : 'primary', size: 'small' },
() => (taskType.value === 'device' ? '设备导入' : 'ICCID导入')
)
}
},
{ label: '批次号', prop: 'batch_no', formatter: (value) => value || '-' },
{ label: '文件名', prop: 'file_name', formatter: (value) => value || '-' },
{
label: '任务状态',
render: (data: TaskDetail) => {
return h(ElTag, { type: getStatusType(data.status) }, () => data.status_text)
}
},
...(taskType.value === 'card'
? [
{
label: '运营商',
prop: 'carrier_name',
formatter: (value: any) => value || '-'
}
]
: []),
{
label: '创建时间',
prop: 'created_at',
formatter: (value) => (value ? formatDateTime(value) : '-')
},
{
label: '开始处理时间',
prop: 'started_at',
formatter: (value) => (value ? formatDateTime(value) : '-')
},
{
label: '完成时间',
prop: 'completed_at',
formatter: (value) => (value ? formatDateTime(value) : '-')
},
...(taskDetail.value?.error_message
? [
{
label: '错误信息',
prop: 'error_message',
fullWidth: true,
render: (data: TaskDetail) => {
return h(
'span',
{ style: { color: 'var(--el-color-danger)' } },
data.error_message || ''
)
}
}
]
: [])
]
},
{
title: '统计信息',
columns: 2,
fields: [
{
label: '总数',
render: (data: TaskDetail) => {
return h(
'span',
{
style: {
fontSize: '16px',
fontWeight: 'bold',
color: 'var(--el-color-primary)'
}
},
String(data.total_count || 0)
)
}
},
{
label: '成功数',
render: (data: TaskDetail) => {
return h(ElTag, { type: 'success' }, () => String(data.success_count || 0))
}
},
{
label: '失败数',
render: (data: TaskDetail) => {
return h(ElTag, { type: 'danger' }, () => String(data.fail_count || 0))
}
},
{
label: '跳过数',
render: (data: TaskDetail) => {
return h(ElTag, { type: 'warning' }, () => String(data.skip_count || 0))
}
}
]
}
]
return sections
})
// 返回列表
const goBack = () => {
router.back()
@@ -181,26 +250,18 @@
<style lang="scss" scoped>
.task-detail-page {
.back-button-wrapper {
margin-bottom: 20px;
}
.detail-header {
display: flex;
align-items: center;
gap: 16px;
padding-bottom: 16px;
.task-info {
margin-bottom: 20px;
}
.statistics-info {
margin-bottom: 20px;
}
.count-text {
font-size: 16px;
font-weight: bold;
color: var(--el-color-primary);
}
.error-message {
color: var(--el-color-danger);
.detail-title {
margin: 0;
font-size: 20px;
font-weight: 600;
color: var(--el-text-color-primary);
}
}
.failure-section,