cursor done.

This commit is contained in:
2025-11-11 14:36:09 +08:00
parent 7a5fb889c5
commit 9b1eb6cafd
27 changed files with 4748 additions and 552 deletions

86
server/routes/auth.js Normal file
View File

@@ -0,0 +1,86 @@
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { db } = require('../database');
const { JWT_SECRET } = require('../config');
const { authenticateToken } = require('../middleware/auth');
const router = express.Router();
router.post('/register', async (req, res) => {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ success: false, error: '用户名和密码不能为空' });
}
if (username.length < 3) {
return res.status(400).json({ success: false, error: '用户名至少需要3个字符' });
}
if (password.length < 6) {
return res.status(400).json({ success: false, error: '密码至少需要6个字符' });
}
const passwordHash = await bcrypt.hash(password, 10);
db.run(
'INSERT INTO users (username, password_hash) VALUES (?, ?)',
[username, passwordHash],
function (err) {
if (err) {
if (err.message.includes('UNIQUE constraint failed')) {
return res.status(400).json({ success: false, error: '用户名已存在' });
}
return res.status(500).json({ success: false, error: '注册失败' });
}
const token = jwt.sign({ userId: this.lastID, username }, JWT_SECRET, { expiresIn: '7d' });
res.json({ success: true, token, userId: this.lastID, username });
}
);
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
router.post('/login', (req, res) => {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ success: false, error: '用户名和密码不能为空' });
}
db.get(
'SELECT * FROM users WHERE username = ?',
[username],
async (err, user) => {
if (err) {
return res.status(500).json({ success: false, error: '登录失败' });
}
if (!user) {
return res.status(401).json({ success: false, error: '用户名或密码错误' });
}
const validPassword = await bcrypt.compare(password, user.password_hash);
if (!validPassword) {
return res.status(401).json({ success: false, error: '用户名或密码错误' });
}
const token = jwt.sign({ userId: user.id, username: user.username }, JWT_SECRET, { expiresIn: '7d' });
res.json({ success: true, token, userId: user.id, username: user.username });
}
);
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
router.get('/me', authenticateToken, (req, res) => {
res.json({ success: true, userId: req.user.userId, username: req.user.username });
});
module.exports = router;

92
server/routes/calendar.js Normal file
View File

@@ -0,0 +1,92 @@
const express = require('express');
const { db } = require('../database');
const router = express.Router();
router.get('/', (req, res) => {
const userId = req.user.userId;
db.all(
'SELECT date, status FROM calendar_marks WHERE user_id = ?',
[userId],
(err, rows) => {
if (err) {
return res.status(500).json({ success: false, error: '获取数据失败' });
}
const markedDates = {};
rows.forEach((row) => {
markedDates[row.date] = row.status;
});
res.json({ success: true, markedDates });
}
);
});
router.post('/', (req, res) => {
const userId = req.user.userId;
const { markedDates } = req.body || {};
if (!markedDates || typeof markedDates !== 'object') {
return res.status(400).json({ success: false, error: '无效的数据格式' });
}
const dbOperations = Object.entries(markedDates).map(([date, status]) => {
return new Promise((resolve, reject) => {
db.run(
`INSERT INTO calendar_marks (user_id, date, status, updated_at)
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
ON CONFLICT(user_id, date) DO UPDATE SET
status = excluded.status,
updated_at = CURRENT_TIMESTAMP`,
[userId, date, status],
(err) => {
if (err) reject(err);
else resolve();
}
);
});
});
const dates = Object.keys(markedDates);
if (dates.length > 0) {
const placeholders = dates.map(() => '?').join(',');
dbOperations.push(
new Promise((resolve, reject) => {
db.run(
`DELETE FROM calendar_marks WHERE user_id = ? AND date NOT IN (${placeholders})`,
[userId, ...dates],
(err) => {
if (err) reject(err);
else resolve();
}
);
})
);
} else {
dbOperations.push(
new Promise((resolve, reject) => {
db.run(
'DELETE FROM calendar_marks WHERE user_id = ?',
[userId],
(err) => {
if (err) reject(err);
else resolve();
}
);
})
);
}
Promise.all(dbOperations)
.then(() => {
res.json({ success: true, message: '数据保存成功' });
})
.catch((err) => {
console.error('保存数据失败:', err);
res.status(500).json({ success: false, error: '保存数据失败' });
});
});
module.exports = router;