af577400fbf90c9d29d90c7a8a0a9141bedad1aa
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,可通过修改表数据实现动态调整。
爬虫不生效时
- 测试 RSS 抓取:
npm run crawler:test(需网络,返回抓取条数) - 单独启动爬虫查看日志:
npm run gdelt(另开终端) - 查看爬虫状态:
curl http://localhost:8000/crawler/status(需爬虫服务已启动) - 数据库面板
/db每 30 秒自动刷新,可观察 situation_update 条数是否增加
面板数据 / 地图 / 战损不更新时
- 确保 API 与爬虫共用同一数据库:本地开发时,Node 默认用
server/data.db,爬虫默认用../server/data.db(同文件)。若 Node 在本地、爬虫在 Docker,则数据库不同,面板不会更新。 - Docker 部署:
GDELT_DISABLED=1时,地图冲突点由 RSS 新闻填充;战损与基地状态由规则/AI 提取后写入combat_losses和key_location。 - 排查:访问
/db看situation_update、gdelt_events、combat_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
- API:
node --watch监听server/变更并自动重启 - 爬虫:
uvicorn --reload监听crawler/变更并自动重启 - 修改
server/或crawler/后,服务会自动重载,无需重新 build
环境变量(可选,在 .env 或 docker-compose.yml 中配置):
VITE_MAPBOX_ACCESS_TOKEN:Mapbox 令牌,构建时注入DB_PATH:数据库路径(默认 /data/data.db)CLEANER_AI_DISABLED=1:爬虫默认禁用 OllamaGDELT_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
Languages
TypeScript
51.4%
Python
30.3%
JavaScript
15.2%
Shell
2%
CSS
0.4%
Other
0.7%