|
|
<template> <div class="wheel-container"> <!-- 顶部区域 --> <div class="top-section"> <div class="expire-time">财富金轮到期时间:{{ expireTime }}</div> <div class="top-right"> <div class="icon-item" @click="toggleHistory"> <img :src="historyImg" class="history-icon" alt="历史记录"> <span class="icon-text">历史记录</span> </div> <div class="icon-item" @click="handleRuleClick"> <img :src="ruleImg" class="rule-icon" alt="活动规则"> <span class="icon-text">活动规则</span> </div> </div> </div> <!-- 主标题图片 --> <img :src="titleImg" class="title-img" alt="转动财富金轮 开启财富人生"> <!-- 转盘区域 - 完全重构 --> <div class="wheel-section"> <div class="wheel-wrapper"> <!-- 转盘图片 --> <img :src="wheelImg" class="wheel-img" alt="财富金轮" > <!-- 指针系统 - 使用绝对精确的定位 --> <div class="pointer-system"> <!-- 中心固定点 - 作为旋转参考 --> <div class="rotation-center"></div> <!-- 指针图片 - 使用精确的transform-origin --> <img src="../../assets/img/wealthGoldenWheel/pointer.png" class="pointer-img" :class="{ spinning: isSpinning }" :style="{ transform: `rotate(${pointerRotation}deg)` }" alt="指针" > <!-- 指针中心盖 --> <img :src="pointerCoverImg" class="pointer-cover-img" alt="指针盖"> </div> </div> </div> <!-- 剩余次数 --> <div class="remaining-section"> <img :src="remainingBgImg" class="remaining-bg" alt="今日剩余"> <span class="remaining-text">今日剩余:{{ remainingTimes }}次</span> </div> <!-- 转动按钮 --> <button class="spin-btn" :disabled="isSpinning || showPrizeModal || showRuleModal || isFirstVisit" @click="handleSpin" > <img :src="(remainingTimes > 0 && !showPrizeModal && !showRuleModal && !isFirstVisit) ? spinBtnImg : disabledSpinBtnImg" alt="转动金轮" class="spin-btn-img" > </button> <!-- 中奖弹窗 --> <div class="prize-modal" v-if="showPrizeModal"> <div class="modal-overlay" @click="closeModal"></div> <div class="modal-content"> <img :src="modalBgImg" class="modal-bg" alt="弹窗背景"> <!-- 右上角关闭按钮 --> <button class="close-modal" @click="closeModal"> <img :src="closeBtnImg" alt="关闭弹窗"> </button> <div class="prize-info"> <div class="prize-title">{{ prizeMessage }}</div> <div class="prize-amount-wrapper"> <img :src="prizeAmountImg" class="prize-amount-bg" alt="奖品数量背景"> <div class="prize-amount" :class="{ scrolling: shouldScroll }"> <span class="prize-text" v-if="shouldScroll"> {{ prizeAmount }} {{ prizeAmount }} </span> <span v-else>{{ prizeAmount }}</span> </div> </div> </div> </div> </div> <!-- 剩余次数为0时的提示弹窗 --> <div class="no-times-modal" v-if="showNoTimesModal"> <div class="modal-overlay" @click="closeNoTimesModal"></div> <div class="no-times-content"> <img :src="noTimesImg" class="no-times-bg" alt="今日次数已用完"> </div> </div> <!-- 活动规则弹窗 --> <div class="rule-modal" v-if="showRuleModal"> <div class="modal-overlay" @click="closeRuleModal"></div> <div class="rule-content"> <img :src="ruleBgImg" class="rule-bg" alt="活动规则背景"> <!-- 右上角关闭按钮 --> <button class="close-rule-btn" @click="closeRuleModal"> <img :src="closeRuleBtnImg" alt="关闭活动规则"> </button> <div class="rule-text"> <div class="rule-line">1.在财富金轮使用期限内,每天可以转动一次</div> <div class="rule-line">2.通过财富金轮可以获得免费Tonken和背包礼物等</div> <div class="rule-line">3.用户通过财富金轮获得的物品以最终展示结果为准</div> <div class="rule-line">4.Homily Link平台拥有最终解释权</div> </div> </div> </div> <!-- 首次访问活动规则弹窗 --> <div class="rule-modal" v-if="isFirstVisit"> <div class="modal-overlay" @click="closeFirstVisitModal"></div> <div class="rule-content"> <img :src="ruleBgImg" class="rule-bg" alt="活动规则背景"> <!-- 右上角关闭按钮 --> <button class="close-rule-btn" @click="closeFirstVisitModal"> <img :src="closeRuleBtnImg" alt="关闭活动规则"> </button> <div class="rule-text"> <div class="rule-line">1.在财富金轮使用期限内,每天可以转动一次</div> <div class="rule-line">2.通过财富金轮可以获得免费Tonken和背包礼物等</div> <div class="rule-line">3.用户通过财富金轮获得的物品以最终展示结果为准</div> <div class="rule-line">4.Homily Link平台拥有最终解释权</div> </div> </div> </div>
<!-- 右侧历史记录侧板 --> <div class="history-record" v-if="historyRecordListVisible"> <img src="../../assets/img/wealthGoldenWheel/foldUpIcon.png" class="fold-up" @click="toggleHistory" />
<div class="history-title">中奖记录</div>
<div style="margin-left: 45px; margin-top: 18px;"> <button v-for="item in options" :key="item.value" :style="{ backgroundColor: selected === item.value ? '#0003bf' : '#7475b2', borderColor: selected === item.value ? '#0003bf' : '#7475b2', color: '#fff', marginRight: '24px', padding: '6px 18px', borderRadius: '8px', border: 'none', cursor: 'pointer' }" @click="changeTypeHistoryList(item)"> {{ item.label }} </button> </div>
<div class="history-contents"> <!-- nowMonths(当前年) --> <div v-if="nowMonths && nowMonths.length > 0" style="padding-left:45px;"> <div v-for="m in nowMonths" :key="m.month"> <div class="month-row" @click="toggleMonthNow(m)"> <span class="month-text">{{ m.month }}</span> <span class="month-caret">{{ m.open ? '▼' : '▲' }}</span> </div>
<div v-if="m.open"> <div v-if="!m.records || m.records.length === 0" class="empty-month">暂无记录</div> <div v-for="(item, idx) in m.records" :key="item.id || idx" class="history-record-item"> <div class="left"> <div class="title" v-if="selected == 1"> <span class="circle"></span>财富金轮—{{ item.type }} </div> <div class="title" v-else-if="selected == 3"> <span class="circle"></span>{{ item.type }} </div> <div class="time">{{ item.time }}</div> </div> <div class="right"> <span class="token">+ {{ item.amount }}</span> </div> </div> </div> </div> </div>
<!-- 历史年列表 --> <div v-if="years && years.length > 0"> <div v-for="y in years" :key="y.year"> <div class="year-header" @click="toggleYear(y)" style="padding-left:14px;"> <span class="year-text">{{ y.year }}年</span> <span class="year-caret">{{ y.expanded ? '▼' : '▲' }}</span> </div> <div v-if="y.expanded" class="months" style="padding-left:45px;"> <div v-for="m in y.months" :key="m.month"> <div class="month-row" @click="toggleMonth(m)"> <span class="month-text">{{ m.month }}</span> <span class="month-caret">{{ m.open ? '▼' : '▲' }}</span> </div>
<div v-if="m.open"> <div v-if="!m.records || m.records.length === 0" class="empty-month">暂无记录</div> <div v-for="(item, idx) in m.records" :key="item.id || idx" class="history-record-item"> <div class="left"> <div class="title" v-if="selected == 1"> <span class="circle"></span>财富金轮—{{ item.type }} </div> <div class="title" v-else-if="selected == 3"> <span class="circle"></span>{{ item.type }} </div> <div class="time">{{ item.time }}</div> </div> <div class="right"> <span class="token">+ {{ item.amount }}</span> </div> </div> </div>
</div> </div> </div> </div>
</div>
<!-- 底部装饰 --> <div class="history-decoration" aria-hidden="true"></div> </div> </div> </template>
<script> import api from '@/utils/common.js' import { permissionApi, lotteryApi,historyApi } from '@/api/goldenWheel'
export default { name: 'FortuneWheel', data() { return { // 图片资源
historyImg: 'https://d31zlh4on95l9h.cloudfront.net/images/aed693de6beb9faae015fd0628c4f052.png', ruleImg: 'https://d31zlh4on95l9h.cloudfront.net/images/9a3f7680b29e31b60151cf562c0d43cb.png', titleImg: 'https://d31zlh4on95l9h.cloudfront.net/images/a87d19806fed47b7fdf18d4b5dd70e65.png', wheelImg: 'https://d31zlh4on95l9h.cloudfront.net/images/caaf77a490be46c56ae824d2d9aa72f4.png', pointerCoverImg: 'https://d31zlh4on95l9h.cloudfront.net/images/19f2ea90e2560330089214e88eff04b5.png', remainingBgImg: 'https://d31zlh4on95l9h.cloudfront.net/images/a43f0c383d55fc56b34768f039a401a8.png', spinBtnImg: 'https://d31zlh4on95l9h.cloudfront.net/images/11b749e0fd4b08238980b74c6e80b2e6.png', disabledSpinBtnImg: 'https://d31zlh4on95l9h.cloudfront.net/images/9b7383c1f80bb32a279791879947791a.png', modalBgImg: 'https://d31zlh4on95l9h.cloudfront.net/images/f75ce9ca2703662fd3176dd0493f6d7b.png', prizeAmountImg: 'https://d31zlh4on95l9h.cloudfront.net/images/878b8ea0c78bcafdaf4f6eb63a0b2eef.png', closeBtnImg: 'https://d31zlh4on95l9h.cloudfront.net/images/453475456dad8e6832e9904c901c1274.png', noTimesImg: 'https://d31zlh4on95l9h.cloudfront.net/images/a67e8b3de6e441af7bcb8fbbb2153ec2.png', ruleBgImg: 'https://d31zlh4on95l9h.cloudfront.net/images/9f585ee0ab251f348a4568355ad36816.png', closeRuleBtnImg: 'https://d31zlh4on95l9h.cloudfront.net/images/ca2ddd411ffb85968bc261382477c984.png', // 数据
token: '', expireTime: '', remainingTimes: 0, isSpinning: false, showPrizeModal: false, showNoTimesModal: false, showRuleModal: false, isFirstVisit: true, pointerRotation: -21.5, // 指针初始旋转角度
noTimesTimer: null, prizeMessage: '', prizeAmount: '', textWidth: 0, targetPointerRotation: 0, // 指针目标旋转角度
historyRecordListVisible: false, nowMonths: [], years: [], selected: 1, options: [ { label: 'Token', value: 1 }, { label: '卡券', value: 3 } ], } }, computed: { // 判断是否需要滚动展示
shouldScroll() { if (!this.prizeAmount) return false; // 判断中文字符数量
const chineseCharCount = (this.prizeAmount.match(/[\u4e00-\u9fa5]/g) || []).length; // 判断英文字母数量
const englishCharCount = (this.prizeAmount.match(/[a-zA-Z]/g) || []).length; // 汉字超过7个或字母超过15个时启用滚动
return chineseCharCount > 7 || englishCharCount > 15; } }, mounted() { this.getTokenFromURL(); this.fetchWheelInfo(); // 预加载图片
this.preloadImages(); api.packageFun('JWsetTitle', function () {}, { platform: 5, title: "财富金轮" }) }, methods: { toggleHistory() { this.historyRecordListVisible = !this.historyRecordListVisible this.selected = 1 if (this.historyRecordListVisible) { this.loadHistoryRecord() } }, changeTypeHistoryList(item) { this.selected = item.value this.loadHistoryRecord() }, async loadHistoryRecord() { try { const res = await historyApi({ token: this.token, type: this.selected }); if (res.code === 200) { const now_year = res.data.now_year || [] const last_year_list = res.data.last_year_list || []
this.nowMonths = (Array.isArray(now_year) ? now_year : []).map((m, idx) => ({ month: m.month, open: idx === 0, records: (m.list || []).map((r, ridx) => ({ id: ridx, time: r.time, amount: parseFloat(r.num), type: r.name })) }))
this.years = (Array.isArray(last_year_list) ? last_year_list : []).map((y) => ({ year: y.year, expanded: false, months: (y.list || []).map((m) => ({ month: m.month, open: false, records: (m.list || []).map((r, ridx) => ({ id: ridx, time: r.time, amount: parseFloat(r.num), type: r.name })) })) })) } else { this.nowMonths = [] this.years = [] } } catch (err) { this.nowMonths = [] this.years = [] } },
toggleMonthNow(m) { m.open = !m.open }, toggleYear(y) { y.expanded = !y.expanded }, toggleMonth(m) { m.open = !m.open }, // 预加载图片以提高性能
preloadImages() { const images = [ this.historyImg, this.ruleImg, this.titleImg, this.wheelImg, this.pointerCoverImg, this.remainingBgImg, this.spinBtnImg, this.disabledSpinBtnImg, this.modalBgImg, this.prizeAmountImg, this.closeBtnImg, this.noTimesImg, this.ruleBgImg, this.closeRuleBtnImg ]; images.forEach(src => { const img = new Image(); img.src = src; }); }, getTokenFromURL() { // 首先尝试从URL获取token
const urlParams = new URLSearchParams(window.location.search); const tokenParam = urlParams.get('token'); if (tokenParam) { // 如果URL中有token,保存到localStorage并设置到组件
const decodedToken = decodeURIComponent(tokenParam); localStorage.setItem('fortuneWheelToken', decodedToken); this.token = decodedToken; } else { // 如果URL中没有token,尝试从localStorage获取
const storedToken = localStorage.getItem('fortuneWheelToken'); if (storedToken) { this.token = storedToken; } else { console.log('URL和localStorage中都没有找到token'); // 这里可以添加处理没有token的情况,比如跳转到登录页
} } }, // 调用API获取财富金轮信息
fetchWheelInfo() { if (!this.token) { console.error('Token为空,无法调用API'); return; } permissionApi({ token: this.token }).then(res => { if(res.code === 200){ this.expireTime = res.data.deadline; this.remainingTimes = res.data.count; } else { console.error('API返回错误:', res.msg); } }).catch(error => { console.error('API调用失败:', error); }); }, // 调用抽奖API获取奖品信息
async fetchPrizeInfo() { if (!this.token) { console.error('Token为空,无法调用抽奖API'); return false; } try { // 调用抽奖API
const res = await lotteryApi({ token: this.token }); if(res.code === 200){ // 解析API返回的字符串数据
const prizeData = res.data; // 关键修改:按照第一个空格分割字符串
const firstSpaceIndex = prizeData.indexOf(' '); if (firstSpaceIndex !== -1) { // 第一个空格前面的部分作为prizeMessage
this.prizeMessage = prizeData.substring(0, firstSpaceIndex); // 第一个空格后面的部分作为prizeAmount
this.prizeAmount = prizeData.substring(firstSpaceIndex + 1); } else { // 如果没有空格,整个字符串作为prizeMessage,prizeAmount为空
this.prizeMessage = prizeData; this.prizeAmount = ''; } // 抽奖API执行完成后,查询最新的剩余次数
await this.fetchWheelInfo(); return true; } else { console.error('抽奖API返回错误:', res.msg); // 设置默认值
this.prizeMessage = '抽奖失败'; this.prizeAmount = '请重试'; // 即使抽奖失败,也查询最新的剩余次数
await this.fetchWheelInfo(); return false; } } catch (error) { console.error('抽奖API调用失败:', error); // 设置默认值
this.prizeMessage = '网络错误'; this.prizeAmount = '请重试'; // 即使抽奖失败,也查询最新的剩余次数
await this.fetchWheelInfo(); return false; } }, // 计算随机停止位置
calculateRandomStop() { // 转盘有8个区域,每个区域45度
const sectorDegrees = 45; // 随机选择一个区域 (0-7)
const randomSector = Math.floor(Math.random() * 8); // 计算目标角度:从初始位置(-21.5度)到选中区域的中心
// 每个区域中心的角度 = 区域索引 * 45度 - 22.5度
const targetAngle = randomSector * sectorDegrees - 21.5; // 计算需要旋转的总角度(确保多转几圈)
// 从当前位置旋转到目标位置,加上多转的圈数(3-5圈)
const extraRotations = 3 + Math.floor(Math.random() * 3); // 4-5圈
const extraDegrees = extraRotations * 360; // 计算最终旋转角度
// 从当前角度旋转到目标角度,加上额外的圈数
// 注意:需要确保旋转方向正确
let rotationNeeded = targetAngle - this.pointerRotation; // 如果旋转角度为负,加上360度使其为正
if (rotationNeeded < 0) { rotationNeeded += 360; } // 加上额外的圈数
return this.pointerRotation + rotationNeeded + extraDegrees; }, // 处理转动
async handleSpin() { if (this.showRuleModal || this.isFirstVisit || this.isSpinning) return; // 先查询剩余次数
try { if (this.remainingTimes <= 0) { this.showNoTimesModal = true; if (this.noTimesTimer) { clearTimeout(this.noTimesTimer); } this.noTimesTimer = setTimeout(() => { this.showNoTimesModal = false; }, 3000); return; } // 有剩余次数,开始抽奖
this.isSpinning = true; // 计算随机停止位置
this.targetPointerRotation = this.calculateRandomStop(); // 设置CSS变量,用于动画
document.documentElement.style.setProperty('--target-pointer-rotation', `${this.targetPointerRotation}deg`); // 开始旋转动画
this.pointerRotation = this.targetPointerRotation; // 调用抽奖API获取奖品信息
const success = await this.fetchPrizeInfo(); setTimeout(() => { this.isSpinning = false; if (success) { // 直接显示弹窗,无需额外延迟
this.showPrizeModal = true; } }, 4000); } catch (error) { console.error('查询剩余次数失败:', error); this.isSpinning = false; } }, // 处理活动规则点击
handleRuleClick() { this.showRuleModal = true; }, // 关闭弹窗
closeModal() { this.showPrizeModal = false; }, // 关闭无次数提示弹窗
closeNoTimesModal() { this.showNoTimesModal = false; if (this.noTimesTimer) { clearTimeout(this.noTimesTimer); } }, // 关闭活动规则弹窗
closeRuleModal() { this.showRuleModal = false; }, // 关闭首次访问弹窗
closeFirstVisitModal() { this.isFirstVisit = false; }, // 跳转到历史记录页面
goToHistory() { this.$router.push('/history'); }, // 计算文本宽度,动态设置动画
calcTextWidth() { if (!this.shouldScroll || !this.prizeAmount) return; // 创建临时元素,用于计算文本宽度
const tempSpan = document.createElement('span'); tempSpan.style.visibility = 'hidden'; tempSpan.style.position = 'absolute'; tempSpan.style.whiteSpace = 'nowrap'; tempSpan.style.fontSize = '25px'; tempSpan.style.fontWeight = 'bold'; tempSpan.style.fontFamily = 'inherit'; tempSpan.textContent = this.prizeAmount; document.body.appendChild(tempSpan); // 获取单个文本宽度
this.textWidth = tempSpan.offsetWidth; document.body.removeChild(tempSpan); // 移除现有的样式
const existingStyle = document.getElementById('scroll-animation-style'); if (existingStyle) { existingStyle.remove(); } // 动态设置滚动动画
const style = document.createElement('style'); style.id = 'scroll-animation-style'; style.textContent = `
@keyframes seamless-scroll { 0% { transform: translateX(0); } 100% { transform: translateX(-${this.textWidth + 20}px); } } @media (max-width: 380px) { @keyframes seamless-scroll { 0% { transform: translateX(0); } 100% { transform: translateX(-${this.textWidth + 16}px); } } } .prize-amount.scrolling .prize-text { animation: seamless-scroll ${Math.max(5, this.textWidth / 30)}s linear infinite; padding-right: 20px; display: inline-block; } `;
document.head.appendChild(style); } }, watch: { // 当奖品金额变化时,重新计算文本宽度
prizeAmount(newVal) { if (newVal && this.shouldScroll) { this.$nextTick(() => { this.calcTextWidth(); }); } } } } </script>
<style scoped> .wheel-container { min-height: 100vh; background-image: url('../../assets/img/wealthGoldenWheel/bg.png'); background-size: cover; background-position: bottom center; padding: 15px; display: flex; flex-direction: column; align-items: center; position: relative; }
/* 顶部区域样式 */ .top-section { width: 100%; display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; }
.expire-time { color: #fff; font-size: 12px; font-weight: bold; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); margin: 11px 0 0 12px; }
.top-right { display: flex; gap: 20px; align-items: center; }
.icon-item { display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; }
.history-icon, .rule-icon { width: 25px; height: 25px; cursor: pointer; }
.icon-text { color: #fff; font-size: 11px; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); }
/* 主标题图片样式 */ .title-img { width: 327px; height: 144px; margin-bottom: 20px; }
/* 转盘区域样式 */ .wheel-section { display: flex; flex-direction: column; align-items: center; margin-bottom: 15px; position: relative; }
.wheel-wrapper { position: relative; width: 333px; height: 333px; }
.wheel-img { width: 100%; height: 100%; transform: rotate(-22.5deg); }
/* 指针系统 - 完全重构 */ .pointer-system { position: absolute; top: 50%; left: 50%; width: 137px; height: 137px; transform: translate(-50%, -50%); z-index: 2; }
/* 中心固定点 - 用于调试和参考 */ .rotation-center { position: absolute; top: 50%; left: 50%; width: 4px; height: 4px; background: red; border-radius: 50%; transform: translate(-50%, -50%); z-index: 4; opacity: 0; /* 调试时可设置为1查看中心点 */ }
/* 指针底座 - 提供固定参考点 */ .pointer-base { position: relative; width: 137px; height: 137px; display: flex; justify-content: center; align-items: center; transform: translateZ(0); /* 启用GPU加速 */ }
/* 指针图片 - 关键优化 */ .pointer-img { position: absolute; top: 0; left: 0; width: 137px; height: 137px; /* 精确计算旋转中心点 */ transform-origin: 68.5px 68.5px; /* 137px / 2 = 68.5px */ transform: rotate(-21.5deg); transition: transform 0.1s linear; image-rendering: crisp-edges; -webkit-font-smoothing: subpixel-antialiased; backface-visibility: hidden; perspective: 1000px; will-change: transform; }
/* 旋转动画 - 使用requestAnimationFrame优化 */ .pointer-img.spinning { animation: smooth-spin 3s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; /* 添加这些属性确保性能 */ backface-visibility: hidden; transform: translateZ(0); will-change: transform; }
@keyframes smooth-spin { 0% { transform: rotate(-21.5deg); animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94); } 100% { transform: rotate(var(--target-pointer-rotation, 1440deg)); } }
/* 指针盖样式 */ .pointer-cover-img { position: absolute; top: 50%; left: 50%; width: 104px; height: 104px; transform: translate(-50%, -50%); z-index: 3; pointer-events: none; }
/* 剩余次数样式 */ .remaining-section { position: relative; margin-bottom: 20px; display: flex; justify-content: center; margin-top: -5px; }
.remaining-bg { width: 104px; height: 21.5px; }
.remaining-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #fff; font-size: 12px; font-weight: bold; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); width: 100%; text-align: center; white-space: nowrap; }
/* 转动按钮样式 */ .spin-btn { background: none; border: none; cursor: pointer; transition: transform 0.2s ease; padding: 0; }
.spin-btn:active:not(:disabled) { transform: scale(0.95); }
.spin-btn:disabled { cursor: not-allowed; opacity: 0.7; }
.spin-btn-img { width: 240px; height: 94px; }
/* 弹窗样式 */ .prize-modal, .no-times-modal, .rule-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; z-index: 1000; }
.modal-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); }
/* 中奖弹窗内容区域尺寸为333x377 */ .modal-content { position: relative; width: 333px; height: 377px; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 1001; animation: modal-appear 0.3s ease-out; }
@keyframes modal-appear { from { opacity: 0; transform: scale(0.8) translateY(-20px); } to { opacity: 1; transform: scale(1) translateY(0); } }
.modal-bg { position: absolute; width: 100%; height: 100%; z-index: -1; }
/* 无次数提示弹窗样式 */ .no-times-content { position: relative; width: 333px; height: 79px; display: flex; justify-content: center; align-items: center; z-index: 1001; margin-top: 250px; animation: slide-up 0.3s ease-out; }
@keyframes slide-up { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.no-times-bg { position: absolute; width: 100%; height: 100%; z-index: -1; }
/* 弹窗内容样式 */ .prize-info { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; z-index: 2; margin-top: 120px; }
.prize-title { color: #B82525; font-size: 25px; font-weight: bold; margin-bottom: 35px; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); animation: text-pulse 2s infinite; }
@keyframes text-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
/* 奖品数量样式 - 优化后的样式 */ .prize-amount-wrapper { position: relative; display: flex; justify-content: center; align-items: center; margin-top: 20px; width: 272px; height: 58px; overflow: hidden; }
.prize-amount-bg { position: absolute; width: 272px; height: 58px; z-index: 1; }
.prize-amount { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #FFFFFF; font-size: 25px; font-weight: bold; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); width: 240px; text-align: center; white-space: nowrap; z-index: 2; overflow: hidden; }
/* 滚动状态:限制文本显示区域,确保仅容器内文本可见 */ .prize-amount.scrolling { width: 170px; text-align: left; }
/* 滚动文本容器 */ .prize-amount.scrolling .prize-text { will-change: transform; backface-visibility: hidden; transform: translateZ(0); }
/* 关闭按钮样式 - 修改位置 */ .close-modal { position: absolute; top: 115px; right: 22px; background: none; border: none; cursor: pointer; z-index: 1002; transition: transform 0.2s ease; padding: 0; }
.close-modal:hover { transform: scale(1.1); }
.close-modal img { width: 35px; height: 35px; }
/* 活动规则弹窗样式 - 整体上移并增大字体 */ .rule-content { position: relative; width: 333px; height: 239px; display: flex; flex-direction: column; align-items: center; z-index: 1001; animation: modal-appear 0.3s ease-out; /* 修改:将弹窗上移,从原来的margin-top: 80px调整为更小的值 */ margin-top: 10px; /* 上移了10px */ }
.rule-bg { position: absolute; width: 100%; height: 100%; z-index: -1; }
/* 活动规则关闭按钮 - 修复:确保按钮层级高于背景 */ .close-rule-btn { position: absolute; top: 45.5px; right: 35.5px; background: none; border: none; cursor: pointer; z-index: 1002; transition: transform 0.2s ease; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; }
.close-rule-btn:hover { transform: scale(1.1); }
.close-rule-btn img { width: 20px; height: 20px; display: block; }
/* 活动规则文本 - 增大字体和行高 */ .rule-text { position: absolute; top: 83px; left: 27px; display: flex; flex-direction: column; gap: 8px; /* 增加行间距,从9.15px增加到12px */ width: calc(100% - 54px); }
.rule-line { color: #FFFFFF; font-size: 14px; /* 增大字体,从12px增加到14px */ line-height: 1.2; /* 增加行高,从1.4增加到1.5 */ }
/* 414×896 适配 (iPhone 11/XR等) */ @media (max-width: 414px) and (max-height: 896px) { .title-img { width: 310px; height: auto; } .wheel-wrapper { width: 310px; height: 310px; } .pointer-system { width: 127px; /* 137 * (310/333) ≈ 127px */ height: 127px; } .pointer-img { width: 127px; height: 127px; transform-origin: 63.5px 63.5px; } .pointer-cover-img { width: 97px; /* 104 * (310/333) ≈ 97px */ height: 97px; } .spin-btn-img { width: 220px; height: 86px; } .remaining-bg { width: 97px; height: 20px; } .remaining-text { font-size: 12px; } .modal-content { width: 320px; height: 360px; } .prize-info { margin-top: 110px; } .prize-title { margin-bottom: 32px; font-size: 24px; } .prize-amount-wrapper { width: 255px; height: 54px; } .prize-amount-bg { width: 255px; height: 54px; } .prize-amount { font-size: 24px; width: 225px; } .close-modal { top: 110px; right: 20px; } .rule-content { width: 320px; height: 225px; } .close-rule-btn { top: 43px; right: 34px; } .rule-text { top: 78px; left: 26px; width: calc(100% - 52px); } }
/* 412×915 适配 (部分Android设备如三星等) */ @media (max-width: 412px) and (max-height: 915px) { .title-img { width: 315px; height: auto; } .wheel-wrapper { width: 315px; height: 315px; } .pointer-system { width: 130px; /* 137 * (315/333) ≈ 130px */ height: 130px; } .pointer-img { width: 130px; height: 130px; transform-origin: 65px 65px; } .pointer-cover-img { width: 98px; /* 104 * (315/333) ≈ 98px */ height: 98px; } .spin-btn-img { width: 225px; height: 88px; } .remaining-bg { width: 98px; height: 20px; } .remaining-text { font-size: 12px; } .modal-content { width: 325px; height: 370px; } .prize-info { margin-top: 115px; } .prize-title { margin-bottom: 35px; font-size: 25px; } .prize-amount-wrapper { width: 260px; height: 56px; } .prize-amount-bg { width: 260px; height: 56px; } .prize-amount { font-size: 25px; width: 230px; } .close-modal { top: 115px; right: 22px; } .close-modal img { width: 32px; height: 32px; } .rule-content { width: 325px; height: 235px; } .close-rule-btn { top: 45px; right: 35px; } .rule-text { top: 82px; left: 27px; width: calc(100% - 54px); } .rule-line { font-size: 14px; } /* 历史记录适配 */ .history-record { width: 88%; } .history-title { font-size: 30px; } .history-record-item .title { font-size: 15px; } .history-record-item .time { font-size: 12px; } .history-record-item .token { font-size: 15px; } }
/* 280×653 适配 (小屏设备) */ @media (max-width: 280px) and (max-height: 653px) { .title-img { width: 235px; height: auto; } .wheel-wrapper { width: 235px; height: 235px; } .pointer-system { width: 97px; /* 137 * (235/333) ≈ 97px */ height: 97px; } .pointer-img { width: 97px; height: 97px; transform-origin: 48.5px 48.5px; } .pointer-cover-img { width: 73px; /* 104 * (235/333) ≈ 73px */ height: 73px; } .spin-btn-img { width: 170px; height: 66px; } .top-section { flex-direction: column; align-items: center; gap: 8px; } .expire-time { margin: 5px 0 0 0; text-align: center; font-size: 11px; } .top-right { gap: 12px; } .history-icon, .rule-icon { width: 20px; height: 20px; } .icon-text { font-size: 9px; } .remaining-bg { width: 75px; height: 15px; } .remaining-text { font-size: 10px; } .modal-content { width: 260px; height: 295px; } .prize-info { margin-top: 90px; } .prize-title { margin-bottom: 25px; font-size: 20px; } .prize-amount-wrapper { width: 215px; height: 45px; } .prize-amount-bg { width: 215px; height: 45px; } .prize-amount { font-size: 20px; width: 185px; } .close-modal { top: 90px; right: 15px; } .close-modal img { width: 28px; height: 28px; } .rule-content { width: 260px; height: 185px; } .close-rule-btn { top: 35px; right: 28px; } .rule-text { top: 65px; left: 22px; width: calc(100% - 44px); gap: 4px; } .rule-line { font-size: 12px; } /* 历史记录适配 */ .history-record { width: 95%; } .history-title { font-size: 24px; } .history-record-item { width: 95%; flex-direction: column; align-items: flex-start; gap: 5px; padding: 6px; } .history-record-item .title { font-size: 12px; } .history-record-item .time { font-size: 10px; margin-left: 15px; } .history-record-item .token { font-size: 12px; } .circle { width: 6px; height: 6px; margin-left: 5px; } .month-text, .year-text { font-size: 14px; } /* 按钮样式调整 */ .history-contents > div > div:first-child { margin-left: 30px; } .history-contents button { margin-right: 15px; padding: 5px 12px; font-size: 12px; } }
/* 通用小屏幕适配 (320-374px作为后备) */ @media (max-width: 374px) and (min-width: 320px) { .title-img { width: 260px; height: auto; } .wheel-wrapper { width: 260px; height: 260px; } .pointer-system { width: 107px; /* 137 * (260/333) ≈ 107px */ height: 107px; } .pointer-img { width: 107px; height: 107px; transform-origin: 53.5px 53.5px; } .pointer-cover-img { width: 81px; /* 104 * (260/333) ≈ 81px */ height: 81px; } .spin-btn-img { width: 185px; height: 72px; } .remaining-bg { width: 81px; height: 17px; } .remaining-text { font-size: 11px; } .modal-content { width: 285px; height: 325px; } .prize-info { margin-top: 95px; } .prize-title { margin-bottom: 28px; font-size: 21px; } .prize-amount-wrapper { width: 230px; height: 49px; } .prize-amount-bg { width: 230px; height: 49px; } .prize-amount { font-size: 21px; width: 200px; } .close-modal { top: 95px; right: 17px; } .rule-content { width: 285px; height: 205px; } .close-rule-btn { top: 39px; right: 30px; } .rule-text { top: 70px; left: 23px; width: calc(100% - 46px); } .rule-line { font-size: 12.5px; } }
/* 390×844 适配 (iPhone 12/13 Pro等) */ @media (max-width: 390px) and (max-height: 844px) { .title-img { width: 295px; height: auto; } .wheel-wrapper { width: 295px; height: 295px; } .pointer-system { width: 121px; /* 137 * (295/333) ≈ 121px */ height: 121px; } .pointer-img { width: 121px; height: 121px; transform-origin: 60.5px 60.5px; } .pointer-cover-img { width: 92px; /* 104 * (295/333) ≈ 92px */ height: 92px; } .spin-btn-img { width: 210px; height: 82px; } .remaining-bg { width: 92px; height: 19px; } .modal-content { width: 305px; height: 345px; } .prize-info { margin-top: 105px; } .prize-title { margin-bottom: 30px; font-size: 23px; } .prize-amount-wrapper { width: 245px; height: 52px; } .prize-amount-bg { width: 245px; height: 52px; } .prize-amount { font-size: 23px; width: 215px; } .close-modal { top: 105px; right: 19px; } .rule-content { width: 305px; height: 220px; } .close-rule-btn { top: 42px; right: 33px; } .rule-text { top: 76px; left: 25px; width: calc(100% - 50px); } } /* 393×851 适配 (部分Android设备) */ @media (max-width: 393px) and (max-height: 851px) { .title-img { width: 297px; height: auto; } .wheel-wrapper { width: 297px; height: 297px; } .pointer-system { width: 122px; /* 137 * (297/333) ≈ 122px */ height: 122px; } .pointer-img { width: 122px; height: 122px; transform-origin: 61px 61px; } .pointer-cover-img { width: 93px; /* 104 * (297/333) ≈ 93px */ height: 93px; } .spin-btn-img { width: 212px; height: 83px; } .remaining-bg { width: 93px; height: 19px; } .modal-content { width: 307px; height: 347px; } .prize-info { margin-top: 106px; } .prize-title { margin-bottom: 31px; font-size: 23px; } .prize-amount-wrapper { width: 247px; height: 53px; } .prize-amount-bg { width: 247px; height: 53px; } .prize-amount { font-size: 23px; width: 217px; } .close-modal { top: 106px; right: 19px; } .rule-content { width: 307px; height: 222px; } .close-rule-btn { top: 42px; right: 33px; } .rule-text { top: 77px; left: 25px; width: calc(100% - 50px); } } /* 通用小屏幕适配 (作为后备) */ @media (max-width: 360px) { .title-img { width: 270px; height: auto; } .wheel-wrapper { width: 270px; height: 270px; } .pointer-system { width: 111px; /* 137 * (270/333) ≈ 111px */ height: 111px; } .pointer-img { width: 111px; height: 111px; transform-origin: 55.5px 55.5px; } .pointer-cover-img { width: 84px; /* 104 * (270/333) ≈ 84px */ height: 84px; } .spin-btn-img { width: 195px; height: 76px; } .remaining-bg { width: 84px; height: 17px; } .remaining-text { font-size: 11px; } .modal-content { width: 290px; height: 330px; } .prize-info { margin-top: 100px; } .prize-title { margin-bottom: 28px; font-size: 22px; } .prize-amount-wrapper { width: 235px; height: 50px; } .prize-amount-bg { width: 235px; height: 50px; } .prize-amount { font-size: 22px; width: 205px; } .close-modal { top: 100px; right: 18px; } .rule-content { width: 290px; height: 210px; } .close-rule-btn { top: 40px; right: 32px; } .rule-text { top: 72px; left: 24px; width: calc(100% - 48px); } .rule-line { font-size: 13px; } } /* 媒体查询 - 适配小屏幕 */ @media (max-width: 375px) { .title-img { width: 275px; height: auto; /* 保持比例 */ } .wheel-wrapper { width: 280px; height: 280px; } /* 关键修复:指针系统居中问题 */ .pointer-system { position: absolute; top: 50%; left: 50%; width: 115px; /* 按比例缩小:137 * (280/333) ≈ 115px */ height: 115px; transform: translate(-50%, -50%); z-index: 2; } .pointer-img { width: 115px; height: 115px; /* 精确计算旋转中心点 */ transform-origin: 57.5px 57.5px; /* 115px / 2 = 57.5px */ transform: rotate(-21.5deg); } .pointer-cover-img { width: 87px; /* 按比例缩小:104 * (280/333) ≈ 87px */ height: 87px; } .spin-btn-img { width: 200px; height: 78px; } .top-right { gap: 15px; } .remaining-section { margin-top: -8px; } .remaining-bg { width: 90px; /* 按比例调整 */ height: 18.5px; } .remaining-text { font-size: 11px; } /* 小屏幕适配中奖弹窗 */ .modal-content { width: 300px; height: 340px; } .prize-info { margin-top: 100px; } .prize-title { margin-bottom: 30px; font-size: 22px; } .prize-amount-wrapper { margin-top: 18px; width: 240px; height: 51px; } .prize-amount-bg { width: 240px; height: 51px; } .prize-amount { font-size: 22px; width: 210px; } .prize-amount.scrolling { width: 190px; } .no-times-content { width: 280px; height: 66px; margin-top: 200px; } /* 小屏幕适配关闭按钮位置 */ .close-modal { top: 100px; right: 18px; } .close-modal img { width: 30px; height: 30px; } /* 小屏幕适配活动规则弹窗 */ .rule-content { width: 300px; height: 215px; margin-top: 20px; } .close-rule-btn { top: 41px; right: 32px; } .rule-text { top: 75px; left: 24px; width: calc(100% - 48px); gap: 5px; } .rule-line { font-size: 13px; } } /* 280×653 适配 (小屏设备) */ @media (max-width: 280px) and (max-height: 653px) { .title-img { width: 235px; height: auto; } .wheel-wrapper { width: 200px; height: 200px; } .pointer-system { width: 97px; /* 137 * (235/333) ≈ 97px */ height: 97px; } .pointer-img { width: 97px; height: 97px; transform-origin: 48.5px 48.5px; } .pointer-cover-img { width: 73px; /* 104 * (235/333) ≈ 73px */ height: 73px; } .spin-btn-img { width: 170px; height: 66px; } .top-section { flex-direction: column; align-items: center; gap: 8px; } .expire-time { margin: 5px 0 0 0; text-align: center; font-size: 11px; } .top-right { gap: 12px; } .history-icon, .rule-icon { width: 20px; height: 20px; } .icon-text { font-size: 9px; } .remaining-bg { width: 75px; height: 15px; } .remaining-text { font-size: 10px; } .modal-content { width: 260px; height: 295px; } .prize-info { margin-top: 90px; } .prize-title { margin-bottom: 25px; font-size: 20px; } .prize-amount-wrapper { width: 215px; height: 45px; } .prize-amount-bg { width: 215px; height: 45px; } .prize-amount { font-size: 20px; width: 185px; } .close-modal { top: 90px; right: 15px; } .close-modal img { width: 28px; height: 28px; } .rule-content { width: 260px; height: 185px; } .close-rule-btn { top: 35px; right: 28px; } .rule-text { top: 65px; left: 22px; width: calc(100% - 44px); gap: 4px; } .rule-line { font-size: 12px; } /* 历史记录适配 */ .history-record { width: 95%; } .history-title { font-size: 24px; } .history-record-item { width: 95%; flex-direction: column; align-items: flex-start; gap: 5px; padding: 6px; } .history-record-item .title { font-size: 12px; } .history-record-item .time { font-size: 10px; margin-left: 15px; } .history-record-item .token { font-size: 12px; } .circle { width: 6px; height: 6px; margin-left: 5px; } .month-text, .year-text { font-size: 14px; } }
.fold-up { width: 30px; height: 30px; position: absolute; top: 20px; left: 45px; cursor: pointer; z-index: 999; }
.history-title { padding-top: 12px; display: flex; justify-content: center; width: 100%; color: #00e5ff; font-size: 32px; font-weight: 700; }
.history-record { background: #080A6D; position: fixed; right: 0; bottom: 0; width: 90%; height: 100vh; display: flex; flex-direction: column; --bottom-cut-height: 220px; overflow: hidden; z-index: 2000; box-shadow: -8px 0 24px rgba(0,0,0,0.6); border-left: 1px solid rgba(255,255,255,0.03); padding-bottom: 0; }
.history-contents { margin-top: 20px; padding-right: 10px; flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; direction: rtl; } .history-contents > * { direction: ltr; } .history-contents * { direction: ltr; }
.history-contents::-webkit-scrollbar { width: 14px; background-color: #20086d; } .history-contents::-webkit-scrollbar-thumb { background-color: #4a4de6; border-radius: 4px; } .history-contents::-webkit-scrollbar-thumb:hover { background-color: #6b6ef5; }
.history-decoration { flex: 0 0 200px; height: var(--bottom-cut-height); position: relative; left: 50%; transform: translateX(-50%); width: 100%; pointer-events: none; z-index: 0; background-image: url('../../assets/img/wealthGoldenWheel/bottomDecoration.png'); background-repeat: no-repeat; background-position: center bottom; background-size: contain; margin-top: 0; }
/* 记录项样式 */ .history-record-item { background: #0b0d99; margin-bottom: 10px; display: flex; justify-content: space-between; width: 80%; padding: 8px; border-radius: 8px; }
.history-record-item .left { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 5px; }
.history-record-item .title { color: #f2f5ff; font-size: 16px; font-weight: 700; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; display: flex; align-items: center; }
.history-record-item .time { font-size: 12px; color: #e6ecff; font-weight: 700; margin-left: 28px; }
.history-record-item .right { display: flex; align-items: center; justify-content: flex-end; min-width: 72px; padding-right: 10px; }
.history-record-item .token { color: #00e6ff; font-size: 16px; font-weight: 700; } .circle { width: 10px; height: 10px; background-color: #fff; margin-right: 8px; flex-shrink: 0; margin-left: 10px; border-radius: 50%; }
.month-row, .year-header { display: flex; align-items: center; padding-bottom: 12px; cursor: pointer; color: #ffffff; font-weight: 700; }
.month-text, .year-text { font-weight: 700; font-size: 16px; color: #ffffff; }
.month-caret, .year-caret { margin-left: 10px; font-size: 16px; color: #ffffff; }
.empty-month { padding: 8px; color: #cfd9ff; background: transparent; }
@media (max-width: 900px) { .history-record { width: 90%; } .history-record-item { width: calc(100% - 60px); } } @media (max-width: 430px) { .history-record-item .title { font-size: 12px; }
.history-record-item .time { font-size: 10px; margin-left:10px; }
.history-record-item .token { font-size: 14px; }
.history-record-item .right { padding-right: 5px; } .circle { width: 8px; height: 8px; margin-left: 0px; } .month-caret, .year-caret { margin-left: 5px; } }
</style>
|