136 lines
3.7 KiB
Markdown
136 lines
3.7 KiB
Markdown
# 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
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
### Mapbox (optional)
|
||
|
||
For the interactive map, create a `.env` file:
|
||
|
||
```bash
|
||
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 存储。
|
||
|
||
```bash
|
||
# 首次运行:初始化数据库并写入种子数据
|
||
npm run api:seed
|
||
|
||
# 启动 API 服务(默认 http://localhost:3001)
|
||
npm run api
|
||
```
|
||
|
||
开发时可用一键启动(推荐):
|
||
|
||
```bash
|
||
npm start
|
||
```
|
||
|
||
或分终端分别运行:
|
||
|
||
```bash
|
||
# 终端 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 条数是否增加
|
||
|
||
## Development
|
||
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
## Build
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
## Docker 部署
|
||
|
||
```bash
|
||
# 构建并启动(需 .env 中配置 VITE_MAPBOX_ACCESS_TOKEN 以启用地图)
|
||
docker compose up -d
|
||
|
||
# 访问前端:http://localhost:3001
|
||
# 数据库与爬虫共享 volume,首次启动自动 seed
|
||
```
|
||
|
||
**拉取镜像超时?** 在 Docker Desktop 配置镜像加速,见 [docs/DOCKER_MIRROR.md](docs/DOCKER_MIRROR.md)
|
||
|
||
**开发时无需每次 rebuild**:使用开发模式挂载源码 + 热重载:
|
||
|
||
```bash
|
||
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`:爬虫默认禁用 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 后生成)
|
||
```
|