chore: 移动端基本适配完成
This commit is contained in:
@@ -84,14 +84,14 @@
|
||||
transform: translateX(-50%);
|
||||
width: auto;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, 0.7); /* 添加半透明背景确保在任何背景下都清晰可见 */
|
||||
background: transparent; /* 设置为透明背景 */
|
||||
padding: 5px;
|
||||
border-radius: 0 0 8px 8px;
|
||||
}
|
||||
|
||||
/* 移动设备上缩小logo尺寸 */
|
||||
/* 移动设备上设置logo尺寸 */
|
||||
.app-logo {
|
||||
width: 60px; /* 移动设备上设置固定宽度 */
|
||||
width: 200px; /* 移动设备上设置固定宽度为200px */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,18 +18,18 @@ import {
|
||||
saveBonusRules as saveBonusRulesToConfig
|
||||
} from '../services/configService';
|
||||
|
||||
// 初始化数据
|
||||
export let individualRankings = getIndividualRankings();
|
||||
export let teamRankings = getTeamRankings();
|
||||
export let bonusRules = getBonusRules() || [
|
||||
// 初始化空数据占位符,将在initializeData中正确加载
|
||||
export let individualRankings = [];
|
||||
export let teamRankings = [];
|
||||
export let bonusRules = [
|
||||
{ rank: '1-3', description: '前三名', individualBonus: '¥10000, ¥8000, ¥5000', teamBonus: '¥50000, ¥30000, ¥20000' },
|
||||
{ rank: '4-10', description: '四至十名', individualBonus: '¥3000/人', teamBonus: '¥10000/队' },
|
||||
{ rank: '11-20', description: '十一至二十名', individualBonus: '¥1000/人', teamBonus: '¥5000/队' }
|
||||
];
|
||||
export let systemUsers = getSystemUsers();
|
||||
export let displayConfig = getDisplayConfig();
|
||||
export let battleEndTime = getBattleEndTime();
|
||||
export let drumConfig = getDrumConfig();
|
||||
export let systemUsers = [];
|
||||
export let displayConfig = null;
|
||||
export let battleEndTime = { date: new Date().toISOString().split('T')[0], time: '00:00:00' };
|
||||
export let drumConfig = {};
|
||||
|
||||
// 保存结束时间
|
||||
export const saveBattleEndTime = async (endTime) => {
|
||||
|
||||
34
src/main.js
34
src/main.js
@@ -4,41 +4,11 @@ import App from './App.vue'
|
||||
import router from './router'
|
||||
import { getBackgroundConfig } from './services/configService'
|
||||
|
||||
// 设置页面背景
|
||||
const setupBackground = async () => {
|
||||
try {
|
||||
const backgroundConfig = await getBackgroundConfig();
|
||||
|
||||
// 如果配置了使用背景图片
|
||||
if (backgroundConfig.useBackgroundImage && backgroundConfig.backgroundImage) {
|
||||
document.body.style.backgroundImage = `url(${backgroundConfig.backgroundImage})`;
|
||||
document.body.style.backgroundSize = backgroundConfig.backgroundSize || 'cover';
|
||||
document.body.style.backgroundPosition = backgroundConfig.backgroundPosition || 'center';
|
||||
document.body.style.backgroundRepeat = 'no-repeat';
|
||||
document.body.style.backgroundAttachment = 'fixed';
|
||||
} else if (backgroundConfig.backgroundColor) {
|
||||
// 使用纯色背景
|
||||
document.body.style.backgroundColor = backgroundConfig.backgroundColor;
|
||||
document.body.style.backgroundImage = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('设置背景失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 设置默认背景(立即应用)
|
||||
document.body.style.backgroundImage = 'url(/battle-background.jpg)';
|
||||
document.body.style.backgroundSize = 'contain';
|
||||
document.body.style.backgroundPosition = 'center';
|
||||
document.body.style.backgroundRepeat = 'no-repeat';
|
||||
document.body.style.backgroundAttachment = 'fixed';
|
||||
// 背景设置已移至样式表 style.css 中定义
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
// 使用路由
|
||||
app.use(router)
|
||||
|
||||
// 挂载应用前设置背景
|
||||
setupBackground().then(() => {
|
||||
app.mount('#app');
|
||||
});
|
||||
app.mount('#app');
|
||||
|
||||
@@ -60,7 +60,10 @@ html, body {
|
||||
height: 100%;
|
||||
color: var(--text-color);
|
||||
background-color: var(--dark-color);
|
||||
background-image: var(--gradient-background);
|
||||
background-image: url(/battle-background.jpg);
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
@@ -524,12 +527,31 @@ table {
|
||||
:root {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 移动端body不设置任何背景相关属性 */
|
||||
html, body {
|
||||
background: none !important;
|
||||
background-image: none !important;
|
||||
background-color: var(--dark-color) !important;
|
||||
background-size: auto !important;
|
||||
background-position: static !important;
|
||||
background-repeat: repeat !important;
|
||||
background-attachment: scroll !important;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
:root {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 游戏化标题发光动画 */
|
||||
|
||||
@@ -27,20 +27,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 第三部分:奖金设置(图片形式) -->
|
||||
<section v-if="localDisplayConfig.showBonusModule" class="bonus-section card-game"
|
||||
@mousedown="startBonusDrag"
|
||||
@mouseup="endDrag"
|
||||
@mouseleave="endDrag"
|
||||
:style="{ left: bonusPosition.x === 'auto' ? 'auto' : (bonusPosition.x + 'px'), right: bonusPosition.x === 'auto' ? '20px' : 'auto', top: bonusPosition.y === 'auto' ? 'auto' : (bonusPosition.y + 'px'), bottom: bonusPosition.y === 'auto' ? '20px' : 'auto' }">
|
||||
<!-- <h2 class="game-subtitle">🎯 奖金设置</h2> -->
|
||||
<div class="bonus-awards-container">
|
||||
<div><img src="/award1.png" alt="一等奖" class="award-image"></div>
|
||||
<div><img src="/award2.png" alt="二等奖" class="award-image"></div>
|
||||
<div><img src="/award3.png" alt="三等奖" class="award-image"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 任务设置模块 -->
|
||||
<section class="task-settings-section card-game">
|
||||
<div class="task-title-container">
|
||||
@@ -49,6 +35,15 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 第三部分:奖金设置(图片形式) -->
|
||||
<section v-if="localDisplayConfig.showBonusModule" class="bonus-section"
|
||||
:style="{ margin: '20px 0' }">
|
||||
<div class="bonus-awards-container">
|
||||
<div><img src="/award1.png" alt="一等奖" class="award-image"></div>
|
||||
<div><img src="/award2.png" alt="二等奖" class="award-image"></div>
|
||||
<div><img src="/award3.png" alt="三等奖" class="award-image"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 第四部分:排名明细 -->
|
||||
<section class="rankings-section card-game">
|
||||
@@ -245,9 +240,7 @@ function createDefaultTeamRankings() {
|
||||
];
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
const individualRankingsData = importedIndividualRankings && importedIndividualRankings.length > 0 ? importedIndividualRankings : createDefaultIndividualRankings();
|
||||
const teamRankingsData = importedTeamRankings && importedTeamRankings.length > 0 ? importedTeamRankings : createDefaultTeamRankings();
|
||||
// 初始化默认显示配置
|
||||
const defaultDisplayConfig = createDefaultDisplayConfig();
|
||||
|
||||
// 深度合并配置,确保所有必要属性都存在
|
||||
@@ -267,9 +260,9 @@ function mergeConfig(config1, config2) {
|
||||
return merged;
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const individualRankings = ref(individualRankingsData);
|
||||
const teamRankings = ref(teamRankingsData);
|
||||
// 响应式数据 - 使用ref包装导入的数据,确保响应式更新
|
||||
const individualRankings = ref(importedIndividualRankings || []);
|
||||
const teamRankings = ref(importedTeamRankings || []);
|
||||
// 确保即使displayConfig存在,也要和默认配置合并,保证结构完整性
|
||||
const localDisplayConfig = ref(displayConfig
|
||||
? mergeConfig(defaultDisplayConfig, JSON.parse(JSON.stringify(displayConfig)))
|
||||
@@ -280,15 +273,38 @@ const taskSettings = ref({
|
||||
subtitle: '时间: 2025-11-12 - 2026-02-08'
|
||||
});
|
||||
|
||||
// 加载任务设置
|
||||
// 加载任务设置和初始化所有数据
|
||||
onMounted(async () => {
|
||||
try {
|
||||
// 首先初始化所有数据,确保从服务器获取最新配置
|
||||
await initializeData();
|
||||
|
||||
// 然后重新获取最新的数据
|
||||
const config = await readConfig();
|
||||
if (config.taskSettings) {
|
||||
taskSettings.value = config.taskSettings;
|
||||
if (config) {
|
||||
// 更新任务设置
|
||||
if (config.taskSettings) {
|
||||
taskSettings.value = config.taskSettings;
|
||||
}
|
||||
|
||||
// 直接从config中更新排名数据,确保使用最新的服务器数据
|
||||
if (config.individualRankings && config.individualRankings.length > 0) {
|
||||
individualRankings.value = config.individualRankings;
|
||||
}
|
||||
|
||||
if (config.teamRankings && config.teamRankings.length > 0) {
|
||||
teamRankings.value = config.teamRankings;
|
||||
}
|
||||
|
||||
// 更新显示配置
|
||||
if (config.displayConfig) {
|
||||
localDisplayConfig.value = mergeConfig(defaultDisplayConfig, JSON.parse(JSON.stringify(config.displayConfig)));
|
||||
}
|
||||
|
||||
console.log('成功从服务器加载最新数据');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载任务设置失败:', error);
|
||||
console.error('加载数据失败:', error);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -912,6 +928,30 @@ onUnmounted(() => {
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
/* 隐藏倒计时模块 */
|
||||
.timer-float {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 隐藏管理员入口 */
|
||||
.admin-entry-float {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 奖金模块垂直居中显示,两侧20px间距 */
|
||||
.bonus-section {
|
||||
/* 背景全部取消设置 **/
|
||||
background: none !important;
|
||||
|
||||
position: static !important;
|
||||
margin: 20px auto;
|
||||
width: calc(100% - 40px);
|
||||
max-width: none;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
top: 0 !important;
|
||||
bottom: 0 !important;
|
||||
}
|
||||
/* 奖金模块响应式调整 */
|
||||
.bonus-section {
|
||||
bottom: 10px;
|
||||
@@ -923,11 +963,6 @@ onUnmounted(() => {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.award-image {
|
||||
max-width: 70px;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.timer-float {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
@@ -1503,29 +1538,255 @@ onUnmounted(() => {
|
||||
|
||||
/* 管理员按钮使用通用按钮样式 */
|
||||
|
||||
/* 响应式设计 */
|
||||
/* 移动端背景图片设置 - 全局样式 */
|
||||
@media (max-width: 768px) {
|
||||
.main-title {
|
||||
/* 1. 背景图片全屏显示并固定 */
|
||||
.battle-ranking {
|
||||
padding: 0 !important;
|
||||
margin-top: 50px;
|
||||
background-image: url('/battle-background.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 移除原有卡片背景,让内容在背景图上显示 */
|
||||
.card-game {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 主题部分调整 */
|
||||
.theme-section {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* 战鼓部分调整 */
|
||||
.drums-section {
|
||||
transform: scale(0.8); /* 缩小战鼓元素 */
|
||||
}
|
||||
|
||||
/* 2. 倒计时模块调整 - 移至冠军战区上方,缩小时间显示为一行 */
|
||||
.timer-float {
|
||||
position: relative;
|
||||
right: auto;
|
||||
top: auto;
|
||||
margin: 10px auto;
|
||||
width: 95%;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.timer-float .label {
|
||||
font-size: 0.9rem;
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.countdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.time-item {
|
||||
font-size: 0.85rem;
|
||||
padding: 4px 6px;
|
||||
background: rgba(255, 215, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(255, 215, 0, 0.5);
|
||||
}
|
||||
|
||||
/* 任务设置调整 */
|
||||
.task-settings-section {
|
||||
margin-top: -100px; /* 调整负边距 */
|
||||
}
|
||||
|
||||
.task-title-container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.task-title-container .game-title {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.task-title-container .game-title-highlight {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.drums-container {
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
.task-title-container .game-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* 排名部分调整 */
|
||||
.rankings-section {
|
||||
margin: 0 10px 20px 10px;
|
||||
}
|
||||
|
||||
.rankings-container {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.individual-rankings,
|
||||
.team-rankings {
|
||||
min-width: auto;
|
||||
width: 100%;
|
||||
/* 调整顺序,确保倒计时在冠军上方 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 将倒计时移动到冠军上方的位置 */
|
||||
.team-rankings {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.team-rankings-container,
|
||||
.individual-rankings-container {
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
.game-subtitle {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* 表格调整 */
|
||||
.rank-table {
|
||||
min-height: 250px;
|
||||
max-height: 250px;
|
||||
overflow-x: auto; /* 允许横向滚动 */
|
||||
}
|
||||
|
||||
.table-header,
|
||||
.table-row {
|
||||
font-size: 0.8rem;
|
||||
padding: 8px 6px;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
/* 冠军部分调整 */
|
||||
.team-champion,
|
||||
.individual-champion {
|
||||
transform: scale(0.9);
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
/* 管理员入口调整 */
|
||||
.admin-entry-float {
|
||||
position: relative;
|
||||
top: auto;
|
||||
right: auto;
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-game-secondary {
|
||||
padding: 10px 15px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* 3. 奖金模块调整 - 移至底部显示 */
|
||||
.bonus-section {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
z-index: 1000;
|
||||
transform: translateY(0);
|
||||
transition: transform 0.3s ease;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.bonus-awards-container {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.award-image {
|
||||
height: 120px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* 确保重要内容优先显示 */
|
||||
.rank-col,
|
||||
.name-col,
|
||||
.score-col {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 为底部奖金模块留出空间 */
|
||||
.admin-entry-float {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
/* 针对极小屏幕的特殊处理 */
|
||||
@media (max-width: 480px) {
|
||||
.table-header,
|
||||
.table-row {
|
||||
min-width: 450px;
|
||||
font-size: 0.75rem;
|
||||
padding: 6px 4px;
|
||||
}
|
||||
|
||||
.game-title {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.game-title-highlight {
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
|
||||
.award-image {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.countdown {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.time-item {
|
||||
font-size: 0.8rem;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 触摸设备优化 */
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
/* 增大点击区域 */
|
||||
.btn-game-secondary {
|
||||
padding: 12px 24px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* 移除hover效果,添加触摸反馈 */
|
||||
.table-row:active {
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
.btn-game-secondary:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user