test(图片预加载、缓存): 功能测试
This commit is contained in:
parent
a59c75c57b
commit
d53b1daddb
@ -10,6 +10,7 @@
|
|||||||
alt=""
|
alt=""
|
||||||
width="100%"
|
width="100%"
|
||||||
style="display: block"
|
style="display: block"
|
||||||
|
:crossorigin="isOSSImage ? 'anonymous' : undefined"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
@ -78,6 +79,11 @@ const shouldShowImage = computed(() => {
|
|||||||
return isVisible.value
|
return isVisible.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 判断是否为OSS图片
|
||||||
|
const isOSSImage = computed(() => {
|
||||||
|
return props.imgUrl.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')
|
||||||
|
})
|
||||||
|
|
||||||
// 创建交叉观察器
|
// 创建交叉观察器
|
||||||
const createObserver = () => {
|
const createObserver = () => {
|
||||||
if (!props.lazy || props.immediate) return
|
if (!props.lazy || props.immediate) return
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
// src/config/imagePaths.js
|
// src/config/imagePaths.js
|
||||||
export const OSS_BASE_URL = 'https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5/' // 阿里云oss
|
export const OSS_BASE_URL =
|
||||||
// export const OMAN_NATIONAL_DAY_PATH = 'Activities/Oman/NationalDay/'// 文件路径
|
process.env.NODE_ENV === 'development'
|
||||||
|
? '/oss/h5/' // 开发环境使用代理
|
||||||
|
: 'https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5/' // 生产环境直接访问
|
||||||
|
|
||||||
// 组合使用示例
|
// 组合使用示例
|
||||||
export const getPngUrl = (imagePath, filename) => {
|
export const getPngUrl = (imagePath, filename) => {
|
||||||
|
|||||||
@ -4,21 +4,37 @@ import { imageCacheManager } from '@/utils/imageCacheManager'
|
|||||||
export const smartImage = {
|
export const smartImage = {
|
||||||
async mounted(el, binding) {
|
async mounted(el, binding) {
|
||||||
if (binding.value) {
|
if (binding.value) {
|
||||||
// 对于外部链接,直接使用普通加载方式
|
|
||||||
if (!imageCacheManager.isBuildAsset(binding.value)) {
|
|
||||||
el.src = binding.value
|
|
||||||
el.style.opacity = '1'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置加载状态样式
|
// 设置加载状态样式
|
||||||
el.style.opacity = '0'
|
el.style.opacity = '0'
|
||||||
el.style.transition = 'opacity 0.3s ease-in-out'
|
el.style.transition = 'opacity 0.3s ease-in-out'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await imageCacheManager.loadImage(binding.value)
|
// 对于OSS图片使用特殊处理
|
||||||
el.src = binding.value
|
if (binding.value.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')) {
|
||||||
el.style.opacity = '1'
|
const img = new Image()
|
||||||
|
img.crossOrigin = 'anonymous'
|
||||||
|
img.onload = () => {
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
}
|
||||||
|
img.onerror = (error) => {
|
||||||
|
console.warn(`图片加载失败: ${binding.value}`, error)
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
}
|
||||||
|
img.src = binding.value
|
||||||
|
} else {
|
||||||
|
// 对于外部链接,直接使用普通加载方式
|
||||||
|
if (!imageCacheManager.isBuildAsset(binding.value)) {
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await imageCacheManager.loadImage(binding.value)
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`图片加载失败: ${binding.value}`, error)
|
console.warn(`图片加载失败: ${binding.value}`, error)
|
||||||
el.src = binding.value
|
el.src = binding.value
|
||||||
@ -29,17 +45,34 @@ export const smartImage = {
|
|||||||
|
|
||||||
async updated(el, binding) {
|
async updated(el, binding) {
|
||||||
if (binding.value !== binding.oldValue && binding.value) {
|
if (binding.value !== binding.oldValue && binding.value) {
|
||||||
// 对于外部链接,直接使用普通加载方式
|
|
||||||
if (!imageCacheManager.isBuildAsset(binding.value)) {
|
|
||||||
el.src = binding.value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
el.style.opacity = '0'
|
el.style.opacity = '0'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await imageCacheManager.loadImage(binding.value)
|
// 对于OSS图片使用特殊处理
|
||||||
el.src = binding.value
|
if (binding.value.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')) {
|
||||||
el.style.opacity = '1'
|
const img = new Image()
|
||||||
|
img.crossOrigin = 'anonymous'
|
||||||
|
img.onload = () => {
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
}
|
||||||
|
img.onerror = (error) => {
|
||||||
|
console.warn(`图片更新失败: ${binding.value}`, error)
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
}
|
||||||
|
img.src = binding.value
|
||||||
|
} else {
|
||||||
|
// 对于外部链接,直接使用普通加载方式
|
||||||
|
if (!imageCacheManager.isBuildAsset(binding.value)) {
|
||||||
|
el.src = binding.value
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await imageCacheManager.loadImage(binding.value)
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`图片更新失败: ${binding.value}`, error)
|
console.warn(`图片更新失败: ${binding.value}`, error)
|
||||||
el.src = binding.value
|
el.src = binding.value
|
||||||
|
|||||||
@ -4,8 +4,8 @@ class ImageCacheManager {
|
|||||||
this.cacheVersionKey = 'likei-image-cache-version'
|
this.cacheVersionKey = 'likei-image-cache-version'
|
||||||
this.currentAppVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'
|
this.currentAppVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'
|
||||||
this.cacheName = `likei-images-v${this.currentAppVersion}`
|
this.cacheName = `likei-images-v${this.currentAppVersion}`
|
||||||
this.maxCacheItems = 50 // 限制最多缓存50张图片(可根据需要调整)
|
this.maxCacheItems = 100 // 限制最多缓存50张图片(可根据需要调整)
|
||||||
this.maxCacheSize = 50 * 1024 * 1024 // 限制总大小50MB(可根据需要调整)
|
this.maxCacheSize = 100 * 1024 * 1024 // 限制总大小50MB(可根据需要调整)
|
||||||
this.init()
|
this.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,10 @@ class ImageCacheManager {
|
|||||||
// 先检查并清理超出限制的缓存
|
// 先检查并清理超出限制的缓存
|
||||||
// await this.enforceCacheLimits(cache)
|
// await this.enforceCacheLimits(cache)
|
||||||
|
|
||||||
const response = await fetch(url)
|
const response = await fetch(url, {
|
||||||
|
mode: 'cors',
|
||||||
|
credentials: 'omit',
|
||||||
|
})
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
await cache.put(url, response.clone())
|
await cache.put(url, response.clone())
|
||||||
console.log(`图片已缓存: ${url}`)
|
console.log(`图片已缓存: ${url}`)
|
||||||
@ -180,15 +183,42 @@ class ImageCacheManager {
|
|||||||
|
|
||||||
async loadImageFromNetwork(src, resolve, reject) {
|
async loadImageFromNetwork(src, resolve, reject) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(src)
|
// 对于OSS资源,先尝试直接创建Image对象(绕过fetch的CORS问题)
|
||||||
|
if (src.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')) {
|
||||||
|
const img = new Image()
|
||||||
|
img.crossOrigin = 'anonymous'
|
||||||
|
img.onload = () => {
|
||||||
|
resolve(img)
|
||||||
|
// 对于OSS资源,仍然尝试缓存(如果支持)
|
||||||
|
if (this.isBuildAsset(src)) {
|
||||||
|
this.cacheImageFromImage(src, img)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img.onerror = (error) => {
|
||||||
|
console.warn('图片加载失败:', src, error)
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
img.src = src
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于其他资源,使用fetch
|
||||||
|
const response = await fetch(src, {
|
||||||
|
mode: 'cors',
|
||||||
|
credentials: 'omit',
|
||||||
|
})
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
img.onload = async () => {
|
img.onload = async () => {
|
||||||
resolve(img)
|
resolve(img)
|
||||||
// 缓存带有 ETag 的响应
|
// 缓存带有 ETag 的响应
|
||||||
if (this.isBuildAsset(src)) {
|
if (this.isBuildAsset(src)) {
|
||||||
const cache = await caches.open(this.cacheName)
|
try {
|
||||||
await cache.put(src, response.clone())
|
await this.cacheImage(src) // 使用原始的缓存方法
|
||||||
|
} catch (cacheError) {
|
||||||
|
console.warn('缓存图片时出错:', cacheError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
img.onerror = reject
|
img.onerror = reject
|
||||||
@ -197,9 +227,43 @@ class ImageCacheManager {
|
|||||||
reject(new Error(`HTTP ${response.status}`))
|
reject(new Error(`HTTP ${response.status}`))
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.warn('网络加载图片失败:', src, error)
|
||||||
reject(error)
|
reject(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 为OSS图片创建缓存的特殊处理
|
||||||
|
async cacheImageFromImage(src, img) {
|
||||||
|
try {
|
||||||
|
if (!('caches' in window) || !this.isBuildAsset(src)) return
|
||||||
|
|
||||||
|
const cache = await caches.open(this.cacheName)
|
||||||
|
const cachedResponse = await cache.match(src)
|
||||||
|
|
||||||
|
if (!cachedResponse) {
|
||||||
|
// 创建一个模拟的响应来缓存
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
canvas.width = img.width
|
||||||
|
canvas.height = img.height
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
ctx.drawImage(img, 0, 0)
|
||||||
|
|
||||||
|
canvas.toBlob(async (blob) => {
|
||||||
|
if (blob) {
|
||||||
|
const response = new Response(blob, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await cache.put(src, response.clone())
|
||||||
|
console.log(`OSS图片已缓存: ${src}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('缓存OSS图片失败:', src, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出单例
|
// 导出单例
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<!-- src/views/Activities/heroesDay/index.vue -->
|
<!-- src/views/Activities/Game/index.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div class="fullPage">
|
<div class="fullPage">
|
||||||
<div class="bg">
|
<div class="bg" :style="{ '--bg-url': `url(${imageUrl('bg')})` }">
|
||||||
<!-- 状态栏占位区域(仅在APP中显示) -->
|
<!-- 状态栏占位区域(仅在APP中显示) -->
|
||||||
<div v-if="isInAppEnvironment" style="height: 30px"></div>
|
<div v-if="isInAppEnvironment" style="height: 30px"></div>
|
||||||
|
|
||||||
@ -20,25 +20,25 @@
|
|||||||
<!-- 倒计时 -->
|
<!-- 倒计时 -->
|
||||||
<div style="display: flex; justify-content: center; margin-top: 15vw">
|
<div style="display: flex; justify-content: center; margin-top: 15vw">
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeBg">
|
<itemCenter :imgUrl="imageUrl('timeBg')">
|
||||||
<div class="timeText" style="">{{ Days }}D</div>
|
<div class="timeText" style="">{{ Days }}D</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeText timeGap"></div>
|
<div class="timeText timeGap"></div>
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeBg">
|
<itemCenter :imgUrl="imageUrl('timeBg')">
|
||||||
<div class="timeText" style="">{{ Hours }}</div>
|
<div class="timeText" style="">{{ Hours }}</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeText timeGap">:</div>
|
<div class="timeText timeGap">:</div>
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeBg">
|
<itemCenter :imgUrl="imageUrl('timeBg')">
|
||||||
<div class="timeText" style="">{{ Minutes }}</div>
|
<div class="timeText" style="">{{ Minutes }}</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeText timeGap">:</div>
|
<div class="timeText timeGap">:</div>
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeBg">
|
<itemCenter :imgUrl="imageUrl('timeBg')">
|
||||||
<div class="timeText" style="">{{ Second }}</div>
|
<div class="timeText" style="">{{ Second }}</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
@ -52,14 +52,14 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="rankingShow ? images.rankingBtActive : images.rankingBt"
|
:src="rankingShow ? imageUrl('rankingBtActive') : imageUrl('rankingBt')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 40%"
|
style="display: block; width: 40%"
|
||||||
@click="rankingShow = true"
|
@click="rankingShow = true"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="!rankingShow ? images.rewardBtActive : images.rewardsBt"
|
:src="!rankingShow ? imageUrl('rewardBtActive') : imageUrl('rewardsBt')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 40%"
|
style="display: block; width: 40%"
|
||||||
@click="rankingShow = false"
|
@click="rankingShow = false"
|
||||||
@ -71,14 +71,14 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="rankingShow ? images.rankingBtActiveAr : images.rankingBtAr"
|
:src="rankingShow ? imageUrl('rankingBtActiveAr') : imageUrl('rankingBtAr')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 40%"
|
style="display: block; width: 40%"
|
||||||
@click="rankingShow = true"
|
@click="rankingShow = true"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="!rankingShow ? images.rewardBtActiveAr : images.rewardsBtAr"
|
:src="!rankingShow ? imageUrl('rewardBtActiveAr') : imageUrl('rewardsBtAr')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 40%"
|
style="display: block; width: 40%"
|
||||||
@click="rankingShow = false"
|
@click="rankingShow = false"
|
||||||
@ -90,20 +90,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<!-- Ranking -->
|
<!-- Ranking -->
|
||||||
<div v-show="rankingShow" style="position: relative; width: 100%">
|
<div v-show="rankingShow" style="position: relative; width: 100%">
|
||||||
<!-- 背景图 -->
|
|
||||||
<!-- <div class="ranking-bg"></div> -->
|
|
||||||
|
|
||||||
<div style="position: relative; z-index: 2">
|
<div style="position: relative; z-index: 2">
|
||||||
<!-- 前三名 -->
|
<!-- 前三名 -->
|
||||||
<itemCenter
|
<itemCenter
|
||||||
:imgUrl="images.RankingMain"
|
:imgUrl="imageUrl('RankingMain')"
|
||||||
:contentStyle="`padding: 25% 5% 0;flex-direction: column;`"
|
:contentStyle="`padding: 25% 5% 0;flex-direction: column;`"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<!-- 第一 -->
|
<!-- 第一 -->
|
||||||
<div style="display: flex; justify-content: center">
|
<div style="display: flex; justify-content: center">
|
||||||
<TopUser
|
<TopUser
|
||||||
:BorderImgUrl="images.topOne"
|
:BorderImgUrl="imageUrl('topOne')"
|
||||||
:avatarUrl="RankingHasTop3[0].avatar"
|
:avatarUrl="RankingHasTop3[0].avatar"
|
||||||
:name="RankingHasTop3[0].nickname"
|
:name="RankingHasTop3[0].nickname"
|
||||||
:distributionValue="RankingHasTop3[0].quantity"
|
:distributionValue="RankingHasTop3[0].quantity"
|
||||||
@ -116,7 +113,7 @@
|
|||||||
<TopUser
|
<TopUser
|
||||||
:isTopOne="false"
|
:isTopOne="false"
|
||||||
ranking="2"
|
ranking="2"
|
||||||
:BorderImgUrl="images.topTwo"
|
:BorderImgUrl="imageUrl('topTwo')"
|
||||||
:avatarUrl="RankingHasTop3[1].avatar"
|
:avatarUrl="RankingHasTop3[1].avatar"
|
||||||
:name="RankingHasTop3[1].nickname"
|
:name="RankingHasTop3[1].nickname"
|
||||||
:distributionValue="RankingHasTop3[1].quantity"
|
:distributionValue="RankingHasTop3[1].quantity"
|
||||||
@ -126,7 +123,7 @@
|
|||||||
<TopUser
|
<TopUser
|
||||||
:isTopOne="false"
|
:isTopOne="false"
|
||||||
ranking="3"
|
ranking="3"
|
||||||
:BorderImgUrl="images.topThree"
|
:BorderImgUrl="imageUrl('topThree')"
|
||||||
:avatarUrl="RankingHasTop3[2].avatar"
|
:avatarUrl="RankingHasTop3[2].avatar"
|
||||||
:name="RankingHasTop3[2].nickname"
|
:name="RankingHasTop3[2].nickname"
|
||||||
:distributionValue="RankingHasTop3[2].quantity"
|
:distributionValue="RankingHasTop3[2].quantity"
|
||||||
@ -143,9 +140,12 @@
|
|||||||
style="margin-bottom: 6vw; position: relative; z-index: 2"
|
style="margin-bottom: 6vw; position: relative; z-index: 2"
|
||||||
>
|
>
|
||||||
<itemCenter
|
<itemCenter
|
||||||
v-for="listItem in showRanking"
|
v-for="(listItem, index) in showRanking"
|
||||||
:imgUrl="images.RankingItem"
|
:key="listItem.userId"
|
||||||
|
:imgUrl="imageUrl('RankingItem')"
|
||||||
:contentStyle="`padding: 2% 13% 0`"
|
:contentStyle="`padding: 2% 13% 0`"
|
||||||
|
:lazy="true"
|
||||||
|
:immediate="index < 2"
|
||||||
@click="viewUserInfo(listItem.userId)"
|
@click="viewUserInfo(listItem.userId)"
|
||||||
>
|
>
|
||||||
<!-- 基本信息 -->
|
<!-- 基本信息 -->
|
||||||
@ -228,7 +228,7 @@
|
|||||||
<!-- 底框 -->
|
<!-- 底框 -->
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="images.RankingBottomBorder"
|
:src="imageUrl('RankingBottomBorder')"
|
||||||
alt=""
|
alt=""
|
||||||
width="100%"
|
width="100%"
|
||||||
style="display: block; margin-top: -40vw; position: relative; z-index: 1"
|
style="display: block; margin-top: -40vw; position: relative; z-index: 1"
|
||||||
@ -255,7 +255,7 @@
|
|||||||
:key="rewardIndex"
|
:key="rewardIndex"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<itemCenter :imgUrl="images.giftItemBg">
|
<itemCenter :imgUrl="imageUrl('giftItemBg')">
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="reward.cover || ''"
|
:src="reward.cover || ''"
|
||||||
@ -298,7 +298,7 @@
|
|||||||
<!-- 我的排名 -->
|
<!-- 我的排名 -->
|
||||||
<itemCenter
|
<itemCenter
|
||||||
style="position: fixed; bottom: 0; z-index: 2"
|
style="position: fixed; bottom: 0; z-index: 2"
|
||||||
:imgUrl="images.myRankingBg"
|
:imgUrl="imageUrl('myRankingBg')"
|
||||||
:contentStyle="`padding: 2% 8% 0`"
|
:contentStyle="`padding: 2% 8% 0`"
|
||||||
>
|
>
|
||||||
<!-- 基本信息 -->
|
<!-- 基本信息 -->
|
||||||
@ -380,14 +380,14 @@
|
|||||||
<img
|
<img
|
||||||
v-if="currentLangType == 'en'"
|
v-if="currentLangType == 'en'"
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="images.helpInfo"
|
:src="imageUrl('helpInfo')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 100%"
|
style="display: block; width: 100%"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="currentLangType == 'ar'"
|
v-if="currentLangType == 'ar'"
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="images.helpInfoAr"
|
:src="imageUrl('helpInfoAr')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 100%"
|
style="display: block; width: 100%"
|
||||||
/>
|
/>
|
||||||
@ -402,6 +402,8 @@ import { computed, onMounted, onUnmounted, ref } from 'vue'
|
|||||||
import { isInApp, viewUserInfo } from '@/utils/appBridge.js'
|
import { isInApp, viewUserInfo } from '@/utils/appBridge.js'
|
||||||
import { connectToApp } from '@/utils/appConnector.js'
|
import { connectToApp } from '@/utils/appConnector.js'
|
||||||
import { useLangStore } from '@/stores/lang'
|
import { useLangStore } from '@/stores/lang'
|
||||||
|
import { getPngUrl } from '@/config/imagePaths.js'
|
||||||
|
import { preloadImages } from '@/utils/imagePreloader.js'
|
||||||
|
|
||||||
import { getThisWeekRewardsAndGifts, getRankingListAndMyRanking } from '@/api/activity.js'
|
import { getThisWeekRewardsAndGifts, getRankingListAndMyRanking } from '@/api/activity.js'
|
||||||
|
|
||||||
@ -409,17 +411,8 @@ import itemCenter from '@/components/itemCenter.vue'
|
|||||||
import TopUser from './components/topUser.vue'
|
import TopUser from './components/topUser.vue'
|
||||||
import maskLayer from '@/components/MaskLayer.vue'
|
import maskLayer from '@/components/MaskLayer.vue'
|
||||||
|
|
||||||
// vite动态批量导入图片
|
// 获取OSS图片URL的函数
|
||||||
const imageModules = import.meta.glob('@/assets/images/Activities/Game/*.{png,jpg,svg}', {
|
const imageUrl = (filename) => getPngUrl('Activities/Game/', 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 isInAppEnvironment = ref(false) // 检测是否在APP环境中
|
const isInAppEnvironment = ref(false) // 检测是否在APP环境中
|
||||||
const maskLayerShow = ref(false) //帮助模块
|
const maskLayerShow = ref(false) //帮助模块
|
||||||
@ -444,7 +437,7 @@ const Ranking = ref([]) // 排行榜
|
|||||||
const myRanking = ref({}) // 我的排名
|
const myRanking = ref({}) // 我的排名
|
||||||
const rewardsList = ref([]) // 奖励列表
|
const rewardsList = ref([]) // 奖励列表
|
||||||
|
|
||||||
const topImg = ref([images.top1RewardBg, images.top2RewardBg, images.top3RewardBg]) // top图片
|
const topImg = ref([imageUrl('top1RewardBg'), imageUrl('top2RewardBg'), imageUrl('top3RewardBg')]) // top图片
|
||||||
|
|
||||||
// 处理排行榜小于3人时的情况
|
// 处理排行榜小于3人时的情况
|
||||||
const RankingHasTop3 = computed(() => {
|
const RankingHasTop3 = computed(() => {
|
||||||
@ -463,7 +456,6 @@ const RankingHasTop3 = computed(() => {
|
|||||||
// 展示用的榜单
|
// 展示用的榜单
|
||||||
const showRanking = computed(() => {
|
const showRanking = computed(() => {
|
||||||
return Ranking.value.filter((_, index) => index >= 3)
|
return Ranking.value.filter((_, index) => index >= 3)
|
||||||
// return []
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 奖励图片资源出错处理
|
// 奖励图片资源出错处理
|
||||||
@ -586,11 +578,43 @@ const initData = () => {
|
|||||||
getRewardsAndGifts() //获取本周的礼物和奖励列表
|
getRewardsAndGifts() //获取本周的礼物和奖励列表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预加载关键图片
|
||||||
|
const preloadCriticalImages = () => {
|
||||||
|
const criticalImages = [
|
||||||
|
imageUrl('bg'),
|
||||||
|
imageUrl('timeBg'),
|
||||||
|
imageUrl('rankingBt'),
|
||||||
|
imageUrl('rankingBtActive'),
|
||||||
|
imageUrl('rankingBtAr'),
|
||||||
|
imageUrl('rankingBtActiveAr'),
|
||||||
|
imageUrl('rewardBtActive'),
|
||||||
|
imageUrl('rewardBtActiveAr'),
|
||||||
|
imageUrl('rewardsBt'),
|
||||||
|
imageUrl('rewardsBtAr'),
|
||||||
|
imageUrl('RankingMain'),
|
||||||
|
imageUrl('topOne'),
|
||||||
|
imageUrl('topTwo'),
|
||||||
|
imageUrl('topThree'),
|
||||||
|
imageUrl('RankingItem'),
|
||||||
|
imageUrl('RankingBottomBorder'),
|
||||||
|
imageUrl('myRankingBg'),
|
||||||
|
imageUrl('helpInfo'),
|
||||||
|
imageUrl('helpInfoAr'),
|
||||||
|
imageUrl('top1RewardBg'),
|
||||||
|
imageUrl('top2RewardBg'),
|
||||||
|
imageUrl('top3RewardBg'),
|
||||||
|
imageUrl('giftItemBg'),
|
||||||
|
]
|
||||||
|
|
||||||
|
preloadImages(criticalImages, { useSmartCache: true })
|
||||||
|
}
|
||||||
|
|
||||||
// 使用工具函数连接APP
|
// 使用工具函数连接APP
|
||||||
const connectToAppHandler = async () => {
|
const connectToAppHandler = async () => {
|
||||||
await connectToApp(() => {
|
await connectToApp(() => {
|
||||||
// 连接成功回调
|
// 连接成功回调
|
||||||
initData() //初始化数据
|
initData() //初始化数据
|
||||||
|
preloadCriticalImages() //预加载关键图片
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,7 +646,7 @@ onUnmounted(() => {
|
|||||||
.bg {
|
.bg {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-image: url(../../../assets/images/Activities/Game/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;
|
||||||
|
|||||||
@ -45,6 +45,13 @@ export default defineConfig({
|
|||||||
cors: true, // 启用CORS
|
cors: true, // 启用CORS
|
||||||
// 代理配置(如果需要)
|
// 代理配置(如果需要)
|
||||||
proxy: {
|
proxy: {
|
||||||
|
// OSS 代理配置
|
||||||
|
'/oss': {
|
||||||
|
target: 'https://tkm-likei.oss-ap-southeast-1.aliyuncs.com',
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/oss/, ''),
|
||||||
|
},
|
||||||
// '/api': {
|
// '/api': {
|
||||||
// target: 'http://localhost:3000',
|
// target: 'http://localhost:3000',
|
||||||
// changeOrigin: true,
|
// changeOrigin: true,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user