Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb17d60101 | |||
| a34c79fe0a | |||
| adbbabdb6a | |||
| c574de4cb2 | |||
| f505f2dfd1 |
@@ -72,7 +72,10 @@
|
|||||||
<section id="manage-matches-tab" class="tab-content">
|
<section id="manage-matches-tab" class="tab-content">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h2>⚽ 比赛管理</h2>
|
<h2>⚽ 比赛管理</h2>
|
||||||
<button onclick="showAddMatchModal()" class="btn-primary">+ 添加比赛</button>
|
<div>
|
||||||
|
<button onclick="showBatchAddMatchModal()" class="btn-secondary">批量添加</button>
|
||||||
|
<button onclick="showAddMatchModal()" class="btn-primary">+ 添加比赛</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -154,6 +157,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 批量添加比赛弹窗 -->
|
||||||
|
<div id="batch-match-modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="closeModal('batch-match-modal')">×</span>
|
||||||
|
<h2>批量添加比赛</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>比赛数据(每行一条,用逗号分隔)</label>
|
||||||
|
<textarea id="batch-match-data" rows="14" placeholder="比赛代码,主队,客队,比赛时间,轮次,状态,主队比分,客队比分
|
||||||
|
|
||||||
|
示例:
|
||||||
|
M001,阿根廷,法国,2026-07-15 21:00,决赛,upcoming,-,-
|
||||||
|
M002,巴西,德国,2026-07-14 18:00,半决赛,finished,2,1
|
||||||
|
M003,西班牙,荷兰,2026-07-14 21:00,半决赛,upcoming,-,-
|
||||||
|
|
||||||
|
状态:upcoming(即将进行)或 finished(已完成)
|
||||||
|
比分:未进行的比赛用 - 表示"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>轮次(可选,批量设置)</label>
|
||||||
|
<select id="batch-match-round">
|
||||||
|
<option value="">-- 使用数据中的轮次 --</option>
|
||||||
|
<option value="小组赛">小组赛</option>
|
||||||
|
<option value="16强">16强</option>
|
||||||
|
<option value="8强">8强</option>
|
||||||
|
<option value="半决赛">半决赛</option>
|
||||||
|
<option value="季军赛">季军赛</option>
|
||||||
|
<option value="决赛">决赛</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button onclick="batchAddMatches()" class="btn-primary">批量添加</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 添加比赛弹窗 -->
|
<!-- 添加比赛弹窗 -->
|
||||||
<div id="match-modal" class="modal">
|
<div id="match-modal" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
<header>
|
<header>
|
||||||
<h1>🏆 世界杯预测系统</h1>
|
<h1>🏆 世界杯预测系统</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/" class="active">比赛预测</a>
|
<a href="/" class="active">世界杯预测系统</a>
|
||||||
<a href="/admin">管理后台</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -409,6 +409,84 @@ async function deleteAlgorithm(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示批量添加比赛弹窗
|
||||||
|
function showBatchAddMatchModal() {
|
||||||
|
document.getElementById('batch-match-data').value = '';
|
||||||
|
document.getElementById('batch-match-round').value = '';
|
||||||
|
document.getElementById('batch-match-modal').style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量添加比赛
|
||||||
|
async function batchAddMatches() {
|
||||||
|
const dataText = document.getElementById('batch-match-data').value.trim();
|
||||||
|
const defaultRound = document.getElementById('batch-match-round').value;
|
||||||
|
|
||||||
|
if (!dataText) {
|
||||||
|
alert('请输入比赛数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = dataText.split('\n').filter(line => line.trim());
|
||||||
|
let successCount = 0;
|
||||||
|
let failCount = 0;
|
||||||
|
let errors = [];
|
||||||
|
for (const line of lines) {
|
||||||
|
const parts = line.split(',').map(p => p.trim());
|
||||||
|
|
||||||
|
if (parts.length < 3) {
|
||||||
|
failCount++;
|
||||||
|
errors.push(`格式错误: ${line}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchData = {
|
||||||
|
match_code: parts[0],
|
||||||
|
home_team: parts[1],
|
||||||
|
away_team: parts[2],
|
||||||
|
match_time: parts[3] || null,
|
||||||
|
round_name: parts[4] || defaultRound || '小组赛',
|
||||||
|
status: parts[5] || 'upcoming',
|
||||||
|
home_score: (parts[6] && parts[6] !== '-') ? parseInt(parts[6]) : null,
|
||||||
|
away_score: (parts[7] && parts[7] !== '-') ? parseInt(parts[7]) : null
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_BASE}/api/matches`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(matchData)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
successCount++;
|
||||||
|
} else {
|
||||||
|
failCount++;
|
||||||
|
errors.push(`${matchData.match_code}: ${result.message}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
failCount++;
|
||||||
|
errors.push(`${matchData.match_code}: 网络错误`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let message = `批量添加完成\n成功: ${successCount} 条\n失败: ${failCount} 条`;
|
||||||
|
if (errors.length > 0 && errors.length <= 5) {
|
||||||
|
message += '\n\n失败详情:\n' + errors.join('\n');
|
||||||
|
} else if (errors.length > 5) {
|
||||||
|
message += '\n\n失败详情(前5条):\n' + errors.slice(0, 5).join('\n') + '\n...';
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(message);
|
||||||
|
|
||||||
|
if (successCount > 0) {
|
||||||
|
closeModal('batch-match-modal');
|
||||||
|
loadMatches();
|
||||||
|
loadPredictions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 显示添加比赛弹窗
|
// 显示添加比赛弹窗
|
||||||
function showAddMatchModal() {
|
function showAddMatchModal() {
|
||||||
document.getElementById('match-modal-title').textContent = '添加比赛';
|
document.getElementById('match-modal-title').textContent = '添加比赛';
|
||||||
|
|||||||
Reference in New Issue
Block a user