608ee017d4
- 添加 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 请求头
129 lines
4.4 KiB
JavaScript
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;
|