Files
2026-01-18 20:39:34 +08:00

248 lines
6.7 KiB
JavaScript

// 页面加载时初始化
document.addEventListener('DOMContentLoaded', () => {
loadData();
initForm();
initModal();
});
// 全局变量存储当前数据和排序状态
let currentRecords = [];
let currentSortField = null;
let currentSortOrder = 'asc'; // 'asc' 或 'desc'
// 初始化表单
function initForm() {
const form = document.getElementById('submitForm');
const noteInput = document.getElementById('note');
const noteCount = document.getElementById('noteCount');
// 字数统计
noteInput.addEventListener('input', () => {
noteCount.textContent = noteInput.value.length;
});
// 表单提交
form.addEventListener('submit', async (e) => {
e.preventDefault();
await submitForm();
});
}
// 提交表单
async function submitForm() {
const form = document.getElementById('submitForm');
const name = document.getElementById('name').value;
const link = document.getElementById('link').value;
const note = document.getElementById('note').value;
try {
const submitBtn = form.querySelector('button[type="submit"]');
submitBtn.disabled = true;
submitBtn.textContent = '提交中...';
const response = await fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: name,
link: link,
note: note
})
});
const result = await response.json();
if (result.success) {
alert('✅ 提交成功!');
form.reset();
document.getElementById('noteCount').textContent = '0';
loadData(); // 刷新数据列表
} else {
alert('❌ ' + result.message);
}
} catch (error) {
alert('❌ 提交失败: ' + error.message);
} finally {
const submitBtn = form.querySelector('button[type="submit"]');
submitBtn.disabled = false;
submitBtn.textContent = '提交数据';
}
}
// 加载数据列表
async function loadData() {
try {
const response = await fetch('/api/list');
const result = await response.json();
if (result.success) {
currentRecords = result.records;
renderTable(currentRecords);
} else {
alert('加载数据失败: ' + result.message);
}
} catch (error) {
console.error('加载数据出错:', error);
document.getElementById('dataTableBody').innerHTML = `
<tr><td colspan="9" class="loading">加载失败,请刷新重试</td></tr>
`;
}
}
// 渲染表格
function renderTable(records) {
const tbody = document.getElementById('dataTableBody');
if (records.length === 0) {
tbody.innerHTML = '<tr><td colspan="9" class="loading">暂无数据</td></tr>';
return;
}
tbody.innerHTML = records.map((record, index) => {
const hasNaga = record.nagaLink && record.nagaLink.trim() !== '';
const nagaStatus = hasNaga
? '<span class="has-naga">✔ 有</span>'
: '<span class="no-naga">✘ 无</span>';
const nagaLinkDisplay = hasNaga
? `<a href="${escapeHtml(record.nagaLink)}" target="_blank">查看链接</a>`
: '-';
const nagaNoteDisplay = record.nagaNote && record.nagaNote.trim() !== ''
? escapeHtml(record.nagaNote)
: '-';
const imagesDisplay = record.images && record.images.length > 0
? `<div class="image-thumbs">
${record.images.map(img => `
<img src="${img}" class="thumb-img" onclick="showImages(${JSON.stringify(record.images).replace(/"/g, '&quot;')})">
`).join('')}
</div>`
: '-';
return `
<tr>
<td>${index + 1}</td>
<td>${escapeHtml(record.submitTime)}</td>
<td>${escapeHtml(record.name)}</td>
<td class="link-cell"><a href="${escapeHtml(record.link)}" target="_blank">查看牌谱</a></td>
<td class="note-cell">${record.note ? escapeHtml(record.note) : '-'}</td>
<td>${nagaStatus}</td>
<td class="link-cell">${nagaLinkDisplay}</td>
<td class="note-cell">${nagaNoteDisplay}</td>
<td>${imagesDisplay}</td>
</tr>
`;
}).join('');
}
// 显示图片模态框
function showImages(images) {
const modal = document.getElementById('imageModal');
const modalImages = document.getElementById('modalImages');
modalImages.innerHTML = images.map(img => `
<img src="${img}" alt="图片">
`).join('');
modal.style.display = 'block';
}
// 初始化模态框
function initModal() {
const modal = document.getElementById('imageModal');
const closeBtn = modal.querySelector('.close');
closeBtn.onclick = () => {
modal.style.display = 'none';
};
window.onclick = (event) => {
if (event.target === modal) {
modal.style.display = 'none';
}
};
}
// HTML 转义函数
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 排序表格
function sortTable(field) {
// 如果点击同一列,切换排序方向
if (currentSortField === field) {
currentSortOrder = currentSortOrder === 'asc' ? 'desc' : 'asc';
} else {
currentSortField = field;
currentSortOrder = 'asc';
}
// 复制数组进行排序
const sortedRecords = [...currentRecords];
sortedRecords.sort((a, b) => {
let valueA, valueB;
switch(field) {
case 'id':
valueA = a.id;
valueB = b.id;
break;
case 'submitTime':
valueA = a.submitTime;
valueB = b.submitTime;
break;
case 'name':
valueA = a.name.toLowerCase();
valueB = b.name.toLowerCase();
break;
case 'hasNaga':
valueA = (a.nagaLink && a.nagaLink.trim() !== '') ? 1 : 0;
valueB = (b.nagaLink && b.nagaLink.trim() !== '') ? 1 : 0;
break;
default:
return 0;
}
if (valueA < valueB) {
return currentSortOrder === 'asc' ? -1 : 1;
}
if (valueA > valueB) {
return currentSortOrder === 'asc' ? 1 : -1;
}
return 0;
});
renderTable(sortedRecords);
updateSortIcons();
}
// 更新排序图标
function updateSortIcons() {
// 移除所有排序图标的激活状态
document.querySelectorAll('.sort-icon').forEach(icon => {
icon.textContent = '⇅';
icon.classList.remove('sort-asc', 'sort-desc');
});
// 如果有当前排序字段,更新对应图标
if (currentSortField) {
const headers = document.querySelectorAll('th.sortable');
headers.forEach(th => {
const onclick = th.getAttribute('onclick');
if (onclick && onclick.includes(`'${currentSortField}'`)) {
const icon = th.querySelector('.sort-icon');
if (icon) {
icon.textContent = currentSortOrder === 'asc' ? '↑' : '↓';
icon.classList.add(currentSortOrder === 'asc' ? 'sort-asc' : 'sort-desc');
}
}
});
}
}