Tiwari1782/VERIDIAN
GitHub: Tiwari1782/VERIDIAN
基于 MERN 栈的实时地缘政治情报仪表板,将全球事件聚合到 3D 地球上,并通过 AI 实时生成金融交易信号。
Stars: 0 | Forks: 2
#
VERIDIAN — 实时地缘政治情报 + AI 交易信号
[](https://www.mongodb.com/)
[](https://reactjs.org/)
[](https://nodejs.org/)
[](https://groq.com/)
[](/)
[](/)
## 什么是 VERIDIAN?
**VERIDIAN** 是一个完全公开的实时地缘政治情报仪表板,基于 **MERN stack** 构建。它将实时全球事件——冲突、抗议、灾难、军事动向、网络威胁——聚合到一个交互式 3D 地球上,并独特地将这些事件实时转化为 **AI 驱动的金融交易信号**。
无需登录。无需认证。任何访客都可以立即查看和使用所有内容。
### 为什么开发这个项目?
| 问题 | 现实 |
|---|---|
| **信息过载** | 分析师需切换 10+ 个标签页:Reuters, BBC, FlightRadar, Bloomberg, Twitter——手动关联线索 |
| **缺乏金融背景** | 每个 OSINT 工具只显示发生了*什么*。没有工具能说明在金融上该*做什么* |
| **速度太慢** | 当情报处理完毕时,市场早已将其消化定价 |
| **工具碎片化** | 地缘政治事件、市场数据、航班追踪、网络威胁分散在不同的平台中 |
**VERIDIAN** 在一个统一、零成本的情报平台中解决了以上四个问题。
## VERIDIAN 的独特之处
### GeoTrade AI 信号引擎 —— 前所未有的创新
目前没有商业 OSINT 工具——无论是 Reuters Eikon、Bloomberg Terminal 还是 Conflictly.app——能自动将实时地缘政治事件转化为带有推理过程的金融交易信号。而 VERIDIAN 可以在 **2 秒内** 完成这一过程。
```
Hormuz tensions escalating → Oil supply disruption likely → BUY $XOM (confidence: 81%)
China suspends rare earths → EV supply chain at risk → SELL $TSLA (confidence: 74%)
Middle East escalation → Safe haven demand rising → BUY $GLD (confidence: 78%)
```
### 竞品对比
| 能力 | Conflictly.app | LiveUAMap | Crisis24 | **VERIDIAN** |
|---|:---:|:---:|:---:|:---:|
| 3D 交互式地球 | ✅ | ✅ | ❌ | ✅ |
| 实时冲突事件数据 | ✅ | ✅ | ✅ | ✅ |
| AI 国家情报简报 | ✅ | ❌ | ❌ | ✅ |
| **金融交易信号** | ❌ | ❌ | ❌ | ✅ |
| **股票 / 加密货币 / 外汇面板** | ❌ | ❌ | ❌ | ✅ |
| 军事航班追踪 | ❌ | ✅ | ❌ | ✅ |
| 网络威胁地球覆盖层 | ❌ | ❌ | ❌ | ✅ |
| **4 密钥 AI 轮换(零停机)** | ❌ | ❌ | ❌ | ✅ |
| 严重性标记新闻流 | ✅ | ❌ | ❌ | ✅ |
| 滚动紧张局势跑马灯 | ✅ | ❌ | ❌ | ✅ |
| **100% 免费运行** | ❌ | ❌ | ❌ | ✅ |
## 功能规格
### 功能 1 — 实时 3D 地缘政治地球
VERIDIAN 的核心组件。一个 WebGL 地球,**空闲时缓慢自动旋转**,并将地球上每个活跃的地缘政治事件显示为发光的彩色圆点。
- **自动旋转** —— 地球空闲时以约 2 RPM 的速度旋转,用户交互时停止,8 秒后恢复
- **发光事件点** —— 每个事件绘制在真实的经纬度位置。点的大小随严重性缩放。颜色对应威胁等级
- **红色脉冲环** —— `CRITICAL` 事件显示双层 CSS 关键帧环动画,立即吸引注意力
- **点击获取简报** —— 点击任何国家会触发 Groq AI 在滑入式侧边面板中生成完整的情报简报
- **2D 地图切换** —— 按钮可在 Globe.gl 3D 视图和 Mapbox GL JS 平面 2D 地图之间平滑切换
- **事件类型过滤器** —— 切换按钮:`Conflicts` (冲突) `Protests` (抗议) `Disasters` (灾难) `Earthquakes` (地震) `Wildfires` (野火) `Military Flights` (军事航班)
- **时间范围过滤器** —— 下拉菜单:`Last 1h` / `6h` / `24h` / `7 days` —— 根据事件时间戳过滤地球上的点
- **热力图层** —— Deck.gl 密度热力图叠加层,显示各区域的事件浓度。可开关
- **国界发光** —— 悬停在国家上方时,其边界多边形以该国的严重性颜色高亮显示
- **飞行动画** —— 点击新闻标题或跑马灯项,地球视角会平滑飞向该事件位置
- **弧线层** —— 军事航班路径在地球表面渲染为动画弧线。可独立开关
**应用于所有点和环的严重性颜色系统:**
| 等级 | 颜色 | 十六进制值 |
|---|---|---|
| `CRITICAL` | ● 红色 | `#EF4444` |
| `HIGH` | ● 橙色 | `#F97316` |
| `MEDIUM` | ● 黄色 | `#EAB308` |
| `LOW` | ● 绿色 | `#00FF88` |
### 功能 2 — 实时情报新闻流
实时、按严重性编码的新闻面板,聚合 **150+ 个全球来源**。每 5 分钟自动刷新。
- **多源聚合** —— NewsAPI.org (免费 100 次/天) + 通过 `rss-parser` npm 直接获取 Reuters, BBC, Al Jazeera, Bloomberg 的 RSS 源
- **GDELT 事件流** —— 带坐标的实时地缘政治事件。无限制,无需密钥
- **严重性颜色编码** —— 每个标题通过后端 NLP 关键词评分自动标记:`CRITICAL` / `HIGH` / `MEDIUM` / `LOW`
- **自动刷新** —— 新闻流每 5 分钟静默刷新。新项目以淡入动画显示在顶部
- **`BREAKING` 徽章** —— 15 分钟内被 3+ 个来源报道的新闻会获得一个脉冲金色 `BREAKING` 徽章
- **区域过滤标签** —— `Middle East` (中东) `Europe` (欧洲) `Asia-Pacific` (亚太) `Americas` (美洲) `Africa` (非洲)
- **关键词搜索** —— 对所有标题进行实时搜索。匹配词以 `#00D4FF` Cyber Cyan 高亮显示
- **实体链接** —— 标题中的国家名称可点击 —— 通过 `Globe.gl flyTo()` 将地球视角缩放到该国家
- **每个标题上的国旗** —— 每个标题使用 `flagcdn.com` 图片显示国家国旗 (例如 `https://flagcdn.com/w20/us.png`)。国旗位于标题文字左侧
- **来源徽章** —— 每个标题显示带有 Font Awesome 图标的来源名称:`fas fa-rss` 用于 RSS 源,`fas fa-globe` 用于 NewsAPI 源
### 功能 3 — AI 国家情报简报 (Groq)
点击地球上的任何国家 → 滑入式面板出现,在 2 秒内显示完整的 AI 生成情报简报。
- **Groq Llama 3.1 8B** —— 主 AI 模型。使用实时新闻作为上下文生成 3 段式简报
- **4 密钥轮换系统** —— 4 个独立的免费 Groq API 密钥 (`GROQ_API_KEY_1` 至 `GROQ_API_KEY_4`) 循环使用。如果密钥 1 达到速率限制,密钥 2 立即激活。然后是密钥 3,再是密钥 4。这确保 AI 在演示期间永远不会明显失败
- **Google Gemini 备用** —— 如果所有 4 个 Groq 密钥都耗尽,Gemini API (免费 15 次/分) 无缝处理请求
- **稳定性评分** —— AI 分配 0-100 的评分,渲染为发光的 `Recharts RadialBarChart` 环。如果 <30 为红色,30-60 为橙色,>60 为绿色
- **前 3 大风险** —— AI 将当前最关键的三个风险因素作为结构化项目符号返回
- **展望徽章** —— `Stable` (稳定) / `Deteriorating` (恶化) / `Escalating` (升级) / `Crisis` (危机) —— 带有 Font Awesome 图标 `fas fa-chart-line` 的彩色徽章
- **来源引用** —— 简报准确列出了用作上下文的新闻(透明 AI)
- **15 分钟 MongoDB 缓存** —— 生成的简报带有 TTL 缓存,以防止速率限制滥用
- **国家元数据** —— 来自 `RestCountries API` (免费、无限制) 的国旗、首都、人口、政府类型。使用 `flagcdn.com/w40/{iso2}.png` 突出显示国旗
- **分享按钮** —— `fas fa-copy` 图标通过 Clipboard API 将简报复制到剪贴板
### 功能 4 — GeoTrade AI 信号引擎
**核心差异化功能。** AI 读取实时地缘政治事件,并为股票、加密货币、外汇和大宗商品生成实时 `BUY` / `HOLD` / `SELL` 信号。
- **股票搜索** —— 带有 `fas fa-search` 图标的输入框。接受任何代码:`AAPL` `TSLA` `XOM` `GLD` `SPY`
- **实时价格和变动** —— 通过 `yahoo-finance2` npm (免费,无需 API 密钥) 获取实时价格、百分比变化、交易量。正数显示绿色 `fas fa-arrow-up`,负数显示红色 `fas fa-arrow-down`
- **7 天迷你走势图** —— 过去 7 天价格历史的 Recharts `LineChart` 迷你图。深色面板背景上的青色线条
- **AI 信号生成** —— Groq 读取与股票行业/国家相关的当前 GDELT 事件 → 输出带有完整推理段落的 `BUY` / `HOLD` / `SELL`。此处同样应用 4 密钥轮换
- **信号置信度** —— 每个信号显示置信度百分比 (例如 `BUY — 81%`),使用 JetBrains Mono 字体显示
- **信号徽章** —— 带有 Font Awesome 图标的发光彩色徽章:
- `BUY` —— `fas fa-arrow-trend-up` —— 绿色发光 (`#00FF88`)
- `SELL` —— `fas fa-arrow-trend-down` —— 红色发光 (`#EF4444`)
- `HOLD` —— `fas fa-pause` —— 黄色发光 (`#EAB308`)
- **恐惧与贪婪指数** —— `alternative.me` API 表盘小部件,显示全球市场情绪 (0-100)。使用 `fas fa-gauge-high` 图标显示
- **加密货币面板** —— BTC / ETH / SOL / XRP 实时价格,通过 CoinGecko API (免费) 获取币种 Logo。带有地缘风险相关性标签
- **外汇面板** —— USD/JPY, EUR/USD, GBP/USD, USD/INR 实时汇率。使用 `flagcdn.com` 为每个货币对显示国旗
- **大宗商品面板** —— 黄金 `fas fa-coins`, 原油 `fas fa-oil-well`, 天然气 `fas fa-fire-flame-curved`,通过 yahoo-finance2 获取,带有冲突驱动的背景标签
- **信号历史** —— 每个代码最后 5 个 AI 信号存储在 MongoDB 中。显示在当前信号下方的迷你时间线中
### 功能 5 — 军事航班追踪器
来自 OpenSky Network 的实时航班位置,在 3D 地球上绘制为动画弧线。
- **实时位置** —— 来自 OpenSky Network API (免费、匿名、无需密钥) 的实时航班经纬度和高度
- **军事过滤器** —— 使用 ICAO 类型和已知呼号模式过滤军用/政府航班
- **地球弧线叠加** —— 航班路径在 Globe.gl 弧线层上渲染为动画青色弧线。可通过 `fas fa-fighter-jet` 按钮开关
- **冲突接近警报** —— 距离活跃冲突区域 200km 以内的航班标记橙色 `fas fa-triangle-exclamation` 徽章
- **激增检测** —— 标记异常集中的军事航班(同一区域 >5 架)并显示 `SURGE` 徽章
- **航班信息弹窗** —— 点击任何航班弧线 → 呼号、航班类型、出发地、目的地、高度、速度。通过 `flagcdn.com` 显示出发国的国旗
- **ADS-B Exchange 备用** —— 如果 OpenSky 速度慢,则使用次要数据源
- **60 秒自动刷新** —— 航班位置每 60 秒更新一次(对速率限制友好)
### 功能 6 — 紧张局势跑马灯
位于仪表板最顶部的滚动警报栏,样式类似金融股票跑马灯。
- **连续水平滚动** —— CSS 动画 (`@keyframes scroll`) 将实时地缘政治警报从左到右滚动显示在整个屏幕宽度上
- **严重性颜色编码** —— `fas fa-circle` 点 + 标签:`CRITICAL` 为 `#EF4444`,`HIGH` 为 `#F97316`,`MEDIUM` 为 `#EAB308`
- **点击聚焦地球** —— 点击任何跑马灯项会调用 `Globe.gl flyTo()` 将地球视角缩放到该事件
- **5 分钟自动刷新** —— 通过 `setInterval` 每 5 分钟使用最新的 GDELT + NewsAPI 数据更新
- **跑马灯中的国旗** —— 在事件国家名称前内联显示小国旗 (`flagcdn.com/w16/{iso2}.png`)
### 功能 7 — 区域情报面板
主地球下方 2×2 网格布局中的四个特定区域情报卡片。
- **4 个面板** —— `Middle East` (中东) `Europe` (欧洲) `Asia-Pacific` (亚太) `Americas` (美洲) —— 每个都有各自的区域旗帜或图标
- **前 3 大事件** —— 每个面板显示该区域当前最关键的 3 个事件,按严重性颜色编码
- **稳定性指数** —— 区域评分 0-100,显示为彩色进度条 (`green` → `yellow` → `red`)
- **热门关键词** —— 该区域前 5 个热门地缘政治术语(例如 `ceasefire` (停火), `sanctions` (制裁), `airstrike` (空袭))
- **事件计数 + 趋势** —— 过去 24 小时内的总事件数,以及与前 24 小时相比的趋势 (`fas fa-arrow-up` / `fas fa-arrow-down`)
- **点击展开** —— 点击区域面板会调用 `Globe.gl flyTo()` 飞向该区域
### 功能 8 — 网络与基础设施威胁层
显示实时网络威胁的可选地球叠加层。
- **C2 服务器位置** —— 来自 `abuse.ch Feodo Tracker` (免费、无限制) 的活跃命令控制僵尸网络服务器位置,在地球上显示为紫色点
- **恶意软件主机位置** —— 来自 `URLhaus API` (免费、无限制) 的恶意软件分发主机
- **互联网中断地图** —— 来自 `Cloudflare Radar API` (免费,需 Cloudflare 账户) 的实时中断情况
- **IP 地理定位** —— 通过 `ipapi.co` (免费 1000 次/天) 对威胁行为者 IP 进行地理定位并放置在地球上
- **切换层** —— `fas fa-shield-halved` 按钮独立切换网络层。紫色 (`#7C3AED`) 配色方案与冲突点区分开
## 设计系统与样式
### 字体排印
VERIDIAN 精确使用从 Google Fonts CDN 加载的 **两种字体**。两者必须通过 `index.html` 中的单个 `` 标签导入。
```
```
```
// tailwind.config.js
fontFamily: {
sans: ['Inter', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
}
```
#### 字体 1 — Inter (主要 UI 字体)
- **用于:** 所有标题、导航、标签、面板标题、正文文本、按钮文本、警报徽章、新闻标题、区域面板文本、功能描述
- **为何选择 Inter:** Conflictly.app 使用的同款字体。在深色背景上各尺寸下都具有极高的可读性。干净的人文主义字形,专业现代而不显得生硬
| 元素 | 粗细 | 大小 | 颜色 |
|---|---|---|---|
| 站点 Logo `VERIDIAN` 字标 | `800` ExtraBold | `32px` | `#00D4FF` Cyber Cyan |
| 章节标题 (``) | `700` Bold | `24px` | `#00D4FF` Cyber Cyan |
| 面板卡片标题 | `600` SemiBold | `16px` | `#FFFFFF` White |
| 功能子标题 | `600` SemiBold | `18px` | `#00FF88` Signal Green |
| 正文 / 描述 | `400` Regular | `14px` | `#CBD5E1` Silver |
| 导航链接 | `500` Medium | `14px` | `#CBD5E1` Silver |
| `BUY` / `SELL` / `HOLD` 徽章 | `700` Bold | `13px` | 信号颜色 |
| `BREAKING` 徽章 | `700` Bold | `12px` | `#0A0F1E` 在 `#F59E0B` 上 |
| 时间戳 / 元数据 | `300` Light | `12px` | `#64748B` Muted |
| 跑马灯滚动文字 | `500` Medium | `13px` | `#FFFFFF` White |
| 严重性标签 | `700` Bold | `12px` | 严重性颜色 |
#### 字体 2 — JetBrains Mono (数据 / 终端字体)
- **用于:** 所有数值数据——股票价格、百分比变化、坐标、稳定性评分、信号置信度百分比、导航栏中的实时 UTC 时钟、航班高度/速度数据、加密货币价格、外汇汇率
- **为何选择 JetBrains Mono:** 等宽字体使数值数据可瞬间扫描——每个数字具有相同的宽度,因此数字在列中对齐。创造真实的 OSINT 终端美感。通过 `font-mono` Tailwind 类或 `font-family: 'JetBrains Mono', monospace` 应用
| 元素 | 粗细 | 大小 | 颜色 |
|---|---|---|---|
| 股票价格 (例如 `$124.38`) | `400` Regular | `20px` | `#FFFFFF` White |
| 价格变动 % | `600` SemiBold | `16px` | `#00FF88` 或 `#EF4444` |
| 稳定性评分 (例如 `23 / 100`) | `600` SemiBold | `18px` | 严重性颜色 |
| 信号置信度 (例如 `78%`) | `400` Regular | `14px` | `#CBD5E1` Silver |
| 实时 UTC 时钟 | `400` Regular | `14px` | `#00D4FF` Cyan |
| 经纬度坐标 | `400` Regular | `12px` | `#64748B` Muted |
| 航班高度 / 速度 | `400` Regular | `12px` | `#64748B` Muted |
| 加密货币 / 外汇汇率 | `400` Regular | `18px` | `#FFFFFF` White |
### 调色板
```
:root {
/* Backgrounds */
--color-bg: #0A0F1E; /* Main page background — deep space black */
--color-navy: #0D1B2A; /* Sidebar / secondary bg */
--color-panel: #111827; /* Card / panel background */
--color-surface: #1E293B; /* Elevated: dropdowns, hover states, alt table rows */
--color-border: #1E3A5F; /* All borders, dividers, input outlines */
/* Accents */
--color-cyan: #00D4FF; /* PRIMARY — headings, globe glow, active states */
--color-cyan-dim: #0EA5E9; /* Secondary — hover, chart lines, focus rings */
--color-green: #00FF88; /* BUY signal, positive values, safe/low severity */
--color-red: #EF4444; /* SELL signal, CRITICAL alerts, danger states */
--color-orange: #F97316; /* HIGH alerts, negative % change */
--color-yellow: #EAB308; /* HOLD signal, MEDIUM alerts */
--color-gold: #F59E0B; /* BREAKING badge, special callouts */
--color-purple: #7C3AED; /* Cyber threat layer dots */
/* Text */
--color-text-primary: #FFFFFF; /* Headings, key values */
--color-text-secondary: #CBD5E1; /* Body copy, descriptions */
--color-text-muted: #64748B; /* Timestamps, labels, metadata */
}
```
#### 语义信号颜色
每个信号徽章使用 **15% 不透明度的同色背景上的彩色文本** 并带有匹配的边框——创造出发光徽章效果:
```
/* BUY badge */
.badge-buy { color: #00FF88; background: rgba(0,255,136,0.15); border: 1px solid #00FF88; }
/* SELL badge */
.badge-sell { color: #EF4444; background: rgba(239,68,68,0.15); border: 1px solid #EF4444; }
/* HOLD badge */
.badge-hold { color: #EAB308; background: rgba(234,179,8,0.15); border: 1px solid #EAB308; }
/* CRITICAL alert badge */
.badge-critical { color: #EF4444; background: rgba(239,68,68,0.15); border: 1px solid #EF4444; }
/* HIGH alert badge */
.badge-high { color: #F97316; background: rgba(249,115,22,0.15); border: 1px solid #F97316; }
/* MEDIUM alert badge */
.badge-medium { color: #EAB308; background: rgba(234,179,8,0.15); border: 1px solid #EAB308; }
/* LOW / STABLE badge */
.badge-low { color: #00FF88; background: rgba(0,255,136,0.15); border: 1px solid #00FF88; }
/* BREAKING badge — solid gold, dark text */
.badge-breaking { color: #0A0F1E; background: #F59E0B; border: none; font-weight: 700; }
```
#### 玻璃拟态面板样式
```
.panel {
background: rgba(13, 27, 42, 0.85);
border: 1px solid #1E3A5F;
border-top: 1px solid rgba(0, 212, 255, 0.30); /* cyan top-edge glow */
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 12px;
box-shadow: 0 0 24px rgba(0, 212, 255, 0.06);
}
```
#### 脉冲环动画 (CRITICAL 事件)
```
@keyframes pulse-ring {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(2.4); opacity: 0; }
}
.pulse-ring {
position: absolute;
border: 2px solid #EF4444;
border-radius: 50%;
animation: pulse-ring 1.4s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
.pulse-ring:nth-child(2) {
animation-delay: 0.7s;
}
```
#### 骨架加载器 (所有面板加载时)
```
@keyframes shimmer {
0% { background-position: -1000px 0; }
100% { background-position: 1000px 0; }
}
.skeleton {
background: linear-gradient(90deg, #111827 25%, #1E293B 50%, #111827 75%);
background-size: 2000px 100%;
animation: shimmer 1.8s infinite linear;
border-radius: 6px;
}
```
### 国旗
```
Format: https://flagcdn.com/w{size}/{iso2_lowercase}.png
Sizes available: w16, w20, w32, w40, w80, w160, w320
Examples:
US flag (20px wide): https://flagcdn.com/w20/us.png
Ukraine flag: https://flagcdn.com/w20/ua.png
China flag: https://flagcdn.com/w20/cn.png
Iran flag: https://flagcdn.com/w20/ir.png
```
**React 中的实现:**
```
// FlagIcon component
const FlagIcon = ({ iso2, size = 20, className = '' }) => (
`) | `700` Bold | `24px` | `#00D4FF` Cyber Cyan |
| 面板卡片标题 | `600` SemiBold | `16px` | `#FFFFFF` White |
| 功能子标题 | `600` SemiBold | `18px` | `#00FF88` Signal Green |
| 正文 / 描述 | `400` Regular | `14px` | `#CBD5E1` Silver |
| 导航链接 | `500` Medium | `14px` | `#CBD5E1` Silver |
| `BUY` / `SELL` / `HOLD` 徽章 | `700` Bold | `13px` | 信号颜色 |
| `BREAKING` 徽章 | `700` Bold | `12px` | `#0A0F1E` 在 `#F59E0B` 上 |
| 时间戳 / 元数据 | `300` Light | `12px` | `#64748B` Muted |
| 跑马灯滚动文字 | `500` Medium | `13px` | `#FFFFFF` White |
| 严重性标签 | `700` Bold | `12px` | 严重性颜色 |
#### 字体 2 — JetBrains Mono (数据 / 终端字体)
- **用于:** 所有数值数据——股票价格、百分比变化、坐标、稳定性评分、信号置信度百分比、导航栏中的实时 UTC 时钟、航班高度/速度数据、加密货币价格、外汇汇率
- **为何选择 JetBrains Mono:** 等宽字体使数值数据可瞬间扫描——每个数字具有相同的宽度,因此数字在列中对齐。创造真实的 OSINT 终端美感。通过 `font-mono` Tailwind 类或 `font-family: 'JetBrains Mono', monospace` 应用
| 元素 | 粗细 | 大小 | 颜色 |
|---|---|---|---|
| 股票价格 (例如 `$124.38`) | `400` Regular | `20px` | `#FFFFFF` White |
| 价格变动 % | `600` SemiBold | `16px` | `#00FF88` 或 `#EF4444` |
| 稳定性评分 (例如 `23 / 100`) | `600` SemiBold | `18px` | 严重性颜色 |
| 信号置信度 (例如 `78%`) | `400` Regular | `14px` | `#CBD5E1` Silver |
| 实时 UTC 时钟 | `400` Regular | `14px` | `#00D4FF` Cyan |
| 经纬度坐标 | `400` Regular | `12px` | `#64748B` Muted |
| 航班高度 / 速度 | `400` Regular | `12px` | `#64748B` Muted |
| 加密货币 / 外汇汇率 | `400` Regular | `18px` | `#FFFFFF` White |
### 调色板
```
:root {
/* Backgrounds */
--color-bg: #0A0F1E; /* Main page background — deep space black */
--color-navy: #0D1B2A; /* Sidebar / secondary bg */
--color-panel: #111827; /* Card / panel background */
--color-surface: #1E293B; /* Elevated: dropdowns, hover states, alt table rows */
--color-border: #1E3A5F; /* All borders, dividers, input outlines */
/* Accents */
--color-cyan: #00D4FF; /* PRIMARY — headings, globe glow, active states */
--color-cyan-dim: #0EA5E9; /* Secondary — hover, chart lines, focus rings */
--color-green: #00FF88; /* BUY signal, positive values, safe/low severity */
--color-red: #EF4444; /* SELL signal, CRITICAL alerts, danger states */
--color-orange: #F97316; /* HIGH alerts, negative % change */
--color-yellow: #EAB308; /* HOLD signal, MEDIUM alerts */
--color-gold: #F59E0B; /* BREAKING badge, special callouts */
--color-purple: #7C3AED; /* Cyber threat layer dots */
/* Text */
--color-text-primary: #FFFFFF; /* Headings, key values */
--color-text-secondary: #CBD5E1; /* Body copy, descriptions */
--color-text-muted: #64748B; /* Timestamps, labels, metadata */
}
```
#### 语义信号颜色
每个信号徽章使用 **15% 不透明度的同色背景上的彩色文本** 并带有匹配的边框——创造出发光徽章效果:
```
/* BUY badge */
.badge-buy { color: #00FF88; background: rgba(0,255,136,0.15); border: 1px solid #00FF88; }
/* SELL badge */
.badge-sell { color: #EF4444; background: rgba(239,68,68,0.15); border: 1px solid #EF4444; }
/* HOLD badge */
.badge-hold { color: #EAB308; background: rgba(234,179,8,0.15); border: 1px solid #EAB308; }
/* CRITICAL alert badge */
.badge-critical { color: #EF4444; background: rgba(239,68,68,0.15); border: 1px solid #EF4444; }
/* HIGH alert badge */
.badge-high { color: #F97316; background: rgba(249,115,22,0.15); border: 1px solid #F97316; }
/* MEDIUM alert badge */
.badge-medium { color: #EAB308; background: rgba(234,179,8,0.15); border: 1px solid #EAB308; }
/* LOW / STABLE badge */
.badge-low { color: #00FF88; background: rgba(0,255,136,0.15); border: 1px solid #00FF88; }
/* BREAKING badge — solid gold, dark text */
.badge-breaking { color: #0A0F1E; background: #F59E0B; border: none; font-weight: 700; }
```
#### 玻璃拟态面板样式
```
.panel {
background: rgba(13, 27, 42, 0.85);
border: 1px solid #1E3A5F;
border-top: 1px solid rgba(0, 212, 255, 0.30); /* cyan top-edge glow */
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 12px;
box-shadow: 0 0 24px rgba(0, 212, 255, 0.06);
}
```
#### 脉冲环动画 (CRITICAL 事件)
```
@keyframes pulse-ring {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(2.4); opacity: 0; }
}
.pulse-ring {
position: absolute;
border: 2px solid #EF4444;
border-radius: 50%;
animation: pulse-ring 1.4s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
.pulse-ring:nth-child(2) {
animation-delay: 0.7s;
}
```
#### 骨架加载器 (所有面板加载时)
```
@keyframes shimmer {
0% { background-position: -1000px 0; }
100% { background-position: 1000px 0; }
}
.skeleton {
background: linear-gradient(90deg, #111827 25%, #1E293B 50%, #111827 75%);
background-size: 2000px 100%;
animation: shimmer 1.8s infinite linear;
border-radius: 6px;
}
```
### 国旗
```
Format: https://flagcdn.com/w{size}/{iso2_lowercase}.png
Sizes available: w16, w20, w32, w40, w80, w160, w320
Examples:
US flag (20px wide): https://flagcdn.com/w20/us.png
Ukraine flag: https://flagcdn.com/w20/ua.png
China flag: https://flagcdn.com/w20/cn.png
Iran flag: https://flagcdn.com/w20/ir.png
```
**React 中的实现:**
```
// FlagIcon component
const FlagIcon = ({ iso2, size = 20, className = '' }) => (
);
// Usage in news headline:
{headline.title}
// Usage in brief panel header:
// Usage in forex pair:
149.82
```
### Font Awesome 图标
```
```
#### 图标映射 —— VERIDIAN 中使用的每个图标
| 位置 | 图标类 | 颜色 | 用途 |
|---|---|---|---|
| 导航栏 —— 地球切换 | `fas fa-globe` | `#00D4FF` | 3D/2D 地图切换按钮 |
| 导航栏 —— UTC 时钟 | `fas fa-clock` | `#64748B` | 实时 UTC 时间标签 |
| 导航栏 —— 事件计数 | `fas fa-bolt` | `#F59E0B` | 实时事件计数徽章 |
| 导航栏 —— 搜索 | `fas fa-magnifying-glass` | `#64748B` | 全局搜索触发器 |
| 新闻流 —— RSS 源 | `fas fa-rss` | `#F97316` | 标题上的 RSS 源指示器 |
| 新闻流 —— NewsAPI 源 | `fas fa-globe` | `#00D4FF` | NewsAPI 源指示器 |
| 新闻流 —— 严重性点 | `fas fa-circle` | 严重性颜色 | 每个标题前的实心点 |
| 新闻流 —— BREAKING | `fas fa-triangle-exclamation` | `#F59E0B` | BREAKING 新闻图标 |
| 新闻流 —— 书签 | `fas fa-bookmark` | `#64748B` | 保存文章操作 |
| 国家简报 —— 稳定性 | `fas fa-shield-halved` | `#00D4FF` | 稳定性评分章节标题 |
| 国家简报 —— 风险 | `fas fa-skull-crossbones` | `#EF4444` | 前 3 大风险章节标题 |
| 国家简报 —— 展望 | `fas fa-chart-line` | `#F97316` | 展望徽章图标 |
| 国家简报 —— 分享 | `fas fa-copy` | `#64748B` | 复制简报到剪贴板 |
| 国家简报 —— 关闭 | `fas fa-xmark` | `#64748B` | 关闭滑入式面板 |
| 金融 —— BUY 信号 | `fas fa-arrow-trend-up` | `#00FF88` | BUY 徽章图标 |
| 金融 —— SELL 信号 | `fas fa-arrow-trend-down` | `#EF4444` | SELL 徽章图标 |
| 金融 —— HOLD 信号 | `fas fa-pause` | `#EAB308` | HOLD 徽章图标 |
| 金融 —— 价格上涨 | `fas fa-arrow-up` | `#00FF88` | 正向价格变化 |
| 金融 —— 价格下跌 | `fas fa-arrow-down` | `#EF4444` | 负向价格变化 |
| 金融 —— 恐惧与贪婪 | `fas fa-gauge-high` | `#00D4FF` | 恐惧与贪婪表盘标题 |
| 金融 —— 股票搜索 | `fas fa-magnifying-glass` | `#64748B` | 搜索输入图标 |
| 金融 —— 黄金大宗商品 | `fas fa-coins` | `#F59E0B` | 黄金价格标签 |
| 金融 —— 石油大宗商品 | `fas fa-oil-well` | `#64748B` | 原油价格标签 |
| 金融 —— 天然气大宗商品 | `fas fa-fire-flame-curved` | `#F97316` | 天然气价格标签 |
| 金融 —— 历史 | `fas fa-clock-rotate-left` | `#64748B` | 信号历史部分 |
| 航班 —— 切换 | `fas fa-fighter-jet` | `#00D4FF` | 军事航班层切换 |
| 航班 —— 接近警报 | `fas fa-triangle-exclamation` | `#F97316` | 航班接近冲突区域 |
| 航班 —— 激增 | `fas fa-radiation` | `#EF4444` | 航班激增检测徽章 |
| 跑马灯 —— CRITICAL | `fas fa-circle-radiation` | `#EF4444` | 关键事件标记 |
| 跑马灯 —— HIGH | `fas fa-circle-exclamation` | `#F97316` | 高危事件标记 |
| 跑马灯 —— MEDIUM | `fas fa-circle-dot` | `#EAB308` | 中危事件标记 |
| 网络层 —— 切换 | `fas fa-shield-halved` | `#7C3A` | 网络威胁层切换 |
| 网络 —— 僵尸网络 | `fas fa-spider` | `#7C3AED` | C2 服务器位置图标 |
| 网络 —— 恶意软件 | `fas fa-virus` | `#EF4444` | 恶意软件主机图标 |
| 网络 —— 中断 | `fas fa-wifi` | `#F97316` | 互联网中断图标 |
| 区域面板 —— 趋势上升 | `fas fa-arrow-trend-up` | `#00FF88` | 事件计数增加 |
| 区域面板 —— 趋势下降 | `fas fa-arrow-trend-down` | `#EF4444` | 事件计数减少 |
| 过滤栏 —— 时间 | `fas fa-filter` | `#64748B` | 时间范围过滤器图标 |
| 过滤栏 —— 活跃过滤器 | `fas fa-check` | `#00D4FF` | 活跃过滤器指示器 |
| 通用 —— 加载 | `fas fa-spinner fa-spin` | `#00D4FF` | 加载状态旋转器 |
| 通用 —— 刷新 | `fas fa-rotate` | `#64748B` | 数据刷新指示器 |
## 完整项目结构
```
veridian/
├── client/ # React 18 + Vite Frontend
│ ├── public/
│ │ └── favicon.ico
│ ├── index.html # Google Fonts + Font Awesome CDN links go here
│ ├── src/
│ │ ├── components/
│ │ │ ├── Globe.jsx # Globe.gl 3D globe — event dots, arc layers, heatmap, fly-to
│ │ │ ├── Map2D.jsx # Mapbox GL JS flat 2D map — toggle from globe
│ │ │ ├── Ticker.jsx # Scrolling tension alert ticker bar — top of screen
│ │ │ ├── Navbar.jsx # Logo, UTC clock (JetBrains Mono), event count, search
│ │ │ ├── NewsPanel.jsx # Live intelligence news feed — severity coded, flags
│ │ │ ├── CountryBrief.jsx # AI country brief slide-in panel — Groq powered
│ │ │ ├── FinancePanel.jsx # GeoTrade signal engine — stocks, crypto, forex, commodities
│ │ │ ├── StockCard.jsx # Individual stock: price (JetBrains Mono), sparkline, signal badge
│ │ │ ├── SignalBadge.jsx # BUY/HOLD/SELL glowing badge — FA icon + colour
│ │ │ ├── FlightTracker.jsx # Military flight overlay toggle — arc layer control
│ │ │ ├── RegionPanel.jsx # 4 regional intelligence cards — 2×2 grid
│ │ │ ├── CyberLayer.jsx # Cyber threat globe overlay — purple dot layer
│ │ │ ├── StabilityRing.jsx # Recharts RadialBarChart — stability score 0–100
│ │ │ ├── FearGreedDial.jsx # alternative.me sentiment dial widget
│ │ │ ├── FlagIcon.jsx # flagcdn.com flag component — reused everywhere
│ │ │ ├── SkeletonLoader.jsx # Shimmer skeleton — shown while any panel is loading
│ │ │ └── FilterBar.jsx # Event type + time range filter toggle buttons
│ │ ├── pages/
│ │ │ └── Dashboard.jsx # Main layout — all panels assembled, grid system
│ │ ├── hooks/
│ │ │ ├── useGlobeData.js # Fetches + caches globe event data from backend
│ │ │ ├── useNews.js # Fetches + auto-refreshes news feed every 5 min
│ │ │ └── useFinance.js # Fetches stock/crypto/forex prices on demand
│ │ ├── utils/
│ │ │ ├── severityColor.js # Maps severity string → hex color token
│ │ │ ├── regionMapper.js # Maps country ISO2 → region (Middle East, Europe, etc.)
│ │ │ ├── countryToIso.js # Maps country name → ISO2 for flagcdn.com
│ │ │ └── formatters.js # Price formatting, % change, lat/lon display
│ │ ├── App.jsx # Root component — React Router routes
│ │ ├── main.jsx # Vite entry point
│ │ └── index.css # Tailwind directives + CSS custom properties + animations
│ ├── tailwind.config.js # Font family + colour token extensions
│ ├── vite.config.js
│ └── package.json
│
├── server/ # Node.js + Express Backend
│ ├── models/
│ │ ├── BriefCache.js # MongoDB: AI briefs cached with 15-min TTL
│ │ └── SignalHistory.js # MongoDB: last 5 AI signals per ticker
│ ├── routes/
│ │ ├── events.js # GET /api/events — GDELT + ACLED + USGS aggregation
│ │ ├── news.js # GET /api/news — NewsAPI + RSS multi-source feed
│ │ ├── country.js # GET /api/country/:name — events + RestCountries metadata
│ │ ├── finance.js # GET /api/finance/:ticker — yahoo-finance2 price data
│ │ ├── flights.js # GET /api/flights — OpenSky Network aircraft positions
│ │ ├── ai.js # POST /api/ai/brief + /api/ai/signal — Groq×4 + Gemini
│ │ └── cyber.js # GET /api/cyber — abuse.ch + URLhaus + Cloudflare Radar
│ ├── services/
│ │ ├── groqService.js # 4-key Groq rotation logic — round-robin with auto-fallback
│ │ ├── gdeltService.js # GDELT fetch + parse into {lat, lon, title, severity, iso2}
│ │ └── cacheService.js # In-memory Map() cache — 5-min TTL for all API responses
│ ├── middleware/
│ │ └── rateLimiter.js # express-rate-limit — protect backend endpoints
│ ├── index.js # Express server entry + MongoDB Atlas connection
│ └── package.json
│
├── .env # All API keys — NEVER commit to GitHub
├── .gitignore
└── README.md
```
## 使用的 API
| 类别 | 服务 | 是否需要密钥? | 免费限制 |
|---|---|---|---|
| **地球** | Globe.gl | 否 | 无限制 |
| **地图** | Mapbox GL JS | 是 (免费) | 50,000 次加载/月 |
| **地图 (备用)** | MapLibre GL JS | 否 | 无限制 |
| **数据层** | Deck.gl | 否 | 无限制 |
| **国家多边形** | Natural Earth GeoJSON | 否 | 无限制,离线 |
| **地缘政治事件** | GDELT Project API | 否 | 无限制 |
| **冲突数据** | ACLED API | 是 (免费) | 黑客马拉松免费 |
| **新闻** | NewsAPI.org | 是 (免费) | 100 次/天 |
| **新闻 (RSS)** | rss-parser npm | 否 | 无限制 |
| **地震** | USGS Earthquake API | 否 | 无限制 |
| **灾难** | GDACS API | 否 | 无限制 |
| **野火** | NASA FIRMS API | 是 (免费) | 免费 |
| **国家元数据** | RestCountries API | 否 | 无限制 |
| **国旗** | flagcdn.com | 否 | 无限制 |
| **AI (主)** | Groq API — 密钥 1 | 是 (免费) | 免费层 |
| **AI (轮换 2)** | Groq API — 密钥 2 | 是 (免费) | 免费层 |
| **AI (轮换 3)** | Groq API — 密钥 3 | 是 (免费) | 免费层 |
| **AI (轮换 4)** | Groq API — 密钥 4 | 是 (免费) | 免费层 |
| **AI (备用)** | Google Gemini API | 是 (免费) | 15 次/分 |
| **浏览器 NLP** | Transformers.js | 否 | 无限制 (客户端) |
| **股票/大宗商品** | yahoo-finance2 npm | 否 | 无限制 |
| **加密货币** | CoinGecko API | 否 | 10,000 次/月 |
| **外汇** | ExchangeRate API | 是 (免费) | 1,500 次/月 |
| **市场情绪** | alternative.me API | 否 | 无限制 |
| **宏观数据** | World Bank API | 否 | 无限制 |
| **航班** | OpenSky Network API | 否 | 免费,匿名 |
| **军事航班** | ADS-B Exchange | 否 | 免费公开流 |
| **僵尸网络** | abuse.ch Feodo Tracker | 否 | 无限制 |
| **恶意软件** | URLhaus API | 否 | 无限制 |
| **互联网中断** | Cloudflare Radar API | 是 (免费) | 免费 |
| **IP 地理定位** | ipapi.co | 否 | 1,000 次/天 |
| **图标** | Font Awesome 6 Free | 否 | 无限制 (CDN) |
| **字体** | Google Fonts (Inter + JetBrains Mono) | 否 | 无限制 (CDN) |
## 环境变量
在 `/server/` 中创建一个 `.env` 文件 —— 切勿将此文件提交到 GitHub。
```
# ── AI — 4 个用于轮换的 Groq 密钥 (在 console.groq.com 创建 4 个免费账户)
GROQ_API_KEY_1=gsk_xxxxxxxxxxxxxxxxxxxx
GROQ_API_KEY_2=gsk_xxxxxxxxxxxxxxxxxxxx
GROQ_API_KEY_3=gsk_xxxxxxxxxxxxxxxxxxxx
GROQ_API_KEY_4=gsk_xxxxxxxxxxxxxxxxxxxx
# ── AI Fallback
GEMINI_API_KEY=AIzaxxxxxxxxxxxxxxxxxxxxxxx
# ── 新闻
NEWS_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ACLED_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NASA_FIRMS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ── 地图
MAPBOX_TOKEN=pk.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ── 金融
EXCHANGE_RATE_KEY=xxxxxxxxxxxxxxxxxxxxxxxx
# ── Cyber
CLOUDFLARE_RADAR_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ── 数据库
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/veridian
PORT=5000
```
## 技术栈
| 层级 | 技术 | 用途 |
|---|---|---|
| **前端框架** | React 18 + Vite | 快速 SPA —— 即时热重载 |
| **样式** | Tailwind CSS + custom CSS | 暗色指挥中心 UI + 动画 |
| **3D 地球** | Globe.gl | WebGL 地球 —— 点、弧线、热力图 |
| **2D 地图** | Mapbox GL JS + MapLibre GL JS | 平面地图切换视图 |
| **数据层** | Deck.gl | 热力图 + 航班弧线 |
| **图表** | Recharts | 迷你走势图、稳定性环、情绪表盘 |
| **HTTP 客户端** | Axios | 前端 → 后端 API 调用 |
| **路由** | React Router DOM v6 | SPA 路由 (单一仪表板路由) |
| **后端** | Node.js + Express | REST API 服务器 |
| **数据库** | MongoDB Atlas + Mongoose | 简报缓存、信号历史 |
| **AI 主力** | Groq API — 4 密钥轮换 | Llama 3.1 8B —— 简报 + 信号 |
| **AI 备用** | Google Gemini API | 当所有 4 个 Groq 密钥被限流时的后备 |
| **浏览器 ML** | Transformers.js | 客户端 NER + 情绪分析 |
| **图标** | Font Awesome 6 Free | 所有 UI 图标通过 CDN |
| **字体** | Inter + JetBrains Mono | Google Fonts CDN |
| **国旗** | flagcdn.com | 通过 ISO2 代码获取国旗 |
| **包管理器** | pnpm | 比 npm 快 50% 的安装速度 |
| **前端部署** | Vercel | 免费、无限制部署 |
| **后端部署** | Railway | $5 免费额度,无冷启动 |
## 系统架构
```
┌─────────────────────────────────────────────────────────────┐
│ DATA SOURCES │
├──────────────┬──────────────┬──────────────┬────────────────┤
│ GDELT/ACLED │ NewsAPI/RSS │ OpenSky │ Yahoo Finance │
│ USGS/GDACS │ │ ADS-B Exch. │ CoinGecko │
│ NASA FIRMS │ │ │ ExchangeRate │
└──────┬───────┴──────┬───────┴──────┬───────┴────────┬───────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ EXPRESS BACKEND (Node.js) │
│ │
│ /api/events /api/news /api/flights /api/finance │
│ /api/country /api/cyber /api/ai/brief /api/ai/signal │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ groqService.js — 4-Key Rotation │ │
│ │ Key 1 → Key 2 → Key 3 → Key 4 → Gemini Fallback │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌──────────────────────────────┐ │
│ │ cacheService │ │ MongoDB Atlas │ │
│ │ (in-memory Map)│ │ BriefCache + SignalHistory │ │
│ │ 5-min TTL │ │ 15-min TTL for AI briefs │ │
│ └─────────────────┘ └──────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────┘
│ REST API responses
▼
┌─────────────────────────────────────────────────────────────┐
│ REACT FRONTEND (Vite) │
│ │
│ Navbar (UTC clock) → Ticker (scrolling alerts) │
│ ↓ │
│ Globe.gl (3D globe with event dots + arcs + heatmap) │
│ ↓ click country │
│ CountryBrief panel (slides in) → StabilityRing + Risks │
│ │
│ NewsPanel ← flagcdn flags + FA icons + severity badges │
│ FinancePanel → StockCard → SignalBadge (BUY/SELL/HOLD) │
│ RegionPanel (2×2 grid) → 4 regional intelligence cards │
│ CyberLayer → purple dots on globe (toggle) │
└─────────────────────────────────────────────────────────────┘
```
## 快速开始
```
# Clone the repository
git clone https://github.com/yourusername/veridian.git
cd veridian
# 全局安装 pnpm (比 npm 更快)
npm install -g pnpm
# ── Backend setup
cd server
pnpm install
cp ../.env.example .env
# 在 .env 中填入您的 API keys
node index.js
# ── Frontend setup (新终端)
cd ../client
pnpm install
pnpm dev
```
访问 `http://localhost:5173` —— 地球会自动加载。
## 黑客马拉松推介
**VERIDIAN** —— *当地缘政治遇上交易情报*
`24 小时构建` · `MERN Stack` · `$0 运行成本` · `零模拟数据`
**在黑客马拉松上用心** **制作**
标签:3D地球, AI交易信号, ESC4, Express, GNU通用公共许可证, HTTP/HTTPS抓包, Llama 3.1, MERN Stack, MITM代理, MongoDB, Node.js, OSINT, React, Syscalls, Sysdig, 全球事件, 军事动态, 冲突监测, 地缘政治, 态势感知, 情报仪表盘, 投资辅助, 抗议活动, 灾难预警, 网络威胁, 金融科技