diff --git a/data/config.json b/data/config.json index 817b612..188ff8c 100644 --- a/data/config.json +++ b/data/config.json @@ -1,15 +1,15 @@ { "individualRankings": [ { - "id": 1763703508858, - "name": "毕艺超", + "id": 8, + "name": "杨鑫鹏", "score": 208600, "level": "SSS", - "avatar": "🎯", + "avatar": "/uploads/1763972044872.jpg", "department": "销售部", - "completedTasks": 0, + "completedTasks": 32, "bonus": 0, - "team": "七战区" + "team": "一战区" }, { "id": 1763600399414, @@ -44,6 +44,50 @@ "bonus": 0, "team": "七战区" }, + { + "id": 1763606483656, + "name": "陈梦蝶", + "score": 149000, + "level": "SSS", + "avatar": "🥈", + "department": "销售部", + "completedTasks": 0, + "bonus": 0, + "team": "三战区" + }, + { + "id": 1, + "name": "刘贵博", + "score": 149000, + "level": "SSS", + "avatar": "👑", + "department": "销售部", + "completedTasks": 48, + "bonus": 0, + "team": "一战区" + }, + { + "id": 3, + "name": "赵政行", + "score": 149000, + "level": "SSS", + "avatar": "👑", + "department": "销售部", + "completedTasks": 42, + "bonus": 0, + "team": "一战区" + }, + { + "id": 1763703454998, + "name": "汪思柔", + "score": 119200, + "level": "SSS", + "avatar": "🎯", + "department": "销售部", + "completedTasks": 0, + "bonus": 0, + "team": "七战区" + }, { "id": 1763703551860, "name": "刘正艺", @@ -67,15 +111,48 @@ "team": "七战区" }, { - "id": 1763703454998, - "name": "汪思柔", + "id": 2, + "name": "张政", "score": 89400, "level": "SSS", - "avatar": "🎯", + "avatar": "👑", + "department": "销售部", + "completedTasks": 45, + "bonus": 0, + "team": "一战区" + }, + { + "id": 1763702288912, + "name": "仝维茜", + "score": 89400, + "level": "SSS", + "avatar": "🥉", "department": "销售部", "completedTasks": 0, "bonus": 0, - "team": "七战区" + "team": "四战区" + }, + { + "id": 1763702407090, + "name": "李明娣", + "score": 89400, + "level": "SSS", + "avatar": "⭐", + "department": "销售部", + "completedTasks": 0, + "bonus": 0, + "team": "五战区" + }, + { + "id": 1763702548562, + "name": "高博祎", + "score": 89400, + "level": "SSS", + "avatar": "🔥", + "department": "销售部", + "completedTasks": 0, + "bonus": 0, + "team": "六战区" }, { "id": 1763606463583, @@ -121,17 +198,6 @@ "bonus": 0, "team": "三战区" }, - { - "id": 1763606483656, - "name": "陈梦蝶", - "score": 59600, - "level": "SSS", - "avatar": "🥈", - "department": "销售部", - "completedTasks": 0, - "bonus": 0, - "team": "三战区" - }, { "id": 1763702177212, "name": "东知", @@ -177,37 +243,26 @@ "team": "四战区" }, { - "id": 1, - "name": "刘贵博", - "score": 0, + "id": 12, + "name": "孙珊珊", + "score": 26820, "level": "SSS", - "avatar": "👑", - "department": "销售部", - "completedTasks": 48, + "avatar": "🥇", + "department": "刘奔腾", + "completedTasks": 24, "bonus": 0, - "team": "一战区" + "team": "二战区" }, { - "id": 2, - "name": "张政", + "id": 1763703508858, + "name": "毕艺超", "score": 0, "level": "SSS", - "avatar": "👑", + "avatar": "/uploads/1763860106271.jpg", "department": "销售部", - "completedTasks": 45, + "completedTasks": 0, "bonus": 0, - "team": "一战区" - }, - { - "id": 3, - "name": "赵政行", - "score": 0, - "level": "SSS", - "avatar": "👑", - "department": "销售部", - "completedTasks": 42, - "bonus": 0, - "team": "一战区" + "team": "七战区" }, { "id": 5, @@ -231,17 +286,6 @@ "bonus": 0, "team": "一战区" }, - { - "id": 8, - "name": "杨鑫鹏", - "score": 0, - "level": "SSS", - "avatar": "👑", - "department": "销售部", - "completedTasks": 32, - "bonus": 0, - "team": "一战区" - }, { "id": 9, "name": "曾焱平", @@ -275,17 +319,6 @@ "bonus": 0, "team": "二战区" }, - { - "id": 12, - "name": "孙珊珊", - "score": 0, - "level": "SSS", - "avatar": "🥇", - "department": "刘奔腾", - "completedTasks": 24, - "bonus": 0, - "team": "二战区" - }, { "id": 13, "name": "刘奔腾", @@ -473,17 +506,6 @@ "bonus": 0, "team": "四战区" }, - { - "id": 1763702288912, - "name": "仝维茜", - "score": 0, - "level": "SSS", - "avatar": "🥉", - "department": "销售部", - "completedTasks": 0, - "bonus": 0, - "team": "四战区" - }, { "id": 1763702306246, "name": "吴玉洁", @@ -528,17 +550,6 @@ "bonus": 0, "team": "五战区" }, - { - "id": 1763702407090, - "name": "李明娣", - "score": 0, - "level": "SSS", - "avatar": "⭐", - "department": "销售部", - "completedTasks": 0, - "bonus": 0, - "team": "五战区" - }, { "id": 1763702423195, "name": "陈亚军", @@ -638,17 +649,6 @@ "bonus": 0, "team": "六战区" }, - { - "id": 1763702548562, - "name": "高博祎", - "score": 0, - "level": "SSS", - "avatar": "🔥", - "department": "销售部", - "completedTasks": 0, - "bonus": 0, - "team": "六战区" - }, { "id": 1763702585045, "name": "孙丽霞", @@ -762,74 +762,74 @@ ], "teamRankings": [ { - "id": 7, - "name": "七战区", - "totalScore": 417200, - "memberCount": 8, - "level": "A", - "leader": "曹恒", - "completedTasks": 148, + "id": 1, + "name": "一战区", + "totalScore": 844400, + "memberCount": 11, + "level": "SSS", + "leader": "王将军", + "completedTasks": 210, "bonus": 0 }, { - "id": 1, - "name": "一战区", - "totalScore": 248400, - "memberCount": 11, - "level": "SSS", - "leader": "王松根", - "completedTasks": 210, + "id": 7, + "name": "七战区", + "totalScore": 447000, + "memberCount": 8, + "level": "A", + "leader": "曹将军", + "completedTasks": 148, "bonus": 0 }, { "id": 4, "name": "四战区", - "totalScore": 238400, + "totalScore": 327800, "memberCount": 10, "level": "S", - "leader": "熊春杰", + "leader": "熊将军", "completedTasks": 172, "bonus": 0 }, { "id": 3, "name": "三战区", - "totalScore": 188800, + "totalScore": 278200, "memberCount": 9, "level": "SS", - "leader": "李杰", + "leader": "李将军", "completedTasks": 185, "bonus": 0 }, - { - "id": 2, - "name": "二战区", - "totalScore": 59600, - "memberCount": 12, - "level": "SS", - "leader": "贺鸿飞", - "completedTasks": 198, - "bonus": 0 - }, { "id": 6, "name": "六战区", - "totalScore": 59600, + "totalScore": 149000, "memberCount": 10, "level": "A", - "leader": "刘家秀", + "leader": "刘将军", "completedTasks": 155, "bonus": 0 }, { "id": 5, "name": "五战区", - "totalScore": 0, + "totalScore": 89400, "memberCount": 9, "level": "S", - "leader": "周顺凡", + "leader": "周将军", "completedTasks": 165, "bonus": 0 + }, + { + "id": 2, + "name": "二战区", + "totalScore": 86420, + "memberCount": 12, + "level": "SS", + "leader": "贺将军", + "completedTasks": 198, + "bonus": 0 } ], "bonusRules": [ @@ -892,7 +892,7 @@ "department": "left", "bonus": "left" }, - "defaultDisplayRows": 7, + "defaultDisplayRows": 0, "filterZeroScore": true }, "crown": { @@ -926,10 +926,19 @@ "filterZeroScore": false }, "championLogos": { - "teamChampion": "", + "teamChampion": "/uploads/1763979489455.png", "individualChampion": "", - "teamChampionSize": 120, - "individualChampionSize": 120 + "teamChampionSize": 121, + "individualChampionSize": 120, + "teamChampionType": "photo", + "teamChampionPhotoWidth": 400, + "teamChampionPhotoHeight": 242 + }, + "subtitleImage": { + "src": "/completed_performance.png", + "width": 200, + "height": 60, + "alt": "总战绩" } }, "battleEndTime": { @@ -957,10 +966,7 @@ "enabled": true }, "pattern": { - "strongBeats": [ - 1, - 4 - ], + "strongBeats": [], "totalBeats": 4, "accentMultiplier": 1.5, "accentFrequencyOffset": 10, diff --git a/src/views/AdminPanel.vue b/src/views/AdminPanel.vue index 0757665..d91c4ec 100644 --- a/src/views/AdminPanel.vue +++ b/src/views/AdminPanel.vue @@ -554,6 +554,51 @@ + +
+

📊 总战绩标题图像配置

+
+
+
+ 总战绩标题图像 +
+
+ 未上传图像 +
+
+
+ + +
+
+
+ + + px +
+
+ + + px +
+
+
+ +
+

支持JPG、PNG、GIF格式,建议尺寸200x60像素,文件大小不超过2MB

+
+
+

👑 英雄冠军皇冠配置

@@ -996,6 +1041,54 @@ const clearChampionLogo = (type) => { championLogos.value[type] = ''; }; +// 处理总战绩标题图像上传 +const handleSubtitleImageUpload = async (event) => { + const file = event.target.files[0]; + if (!file) return; + + const formData = new FormData(); + formData.append('file', file); + + try { + const response = await fetch('/api/upload', { + method: 'POST', + body: formData + }); + + if (response.ok) { + const data = await response.json(); + // 确保subtitleImage对象存在 + if (!localDisplayConfig.value.subtitleImage) { + localDisplayConfig.value.subtitleImage = {}; + } + // 清除旧的文件(如果是上传的文件) + if (localDisplayConfig.value.subtitleImage.src && localDisplayConfig.value.subtitleImage.src.startsWith('/uploads/')) { + const oldFilename = localDisplayConfig.value.subtitleImage.src.split('/').pop(); + fetch(`/api/upload/${oldFilename}`, { method: 'DELETE' }) + .catch(error => console.error('删除旧文件失败:', error)); + } + // 设置新的图像路径 + localDisplayConfig.value.subtitleImage.src = data.filePath; + } else { + console.error('上传失败:', response.status); + } + } catch (error) { + console.error('上传文件时出错:', error); + } +}; + +// 清除总战绩标题图像 +const clearSubtitleImage = () => { + if (localDisplayConfig.value.subtitleImage?.src && localDisplayConfig.value.subtitleImage.src.startsWith('/uploads/')) { + const filename = localDisplayConfig.value.subtitleImage.src.split('/').pop(); + fetch(`/api/upload/${filename}`, { method: 'DELETE' }) + .catch(error => console.error('删除文件失败:', error)); + } + // 重置为默认图像 + localDisplayConfig.value.subtitleImage = localDisplayConfig.value.subtitleImage || {}; + localDisplayConfig.value.subtitleImage.src = '/completed_performance.png'; +}; + // 刷新数据 const handleRefreshData = () => { try { diff --git a/src/views/BattleRanking.vue b/src/views/BattleRanking.vue index 101a998..168055d 100644 --- a/src/views/BattleRanking.vue +++ b/src/views/BattleRanking.vue @@ -44,10 +44,12 @@
-

总战绩

+
+ 总战绩 +
- {{ localDisplayConfig.team?.totalScoreColumn?.displayStyle === 'amount' ? '¥' : '' }}{{ totalTeamScore }} + {{ localDisplayConfig.team?.totalScoreColumn?.displayStyle === 'amount' ? '¥' : '' }}{{ totalTeamScore }}
@@ -224,6 +226,12 @@ function createDefaultDisplayConfig() { individualChampion: '', individualChampionSize: 60 }, + subtitleImage: { + src: '/completed_performance.png', + width: 200, + height: 60, + alt: '总战绩' + }, individual: { scoreColumn: { displayName: '业绩', @@ -237,7 +245,7 @@ function createDefaultDisplayConfig() { showBonus: false, showTeam: true, // 默认显示战区列 showAvatar: false, // 默认不显示头像列 - defaultDisplayRows: 10, // 默认显示10行 + defaultDisplayRows: 0, // 默认显示所有行 filterZeroScore: false, // 默认不过滤业绩为0的记录 columnWidths: { team: 120 // 默认战区列宽 @@ -419,30 +427,75 @@ onBeforeMount(async () => { } }); -// 定义每行默认高度 -const tableRowHeight = 50; +// 定义英雄排名表中每行默认高度 +const tableIndividualTopThreeHeight = 3 * 47.5; // 前三名高度px +const tableIndividualRowHeight = 34.5; // 其他行高度px +const tableIndividualReserveHeight = 20; // 保留空间高度px + + // 更新CSS变量,将默认显示行数传递给样式 watch( () => localDisplayConfig.value?.individual?.defaultDisplayRows, - (newRows) => { - document.documentElement.style.setProperty('--default-display-rows', newRows); + (newValue) => { + if (newValue && newValue > 0) { + const otherRowsHeight = (newValue - 3) * tableIndividualRowHeight; + const actualHeight = tableIndividualTopThreeHeight + otherRowsHeight + tableIndividualReserveHeight; + document.documentElement.style.setProperty('--individual-default-height', `${actualHeight}px`); + document.documentElement.style.setProperty('--individual-overflow-y', 'auto'); + document.documentElement.style.setProperty('--individual-overflow-x', 'auto'); + document.documentElement.style.setProperty('--individual-scroll-lock', ''); + } else { + // 根据实际数据条数计算高度 + const otherRowsHeight = (filteredIndividualRankings.value.length - 3) * tableIndividualRowHeight; + const actualHeight = tableIndividualTopThreeHeight + otherRowsHeight + tableIndividualReserveHeight; + document.documentElement.style.setProperty('--individual-default-height', `${actualHeight}px`); + document.documentElement.style.setProperty('--individual-overflow-y', 'hidden'); + document.documentElement.style.setProperty('--individual-overflow-x', 'hidden'); + document.documentElement.style.setProperty('--individual-scroll-lock', 'lock'); + } }, { immediate: true } ); +// 当英雄排名数据变化时,重新计算高度(如果当前是显示所有行模式) +watch( + () => filteredIndividualRankings.value.length, + () => { + console.log('filteredIndividualRankings.value.length', filteredIndividualRankings.value.length); + const displayRows = localDisplayConfig.value?.individual?.defaultDisplayRows; + if (!displayRows || displayRows === 0) { + // 根据实际数据条数计算高度 + const otherRowsHeight = (filteredIndividualRankings.value.length - 3) * tableIndividualRowHeight; + const actualHeight = tableIndividualTopThreeHeight + otherRowsHeight + tableIndividualReserveHeight; + document.documentElement.style.setProperty('--individual-default-height', `${actualHeight}px`); + document.documentElement.style.setProperty('--individual-overflow-y', 'hidden'); + document.documentElement.style.setProperty('--individual-overflow-x', 'hidden'); + document.documentElement.style.setProperty('--individual-scroll-lock', 'lock'); + } + } +); + +// 定义战区排名表中每行默认高度 +const tableTeamTopThreeHeight = 3 * 48; // 前三名高度px +const tableTeamRowHeight = 48; // 其他行高度px +const tableTeamReserveHeight = 20; // 保留空间高度px + // 添加监听以同步战区排名默认显示行数配置到CSS变量 watch( () => localDisplayConfig.value?.team?.defaultDisplayRows, (newValue) => { if (newValue && newValue > 0) { - document.documentElement.style.setProperty('--team-default-height', `calc(${tableRowHeight}px * ${newValue})`); + const otherRowsHeight = (newValue - 3) * tableTeamRowHeight; + const actualHeight = tableTeamTopThreeHeight + otherRowsHeight + tableTeamReserveHeight; + document.documentElement.style.setProperty('--team-default-height', `${actualHeight}px`); document.documentElement.style.setProperty('--team-overflow-y', 'auto'); document.documentElement.style.setProperty('--team-overflow-x', 'auto'); document.documentElement.style.setProperty('--team-scroll-lock', ''); } else { - // 根据实际数据条数计算高度,每行tableRowHeight,加上一些额外空间(20px) - const actualHeight = teamRankings.value.length * tableRowHeight + 20; + // 根据实际数据条数计算高度 + const otherRowsHeight = (teamRankings.value.length - 3) * tableTeamRowHeight; + const actualHeight = tableTeamTopThreeHeight + otherRowsHeight + tableTeamReserveHeight; document.documentElement.style.setProperty('--team-default-height', `${actualHeight}px`); document.documentElement.style.setProperty('--team-overflow-y', 'hidden'); document.documentElement.style.setProperty('--team-overflow-x', 'hidden'); @@ -458,8 +511,9 @@ watch( () => { const displayRows = localDisplayConfig.value?.team?.defaultDisplayRows; if (!displayRows || displayRows === 0) { - // 根据实际数据条数计算高度,每行tableRowHeight,加上一些额外空间(20px) - const actualHeight = teamRankings.value.length * tableRowHeight + 20; + // 根据实际数据条数计算高度 + const otherRowsHeight = (teamRankings.value.length - 3) * tableTeamRowHeight; + const actualHeight = tableTeamTopThreeHeight + otherRowsHeight + tableTeamReserveHeight; document.documentElement.style.setProperty('--team-default-height', `${actualHeight}px`); document.documentElement.style.setProperty('--team-overflow-y', 'hidden'); document.documentElement.style.setProperty('--team-overflow-x', 'hidden'); @@ -468,6 +522,24 @@ watch( } ); +// 监听冠军字体大小配置变化,更新CSS变量 +watch( + () => localDisplayConfig.value?.championLogos, + (newConfig) => { + if (newConfig) { + // 设置战区冠军字体大小 + if (newConfig.teamChampionFontSize) { + document.documentElement.style.setProperty('--team-champion-font-size', newConfig.teamChampionFontSize + 'rem'); + } + // 设置英雄冠军字体大小 + if (newConfig.individualChampionFontSize) { + document.documentElement.style.setProperty('--individual-champion-font-size', newConfig.individualChampionFontSize + 'rem'); + } + } + }, + { immediate: true, deep: true } +); + // 确保奖金规则有默认值 const displayBonusRules = computed(() => { return Array.isArray(bonusRules) && bonusRules.length > 0 @@ -1132,11 +1204,16 @@ onUnmounted(() => { } .champion-name { - font-size: 1.8rem; + font-size: var(--individual-champion-font-size, 1.8rem); font-weight: bold; color: gold; } +/* 战区冠军名称特殊样式 */ +.team-champion .champion-name { + font-size: var(--team-champion-font-size, 1.8rem); +} + /* 基础样式 */ :root { --gold-primary: #ffd700; @@ -1195,6 +1272,11 @@ onUnmounted(() => { /* 响应式设计 */ @media (max-width: 768px) { + .total-score-total-image { + width: 320px; + } + + /** 皇冠动画 */ .crown-animation { top: -120px; @@ -1655,8 +1737,6 @@ onUnmounted(() => { .rank-table { border-radius: 10px; overflow: hidden; - min-height: 480px; - max-height: 480px; overflow-y: auto; position: relative; margin-top: 0.8rem; @@ -1817,10 +1897,26 @@ onUnmounted(() => { } .score-value { - font-size: 3.6rem; + font-size: calc(var(--individual-champion-font-size, 2.4rem) * 2); font-weight: bold; - color: var(--gold-primary); - text-shadow: 0 0 10px rgba(255, 215, 0, 0.5); + color: #fff2c4; + text-shadow: + 0 0 10px rgba(255, 215, 0, 0.5), + 0 0 20px rgba(255, 215, 0, 0.3), + 1px 1px 2px rgba(0, 0, 0, 0.8); +} + +.total-score-total-value { + margin-top: -40px; +} + +/* 战区冠军分数特殊样式 */ +.team-champion .score-value { + font-size: calc(var(--team-champion-font-size, 1.8rem) * 2); + text-shadow: + 0 0 15px rgba(255, 215, 0, 0.7), + 0 0 30px rgba(255, 215, 0, 0.4), + 2px 2px 3px rgba(0, 0, 0, 0.9); } /* 照片容器样式 */ @@ -1838,6 +1934,12 @@ onUnmounted(() => { } @media (max-width: 768px) { + + .total-score-total-title { + align-items: center; + display: flex; + justify-content: center; + } /* 战区排名容器设置 - 根据配置决定显示行数和滚动行为 */ .team-rankings-container .rank-table { @@ -1871,17 +1973,37 @@ onUnmounted(() => { margin-top: 60px; /* 增加排名列表的顶部间距 */ } - /* 英雄排名容器设置 - 显示所有行,与战区排名保持一致 */ + /* 英雄排名容器设置 - 根据配置决定显示行数和滚动行为 */ .individual-rankings-container .rank-table { - overflow-y: hidden; - overflow-x: auto; /* 允许水平滚动 */ position: relative; - height: auto !important; /* 自动高度,显示所有行 */ + min-height: auto; + /* 如果配置了具体了默认显示行数,则设置高度和滚动,否则显示所有行 */ + height: var(--individual-default-height, auto) !important; + overflow-y: var(--individual-overflow-y, hidden); + overflow-x: var(--individual-overflow-x, auto); /* 隐藏滚动条 */ -ms-overflow-style: none; scrollbar-width: none; } + /* 当设置了滚动锁定时,禁止所有滚动 */ + :root[style*="--individual-scroll-lock: lock"] .individual-rankings-container .rank-table { + overflow-y: hidden !important; + overflow-x: hidden !important; + height: var(--individual-default-height, auto) !important; + min-width: auto !important; + width: 100% !important; + } + + /* 确保表格内容在锁定模式下正确显示 */ + :root[style*="--individual-scroll-lock: lock"] .individual-rankings-container .rank-table .table-header, + :root[style*="--individual-scroll-lock: lock"] .individual-rankings-container .rank-table .table-row { + min-width: auto !important; + width: 100% !important; + overflow-x: visible !important; + white-space: normal !important; + } + /* 移动端非前三名字体放大 */ .team-rankings-container .table-row:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3)), .individual-rankings-container .table-row:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3)) { @@ -2101,19 +2223,30 @@ onUnmounted(() => { display: none; } - /* 英雄排名列表设置 - 显示所有行 */ - .individual-rankings-container .rank-table { - overflow-x: hidden !important; - /* 禁止横向滚动 */ - overflow-y: hidden !important; - /* 不允许纵向滚动,显示所有行 */ - height: auto !important; - /* 确保英雄排名列表隐藏滚动条 */ - -ms-overflow-style: none; - scrollbar-width: none; - display: flex; - flex-direction: column; - } + /* 英雄排名列表设置 - 根据配置决定显示行数和滚动行为 */ + .individual-rankings-container .rank-table { + overflow-x: hidden !important; + /* 禁止横向滚动 */ + height: var(--individual-default-height, auto) !important; + overflow-y: var(--individual-overflow-y, auto) !important; + /* 确保英雄排名列表隐藏滚动条 */ + -ms-overflow-style: none; + scrollbar-width: none; + display: flex; + flex-direction: column; + } + + /* 当设置了滚动锁定时,禁止所有滚动 */ + :root[style*="--individual-scroll-lock: lock"] .individual-rankings-container { + overflow: visible !important; + height: auto !important; + } + + :root[style*="--individual-scroll-lock: lock"] .individual-rankings-container .rank-table { + overflow: hidden !important; + white-space: nowrap; + display: block; + } .individual-rankings-container .rank-table::-webkit-scrollbar { display: none; diff --git a/uploads/1763860106271.jpg b/uploads/1763860106271.jpg new file mode 100644 index 0000000..c9bf9af Binary files /dev/null and b/uploads/1763860106271.jpg differ diff --git a/uploads/1763956859312.jpg b/uploads/1763956859312.jpg new file mode 100644 index 0000000..6818653 Binary files /dev/null and b/uploads/1763956859312.jpg differ diff --git a/uploads/1763972044872.jpg b/uploads/1763972044872.jpg new file mode 100644 index 0000000..2218650 Binary files /dev/null and b/uploads/1763972044872.jpg differ diff --git a/uploads/1763979489455.png b/uploads/1763979489455.png new file mode 100644 index 0000000..88b8774 Binary files /dev/null and b/uploads/1763979489455.png differ