feat(新页面): 靓号申请页(已对接接口)

This commit is contained in:
hzj 2025-12-11 11:53:39 +08:00
parent d4013ea556
commit 462b351389
8 changed files with 334 additions and 4 deletions

25
src/api/goodId.js Normal file
View File

@ -0,0 +1,25 @@
import { get, post } from '../utils/http.js'
// 获取用户消费等级
export const apiGetUserWealthLevel = async (userId) => {
try {
const response = await get(`/user-level/client/getByUserId?sysOrigin=LIKEI&userId=${userId}`)
return response
} catch (error) {
console.error('Failed to fetch get user wealth level:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}
// 申请靓号
export const applyGoodID = async (data) => {
try {
const response = await post(`/user/beautiful-number/apply`, data)
return response
} catch (error) {
console.error('Failed to fetch apply goodID:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}

View File

@ -353,5 +353,8 @@
"ranking_daily": "اليومي",
"ranking_weekly": "الأسبوعي",
"ranking_monthly": "الشهري",
"ranking_hourly": "بالساعة"
"ranking_hourly": "بالساعة",
"good_id_placeholder": "أدخل من 2 إلى 8 أرقام",
"my_wealth_level": "مستوى الثراء الخاص بي:"
}

View File

@ -353,5 +353,8 @@
"ranking_daily": "Daily",
"ranking_weekly": "Weekly",
"ranking_monthly": "Monthly",
"ranking_hourly": "Hourly"
"ranking_hourly": "Hourly",
"good_id_placeholder": "Enter 2 To 8 Digits",
"my_wealth_level": "My wealth level:"
}

View File

@ -353,5 +353,8 @@
"ranking_daily": "日榜",
"ranking_weekly": "周榜",
"ranking_monthly": "月榜",
"ranking_hourly": "小时榜"
"ranking_hourly": "小时榜",
"good_id_placeholder": "输入2到8位数字",
"my_wealth_level": "我的财富等级:"
}

View File

@ -196,6 +196,14 @@ const router = createRouter({
meta: { requiresAuth: true },
},
// 靓号
{
path: '/good-ID',
name: 'good-ID',
component: () => import('../views/GoodID/index.vue'),
meta: { requiresAuth: true },
},
// 收支相关页面
{
path: '/available-income',

View File

@ -73,15 +73,19 @@ export const ROLE_PERMISSIONS = {
PAGES.MAP, // 地图选择页面
...RANKING_PAGES, //排行榜
...ACTIVITIES, //活动页面
'/recharge', //搜索充值对象页面
'/recharge-pay-way', //充值方式页面
'/recharge-guide', //充值引导页面
'/recharge-agency-recruit', //充值代理介绍页面
'/search-payee', //搜索收款人
'/cash-out', // 提现页面
'/cash-out-details', //提现详情页面
'/KYC', //提现资料提交
'/bank-card', //选择银行卡
'/good-ID', //靓号申请页
],
// Admin管理员

View File

@ -421,16 +421,20 @@ class RouteGuard {
...ACTIVITIES, // 活动页面
'/404', // 404页面
'/error', // 通用错误页面
'/recharge', //搜索充值对象页面
'/recharge-pay-way', //充值方式页面
'/recharge-guide', //充值引导页面
'/recharge-agency-recruit', //充值代理介绍页面
'/pay-result',
'/pay-result', //支付结果页
'/search-payee', //搜索收款人
'/cash-out', // 提现页面
'/cash-out-details', //提现详情页面
'/KYC', //提现资料提交
'/bank-card', //选择银行卡
'/good-ID', //靓号申请页
]
return publicPages.includes(path)
}

280
src/views/GoodID/index.vue Normal file
View File

@ -0,0 +1,280 @@
<!-- src/views/Activities/Reward/RechargeReward.vue -->
<template>
<div>
<!-- Rewards0.png 使用相对定位容器 -->
<itemCenter :imgUrl="imageUrl('goodID0')" :contentStyle="`display: block;`">
<!-- 帮助按钮 -->
<img
v-smart-img
:src="imageUrl('help')"
alt=""
style="
position: absolute;
top: 57%;
right: 4%;
display: block;
width: 10vw;
aspect-ratio: 1/1;
object-fit: cover;
"
@click="maskLayerShow = true"
/>
<!-- 用户财富等级靓号申请窗口 -->
<itemCenter
style="position: absolute; top: 65%"
:imgUrl="imageUrl('applyBg')"
:contentStyle="`display: block;`"
>
<!-- 财富等级 -->
<div style="height: 46%; display: flex; justify-content: center; align-items: center">
<div
style="
width: 50%;
height: 30%;
display: flex;
justify-content: center;
align-items: center;
"
>
<div
style="
font-weight: 700;
font-size: 0.9em;
background: linear-gradient(0deg, #fff 0%, #ffe656 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
"
>
{{ t('my_wealth_level') }} {{ wealthLevel }}
</div>
</div>
</div>
<!-- 申请 -->
<div
style="
position: absolute;
bottom: 22%;
width: 79%;
height: 30%;
left: 50%;
transform: translateX(-50%);
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
"
>
<!-- 输入框 -->
<input
v-model="goodId"
type="text"
:placeholder="t('good_id_placeholder')"
style="
flex: 1;
min-width: 0;
align-self: stretch;
color: white;
font-weight: 700;
font-size: 1.1em;
border: none;
outline: none;
background-color: transparent;
"
@keyup.enter="confirm"
/>
<!-- 按钮 -->
<img
v-smart-img
:src="imageUrl(getImgName('applyBt'))"
alt=""
style="height: 70%; display: block"
@click="confirm"
/>
</div>
</itemCenter>
</itemCenter>
<!-- 其他图片直接引入 -->
<img v-smart-img :src="imageUrl('goodID1')" alt="" style="width: 100%; display: block" />
<img v-smart-img :src="imageUrl('goodID2')" alt="" style="width: 100%; display: block" />
<!-- 弹窗遮罩层 -->
<maskLayer :maskLayerShow="maskLayerShow" @click="maskLayerShow = false">
<!-- help弹窗 -->
<div style="margin: 20% 0" @click.stop>
<img
v-smart-img
:src="imageUrl(getImgName('rule'))"
alt=""
style="display: block; width: 100%"
/>
</div>
</maskLayer>
</div>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { useLangStore } from '@/stores/lang'
import { useI18n } from 'vue-i18n'
import { getPngUrl } from '@/config/imagePaths.js'
import { connectToApp } from '@/utils/appConnector.js'
import { preloadImages } from '@/utils/imagePreloader.js'
import { getUserId } from '@/utils/userStore.js'
import { showError, showWarning, showSuccess } from '@/utils/toast.js'
import { apiGetUserWealthLevel, applyGoodID } from '@/api/goodId.js'
import itemCenter from '@/components/itemCenter.vue'
import maskLayer from '@/components/MaskLayer.vue'
const { t, locale } = useI18n()
const langStore = useLangStore()
//
const currentLangType = computed(() => {
return langStore.selectedLang?.type || 'en'
})
// OSSURL
const imageUrl = (filename) => getPngUrl('GoodID/', filename)
//
const getImgName = (filename) => {
return currentLangType.value === 'ar' ? `${filename}_ar` : filename
}
const wealthLevel = ref('-') //
const goodId = ref('') //
const maskLayerShow = ref(false) //
//
const confirm = async () => {
if (!goodId.value.trim()) return
let data = { account: goodId.value.trim(), wealthLevel: wealthLevel.value }
try {
await applyGoodID(data)
goodId.value = '-'
} catch (error) {
showError(error.errorMsg)
}
}
//
const getUserWealthLevel = async () => {
try {
const resWealthLevel = await apiGetUserWealthLevel(getUserId())
if (resWealthLevel.status && resWealthLevel.body) {
wealthLevel.value = resWealthLevel.body?.wealthLevel || '-'
}
} catch (error) {
showError(error.errorMsg)
}
}
//
const initData = () => {
getUserWealthLevel() //
}
//
const preloadCriticalImages = () => {
const criticalImages = [
imageUrl('goodID0'),
imageUrl('goodID1'),
imageUrl('goodID2'),
imageUrl('help'),
imageUrl('rule'),
imageUrl('applyBg'),
imageUrl('applyBt'),
]
const criticalImages_ar = [
imageUrl('goodID0'),
imageUrl('goodID1'),
imageUrl('goodID2'),
imageUrl('help'),
imageUrl('rule_ar'),
imageUrl('applyBg'),
imageUrl('applyBt_ar'),
]
if (currentLangType.value == 'en') {
preloadImages(criticalImages)
} else if (currentLangType.value == 'ar') {
preloadImages(criticalImages_ar)
}
}
// 使APP
const connectToAppHandler = async () => {
await connectToApp(() => {
preloadCriticalImages() //
initData() //
})
}
onMounted(() => {
connectToAppHandler()
})
</script>
<style lang="scss" scoped>
* {
color: white;
font-family: 'Baloo 2';
}
.textGold {
background: linear-gradient(
255deg,
#b77c44 28.08%,
#fee5bb 46.5%,
#bf854a 67.95%,
#fcdfb3 85.67%,
#c0864b 102.89%,
#fbe8d4 122.57%
);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
input::placeholder {
color: #fff;
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;
}
}
@media screen and (min-width: 360px) {
* {
font-size: 12px;
}
}
@media screen and (min-width: 768px) {
* {
font-size: 24px;
}
}
@media screen and (min-width: 1024px) {
* {
font-size: 32px;
}
}
</style>