bindbox-mini/components/SplashScreen.vue
tsui110 8d5cf5ee17 fix :修复缓存逻辑,避免无限增加
feat:新增前端限制修改昵称和头像需要7天
2026-01-03 09:26:03 +08:00

205 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view v-if="visible" class="splash-screen" :class="{ 'fade-out': fadingOut }">
<view class="splash-content">
<view class="logo-wrapper">
<image class="logo-img" :src="logoUrl" mode="aspectFit" />
</view>
<view class="slogan-wrapper">
<text class="slogan-text">{{ sloganText }}</text>
</view>
<view class="loading-dots">
<view class="dot"></view>
<view class="dot"></view>
<view class="dot"></view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const visible = ref(false)
const fadingOut = ref(false)
const sloganText = ref('没有套路的真盲盒,就在柯大鸭')
const logoUrl = ref('/static/logo.png')
onMounted(() => {
// 获取今天的日期字符串YYYY-MM-DD格式
const today = new Date()
const dateStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`
// 获取所有日期的显示记录JSON对象
const splashKey = 'splash_count'
let splashData = uni.getStorageSync(splashKey)
// 如果缓存不存在或格式错误,初始化为空对象
if (!splashData || typeof splashData !== 'object') {
splashData = {}
}
// 清理不是今天的缓存,只保留今天的记录
const cleanedSplashData = {}
if (splashData[dateStr]) {
cleanedSplashData[dateStr] = splashData[dateStr]
}
splashData = cleanedSplashData
// 获取今天的显示次数
const todayCount = splashData[dateStr] || 0
// 每天前10次启动显示开屏动画
if (todayCount < 10) {
// 显示开屏动画
visible.value = true
// 更新今天的显示次数
splashData[dateStr] = todayCount + 1
uni.setStorageSync(splashKey, splashData)
// 停留5秒后开始淡出动画
setTimeout(() => {
fadingOut.value = true
// 淡出动画持续0.6秒,然后隐藏组件
setTimeout(() => {
visible.value = false
}, 600)
}, 5000)
}
})
</script>
<style lang="scss" scoped>
.splash-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
background: linear-gradient(135deg, #FF6B00 0%, #FF9500 100%);
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.6s ease-out, visibility 0.6s ease-out;
&.fade-out {
opacity: 0;
visibility: hidden;
}
}
.splash-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 60rpx;
animation: splashContentIn 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes splashContentIn {
from {
opacity: 0;
transform: scale(0.8) translateY(40rpx);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.logo-wrapper {
margin-bottom: 60rpx;
animation: logoFloat 2s ease-in-out infinite;
.logo-img {
width: 200rpx;
height: 200rpx;
border-radius: 40rpx;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.2);
}
}
@keyframes logoFloat {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-15rpx);
}
}
.slogan-wrapper {
margin-bottom: 80rpx;
text-align: center;
.slogan-text {
font-size: 44rpx;
font-weight: 900;
color: #ffffff;
letter-spacing: 2rpx;
line-height: 1.5;
text-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
animation: sloganFadeIn 1s ease-out 0.3s both;
}
}
@keyframes sloganFadeIn {
from {
opacity: 0;
transform: translateY(20rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.loading-dots {
display: flex;
gap: 16rpx;
animation: dotsFadeIn 0.6s ease-out 0.6s both;
.dot {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
animation: dotBounce 1.4s ease-in-out infinite;
&:nth-child(1) {
animation-delay: 0s;
}
&:nth-child(2) {
animation-delay: 0.2s;
}
&:nth-child(3) {
animation-delay: 0.4s;
}
}
}
@keyframes dotsFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: scale(0.6);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
</style>