feat(邀请新用户页面): 使用网络图片,并对接图片的缓存,预加载等功能

This commit is contained in:
hzj 2025-12-02 18:22:44 +08:00
parent e47f2b9299
commit f95db045c9

View File

@ -1,5 +1,6 @@
<!-- src/views/Invitation/InviteToRegister.vue -->
<template> <template>
<div class="fullPage"> <div class="fullPage" :style="{ '--bg-url': `url(${imageUrl('bg')})` }">
<div style="position: absolute; top: 0; left: 0; width: 100%"> <div style="position: absolute; top: 0; left: 0; width: 100%">
<GeneralHeader <GeneralHeader
:isHomePage="true" :isHomePage="true"
@ -13,7 +14,8 @@
<div style="padding: 87% 0 5%"> <div style="padding: 87% 0 5%">
<img <img
v-if="showBindingBt" v-if="showBindingBt"
:src="images.enterCode" v-smart-img
:src="imageUrl('enterCode')"
alt="" alt=""
width="40%" width="40%"
@click="enterCodeShow = true" @click="enterCodeShow = true"
@ -21,7 +23,8 @@
/> />
<img <img
v-else-if="myInviter.inviterInfo?.userId" v-else-if="myInviter.inviterInfo?.userId"
:src="images.privateChat" v-smart-img
:src="imageUrl('privateChat')"
alt="" alt=""
width="40%" width="40%"
@click="gotoPrivateChat(myInviter.inviterInfo?.userId)" @click="gotoPrivateChat(myInviter.inviterInfo?.userId)"
@ -33,26 +36,6 @@
<div <div
style="padding: 0 3%; display: flex; flex-direction: column; gap: 12px; padding-bottom: 30px" style="padding: 0 3%; display: flex; flex-direction: column; gap: 12px; padding-bottom: 30px"
> >
<!-- 倒计时 -->
<!-- <div style="position: relative">
<img :src="images.countdownBg" alt="" width="100%" style="display: block" />
<div
style="
position: absolute;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
font-weight: 700;
letter-spacing: 2px;
"
>
29D 2323:23
</div>
</div> -->
<!-- 我的邀请码 --> <!-- 我的邀请码 -->
<div <div
style=" style="
@ -81,6 +64,7 @@
> >
<div style="font-weight: 590">{{ myInviteInfo.inviteCode || '' }}</div> <div style="font-weight: 590">{{ myInviteInfo.inviteCode || '' }}</div>
<img <img
v-smart-img
src="../../assets/icon/copy.png" src="../../assets/icon/copy.png"
alt="" alt=""
width="24px" width="24px"
@ -93,29 +77,45 @@
</div> </div>
<!-- 模块切换按钮 --> <!-- 模块切换按钮 -->
<div> <div style="display: flex; justify-content: space-around; align-items: center">
<div <!-- 列表按钮 -->
v-if="showModule == 'list'" <div style="width: 40%; position: relative">
style="display: flex; justify-content: space-around; align-items: center"
>
<img :src="images.listBtActive" alt="" width="40%" style="display: block" />
<img <img
:src="images.rewardBt" v-smart-img
:src="imageUrl('listBt')"
alt="" alt=""
width="40%" style="display: block; width: 100%"
style="display: block" :style="{ opacity: showModule === 'list' ? 0 : 1 }"
@click="showModule = 'reward'"
/>
</div>
<div v-else style="display: flex; justify-content: space-around; align-items: center">
<img
:src="images.listBt"
alt=""
width="40%"
style="display: block"
@click="showModule = 'list'" @click="showModule = 'list'"
/> />
<img :src="images.rewardBtActive" alt="" width="40%" style="display: block" /> <img
v-smart-img
:src="imageUrl('listBtActive')"
alt=""
style="display: block; width: 100%; position: absolute; top: 0; left: 0"
:style="{ opacity: showModule === 'list' ? 1 : 0 }"
@click="showModule = 'list'"
/>
</div>
<!-- 奖励按钮 -->
<div style="width: 40%; position: relative">
<img
v-smart-img
:src="imageUrl('rewardBt')"
alt=""
style="display: block; width: 100%"
:style="{ opacity: showModule === 'reward' ? 0 : 1 }"
@click="showModule = 'reward'"
/>
<img
v-smart-img
:src="imageUrl('rewardBtActive')"
alt=""
style="display: block; width: 100%; position: absolute; top: 0; left: 0"
:style="{ opacity: showModule === 'reward' ? 1 : 0 }"
@click="showModule = 'reward'"
/>
</div> </div>
</div> </div>
@ -124,7 +124,13 @@
<!-- 收入展示 --> <!-- 收入展示 -->
<div style="display: flex; justify-content: space-around; align-items: center"> <div style="display: flex; justify-content: space-around; align-items: center">
<div style="position: relative; width: 47%"> <div style="position: relative; width: 47%">
<img :src="images.totalIncome" alt="" width="100%" style="display: block" /> <img
v-smart-img
:src="imageUrl('totalIncome')"
alt=""
width="100%"
style="display: block"
/>
<div <div
style=" style="
position: absolute; position: absolute;
@ -136,12 +142,24 @@
align-items: center; align-items: center;
" "
> >
<img src="/src/assets/icon/coin.png" alt="" width="10%" style="display: block" /> <img
v-smart-img
src="/src/assets/icon/coin.png"
alt=""
width="10%"
style="display: block"
/>
<div style="font-weight: 590">{{ myInviteIncome.totalIncome || 0 }}</div> <div style="font-weight: 590">{{ myInviteIncome.totalIncome || 0 }}</div>
</div> </div>
</div> </div>
<div style="position: relative; width: 47%"> <div style="position: relative; width: 47%">
<img :src="images.todayIncome" alt="" width="100%" style="display: block" /> <img
v-smart-img
:src="imageUrl('todayIncome')"
alt=""
width="100%"
style="display: block"
/>
<div <div
style=" style="
position: absolute; position: absolute;
@ -153,7 +171,13 @@
align-items: center; align-items: center;
" "
> >
<img src="/src/assets/icon/coin.png" alt="" width="10%" style="display: block" /> <img
v-smart-img
src="/src/assets/icon/coin.png"
alt=""
width="10%"
style="display: block"
/>
<div style="font-weight: 590">{{ myInviteIncome.todayIncome || 0 }}</div> <div style="font-weight: 590">{{ myInviteIncome.todayIncome || 0 }}</div>
</div> </div>
</div> </div>
@ -287,7 +311,7 @@
gap: 4px; gap: 4px;
" "
> >
<img src="../../assets/icon/coin.png" alt="" width="15%" /> <img v-smart-img src="/src/assets/icon/coin.png" alt="" width="15%" />
<div style="color: #ffb627; font-size: 0.8em; font-weight: 590"> <div style="color: #ffb627; font-size: 0.8em; font-weight: 590">
{{ user.provideIncome || 0 }} {{ user.provideIncome || 0 }}
</div> </div>
@ -300,7 +324,8 @@
<div v-if="showModule == 'reward'" style="display: flex; flex-direction: column; gap: 12px"> <div v-if="showModule == 'reward'" style="display: flex; flex-direction: column; gap: 12px">
<div style="position: relative" v-for="poolItem in inviteAwardPool"> <div style="position: relative" v-for="poolItem in inviteAwardPool">
<img <img
:src="images[`reward${poolItem.quantity}people`]" v-smart-img
:src="imageUrl(`reward${poolItem.quantity}people`)"
alt="" alt=""
width="100%" width="100%"
style="display: block" style="display: block"
@ -319,7 +344,7 @@
style="width: 45%; position: relative" style="width: 45%; position: relative"
v-for="(award, index) in poolItem.activityRewardPropsList" v-for="(award, index) in poolItem.activityRewardPropsList"
> >
<img :src="images.rewardItemBg" alt="" width="100%" /> <img v-smart-img :src="imageUrl('rewardItemBg')" alt="" width="100%" />
<div <div
style=" style="
position: absolute; position: absolute;
@ -330,7 +355,7 @@
align-items: center; align-items: center;
" "
> >
<img :src="award.cover" alt="" width="50%" /> <img v-smart-img :src="award.cover" alt="" width="50%" />
<div>{{ showAwardText(award) }}</div> <div>{{ showAwardText(award) }}</div>
</div> </div>
</div> </div>
@ -338,12 +363,13 @@
<div style="display: flex; justify-content: center"> <div style="display: flex; justify-content: center">
<img <img
v-if="poolItem.state == '1'" v-if="poolItem.state == '1'"
:src="images.receiveBtActive" v-smart-img
:src="imageUrl('receiveBtActive')"
alt="" alt=""
width="35%" width="35%"
@click="receiveAward(poolItem.id)" @click="receiveAward(poolItem.id)"
/> />
<img v-else :src="images.receiveBt" alt="" width="35%" /> <img v-else v-smart-img :src="imageUrl('receiveBt')" alt="" width="35%" />
</div> </div>
</div> </div>
</div> </div>
@ -354,7 +380,7 @@
<maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup"> <maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup">
<!-- 帮助模块 --> <!-- 帮助模块 -->
<div v-if="helpInfoShow" style="margin: 20% 10%; position: relative" @click.stop> <div v-if="helpInfoShow" style="margin: 20% 10%; position: relative" @click.stop>
<img :src="images.helpInfo" alt="" width="100%" /> <img v-smart-img :src="imageUrl('helpInfo')" alt="" width="100%" />
<div <div
style="position: absolute; width: 8%; aspect-ratio: 1/1; top: 3.8%; right: 7%" style="position: absolute; width: 8%; aspect-ratio: 1/1; top: 3.8%; right: 7%"
@click="closedPopup" @click="closedPopup"
@ -408,7 +434,7 @@
</div> </div>
<!-- 确认按钮 --> <!-- 确认按钮 -->
<img :src="images.confirm" alt="" width="25%" @click="confirm" /> <img v-smart-img :src="imageUrl('confirm')" alt="" width="25%" @click="confirm" />
</div> </div>
<div style="color: rgba(0, 0, 0, 0.4); font-weight: 510; font-size: 0.7em"> <div style="color: rgba(0, 0, 0, 0.4); font-weight: 510; font-size: 0.7em">
*Only users who registered within 72 hours can fill in the invitation code. Once the *Only users who registered within 72 hours can fill in the invitation code. Once the
@ -434,7 +460,7 @@
<script setup> <script setup>
import { gotoPrivateChat } from '@/utils/appBridge.js' import { gotoPrivateChat } from '@/utils/appBridge.js'
import { computed, onMounted, onUnmounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import GeneralHeader from '@/components/GeneralHeader.vue' import GeneralHeader from '@/components/GeneralHeader.vue'
import maskLayer from '../../components/MaskLayer.vue' import maskLayer from '../../components/MaskLayer.vue'
import { showError, showWarning, showInfo, showSuccess } from '@/utils/toast.js' import { showError, showWarning, showInfo, showSuccess } from '@/utils/toast.js'
@ -449,18 +475,11 @@ import {
getMyInviter, // getMyInviter, //
} from '@/api/invitation.js' } from '@/api/invitation.js'
import { connectToApp } from '@/utils/appConnector.js' import { connectToApp } from '@/utils/appConnector.js'
import { getPngUrl } from '@/config/imagePaths.js'
import { preloadImages } from '@/utils/imagePreloader.js'
// vite // OSSURL
const imageModules = import.meta.glob('@/assets/images/InvitationNewUser/*.{png,jpg,svg}', { const imageUrl = (filename) => getPngUrl('invitation/InviteNewUser/', filename)
eager: true,
})
//
const images = Object.fromEntries(
Object.entries(imageModules).map(([path, module]) => {
const fileName = path.split('/').pop().split('.')[0]
return [fileName, module.default]
})
)
const { copy, isSupported } = useClipboard() const { copy, isSupported } = useClipboard()
@ -599,6 +618,38 @@ const receiveAward = async (awardId) => {
} }
} }
//
const preloadCriticalImages = () => {
const criticalImages = [
imageUrl('bg'),
imageUrl('enterCode'),
imageUrl('privateChat'),
imageUrl('listBtActive'),
imageUrl('rewardBt'),
imageUrl('listBt'),
imageUrl('rewardBtActive'),
imageUrl('totalIncome'),
imageUrl('todayIncome'),
imageUrl('helpInfo'),
imageUrl('confirm'),
imageUrl('rewardItemBg'),
imageUrl('receiveBtActive'),
imageUrl('receiveBt'),
imageUrl('reward5people'),
imageUrl('reward10people'),
imageUrl('reward15people'),
]
//
if (inviteAwardPool.value && Array.isArray(inviteAwardPool.value)) {
inviteAwardPool.value.forEach((poolItem) => {
criticalImages.push(imageUrl(`reward${poolItem.quantity}people`))
})
}
preloadImages(criticalImages, { useSmartCache: true })
}
// //
const initData = () => { const initData = () => {
apiGetMyInviteCode() // apiGetMyInviteCode() //
@ -613,6 +664,7 @@ const connectToAppHandler = async () => {
await connectToApp(() => { await connectToApp(() => {
// //
initData() initData()
preloadCriticalImages() //
}) })
} }
@ -631,7 +683,7 @@ onMounted(() => {
width: 100vw; width: 100vw;
min-height: 100vh; min-height: 100vh;
background-color: #5b4a8a; background-color: #5b4a8a;
background-image: url(../../assets/images/InvitationNewUser/bg.png); background-image: var(--bg-url);
background-size: 100% auto; background-size: 100% auto;
background-repeat: no-repeat; background-repeat: no-repeat;
position: relative; position: relative;