2
0

feat:套餐办理界面中英适配

This commit is contained in:
zhongzm
2025-01-23 17:25:13 +08:00
parent 9dee7d17eb
commit 34cdce8a87
3 changed files with 79 additions and 38 deletions

View File

@@ -518,16 +518,28 @@ const local: any = {
},
},
setmeal:{
changemeallable:'Change package discount|The traffic is unlimited, and you can choose from multiple grades!',
changablelevel:'Selectable gears',
highlyrecommended:'HOT',
mealmin:'min',
mealvip:'VIP*1',
mealdetail:'Course details',
Limitedtimeoffer:'Limited time offer',
GeneralPurposeTraffic:'General Purpose Traffic',
packagename:'Package name',
client:'Client',
GeneralPurposeTraffic:'Traffic',
Expirationdate:'Expiration date',
rate:'Rate',
unlimit:'Unlimited',
uplimit:'Up rate',
downlimit:'Down rate',
useful:' validity',
device:'device',
upto:'Up to ',
canbe:' device can be online simultaneously',
hour:'Hour',
day:'Day',
month:'Month',
year:'Year',
unknow:'Unknow',
Effectivemethod:'Effective method',
Applynow:'Apply now',
noPackages:'No packages'
},
carddata:{
email:'Email',

View File

@@ -520,16 +520,28 @@ const local:any = {
}
},
setmeal:{
changemeallable:'换套餐优惠|流量畅用,多个档次任你选!',
changablelevel:'可选档位',
highlyrecommended:'强烈推荐',
mealmin:'分钟',
mealvip:'会员',
mealdetail:'套餐详情',
Limitedtimeoffer:'限时优惠',
packagename:'套餐名称',
client:'设备数量',
GeneralPurposeTraffic:'通用流量',
Expirationdate:'有效期限',
rate:'套餐速率',
unlimit:'无限制',
uplimit:'上行速率',
downlimit:'下行速率',
useful:'内有效',
device:'台设备',
upto:'最多',
canbe:'台设备允许同时在线',
hour:'小时',
day:'天',
month:'月',
year:'年',
unknow:'未知',
Effectivemethod:'生效方式',
Applynow:'立即办理',
noPackages:'暂无套餐'
},
carddata:{
email:'邮箱地址',

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { ref, onMounted } from 'vue';
import { ref, onMounted, computed } from 'vue';
import { fetchPackageList, submitOrder } from '@/service/api/auth';
import { message } from 'ant-design-vue';
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
@@ -49,15 +49,15 @@ const PERIOD_TYPE = {
// 添加有效期单位映射
const PERIOD_UNIT = {
0: '小时',
1: '天',
2: '月',
3: '年'
0: t('page.setmeal.hour'),
1: t('page.setmeal.day'),
2: t('page.setmeal.month'),
3: t('page.setmeal.year')
} as const;
// 格式化有效期显示
const formatValidityPeriod = (num: number, type: number): string => {
const unit = PERIOD_UNIT[type as keyof typeof PERIOD_UNIT] || '未知';
const unit = PERIOD_UNIT[type as keyof typeof PERIOD_UNIT] || t('page.setmeal.unknow');
return `${num}${unit}`;
};
@@ -95,10 +95,10 @@ const formatTraffic = (bytes: number): string => {
// 添加速率格式化函数
const formatSpeed = (speed: number): string => {
if (speed >= 1000000) {
return `${(speed / 1000000).toFixed(1)}Gbps`;
} else if (speed >= 1000) {
return `${(speed / 1000).toFixed(1)}Mbps`;
if (speed >= 1048576) {
return `${(speed / 1048576).toFixed(1)}Gbps`;
} else if (speed >= 1024) {
return `${(speed / 1024).toFixed(1)}Mbps`;
}
return `${speed}Kbps`;
};
@@ -142,7 +142,12 @@ const currentOrderInfo = ref({
// 添加 appStore 实例
const appStore = useAppStore();
// 添加加载状态和数据状态的响应式引用
const isLoading = ref(false);
const hasPackages = computed(() => packageOptions.value.length > 0);
const fetchPackages = async () => {
isLoading.value = true;
try {
const response = await fetchPackageList();
if (response.data && Array.isArray(response.data)) {
@@ -154,7 +159,7 @@ const fetchPackages = async () => {
clientNumEnable: pkg.clientNumEnable,
traffic: Number(pkg.traffic),
trafficEnable: pkg.trafficEnable,
trafficDisplay: pkg.trafficEnable ? formatTraffic(Number(pkg.traffic)) : '无限制',
trafficDisplay: pkg.trafficEnable ? formatTraffic(Number(pkg.traffic)) : t('page.setmeal.unlimit'),
durationEnable: Boolean(pkg.periodNum && pkg.periodType !== undefined),
isRecommended: pkg.isRecommended || false,
promotion: pkg.promotion || '',
@@ -162,7 +167,7 @@ const fetchPackages = async () => {
periodType: Number(pkg.periodType),
validityPeriod: pkg.periodNum && pkg.periodType !== undefined
? formatValidityPeriod(Number(pkg.periodNum), Number(pkg.periodType))
: '无限制',
: t('page.setmeal.unlimit'),
rateLimitEnable: pkg.rateLimitEnable,
rateLimits: {
upLimitEnable: pkg.rateLimits?.upLimitEnable || false,
@@ -178,6 +183,9 @@ const fetchPackages = async () => {
}
} catch (error) {
console.error('Failed to fetch packages:', error);
message.error(t('page.setmeal.fetchFailed'));
} finally {
isLoading.value = false;
}
};
@@ -251,7 +259,6 @@ onMounted(async () => {
<div class="price">
<span class="currency">¥</span>
<span class="amount">{{ selectedPackage.price }}</span>
<span class="period">/</span>
</div>
<div class="subtitle">{{ selectedPackage.packageName }}</div>
</div>
@@ -277,9 +284,9 @@ onMounted(async () => {
</div>
<div class="package-name">{{ option.packageName }}</div>
<div class="price">¥{{ option.price }}</div>
<div class="traffic">{{ option.trafficEnable ? option.trafficDisplay : '无限制' }}</div>
<div class="traffic">{{ option.trafficEnable ? option.trafficDisplay : t('page.setmeal.unlimit') }}</div>
<div class="device-count">
{{ option.clientNumEnable ? `${option.clientNum}台设备` : '无限制' }}
{{ option.clientNumEnable ? `${option.clientNum} ${t('page.setmeal.device')}` : t('page.setmeal.unlimit') }}
</div>
</div>
</div>
@@ -290,39 +297,39 @@ onMounted(async () => {
<h3 class="section-title">{{ t('page.setmeal.mealdetail') }}</h3>
<div class="details-list">
<div class="detail-item">
<div class="label">套餐名称</div>
<div class="label">{{ t('page.setmeal.packagename') }}</div>
<div class="value">{{ selectedPackage.packageName }}</div>
</div>
<div class="detail-item">
<div class="label">{{ t('page.setmeal.GeneralPurposeTraffic') }}</div>
<div class="value">
{{ selectedPackage.trafficEnable ? selectedPackage.trafficDisplay : '无限制' }}
{{ selectedPackage.trafficEnable ? selectedPackage.trafficDisplay : t('page.setmeal.unlimit') }}
</div>
</div>
<div class="detail-item">
<div class="label">设备数量</div>
<div class="label">{{ t('page.setmeal.client') }}</div>
<div class="value">
{{ selectedPackage.clientNumEnable ? `最多${selectedPackage.clientNum}台设备同时在线` : '无限制' }}
{{ selectedPackage.clientNumEnable ? `${t('page.setmeal.upto')} ${selectedPackage.clientNum} ${t('page.setmeal.canbe')}` : t('page.setmeal.unlimit') }}
</div>
</div>
<div class="detail-item">
<div class="label">有效期限</div>
<div class="label">{{ t('page.setmeal.Expirationdate') }}</div>
<div class="value">
{{ selectedPackage.durationEnable ? selectedPackage.validityPeriod+'内有效' : '无限制' }}
{{ selectedPackage.durationEnable ? selectedPackage.validityPeriod+t('page.setmeal.useful') : t('page.setmeal.unlimit') }}
</div>
</div>
<div class="detail-item">
<div class="label">速率限制</div>
<div class="label">{{ t('page.setmeal.rate') }}</div>
<div class="value">
<template v-if="!selectedPackage.rateLimitEnable">
不限速
{{ t('page.setmeal.unlimit') }}
</template>
<template v-else>
<div>
上行{{ selectedPackage.rateLimits.upLimitEnable ? formatSpeed(selectedPackage.rateLimits.upLimit) : '-' }}
{{ t('page.setmeal.uplimit') }}{{ selectedPackage.rateLimits.upLimitEnable ? formatSpeed(selectedPackage.rateLimits.upLimit) : '-' }}
</div>
<div>
下行{{ selectedPackage.rateLimits.downLimitEnable ? formatSpeed(selectedPackage.rateLimits.downLimit) : '-' }}
{{ t('page.setmeal.downlimit') }}{{ selectedPackage.rateLimits.downLimitEnable ? formatSpeed(selectedPackage.rateLimits.downLimit) : '-' }}
</div>
</template>
</div>
@@ -331,9 +338,12 @@ onMounted(async () => {
<button
class="btn-primary"
@click="handleSubmitOrder"
:disabled="!selectedPackage.id"
:disabled="isLoading || !hasPackages"
>
{{ t('page.setmeal.Applynow') }}
{{ isLoading ? t('page.common.loading') :
!hasPackages ? t('page.setmeal.noPackages') :
t('page.setmeal.Applynow')
}}
</button>
</div>
</div>
@@ -491,6 +501,13 @@ onMounted(async () => {
font-size: 16px;
width: 90%;
max-width: 400px;
transition: all 0.3s;
}
.btn-primary:disabled {
background: #ccc;
cursor: not-allowed;
opacity: 0.7;
}
.package-name {