Files
accountbook/server/index.js
T
DeveloperandClaude Opus 4.6 98aa39cb1c refactor: 代码质量优化与安全修复
- 删除根目录重复的 server.js (830行),统一使用模块化的 server/index.js
- 修复 ESLint 错误: 移除未使用变量、修复 const 声明、处理未使用参数
- 修复 React Hooks 依赖警告: 使用 useCallback 包装函数并添加正确依赖项
- SQL LIKE 查询添加特殊字符转义,防止注入风险
- 移除 CSS 中重复的 @keyframes spin 定义

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 10:49:12 +08:00

84 lines
2.4 KiB
JavaScript

const express = require('express');
const cors = require('cors');
const path = require('path');
const fs = require('fs');
// 确保日志目录存在
const logsDir = path.join(__dirname, '../logs');
if (!fs.existsSync(logsDir)) {
fs.mkdirSync(logsDir, { recursive: true });
}
// 加载环境变量
if (fs.existsSync(path.join(__dirname, '../.env'))) {
require('dotenv').config({ path: path.join(__dirname, '../.env') });
}
const { errorHandler } = require('./middleware/errorHandler');
// 运行数据库迁移
require('./db/migrate');
const app = express();
const PORT = process.env.PORT || 3501;
// 中间件
app.use(cors({
origin: process.env.NODE_ENV === 'production'
? (process.env.ALLOWED_ORIGINS || '').split(',').filter(Boolean)
: ['http://localhost:3500', 'http://127.0.0.1:3500'],
credentials: true,
}));
app.use(express.json());
app.use(express.static(path.join(__dirname, '../public')));
app.use(express.static(path.join(__dirname, '../frontend/.next')));
app.use(express.static(path.join(__dirname, '../frontend/.next/server/pages')));
// 请求日志
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// 路由
app.use('/api/auth', require('./routes/auth'));
app.use('/api/records', require('./routes/records'));
app.use('/api/stats', require('./routes/stats'));
app.use('/api/recurring', require('./routes/recurring'));
app.use('/api/categories', require('./routes/categories'));
app.use('/api/export', require('./routes/export'));
app.use('/api/search', require('./routes/search'));
// 健康检查
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// 前端路由 - Next.js 静态文件
app.get('/_next/static/:path(*)', (req, res) => {
const filePath = path.join(__dirname, '../frontend/.next/static', req.params.path);
res.sendFile(filePath, (err) => {
if (err) res.status(404).send('Not found');
});
});
app.get('*', (req, res) => {
const pagePath = req.path === '/' ? '/index.html' : req.path + '.html';
const nextPagePath = path.join(__dirname, '../frontend/.next/server/pages', pagePath);
res.sendFile(nextPagePath, (err) => {
if (err) {
res.sendFile(path.join(__dirname, '../frontend/.next/server/pages/index.html'));
}
});
});
// 错误处理
app.use(errorHandler);
// 启动服务器
app.listen(PORT, '0.0.0.0', () => {
console.log(`记账本服务已启动: http://0.0.0.0:${PORT}`);
});