parent
fdbc214f27
commit
fb357ca552
@ -1,2 +0,0 @@
|
||||
# Pair-Programming
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
||||
{
|
||||
"name": "math-learning-app",
|
||||
"version": "1.0.0",
|
||||
"description": "小初高数学学习软件",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"dev": "electron . --dev",
|
||||
"build": "electron-builder"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^22.0.0",
|
||||
"electron-builder": "^24.0.0"
|
||||
},
|
||||
"build": {
|
||||
"appId": "com.mathlearning.app",
|
||||
"productName": "数学学习系统",
|
||||
"directories": {
|
||||
"output": "dist"
|
||||
},
|
||||
"files": [
|
||||
"src/**/*",
|
||||
"styles/**/*",
|
||||
"assets/**/*"
|
||||
],
|
||||
"win": {
|
||||
"target": "nsis",
|
||||
"icon": "assets/icon.ico"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.7.0"
|
||||
}
|
||||
}
|
||||
@ -1,129 +0,0 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron');
|
||||
|
||||
// 统一的会话管理器
|
||||
const SessionManager = {
|
||||
// 获取当前用户会话(强制从存储读取)
|
||||
getCurrentUser() {
|
||||
try {
|
||||
const session = localStorage.getItem('userSession');
|
||||
return session ? JSON.parse(session) : null;
|
||||
} catch (error) {
|
||||
console.error('获取用户会话失败:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
// 获取当前考试会话
|
||||
getCurrentExam() {
|
||||
try {
|
||||
const exam = localStorage.getItem('currentExam');
|
||||
return exam ? JSON.parse(exam) : null;
|
||||
} catch (error) {
|
||||
console.error('获取考试会话失败:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
// 清除所有会话
|
||||
clearAllSessions() {
|
||||
localStorage.removeItem('userSession');
|
||||
localStorage.removeItem('currentExam');
|
||||
localStorage.removeItem('examResult');
|
||||
console.log('所有会话已清除');
|
||||
},
|
||||
|
||||
// 验证会话是否有效
|
||||
validateUserSession() {
|
||||
const user = this.getCurrentUser();
|
||||
if (!user || !user.sessionId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 可以添加更多验证逻辑,比如检查过期时间等
|
||||
return true;
|
||||
},
|
||||
|
||||
// 刷新用户会话(在修改密码等操作后)
|
||||
refreshUserSession(updatedUserData) {
|
||||
if (updatedUserData) {
|
||||
localStorage.setItem('userSession', JSON.stringify(updatedUserData));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 暴露安全的API给渲染进程
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
// 页面导航
|
||||
navigateTo: (page) => ipcRenderer.invoke('navigate-to', page),
|
||||
|
||||
// 存储会话数据
|
||||
setSession: (key, value) => {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
},
|
||||
|
||||
getSession: (key) => {
|
||||
const item = localStorage.getItem(key);
|
||||
return item ? JSON.parse(item) : null;
|
||||
},
|
||||
|
||||
removeSession: (key) => {
|
||||
localStorage.removeItem(key);
|
||||
},
|
||||
|
||||
// 新增:获取当前会话状态
|
||||
getSessionState: () => {
|
||||
return SessionManager.validateSession();
|
||||
},
|
||||
|
||||
// 新增:强制清除所有会话
|
||||
clearAllSessions: () => {
|
||||
SessionManager.clearAllSessions();
|
||||
},
|
||||
// 新增会话验证方法
|
||||
validateSession: () => {
|
||||
return SessionManager.validateUserSession();
|
||||
},
|
||||
|
||||
// 新增会话刷新方法
|
||||
refreshSession: (userData) => {
|
||||
SessionManager.refreshUserSession(userData);
|
||||
}
|
||||
});
|
||||
|
||||
// 直接在渲染进程中暴露 API 调用函数
|
||||
contextBridge.exposeInMainWorld('api', {
|
||||
request: async (endpoint, method = 'POST', data = {}) => {
|
||||
try {
|
||||
console.log('API Request:', endpoint, method, data);
|
||||
|
||||
const url = `http://localhost:8080/api${endpoint}`;
|
||||
const formData = new URLSearchParams();
|
||||
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
formData.append(key, value);
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: method,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
console.log('API Response:', result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('API Error:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: `网络错误: ${error.message}`,
|
||||
data: null
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Preload script loaded successfully');
|
||||
@ -1,119 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>数学试卷自动生成系统 - 登录</title>
|
||||
<link rel="stylesheet" href="../style/common.css">
|
||||
<style>
|
||||
.login-container {
|
||||
max-width: 400px;
|
||||
margin: 100px auto;
|
||||
padding: 40px;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: #007acc;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #005a9e;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #007acc;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<h2>数学试卷自动生成系统</h2>
|
||||
<form id="loginForm">
|
||||
<div class="form-group">
|
||||
<input type="text" id="username" placeholder="用户名" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" id="password" placeholder="密码" required>
|
||||
</div>
|
||||
<button type="submit">登录</button>
|
||||
</form>
|
||||
<span class="link" id="registerLink">没有账号?立即注册</span>
|
||||
<div id="message" class="message"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 页面加载完成后自动聚焦到用户名输入框
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setTimeout(() => {
|
||||
const usernameInput = document.getElementById('username');
|
||||
if (usernameInput) {
|
||||
// 强制触发重绘
|
||||
usernameInput.style.display = 'none';
|
||||
usernameInput.offsetHeight; // 触发回流
|
||||
usernameInput.style.display = '';
|
||||
|
||||
// 设置焦点
|
||||
usernameInput.focus();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
document.getElementById('loginForm').addEventListener('submit', async (e) => {
|
||||
// 原有登录逻辑保持不变...
|
||||
e.preventDefault();
|
||||
|
||||
const username = document.getElementById('username').value;
|
||||
const password = document.getElementById('password').value;
|
||||
const messageEl = document.getElementById('message');
|
||||
|
||||
const result = await window.api.request('/login', 'POST', {
|
||||
username, password
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
window.electronAPI.setSession('userSession', {
|
||||
sessionId: result.data.sessionId,
|
||||
username: result.data.username,
|
||||
userType: result.data.userType
|
||||
});
|
||||
await window.electronAPI.navigateTo('main');
|
||||
} else {
|
||||
messageEl.textContent = result.message;
|
||||
messageEl.className = 'message error';
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('registerLink').addEventListener('click', async () => {
|
||||
await window.electronAPI.navigateTo('register');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,264 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>数学学习系统 - 答题</title>
|
||||
<link rel="stylesheet" href="../style/common.css">
|
||||
<style>
|
||||
.quiz-container {
|
||||
max-width: 800px;
|
||||
margin: 20px auto;
|
||||
padding: 30px;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.question {
|
||||
font-size: 20px;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.options {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.option {
|
||||
display: block;
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.option.selected {
|
||||
border-color: #007acc;
|
||||
background: #e7f3ff;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.prev {
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.next {
|
||||
background: #007acc;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="quiz-container">
|
||||
<div class="progress" id="progress">
|
||||
<!-- 进度信息将通过JavaScript填充 -->
|
||||
</div>
|
||||
|
||||
<div class="question" id="question">
|
||||
<!-- 题目内容将通过JavaScript填充 -->
|
||||
</div>
|
||||
|
||||
<div class="options" id="options">
|
||||
<!-- 选项将通过JavaScript填充 -->
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<button class="prev" id="prevBtn">上一题</button>
|
||||
<button class="next" id="nextBtn">下一题</button>
|
||||
<button class="submit" id="submitBtn" style="display: none;">提交答案</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let currentUser = null;
|
||||
let currentExam = null;
|
||||
let currentQuestionIndex = 0;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
currentUser = window.electronAPI.getSession('userSession');
|
||||
currentExam = window.electronAPI.getSession('currentExam');
|
||||
|
||||
if (!currentUser || !currentExam) {
|
||||
await window.electronAPI.navigateTo('main');
|
||||
return;
|
||||
}
|
||||
|
||||
currentQuestionIndex = currentExam.currentQuestion || 0;
|
||||
await loadQuestion(currentQuestionIndex);
|
||||
|
||||
// 绑定事件
|
||||
document.getElementById('prevBtn').addEventListener('click', () => {
|
||||
if (currentQuestionIndex > 0) {
|
||||
currentQuestionIndex--;
|
||||
loadQuestion(currentQuestionIndex);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('nextBtn').addEventListener('click', () => {
|
||||
if (currentQuestionIndex < currentExam.totalQuestions - 1) {
|
||||
currentQuestionIndex++;
|
||||
loadQuestion(currentQuestionIndex);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('submitBtn').addEventListener('click', async () => {
|
||||
const result = await window.api.request('/finish-exam', 'POST', {
|
||||
sessionId: currentUser.sessionId
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
window.electronAPI.setSession('examResult', result.data);
|
||||
window.electronAPI.removeSession('currentExam');
|
||||
await window.electronAPI.navigateTo('result');
|
||||
} else {
|
||||
alert('提交失败: ' + result.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function loadQuestion(index) {
|
||||
try {
|
||||
console.log(`加载第 ${index + 1} 题,用户会话:`, currentUser);
|
||||
|
||||
const result = await window.api.request('/get-question', 'POST', {
|
||||
sessionId: currentUser.sessionId,
|
||||
questionIndex: index
|
||||
});
|
||||
|
||||
console.log('获取题目响应:', result);
|
||||
|
||||
if (result.success) {
|
||||
// 更新进度
|
||||
document.getElementById('progress').innerHTML = `
|
||||
<strong>第 ${index + 1} 题 / 共 ${result.data.totalQuestions} 题</strong>
|
||||
<br><small>考试ID: ${result.data.examId}</small>
|
||||
`;
|
||||
|
||||
// 显示题目
|
||||
const questionEl = document.getElementById('question');
|
||||
questionEl.innerHTML = `<strong>题目 ${index + 1}:</strong> ${result.data.question}`;
|
||||
|
||||
// 显示选项
|
||||
const optionsContainer = document.getElementById('options');
|
||||
optionsContainer.innerHTML = '';
|
||||
|
||||
if (!result.data.options || result.data.options.length === 0) {
|
||||
optionsContainer.innerHTML = '<div class="option">暂无选项</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
result.data.options.forEach((option, i) => {
|
||||
const optionEl = document.createElement('div');
|
||||
optionEl.className = 'option';
|
||||
optionEl.innerHTML = `
|
||||
<strong>${String.fromCharCode(65 + i)}.</strong> ${option}
|
||||
`;
|
||||
|
||||
// 检查是否是当前选中的答案
|
||||
if (result.data.userAnswer === i) {
|
||||
optionEl.classList.add('selected');
|
||||
}
|
||||
|
||||
optionEl.addEventListener('click', async () => {
|
||||
console.log(`用户选择选项 ${i}: ${option}`);
|
||||
|
||||
// 移除其他选项的选中状态
|
||||
document.querySelectorAll('.option').forEach(opt => {
|
||||
opt.classList.remove('selected');
|
||||
});
|
||||
|
||||
// 选中当前选项
|
||||
optionEl.classList.add('selected');
|
||||
|
||||
try {
|
||||
// 提交答案
|
||||
const submitResult = await window.api.request('/submit-answer', 'POST', {
|
||||
sessionId: currentUser.sessionId,
|
||||
questionIndex: index,
|
||||
answerIndex: i
|
||||
});
|
||||
|
||||
console.log('提交答案响应:', submitResult);
|
||||
|
||||
if (!submitResult.success) {
|
||||
console.error('提交答案失败:', submitResult.message);
|
||||
// 回退选中状态
|
||||
optionEl.classList.remove('selected');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交答案错误:', error);
|
||||
// 回退选中状态
|
||||
optionEl.classList.remove('selected');
|
||||
}
|
||||
});
|
||||
|
||||
optionsContainer.appendChild(optionEl);
|
||||
});
|
||||
|
||||
// 更新导航按钮状态
|
||||
document.getElementById('prevBtn').disabled = index === 0;
|
||||
document.getElementById('nextBtn').style.display =
|
||||
index < result.data.totalQuestions - 1 ? 'inline-block' : 'none';
|
||||
document.getElementById('submitBtn').style.display =
|
||||
index === result.data.totalQuestions - 1 ? 'inline-block' : 'none';
|
||||
|
||||
// 保存当前题目索引
|
||||
currentExam.currentQuestion = index;
|
||||
window.electronAPI.setSession('currentExam', currentExam);
|
||||
|
||||
console.log(`第 ${index + 1} 题加载完成`);
|
||||
} else {
|
||||
console.error('加载题目失败:', result.message);
|
||||
alert('加载题目失败: ' + result.message);
|
||||
|
||||
// 如果是会话问题,跳转到登录页
|
||||
if (result.message.includes('会话') || result.message.includes('登录')) {
|
||||
window.electronAPI.removeSession('userSession');
|
||||
window.electronAPI.removeSession('currentExam');
|
||||
await window.electronAPI.navigateTo('login');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载题目错误:', error);
|
||||
alert('加载题目时发生错误: ' + error.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,104 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>数学学习系统 - 成绩</title>
|
||||
<link rel="stylesheet" href="../style/common.css">
|
||||
<style>
|
||||
.result-container {
|
||||
max-width: 600px;
|
||||
margin: 50px auto;
|
||||
padding: 40px;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.score {
|
||||
font-size: 48px;
|
||||
font-weight: bold;
|
||||
color: #28a745;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background: #007acc;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.success {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="result-container">
|
||||
<h2>考试完成</h2>
|
||||
<div class="score" id="score">
|
||||
<!-- 分数将通过JavaScript填充 -->
|
||||
</div>
|
||||
<p id="resultText"><!-- 结果文本将通过JavaScript填充 --></p>
|
||||
|
||||
<div class="btn-group">
|
||||
<button class="primary" id="continueBtn">继续做题</button>
|
||||
<button class="success" id="mainBtn">返回主页</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const result = window.electronAPI.getSession('examResult');
|
||||
|
||||
if (!result) {
|
||||
window.electronAPI.navigateTo('main');
|
||||
return;
|
||||
}
|
||||
|
||||
const score = result.score.toFixed(1);
|
||||
document.getElementById('score').textContent = `${score}分`;
|
||||
|
||||
let resultText = '';
|
||||
if (score >= 90) {
|
||||
resultText = '优秀!你做得非常棒!';
|
||||
} else if (score >= 70) {
|
||||
resultText = '良好!继续努力!';
|
||||
} else if (score >= 60) {
|
||||
resultText = '及格!还有提升空间!';
|
||||
} else {
|
||||
resultText = '需要加油哦!多多练习!';
|
||||
}
|
||||
|
||||
document.getElementById('resultText').textContent =
|
||||
`你在 ${result.totalQuestions} 道题中答对了 ${Math.round(result.totalQuestions * score / 100)} 道题。${resultText}`;
|
||||
|
||||
document.getElementById('continueBtn').addEventListener('click', async () => {
|
||||
await window.electronAPI.navigateTo('main');
|
||||
});
|
||||
|
||||
document.getElementById('mainBtn').addEventListener('click', async () => {
|
||||
await window.electronAPI.navigateTo('main');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,118 +0,0 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 10px;
|
||||
margin-top: 15px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message.success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
|
||||
.message.error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
||||
.message.info {
|
||||
background: #d1ecf1;
|
||||
color: #0c5460;
|
||||
border: 1px solid #bee5eb;
|
||||
}
|
||||
|
||||
/* 基础按钮样式 */
|
||||
.btn {
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 按钮交互效果 */
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 主按钮 - 用于主要操作 */
|
||||
.btn-primary {
|
||||
background: #007acc;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #005fa3;
|
||||
}
|
||||
|
||||
/* 次要按钮 - 用于辅助操作 */
|
||||
.btn-secondary {
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #5a6268;
|
||||
}
|
||||
|
||||
/* 成功按钮 - 用于提交、确认等操作 */
|
||||
.btn-success {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
background: #218838;
|
||||
}
|
||||
|
||||
/* 危险按钮 - 用于删除、退出等操作 */
|
||||
.btn-danger {
|
||||
background: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background: #c82333;
|
||||
}
|
||||
|
||||
/* 禁用状态 */
|
||||
.btn:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 图标按钮样式(如果需要) */
|
||||
.btn-icon-left i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.btn-icon-right i {
|
||||
margin-left: 8px;
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
@echo off
|
||||
echo 启动数学学习系统后端服务器...
|
||||
cd java-backend
|
||||
javac math_question.java
|
||||
java math_question
|
||||
pause
|
||||
@ -1,30 +0,0 @@
|
||||
### IntelliJ IDEA ###
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
.kotlin
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
@ -1,8 +0,0 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/math_learn.iml" filepath="$PROJECT_DIR$/math_learn.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
package com.mathlearn.generator;
|
||||
|
||||
import com.mathlearn.model.exam.Question;
|
||||
|
||||
public interface QuestionGenerator {
|
||||
Question generateQuestion();
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,17 +0,0 @@
|
||||
package com.mathlearn.model.api;
|
||||
|
||||
public class ApiResponse {
|
||||
private boolean success;
|
||||
private String message;
|
||||
private Object data;
|
||||
|
||||
public ApiResponse(boolean success, String message, Object data) {
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public boolean isSuccess() { return success; }
|
||||
public String getMessage() { return message; }
|
||||
public Object getData() { return data; }
|
||||
}
|
||||
Binary file not shown.
@ -1,46 +0,0 @@
|
||||
package com.mathlearn.model.exam;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class Exam {
|
||||
private List<Question> questions;
|
||||
private List<Integer> userAnswers;
|
||||
private Date startTime;
|
||||
private String examId;
|
||||
|
||||
public Exam(List<Question> questions) {
|
||||
this.questions = questions;
|
||||
this.userAnswers = new ArrayList<>();
|
||||
this.startTime = new Date();
|
||||
this.examId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
|
||||
|
||||
// 初始化用户答案列表
|
||||
for (int i = 0; i < questions.size(); i++) {
|
||||
userAnswers.add(-1); // -1表示未作答
|
||||
}
|
||||
}
|
||||
|
||||
public List<Question> getQuestions() { return questions; }
|
||||
public List<Integer> getUserAnswers() { return userAnswers; }
|
||||
public Date getStartTime() { return startTime; }
|
||||
public String getExamId() { return examId; }
|
||||
|
||||
public void setAnswer(int questionIndex, int answerIndex) {
|
||||
if (questionIndex >= 0 && questionIndex < userAnswers.size()) {
|
||||
userAnswers.set(questionIndex, answerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public double calculateScore() {
|
||||
int correctCount = 0;
|
||||
for (int i = 0; i < questions.size(); i++) {
|
||||
if (userAnswers.get(i) == questions.get(i).getCorrectAnswerIndex()) {
|
||||
correctCount++;
|
||||
}
|
||||
}
|
||||
return (double) correctCount / questions.size() * 100;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -1,19 +0,0 @@
|
||||
package com.mathlearn.model.exam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Question {
|
||||
private String questionText;
|
||||
private List<String> options;
|
||||
private int correctAnswerIndex;
|
||||
|
||||
public Question(String questionText, List<String> options, int correctAnswerIndex) {
|
||||
this.questionText = questionText;
|
||||
this.options = options;
|
||||
this.correctAnswerIndex = correctAnswerIndex;
|
||||
}
|
||||
|
||||
public String getQuestionText() { return questionText; }
|
||||
public List<String> getOptions() { return options; }
|
||||
public int getCorrectAnswerIndex() { return correctAnswerIndex; }
|
||||
}
|
||||
Binary file not shown.
@ -1,49 +0,0 @@
|
||||
package com.mathlearn.model.user;
|
||||
|
||||
// 用户账户类
|
||||
public class UserAccount {
|
||||
private String username;
|
||||
private String password;
|
||||
private String userType;
|
||||
private String email; // 添加邮箱字段
|
||||
private String registrationCode;
|
||||
private boolean registered;
|
||||
|
||||
public UserAccount(String username, String password, String userType) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.userType = userType;
|
||||
this.registered = true;
|
||||
}
|
||||
|
||||
public UserAccount(String username, String password, String userType, String email) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.userType = userType;
|
||||
this.email = email;
|
||||
this.registered = true;
|
||||
}
|
||||
|
||||
public UserAccount(String email, String registrationCode) {
|
||||
this.email = email;
|
||||
this.registrationCode = registrationCode;
|
||||
this.registered = false;
|
||||
}
|
||||
|
||||
public void completeRegistration(String username, String password, String userType) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.userType = userType;
|
||||
this.registered = true;
|
||||
}
|
||||
|
||||
public String getUsername() { return username; }
|
||||
public String getPassword() { return password; }
|
||||
public String getUserType() { return userType; }
|
||||
public String getRegistrationCode() { return registrationCode; }
|
||||
public boolean isRegistered() { return registered; }
|
||||
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
public String getEmail() { return email; }
|
||||
public void setEmail(String email) { this.email = email; }
|
||||
}
|
||||
Loading…
Reference in new issue