fix:套餐界面
This commit is contained in:
@@ -484,8 +484,57 @@ const local: any = {
|
|||||||
},
|
},
|
||||||
addDict: 'Add Dictionary',
|
addDict: 'Add Dictionary',
|
||||||
editDict: 'Edit Dictionary'
|
editDict: 'Edit Dictionary'
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
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',
|
||||||
|
Effectivemethod:'Effective method',
|
||||||
|
Applynow:'Apply now',
|
||||||
|
},
|
||||||
|
carddata:{
|
||||||
|
email:'Email',
|
||||||
|
Rechargeamount:'Recharge amount',
|
||||||
|
Customization:'Customize',
|
||||||
|
price:'price',
|
||||||
|
setprice:'Please enter the amount',
|
||||||
|
Remainingbalance:'Remaining balance',
|
||||||
|
Theamountreceived:'The amount received',
|
||||||
|
pay:'pay now'
|
||||||
|
},
|
||||||
|
headerbanner:{
|
||||||
|
Remainingcredit:'Remain credit',
|
||||||
|
monthphonebill:'Month bill',
|
||||||
|
Flowremaining:'Remain flowr',
|
||||||
|
monthflowr:'Month flowr',
|
||||||
|
Trafficrate:'Traffic rate',
|
||||||
|
Currentspeed:'Current speed',
|
||||||
|
Used:'Used',
|
||||||
|
maxspeed:'Max',
|
||||||
|
},
|
||||||
|
userInfo:{
|
||||||
|
user:'User',
|
||||||
|
ownInfo:'Personal Information',
|
||||||
|
changepassword:'Change password',
|
||||||
|
KYCselect:'KYC certification',
|
||||||
|
Devicemanage:'Device management',
|
||||||
|
},
|
||||||
|
histories:{
|
||||||
|
billdate:'Bill date',
|
||||||
|
amount:'Amount',
|
||||||
|
status:'Status',
|
||||||
|
Historicalbilling:'Historical billing',
|
||||||
|
device:'Device',
|
||||||
|
Usetraffic:'Use traffic',
|
||||||
|
Paid:'Paid',
|
||||||
|
Unpaid:'Unpaid',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
required: 'Cannot be empty',
|
required: 'Cannot be empty',
|
||||||
|
|||||||
@@ -485,7 +485,56 @@ const local:any = {
|
|||||||
addDict: '新增字典',
|
addDict: '新增字典',
|
||||||
editDict: '编辑字典'
|
editDict: '编辑字典'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
setmeal:{
|
||||||
|
changemeallable:'换套餐优惠|流量畅用,多个档次任你选!',
|
||||||
|
changablelevel:'可选档位',
|
||||||
|
highlyrecommended:'强烈推荐',
|
||||||
|
mealmin:'分钟',
|
||||||
|
mealvip:'会员',
|
||||||
|
mealdetail:'套餐详情',
|
||||||
|
Limitedtimeoffer:'限时优惠',
|
||||||
|
GeneralPurposeTraffic:'通用流量',
|
||||||
|
Effectivemethod:'生效方式',
|
||||||
|
Applynow:'立即办理',
|
||||||
|
},
|
||||||
|
carddata:{
|
||||||
|
email:'邮箱地址',
|
||||||
|
Rechargeamount:'充值金额',
|
||||||
|
Customization:'自定义',
|
||||||
|
price:'售价',
|
||||||
|
setprice:'请输入金额',
|
||||||
|
Remainingbalance:'话费余额',
|
||||||
|
Theamountreceived:'到账金额',
|
||||||
|
pay:'立即支付',
|
||||||
|
},
|
||||||
|
headerbanner:{
|
||||||
|
Remainingcredit:'剩余话费',
|
||||||
|
monthphonebill:'本月话费',
|
||||||
|
Flowremaining:'剩余流量',
|
||||||
|
monthflowr:'本月流量',
|
||||||
|
Trafficrate:'流量速率',
|
||||||
|
Currentspeed:'当前速度',
|
||||||
|
Used:'已用',
|
||||||
|
maxspeed:'峰值',
|
||||||
|
},
|
||||||
|
userInfo:{
|
||||||
|
user:'用户',
|
||||||
|
ownInfo:'个人信息',
|
||||||
|
changepassword:'修改密码',
|
||||||
|
KYCselect:'KYC认证',
|
||||||
|
Devicemanage:'设备管理',
|
||||||
|
},
|
||||||
|
histories:{
|
||||||
|
billdate:'账单日期',
|
||||||
|
amount:'金额',
|
||||||
|
status:'状态',
|
||||||
|
Historicalbilling:'历史账单',
|
||||||
|
device:'设备',
|
||||||
|
Usetraffic:'使用流量',
|
||||||
|
Paid:'已支付',
|
||||||
|
Unpaid:'未支付',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
required: '不能为空',
|
required: '不能为空',
|
||||||
|
|||||||
1
src/typings/auto-imports.d.ts
vendored
1
src/typings/auto-imports.d.ts
vendored
@@ -246,6 +246,7 @@ declare global {
|
|||||||
const useAuthStore: typeof import('../store/modules/auth/index')['useAuthStore']
|
const useAuthStore: typeof import('../store/modules/auth/index')['useAuthStore']
|
||||||
const useBase64: typeof import('@vueuse/core')['useBase64']
|
const useBase64: typeof import('@vueuse/core')['useBase64']
|
||||||
const useBattery: typeof import('@vueuse/core')['useBattery']
|
const useBattery: typeof import('@vueuse/core')['useBattery']
|
||||||
|
const useBillingStore: typeof import('../store/modules/billing/billing')['useBillingStore']
|
||||||
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
|
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
|
||||||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||||
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
||||||
|
|||||||
@@ -1,7 +1,259 @@
|
|||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
const { t } = useI18n();
|
||||||
|
interface PackageOption {
|
||||||
|
id: number
|
||||||
|
price: number
|
||||||
|
minutes: number
|
||||||
|
data: number
|
||||||
|
isRecommended?: boolean
|
||||||
|
promotion?: string
|
||||||
|
callMinutes?: string
|
||||||
|
cloudStorage?: string
|
||||||
|
effectiveDate?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const packageOptions: PackageOption[] = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
price: 59,
|
||||||
|
minutes: 100,
|
||||||
|
data: 10,
|
||||||
|
isRecommended: true,
|
||||||
|
promotion: '升59元全家享套餐,每月享10元话费+10GB国内通用流量,共12个月;限时加享价值120元热门会员优惠',
|
||||||
|
callMinutes: '100分钟,当月有效',
|
||||||
|
cloudStorage: '40GB,每月有效',
|
||||||
|
effectiveDate: '下一月结日'
|
||||||
|
},
|
||||||
|
{ id: 2, price: 59, minutes: 100, data: 10 },
|
||||||
|
{ id: 3, price: 79, minutes: 150, data: 15 },
|
||||||
|
{ id: 4, price: 99, minutes: 200, data: 20 },
|
||||||
|
{ id: 5, price: 129, minutes: 300, data: 30 },
|
||||||
|
{ id: 6, price: 169, minutes: 500, data: 40 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const selectedPackage = ref(packageOptions[0])
|
||||||
|
|
||||||
|
const selectPackage = (option: PackageOption) => {
|
||||||
|
selectedPackage.value = option
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>套餐</div>
|
<div class="package-container">
|
||||||
|
<!-- 顶部价格展示 -->
|
||||||
|
<div class="price-header">
|
||||||
|
<div class="price">
|
||||||
|
<span class="currency">¥</span>
|
||||||
|
<span class="amount">{{ selectedPackage.price }}</span>
|
||||||
|
<span class="period">/月</span>
|
||||||
|
</div>
|
||||||
|
<div class="subtitle">{{t('page.setmeal.changemeallable')}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 套餐选项 -->
|
||||||
|
<div class="package-options">
|
||||||
|
<h3 class="section-title">{{ t('page.setmeal.changablelevel') }}</h3>
|
||||||
|
<div class="options-grid">
|
||||||
|
<div
|
||||||
|
v-for="option in packageOptions"
|
||||||
|
:key="option.id"
|
||||||
|
:class="[
|
||||||
|
'option-card',
|
||||||
|
{
|
||||||
|
recommended: option.isRecommended,
|
||||||
|
selected: selectedPackage.id === option.id
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
@click="selectPackage(option)"
|
||||||
|
>
|
||||||
|
<div v-if="option.isRecommended" class="recommended-tag">{{ t('page.setmeal.highlyrecommended') }}</div>
|
||||||
|
<div class="price">¥{{ option.price }}</div>
|
||||||
|
<div class="details">
|
||||||
|
{{ option.minutes }} {{ t('page.setmeal.mealmin') }} / {{ option.data }}GB
|
||||||
|
<template v-if="option.isRecommended">/ {{ t('page.setmeal.mealvip') }}</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 套餐详情 -->
|
||||||
|
<div class="package-details">
|
||||||
|
<h3 class="section-title">{{ t('page.setmeal.mealdetail') }}</h3>
|
||||||
|
<div class="details-list">
|
||||||
|
<div class="detail-item">
|
||||||
|
<div class="label">{{ t('page.setmeal.Limitedtimeoffer') }}</div>
|
||||||
|
<div class="value highlight">{{ selectedPackage.promotion || '暂无优惠' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<div class="label">{{ t('page.setmeal.GeneralPurposeTraffic') }}</div>
|
||||||
|
<div class="value">{{ `${selectedPackage.data}GB,当月有效` }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<div class="label">{{ t('page.setmeal.Effectivemethod') }}</div>
|
||||||
|
<div class="value">{{ selectedPackage.effectiveDate || '下一月结日' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部操作栏 -->
|
||||||
|
<div class="bottom-bar">
|
||||||
|
<button class="btn-primary">{{ t('page.setmeal.Applynow') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.package-container {
|
||||||
|
background: #f5f5f5;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 16px 16px 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-header {
|
||||||
|
background: #fff1f0;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
color: #ff4d4f;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.currency {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #333;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 4px;
|
||||||
|
height: 16px;
|
||||||
|
background: #1890ff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-card {
|
||||||
|
background: white;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-card.selected {
|
||||||
|
border-color: #ff4d4f;
|
||||||
|
background: #fff1f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommended-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 0 0 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-details {
|
||||||
|
background: white;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 80px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-bar {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: white;
|
||||||
|
padding: 12px 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 32px;
|
||||||
|
border-radius: 24px;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user