feat: add new server entry point and update package.json
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
# 服务器配置
|
||||||
|
PORT=3501
|
||||||
|
NODE_ENV=development
|
||||||
|
|
||||||
|
# JWT 密钥(生产环境必须修改)
|
||||||
|
JWT_SECRET=your-secret-key-here
|
||||||
|
|
||||||
|
# 数据库路径
|
||||||
|
DB_PATH=./accountbook.db
|
||||||
|
|
||||||
|
# 日志级别
|
||||||
|
LOG_LEVEL=info
|
||||||
|
|
||||||
|
# 生产环境允许的域名(逗号分隔)
|
||||||
|
ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
|
||||||
+23
-4
@@ -1,16 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "accountbook",
|
"name": "accountbook",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"description": "简易记账本",
|
"description": "简易记账本",
|
||||||
"main": "server.js",
|
"main": "server/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js"
|
"start": "node server/index.js",
|
||||||
|
"dev": "concurrently \"npm run server:dev\" \"npm run client:dev\"",
|
||||||
|
"server:dev": "node server/index.js",
|
||||||
|
"client:dev": "cd frontend && npm run dev",
|
||||||
|
"build": "cd frontend && npm run build",
|
||||||
|
"migrate": "node server/db/migrate.js",
|
||||||
|
"test": "jest",
|
||||||
|
"lint": "eslint server/ frontend/",
|
||||||
|
"lint:fix": "eslint server/ frontend/ --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"better-sqlite3": "^9.2.2",
|
"better-sqlite3": "^9.2.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"cors": "^2.8.5"
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"concurrently": "^8.2.2",
|
||||||
|
"eslint": "^8.55.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"nodemon": "^3.0.2",
|
||||||
|
"prettier": "^3.1.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"supertest": "^6.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
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) => {
|
||||||
|
let 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}`);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user