|
|
<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 */ }
/* 媒体查询 - 适配小屏幕 */ @media (max-width: 380px) { .title-img { width: 280px; height: 123px; } .wheel-wrapper { width: 280px; height: 280px; } .pointer-container { width: 115px; height: 115px; }
.pointer-system { width: 115px; height: 115px; } .pointer-system { width: 115px; height: 115px; } .pointer-cover-img { width: 70px; height: 70px; } .spin-btn-img { width: 200px; height: 78px; } .top-right { gap: 15px; } .remaining-section { margin-top: -8px; } /* 小屏幕适配中奖弹窗 */ .modal-content { width: 300px; height: 340px; } .prize-info { margin-top: 100px; } .prize-title { margin-bottom: 30px; } .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; /* 小屏幕字体稍小但依然比原来大 */ } } .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>
|