node-blog/app.js
2025-06-24 11:42:12 +08:00

119 lines
3.6 KiB
JavaScript

const express = require('express');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoStore = require('connect-mongo');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const path = require('path');
const { paginateQuery } = require('./utils/pagination');
const app = express();
// 增强的 MongoDB 连接配置
mongoose.connect('mongodb://127.0.0.1:27017/blog', { // 使用127.0.0.1而不是localhost
useNewUrlParser: true,
useUnifiedTopology: true,
serverSelectionTimeoutMS: 5000, // 添加服务器选择超时
socketTimeoutMS: 45000, // 添加socket超时
family: 4 // 强制使用IPv4
})
.then(() => {
console.log('MongoDB 已经连接');
// 连接成功后启动服务器
startServer();
})
.catch(err => {
console.error('MongoDB 连接错误:', err);
process.exit(1); // 如果数据库连接失败,退出应用
});
// 添加Mongoose连接状态监听
mongoose.connection.on('connecting', () => console.log('正在连接MongoDB...'));
mongoose.connection.on('disconnected', () => console.log('MongoDB 连接断开'));
mongoose.connection.on('reconnected', () => console.log('MongoDB 重新连接'));
// 其他中间件配置
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
// 增强的session配置
app.use(session({
secret: 'chenlilong_blog_secret',
resave: false,
saveUninitialized: false,
store: MongoStore.create({
mongoUrl: 'mongodb://127.0.0.1:27017/blog',
ttl: 24 * 60 * 60, // 1天
autoRemove: 'native' // 自动清理过期session
}),
cookie: {
maxAge: 1000 * 60 * 60 * 24,
httpOnly: true,
secure: process.env.NODE_ENV === 'production'
}
}));
// 路由配置
app.get('/', async (req, res) => {
try {
const Post = require('./models/Post');
const Link = require('./models/Link');
const { paginateQuery } = require('./utils/pagination');
// 获取分页参数
const page = parseInt(req.query.page) || 1;
const limit = 5; // 每页显示5篇文章
// 获取博客文章(带分页,只获取已发布的文章)
const postsResult = await paginateQuery(
Post,
{ isPublished: true }, // 只显示已发布的文章
{ sort: { isTop: -1, createdAt: -1 } }, // 置顶文章优先,然后按时间倒序
page,
limit
);
// 获取所有友情链接
const links = await Link.find().sort({ order: 1, createdAt: -1 });
res.render('user/index', {
user: req.session.user || null,
posts: postsResult.data,
links: links,
pagination: postsResult.pagination,
baseUrl: '/',
query: {}
});
} catch (error) {
console.error('获取首页数据失败:', error);
res.render('user/index', {
user: req.session.user || null,
posts: [],
links: [],
pagination: { currentPage: 1, totalPages: 1, total: 0 },
baseUrl: '/',
query: {}
});
}
});
const userAuthRouter = require('./routes/user/auth');
app.use('/', userAuthRouter);
const adminRouter = require('./routes/admin/index');
app.use('/admin', adminRouter);
app.use((req, res) => {
res.status(404).send('404 Not Found');
});
// 将服务器启动封装为函数
function startServer() {
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
}