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 = ``;
// 如果有数字,显示数字
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 `
`;
}).join('');
problemAnswer.innerHTML = `
答案
${answersHTML}
`;
} else {
// 如果是单个值
problemAnswer.innerHTML = `
答案
`;
}
}
// 获取解法
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 += `
${item.question || ''}
${item.numbers ? `
${item.numbers.split(',').map(num => `${num.trim() === 'None' ? "?" : num.trim()}`).join('')}
` : ''}
${renderHistoryAnswers(answers)}
`;
});
// 如果是追加模式,则添加到现有内容后面
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 `
`;
}).join('');
str = `
答案
${answersHTML}
`;
} else {
// 如果是单个值
str = `
答案
`;
}
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];
});