fetch(add): 新增企业设备授权
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 2m25s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 2m25s
This commit is contained in:
310
src/views/asset-management/device-task/index.vue
Normal file
310
src/views/asset-management/device-task/index.vue
Normal file
@@ -0,0 +1,310 @@
|
||||
<template>
|
||||
<ArtTableFullScreen>
|
||||
<div class="device-task-page" id="table-full-screen">
|
||||
<!-- 搜索栏 -->
|
||||
<ArtSearchBar
|
||||
v-model:filter="searchForm"
|
||||
:items="searchFormItems"
|
||||
@reset="handleReset"
|
||||
@search="handleSearch"
|
||||
></ArtSearchBar>
|
||||
|
||||
<ElCard shadow="never" class="art-table-card">
|
||||
<!-- 表格头部 -->
|
||||
<ArtTableHeader
|
||||
:columnList="columnOptions"
|
||||
v-model:columns="columnChecks"
|
||||
@refresh="handleRefresh"
|
||||
/>
|
||||
|
||||
<!-- 表格 -->
|
||||
<ArtTable
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:loading="loading"
|
||||
:data="taskList"
|
||||
:currentPage="pagination.page"
|
||||
:pageSize="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:marginTop="10"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
<template #default>
|
||||
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
|
||||
</template>
|
||||
</ArtTable>
|
||||
</ElCard>
|
||||
</div>
|
||||
</ArtTableFullScreen>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { DeviceService } from '@/api/modules'
|
||||
import { ElMessage, ElTag } from 'element-plus'
|
||||
import type { SearchFormItem } from '@/types'
|
||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
||||
import type { DeviceImportTask, DeviceImportTaskStatus } from '@/types/api/device'
|
||||
|
||||
defineOptions({ name: 'DeviceTask' })
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
const tableRef = ref()
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState = {
|
||||
status: undefined,
|
||||
batch_no: '',
|
||||
start_time: '',
|
||||
end_time: ''
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({ ...initialSearchState })
|
||||
|
||||
// 分页
|
||||
const pagination = reactive({
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 搜索表单配置
|
||||
const searchFormItems: SearchFormItem[] = [
|
||||
{
|
||||
label: '任务状态',
|
||||
prop: 'status',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '全部'
|
||||
},
|
||||
options: () => [
|
||||
{ label: '待处理', value: 1 },
|
||||
{ label: '处理中', value: 2 },
|
||||
{ label: '已完成', value: 3 },
|
||||
{ label: '失败', value: 4 }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '批次号',
|
||||
prop: 'batch_no',
|
||||
type: 'input',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '请输入批次号'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '创建时间',
|
||||
prop: 'dateRange',
|
||||
type: 'daterange',
|
||||
config: {
|
||||
type: 'daterange',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
valueFormat: 'YYYY-MM-DDTHH:mm:ssZ'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// 列配置
|
||||
const columnOptions = [
|
||||
{ label: '任务编号', prop: 'task_no' },
|
||||
{ label: '批次号', prop: 'batch_no' },
|
||||
{ label: '文件名', prop: 'file_name' },
|
||||
{ label: '任务状态', prop: 'status' },
|
||||
{ label: '总数', prop: 'total_count' },
|
||||
{ label: '成功数', prop: 'success_count' },
|
||||
{ label: '失败数', prop: 'fail_count' },
|
||||
{ label: '跳过数', prop: 'skip_count' },
|
||||
{ label: '创建时间', prop: 'created_at' },
|
||||
{ label: '完成时间', prop: 'completed_at' },
|
||||
{ label: '操作', prop: 'operation' }
|
||||
]
|
||||
|
||||
const taskList = ref<DeviceImportTask[]>([])
|
||||
|
||||
// 获取状态标签类型
|
||||
const getStatusType = (status: DeviceImportTaskStatus) => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return 'info'
|
||||
case 2:
|
||||
return 'warning'
|
||||
case 3:
|
||||
return 'success'
|
||||
case 4:
|
||||
return 'danger'
|
||||
default:
|
||||
return 'info'
|
||||
}
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const viewDetail = (row: DeviceImportTask) => {
|
||||
router.push({
|
||||
path: '/asset-management/task-detail',
|
||||
query: {
|
||||
id: row.id,
|
||||
task_type: 'device'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 动态列配置
|
||||
const { columnChecks, columns } = useCheckedColumns(() => [
|
||||
{
|
||||
prop: 'task_no',
|
||||
label: '任务编号',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
prop: 'batch_no',
|
||||
label: '批次号',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'file_name',
|
||||
label: '文件名',
|
||||
minWidth: 200
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '任务状态',
|
||||
width: 100,
|
||||
formatter: (row: DeviceImportTask) => {
|
||||
return h(ElTag, { type: getStatusType(row.status) }, () => row.status_text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'total_count',
|
||||
label: '总数',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
prop: 'success_count',
|
||||
label: '成功数',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
prop: 'fail_count',
|
||||
label: '失败数',
|
||||
width: 80,
|
||||
formatter: (row: DeviceImportTask) => {
|
||||
const type = row.fail_count > 0 ? 'danger' : 'success'
|
||||
return h(ElTag, { type, size: 'small' }, () => row.fail_count)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'skip_count',
|
||||
label: '跳过数',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
prop: 'created_at',
|
||||
label: '创建时间',
|
||||
width: 160,
|
||||
formatter: (row: DeviceImportTask) => formatDateTime(row.created_at)
|
||||
},
|
||||
{
|
||||
prop: 'completed_at',
|
||||
label: '完成时间',
|
||||
width: 160,
|
||||
formatter: (row: DeviceImportTask) => (row.completed_at ? formatDateTime(row.completed_at) : '-')
|
||||
},
|
||||
{
|
||||
prop: 'operation',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
formatter: (row: DeviceImportTask) => {
|
||||
return h(ArtButtonTable, {
|
||||
type: 'view',
|
||||
onClick: () => viewDetail(row)
|
||||
})
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
|
||||
// 获取设备任务列表
|
||||
const getTableData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params: any = {
|
||||
page: pagination.page,
|
||||
page_size: pagination.pageSize,
|
||||
status: searchForm.status,
|
||||
batch_no: searchForm.batch_no || undefined
|
||||
}
|
||||
|
||||
// 处理时间范围
|
||||
if (searchForm.dateRange && Array.isArray(searchForm.dateRange)) {
|
||||
params.start_time = searchForm.dateRange[0]
|
||||
params.end_time = searchForm.dateRange[1]
|
||||
}
|
||||
|
||||
// 清理空值
|
||||
Object.keys(params).forEach((key) => {
|
||||
if (params[key] === '' || params[key] === undefined) {
|
||||
delete params[key]
|
||||
}
|
||||
})
|
||||
|
||||
const res = await DeviceService.getImportTasks(params)
|
||||
if (res.code === 0) {
|
||||
taskList.value = res.data.list || []
|
||||
pagination.total = res.data.total || 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
ElMessage.error('获取设备任务列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
const handleReset = () => {
|
||||
Object.assign(searchForm, { ...initialSearchState })
|
||||
pagination.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
pagination.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 刷新表格
|
||||
const handleRefresh = () => {
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 处理表格分页变化
|
||||
const handleSizeChange = (newPageSize: number) => {
|
||||
pagination.pageSize = newPageSize
|
||||
getTableData()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (newCurrentPage: number) => {
|
||||
pagination.page = newCurrentPage
|
||||
getTableData()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.device-task-page {
|
||||
// Device task page styles
|
||||
}
|
||||
</style>
|
||||
@@ -28,6 +28,11 @@
|
||||
<ElButton type="info" :disabled="selectedCards.length === 0" @click="showSeriesBindingDialog">
|
||||
批量设置套餐系列
|
||||
</ElButton>
|
||||
<ElButton type="primary" @click="cardDistribution">网卡分销</ElButton>
|
||||
<ElButton type="success" @click="batchRecharge">批量充值</ElButton>
|
||||
<ElButton type="danger" @click="cardRecycle">网卡回收</ElButton>
|
||||
<ElButton type="info" @click="batchDownload">批量下载</ElButton>
|
||||
<ElButton type="warning" @click="changePackage">变更套餐</ElButton>
|
||||
</template>
|
||||
</ArtTableHeader>
|
||||
|
||||
@@ -404,15 +409,10 @@
|
||||
const initialSearchState = {
|
||||
status: undefined,
|
||||
carrier_id: undefined,
|
||||
shop_id: undefined,
|
||||
iccid: '',
|
||||
msisdn: '',
|
||||
batch_no: '',
|
||||
package_id: undefined,
|
||||
is_distributed: undefined,
|
||||
is_replaced: undefined,
|
||||
iccid_start: '',
|
||||
iccid_end: ''
|
||||
is_distributed: undefined
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
@@ -603,14 +603,19 @@
|
||||
// 列配置
|
||||
const columnOptions = [
|
||||
{ label: 'ICCID', prop: 'iccid' },
|
||||
{ label: 'IMSI', prop: 'imsi' },
|
||||
{ label: '卡接入号', prop: 'msisdn' },
|
||||
{ label: '运营商', prop: 'carrier_name' },
|
||||
{ label: '卡类型', prop: 'card_type' },
|
||||
{ label: '卡业务类型', prop: 'card_category' },
|
||||
{ label: '运营商', prop: 'carrier_name' },
|
||||
{ label: '成本价', prop: 'cost_price' },
|
||||
{ label: '分销价', prop: 'distribute_price' },
|
||||
{ label: '状态', prop: 'status' },
|
||||
{ label: '批次号', prop: 'batch_no' },
|
||||
{ label: '店铺名称', prop: 'shop_name' },
|
||||
{ label: '激活时间', prop: 'activated_at' },
|
||||
{ label: '激活状态', prop: 'activation_status' },
|
||||
{ label: '网络状态', prop: 'network_status' },
|
||||
{ label: '实名状态', prop: 'real_name_status' },
|
||||
{ label: '累计流量(MB)', prop: 'data_usage_mb' },
|
||||
{ label: '首次佣金', prop: 'first_commission_paid' },
|
||||
{ label: '累计充值', prop: 'accumulated_recharge' },
|
||||
{ label: '创建时间', prop: 'created_at' }
|
||||
]
|
||||
|
||||
@@ -653,28 +658,40 @@
|
||||
{
|
||||
prop: 'iccid',
|
||||
label: 'ICCID',
|
||||
minWidth: 180
|
||||
},
|
||||
{
|
||||
prop: 'imsi',
|
||||
label: 'IMSI',
|
||||
width: 150
|
||||
minWidth: 190
|
||||
},
|
||||
{
|
||||
prop: 'msisdn',
|
||||
label: '卡接入号',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'carrier_name',
|
||||
label: '运营商',
|
||||
width: 100
|
||||
width: 130
|
||||
},
|
||||
{
|
||||
prop: 'card_type',
|
||||
label: '卡类型',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
prop: 'card_category',
|
||||
label: '卡业务类型',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
prop: 'carrier_name',
|
||||
label: '运营商',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
prop: 'cost_price',
|
||||
label: '成本价',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => `¥${(row.cost_price / 100).toFixed(2)}`
|
||||
},
|
||||
{
|
||||
prop: 'distribute_price',
|
||||
label: '分销价',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => `¥${(row.distribute_price / 100).toFixed(2)}`
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
@@ -684,20 +701,55 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'batch_no',
|
||||
label: '批次号',
|
||||
prop: 'activation_status',
|
||||
label: '激活状态',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => {
|
||||
const type = row.activation_status === 1 ? 'success' : 'info'
|
||||
const text = row.activation_status === 1 ? '已激活' : '未激活'
|
||||
return h(ElTag, { type }, () => text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'network_status',
|
||||
label: '网络状态',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => {
|
||||
const type = row.network_status === 1 ? 'success' : 'danger'
|
||||
const text = row.network_status === 1 ? '开机' : '停机'
|
||||
return h(ElTag, { type }, () => text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'real_name_status',
|
||||
label: '实名状态',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => {
|
||||
const type = row.real_name_status === 1 ? 'success' : 'warning'
|
||||
const text = row.real_name_status === 1 ? '已实名' : '未实名'
|
||||
return h(ElTag, { type }, () => text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'data_usage_mb',
|
||||
label: '累计流量(MB)',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'shop_name',
|
||||
label: '店铺名称',
|
||||
width: 150
|
||||
prop: 'first_commission_paid',
|
||||
label: '首次佣金',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => {
|
||||
const type = row.first_commission_paid ? 'success' : 'info'
|
||||
const text = row.first_commission_paid ? '已支付' : '未支付'
|
||||
return h(ElTag, { type, size: 'small' }, () => text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'activated_at',
|
||||
label: '激活时间',
|
||||
width: 160,
|
||||
formatter: (row: StandaloneIotCard) => (row.activated_at ? formatDateTime(row.activated_at) : '-')
|
||||
prop: 'accumulated_recharge',
|
||||
label: '累计充值',
|
||||
width: 100,
|
||||
formatter: (row: StandaloneIotCard) => `¥${(row.accumulated_recharge / 100).toFixed(2)}`
|
||||
},
|
||||
{
|
||||
prop: 'created_at',
|
||||
@@ -729,7 +781,7 @@
|
||||
|
||||
const res = await CardService.getStandaloneIotCards(params)
|
||||
if (res.code === 0) {
|
||||
cardList.value = res.data.list || []
|
||||
cardList.value = res.data.items || []
|
||||
pagination.total = res.data.total || 0
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -1127,6 +1179,31 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 网卡分销 - 正在开发中
|
||||
const cardDistribution = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 批量充值 - 正在开发中
|
||||
const batchRecharge = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 网卡回收 - 正在开发中
|
||||
const cardRecycle = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 批量下载 - 正在开发中
|
||||
const batchDownload = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 变更套餐 - 正在开发中
|
||||
const changePackage = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ArtTableFullScreen>
|
||||
<div class="task-management-page" id="table-full-screen">
|
||||
<div class="iot-card-task-page" id="table-full-screen">
|
||||
<!-- 搜索栏 -->
|
||||
<ArtSearchBar
|
||||
v-model:filter="searchForm"
|
||||
@@ -42,33 +42,26 @@
|
||||
<script setup lang="ts">
|
||||
import { h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { CardService, DeviceService } from '@/api/modules'
|
||||
import { CardService } from '@/api/modules'
|
||||
import { ElMessage, ElTag } from 'element-plus'
|
||||
import type { SearchFormItem } from '@/types'
|
||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
||||
import type { IotCardImportTask, IotCardImportTaskStatus } from '@/types/api/card'
|
||||
import type { DeviceImportTask } from '@/types/api/device'
|
||||
|
||||
defineOptions({ name: 'TaskManagement' })
|
||||
defineOptions({ name: 'IotCardTask' })
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
const tableRef = ref()
|
||||
|
||||
// 任务类型
|
||||
type TaskType = 'card' | 'device'
|
||||
type ImportTask = IotCardImportTask | DeviceImportTask
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState = {
|
||||
task_type: undefined as TaskType | undefined,
|
||||
status: undefined,
|
||||
carrier_id: undefined,
|
||||
batch_no: '',
|
||||
start_time: '',
|
||||
end_time: ''
|
||||
dateRange: undefined as any
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
@@ -83,19 +76,6 @@
|
||||
|
||||
// 搜索表单配置
|
||||
const searchFormItems: SearchFormItem[] = [
|
||||
{
|
||||
label: '任务类型',
|
||||
prop: 'task_type',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '全部'
|
||||
},
|
||||
options: () => [
|
||||
{ label: 'ICCID导入', value: 'card' },
|
||||
{ label: '设备导入', value: 'device' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '任务状态',
|
||||
prop: 'status',
|
||||
@@ -150,21 +130,21 @@
|
||||
// 列配置
|
||||
const columnOptions = [
|
||||
{ label: '任务编号', prop: 'task_no' },
|
||||
{ label: '任务类型', prop: 'task_type' },
|
||||
{ label: '批次号', prop: 'batch_no' },
|
||||
{ label: '任务状态', prop: 'status' },
|
||||
{ label: '运营商', prop: 'carrier_name' },
|
||||
{ label: '文件名', prop: 'file_name' },
|
||||
{ label: '任务状态', prop: 'status' },
|
||||
{ label: '总数', prop: 'total_count' },
|
||||
{ label: '成功数', prop: 'success_count' },
|
||||
{ label: '失败数', prop: 'fail_count' },
|
||||
{ label: '跳过数', prop: 'skip_count' },
|
||||
{ label: '创建时间', prop: 'created_at' },
|
||||
{ label: '开始时间', prop: 'started_at' },
|
||||
{ label: '完成时间', prop: 'completed_at' },
|
||||
{ label: '错误信息', prop: 'error_message' },
|
||||
{ label: '创建时间', prop: 'created_at' },
|
||||
{ label: '操作', prop: 'operation' }
|
||||
]
|
||||
|
||||
const taskList = ref<ImportTask[]>([])
|
||||
const taskList = ref<IotCardImportTask[]>([])
|
||||
|
||||
// 获取状态标签类型
|
||||
const getStatusType = (status: IotCardImportTaskStatus) => {
|
||||
@@ -182,27 +162,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 获取任务类型
|
||||
const getTaskType = (row: ImportTask): TaskType => {
|
||||
// 判断是否为设备导入任务(设备导入任务有 device_no 字段,卡导入任务有 carrier_name 字段)
|
||||
if ('device_no' in row || (row.batch_no && row.batch_no.startsWith('DEV-'))) {
|
||||
return 'device'
|
||||
}
|
||||
return 'card'
|
||||
}
|
||||
|
||||
// 获取任务类型文本
|
||||
const getTaskTypeText = (taskType: TaskType) => {
|
||||
return taskType === 'device' ? '设备导入' : 'ICCID导入'
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const viewDetail = (row: ImportTask) => {
|
||||
const viewDetail = (row: IotCardImportTask) => {
|
||||
router.push({
|
||||
path: '/asset-management/task-detail',
|
||||
query: {
|
||||
id: row.id,
|
||||
task_type: getTaskType(row)
|
||||
task_type: 'card'
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -212,44 +178,26 @@
|
||||
{
|
||||
prop: 'task_no',
|
||||
label: '任务编号',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
prop: 'task_type',
|
||||
label: '任务类型',
|
||||
width: 100,
|
||||
formatter: (row: ImportTask) => {
|
||||
const taskType = getTaskType(row)
|
||||
const tagType = taskType === 'device' ? 'warning' : 'primary'
|
||||
return h(ElTag, { type: tagType, size: 'small' }, () => getTaskTypeText(taskType))
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'batch_no',
|
||||
label: '批次号',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'carrier_name',
|
||||
label: '运营商',
|
||||
width: 100,
|
||||
formatter: (row: ImportTask) => {
|
||||
return (row as IotCardImportTask).carrier_name || '-'
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'file_name',
|
||||
label: '文件名',
|
||||
minWidth: 200
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '任务状态',
|
||||
width: 100,
|
||||
formatter: (row: ImportTask) => {
|
||||
formatter: (row: IotCardImportTask) => {
|
||||
return h(ElTag, { type: getStatusType(row.status) }, () => row.status_text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'carrier_name',
|
||||
label: '运营商',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'file_name',
|
||||
label: '文件名',
|
||||
minWidth: 250
|
||||
},
|
||||
{
|
||||
prop: 'total_count',
|
||||
label: '总数',
|
||||
@@ -264,7 +212,7 @@
|
||||
prop: 'fail_count',
|
||||
label: '失败数',
|
||||
width: 80,
|
||||
formatter: (row: ImportTask) => {
|
||||
formatter: (row: IotCardImportTask) => {
|
||||
const type = row.fail_count > 0 ? 'danger' : 'success'
|
||||
return h(ElTag, { type, size: 'small' }, () => row.fail_count)
|
||||
}
|
||||
@@ -275,25 +223,37 @@
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
prop: 'created_at',
|
||||
label: '创建时间',
|
||||
prop: 'started_at',
|
||||
label: '开始时间',
|
||||
width: 160,
|
||||
formatter: (row: ImportTask) => formatDateTime(row.created_at)
|
||||
formatter: (row: IotCardImportTask) => (row.started_at ? formatDateTime(row.started_at) : '-')
|
||||
},
|
||||
{
|
||||
prop: 'completed_at',
|
||||
label: '完成时间',
|
||||
width: 160,
|
||||
formatter: (row: ImportTask) => (row.completed_at ? formatDateTime(row.completed_at) : '-')
|
||||
formatter: (row: IotCardImportTask) => (row.completed_at ? formatDateTime(row.completed_at) : '-')
|
||||
},
|
||||
{
|
||||
prop: 'error_message',
|
||||
label: '错误信息',
|
||||
minWidth: 200,
|
||||
formatter: (row: IotCardImportTask) => row.error_message || '-'
|
||||
},
|
||||
{
|
||||
prop: 'created_at',
|
||||
label: '创建时间',
|
||||
width: 160,
|
||||
formatter: (row: IotCardImportTask) => formatDateTime(row.created_at)
|
||||
},
|
||||
{
|
||||
prop: 'operation',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
formatter: (row: ImportTask) => {
|
||||
formatter: (row: IotCardImportTask) => {
|
||||
return h(ArtButtonTable, {
|
||||
type: 'view',
|
||||
text: '查看详情',
|
||||
onClick: () => viewDetail(row)
|
||||
})
|
||||
}
|
||||
@@ -304,7 +264,7 @@
|
||||
getTableData()
|
||||
})
|
||||
|
||||
// 获取任务列表
|
||||
// 获取IoT卡任务列表
|
||||
const getTableData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -312,6 +272,7 @@
|
||||
page: pagination.page,
|
||||
page_size: pagination.pageSize,
|
||||
status: searchForm.status,
|
||||
carrier_id: searchForm.carrier_id,
|
||||
batch_no: searchForm.batch_no || undefined
|
||||
}
|
||||
|
||||
@@ -328,52 +289,14 @@
|
||||
}
|
||||
})
|
||||
|
||||
// 根据任务类型获取不同的数据
|
||||
if (searchForm.task_type === 'device') {
|
||||
// 仅获取设备导入任务
|
||||
const res = await DeviceService.getImportTasks(params)
|
||||
if (res.code === 0) {
|
||||
taskList.value = res.data.list || []
|
||||
pagination.total = res.data.total || 0
|
||||
}
|
||||
} else if (searchForm.task_type === 'card') {
|
||||
// 仅获取ICCID导入任务(需要carrier_id参数)
|
||||
const cardParams = {
|
||||
...params,
|
||||
carrier_id: searchForm.carrier_id
|
||||
}
|
||||
const res = await CardService.getIotCardImportTasks(cardParams)
|
||||
if (res.code === 0) {
|
||||
taskList.value = res.data.list || []
|
||||
pagination.total = res.data.total || 0
|
||||
}
|
||||
} else {
|
||||
// 获取所有类型任务 - 分别调用两个API然后合并结果
|
||||
const [cardRes, deviceRes] = await Promise.all([
|
||||
CardService.getIotCardImportTasks({
|
||||
...params,
|
||||
carrier_id: searchForm.carrier_id
|
||||
}),
|
||||
DeviceService.getImportTasks(params)
|
||||
])
|
||||
|
||||
const cardTasks = cardRes.code === 0 ? cardRes.data.list || [] : []
|
||||
const deviceTasks = deviceRes.code === 0 ? deviceRes.data.list || [] : []
|
||||
|
||||
// 合并并按创建时间排序
|
||||
const allTasks = [...cardTasks, ...deviceTasks].sort((a, b) => {
|
||||
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
||||
})
|
||||
|
||||
// 前端分页
|
||||
const start = (pagination.page - 1) * pagination.pageSize
|
||||
const end = start + pagination.pageSize
|
||||
taskList.value = allTasks.slice(start, end)
|
||||
pagination.total = allTasks.length
|
||||
const res = await CardService.getIotCardImportTasks(params)
|
||||
if (res.code === 0) {
|
||||
taskList.value = res.data.items || []
|
||||
pagination.total = res.data.total || 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
ElMessage.error('获取任务列表失败')
|
||||
ElMessage.error('获取IoT卡任务列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -410,7 +333,7 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.task-management-page {
|
||||
// Task management page styles
|
||||
.iot-card-task-page {
|
||||
// IoT card task page styles
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user