# 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 条数是否增加

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

- **确保 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

```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
```

**迁移到服务器**：见 [DEPLOY.md](DEPLOY.md)（构建、推送、单机/多机部署说明）

**拉取镜像超时？** 在 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 后生成）
```


https://git.bimwe.com/Daniel/usa.git