You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于jQuery Bracket生成世界杯式8组循环赛及数据库存储指南问询

基于jQuery Bracket复刻世界杯赛制教程

一、赛制整体说明

世界杯赛制分为两个核心阶段:

  1. 小组赛阶段:8个小组,每组4支球队进行单循环赛(每队与组内其他3队各赛一场),每组前两名晋级淘汰赛。
  2. 淘汰赛阶段:16支晋级球队采用单败淘汰制,对阵规则为小组第一对阵其他小组第二(同小组球队首轮不相遇),直至决出冠军。

二、搭建小组赛阶段

1. HTML结构

添加8个小组的比赛与排名展示区域,以及触发排名计算的按钮:

<div class="group-container">
    <div class="group" id="groupA">
        <h3>A组</h3>
        <table class="group-matches">
            <thead>
                <tr><th>主队</th><th>比分</th><th>客队</th></tr>
            </thead>
            <tbody></tbody>
        </table>
        <table class="group-standings">
            <thead>
                <tr><th>排名</th><th>球队</th><th>场次</th><th>胜</th><th>平</th><th>负</th><th>进球</th><th>失球</th><th>净胜球</th><th>积分</th></tr>
            </thead>
            <tbody></tbody>
        </table>
    </div>
    <!-- 重复B-H组结构,id依次为groupB至groupH -->
</div>
<button id="calculateStandings">计算排名并生成淘汰赛</button>
<div id="knockoutBracket"></div>

2. 初始化小组比赛

在JS中定义各小组球队,并自动生成所有单循环对阵:

$(document).ready(function() {
    // 定义8个小组的参赛球队
    var groupsData = {
        groupA: ['卡塔尔', '厄瓜多尔', '塞内加尔', '荷兰'],
        groupB: ['英格兰', '伊朗', '美国', '威尔士'],
        groupC: ['阿根廷', '沙特阿拉伯', '墨西哥', '波兰'],
        groupD: ['法国', '澳大利亚', '丹麦', '突尼斯'],
        groupE: ['西班牙', '哥斯达黎加', '德国', '日本'],
        groupF: ['比利时', '加拿大', '摩洛哥', '克罗地亚'],
        groupG: ['巴西', '塞尔维亚', '瑞士', '喀麦隆'],
        groupH: ['葡萄牙', '加纳', '乌拉圭', '韩国']
    };

    // 生成单循环对阵的工具函数
    function generateRoundRobinMatches(teams) {
        var matches = [];
        for (var i = 0; i < teams.length; i++) {
            for (var j = i + 1; j < teams.length; j++) {
                matches.push([teams[i], teams[j]]);
            }
        }
        return matches;
    }

    // 为每个小组渲染比赛表格
    $.each(groupsData, function(groupId, teams) {
        var matches = generateRoundRobinMatches(teams);
        var $tbody = $('#' + groupId + ' .group-matches tbody');
        matches.forEach(function(match) {
            var row = `<tr><td>${match[0]}</td><td><input type="number" class="goals" min="0" value="0"> - <input type="number" class="goals" min="0" value="0"></td><td>${match[1]}</td></tr>`;
            $tbody.append(row);
        });
    });
});

3. 计算小组排名

实现符合世界杯规则的排名逻辑(积分优先,净胜球次之,进球数次之):

