feat(兑换金币页): 使用新的头部组件,对接语言切换功能并调整布局
This commit is contained in:
parent
bb1db52774
commit
3e5fd32bea
@ -137,6 +137,17 @@
|
|||||||
"tips": "نصائح",
|
"tips": "نصائح",
|
||||||
"leave_agent_tips": "يمكن للمضيف مغادرة الوكيل الحالي فقط في اليوم الأول والـ16 من كل شهر",
|
"leave_agent_tips": "يمكن للمضيف مغادرة الوكيل الحالي فقط في اليوم الأول والـ16 من كل شهر",
|
||||||
|
|
||||||
|
"loading": "جار التحميل",
|
||||||
|
"details": "تفاصيل",
|
||||||
|
"failed_to_load_balance": "فشل تحميل الرصيد. يرجى المحاولة مرة أخرى.",
|
||||||
|
"failed_to_load_user_info": "فشل تحميل معلومات المستخدم",
|
||||||
|
"please_select_coin_amount": "يرجى اختيار كمية العملات أولاً",
|
||||||
|
"insufficient_balance": "رصيد غير كافٍ. رصيدك الحالي هو ${balance} دولارًا، لكنك تحتاج إلى ${price} دولارًا للتبادل.",
|
||||||
|
"confirm_exchange_coins": "هل تريد تبادل العملات مقابل ${price} دولارًا؟",
|
||||||
|
"exchange_success": "تم تبادل العملات مقابل ${price} دولارًا بنجاح",
|
||||||
|
"exchange_failed": "فشل التبادل، يرجى المحاولة لاحقًا.",
|
||||||
|
"exchange_error_occurred": "حدث خطأ أثناء عملية التبادل. يرجى المحاولة لاحقًا.",
|
||||||
|
|
||||||
"application_record_not_found": "Application record not found",
|
"application_record_not_found": "Application record not found",
|
||||||
"application_processed_cannot_cancel": "Application has been processed and cannot be canceled",
|
"application_processed_cannot_cancel": "Application has been processed and cannot be canceled",
|
||||||
"cancellation_failed_try_again": "Cancellation failed, please try again",
|
"cancellation_failed_try_again": "Cancellation failed, please try again",
|
||||||
|
|||||||
@ -137,6 +137,17 @@
|
|||||||
"tips": "Tips",
|
"tips": "Tips",
|
||||||
"leave_agent_tips": "The host can only leave the current agent on the 1st and 16th of each month",
|
"leave_agent_tips": "The host can only leave the current agent on the 1st and 16th of each month",
|
||||||
|
|
||||||
|
"loading": "Loading",
|
||||||
|
"details": "Details",
|
||||||
|
"failed_to_load_balance": "Failed to load balance. Please try again.",
|
||||||
|
"failed_to_load_user_info": "Failed to load user information",
|
||||||
|
"please_select_coin_amount": "Please select a coin amount first",
|
||||||
|
"insufficient_balance": "Insufficient balance. Your current balance is ${balance}, but you need $${price} to exchange.",
|
||||||
|
"confirm_exchange_coins": "Do you want to exchange coins for $${price}?",
|
||||||
|
"exchange_success": "Successfully exchanged coins for $${price}",
|
||||||
|
"exchange_failed": "Exchange failed, please try again later.",
|
||||||
|
"exchange_error_occurred": "An error occurred during the exchange process. Please try again later.",
|
||||||
|
|
||||||
"application_record_not_found": "Application record not found",
|
"application_record_not_found": "Application record not found",
|
||||||
"application_processed_cannot_cancel": "Application has been processed and cannot be canceled",
|
"application_processed_cannot_cancel": "Application has been processed and cannot be canceled",
|
||||||
"cancellation_failed_try_again": "Cancellation failed, please try again",
|
"cancellation_failed_try_again": "Cancellation failed, please try again",
|
||||||
|
|||||||
@ -137,6 +137,17 @@
|
|||||||
"tips": "提示",
|
"tips": "提示",
|
||||||
"leave_agent_tips": "主播只能在每月1日和16日离开当前代理",
|
"leave_agent_tips": "主播只能在每月1日和16日离开当前代理",
|
||||||
|
|
||||||
|
"loading": "加载中",
|
||||||
|
"details": "详情",
|
||||||
|
"failed_to_load_balance": "加载余额失败,请重试。",
|
||||||
|
"failed_to_load_user_info": "加载用户信息失败",
|
||||||
|
"please_select_coin_amount": "请先选择金币数量",
|
||||||
|
"insufficient_balance": "余额不足。您当前余额为${balance}美元,但兑换需要${price}美元。",
|
||||||
|
"confirm_exchange_coins": "您确定要兑换${price}美元的金币吗?",
|
||||||
|
"exchange_success": "成功兑换${price}美元的金币",
|
||||||
|
"exchange_failed": "兑换失败,请稍后重试。",
|
||||||
|
"exchange_error_occurred": "兑换过程中发生错误,请稍后重试。",
|
||||||
|
|
||||||
"application_record_not_found": "申请记录未找到",
|
"application_record_not_found": "申请记录未找到",
|
||||||
"application_processed_cannot_cancel": "申请已被处理,无法取消",
|
"application_processed_cannot_cancel": "申请已被处理,无法取消",
|
||||||
"cancellation_failed_try_again": "取消失败,请重试",
|
"cancellation_failed_try_again": "取消失败,请重试",
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="exchange-gold-coins gradient-background-circles">
|
<div class="exchange-gold-coins gradient-background-circles">
|
||||||
<MobileHeader title="Exchange Gold Coins" />
|
<!-- 使用 GeneralHeader 替换 MobileHeader -->
|
||||||
|
<GeneralHeader
|
||||||
|
:title="t('exchange_gold_coins')"
|
||||||
|
:showBack="true"
|
||||||
|
:showLanguageList="true"
|
||||||
|
color="black"
|
||||||
|
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 999"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<!-- 信息部分 -->
|
<!-- 信息部分 -->
|
||||||
@ -13,10 +20,10 @@
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div style="font-weight: 600">Information</div>
|
<div style="font-weight: 600">{{ t('information') }}</div>
|
||||||
<div style="display: flex; align-items: center" @click="showDetails">
|
<div style="display: flex; align-items: center" @click="showDetails">
|
||||||
<div style="color: rgba(0, 0, 0, 0.4)">Details</div>
|
<div style="color: rgba(0, 0, 0, 0.4)">{{ t('details') }}</div>
|
||||||
<img src="../assets/icon/arrow.png" alt="" width="16px" />
|
<img src="../assets/icon/arrow.png" alt="" class="flipImg" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -28,8 +35,8 @@
|
|||||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
|
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<span style="font-weight: 510; font-size: 1em">Available salary: </span>
|
<span style="font-weight: 510; font-size: 1em">{{ t('available_salaries') }} </span>
|
||||||
<span v-if="loading" class="loading-text">Loading...</span>
|
<span v-if="loading" class="loading-text">{{ t('loading') }}...</span>
|
||||||
<span v-else style="font-weight: 700; color: #333; font-size: 1.1em">{{
|
<span v-else style="font-weight: 700; color: #333; font-size: 1.1em">{{
|
||||||
availableSalary
|
availableSalary
|
||||||
}}</span>
|
}}</span>
|
||||||
@ -38,7 +45,7 @@
|
|||||||
|
|
||||||
<!-- 兑换部分 -->
|
<!-- 兑换部分 -->
|
||||||
<div>
|
<div>
|
||||||
<div style="font-weight: 600; margin-bottom: 10px">Exchange Gold Coins</div>
|
<div style="font-weight: 600; margin-bottom: 10px">{{ t('exchange_gold_coins') }}</div>
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -64,7 +71,7 @@
|
|||||||
<!-- 兑换按钮 -->
|
<!-- 兑换按钮 -->
|
||||||
<div style="display: flex; justify-content: center; margin-top: 10px">
|
<div style="display: flex; justify-content: center; margin-top: 10px">
|
||||||
<button class="exchange-btn" @click="exchangeCoins" :disabled="!selectedCoin">
|
<button class="exchange-btn" @click="exchangeCoins" :disabled="!selectedCoin">
|
||||||
Exchange
|
{{ t('exchange') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -73,14 +80,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted, computed } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import GeneralHeader from '@/components/GeneralHeader.vue'
|
||||||
import { getBankBalance, userSalaryCheckExchange, userBankExchangeGold } from '../api/wallet.js'
|
import { getBankBalance, userSalaryCheckExchange, userBankExchangeGold } from '../api/wallet.js'
|
||||||
import { showError, showSuccess, showWarning } from '@/utils/toast.js'
|
import { showError, showSuccess, showWarning } from '@/utils/toast.js'
|
||||||
|
import { setDocumentDirection } from '@/locales/i18n'
|
||||||
|
|
||||||
|
const { t, locale } = useI18n()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
// 监听语言变化并设置文档方向
|
||||||
|
locale.value && setDocumentDirection(locale.value)
|
||||||
|
|
||||||
const availableSalary = ref('0')
|
const availableSalary = ref('0')
|
||||||
const selectedCoin = ref(null)
|
const selectedCoin = ref(null)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -114,7 +127,7 @@ const fetchBankBalance = async () => {
|
|||||||
console.error('Failed to fetch bank balance:', error)
|
console.error('Failed to fetch bank balance:', error)
|
||||||
availableSalary.value = '0.00'
|
availableSalary.value = '0.00'
|
||||||
// 可以显示错误提示
|
// 可以显示错误提示
|
||||||
showError('Failed to load balance. Please try again.')
|
showError(t('failed_to_load_balance'))
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -139,15 +152,13 @@ const checkUserRole = async () => {
|
|||||||
// 处理特定错误情况
|
// 处理特定错误情况
|
||||||
if (error.errorCode === 1083) {
|
if (error.errorCode === 1083) {
|
||||||
// NOT_OPEN_ERROR
|
// NOT_OPEN_ERROR
|
||||||
showWarning('Exchange NOT_OPEN_ERROR')
|
showWarning(t('exchange_not_available'))
|
||||||
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
||||||
// 处理 406 Not Acceptable 状态码
|
// 处理 406 Not Acceptable 状态码
|
||||||
showError(
|
showError(t('request_not_acceptable'))
|
||||||
'The server cannot produce a response matching the list of acceptable values defined in the request headers'
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// 其他错误情况
|
// 其他错误情况
|
||||||
showError('Failed to load user information')
|
showError(t('failed_to_load_user_info'))
|
||||||
}
|
}
|
||||||
router.back() // 对于其他严重错误,也建议退出页面
|
router.back() // 对于其他严重错误,也建议退出页面
|
||||||
|
|
||||||
@ -160,7 +171,7 @@ const checkUserRole = async () => {
|
|||||||
|
|
||||||
const exchangeCoins = async () => {
|
const exchangeCoins = async () => {
|
||||||
if (!selectedCoin.value) {
|
if (!selectedCoin.value) {
|
||||||
showError('Please select a coin amount first')
|
showError(t('please_select_coin_amount'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,15 +183,16 @@ const exchangeCoins = async () => {
|
|||||||
|
|
||||||
if (isNaN(availableBalance) || availableBalance < coinPrice) {
|
if (isNaN(availableBalance) || availableBalance < coinPrice) {
|
||||||
showError(
|
showError(
|
||||||
`Insufficient balance. Your current balance is $${availableBalance.toFixed(
|
t('insufficient_balance', {
|
||||||
2
|
balance: availableBalance.toFixed(2),
|
||||||
)}, but you need $${coinPrice} to exchange.`
|
price: coinPrice,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示确认对话框
|
// 显示确认对话框
|
||||||
const confirmExchange = confirm(`Do you want to exchange coins for $${selectedCoinData.price}?`)
|
const confirmExchange = confirm(t('confirm_exchange_coins', { price: selectedCoinData.price }))
|
||||||
|
|
||||||
if (confirmExchange) {
|
if (confirmExchange) {
|
||||||
try {
|
try {
|
||||||
@ -192,7 +204,7 @@ const exchangeCoins = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (response.status === true || response.errorCode === 0) {
|
if (response.status === true || response.errorCode === 0) {
|
||||||
showSuccess(`Successfully exchanged coins for $${selectedCoinData.price}`)
|
showSuccess(t('exchange_success', { price: selectedCoinData.price }))
|
||||||
|
|
||||||
// 刷新银行余额
|
// 刷新银行余额
|
||||||
await fetchBankBalance()
|
await fetchBankBalance()
|
||||||
@ -201,12 +213,12 @@ const exchangeCoins = async () => {
|
|||||||
selectedCoin.value = null
|
selectedCoin.value = null
|
||||||
} else {
|
} else {
|
||||||
// 接口调用失败
|
// 接口调用失败
|
||||||
const errorMessage = response.message || 'Exchange failed, please try again later.'
|
const errorMessage = response.message || t('exchange_failed')
|
||||||
showError(errorMessage)
|
showError(errorMessage)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Exchange error:', error)
|
console.error('Exchange error:', error)
|
||||||
showError('An error occurred during the exchange process. Please try again later.')
|
showError(t('exchange_error_occurred'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果用户取消,则什么都不做
|
// 如果用户取消,则什么都不做
|
||||||
@ -230,6 +242,10 @@ const selectCoin = (coin) => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
checkUserRole()
|
checkUserRole()
|
||||||
fetchBankBalance()
|
fetchBankBalance()
|
||||||
|
console.log(
|
||||||
|
"document.documentElement.getAttribute('dir') === 'rtl'",
|
||||||
|
document.documentElement.getAttribute('dir') === 'rtl'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -334,10 +350,19 @@ onMounted(() => {
|
|||||||
border: none;
|
border: none;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
color: white;
|
color: white;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exchange-btn:disabled {
|
.exchange-btn:disabled {
|
||||||
background: #ccc;
|
background: #ccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flipImg {
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 360px) {
|
@media screen and (max-width: 360px) {
|
||||||
@ -357,4 +382,16 @@ onMounted(() => {
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RTL支持 */
|
||||||
|
[dir='rtl'] .details-btn {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir='rtl'] .flipImg {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 4px;
|
||||||
|
-webkit-transform: scaleX(-1);
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user