Files
usa/server/routes.js
2026-03-02 14:23:36 +08:00

140 lines
3.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const express = require('express')
const { getSituation } = require('./situationData')
const db = require('./db')
const router = express.Router()
// 数据库 Dashboard返回各表原始数据
router.get('/db/dashboard', (req, res) => {
try {
const tables = [
'feedback',
'situation',
'force_summary',
'power_index',
'force_asset',
'key_location',
'combat_losses',
'wall_street_trend',
'retaliation_current',
'retaliation_history',
'situation_update',
'gdelt_events',
'conflict_stats',
]
const data = {}
const timeSort = {
feedback: 'created_at DESC',
situation: 'updated_at DESC',
situation_update: 'timestamp DESC',
gdelt_events: 'event_time DESC',
wall_street_trend: 'time DESC',
retaliation_history: 'time DESC',
conflict_stats: 'updated_at DESC',
}
for (const name of tables) {
try {
const order = timeSort[name]
let rows
try {
rows = order
? db.prepare(`SELECT * FROM ${name} ORDER BY ${order}`).all()
: db.prepare(`SELECT * FROM ${name}`).all()
} catch (qerr) {
rows = db.prepare(`SELECT * FROM ${name}`).all()
}
data[name] = rows
} catch (e) {
data[name] = { error: e.message }
}
}
res.json(data)
} catch (err) {
console.error(err)
res.status(500).json({ error: err.message })
}
})
router.get('/situation', (req, res) => {
try {
res.json(getSituation())
} catch (err) {
console.error(err)
res.status(500).json({ error: err.message })
}
})
// 来访统计:记录 IP返回在看/累积
function getClientIp(req) {
const forwarded = req.headers['x-forwarded-for']
if (forwarded) return forwarded.split(',')[0].trim()
return req.ip || req.socket?.remoteAddress || 'unknown'
}
router.post('/visit', (req, res) => {
try {
const ip = getClientIp(req)
db.prepare(
"INSERT OR REPLACE INTO visits (ip, last_seen) VALUES (?, datetime('now'))"
).run(ip)
db.prepare(
'INSERT INTO visitor_count (id, total) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET total = total + 1'
).run()
const viewers = db.prepare(
"SELECT COUNT(*) as n FROM visits WHERE last_seen > datetime('now', '-2 minutes')"
).get().n
const cumulative = db.prepare('SELECT total FROM visitor_count WHERE id = 1').get()?.total ?? 0
res.json({ viewers, cumulative })
} catch (err) {
console.error(err)
res.status(500).json({ viewers: 0, cumulative: 0 })
}
})
router.post('/feedback', (req, res) => {
try {
const content = (req.body?.content ?? '').toString().trim()
if (!content || content.length > 2000) {
return res.status(400).json({ ok: false, error: '留言内容 12000 字' })
}
const ip = getClientIp(req)
db.prepare(
'INSERT INTO feedback (content, ip) VALUES (?, ?)'
).run(content.slice(0, 2000), ip)
res.json({ ok: true })
} catch (err) {
console.error(err)
res.status(500).json({ ok: false, error: err.message })
}
})
router.get('/stats', (req, res) => {
try {
const viewers = db.prepare(
"SELECT COUNT(*) as n FROM visits WHERE last_seen > datetime('now', '-2 minutes')"
).get().n
const cumulative = db.prepare('SELECT total FROM visitor_count WHERE id = 1').get()?.total ?? 0
res.json({ viewers, cumulative })
} catch (err) {
console.error(err)
res.status(500).json({ viewers: 0, cumulative: 0 })
}
})
router.get('/events', (req, res) => {
try {
const s = getSituation()
res.json({
updated_at: s.lastUpdated,
count: (s.conflictEvents || []).length,
events: s.conflictEvents || [],
conflict_stats: s.conflictStats || {},
})
} catch (err) {
console.error(err)
res.status(500).json({ error: err.message })
}
})
module.exports = router