From afd5323ade372095936e71d1a53926508124c9db Mon Sep 17 00:00:00 2001 From: Kunagisa <1549184870@qq.com> Date: Sun, 3 Aug 2025 13:53:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E8=B4=A5=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DoubleEliminationBracket.vue | 117 ++------------------ src/components/TournamentBracket.vue | 12 +- src/views/index.vue | 1 - 3 files changed, 13 insertions(+), 117 deletions(-) diff --git a/src/components/DoubleEliminationBracket.vue b/src/components/DoubleEliminationBracket.vue index 2be3896..790126c 100644 --- a/src/components/DoubleEliminationBracket.vue +++ b/src/components/DoubleEliminationBracket.vue @@ -2,43 +2,6 @@

双败淘汰赛赛程树状图

- -
-
-
- 当前比赛: {{ tournament.name || '加载中...' }} -
-
- -

参赛者列表

-
-
加载中...
-
-

暂无参赛者

- -
-
- -

生成赛程

- - -
-

最终排名

-

🏆 冠军: {{ champion }}

-

🥈 亚军: {{ runnerUp }}

-

🥉 季军: {{ thirdPlace }}

-
-
-
@@ -145,9 +108,7 @@ let winnerssvgSelection = null; let losersZoomBehavior = null; let loserssvgSelection = null; -const canGenerateBracket = computed(() => { - return participants.value.length >= 4; -}); + onMounted(() => { loadTournamentData(); @@ -155,7 +116,6 @@ onMounted(() => { // Add keyboard shortcuts for zoom control const handleKeydown = (event) => { if (event.target.tagName === 'INPUT') return; - switch(event.key) { case '+': case '=': @@ -220,6 +180,11 @@ const loadTournamentData = async () => { qq_code: item.qq_code || '', status: item.status || '' })); + + // 数据加载完成后自动生成赛程 + if (participants.value.length >= 4) { + generateDoubleEliminationBracket(); + } } catch (err) { console.error('获取比赛数据失败:', err); } finally { @@ -248,21 +213,17 @@ const generateDoubleEliminationBracket = () => { while (shuffledParticipants.length < totalSlots) { shuffledParticipants.push(null); } - console.log(`总参赛者: ${totalPlayers}, 总槽位: ${totalSlots}`); - // 生成胜者组第一轮 const winnersRound1 = []; for (let i = 0; i < totalSlots; i += 2) { const p1 = shuffledParticipants[i]; const p2 = shuffledParticipants[i + 1]; - // 处理轮空情况 let winner = null; let decided = false; let score1 = 0; let score2 = 0; - if (p1 && !p2) { // p1轮空直接晋级 winner = p1; @@ -297,7 +258,6 @@ const generateDoubleEliminationBracket = () => { }); } winnersBracket.value = [winnersRound1]; - // 预生成胜者组的所有轮次结构 let currentRoundSize = Math.ceil(totalSlots / 2); while (currentRoundSize > 1) { @@ -318,12 +278,9 @@ const generateDoubleEliminationBracket = () => { winnersBracket.value.push(nextRound); } } - console.log(`胜者组轮次数: ${winnersBracket.value.length}`); - // 预生成败者组结构 generateLosersBracketStructure(totalPlayers); - // 处理第一轮的轮空晋级 winnersRound1.forEach((match, index) => { if (match.decided && match.winner) { @@ -370,11 +327,9 @@ const generateLosersBracketStructure = (totalPlayers) => { for (let round = 0; round < losersRounds; round++) { const roundMatches = []; let matchCount = 1; - // 败者组比赛数量规律: // LR1: 1场 (胜者组第1轮败者们对战,但要考虑轮空) // LR2: 1场 (LR1胜者 vs 胜者组第2轮败者) - if (round === 0) { // 第一轮败者组:计算实际的败者数量 const firstRoundLosers = Math.floor(totalPlayers / 2); // 第一轮实际对战产生的败者数 @@ -387,10 +342,8 @@ const generateLosersBracketStructure = (totalPlayers) => { } else { matchCount = 1; // 其他轮次通常是1场 } - // 确保至少有0场比赛(可能某轮不需要比赛) matchCount = Math.max(0, matchCount); - if (matchCount > 0) { for (let i = 0; i < matchCount; i++) { roundMatches.push({ @@ -430,7 +383,6 @@ const drawD3LosersBracket = () => { drawD3Bracket(svg, losersBracket.value, 'losersBracketContainer', 'losers'); }; - // Generic D3.js bracket drawing function const drawD3Bracket = (svg, bracket, containerId, bracketType) => { const margin = { top: 40, right: 40, bottom: 40, left: 40 }; @@ -1134,37 +1086,8 @@ h1 { min-height: 500px; } -.control-panel { - flex: 1; - min-width: 280px; - background: #f0f0f0; - padding: 15px; - border-radius: 6px; - height: 100%; - box-sizing: border-box; -} - -.tournament-info { - margin-bottom: 15px; - padding: 10px; - background: #e6f7ff; - border-radius: 4px; -} - -.control-panel h2 { - color: #1a237e; - font-size: 1.2rem; - font-weight: 600; - margin: 20px 0 10px 0; -} - -.loading { - color: #666; - font-style: italic; -} - .bracket-main { - flex: 3; + flex: 1; display: flex; flex-direction: column; gap: 20px; @@ -1336,31 +1259,5 @@ button:hover:not(:disabled) { background: #66b1ff; } -.final-ranking { - background: #fffbdb; - border: 1px solid #f0e68c; - padding: 15px; - border-radius: 6px; - margin-top: 20px; -} -.final-ranking h3 { - margin-top: 0; - color: #b8860b; -} - -.final-ranking p { - margin: 5px 0; - font-size: 16px; -} - -ul { - padding-left: 20px; - margin: 0 0 10px 0; -} - -li { - margin-bottom: 4px; - list-style: disc; -} \ No newline at end of file diff --git a/src/components/TournamentBracket.vue b/src/components/TournamentBracket.vue index 07f3490..662d80e 100644 --- a/src/components/TournamentBracket.vue +++ b/src/components/TournamentBracket.vue @@ -291,18 +291,18 @@ const generateRoundMatches = async (round, roundData) => { // 处理已有数据的比赛 for (const player of roundData) { - if (usedPlayers.has(player.id)) { + if (usedPlayers.has(player.id)) { console.log(`玩家 ${player.sign_name} (ID: ${player.id}) 已被使用,跳过`); - continue; - } + continue; + } const rivalName = player.rival_name; const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye'; const isPending = rivalName === '待定' || rivalName === 'pending' || rivalName === 'PENDING' || rivalName === 'Pending'; - if (isBye || isPending) { + if (isBye || isPending) { console.log(`玩家 ${player.sign_name} 的对手是 ${rivalName},跳过正常比赛处理`); - continue; + continue; } // 寻找对手 @@ -665,7 +665,7 @@ const matchOpponentsInRound = async (round) => { } else { console.log(`第${round}轮待定玩家数量为${roundData.length},无法匹配`); } - } catch (error) { + } catch (error) { console.error(`匹配第${round}轮对手失败:`, error); } }; diff --git a/src/views/index.vue b/src/views/index.vue index 611dd92..dc0e8a1 100644 --- a/src/views/index.vue +++ b/src/views/index.vue @@ -366,7 +366,6 @@ function handlePasswordChangeError(errorMessage) { 赛程信息
-