合并后端内容 #4

Closed
pijtbanfl wants to merge 3 commits from wengweibin_branch into main

@ -8,9 +8,9 @@
},
{
"email": "3063485007@qq.com",
"registeredAt": "2025-10-12T08:56:13.598Z",
"username": "wqs",
"registeredAt": "2025-10-11T19:08:09.303Z",
"password": "be0c664d19564b568c4dd76d00a26a08ee89214877e52225eee5ffefab36c15f",
"updatedAt": "2025-10-11T19:08:26.339Z"
"updatedAt": "2025-10-12T08:56:13.606Z"
}
]

File diff suppressed because it is too large Load Diff

@ -1,35 +1,14 @@
{
"name": "math-learning-backend",
"version": "1.0.0",
"description": "数学学习软件后端API - 支持QQ邮箱和163邮箱验证",
"main": "server.js",
"description": "小初高数学学习软件 - 后端业务逻辑",
"main": "utils/",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"后端服务测试模式\" && node server.js"
"install-deps": "npm install"
},
"dependencies": {
"express": "^4.18.2",
"cors": "^2.8.5",
"body-parser": "^1.20.2",
"nodemailer": "^6.9.7"
},
"devDependencies": {
"nodemon": "^3.0.1"
},
"keywords": [
"education",
"math",
"learning",
"email",
"qq",
"163"
],
"author": "数学学习软件团队",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/your-repo/math-learning-software"
}
"author": "Pair Backend",
"license": "MIT"
}

