Files
miniapp-api/src/app.js
T
Developer 608ee017d4 fix: 配置微信小程序域名的跨域 CORS
- 添加 servicewechat.com、miniapp-api-test.dxz99wyr.cn、api-miniapp.dxz99wyr.cn 到 CORS origin
- 允许 GET/POST/PUT/DELETE/OPTIONS 方法
- 允许 Content-Type/Authorization/Accept/Origin/X-Requested-With 请求头
2026-05-18 21:41:42 +08:00

129 lines
4.4 KiB
JavaScript

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const path = require('path');
require('dotenv').config();
const connectDB = require('./config/database');
const errorHandler = require('./middleware/errorHandler');
const { notFound } = require('./middleware/notFound');
const authRoutes = require('./routes/auth');
const equityRoutes = require('./routes/equity');
const userRoutes = require('./routes/user');
const tradeRoutes = require('./routes/trade');
const userEquityRoutes = require('./routes/userEquity');
const ocrRoutes = require('./routes/ocr');
const presetRoutes = require('./routes/preset');
const equityDetailRoutes = require('./routes/equityDetail');
const membershipRoutes = require('./routes/membership');
const settingsRoutes = require('./routes/settings');
const subscribeRoutes = require('./routes/subscribe');
const uploadRoutes = require('./routes/upload');
const wechatMessageRoutes = require('./routes/wechatMessage');
const cron = require('node-cron');
const app = express();
connectDB();
app.use(helmet({
crossOriginResourcePolicy: false,
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
scriptSrcAttr: ["'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'", "https:"],
imgSrc: ["*", "data:", "blob:"],
connectSrc: ["'self'", "https:", "http:"],
},
},
}));
app.use(cors({
origin: [
'https://servicewechat.com',
'https://miniapp-api-test.dxz99wyr.cn',
'https://api-miniapp.dxz99wyr.cn'
],
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'Accept', 'Origin', 'X-Requested-With'],
credentials: false
}));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
}
app.use('/uploads', express.static(path.join(__dirname, '../public/uploads')));
app.use('/admin', express.static(path.join(__dirname, '../public/admin')));
app.get('/health', (req, res) => {
res.json({
status: 'ok',
timestamp: new Date().toISOString(),
service: 'quanyixiaozhushou-backend'
});
});
app.use('/api/auth', authRoutes);
app.use('/api/equity', equityRoutes);
app.use('/api/user', userRoutes);
app.use('/api/trade', tradeRoutes);
app.use('/api/user-equity', userEquityRoutes);
app.use('/api/ocr', ocrRoutes);
app.use('/api/presets', presetRoutes);
app.use('/api/equity-detail', equityDetailRoutes);
app.use('/api/membership', membershipRoutes);
app.use('/api/settings', settingsRoutes);
app.use('/api/subscribe', subscribeRoutes);
app.use('/api/upload', uploadRoutes);
app.use('/wechat-message', wechatMessageRoutes);
const adminRoutes = require('./routes/admin');
app.use('/api/admin', adminRoutes);
const { sendExpiryReminders } = require('./routes/subscribe');
cron.schedule('40 9 * * *', async () => {
console.log(`[${new Date().toISOString()}] ⏰ 到期提醒定时任务开始执行...`);
try {
const results = await sendExpiryReminders();
console.log(`[${new Date().toISOString()}] ✅ 到期提醒执行完成: 共${results.total}条, 发送成功${results.sent}条, 失败${results.failed}`);
if (results.errors.length > 0) {
console.error('失败详情:', JSON.stringify(results.errors.slice(0, 10)));
}
} catch (error) {
console.error(`[${new Date().toISOString()}] ❌ 到期提醒执行失败:`, error.message);
}
}, {
timezone: 'Asia/Shanghai'
});
app.use(notFound);
app.use(errorHandler);
const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => {
console.log(`🚀 权益小助手后端服务运行在端口 ${PORT}`);
console.log(`📊 环境: ${process.env.NODE_ENV || 'development'}`);
console.log(`🌐 访问地址: https://api-miniapp.dxz99wyr.cn`);
});
process.on('uncaughtException', (error) => {
console.error('💥 未捕获异常 - 进程即将退出:', error.message);
console.error('Stack:', error.stack);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('💥 未处理的Promise拒绝:', reason);
if (reason && reason.stack) console.error('Stack:', reason.stack);
});
module.exports = app;