单败重构
This commit is contained in:
@@ -73,7 +73,7 @@ const fetchRankData = async () => {
|
||||
if (!playerStats[playerName]) {
|
||||
playerStats[playerName] = {
|
||||
username: playerName,
|
||||
faction: player.faction || player.team_name || '',
|
||||
faction: player.faction || player.team_name || '',
|
||||
totalWin: 0,
|
||||
totalLose: 0,
|
||||
totalPoints: 0,
|
||||
@@ -113,7 +113,7 @@ const fetchRankData = async () => {
|
||||
bracket_type: 'winners',
|
||||
score: `${player.totalWin}胜${player.totalLose}负 (${player.totalPoints.toFixed(1)}分)`,
|
||||
rounds: player.rounds.join(',')
|
||||
}))
|
||||
}))
|
||||
|
||||
console.log('RankContestant 最终排名结果:', sortedPlayers)
|
||||
rankData.value = sortedPlayers
|
||||
|
||||
@@ -165,16 +165,16 @@ const generateSingleEliminationBracket = async () => {
|
||||
// 获取所有存在的轮次
|
||||
const existingRounds = Object.keys(roundsData).map(Number).sort((a, b) => a - b);
|
||||
console.log('存在的轮次:', existingRounds);
|
||||
|
||||
|
||||
// 生成所有轮次的比赛
|
||||
for (const round of existingRounds) {
|
||||
if (round === 0) {
|
||||
if (round === 0) {
|
||||
await generateRound0Matches(roundsData[round] || []);
|
||||
} else {
|
||||
} else {
|
||||
await generateRoundMatches(round, roundsData[round] || []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 更新总轮数为实际存在的最大轮次
|
||||
if (existingRounds.length > 0) {
|
||||
tournament.value.rounds = Math.max(...existingRounds);
|
||||
@@ -182,131 +182,176 @@ const generateSingleEliminationBracket = async () => {
|
||||
};
|
||||
|
||||
const generateRound0Matches = async (round0Data) => {
|
||||
const matches = [];
|
||||
const usedPlayers = new Set();
|
||||
|
||||
const matches = [];
|
||||
const usedPlayers = new Set();
|
||||
|
||||
// 处理正常配对
|
||||
for (const player of round0Data) {
|
||||
if (usedPlayers.has(player.id)) 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 (usedPlayers.has(player.id)) 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) continue;
|
||||
|
||||
// 寻找对手
|
||||
// 寻找对手
|
||||
const rival = round0Data.find(p =>
|
||||
p.sign_name === rivalName && p.id !== player.id && !usedPlayers.has(p.id)
|
||||
);
|
||||
|
||||
if (rival) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
p.sign_name === rivalName && p.id !== player.id && !usedPlayers.has(p.id)
|
||||
);
|
||||
|
||||
if (rival) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
id: `0-${matchNumber}`,
|
||||
round: 0,
|
||||
matchNumber: matchNumber,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: { id: rival.id, name: rival.sign_name },
|
||||
winner: null,
|
||||
score1: parseInt(player.win || 0),
|
||||
score2: parseInt(rival.win || 0),
|
||||
decided: false
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
usedPlayers.add(rival.id);
|
||||
}
|
||||
}
|
||||
|
||||
winner: null,
|
||||
score1: parseInt(player.win || 0),
|
||||
score2: parseInt(rival.win || 0),
|
||||
decided: false
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
usedPlayers.add(rival.id);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理轮空
|
||||
for (const player of round0Data) {
|
||||
if (usedPlayers.has(player.id)) continue;
|
||||
|
||||
const rivalName = player.rival_name;
|
||||
const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
|
||||
|
||||
if (isBye) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
if (usedPlayers.has(player.id)) continue;
|
||||
|
||||
const rivalName = player.rival_name;
|
||||
const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
|
||||
|
||||
if (isBye) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
id: `0-${matchNumber}`,
|
||||
round: 0,
|
||||
matchNumber: matchNumber,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: null,
|
||||
participant2: null,
|
||||
winner: { id: player.id, name: player.sign_name },
|
||||
score1: 1,
|
||||
score2: 0,
|
||||
decided: true
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
}
|
||||
}
|
||||
|
||||
tournament.value.matches.push(...matches);
|
||||
score1: 1,
|
||||
score2: 0,
|
||||
decided: true
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
}
|
||||
}
|
||||
|
||||
tournament.value.matches.push(...matches);
|
||||
};
|
||||
|
||||
const generateRoundMatches = async (round, roundData) => {
|
||||
const matches = [];
|
||||
const usedPlayers = new Set();
|
||||
|
||||
const matches = [];
|
||||
const usedPlayers = new Set();
|
||||
|
||||
console.log(`生成第${round}轮比赛,数据:`, roundData);
|
||||
console.log(`第${round}轮详细数据:`, roundData.map(p => ({
|
||||
id: p.id,
|
||||
sign_name: p.sign_name,
|
||||
rival_name: p.rival_name,
|
||||
status: p.status,
|
||||
win: p.win,
|
||||
lose: p.lose
|
||||
})));
|
||||
|
||||
// 处理已有数据的比赛
|
||||
for (const player of roundData) {
|
||||
if (usedPlayers.has(player.id)) 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) continue;
|
||||
|
||||
// 寻找对手
|
||||
const rival = roundData.find(p =>
|
||||
p.sign_name === rivalName && p.id !== player.id && !usedPlayers.has(p.id)
|
||||
);
|
||||
|
||||
if (rival) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
id: `${round}-${matchNumber}`,
|
||||
round: round,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: { id: rival.id, name: rival.sign_name },
|
||||
winner: null,
|
||||
score1: parseInt(player.win || 0),
|
||||
score2: parseInt(rival.win || 0),
|
||||
decided: false
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
usedPlayers.add(rival.id);
|
||||
if (usedPlayers.has(player.id)) {
|
||||
console.log(`玩家 ${player.sign_name} (ID: ${player.id}) 已被使用,跳过`);
|
||||
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) {
|
||||
console.log(`玩家 ${player.sign_name} 的对手是 ${rivalName},跳过正常比赛处理`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 寻找对手
|
||||
const rival = roundData.find(p =>
|
||||
p.sign_name === rivalName && p.id !== player.id && !usedPlayers.has(p.id)
|
||||
);
|
||||
|
||||
if (rival) {
|
||||
const matchNumber = matches.length + 1;
|
||||
|
||||
// 判断比赛是否已完成
|
||||
const playerStatus = player.status;
|
||||
const rivalStatus = rival.status;
|
||||
const playerWin = parseInt(player.win || 0);
|
||||
const rivalWin = parseInt(rival.win || 0);
|
||||
|
||||
// 如果任一玩家有胜场,说明比赛已完成
|
||||
const isDecided = playerWin > 0 || rivalWin > 0 ||
|
||||
playerStatus === 'win' || playerStatus === 'lose' ||
|
||||
rivalStatus === 'win' || rivalStatus === 'lose';
|
||||
|
||||
// 确定获胜者
|
||||
let winner = null;
|
||||
if (playerStatus === 'win' || playerWin > rivalWin) {
|
||||
winner = { id: player.id, name: player.sign_name };
|
||||
} else if (rivalStatus === 'win' || rivalWin > playerWin) {
|
||||
winner = { id: rival.id, name: rival.sign_name };
|
||||
}
|
||||
|
||||
console.log(`创建比赛 ${matchNumber}: ${player.sign_name} vs ${rival.sign_name}`, {
|
||||
playerStatus,
|
||||
rivalStatus,
|
||||
isDecided,
|
||||
winner: winner?.name,
|
||||
playerData: { id: player.id, name: player.sign_name, status: player.status, win: player.win, lose: player.lose },
|
||||
rivalData: { id: rival.id, name: rival.sign_name, status: rival.status, win: rival.win, lose: rival.lose }
|
||||
});
|
||||
|
||||
matches.push({
|
||||
id: `${round}-${matchNumber}`,
|
||||
round: round,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: { id: rival.id, name: rival.sign_name },
|
||||
winner: winner,
|
||||
score1: parseInt(player.win || 0),
|
||||
score2: parseInt(rival.win || 0),
|
||||
decided: isDecided
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
usedPlayers.add(rival.id);
|
||||
} else {
|
||||
console.log(`未找到玩家 ${player.sign_name} 的对手 ${rivalName}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理轮空
|
||||
for (const player of roundData) {
|
||||
if (usedPlayers.has(player.id)) continue;
|
||||
|
||||
const rivalName = player.rival_name;
|
||||
const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
|
||||
|
||||
if (isBye) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
id: `${round}-${matchNumber}`,
|
||||
round: round,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: null,
|
||||
winner: { id: player.id, name: player.sign_name },
|
||||
score1: 1,
|
||||
score2: 0,
|
||||
decided: true
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
}
|
||||
}
|
||||
|
||||
const rivalName = player.rival_name;
|
||||
const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
|
||||
|
||||
if (isBye) {
|
||||
const matchNumber = matches.length + 1;
|
||||
matches.push({
|
||||
id: `${round}-${matchNumber}`,
|
||||
round: round,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: null,
|
||||
winner: { id: player.id, name: player.sign_name },
|
||||
score1: 1,
|
||||
score2: 0,
|
||||
decided: true
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理待定的玩家(单独显示)
|
||||
for (const player of roundData) {
|
||||
@@ -317,43 +362,84 @@ const generateRoundMatches = async (round, roundData) => {
|
||||
|
||||
if (isPending) {
|
||||
const matchNumber = matches.length + 1;
|
||||
|
||||
// 判断比赛是否已完成(如果玩家状态是win或lose,或者有胜场,说明比赛已完成)
|
||||
const playerWin = parseInt(player.win || 0);
|
||||
const isDecided = player.status === 'win' || player.status === 'lose' || playerWin > 0;
|
||||
let winner = null;
|
||||
if (player.status === 'win' || playerWin > 0) {
|
||||
winner = { id: player.id, name: player.sign_name };
|
||||
}
|
||||
|
||||
console.log(`创建待定比赛 ${matchNumber}: ${player.sign_name} vs 待定`, {
|
||||
playerStatus: player.status,
|
||||
isDecided,
|
||||
winner: winner?.name
|
||||
});
|
||||
|
||||
matches.push({
|
||||
id: `${round}-${matchNumber}`,
|
||||
round: round,
|
||||
matchNumber: matchNumber,
|
||||
participant1: { id: player.id, name: player.sign_name },
|
||||
participant2: null,
|
||||
winner: null,
|
||||
winner: winner,
|
||||
score1: parseInt(player.win || 0),
|
||||
score2: 0,
|
||||
decided: false
|
||||
decided: isDecided
|
||||
});
|
||||
usedPlayers.add(player.id);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`第${round}轮生成比赛:`, matches);
|
||||
tournament.value.matches.push(...matches);
|
||||
tournament.value.matches.push(...matches);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 检查比赛顺序是否合法
|
||||
const isMatchOrderValid = (match) => {
|
||||
console.log('检查比赛顺序:', {
|
||||
matchId: match.id,
|
||||
round: match.round,
|
||||
matchNumber: match.matchNumber
|
||||
});
|
||||
|
||||
const currentRoundMatches = tournament.value.matches
|
||||
.filter(m => m.round === match.round)
|
||||
.sort((a, b) => a.matchNumber - b.matchNumber);
|
||||
|
||||
console.log('当前轮次所有比赛:', currentRoundMatches.map(m => ({
|
||||
id: m.id,
|
||||
matchNumber: m.matchNumber,
|
||||
decided: m.decided,
|
||||
participant1: m.participant1?.name,
|
||||
participant2: m.participant2?.name,
|
||||
winner: m.winner?.name,
|
||||
score1: m.score1,
|
||||
score2: m.score2
|
||||
})));
|
||||
|
||||
const currentMatchIndex = currentRoundMatches.findIndex(m => m.id === match.id);
|
||||
console.log('当前比赛索引:', currentMatchIndex);
|
||||
|
||||
// 检查是否有更小编号的比赛未完成
|
||||
for (let i = 0; i < currentMatchIndex; i++) {
|
||||
const previousMatch = currentRoundMatches[i];
|
||||
console.log(`检查第${i + 1}场比赛:`, {
|
||||
id: previousMatch.id,
|
||||
matchNumber: previousMatch.matchNumber,
|
||||
decided: previousMatch.decided
|
||||
});
|
||||
|
||||
if (!previousMatch.decided) {
|
||||
console.log(`第${previousMatch.matchNumber}场比赛未完成,阻止进行第${match.matchNumber}场比赛`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('比赛顺序验证通过');
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -474,6 +560,14 @@ const handlePlayerAdvancement = async (match) => {
|
||||
};
|
||||
|
||||
const confirmScore = async (match) => {
|
||||
console.log('确认比分,比赛信息:', {
|
||||
id: match.id,
|
||||
round: match.round,
|
||||
matchNumber: match.matchNumber,
|
||||
participant1: match.participant1?.name,
|
||||
participant2: match.participant2?.name
|
||||
});
|
||||
|
||||
// 检查比赛顺序
|
||||
if (!isMatchOrderValid(match)) {
|
||||
const currentRoundMatches = tournament.value.matches
|
||||
@@ -483,6 +577,12 @@ const confirmScore = async (match) => {
|
||||
const currentMatchIndex = currentRoundMatches.findIndex(m => m.id === match.id);
|
||||
const previousMatch = currentRoundMatches[currentMatchIndex - 1];
|
||||
|
||||
console.log('比赛顺序验证失败,阻止的比赛:', {
|
||||
currentMatch: match.matchNumber,
|
||||
previousMatch: previousMatch?.matchNumber,
|
||||
previousMatchId: previousMatch?.id
|
||||
});
|
||||
|
||||
errorDialog.value = {
|
||||
visible: true,
|
||||
message: `请先完成第${previousMatch.matchNumber}场比赛`
|
||||
@@ -531,16 +631,16 @@ const confirmScore = async (match) => {
|
||||
await addSignUpResult(newRecord);
|
||||
console.log(`轮空玩家 ${p1Data.sign_name} 晋级到第${nextRound}轮`);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error) {
|
||||
console.error('处理轮空晋级失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
nextTick(() => drawD3Bracket());
|
||||
await loadTournamentData();
|
||||
emit('refreshPlayers');
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 验证比分
|
||||
const s1 = Number(match.score1);
|
||||
const s2 = Number(match.score2);
|
||||
@@ -670,9 +770,9 @@ const drawD3Bracket = () => {
|
||||
const roundMatches = tournament.value.matches
|
||||
.filter(m => m.round === round)
|
||||
.sort((a, b) => a.matchNumber - b.matchNumber);
|
||||
|
||||
|
||||
console.log(`绘制第${round}轮比赛:`, roundMatches);
|
||||
|
||||
|
||||
const matchesInRound = roundMatches.length;
|
||||
const roundX = round * (matchWidth + roundGap);
|
||||
const roundStartY = (maxMatchesInRound * (matchHeight + matchGap) - matchesInRound * (matchHeight + matchGap)) / 2;
|
||||
|
||||
@@ -49,13 +49,15 @@ const routes = [
|
||||
path: 'weapon-match',
|
||||
name: 'WeaponMatch',
|
||||
component: () => import('@/views/weapon/WeaponMatch.vue'),
|
||||
meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-mod'] }
|
||||
// meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-mod'] }
|
||||
meta: { requiresAuth: true}
|
||||
},
|
||||
{
|
||||
path: 'configEditor',
|
||||
name: 'ConfigEditor',
|
||||
component: () => import('@/views/index/ConfigEditor.vue'),
|
||||
meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-mod'] }
|
||||
// meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-mod'] }
|
||||
meta: { requiresAuth: true}
|
||||
},
|
||||
{
|
||||
path: 'competition',
|
||||
@@ -102,13 +104,13 @@ const routes = [
|
||||
path: 'PIC2TGA',
|
||||
name: 'PIC2TGA',
|
||||
component: () => import('@/views/index/PIC2TGA.vue'),
|
||||
meta: { requiredPrivilege: ['lv-admin','lv-mod','lv-map','lv-competitor'] }
|
||||
// meta: { requiredPrivilege: ['lv-admin','lv-mod','lv-map','lv-competitor'] }
|
||||
},
|
||||
{
|
||||
path: 'terrainGenerate',
|
||||
name: 'TerrainGenerate',
|
||||
component: () => import('@/views/index/TerrainGenerate.vue'),
|
||||
meta: { requiredPrivilege: ['lv-admin','lv-mod','lv-map','lv-competitor'] }
|
||||
// meta: { requiredPrivilege: ['lv-admin','lv-mod','lv-map','lv-competitor'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -437,12 +437,12 @@ function handlePasswordChangeError(errorMessage) {
|
||||
:message="errorDialogMessage"
|
||||
@close="errorDialogVisible = false"
|
||||
/>
|
||||
<PrivilegeRequestDialog
|
||||
:visible="privilegeDialogVisible"
|
||||
:privilegeName="privilegeDialogName"
|
||||
@close="privilegeDialogVisible = false"
|
||||
@apply="handlePrivilegeApply"
|
||||
/>
|
||||
<!-- <PrivilegeRequestDialog-->
|
||||
<!-- :visible="privilegeDialogVisible"-->
|
||||
<!-- :privilegeName="privilegeDialogName"-->
|
||||
<!-- @close="privilegeDialogVisible = false"-->
|
||||
<!-- @apply="handlePrivilegeApply"-->
|
||||
<!-- />-->
|
||||
<SuccessDialog
|
||||
:visible="successDialog.visible"
|
||||
:message="successDialog.message"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user