function calculateGroupStandings(groupId) {
    var teams = groupsData[groupId];
    // 初始化各队数据
    var standings = teams.map(function(team) {
        return {
            name: team,
            played: 0,
            won: 0,
            drawn: 0,
            lost: 0,
            goalsFor: 0,
            goalsAgainst: 0,
            goalDifference: 0,
            points: 0
        };
    });

    // 读取所有比赛结果并更新数据
    var $matches = $('#' + groupId + ' .group-matches tbody tr');
    $matches.each(function() {
        var homeTeam = $(this).find('td:first').text();
        var awayTeam = $(this).find('td:last').text();
        var homeGoals = parseInt($(this).find('.goals:first').val());
        var awayGoals = parseInt($(this).find('.goals:last').val());

        var homeStanding = standings.find(s => s.name === homeTeam);
        var awayStanding = standings.find(s => s.name === awayTeam);

        // 更新场次与进球数据
        homeStanding.played++;
        awayStanding.played++;
        homeStanding.goalsFor += homeGoals;
        homeStanding.goalsAgainst += awayGoals;
        awayStanding.goalsFor += awayGoals;
        awayStanding.goalsAgainst += homeGoals;

        // 更新胜负与积分
        if (homeGoals > awayGoals) {
            homeStanding.won++;
            homeStanding.points += 3;
            awayStanding.lost++;
        } else if (homeGoals === awayGoals) {
            homeStanding.drawn++;
            homeStanding.points += 1;
            awayStanding.drawn++;
            awayStanding.points += 1;
        } else {
            awayStanding.won++;
            awayStanding.points += 3;
            homeStanding.lost++;
        }
    });

    // 计算净胜球并排序
    standings.forEach(function(s) {
        s.goalDifference = s.goalsFor - s.goalsAgainst;
    });
    standings.sort(function(a, b) {
        if (b.points !== a.points) return b.points - a.points;
        if (b.goalDifference !== a.goalDifference) return b.goalDifference - a.goalDifference;
        if (b.goalsFor !== a.goalsFor) return b.goalsFor - a.goalsFor;
        return 0;
    });

    // 更新排名表格
    var $standingsTbody = $('#' + groupId + ' .group-standings tbody');
    $standingsTbody.empty();
    standings.forEach(function(s, index) {
        var row = `<tr><td>${index+1}</td><td>${s.name}</td><td>${s.played}</td><td>${s.won}</td><td>${s.drawn}</td><td>${s.lost}</td><td>${s.goalsFor}</td><td>${s.goalsAgainst}</td><td>${s.goalDifference}</td><td>${s.points}</td></tr>`;
        $standingsTbody.append(row);
    });

    // 返回小组前两名
    return [standings[0].name, standings[1].name];
}

三、搭建淘汰赛阶段

1. 生成淘汰赛对阵

绑定按钮点击事件,计算所有小组排名后生成符合世界杯规则的淘汰赛 bracket:

$('#calculateStandings').click(function() {
    // 获取所有小组的晋级球队
    var groupQualifiers = {
        groupA: calculateGroupStandings('groupA'),
        groupB: calculateGroupStandings('groupB'),
        groupC: calculateGroupStandings('groupC'),
        groupD: calculateGroupStandings('groupD'),
        groupE: calculateGroupStandings('groupE'),
        groupF: calculateGroupStandings('groupF'),
        groupG: calculateGroupStandings('groupG'),
        groupH: calculateGroupStandings('groupH')
    };

    // 按照世界杯规则生成1/8决赛对阵
    var knockoutTeams = [
        [groupQualifiers.groupA[0], groupQualifiers.groupB[1]],
        [groupQualifiers.groupC[0], groupQualifiers.groupD[1]],
        [groupQualifiers.groupE[0], groupQualifiers.groupF[1]],
        [groupQualifiers.groupG[0], groupQualifiers.groupH[1]],
        [groupQualifiers.groupB[0], groupQualifiers.groupA[1]],
        [groupQualifiers.groupD[0], groupQualifiers.groupC[1]],
        [groupQualifiers.groupF[0], groupQualifiers.groupE[1]],
        [groupQualifiers.groupH[0], groupQualifiers.groupG[1]]
    ];

    // 初始化淘汰赛 bracket
    $('#knockoutBracket').bracket({
        init: {
            teams: knockoutTeams,
            results: []
        },
        skipConsolationRound: true,
        onMatchUpdate: function(match) {
            // 比赛结果更新时触发保存逻辑
            saveMatchData(match);
        }
    });

    // 保存小组赛数据
    saveGroupMatches();
});

四、赛事数据保存到数据库

1. 数据库表设计(MySQL示例)

