document.addEventListener('DOMContentLoaded', function () { // 获取DOM元素 - 计算器模块 const calculateBtn = document.getElementById('calculate-btn'); const solutionsContainer = document.getElementById('solutions'); const statsContainer = document.getElementById('stats'); // 获取DOM元素 - 一星数据模块 const flag1MinInput = document.getElementById('flag1-min'); const flag1SearchBtn = document.getElementById('flag1-search-btn'); const flag1Table = document.getElementById('flag1-table'); // 获取DOM元素 - 二星数据模块 const flag2MinInput = document.getElementById('flag2-min'); const flag2SearchBtn = document.getElementById('flag2-search-btn'); const flag2Table = document.getElementById('flag2-table'); // 获取DOM元素 - 历史记录模块 const historyTypeSelect = document.getElementById('history-type'); const historyStartDateInput = document.getElementById('history-start-date'); const historyEndDateInput = document.getElementById('history-end-date'); const historySearchBtn = document.getElementById('history-search-btn'); const historyContainer = document.getElementById('history-container'); const historyStats = document.getElementById('history-stats'); // 获取DOM元素 - 我的收藏模块 const favoriteContainer = document.getElementById('favorite-container'); const favoriteStats = document.getElementById('favorite-stats'); // 获取DOM元素 - 出题模块 const problemContent = document.getElementById('problem-content'); const problemAnswer = document.getElementById('problem-answer'); const showAnswerBtn = document.getElementById('show-answer-btn'); // 数字输入框 const num1Input = document.getElementById('num1'); const num2Input = document.getElementById('num2'); const num3Input = document.getElementById('num3'); const num4Input = document.getElementById('num4'); // 限制输入范围为1-13 [num1Input, num2Input, num3Input, num4Input].forEach(input => { input.addEventListener('input', function () { const value = parseInt(this.value); if (value < 1) this.value = 1; if (value > 13) this.value = 13; }); }); // 定义SVG图标 const svgIcons = { star: ``, starFilled: ``, trash: ``, eye: ``, eyeOff: `` }; // 存储当前解法和问题数据 let currentSolutions = []; let currentProblem = null; // 获取问题类型选择框和出题按钮 const problemTypeSelect = document.getElementById('problem-type-select'); const generateProblemBtn = document.getElementById('generate-problem-btn'); // 为出题按钮添加点击事件 generateProblemBtn.addEventListener('click', function () { const selectedType = problemTypeSelect.value; if (selectedType) { // 根据选择的类型生成题目 generateProblem(selectedType); } else { // 如果没有选择类型,提示用户 problemContent.innerHTML = '

请先选择题目类型

'; } }); // 为显示答案按钮添加点击事件 showAnswerBtn.addEventListener('click', function () { if (currentProblem && currentProblem.answers) { console.log('currentProblem:', currentProblem.answers) if (problemAnswer.style.display === 'block') { problemAnswer.style.display = 'none'; showAnswerBtn.innerHTML = '显示答案'; } else { problemAnswer.style.display = 'block'; renderProblemAnswers(currentProblem.answers); showAnswerBtn.innerHTML = '隐藏答案'; } } }); // 初始化显示答案按钮图标 if (showAnswerBtn) { showAnswerBtn.innerHTML = '显示答案'; } // 为计算按钮添加点击事件 calculateBtn.addEventListener('click', fetchSolutions); // 为历史记录查询按钮添加点击事件 historySearchBtn.addEventListener('click', () => { fetchHistory(false) }); // 添加滚动监听器,实现自动加载更多 document.querySelector('.history-data-container').addEventListener('scroll', function () { const module5 = document.querySelector('.module-5'); const module6 = document.querySelector('.module-6'); // 检查历史记录模块是否可见 if (module5.style.display === 'block') { const historyStatsRect = historyStats.getBoundingClientRect(); if (historyStatsRect.top <= window.innerHeight && !isLoadingHistory && hasMoreHistory) { fetchHistory(true); } } // 检查收藏模块是否可见 if (module6.style.display === 'block') { const favoriteStatsRect = favoriteStats.getBoundingClientRect(); if (favoriteStatsRect.top <= window.innerHeight && !isLoadingFavorite && hasMoreFavorite) { fetchFavorites(true); } } }); // 根据题型生成题目 let answerTimer = null; let timerInterval = null; let timerSeconds = 0; let timerDisplay; async function generateProblem(type) { if (answerTimer) clearTimeout(answerTimer); if (timerInterval) clearInterval(timerInterval); // 重置问题和答案区域 problemContent.innerHTML = '

正在生成题目,请稍候...

'; problemAnswer.innerHTML = ''; problemAnswer.style.display = 'none'; showAnswerBtn.style.display = 'none'; currentProblem = null; // 重置计时器 timerSeconds = 0; try { // 调用API获取问题 const response = await fetch(`/api/questions?t=${type}`); const data = await response.json(); if (response.ok && data.question) { // 保存当前问题数据 currentProblem = data; problemContent.dataset.id = currentProblem.record_id; // 显示问题内容 problemContent.innerHTML = `
00:00
${data.question}
`; // 如果有数字,显示数字 if (data.numbers) { const numbersHTML = `
${data.numbers.map(num => `${num === null ? '?' : num}`).join('')}
`; problemContent.innerHTML += numbersHTML; } timerDisplay = document.getElementById('timer-display'); // 开始计时 startTimer(); // 显示答案按钮 answerTimer = setTimeout(() => { showAnswerBtn.innerHTML = ' 显示答案'; showAnswerBtn.style.display = 'block'; }, 10 * 1000); } else { problemContent.innerHTML = `

${data.detail || '获取题目失败'}

`; } } catch (error) { console.error('Error:', error); problemContent.innerHTML = '

请求失败,请检查网络连接

'; } // 为收藏按钮添加点击事件 problemContent.querySelectorAll('.favorite-btn').forEach((btn, index) => { btn.addEventListener('click', async function () { const card = this.closest('.problem-content'), is_favorite = this.classList.contains('active'); const recordId = card.dataset.id; try { const response = await fetch(`/api/history/${recordId}/favorite`, { method: 'POST' }); if (response.ok) { if (is_favorite) { this.innerHTML = svgIcons.star; this.classList.remove('active'); alert('取消成功'); } else { this.innerHTML = svgIcons.starFilled; this.classList.add('active'); alert('收藏成功'); } } else { alert('收藏失败,请重试'); } } catch (error) { console.error('收藏操作失败:', error); alert('收藏失败,请检查网络连接'); } }); }); // 开始计时器 function startTimer() { // 清除之前的计时器 if (timerInterval) { clearInterval(timerInterval); } // 重置计时 timerSeconds = 0; updateTimerDisplay(); // 启动新的计时器 timerInterval = setInterval(() => { timerSeconds++; if (timerSeconds > 130) { clearInterval(timerInterval); } updateTimerDisplay(); }, 1000); } // 更新计时器显示 function updateTimerDisplay() { if (timerDisplay) { if (timerSeconds >= 120) { timerDisplay.textContent = "时间到"; timerDisplay.classList.add('time-up'); } else { const minutes = Math.floor(timerSeconds / 60); const seconds = timerSeconds % 60; timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; timerDisplay.classList.remove('time-up'); } } } } generateProblem(0) // 渲染问题答案 function renderProblemAnswers(answers) { if (!answers || answers.length === 0) { problemAnswer.innerHTML = '

没有找到答案

'; return; } // 根据答案类型渲染不同的内容 if (Array.isArray(answers)) { // 如果是数组,渲染为列表 const answersHTML = answers.map(answer => { if (typeof answer === 'object' && answer.expression) { // 如果是解法对象 return `
${answer.expression}
${answer.flag === 1 ? '★' : answer.flag === 2 ? '★★' : ''}
`; } else { // 如果是普通文本 return `
${answer}
`; } }).join(''); problemAnswer.innerHTML = `

答案

${answersHTML}
`; } else if (typeof answers === 'object') { // 如果是单个对象 const answerKeys = Object.keys(answers); const answersHTML = answerKeys.map(key => { return `
${key}:
${answers[key]}
`; }).join(''); problemAnswer.innerHTML = `

答案

${answersHTML}
`; } else { // 如果是单个值 problemAnswer.innerHTML = `

答案

${answers}
`; } } // 获取解法 async function fetchSolutions() { // 获取输入值 const num1 = parseInt(num1Input.value) || 1; const num2 = parseInt(num2Input.value) || 1; const num3 = parseInt(num3Input.value) || 1; const num4 = parseInt(num4Input.value) || 1; // 显示加载状态 solutionsContainer.innerHTML = '

正在计算解法,请稍候...

'; statsContainer.textContent = ''; try { // 调用API const response = await fetch(`/api/solutions?num1=${num1}&num2=${num2}&num3=${num3}&num4=${num4}`); const data = await response.json(); if (response.ok) { // 保存解法 currentSolutions = data.solutions || []; // 显示统计信息 if (currentSolutions.length > 0) { statsContainer.textContent = `共 ${data.count} 种解法(一星: ${data.flag1_count}, 二星: ${data.flag2_count})`; } else { statsContainer.textContent = '没有找到任何解法'; } // 渲染解法 renderSolutions(); } else { // 显示错误信息 solutionsContainer.innerHTML = `

${data.detail || '没有找到解法'}

`; statsContainer.textContent = ''; } } catch (error) { console.error('Error:', error); solutionsContainer.innerHTML = '

请求失败,请检查网络连接

'; statsContainer.textContent = ''; } } // 渲染解法 function renderSolutions() { // 如果没有解法 if (!currentSolutions || currentSolutions.length === 0) { solutionsContainer.innerHTML = '

没有找到匹配的解法,请尝试其他数字组合

'; return; } // 直接使用所有解法 const filteredSolutions = currentSolutions; // 渲染解法列表 const solutionsHTML = filteredSolutions.map(solution => { return `
${solution.expression}
${solution.flag === 1 ? '★' : solution.flag === 2 ? '★★' : ''}
`; }).join(''); solutionsContainer.innerHTML = solutionsHTML; } // 为一星数据查询按钮添加点击事件 flag1SearchBtn.addEventListener('click', async function () { const min = flag1MinInput.value || 1; await fetchFlagData(1, min, flag1Table); }); // 为二星数据查询按钮添加点击事件 flag2SearchBtn.addEventListener('click', async function () { const min = flag2MinInput.value || 1; await fetchFlagData(2, min, flag2Table); }); // 获取一星/二星数据 async function fetchFlagData(flag, min, tableElement) { // 显示加载状态 tableElement.querySelector('tbody').innerHTML = '正在加载数据,请稍候...'; try { // 调用API获取数据 const response = await fetch(`/api/flag?flag=${flag}&min_num=${min}&max_num=`); const data = await response.json(); if (response.ok && data.length > 0) { // 处理数据并按数字组合分组 const groupedData = {}; data.forEach(item => { // 创建数字组合的键 const numbersKey = [item.n1, item.n2, item.n3, item.n4].sort((a, b) => a - b).join(','); // 如果这个数字组合不存在,创建一个新数组 if (!groupedData[numbersKey]) { groupedData[numbersKey] = []; } // 添加解法到对应的数字组合 item.s.forEach(solution => { groupedData[numbersKey].push({ expression: solution.c, flag: solution.f }); }); }); console.log(groupedData); // 渲染表格 renderFlagTable(groupedData, tableElement, flag); } else { // 显示无数据信息 tableElement.querySelector('tbody').innerHTML = '没有找到匹配的数据'; } } catch (error) { console.error('Error:', error); tableElement.querySelector('tbody').innerHTML = '请求失败,请检查网络连接'; } } // 渲染一星/二星数据表格 function renderFlagTable(groupedData, tableElement, currentFlag) { const tbody = tableElement.querySelector('tbody'); tbody.innerHTML = ''; // 遍历分组数据 Object.entries(groupedData).forEach(([numbersKey, solutions]) => { const tr = document.createElement('tr'); // 数字单元格 const tdNumbers = document.createElement('td'); tdNumbers.className = 'number-cell'; tdNumbers.textContent = numbersKey; tr.appendChild(tdNumbers); // 表达式单元格 const tdExpressions = document.createElement('td'); tdExpressions.className = 'expressions-cell'; const container = document.createElement('div'); container.className = 'expression-container hidden'; // 创建显示按钮 const toggleBtn = document.createElement('button'); toggleBtn.className = 'toggle-btn'; toggleBtn.textContent = '查看答案'; // 添加每个表达式 solutions.forEach(solution => { // const expressionDiv = document.createElement('div'); // expressionDiv.className = `expression-item flag-${solution.flag}`; // expressionDiv.textContent = solution.expression; const expressionDiv = document.createElement('div'); expressionDiv.className = `expression-item flag-${solution.flag} `; expressionDiv.textContent = solution.expression; container.appendChild(expressionDiv); }); tdExpressions.appendChild(container); // 按钮点击事件 toggleBtn.addEventListener('click', () => { container.classList.remove('hidden'); toggleBtn.remove(); }); tdExpressions.appendChild(toggleBtn); tr.appendChild(tdExpressions); tbody.appendChild(tr); }); // 如果没有数据 if (tbody.children.length === 0) { tbody.innerHTML = '没有找到匹配的数据'; } } // 添加模块切换事件监听 const moduleSelect = document.getElementById('module-select'); moduleSelect.addEventListener('change', function () { document.querySelectorAll('.module-container').forEach(module => { module.style.display = 'none'; }); document.querySelector(`.module-` + this.value).style.display = 'block'; // 切换到计算器模块时重置输入框 if (this.value === '2') { [num1Input, num2Input, num3Input, num4Input].forEach(input => input.value = 1); solutionsContainer.innerHTML = '

请输入4个数字并点击"计算解法"按钮

'; } // 切换到一星数据模块时加载数据 if (this.value === '3' && flag1Table.querySelector('tbody tr td.placeholder')) { fetchFlagData(1, flag1MinInput.value, flag1Table); } // 切换到二星数据模块时加载数据 if (this.value === '4' && flag2Table.querySelector('tbody tr td.placeholder')) { fetchFlagData(2, flag2MinInput.value, flag2Table); } // 切换到历史记录模块时加载数据 if (this.value === '5' && historyContainer) { fetchHistory(false); } // 切换到我的收藏模块时加载数据 if (this.value === '6' && favoriteContainer) { fetchFavorites(false); } }); // 初始化默认显示模块 document.querySelectorAll('.module-container').forEach(module => { module.style.display = module.classList.contains('module-1') ? 'block' : 'none'; }); // 历史记录相关变量 let currentHistoryPage = 1; let isLoadingHistory = false; let hasMoreHistory = true; // 收藏记录相关变量 let currentFavoritePage = 1; let isLoadingFavorite = false; let hasMoreFavorite = true; // 获取历史记录数据 async function fetchHistory(loadMore = false) { if (isLoadingHistory) return; isLoadingHistory = true; historyStats.textContent = '' if (!loadMore) { currentHistoryPage = 1; hasMoreHistory = true; } try { // 构建查询参数 const params = new URLSearchParams(); if (historyTypeSelect.value) { params.append('game_type', historyTypeSelect.value); } if (historyStartDateInput.value) { params.append('start_date', historyStartDateInput.value); } if (historyEndDateInput.value) { params.append('end_date', historyEndDateInput.value); } params.append('page', currentHistoryPage.toString()); params.append('page_size', '10'); // 调用API获取历史记录 const response = await fetch(`/api/history?${params.toString()}`); const data = await response.json(); if (response.ok && data.history) { // 渲染历史记录 renderHistoryData(data.history, historyContainer, loadMore, false); // 更新分页状态 hasMoreHistory = currentHistoryPage < data.total_pages; const historyRecordsStats = document.querySelector('.history-records-stats span'); historyRecordsStats.textContent = data.count // 如果成功加载,增加页码 currentHistoryPage++; } else { throw new Error(data.detail || '获取历史记录失败'); } } catch (error) { if (!loadMore) { historyContainer.innerHTML = `
${error.message}
`; historyStats.textContent = '加载失败'; } else { // 显示加载失败消息 alert('加载更多历史记录失败: ' + error.message); } } finally { isLoadingHistory = false; } } // 获取收藏记录数据 async function fetchFavorites(loadMore = false) { if (isLoadingFavorite) return; isLoadingFavorite = true; favoriteStats.textContent = '' // 如果不是加载更多,则重置状态 if (!loadMore) { currentFavoritePage = 1; hasMoreFavorite = true; } try { // 构建查询参数 const params = new URLSearchParams(); params.append('page', currentFavoritePage); params.append('page_size', "10"); params.append('only_favorite', "true"); params.append('include_deleted', "false"); // 调用API获取收藏记录 const response = await fetch(`/api/history?${params.toString()}`); const data = await response.json(); if (response.ok) { // 渲染历史记录 renderHistoryData(data.history, favoriteContainer, loadMore, true); // 更新分页状态 hasMoreFavorite = currentFavoritePage < data.total_pages; const favoriteRecordsStats = document.querySelector('.favorite-records-stats span'); favoriteRecordsStats.textContent = data.count // 更新分页状态 currentFavoritePage++; } else { if (!loadMore) { favoriteContainer.innerHTML = `
${data.detail || '获取收藏记录失败'}
`; favoriteStats.textContent = '加载失败'; } } } catch (error) { console.error('Error:', error); if (!loadMore) { favoriteContainer.innerHTML = '
请求失败,请检查网络连接
'; favoriteStats.textContent = '加载失败'; } } finally { isLoadingFavorite = false; } } function renderHistoryData(historyItems, container, append = false, isFavorite = false) { if (!historyItems || historyItems.length === 0) { if (!append) { container.innerHTML = `
${isFavorite ? '暂无收藏记录' : '没有找到历史记录'}
`; } return; } // 构建卡片内容 let cardsHTML = ``; historyItems.forEach(item => { // 格式化日期时间 const date = new Date(item.created_at); const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; // 获取操作类型的中文名称 const type_names = { "A": "推理未知数", "B": "一题多解1", "C": "一题多解2", "D": "一星题目", "E": "二星题目" }; let typeText = type_names[item.game_type] || item.game_type || '未知类型'; let typeClass = `type-${(item.game_type || '').toLowerCase()}`; if (!type_names[item.game_type]) { typeClass = 'type-unknown'; } // 解析答案数据 let answers = null; try { // 尝试解析JSON字符串 if (item.answers && typeof item.answers === 'string') { const jsonString = item.answers.replace(/'/g, '"'); answers = JSON.parse(jsonString); } else if (item.answers) { answers = item.answers; } } catch (e) { // 如果解析失败,直接使用原始字符串 answers = item.answers; } // 构建卡片HTML cardsHTML += `
${typeText}
${item.is_favorite ? `` : ``} ${item.is_deleted ? `` : isFavorite ? '' : ``}
${formattedDate}
${item.question || ''}
${item.numbers ? `
${item.numbers.split(',').map(num => `${num.trim() === 'None' ? "?" : num.trim()}`).join('')}
` : ''}
`; }); // 如果是追加模式,则添加到现有内容后面 if (append) { container.innerHTML += cardsHTML; } else { container.innerHTML = cardsHTML; } // 为所有显示答案按钮添加点击事件 container.querySelectorAll('.show-history-answer-btn').forEach((btn, index) => { btn.addEventListener('click', function () { const card = this.closest('.history-card'); const answersContainer = card.querySelector('.history-card-answers'); if (answersContainer.style.display === 'block') { // 隐藏答案 answersContainer.style.display = 'none'; this.innerHTML = svgIcons.eye; this.title = '显示答案'; } else { // 显示答案 answersContainer.style.display = 'block'; this.innerHTML = svgIcons.eyeOff; this.title = '隐藏答案'; } }); }); // 为收藏按钮添加点击事件 container.querySelectorAll('.favorite-btn').forEach((btn, index) => { btn.addEventListener('click', async function () { const card = this.closest('.history-card'), is_favorite = this.classList.contains('active'); const recordId = card.dataset.id; try { const response = await fetch(`/api/history/${recordId}/favorite`, { method: 'POST' }); if (response.ok) { if (is_favorite) { this.innerHTML = svgIcons.star; this.title = '未收藏'; this.classList.remove('active'); if (isFavorite) { card.remove(); // 如果没有卡片了,显示空提示 if (container.querySelectorAll('.history-card').length === 0) { container.innerHTML = '
暂无记录
'; } } alert('取消成功'); } else { this.innerHTML = svgIcons.starFilled; this.title = '已收藏'; this.classList.add('active'); alert('收藏成功'); } } else { alert('收藏失败,请重试'); } } catch (error) { console.error('收藏操作失败:', error); alert('收藏失败,请检查网络连接'); } }); }); // 为删除收藏按钮添加点击事件 container.querySelectorAll('.delete-btn').forEach((btn, index) => { btn.addEventListener('click', async function () { const card = this.closest('.history-card'), is_recover = this.classList.contains('active'); const recordId = card.dataset.id; if (confirm(`确定要${is_recover ? '恢复' : '删除'}这条记录吗?`)) { try { const response = await fetch(`/api/history/${recordId}/delete`, { method: 'POST' }); if (response.ok) { card.remove(); // 如果没有卡片了,显示空提示 if (container.querySelectorAll('.history-card').length === 0) { container.innerHTML = '
暂无记录
'; } if (is_recover) { alert('恢复成功'); } else { alert('删除成功'); } } else { alert('删除失败,请重试'); } } catch (error) { console.error('删除操作失败:', error); alert('删除失败,请检查网络连接'); } } }); }); function renderHistoryAnswers(answers) { let str = '' if (!answers || answers.length === 0) { str = '

没有找到答案

'; return str; } // 根据答案类型渲染不同的内容 if (Array.isArray(answers)) { // 如果是数组,渲染为列表 const answersHTML = answers.map(answer => { if (typeof answer === 'object' && answer.expression) { // 如果是解法对象 return `
${answer.expression}
${answer.flag === 1 ? '★' : answer.flag === 2 ? '★★' : ''}
`; } else { // 如果是普通文本 return `
${answer}
`; } }).join(''); str = `
${answersHTML}
`; } else if (typeof answers === 'object') { // 如果是单个对象 const answerKeys = Object.keys(answers); const answersHTML = answerKeys.map(key => { return `
${key}:
${answers[key]}
`; }).join(''); str = `

答案

${answersHTML}
`; } else { // 如果是单个值 str = `

答案

${answers}
`; } return str; } } // 设置日期输入框的默认值为当前日期 const today = new Date(); // 计算三天前的日期 const threeDaysAgo = new Date(); threeDaysAgo.setDate(today.getDate() - 3); // 设置开始日期输入框的值为三天前 historyStartDateInput.value = threeDaysAgo.toISOString().split('T')[0]; historyEndDateInput.value = today.toISOString().split('T')[0]; });