#!/usr/bin/env node /** * 静态资源 + API 服务。统计、点赞、分享、留言(弹幕)写入 SQLite。 * 用法: node server.js [目录] 默认目录为项目根目录。 */ const path = require('path'); const express = require('express'); const db = require('./db.js'); const PORT = process.env.PORT || 3000; const ROOT = path.resolve(__dirname, process.argv[2] || '.'); db.initDb(); const app = express(); app.use(express.json()); app.use(express.static(ROOT)); app.get('/api/stats', (req, res) => { try { res.json(db.getStats()); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.post('/api/view', (req, res) => { try { res.json(db.incView()); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.post('/api/like', (req, res) => { try { res.json(db.incLike()); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.post('/api/share', (req, res) => { try { res.json(db.incShare()); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.post('/api/join', (req, res) => { try { const viewerId = req.body && req.body.viewerId ? String(req.body.viewerId) : null; if (!viewerId) { return res.status(400).json({ error: 'viewerId required' }); } const watchingNow = db.joinViewer(viewerId); res.json({ watchingNow }); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.post('/api/leave', (req, res) => { try { const viewerId = req.body && req.body.viewerId ? String(req.body.viewerId) : null; if (!viewerId) { return res.status(400).json({ error: 'viewerId required' }); } const watchingNow = db.leaveViewer(viewerId); res.json({ watchingNow }); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.get('/api/comments', (req, res) => { try { const limit = Math.min(parseInt(req.query.limit, 10) || 100, 200); res.json(db.getComments(limit)); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.post('/api/comments', (req, res) => { try { const content = req.body && req.body.content != null ? String(req.body.content) : ''; const nickname = req.body && req.body.nickname != null ? String(req.body.nickname) : ''; if (!content.trim()) { return res.status(400).json({ error: 'content required' }); } const comment = db.addComment(content.trim(), nickname.trim() || null); res.json(comment); } catch (e) { res.status(500).json({ error: String(e.message) }); } }); app.listen(PORT, () => { console.log('已启动: http://localhost:' + PORT); });