fix: 优化docker 镜像
This commit is contained in:
Binary file not shown.
Binary file not shown.
17
server/db.js
17
server/db.js
@@ -1,7 +1,7 @@
|
||||
const Database = require('better-sqlite3')
|
||||
const path = require('path')
|
||||
|
||||
const dbPath = path.join(__dirname, 'data.db')
|
||||
const dbPath = process.env.DB_PATH || path.join(__dirname, 'data.db')
|
||||
const db = new Database(dbPath)
|
||||
|
||||
// 启用外键
|
||||
@@ -147,4 +147,19 @@ addUpdatedAt('force_asset')
|
||||
addUpdatedAt('key_location')
|
||||
addUpdatedAt('retaliation_current')
|
||||
|
||||
// 来访统计:visits 用于在看(近期活跃 IP),visitor_count 用于累积人次(每次接入 +1)
|
||||
try {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS visits (
|
||||
ip TEXT PRIMARY KEY,
|
||||
last_seen TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS visitor_count (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
total INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
INSERT OR IGNORE INTO visitor_count (id, total) VALUES (1, 0);
|
||||
`)
|
||||
} catch (_) {}
|
||||
|
||||
module.exports = db
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const http = require('http')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const express = require('express')
|
||||
const cors = require('cors')
|
||||
const { WebSocketServer } = require('ws')
|
||||
@@ -8,6 +10,7 @@ const { getSituation } = require('./situationData')
|
||||
const app = express()
|
||||
const PORT = process.env.API_PORT || 3001
|
||||
|
||||
app.set('trust proxy', 1)
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
app.use('/api', routes)
|
||||
@@ -17,6 +20,17 @@ app.post('/api/crawler/notify', (_, res) => {
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// 生产环境:提供前端静态文件
|
||||
const distPath = path.join(__dirname, '..', 'dist')
|
||||
if (fs.existsSync(distPath)) {
|
||||
app.use(express.static(distPath))
|
||||
app.get('*', (req, res, next) => {
|
||||
if (!req.path.startsWith('/api') && req.path !== '/ws') {
|
||||
res.sendFile(path.join(distPath, 'index.html'))
|
||||
} else next()
|
||||
})
|
||||
}
|
||||
|
||||
const server = http.createServer(app)
|
||||
|
||||
const wss = new WebSocketServer({ server, path: '/ws' })
|
||||
|
||||
@@ -62,6 +62,46 @@ router.get('/situation', (req, res) => {
|
||||
}
|
||||
})
|
||||
|
||||
// 来访统计:记录 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.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()
|
||||
|
||||
Reference in New Issue
Block a user