fix: 移除繁体转简体和资讯
This commit is contained in:
29
package-lock.json
generated
29
package-lock.json
generated
@@ -20,6 +20,7 @@
|
|||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-map-gl": "^7.1.7",
|
"react-map-gl": "^7.1.7",
|
||||||
"react-router-dom": "^7.13.1",
|
"react-router-dom": "^7.13.1",
|
||||||
|
"swagger-ui-express": "^5.0.1",
|
||||||
"ws": "^8.19.0",
|
"ws": "^8.19.0",
|
||||||
"zustand": "^5.0.0"
|
"zustand": "^5.0.0"
|
||||||
},
|
},
|
||||||
@@ -1344,6 +1345,12 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@scarf/scarf": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@scarf/scarf/-/scarf-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
|
||||||
|
"hasInstallScript": true
|
||||||
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||||
@@ -5023,6 +5030,28 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/swagger-ui-dist": {
|
||||||
|
"version": "5.32.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/swagger-ui-dist/-/swagger-ui-dist-5.32.0.tgz",
|
||||||
|
"integrity": "sha512-nKZB0OuDvacB0s/lC2gbge+RigYvGRGpLLMWMFxaTUwfM+CfndVk9Th2IaTinqXiz6Mn26GK2zriCpv6/+5m3Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@scarf/scarf": "=1.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/swagger-ui-express": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==",
|
||||||
|
"dependencies": {
|
||||||
|
"swagger-ui-dist": ">=5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= v0.10.32"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"express": ">=4.0.0 || >=5.0.0-beta"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.19",
|
||||||
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.19.tgz",
|
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.19.tgz",
|
||||||
|
|||||||
@@ -24,11 +24,11 @@
|
|||||||
"express": "^4.21.1",
|
"express": "^4.21.1",
|
||||||
"lucide-react": "^0.460.0",
|
"lucide-react": "^0.460.0",
|
||||||
"mapbox-gl": "^3.6.0",
|
"mapbox-gl": "^3.6.0",
|
||||||
"opencc-js": "^1.0.5",
|
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-map-gl": "^7.1.7",
|
"react-map-gl": "^7.1.7",
|
||||||
"react-router-dom": "^7.13.1",
|
"react-router-dom": "^7.13.1",
|
||||||
|
"swagger-ui-express": "^5.0.1",
|
||||||
"ws": "^8.19.0",
|
"ws": "^8.19.0",
|
||||||
"zustand": "^5.0.0"
|
"zustand": "^5.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Binary file not shown.
@@ -7,12 +7,19 @@ const { WebSocketServer } = require('ws')
|
|||||||
const routes = require('./routes')
|
const routes = require('./routes')
|
||||||
const { getSituation } = require('./situationData')
|
const { getSituation } = require('./situationData')
|
||||||
|
|
||||||
|
const swaggerUi = require('swagger-ui-express')
|
||||||
|
const openApiSpec = require('./openapi')
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
const PORT = process.env.API_PORT || 3001
|
const PORT = process.env.API_PORT || 3001
|
||||||
|
|
||||||
app.set('trust proxy', 1)
|
app.set('trust proxy', 1)
|
||||||
app.use(cors())
|
app.use(cors())
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
|
|
||||||
|
// Swagger 文档
|
||||||
|
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiSpec))
|
||||||
|
|
||||||
app.use('/api', routes)
|
app.use('/api', routes)
|
||||||
app.get('/api/health', (_, res) => res.json({ ok: true }))
|
app.get('/api/health', (_, res) => res.json({ ok: true }))
|
||||||
app.post('/api/crawler/notify', (_, res) => {
|
app.post('/api/crawler/notify', (_, res) => {
|
||||||
@@ -58,4 +65,5 @@ function notifyCrawlerUpdate() {
|
|||||||
|
|
||||||
server.listen(PORT, () => {
|
server.listen(PORT, () => {
|
||||||
console.log(`API + WebSocket running at http://localhost:${PORT}`)
|
console.log(`API + WebSocket running at http://localhost:${PORT}`)
|
||||||
|
console.log(`Swagger docs at http://localhost:${PORT}/api-docs`)
|
||||||
})
|
})
|
||||||
|
|||||||
134
server/openapi.js
Normal file
134
server/openapi.js
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI 3.0 规范,供 Swagger UI 展示
|
||||||
|
*/
|
||||||
|
const PORT = process.env.API_PORT || 3001
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openapi: '3.0.3',
|
||||||
|
info: {
|
||||||
|
title: 'US-Iran Military Dashboard API',
|
||||||
|
version: '1.0.0',
|
||||||
|
description: '美伊军事态势面板后端接口',
|
||||||
|
},
|
||||||
|
servers: [{ url: `http://localhost:${PORT}`, description: '本地' }],
|
||||||
|
paths: {
|
||||||
|
'/api/situation': {
|
||||||
|
get: {
|
||||||
|
summary: '获取态势数据',
|
||||||
|
description: '战损、基地、新闻、冲突事件等完整态势',
|
||||||
|
tags: ['态势'],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: '态势 JSON',
|
||||||
|
content: { 'application/json': { schema: { type: 'object' } } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/db/dashboard': {
|
||||||
|
get: {
|
||||||
|
summary: '数据库面板',
|
||||||
|
description: '各表原始数据,供 /db 调试页',
|
||||||
|
tags: ['调试'],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: '各表数据',
|
||||||
|
content: { 'application/json': { schema: { type: 'object' } } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/visit': {
|
||||||
|
post: {
|
||||||
|
summary: '来访统计',
|
||||||
|
description: '记录 IP,返回当前在看人数和累积访问',
|
||||||
|
tags: ['统计'],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: 'OK',
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
viewers: { type: 'number' },
|
||||||
|
cumulative: { type: 'number' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/feedback': {
|
||||||
|
post: {
|
||||||
|
summary: '提交反馈',
|
||||||
|
description: '留言 1–2000 字',
|
||||||
|
tags: ['反馈'],
|
||||||
|
requestBody: {
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['content'],
|
||||||
|
properties: { content: { type: 'string', maxLength: 2000 } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: { description: 'ok: true' },
|
||||||
|
400: { description: '内容超长或为空' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/health': {
|
||||||
|
get: {
|
||||||
|
summary: '健康检查',
|
||||||
|
tags: ['系统'],
|
||||||
|
responses: { 200: { description: 'ok: true' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/crawler/notify': {
|
||||||
|
post: {
|
||||||
|
summary: '爬虫通知',
|
||||||
|
description: '爬虫更新后调用,触发前端推送',
|
||||||
|
tags: ['系统'],
|
||||||
|
responses: { 200: { description: 'ok' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/stats': {
|
||||||
|
get: {
|
||||||
|
summary: '统计快照',
|
||||||
|
description: 'viewers / cumulative,不写入',
|
||||||
|
tags: ['统计'],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
viewers: { type: 'number' },
|
||||||
|
cumulative: { type: 'number' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/api/events': {
|
||||||
|
get: {
|
||||||
|
summary: '冲突事件',
|
||||||
|
description: '冲突事件列表及统计',
|
||||||
|
tags: ['态势'],
|
||||||
|
responses: { 200: { description: 'events + conflict_stats' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tags: [{ name: '态势' }, { name: '统计' }, { name: '反馈' }, { name: '调试' }, { name: '系统' }],
|
||||||
|
}
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 滚动情报文本处理:转为简体中文,过滤非中文内容
|
* 滚动情报文本处理:过滤非中文为主的内容
|
||||||
*/
|
*/
|
||||||
import { Converter } from 'opencc-js/t2cn'
|
|
||||||
|
|
||||||
const t2s = Converter({ from: 'twp', to: 'cn' })
|
|
||||||
|
|
||||||
/** 简体中文字符范围 */
|
/** 简体中文字符范围 */
|
||||||
const ZH_REGEX = /[\u4e00-\u9fff]/g
|
const ZH_REGEX = /[\u4e00-\u9fff]/g
|
||||||
|
|
||||||
@@ -16,20 +12,10 @@ export function isMostlyChinese(text: string): boolean {
|
|||||||
return zhCount / text.length >= 0.3
|
return zhCount / text.length >= 0.3
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 繁体转简体 */
|
/** 处理滚动情报项:非中文为主则过滤 */
|
||||||
export function toSimplifiedChinese(text: string): string {
|
|
||||||
if (!text?.trim()) return text
|
|
||||||
try {
|
|
||||||
return t2s(text)
|
|
||||||
} catch {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 处理滚动情报项:转为简体,非中文为主则过滤 */
|
|
||||||
export function processTickerText(text: string): string | null {
|
export function processTickerText(text: string): string | null {
|
||||||
const t = (text || '').trim()
|
const t = (text || '').trim()
|
||||||
if (!t) return null
|
if (!t) return null
|
||||||
if (!isMostlyChinese(t)) return null
|
if (!isMostlyChinese(t)) return null
|
||||||
return toSimplifiedChinese(t)
|
return t
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user