@@ -0,0 +1,161 @@
# Earth 新闻源配置
Earth 态势新闻使用 `/api/v1/news/earth-feed` 输出给前端。新闻源配置存放在 `SystemSetting.category = "earth_news_sources"` ;没有数据库配置时,后端使用内置默认源作为 fallback seed。
## 默认源
默认源包含四类:
- **新闻源**: BBC World、DW Top Stories、CNBC Business、BBC Business、Guardian Business、NPR Business、MarketWatch、TechCrunch、Retail Dive、PR Newswire Retail、36氪、亿邦动力、国家统计局数据发布。
- **行业洞察源**: McKinsey Retail、Deloitte Retail。
- **官方数据源**: 国家统计局数据发布、US Census Retail / E-Commerce、商务数据中心、商务部电商动态、电商物流指数。
- **线索源**: BusinessWire Electronic Commerce; Google News 作为一个聚合 source, 下面挂 global / americas / europe / middle-east-africa / asia-pacific 五个区域 Feed 子项。
配置型数据源默认保留在 Admin 配置中,但若不是稳定 RSS/Atom, 则默认不参与自动抓取。管理员可以在 `Earth 内容 -> 新闻源` 中改成可抓取 RSS、启用或禁用。
| 来源 | 类型 | 默认状态 | 默认主类型 | 主要标签 | 用途 |
| --- | --- | --- | --- | --- | --- |
| BBC World | RSS | 启用 | 政治 | `official_media` , `global` | 全球公共新闻基线 |
| DW Top Stories | RSS | 启用 | 政治 | `official_media` , `europe` | 欧洲与国际新闻基线 |
| CNBC Business | RSS | 启用 | 商业 | `business_news` , `us` , `global` | 国际商业新闻 |
| BBC Business / Guardian Business / NPR Business / MarketWatch | RSS | 启用 | 商业 / 金融 | `business_news` , `finance` | 英美商业与金融基线 |
| TechCrunch / Retail Dive / PR Newswire Retail | RSS | 启用 | 科技 / 商业 | `business_news` , `ecommerce` , `retail` , `press_release` | 科技、电商、零售和企业公告 |
| 36氪 | RSS | 启用 | 商业 | `business_news` , `ecommerce` , `china` | 国内商业、创投和快讯;主页是 `https://www.36kr.com/` , Feed 信息页是 `https://www.36kr.com/rss-center` , Feed 子项是综合资讯、文章资讯、最新快讯、动态内容 |
| 亿邦动力 | RSS | 启用 | 电商 | `ecommerce` , `business_news` , `china` , `retail` | 国内电商行业新闻;主页是 `https://www.ebrun.com/` , Feed 信息页是 `https://www.ebrun.com/rss/` , Feed 子项是 B2C、B2B、零售、O2O、服务、数据、政策 XML |
| 国家统计局数据发布 | RSS | 启用 | 电商 | `official_data` , `ecommerce` , `retail` , `china` | 官方数据发布 RSS; 社零和网上零售条目由分类/重要度规则识别 |
| Google News | Aggregated | 启用 | 政治 | `aggregated` , `low_stability` | 一个聚合 source, Feed 子项为全球、美洲、欧洲、中东与非洲、亚太区域兜底 RSS; 优先级低于真实 RSS |
| BusinessWire Electronic Commerce | Reference | 禁用 | 电商 | `press_release` , `ecommerce` , `low_stability` | 企业公告线索 |
| McKinsey Retail Insights | Reference | 禁用 | 商业 | `industry_insight` , `retail` | 零售行业洞察 |
| Deloitte Retail | Reference | 禁用 | 商业 | `industry_insight` , `retail` | 零售行业洞察 |
| US Census Retail / E-Commerce | Reference | 禁用 | 电商 | `official_data` , `ecommerce` , `retail` , `us` | 美国零售和电商官方数据 |
| 商务数据中心 | Reference | 禁用 | 商业 | `official_data` , `china` | 国内商务数据 |
| 商务部电商动态 | Reference | 禁用 | 电商 | `official_data` , `ecommerce` , `china` | 国内电商政策与动态 |
| 电商物流指数 | Reference | 禁用 | 电商 | `official_data` , `ecommerce` , `logistics` , `china` | 物流履约与电商景气度 |
`Reference` 源表示参考链接/未来采集器线索,只记录官网、报告页或数据页,不参与 RSS/Atom 抓取。这样可以把商业与官方数据源先纳入后台治理,同时避免不可抓取页面拖垮新闻 feed。
新闻源模型是两层结构:
- `source` 表示来源品牌或聚合器,例如 36氪、亿邦动力、Google News、BBC。
- `homepage_url` 表示来源官网、栏目页或报告页。
- `feed_directory_url` 表示 Feed 信息页,也就是 RSS 订阅中心或 Feed 聚合页,只用于人工查看,不参与抓取。
- `feeds` 表示该来源下真正抓取的 RSS、Atom 或 Aggregated 子项。每个 Feed 子项都有 `id / name / url / type / enabled / default_category / tags / priority` 。
后端会遍历同一 source 下所有启用的 Feed 子项,逐个抓取、合并去重,并把单个子项的检测结果写入 `health.feed_results` 。这不是“备用地址”逻辑; 36氪的四个订阅地址、亿邦的多个分类 XML、Google News 的五个区域 RSS 都可以同时启用,并且每个 Feed 可以单独配置默认新闻类型和启用状态。HTML 订阅中心或聚合页只能放在 `feed_directory_url` ,不能放进 Feed 地址。默认启用的可抓 Feed 已逐项连通性检测: RSS/Atom/Aggregated Feed 必须解析到条目, Reference 源只保留参考地址和后续采集器线索。
当前仍保留为 Reference 的项不是“坏源”,而是没有找到稳定、可直接消费的 RSS/Atom:
- BusinessWire 官方说明支持可定制 RSS/Atom, 但公开页面未暴露稳定行业 feed URL; 当前保留电子商务行业页作为公告线索。
- McKinsey / Deloitte 的零售洞察页是报告和文章集合,不是公开 RSS。
- US Census 的 press release RSS 可访问, 但条目链接为空; Quarterly E-Commerce 页面保留为官方数据参考链接。
- 商务部数据、电商物流指数目前未找到稳定 RSS, 后续应做专用 collector 或人工配置可抓 feed。
## 源属性标签与新闻类型
新闻源有 `source_tags` ,在 Admin 中显示为“源属性标签”。它用于描述 source 的属性,不是媒体来源名,也不是新闻条目的内容类型。例如:
- `official_data` :官方数据
- `business_news` :商业新闻
- `ecommerce` :电商
- `finance` :金融
- `retail` :零售
- `logistics` :物流
- `industry_insight` :行业洞察
- `press_release` :企业公告
- `china` 、`global` 、`us`
- `aggregated` 、`low_stability`
单条新闻有一个主类型 `category` ,默认类型包括:政治、商业、电商、金融、体育、科技、军事、灾害、能源、社会、文化、其他。`item_tags` 是条目级补充标签, 例如跨境电商、直播电商、零售数据、物流履约、平台治理、AI、半导体、选举、油价、足球、供应链。
主类型优先由规则引擎根据标题、摘要、来源名打分生成;规则未命中时优先使用 Feed 子项的默认类型,再回退 source 默认类型。AI enrichment 不阻塞新闻展示。
## 重要度
每条新闻输出:
- `importance_score`
- `importance_level`
- `importance_reasons`
- `market_impact`
官方数据源、电商指标、平台型公司、量化指标会提高重要度;企业公告基础权重较低,只有命中大平台、金额、并购、监管等信号时提升。
## 配置与缓存
`GET /api/v1/earth/news-sources` 返回默认或已保存配置。`PUT /api/v1/earth/news-sources` 保存配置并递增 `cache_version` ,同时清理进程内 region cache。`POST /api/v1/earth/news-sources/reset` 恢复默认源。`POST /api/v1/earth/news-sources/test` 只测试单个 RSS/Atom/Aggregated 源,不写入新闻表。
## Feed 查询与类型过滤
星球端和 UE 端统一使用 `GET /api/v1/news/earth-feed` 获取新闻。接口支持服务端过滤,不要求客户端拿全量列表后自行筛选。
- `lat` / `lon` :按当前视角推断区域,适合 Web 星球端。
- `region` :显式指定区域,适合 UE 端或服务端集成;可选值包括 `global` 、`americas` 、`europe` 、`asia-pacific` 、`middle-east-africa` 。`global` 是全局聚合视图,会展示所有区域来源;其它区域只展示该区域和 `global` 来源。
- `categories` :逗号分隔的新闻类型 key, 例如 `business,ecommerce` 。全选时可以不传。
- `locale` :展示语言,支持 `zh-CN` 和 `en-US` ,默认 `zh-CN` 。中文 RSS 会以中文原文入库,并由后台补 `en-US` ;英文 RSS 则由后台补 `zh-CN` 。
示例:
``` http
G E T / a p i / v 1 / n e w s / e a r t h - f e e d ? r e g i o n = e u r o p e & c a t e g o r i e s = b u s i n e s s , e c o m m e r c e
G E T / a p i / v 1 / n e w s / e a r t h - f e e d ? l a t = 4 8 & l o n = 1 0 & c a t e g o r i e s = t e c h n o l o g y
G E T / a p i / v 1 / n e w s / e a r t h - f e e d ? r e g i o n = g l o b a l & c a t e g o r i e s = b u s i n e s s , e c o m m e r c e & l o c a l e = z h - C N
```
非法新闻类型或语言会返回 `422` ,响应中包含允许值。响应体会带 `filters` ,用于确认后端实际应用的区域、类型和语言过滤。`items` 和 `cruise_items` 使用同一套类型过滤规则。
Web 星球端的新闻类型按钮只保存当前浏览器的显示偏好; 偏好变化后会重新请求接口。UE 端应直接把类型选择拼到 `categories` 参数里,不需要再做主过滤。
源测试只证明当前 RSS/Atom/XML 能解析到条目,不等于这些条目已经入库展示。展示链路还会检查区域、类型过滤和数据库新鲜度。保存或重置新闻源会递增配置版本并清理缓存;如果当前启用的 Feed 子项在库里没有近期条目,下一次 `earth-feed` 请求会补抓,避免新启用的 36氪、亿邦被旧 Google News 缓存挡住。
## 连通性监测
`POST /api/v1/earth/news-sources/test` 会测试单个源并把结果写入 `earth_news_sources.health[source_id]` 。实际 RSS/Atom 抓取也会更新同一份健康状态。
健康结果包含:
- `status` : `ok` 、`empty` 、`format_error` 、`http_error` 、`timeout` 、`network_error` 、`reference` 。
- `status_code` 、`content_type` 、`item_count` 、`latency_ms` 、`error` 、`fetched_at` 。
- `feed_results` :多 Feed source 的逐 Feed 子项检测结果,包含 `feed_id` 、`feed_name` 、`feed_type` 、`feed_url` 、状态、条数和错误。
常见诊断:
- 返回 HTML 页面:说明配置 URL 不是 RSS/Atom feed, 例如把网页中心页当成 feed。
- HTTP 403: 通常是 CDN、反爬或源站拒绝抓取。
- Reference: 参考链接, 不参与抓取; 需要改为 RSS、Atom 或 Aggregated 后才可测试抓取。
Admin 入口是 `Earth 内容 -> 新闻源` 。界面不是整包 JSON 编辑,而是两层:
- **新闻源**:左侧逐个 source 列表, 支持按启用、停用、参考链接、RSS/Atom/Aggregated、区域和源属性标签筛选; 右侧编辑当前 source 字段和 Feed 子项列表。
- **策略规则**:保留源属性标签、新闻类型、条目标签规则、默认健康策略等全局规则。高级 JSON 只用于排障,不作为默认编辑路径。
单源表单分为“来源信息”和“Feed 子项”:
- 来源信息包括名称、ID、区域、主页 URL、Feed 信息页、源类型、启用开关、源属性标签、重要度权重、抓取间隔、超时、失败阈值和熔断开关。
- Feed 子项包括 Feed ID、名称、真实 Feed URL、类型、启用开关、默认新闻类型、优先级和 Feed 标签。Feed 子项底部的 `+` 只新增一个前端草稿;保存 source 后才写入配置,取消会销毁草稿。
单源“测试源”会测试当前 source 下全部启用 Feed; Feed 子项上的测试按钮只测试当前 Feed。测试请求仍发送到 `/api/v1/earth/news-sources/test` ,但 payload 里只带当前 source 和选中的 Feed 子项。
参考链接会显示“只记录官网、报告页或未来采集器线索,不参与 RSS/Atom 抓取”。它可作为商业或官方数据线索保留在配置中,但启用抓取前必须改成 RSS、Atom 或 Aggregated, 并提供可抓取的 Feed 地址。
``` mermaid
flowchart LR
Admin["Admin: Earth 内容 / 新闻源"] --> Source["Source 配置"]
Source --> Feed["Feed 子项"]
Feed --> ConfigAPI["/api/v1/earth/news-sources"]
ConfigAPI --> Config["SystemSetting: earth_news_sources"]
Earth["Earth 新闻面板"] --> NewsAPI["/api/v1/news/earth-feed"]
NewsAPI --> Resolver["Source Resolver"]
Resolver --> Config
Resolver --> Cache["Region Feed Cache"]
Resolver --> Fetcher["RSS / Atom Fetcher"]
Fetcher --> Parser["Feed Parser"]
Parser --> Classifier["Classifier: category + item_tags + importance"]
Classifier --> Store["earth_news_items"]
Fetcher --> Health["source health"]
Health --> Config
Store --> EnrichQueue["Location / Localization Queue"]
EnrichQueue --> AI["AI Provider"]
Store --> NewsAPI
UE["UE Client"] --> NewsAPI
```