feat: 预计最终到期时间展示
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 8m8s

This commit is contained in:
luo
2026-07-22 16:31:01 +08:00
parent 8de4339505
commit 8faa2ea2ef
16 changed files with 342 additions and 0 deletions

View File

@@ -86,6 +86,14 @@
<ElDescriptionsItem label="所有套餐剩余量">
{{ formatUsageSummaryMb(cardInfo?.total_virtual_remaining_mb) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预计套餐到期时间">
<span
:class="{ 'expiry-estimate--expiring': cardInfo?.is_expiring }"
:title="getExpiryEstimateTooltip(cardInfo)"
>
{{ getExpiryEstimateText(cardInfo) }}
</span>
</ElDescriptionsItem>
<template v-if="cardInfo?.bound_device_id">
<ElDescriptionsItem label="绑定设备号">
@@ -172,6 +180,14 @@
<ElDescriptionsItem label="所有套餐剩余量">
{{ formatUsageSummaryMb(cardInfo?.total_virtual_remaining_mb) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预计套餐到期时间">
<span
:class="{ 'expiry-estimate--expiring': cardInfo?.is_expiring }"
:title="getExpiryEstimateTooltip(cardInfo)"
>
{{ getExpiryEstimateText(cardInfo) }}
</span>
</ElDescriptionsItem>
<ElDescriptionsItem label="最后同步时间">{{
formatDateTime(deviceRealtime?.last_sync_time) || '-'
}}</ElDescriptionsItem>
@@ -577,6 +593,7 @@
import { useAuth } from '@/composables/useAuth'
import { useUserStore } from '@/store/modules/user'
import { formatDateTime } from '@/utils/business/format'
import { getExpiryEstimateText, getExpiryEstimateTooltip } from '@/utils/business/expiryEstimate'
// Props
interface BindingCard {
@@ -624,6 +641,10 @@
gateway_extend?: string
total_virtual_used_mb?: number | null
total_virtual_remaining_mb?: number | null
estimated_final_expires_at?: string | null
days_until_final_expiry?: number | null
expiry_estimate_status?: string
is_expiring?: boolean
last_sync_time?: string | null
last_data_check_at?: string | null
last_real_name_check_at?: string | null
@@ -965,6 +986,11 @@
word-break: break-all;
}
.expiry-estimate--expiring {
font-weight: 500;
color: var(--el-color-danger);
}
.card-header {
display: flex;
gap: 12px;

View File

@@ -140,6 +140,10 @@ export function useAssetInfo() {
gateway_extend: data.gateway_extend ?? '',
total_virtual_used_mb: data.total_virtual_used_mb ?? null,
total_virtual_remaining_mb: data.total_virtual_remaining_mb ?? null,
estimated_final_expires_at: data.estimated_final_expires_at ?? null,
days_until_final_expiry: data.days_until_final_expiry ?? null,
expiry_estimate_status: data.expiry_estimate_status,
is_expiring: data.is_expiring ?? false,
bound_device_id: data.bound_device_id,
bound_device_no: data.bound_device_no || '',
bound_device_name: data.bound_device_name || '',

View File

@@ -35,6 +35,10 @@ export interface AssetInfo {
gateway_extend?: string
total_virtual_used_mb?: number | null
total_virtual_remaining_mb?: number | null
estimated_final_expires_at?: string | null
days_until_final_expiry?: number | null
expiry_estimate_status?: string
is_expiring?: boolean
last_sync_time?: string | null
last_data_check_at?: string | null
last_real_name_check_at?: string | null

View File

@@ -995,6 +995,7 @@
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import { formatDateTime } from '@/utils/business/format'
import { getExpiryEstimateText, getExpiryEstimateTooltip } from '@/utils/business/expiryEstimate'
import type { PackageSeriesResponse } from '@/types/api'
import type { EnterpriseItem } from '@/types/api/enterprise'
import type {
@@ -1606,6 +1607,7 @@
{ label: '设备名称', prop: 'device_name' },
{ label: '店铺名称', prop: 'shop_name' },
{ label: '套餐系列', prop: 'series_name' },
{ label: '预计套餐到期时间', prop: 'estimated_final_expires_at' },
{ label: '设备型号', prop: 'device_model' },
{ label: '设备类型', prop: 'device_type' },
{ label: '状态', prop: 'status' },
@@ -1890,6 +1892,20 @@
minWidth: 180,
showOverflowTooltip: true
},
{
prop: 'estimated_final_expires_at',
label: '预计套餐到期时间',
width: 180,
formatter: (row: Device) =>
h(
'span',
{
class: { 'expiry-estimate--expiring': row.is_expiring },
title: getExpiryEstimateTooltip(row)
},
getExpiryEstimateText(row)
)
},
{
prop: 'device_model',
label: '设备型号',
@@ -3201,4 +3217,9 @@
:deep(.el-table__row.table-row-with-context-menu) {
cursor: pointer;
}
.expiry-estimate--expiring {
font-weight: 500;
color: var(--el-color-danger);
}
</style>

View File

@@ -1045,6 +1045,7 @@
import { useUserStore } from '@/store/modules/user'
import { storeToRefs } from 'pinia'
import { formatDateTime } from '@/utils/business/format'
import { getExpiryEstimateText, getExpiryEstimateTooltip } from '@/utils/business/expiryEstimate'
import { formatRemainingTime, FrontendRateLimitError } from '@/utils/business/apiRateLimit'
import type {
StandaloneIotCard,
@@ -1946,6 +1947,7 @@
{ label: '绑定设备虚拟号', prop: 'device_virtual_no' },
{ label: '店铺名称', prop: 'shop_name' },
{ label: '套餐系列', prop: 'series_name' },
{ label: '预计套餐到期时间', prop: 'estimated_final_expires_at' },
{ label: '自然月累计流量(MB)', prop: 'current_month_usage_mb' },
{ label: '本月开始日期', prop: 'current_month_start_date' },
{ label: '上月流量总量(MB)', prop: 'last_month_total_mb' },
@@ -2117,6 +2119,20 @@
showOverflowTooltip: true,
formatter: (row: StandaloneIotCard) => row.series_name || '-'
},
{
prop: 'estimated_final_expires_at',
label: '预计套餐到期时间',
width: 180,
formatter: (row: StandaloneIotCard) =>
h(
'span',
{
class: { 'expiry-estimate--expiring': row.is_expiring },
title: getExpiryEstimateTooltip(row)
},
getExpiryEstimateText(row)
)
},
{
prop: 'status',
label: '状态',
@@ -3027,4 +3043,9 @@
:deep(.el-table__row.table-row-with-context-menu) {
cursor: pointer;
}
.expiry-estimate--expiring {
font-weight: 500;
color: var(--el-color-danger);
}
</style>