2026-03-02 16:42:35 +08:00
2026-03-02 16:29:11 +08:00
2026-03-02 14:10:43 +08:00
2026-03-02 16:41:57 +08:00
2026-03-02 14:10:43 +08:00
2026-03-02 14:25:44 +08:00
2026-03-02 16:36:49 +08:00
2026-03-02 14:27:30 +08:00
2026-03-02 01:00:04 +08:00
2026-03-02 16:36:49 +08:00
2026-03-02 16:36:49 +08:00
2026-03-02 14:10:43 +08:00
2026-03-02 16:36:49 +08:00
2026-03-02 16:36:49 +08:00
2026-03-02 14:32:32 +08:00
2026-03-01 19:23:48 +08:00
2026-03-01 19:23:48 +08:00
2026-03-01 17:21:15 +08:00
2026-03-02 16:36:49 +08:00
2026-03-02 11:28:13 +08:00
2026-03-02 16:29:11 +08:00
2026-03-01 17:21:15 +08:00
2026-03-01 17:21:15 +08:00
2026-03-01 17:21:15 +08:00
2026-03-01 19:23:48 +08:00
2026-03-01 22:26:14 +08:00

US-Iran Military Situation Display Dashboard

A production-ready data visualization dashboard with 1920×1080 resolution, dark-themed military-grade UI.

Tech Stack

  • Build: Vite (React + TypeScript)
  • Styling: Tailwind CSS
  • State: Zustand
  • Charts: echarts, echarts-for-react
  • Maps: react-map-gl, mapbox-gl
  • Icons: lucide-react
  • Font: Orbitron (Google Fonts)

Setup

npm install

Mapbox (optional)

For the interactive map, create a .env file:

cp .env.example .env
# Edit .env and add your Mapbox token from https://account.mapbox.com/access-tokens/

Without a token, the map area shows a placeholder with location labels.

API 与数据库

页面数据通过 REST API 从后端获取,后端使用 SQLite 存储。

# 首次运行:初始化数据库并写入种子数据
npm run api:seed

# 启动 API 服务(默认 http://localhost:3001
npm run api

开发时可用一键启动(推荐):

npm start

或分终端分别运行:

# 终端 1
npm run api

# 终端 2
npm run dev

API 会由 Vite 代理到 /api,前端通过 /api/situation 获取完整态势数据。数据库文件位于 server/data.db,可通过修改表数据实现动态调整。

爬虫不生效时

  1. 测试 RSS 抓取:npm run crawler:test(需网络,返回抓取条数)
  2. 单独启动爬虫查看日志:npm run gdelt(另开终端)
  3. 查看爬虫状态:curl http://localhost:8000/crawler/status(需爬虫服务已启动)
  4. 数据库面板 /db 每 30 秒自动刷新,可观察 situation_update 条数是否增加

面板数据 / 地图 / 战损不更新时

  • 确保 API 与爬虫共用同一数据库本地开发时Node 默认用 server/data.db,爬虫默认用 ../server/data.db(同文件)。若 Node 在本地、爬虫在 Docker则数据库不同面板不会更新。
  • Docker 部署GDELT_DISABLED=1 时,地图冲突点由 RSS 新闻填充;战损与基地状态由规则/AI 提取后写入 combat_losseskey_location
  • 排查:访问 /dbsituation_updategdelt_eventscombat_losses 是否在增长;确认 API 已启动且前端能访问 /api/situation

Development

npm run dev

Build

npm run build

Docker 部署

# 构建并启动(需 .env 中配置 VITE_MAPBOX_ACCESS_TOKEN 以启用地图)
docker compose up -d

# 访问前端http://localhost:3001
# 数据库与爬虫共享 volume首次启动自动 seed

迁移到服务器:见 DEPLOY.md(构建、推送、单机/多机部署说明)

拉取镜像超时? 在 Docker Desktop 配置镜像加速,见 docs/DOCKER_MIRROR.md

开发时无需每次 rebuild:使用开发模式挂载源码 + 热重载:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
  • APInode --watch 监听 server/ 变更并自动重启
  • 爬虫:uvicorn --reload 监听 crawler/ 变更并自动重启
  • 修改 server/crawler/ 后,服务会自动重载,无需重新 build

环境变量(可选,在 .env 或 docker-compose.yml 中配置):

  • VITE_MAPBOX_ACCESS_TOKENMapbox 令牌,构建时注入
  • DB_PATH:数据库路径(默认 /data/data.db
  • CLEANER_AI_DISABLED=1:爬虫默认禁用 Ollama
  • GDELT_DISABLED=1:爬虫默认禁用 GDELT国内易超时

Project Structure

src/
├── components/
│   ├── HeaderPanel.tsx   # Top global overview & power index comparison
│   ├── ForcePanel.tsx    # Reusable left/right panel for military forces
│   ├── WarMap.tsx        # Mapbox GL (Persian Gulf center)
│   └── StatCard.tsx      # Reusable number card
├── api/
│   └── situation.ts      # 态势数据 API 请求
├── store/
│   └── situationStore.ts # Zustand store + API 轮询
├── data/
│   └── mockData.ts       # 类型定义与初始兜底数据
├── pages/
│   └── Dashboard.tsx     # Main layout (1920×1080)
├── App.tsx
└── index.css
server/
├── index.js    # Express API 入口
├── db.js       # SQLite 建表与连接
├── routes.js   # /api/situation 路由
├── seed.js     # 数据库种子脚本
└── data.db     # SQLite 数据库(运行 seed 后生成)
Description
No description provided
Readme 5.8 MiB
Languages
TypeScript 51.4%
Python 30.3%
JavaScript 15.2%
Shell 2%
CSS 0.4%
Other 0.7%