feat:套餐记录界面增加套餐显示以及中英文显示
This commit is contained in:
@@ -605,7 +605,18 @@ const local: any = {
|
|||||||
status: 'Status',
|
status: 'Status',
|
||||||
packageType: 'Package',
|
packageType: 'Package',
|
||||||
paid: 'Paid',
|
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:{
|
endpoint:{
|
||||||
access:"current client",
|
access:"current client",
|
||||||
|
|||||||
@@ -607,7 +607,18 @@ const local:any = {
|
|||||||
status: '状态',
|
status: '状态',
|
||||||
packageType: '套餐',
|
packageType: '套餐',
|
||||||
paid: '已支付',
|
paid: '已支付',
|
||||||
unpaid: '未支付'
|
unpaid: '未支付',
|
||||||
|
packagename:'套餐名',
|
||||||
|
packageinfo:'套餐详情',
|
||||||
|
price:'套餐金额',
|
||||||
|
traffic:'流量',
|
||||||
|
Expirationdate:'有效期限',
|
||||||
|
unpackage:'未知套餐',
|
||||||
|
unlimit:'无限制',
|
||||||
|
hour:'小时',
|
||||||
|
day:'天',
|
||||||
|
month:'月',
|
||||||
|
year:'年',
|
||||||
},
|
},
|
||||||
endpoint:{
|
endpoint:{
|
||||||
access:"当前设备",
|
access:"当前设备",
|
||||||
|
|||||||
53
src/typings/api.d.ts
vendored
53
src/typings/api.d.ts
vendored
@@ -616,27 +616,50 @@ declare namespace Api {
|
|||||||
|
|
||||||
/** Package history record information */
|
/** Package history record information */
|
||||||
interface PackageHistoryRecord {
|
interface PackageHistoryRecord {
|
||||||
id: string;
|
/** Record ID */
|
||||||
delFlag: boolean;
|
id: number;
|
||||||
createBy: number;
|
/** Order creation time */
|
||||||
createTime: string;
|
createTime: string;
|
||||||
updateBy: number;
|
/** Order amount */
|
||||||
updateTime: string;
|
|
||||||
userId: number;
|
|
||||||
packageId: string;
|
|
||||||
paymentId: string | null;
|
|
||||||
orderNo: string | null;
|
|
||||||
type: number; // 0 表示套餐
|
|
||||||
orderAmount: string;
|
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 */
|
/** Package history response */
|
||||||
interface PackageHistoryListResponse {
|
interface PackageHistoryResponse {
|
||||||
rows: PackageHistoryRecord[];
|
code: number;
|
||||||
total: 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 */
|
/** Package history query parameters */
|
||||||
interface PackageHistoryQueryParams {
|
interface PackageHistoryQueryParams {
|
||||||
pageNum: number;
|
pageNum: number;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import type { TableColumnsType } from 'ant-design-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 { useI18n } from "vue-i18n";
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { fetchPackageHistory } from '@/service/api/auth';
|
import { fetchPackageHistory } from '@/service/api/auth';
|
||||||
@@ -53,6 +53,50 @@ onMounted(() => {
|
|||||||
getPackageData();
|
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>(() => [
|
const columns = computed<TableColumnsType>(() => [
|
||||||
{
|
{
|
||||||
title: t('page.packagehistories.orderdate'),
|
title: t('page.packagehistories.orderdate'),
|
||||||
@@ -71,15 +115,20 @@ const columns = computed<TableColumnsType>(() => [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('page.packagehistories.type'),
|
title: t('page.packagehistories.packagename'),
|
||||||
dataIndex: 'type',
|
dataIndex: ['upackage', 'packageName'],
|
||||||
key: 'type',
|
key: 'packageName',
|
||||||
customRender: ({ text }: { text: number }) => {
|
customRender: ({ text, record }: { text: string; record: Api.Package.PackageHistoryRecord }) => {
|
||||||
return h(ATag, {
|
return h(AButton, {
|
||||||
color: 'green'
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -148,4 +210,45 @@ const columns = computed<TableColumnsType>(() => [
|
|||||||
.pl-4 {
|
.pl-4 {
|
||||||
padding-left: 1rem;
|
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>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user