P0 - AI交互层:
- ai/prompt.js: 模块化 Prompt 模板
- ai/validator.js: JSON Schema 校验 + normalize
- ai/client.js: DeepSeek API 封装
- 金额计算唯一化,时间格式归一化
P1 - 后端架构:
- routes/: auth/rooms/messages/purchases 独立路由
- middleware/auth.js: 认证授权中间件
- ws/index.js: WebSocket 连接管理
- db.js: 启用 foreign_keys
- server.js: 从588行精简到40行入口
P2 - 前端架构:
- public/css/style.css: CSS 独立
- public/js/store.js: 全局状态 Store
- public/js/{chat,ws,purchases,auth}.js: 功能模块拆分
- index.html: 纯 HTML 结构, v2.6
62 lines
1.9 KiB
JavaScript
62 lines
1.9 KiB
JavaScript
// 入口文件 — 组装所有模块
|
|
const express = require('express');
|
|
const http = require('http');
|
|
const { WebSocketServer } = require('ws');
|
|
const multer = require('multer');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const { v4: uuidv4 } = require('uuid');
|
|
const db = require('./db');
|
|
const wsModule = require('./ws');
|
|
const { authMiddleware } = require('./middleware/auth');
|
|
|
|
const app = express();
|
|
const server = http.createServer(app);
|
|
const wss = new WebSocketServer({ server });
|
|
|
|
// 中间件
|
|
app.use(express.json());
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
// 上传目录
|
|
const uploadsDir = path.join(__dirname, '..', 'data', 'uploads');
|
|
if (!fs.existsSync(uploadsDir)) fs.mkdirSync(uploadsDir, { recursive: true });
|
|
app.use('/uploads', express.static(uploadsDir));
|
|
|
|
// Multer 配置
|
|
const storage = multer.diskStorage({
|
|
destination: uploadsDir,
|
|
filename: (req, file, cb) => {
|
|
const ext = path.extname(file.originalname);
|
|
const safeName = uuidv4().replace(/-/g, '').substring(0, 12);
|
|
cb(null, safeName + ext);
|
|
}
|
|
});
|
|
const upload = multer({
|
|
storage,
|
|
limits: { fileSize: 10 * 1024 * 1024 },
|
|
fileFilter: (req, file, cb) => {
|
|
const allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
|
cb(null, allowed.includes(file.mimetype));
|
|
}
|
|
});
|
|
|
|
// 路由
|
|
app.use('/api', require('./routes/auth'));
|
|
app.use('/api/rooms', require('./routes/rooms'));
|
|
app.use('/api/rooms', require('./routes/messages'));
|
|
app.use('/api', require('./routes/purchases'));
|
|
|
|
// 上传
|
|
app.post('/api/upload', authMiddleware, upload.single('file'), (req, res) => {
|
|
if (!req.file) return res.status(400).json({ error: '请上传图片' });
|
|
res.json({ path: '/uploads/' + req.file.filename });
|
|
});
|
|
|
|
// WebSocket
|
|
wsModule.init(wss);
|
|
|
|
// 启动
|
|
const PORT = process.env.PORT || 3000;
|
|
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
|