@ -1,310 +0,0 @@
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
// 导入工具类
const UserManager = require('./utils/user-manager');
const MultiEmailService = require('./utils/multi-email-service');
const MathQuestionGenerator = require('./utils/question-generator');
// 创建Express应用实例
const app = express();
const PORT = 8080;
// 配置中间件
app.use(cors());
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../project4')));
// 实例化管理器
const userManager = new UserManager();
const emailService = new MultiEmailService();
// 存储验证码(内存存储,重启后失效)
const verificationCodes = new Map();
// 生成6位数字验证码
function generateVerificationCode() {
return Math.floor(100000 + Math.random() * 900000).toString();
}
// 验证邮箱格式是否正确
function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
// API路由
// 检查服务器健康状态
app.get('/api/health', (req, res) => {
res.json({
ok: true,
message: '服务正常运行',
emailService: emailService.transporter ? '已配置' : '测试模式'
});
});
// 发送邮箱验证码
app.post('/api/send-code', async (req, res) => {
try {
const {email, username} = req.body;
console.log('收到发送验证码请求:', {email, username});
if (!email || !username) {
return res.json({ok: false, message: '邮箱和用户名不能为空'});
}
// 验证邮箱格式
if (!validateEmail(email)) {
return res.json({ok: false, message: '邮箱格式不正确'});
}
// 限制邮箱域名只允许QQ邮箱和163邮箱
if (!email.includes('@qq.com') && !email.includes('@163.com')) {
return res.json({ok: false, message: '只支持QQ邮箱和163邮箱'});
}
// 检查用户名是否已存在
if (userManager.findUserByUsername(username)) {
return res.json({ok: false, message: '用户名已存在'});
}
// 检查邮箱是否已注册
if (userManager.findUserByEmail(email)) {
return res.json({ok: false, message: '邮箱已被注册'});
}
const code = generateVerificationCode();
verificationCodes.set(email, {
code,
username,
timestamp: Date.now(),
});
console.log(`为邮箱 ${email} 生成验证码: ${code}`);
// 发送邮件
const emailResult = await emailService.sendVerificationCode(email, code, username);
if (emailResult.success) {
res.json({ok: true, message: emailResult.message});
} else {
// 如果邮件发送失败,但在开发模式下提供了验证码,仍然算成功
if (emailResult.debug) {
res.json({ok: true, message: emailResult.message + ' ' + emailResult.debug});
} else {
res.json({ok: false, message: emailResult.message});
}
}
} catch (error) {
console.error('发送验证码错误:', error);
res.json({ok: false, message: '服务器内部错误'});
}
});
// 验证码验证
app.post('/api/verify-code', (req, res) => {
try {
const {email, username, code} = req.body;
console.log('收到验证码验证请求:', {email, username, code});
if (!email || !username || !code) {
return res.json({ok: false, message: '请填写完整信息'});
}
const storedData = verificationCodes.get(email);
if (!storedData) {
return res.json({ok: false, message: '请先获取验证码'});
}
// 验证码10分钟过期
if (Date.now() - storedData.timestamp > 10 * 60 * 1000) {
verificationCodes.delete(email);
return res.json({ok: false, message: '验证码已过期,请重新获取'});
}
if (storedData.code !== code) {
return res.json({ok: false, message: '验证码不正确'});
}
if (storedData.username !== username) {
return res.json({ok: false, message: '用户名与验证时不一致'});
}
// 清除验证码
verificationCodes.delete(email);
res.json({ok: true, message: '验证成功,请设置密码'});
} catch (error) {
console.error('验证码验证错误:', error);
res.json({ok: false, message: error.message});
}
});
// 注册(创建用户 + 设置密码)
app.post('/api/register', (req, res) => {
try {
const {email, username, password} = req.body;
console.log('收到注册请求:', {email, username});
if (!email || !username || !password) {
return res.json({ok: false, message: '请填写完整信息'});
}
// 创建用户并设置密码
userManager.createUser(email, username);
userManager.setPassword(email, password);
res.json({ok: true, message: '注册成功'});
} catch (error) {
console.error('注册错误:', error);
res.json({ok: false, message: error.message});
}
});
// 登录
app.post('/api/login', (req, res) => {
try {
const {account, password} = req.body;
if (!account || !password) {
return res.json({ok: false, message: '请填写账号和密码'});
}
// 通过邮箱或用户名查找用户
let user = userManager.findUserByEmail(account);
if (!user) {
user = userManager.findUserByUsername(account);
}
if (!user || !user.password) {
return res.json({ok: false, message: '用户不存在'});
}
if (!userManager.verifyPassword(user.email, password)) {
return res.json({ok: false, message: '密码不正确'});
}
res.json({
ok: true,
message: '登录成功',
data: {
email: user.email,
username: user.username,
},
});
} catch (error) {
console.error('登录错误:', error);
res.json({ok: false, message: error.message});
}
});
// 修改密码
app.post('/api/change-password', (req, res) => {
try {
const {email, oldPassword, newPassword} = req.body;
if (!email || !oldPassword || !newPassword) {
return res.json({ok: false, message: '请填写完整信息'});
}
userManager.changePassword(email, oldPassword, newPassword);
res.json({ok: true, message: '密码修改成功'});
} catch (error) {
console.error('修改密码错误:', error);
res.json({ok: false, message: error.message});
}
});
// 修改用户名
app.post('/api/change-username', (req, res) => {
try {
const {email, username} = req.body;
if (!email || !username) {
return res.json({ok: false, message: '请填写完整信息'});
}
userManager.changeUsername(email, username);
res.json({ok: true, message: '用户名修改成功'});
} catch (error) {
console.error('修改用户名错误:', error);
res.json({ok: false, message: error.message});
}
});
// 删除账号
app.post('/api/delete-account', (req, res) => {
try {
const {email, password} = req.body;
if (!email || !password) {
return res.json({ok: false, message: '请填写完整信息'});
}
// 验证密码
if (!userManager.verifyPassword(email, password)) {
return res.json({ok: false, message: '密码不正确'});
}
userManager.deleteUser(email);
res.json({ok: true, message: '账号删除成功'});
} catch (error) {
console.error('删除账号错误:', error);
res.json({ok: false, message: error.message});
}
});
// 获取题目
app.get('/api/questions', (req, res) => {
try {
const {grade, count} = req.query;
if (!grade || !count) {
return res.json({ok: false, message: '请选择年级和题目数量'});
}
const countNum = parseInt(count);
if (isNaN(countNum) || countNum < 10 || countNum > 30) {
return res.json({ok: false, message: '题目数量需在10-30之间'});
}
const generator = new MathQuestionGenerator();
const questions = generator.generateQuestions(grade, countNum);
res.json({
ok: true,
data: questions,
message: '题目生成成功',
});
} catch (error) {
console.error('生成题目失败:', error);
res.json({ok: false, message: '生成题目失败'});
}
});
// 提供前端页面
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '../project4/index.html'));
});
// 启动服务器
app.listen(PORT, () => {
console.log(`========================================`);
console.log(`🎓 数学学习软件后端服务已启动`);
console.log(`📍 服务地址: http://localhost:${PORT}`);
console.log(`🌐 前端页面: http://localhost:${PORT}/`);
console.log(`🔧 API文档: http://localhost:${PORT}/api/health`);
console.log(`📧 邮箱服务: ${emailService.transporter ? '已配置' : '测试模式'}`);
console.log(`========================================`);
});
module.exports = app;
Loading…
Cancel
Save