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-map-gl": "^7.1.7",
|
||||
"react-router-dom": "^7.13.1",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
"ws": "^8.19.0",
|
||||
"zustand": "^5.0.0"
|
||||
},
|
||||
@@ -1344,6 +1345,12 @@
|
||||
"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": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
@@ -5023,6 +5030,28 @@
|
||||
"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": {
|
||||
"version": "3.4.19",
|
||||
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.19.tgz",
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
"express": "^4.21.1",
|
||||
"lucide-react": "^0.460.0",
|
||||
"mapbox-gl": "^3.6.0",
|
||||
"opencc-js": "^1.0.5",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-map-gl": "^7.1.7",
|
||||
"react-router-dom": "^7.13.1",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
"ws": "^8.19.0",
|
||||
"zustand": "^5.0.0"
|
||||
},
|
||||
|
||||
Binary file not shown.
@@ -7,12 +7,19 @@ const { WebSocketServer } = require('ws')
|
||||
const routes = require('./routes')
|
||||
const { getSituation } = require('./situationData')
|
||||
|
||||
const swaggerUi = require('swagger-ui-express')
|
||||
const openApiSpec = require('./openapi')
|
||||
|
||||
const app = express()
|
||||
const PORT = process.env.API_PORT || 3001
|
||||
|
||||
app.set('trust proxy', 1)
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
|
||||
// Swagger 文档
|
||||
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiSpec))
|
||||
|
||||
app.use('/api', routes)
|
||||
app.get('/api/health', (_, res) => res.json({ ok: true }))
|
||||
app.post('/api/crawler/notify', (_, res) => {
|
||||
@@ -58,4 +65,5 @@ function notifyCrawlerUpdate() {
|
||||
|
||||
server.listen(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
|
||||
|
||||
@@ -16,20 +12,10 @@ export function isMostlyChinese(text: string): boolean {
|
||||
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 {
|
||||
const t = (text || '').trim()
|
||||
if (!t) return null
|
||||
if (!isMostlyChinese(t)) return null
|
||||
return toSimplifiedChinese(t)
|
||||
return t
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user