import express from 'express' import cors from 'cors' import helmet from 'helmet' import morgan from 'morgan' import compression from 'compression' import { errorHandler } from './middleware/errorHandler' import { apiLimiter } from './middleware/rateLimit' const app = express() app.set('trust proxy', 1) app.use(helmet()) app.use(compression({ filter: (req, res) => { // SSE 流式响应不压缩,避免缓冲导致前端一次性收到所有数据 if (req.headers['accept'] === 'text/event-stream' || res.getHeader('Content-Type') === 'text/event-stream') { return false } return compression.filter(req, res) }, })) app.use( cors({ origin: process.env.CORS_ORIGIN || 'http://localhost:5173', credentials: true, }), ) app.use(express.json({ limit: '10mb' })) app.use(morgan('dev')) app.get('/health', (_req, res) => { res.json({ success: true, data: { status: 'ok', timestamp: new Date().toISOString() } }) }) app.use('/api/v1', apiLimiter) // 路由挂载 import authRoutes from './routes/auth.routes' import dashboardRoutes from './routes/dashboard.routes' import employeeRoutes from './routes/employee.routes' import terminationRoutes from './routes/termination.routes' import aiRoutes from './routes/ai.routes' import portalRoutes from './routes/portal.routes' import settingsRoutes from './routes/settings.routes' import payrollRoutes from './routes/payroll.routes' import payroll2Routes from './routes/payroll2.routes' import socialRoutes from './routes/social.routes' import notificationRoutes from './routes/notification.routes' import attachmentRoutes from './routes/attachment.routes' import rosterRoutes from './routes/roster.routes' import exportRoutes from './routes/export.routes' import importRoutes from './routes/import.routes' import evidenceRoutes from './routes/evidence.routes' import policyRoutes from './routes/policy.routes' import attendanceRoutes from './routes/attendance.routes' import templateRoutes from './routes/template.routes' import auditRoutes from './routes/audit.routes' import calendarRoutes from './routes/calendar.routes' import platformRoutes from './routes/platform.routes' import workProcessRoutes from './routes/work-process.routes' import enterpriseTemplateRoutes from './routes/enterprise-template.routes' import specialStatusRoutes from './routes/special-status.routes' app.use('/api/v1/auth', authRoutes) app.use('/api/v1/dashboard', dashboardRoutes) app.use('/api/v1/employees', employeeRoutes) app.use('/api/v1/termination', terminationRoutes) app.use('/api/v1/ai', aiRoutes) app.use('/api/v1/portal', portalRoutes) app.use('/api/v1/settings', settingsRoutes) app.use('/api/v1/payroll', payrollRoutes) app.use('/api/v1/payroll2', payroll2Routes) app.use('/api/v1/social', socialRoutes) app.use('/api/v1/notifications', notificationRoutes) app.use('/api/v1/attachments', attachmentRoutes) app.use('/api/v1/roster', rosterRoutes) app.use('/api/v1/export', exportRoutes) app.use('/api/v1/import', importRoutes) app.use('/api/v1/evidence', evidenceRoutes) app.use('/api/v1/policies', policyRoutes) app.use('/api/v1/attendance', attendanceRoutes) app.use('/api/v1/templates', templateRoutes) app.use('/api/v1/audit', auditRoutes) app.use('/api/v1/calendar', calendarRoutes) app.use('/api/v1/platform', platformRoutes) app.use('/api/v1/work-processes', workProcessRoutes) app.use('/api/v1/enterprise-templates', enterpriseTemplateRoutes) app.use('/api/v1/special-statuses', specialStatusRoutes) app.use(errorHandler) // RAG 知识库自动初始化(异步,不阻塞启动) import { seedKnowledgeBase } from './services/rag.service' seedKnowledgeBase().catch((err) => { console.warn('[RAG] 知识库初始化失败,AI 问答将不使用 RAG 检索:', err?.message || err) }) export default app