2
0

feat:套餐记录界面增加套餐显示以及中英文显示

This commit is contained in:
zhongzm
2025-01-22 20:27:22 +08:00
parent 837a752021
commit bf35afa9e2
4 changed files with 174 additions and 26 deletions

View File

@@ -605,7 +605,18 @@ const local: any = {
status: 'Status',
packageType: 'Package',
paid: 'Paid',
unpaid: 'Unpaid'
unpaid: 'Unpaid',
packagename:'Package name',
packageinfo:'Package',
price:'Price',
traffic:'Traffic',
Expirationdate:'Expiration date',
unpackage:'Unknow package',
unlimit:'Unlimited',
hour:'Hour',
day:'Day',
month:'Month',
year:'Year',
},
endpoint:{
access:"current client",

View File

@@ -607,7 +607,18 @@ const local:any = {
status: '状态',
packageType: '套餐',
paid: '已支付',
unpaid: '未支付'
unpaid: '未支付',
packagename:'套餐名',
packageinfo:'套餐详情',
price:'套餐金额',
traffic:'流量',
Expirationdate:'有效期限',
unpackage:'未知套餐',
unlimit:'无限制',
hour:'小时',
day:'天',
month:'月',
year:'年',
},
endpoint:{
access:"当前设备",

49
src/typings/api.d.ts vendored
View File

@@ -616,27 +616,50 @@ declare namespace Api {
/** Package history record information */
interface PackageHistoryRecord {
id: string;
delFlag: boolean;
createBy: number;
/** Record ID */
id: number;
/** Order creation time */
createTime: string;
updateBy: number;
updateTime: string;
userId: number;
packageId: string;
paymentId: string | null;
orderNo: string | null;
type: number; // 0 表示套餐
/** Order amount */
orderAmount: string;
status: number; // 0未支付1已支付
/** Order status: 1-paid, 0-unpaid */
status: number;
/** Package information */
upackage?: {
/** Package name */
packageName: string;
/** Package price */
price: number;
/** Whether traffic is limited */
trafficEnable: boolean;
/** Traffic limit in bytes */
traffic: number;
/** Period number */
periodNum: number;
/** Period type: 0-hour, 1-day, 2-month, 3-year */
periodType: number;
};
}
/** Package history list response */
interface PackageHistoryListResponse {
/** Package history response */
interface PackageHistoryResponse {
code: number;
msg: string;
data: {
rows: PackageHistoryRecord[];
total: number;
};
}
/** Package history response */
interface PackageHistoryResponse {
code: number;
msg: string;
data: {
rows: PackageHistoryRecord[];
total: number;
};
}
/** Package history query parameters */
interface PackageHistoryQueryParams {
pageNum: number;

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { TableColumnsType } from 'ant-design-vue'
import { Tag as ATag, Table as ATable } from 'ant-design-vue'
import { Tag as ATag, Table as ATable, Modal, Button as AButton } from 'ant-design-vue'
import { useI18n } from "vue-i18n";
import { useRouter } from 'vue-router';
import { fetchPackageHistory } from '@/service/api/auth';
@@ -53,6 +53,50 @@ onMounted(() => {
getPackageData();
});
const formatPeriodType = (type: number) => {
switch (type) {
case 0: return t('page.packagehistories.hour');
case 1: return t('page.packagehistories.day');
case 2: return t('page.packagehistories.month');
case 3: return t('page.packagehistories.year');
default: return '未知';
}
};
const showPackageDetail = (record: Api.Package.PackageHistoryRecord) => {
Modal.info({
title: t('page.packagehistories.packageinfo'),
width: 400,
content: h('div', { class: 'package-detail' }, [
h('div', { class: 'detail-item' }, [
h('span', { class: 'detail-label' }, t('page.packagehistories.packagename')+':'),
h('span', { class: 'detail-value' }, record.upackage?.packageName || '未知套餐')
]),
h('div', { class: 'detail-item' }, [
h('span', { class: 'detail-label' }, t('page.packagehistories.price')+':'),
h('span', { class: 'detail-value' }, `¥${Number(record.upackage?.price || 0).toFixed(2)}`)
]),
h('div', { class: 'detail-item' }, [
h('span', { class: 'detail-label' }, t('page.packagehistories.traffic')+':'),
h('span', { class: 'detail-value' },
record.upackage?.trafficEnable ? formatTraffic(record.upackage.traffic) : t('page.packagehistories.unlimit')
)
]),
h('div', { class: 'detail-item' }, [
h('span', { class: 'detail-label' }, t('page.packagehistories.Expirationdate')+':'),
h('span', { class: 'detail-value' },
`${record.upackage?.periodNum || 0} ${formatPeriodType(record.upackage?.periodType || 0)}`
)
]),
h('div', { class: 'detail-item' }, [
h('span', { class: 'detail-label' }, t('page.packagehistories.orderdate')+':'),
h('span', { class: 'detail-value' }, formatDateTime(record.createTime))
])
]),
class: 'package-detail-modal'
});
};
const columns = computed<TableColumnsType>(() => [
{
title: t('page.packagehistories.orderdate'),
@@ -71,15 +115,20 @@ const columns = computed<TableColumnsType>(() => [
}
},
{
title: t('page.packagehistories.type'),
dataIndex: 'type',
key: 'type',
customRender: ({ text }: { text: number }) => {
return h(ATag, {
color: 'green'
title: t('page.packagehistories.packagename'),
dataIndex: ['upackage', 'packageName'],
key: 'packageName',
customRender: ({ text, record }: { text: string; record: Api.Package.PackageHistoryRecord }) => {
return h(AButton, {
type: 'link',
size: 'small',
onClick: (e: Event) => {
e.stopPropagation(); // 阻止事件冒泡,避免触发行点击事件
showPackageDetail(record);
}
}, {
default: () => t('page.packagehistories.packageType')
})
default: () => text || t('page.packagehistories.unpackage')
});
}
},
{
@@ -95,6 +144,19 @@ const columns = computed<TableColumnsType>(() => [
}
}
]);
const formatTraffic = (bytes: number): string => {
if (!bytes) return '0B';
if (bytes >= 1024 * 1024 * 1024) {
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
} else if (bytes >= 1024 * 1024) {
return `${(bytes / (1024 * 1024)).toFixed(2)}MB`;
} else if (bytes >= 1024) {
return `${(bytes / 1024).toFixed(2)}KB`;
}
return `${bytes}B`;
};
</script>
<template>
@@ -148,4 +210,45 @@ const columns = computed<TableColumnsType>(() => [
.pl-4 {
padding-left: 1rem;
}
:deep(.package-detail) {
padding: 12px;
}
:deep(.detail-item) {
margin-bottom: 12px;
display: flex;
align-items: center;
}
:deep(.detail-item:last-child) {
margin-bottom: 0;
}
:deep(.detail-label) {
color: rgba(0, 0, 0, 0.65);
margin-right: 8px;
flex-shrink: 0;
width: 80px;
}
:deep(.detail-value) {
color: rgba(0, 0, 0, 0.85);
flex: 1;
}
:deep(.package-detail-modal .ant-modal-confirm-content) {
margin-top: 16px;
}
:deep(.ant-btn-link) {
padding: 0;
height: auto;
line-height: inherit;
}
:deep(.ant-btn-link:hover) {
color: #1890ff;
text-decoration: underline;
}
</style>