基于 Node.js + Express.js 构建的「闪电准备包」后端服务,采用 MVC 架构模式,支持微信小程序认证、支付、内容管理等核心功能。
server/
├── package.json # 项目依赖配置
├── package-lock.json # 依赖锁定文件
├── .env # 环境变量配置
├── .env.example # 环境变量示例
├── .gitignore # Git忽略文件
├── README.md # 项目说明文档
├── app.js # 应用入口文件
├── server.js # 服务器启动文件
│
├── src/ # 源代码目录
│ ├── controllers/ # 控制器层
│ │ ├── auth.js # 认证控制器
│ │ ├── user.js # 用户控制器
│ │ ├── company.js # 公司控制器
│ │ ├── job.js # 职位控制器
│ │ ├── package.js # 准备包控制器
│ │ ├── content.js # 内容控制器
│ │ ├── order.js # 订单控制器
│ │ ├── progress.js # 进度控制器
│ │ └── admin.js # 管理后台控制器
│ │
│ ├── models/ # 数据模型层
│ │ ├── User.js # 用户模型
│ │ ├── Company.js # 公司模型
│ │ ├── Job.js # 职位模型
│ │ ├── Package.js # 准备包模型
│ │ ├── Content.js # 内容模型
│ │ ├── Order.js # 订单模型
│ │ ├── Progress.js # 进度模型
│ │ ├── Coupon.js # 优惠券模型
│ │ └── Review.js # 评价模型
│ │
│ ├── services/ # 业务服务层
│ │ ├── auth.js # 认证服务
│ │ ├── wechat.js # 微信服务
│ │ ├── payment.js # 支付服务
│ │ ├── content.js # 内容服务
│ │ ├── notification.js # 通知服务
│ │ ├── email.js # 邮件服务
│ │ ├── sms.js # 短信服务
│ │ └── analytics.js # 数据分析服务
│ │
│ ├── middleware/ # 中间件
│ │ ├── auth.js # 认证中间件
│ │ ├── validation.js # 参数验证中间件
│ │ ├── rateLimit.js # 限流中间件
│ │ ├── error.js # 错误处理中间件
│ │ ├── cors.js # 跨域中间件
│ │ ├── logger.js # 日志中间件
│ │ └── upload.js # 文件上传中间件
│ │
│ ├── routes/ # 路由定义
│ │ ├── index.js # 路由入口
│ │ ├── auth.js # 认证路由
│ │ ├── user.js # 用户路由
│ │ ├── company.js # 公司路由
│ │ ├── package.js # 准备包路由
│ │ ├── content.js # 内容路由
│ │ ├── order.js # 订单路由
│ │ ├── progress.js # 进度路由
│ │ └── admin.js # 管理后台路由
│ │
│ ├── utils/ # 工具类
│ │ ├── crypto.js # 加密工具
│ │ ├── validator.js # 验证工具
│ │ ├── logger.js # 日志工具
│ │ ├── redis.js # Redis工具
│ │ ├── response.js # 响应格式化工具
│ │ ├── constants.js # 常量定义
│ │ ├── helpers.js # 辅助函数
│ │ └── queue.js # 队列工具
│ │
│ └── validators/ # 数据验证器
│ ├── auth.js # 认证验证器
│ ├── user.js # 用户验证器
│ ├── package.js # 准备包验证器
│ ├── order.js # 订单验证器
│ └── content.js # 内容验证器
│
├── config/ # 配置文件目录
│ ├── index.js # 配置入口
│ ├── database.js # 数据库配置
│ ├── wechat.js # 微信配置
│ ├── payment.js # 支付配置
│ ├── redis.js # Redis配置
│ ├── email.js # 邮件配置
│ ├── upload.js # 文件上传配置
│ └── app.js # 应用配置
│
├── scripts/ # 脚本文件
│ ├── seed.js # 数据初始化脚本
│ ├── migrate.js # 数据迁移脚本
│ ├── backup.js # 数据备份脚本
│ ├── cleanup.js # 数据清理脚本
│ └── deploy.js # 部署脚本
│
├── tests/ # 测试文件
│ ├── unit/ # 单元测试
│ │ ├── controllers/ # 控制器测试
│ │ ├── services/ # 服务测试
│ │ ├── models/ # 模型测试
│ │ └── utils/ # 工具测试
│ ├── integration/ # 集成测试
│ │ ├── auth.test.js # 认证集成测试
│ │ ├── order.test.js # 订单集成测试
│ │ └── payment.test.js # 支付集成测试
│ ├── fixtures/ # 测试数据
│ │ ├── users.json # 用户测试数据
│ │ ├── companies.json # 公司测试数据
│ │ └── packages.json # 准备包测试数据
│ └── helpers/ # 测试辅助函数
│ ├── setup.js # 测试环境设置
│ └── teardown.js # 测试环境清理
│
├── docs/ # 文档目录
│ ├── api.md # API文档
│ ├── deployment.md # 部署文档
│ └── development.md # 开发文档
│
├── logs/ # 日志文件目录
│ ├── access.log # 访问日志
│ ├── error.log # 错误日志
│ └── app.log # 应用日志
│
└── uploads/ # 文件上传目录
├── images/ # 图片文件
├── documents/ # 文档文件
└── temp/ # 临时文件
- Node.js: v18.x LTS
- Express.js: v4.18.x
- MongoDB: v6.x
- Mongoose: v7.x
- Redis: v7.x
- jsonwebtoken: JWT认证
- bcryptjs: 密码加密
- helmet: 安全头设置
- cors: 跨域处理
- express-rate-limit: 请求限流
- wechat-api: 微信API封装
- wechat-pay: 微信支付
- crypto: 加密解密
- joi: 数据验证
- winston: 日志管理
- nodemailer: 邮件发送
- multer: 文件上传
- moment: 日期处理
const authService = require('../services/auth')
const wechatService = require('../services/wechat')
const { successResponse, errorResponse } = require('../utils/response')
class AuthController {
// 微信登录
async wechatLogin(req, res) {
try {
const { code, userInfo } = req.body
// 获取微信用户信息
const wechatUser = await wechatService.getUser(code)
// 创建或更新用户
const user = await authService.createOrUpdateUser(wechatUser, userInfo)
// 生成JWT token
const token = authService.generateToken(user._id)
return successResponse(res, {
token,
userInfo: user
}, '登录成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
// 绑定手机号
async bindPhone(req, res) {
try {
const { encryptedData, iv } = req.body
const userId = req.user.id
// 解密手机号
const phoneData = await wechatService.decryptData(encryptedData, iv)
// 更新用户手机号
await authService.bindPhone(userId, phoneData.phoneNumber)
return successResponse(res, { phone: phoneData.phoneNumber }, '绑定成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
// 刷新token
async refreshToken(req, res) {
try {
const { refreshToken } = req.body
const newToken = await authService.refreshToken(refreshToken)
return successResponse(res, { token: newToken }, 'Token刷新成功')
} catch (error) {
return errorResponse(res, error.message, 401)
}
}
}
module.exports = new AuthController()const jwt = require('jsonwebtoken')
const bcrypt = require('bcryptjs')
const User = require('../models/User')
const config = require('../config')
class AuthService {
// 生成JWT token
generateToken(userId) {
return jwt.sign(
{ userId },
config.jwt.secret,
{ expiresIn: config.jwt.expiresIn }
)
}
// 验证token
verifyToken(token) {
return jwt.verify(token, config.jwt.secret)
}
// 创建或更新用户
async createOrUpdateUser(wechatUser, userInfo) {
const { openid, unionid } = wechatUser
let user = await User.findOne({ openid })
if (user) {
// 更新用户信息
user.nickName = userInfo.nickName
user.avatarUrl = userInfo.avatarUrl
user.lastLoginAt = new Date()
await user.save()
} else {
// 创建新用户
user = new User({
openid,
unionid,
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
isVip: false,
points: 0,
level: 1,
createdAt: new Date(),
lastLoginAt: new Date()
})
await user.save()
}
return user
}
// 绑定手机号
async bindPhone(userId, phone) {
const user = await User.findById(userId)
if (!user) {
throw new Error('用户不存在')
}
user.phone = phone
await user.save()
return user
}
}
module.exports = new AuthService()const orderService = require('../services/order')
const paymentService = require('../services/payment')
const { successResponse, errorResponse } = require('../utils/response')
class OrderController {
// 创建订单
async createOrder(req, res) {
try {
const { packageId, paymentMethod } = req.body
const userId = req.user.id
// 创建订单
const order = await orderService.createOrder(userId, packageId)
// 生成支付信息
const paymentInfo = await paymentService.createPayment(order, paymentMethod)
return successResponse(res, {
orderId: order._id,
paymentInfo
}, '订单创建成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
// 支付回调
async paymentCallback(req, res) {
try {
const paymentData = req.body
// 验证支付结果
const isValid = await paymentService.verifyPayment(paymentData)
if (!isValid) {
throw new Error('支付验证失败')
}
// 更新订单状态
await orderService.updateOrderStatus(paymentData.orderId, 'paid')
return successResponse(res, null, '支付成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
// 获取订单列表
async getOrders(req, res) {
try {
const userId = req.user.id
const { page = 1, limit = 10, status } = req.query
const orders = await orderService.getUserOrders(userId, {
page: parseInt(page),
limit: parseInt(limit),
status
})
return successResponse(res, orders, '获取成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
}
module.exports = new OrderController()const contentService = require('../services/content')
const { successResponse, errorResponse } = require('../utils/response')
class ContentController {
// 获取模块内容
async getModuleContent(req, res) {
try {
const { moduleId } = req.params
const { orderId } = req.query
const userId = req.user.id
// 验证用户权限
const hasAccess = await contentService.checkAccess(userId, orderId, moduleId)
if (!hasAccess) {
return errorResponse(res, '无访问权限', 403)
}
// 获取内容
const content = await contentService.getContent(moduleId, orderId)
return successResponse(res, content, '获取成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
// 更新学习进度
async updateProgress(req, res) {
try {
const { orderId, moduleId, sectionId, action, timeSpent } = req.body
const userId = req.user.id
await contentService.updateProgress(userId, orderId, moduleId, sectionId, action, timeSpent)
return successResponse(res, null, '进度更新成功')
} catch (error) {
return errorResponse(res, error.message, 400)
}
}
}
module.exports = new ContentController()const mongoose = require('mongoose')
const config = require('./index')
class Database {
constructor() {
this.connect()
}
connect() {
mongoose.connect(config.database.mongodb.uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
})
mongoose.connection.on('connected', () => {
console.log('MongoDB connected successfully')
})
mongoose.connection.on('error', (err) => {
console.error('MongoDB connection error:', err)
})
mongoose.connection.on('disconnected', () => {
console.log('MongoDB disconnected')
})
// 优雅关闭
process.on('SIGINT', async () => {
await mongoose.connection.close()
console.log('MongoDB connection closed through app termination')
process.exit(0)
})
}
}
module.exports = new Database()const redis = require('redis')
const config = require('../config')
class RedisClient {
constructor() {
this.client = redis.createClient({
host: config.redis.host,
port: config.redis.port,
password: config.redis.password,
db: config.redis.db
})
this.client.on('connect', () => {
console.log('Redis connected successfully')
})
this.client.on('error', (err) => {
console.error('Redis connection error:', err)
})
}
// 设置缓存
async set(key, value, expire = 3600) {
const data = JSON.stringify(value)
if (expire) {
return await this.client.setex(key, expire, data)
}
return await this.client.set(key, data)
}
// 获取缓存
async get(key) {
const data = await this.client.get(key)
return data ? JSON.parse(data) : null
}
// 删除缓存
async del(key) {
return await this.client.del(key)
}
// 检查键是否存在
async exists(key) {
return await this.client.exists(key)
}
}
module.exports = new RedisClient()const jwt = require('jsonwebtoken')
const User = require('../models/User')
const config = require('../config')
const { errorResponse } = require('../utils/response')
const authMiddleware = async (req, res, next) => {
try {
const token = req.header('Authorization')?.replace('Bearer ', '')
if (!token) {
return errorResponse(res, '未提供认证token', 401)
}
const decoded = jwt.verify(token, config.jwt.secret)
const user = await User.findById(decoded.userId)
if (!user) {
return errorResponse(res, '用户不存在', 401)
}
req.user = user
next()
} catch (error) {
return errorResponse(res, '认证失败', 401)
}
}
// 可选认证中间件
const optionalAuth = async (req, res, next) => {
try {
const token = req.header('Authorization')?.replace('Bearer ', '')
if (token) {
const decoded = jwt.verify(token, config.jwt.secret)
const user = await User.findById(decoded.userId)
req.user = user
}
next()
} catch (error) {
next()
}
}
module.exports = {
authMiddleware,
optionalAuth
}const rateLimit = require('express-rate-limit')
const RedisStore = require('rate-limit-redis')
const redis = require('../utils/redis')
// 通用限流
const generalLimiter = rateLimit({
store: new RedisStore({
client: redis.client
}),
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 最多100次请求
message: {
code: 429,
message: '请求过于频繁,请稍后再试'
}
})
// 登录限流
const loginLimiter = rateLimit({
store: new RedisStore({
client: redis.client
}),
windowMs: 15 * 60 * 1000, // 15分钟
max: 5, // 最多5次登录尝试
skipSuccessfulRequests: true,
message: {
code: 429,
message: '登录尝试过于频繁,请15分钟后再试'
}
})
// 支付限流
const paymentLimiter = rateLimit({
store: new RedisStore({
client: redis.client
}),
windowMs: 60 * 1000, // 1分钟
max: 3, // 最多3次支付请求
message: {
code: 429,
message: '支付请求过于频繁,请稍后再试'
}
})
module.exports = {
generalLimiter,
loginLimiter,
paymentLimiter
}const logger = require('../utils/logger')
const errorHandler = (err, req, res, next) => {
let error = { ...err }
error.message = err.message
// 记录错误日志
logger.error(err)
// Mongoose错误处理
if (err.name === 'CastError') {
const message = '资源未找到'
error = { message, statusCode: 404 }
}
// Mongoose重复字段错误
if (err.code === 11000) {
const message = '数据已存在'
error = { message, statusCode: 400 }
}
// Mongoose验证错误
if (err.name === 'ValidationError') {
const message = Object.values(err.errors).map(val => val.message).join(', ')
error = { message, statusCode: 400 }
}
// JWT错误
if (err.name === 'JsonWebTokenError') {
const message = '无效的token'
error = { message, statusCode: 401 }
}
// JWT过期错误
if (err.name === 'TokenExpiredError') {
const message = 'Token已过期'
error = { message, statusCode: 401 }
}
res.status(error.statusCode || 500).json({
code: error.statusCode || 500,
message: error.message || '服务器内部错误',
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
})
}
module.exports = errorHandlerconst crypto = require('crypto')
const axios = require('axios')
const config = require('../config')
class WechatService {
constructor() {
this.appId = config.wechat.appId
this.appSecret = config.wechat.appSecret
}
// 获取access_token
async getAccessToken() {
const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`
const response = await axios.get(url)
if (response.data.errcode) {
throw new Error(`获取access_token失败: ${response.data.errmsg}`)
}
return response.data.access_token
}
// 通过code获取用户信息
async getUser(code) {
const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${this.appId}&secret=${this.appSecret}&js_code=${code}&grant_type=authorization_code`
const response = await axios.get(url)
if (response.data.errcode) {
throw new Error(`获取用户信息失败: ${response.data.errmsg}`)
}
return {
openid: response.data.openid,
unionid: response.data.unionid,
sessionKey: response.data.session_key
}
}
// 解密数据
decryptData(encryptedData, iv, sessionKey) {
const decipher = crypto.createDecipheriv('aes-128-cbc', Buffer.from(sessionKey, 'base64'), Buffer.from(iv, 'base64'))
decipher.setAutoPadding(true)
let decrypted = decipher.update(encryptedData, 'base64', 'utf8')
decrypted += decipher.final('utf8')
return JSON.parse(decrypted)
}
// 发送模板消息
async sendTemplateMessage(openid, templateId, data, page) {
const accessToken = await this.getAccessToken()
const url = `https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=${accessToken}`
const payload = {
touser: openid,
template_id: templateId,
page,
data
}
const response = await axios.post(url, payload)
if (response.data.errcode !== 0) {
throw new Error(`发送模板消息失败: ${response.data.errmsg}`)
}
return response.data
}
}
module.exports = new WechatService()const crypto = require('crypto')
const axios = require('axios')
const config = require('../config')
class PaymentService {
constructor() {
this.appId = config.wechat.appId
this.mchId = config.payment.mchId
this.key = config.payment.key
this.notifyUrl = config.payment.notifyUrl
}
// 创建支付订单
async createPayment(order, paymentMethod = 'wechat') {
if (paymentMethod === 'wechat') {
return await this.createWechatPayment(order)
}
throw new Error('不支持的支付方式')
}
// 创建微信支付订单
async createWechatPayment(order) {
const params = {
appid: this.appId,
mch_id: this.mchId,
nonce_str: this.generateNonceStr(),
body: `闪电准备包-${order.packageId}`,
out_trade_no: order._id.toString(),
total_fee: Math.round(order.price * 100), // 转换为分
spbill_create_ip: '127.0.0.1',
notify_url: this.notifyUrl,
trade_type: 'JSAPI',
openid: order.userId.openid
}
// 生成签名
params.sign = this.generateSign(params)
// 转换为XML
const xml = this.objectToXml(params)
// 发送请求
const response = await axios.post('https://api.mch.weixin.qq.com/pay/unifiedorder', xml, {
headers: { 'Content-Type': 'application/xml' }
})
const result = this.xmlToObject(response.data)
if (result.return_code !== 'SUCCESS' || result.result_code !== 'SUCCESS') {
throw new Error(`微信支付创建失败: ${result.err_code_des || result.return_msg}`)
}
// 生成小程序支付参数
const paymentInfo = {
appId: this.appId,
timeStamp: Math.floor(Date.now() / 1000).toString(),
nonceStr: this.generateNonceStr(),
package: `prepay_id=${result.prepay_id}`,
signType: 'MD5'
}
paymentInfo.paySign = this.generateSign(paymentInfo)
return paymentInfo
}
// 验证支付结果
async verifyPayment(paymentData) {
const sign = paymentData.sign
delete paymentData.sign
const generatedSign = this.generateSign(paymentData)
return sign === generatedSign && paymentData.result_code === 'SUCCESS'
}
// 生成随机字符串
generateNonceStr() {
return crypto.randomBytes(16).toString('hex')
}
// 生成签名
generateSign(params) {
const sortedKeys = Object.keys(params).sort()
const stringA = sortedKeys.map(key => `${key}=${params[key]}`).join('&')
const stringSignTemp = `${stringA}&key=${this.key}`
return crypto.createHash('md5').update(stringSignTemp).digest('hex').toUpperCase()
}
// 对象转XML
objectToXml(obj) {
let xml = '<xml>'
for (const key in obj) {
xml += `<${key}>${obj[key]}</${key}>`
}
xml += '</xml>'
return xml
}
// XML转对象
xmlToObject(xml) {
const result = {}
const regex = /<(\w+)>([^<]*)<\/\1>/g
let match
while ((match = regex.exec(xml)) !== null) {
result[match[1]] = match[2]
}
return result
}
}
module.exports = new PaymentService()# 应用配置
NODE_ENV=development
PORT=3005
APP_NAME=闪电准备包
# 数据库配置
MONGODB_URI=mongodb://localhost:27017/lightning-prep
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# JWT配置
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRES_IN=7d
# 微信配置
WECHAT_APP_ID=your_wechat_app_id
WECHAT_APP_SECRET=your_wechat_app_secret
# 微信支付配置
WECHAT_MCH_ID=your_mch_id
WECHAT_PAY_KEY=your_pay_key
WECHAT_NOTIFY_URL=https://your-domain.com/api/v1/orders/payment-callback
# 邮件配置
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your_email@gmail.com
EMAIL_PASS=your_email_password
# 文件上传配置
UPLOAD_PATH=./uploads
MAX_FILE_SIZE=5242880
# 日志配置
LOG_LEVEL=info
LOG_FILE=./logs/app.logrequire('dotenv').config()
module.exports = {
app: {
name: process.env.APP_NAME || '闪电准备包',
port: process.env.PORT || 3000,
env: process.env.NODE_ENV || 'development'
},
database: {
mongodb: {
uri: process.env.MONGODB_URI || 'mongodb://localhost:27017/lightning-prep'
}
},
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: process.env.REDIS_PORT || 6379,
password: process.env.REDIS_PASSWORD || '',
db: process.env.REDIS_DB || 0
},
jwt: {
secret: process.env.JWT_SECRET || 'your_jwt_secret',
expiresIn: process.env.JWT_EXPIRES_IN || '7d'
},
wechat: {
appId: process.env.WECHAT_APP_ID,
appSecret: process.env.WECHAT_APP_SECRET
},
payment: {
mchId: process.env.WECHAT_MCH_ID,
key: process.env.WECHAT_PAY_KEY,
notifyUrl: process.env.WECHAT_NOTIFY_URL
},
email: {
host: process.env.EMAIL_HOST,
port: process.env.EMAIL_PORT,
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS
},
upload: {
path: process.env.UPLOAD_PATH || './uploads',
maxSize: process.env.MAX_FILE_SIZE || 5242880
},
log: {
level: process.env.LOG_LEVEL || 'info',
file: process.env.LOG_FILE || './logs/app.log'
}
}const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const morgan = require('morgan')
const path = require('path')
// 导入配置和工具
const config = require('./config')
const logger = require('./src/utils/logger')
const errorHandler = require('./src/middleware/error')
const { generalLimiter } = require('./src/middleware/rateLimit')
// 导入路由
const routes = require('./src/routes')
// 导入数据库连接
require('./config/database')
const app = express()
// 基础中间件
app.use(helmet())
app.use(cors())
app.use(express.json({ limit: '10mb' }))
app.use(express.urlencoded({ extended: true }))
app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } }))
// 限流中间件
app.use(generalLimiter)
// 静态文件服务
app.use('/uploads', express.static(path.join(__dirname, 'uploads')))
// API路由
app.use('/api/v1', routes)
// 健康检查
app.get('/health', (req, res) => {
res.json({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: process.uptime()
})
})
// 404处理
app.use('*', (req, res) => {
res.status(404).json({
code: 404,
message: '接口不存在'
})
})
// 错误处理中间件
app.use(errorHandler)
module.exports = appconst app = require('./app')
const config = require('./config')
const logger = require('./src/utils/logger')
const PORT = config.app.port
const server = app.listen(PORT, () => {
logger.info(`🚀 服务器启动成功,端口: ${PORT}`)
logger.info(`🌍 环境: ${config.app.env}`)
logger.info(`📱 应用: ${config.app.name}`)
})
// 优雅关闭
process.on('SIGTERM', () => {
logger.info('收到SIGTERM信号,开始优雅关闭...')
server.close(() => {
logger.info('服务器已关闭')
process.exit(0)
})
})
process.on('SIGINT', () => {
logger.info('收到SIGINT信号,开始优雅关闭...')
server.close(() => {
logger.info('服务器已关闭')
process.exit(0)
})
})
// 未捕获异常处理
process.on('uncaughtException', (err) => {
logger.error('未捕获异常:', err)
process.exit(1)
})
process.on('unhandledRejection', (err) => {
logger.error('未处理的Promise拒绝:', err)
server.close(() => {
process.exit(1)
})
})本后端架构设计具有以下特点:
- 分层架构:控制器、服务、模型分离,职责清晰
- 模块化设计:功能模块独立,便于维护和扩展
- 安全性:JWT认证、限流、数据验证、错误处理
- 可扩展性:支持微信支付、消息推送、文件上传等功能
- 高性能:Redis缓存、数据库优化、连接池管理
- 可监控:完善的日志系统、健康检查、错误追踪
通过这个架构,可以确保系统的稳定性、安全性和可维护性。