创建两个表分别存储小组赛与淘汰赛数据:

-- 小组赛数据表
CREATE TABLE group_matches (
    id INT AUTO_INCREMENT PRIMARY KEY,
    group_id VARCHAR(10) NOT NULL,
    home_team VARCHAR(50) NOT NULL,
    away_team VARCHAR(50) NOT NULL,
    home_goals INT NOT NULL,
    away_goals INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 淘汰赛数据表
CREATE TABLE knockout_matches (
    id INT AUTO_INCREMENT PRIMARY KEY,
    round INT NOT NULL, -- 1:1/8决赛, 2:1/4决赛, 3:半决赛,4:决赛
    match_index INT NOT NULL,
    home_team VARCHAR(50),
    away_team VARCHAR(50),
    home_goals INT,
    away_goals INT,
    winner VARCHAR(50),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

2. 前端AJAX保存逻辑

编写函数将比赛结果发送至后端:

// 保存所有小组赛数据
function saveGroupMatches() {
    $.each(groupsData, function(groupId, teams) {
        var $matches = $('#' + groupId + ' .group-matches tbody tr');
        $matches.each(function() {
            var homeTeam = $(this).find('td:first').text();
            var awayTeam = $(this).find('td:last').text();
            var homeGoals = parseInt($(this).find('.goals:first').val());
            var awayGoals = parseInt($(this).find('.goals:last').val());

            $.ajax({
                url: 'save_group_match.php',
                method: 'POST',
                data: {
                    group_id: groupId,
                    home_team: homeTeam,
                    away_team: awayTeam,
                    home_goals: homeGoals,
                    away_goals: awayGoals
                },
                success: function() {
                    console.log('小组赛数据保存成功');
                },
                error: function() {
                    console.error('小组赛数据保存失败');
                }
            });
        });
    });
}

// 保存淘汰赛数据
function saveMatchData(match) {
    var round = match.round + 1;
    var matchIndex = match.index;
    var homeTeam = match.team1;
    var awayTeam = match.team2;
    var homeGoals = match.score1;
    var awayGoals = match.score2;
    var winner = homeGoals > awayGoals ? homeTeam : awayTeam;

    $.ajax({
        url: 'save_knockout_match.php',
        method: 'POST',
        data: {
            round: round,
            match_index: matchIndex,
            home_team: homeTeam,
            away_team: awayTeam,
            home_goals: homeGoals,
            away_goals: awayGoals,
            winner: winner
        },
        success: function() {
            console.log('淘汰赛数据保存成功');
        },
        error: function() {
            console.error('淘汰赛数据保存失败');
        }
    });
}

3. 后端处理脚本(PHP示例)

save_group_match.php:

<?php
$conn = new mysqli('localhost', '用户名', '密码', '数据库名');
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);

$groupId = $_POST['group_id'];
$homeTeam = $_POST['home_team'];
$awayTeam = $_POST['away_team'];
$homeGoals = $_POST['home_goals'];
$awayGoals = $_POST['away_goals'];

// 检查是否已存在该比赛,存在则更新,否则插入
$sql = "SELECT id FROM group_matches WHERE group_id = ? AND home_team = ? AND away_team = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("sss", $groupId, $homeTeam, $awayTeam);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    $sql = "UPDATE group_matches SET home_goals = ?, away_goals = ? WHERE group_id = ? AND home_team = ? AND away_team = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("iisss", $homeGoals, $awayGoals, $groupId, $homeTeam, $awayTeam);
} else {
    $sql = "INSERT INTO group_matches (group_id, home_team, away_team, home_goals, away_goals) VALUES (?, ?, ?, ?, ?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("sssii", $groupId, $homeTeam, $awayTeam, $homeGoals, $awayGoals);
}

$stmt->execute();
$stmt->close();
$conn->close();
echo "保存成功";
?>

save_knockout_match.php逻辑类似,处理淘汰赛数据的插入与更新。


内容的提问来源于stack exchange,提问作者NoGodButAllah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:55:54