From aa9cf128d55ab11a3be60199f4a854b24c7defc4 Mon Sep 17 00:00:00 2001
From: zheng <18760530726@163.com>
Date: Thu, 30 Apr 2026 14:20:56 +0800
Subject: [PATCH] feat: update news service to fetch Naver Stock news and
enhance category handling
---
.env.example | 5 +-
.idea/.gitignore | 8 +
.idea/copilot.data.migration.ask2agent.xml | 6 +
README.md | 32 +-
data/images/00423321d15041b5393762d8.jpg | Bin 0 -> 90709 bytes
data/images/03af58329dd7bd7fcd08caad.jpg | Bin 0 -> 98878 bytes
data/images/0445b97587e4c18101545440.jpg | Bin 0 -> 55027 bytes
data/images/0f96cb3f70a4acd146221745.jpg | Bin 0 -> 103251 bytes
data/images/11778425c7e41f364095c173.jpg | Bin 0 -> 166523 bytes
data/images/1bd919fe25561f244ba4bcde.jpg | Bin 0 -> 187512 bytes
data/images/1e692bb0a695d254ec4c5b52.png | Bin 0 -> 723674 bytes
data/images/21a2fb69ddc27788a8f90a2d.png | Bin 0 -> 215319 bytes
data/images/29a20d669f90c51ca45028eb.jpg | Bin 0 -> 41097 bytes
data/images/2c1f2057e6af366bf3015f4e.jpg | Bin 0 -> 93389 bytes
data/images/2cf8458e423bfdbf34c2acee.png | Bin 0 -> 800163 bytes
data/images/2d3065fcd29569d3e701f490.jpg | Bin 0 -> 155694 bytes
data/images/2d963b28def0c168195ad9d8.jpg | Bin 0 -> 213606 bytes
data/images/34197e5f6ef10ba5374ba06c.jpg | Bin 0 -> 231476 bytes
data/images/343eccb6d55919e039fc623a.jpg | Bin 0 -> 169112 bytes
data/images/348dc9cbc9f3bfcfb69faaf3.jpg | Bin 0 -> 55004 bytes
data/images/36fd3a527a390add0e94e45a.png | Bin 0 -> 26451 bytes
data/images/39d36e714c455c22a8ae33e8.jpg | Bin 0 -> 32895 bytes
data/images/3b031723f9b8f70495cbe385.jpg | Bin 0 -> 148944 bytes
data/images/3e05220de047caa3995223f7.jpg | Bin 0 -> 199170 bytes
data/images/40f0e5b20b96a98d559b2393.jpg | Bin 0 -> 490850 bytes
data/images/4e61d48bc97636e335c58571.jpg | Bin 0 -> 523761 bytes
data/images/593d13ceade737dab3554b79.jpg | Bin 0 -> 650040 bytes
data/images/594e056c755a3d8896657cb5.jpg | Bin 0 -> 174469 bytes
data/images/6747eff8ce40e840a4bcc543.jpg | Bin 0 -> 45240 bytes
data/images/6e1153f65f086156ab4507ff.jpg | Bin 0 -> 28252 bytes
data/images/774506d32ba3ebee62d98b73.jpg | Bin 0 -> 149933 bytes
data/images/8042891de0f32ce59c98bd0c.jpg | Bin 0 -> 70179 bytes
data/images/8091fc1d13183104e622930b.png | Bin 0 -> 338542 bytes
data/images/8425db5d40cdea4ebc5e48f3.png | Bin 0 -> 267890 bytes
data/images/878e7cffa8e291d9522789eb.jpg | Bin 0 -> 123774 bytes
data/images/8b832a8f758e51991a9d806b.jpg | Bin 0 -> 13708 bytes
data/images/8c36e3ba8584a98cf35d5cc1.jpg | Bin 0 -> 27784 bytes
data/images/91beb422e27fa644a3ded9d8.jpg | Bin 0 -> 165397 bytes
data/images/a3b1c1c137445c6a9f013faa.png | Bin 0 -> 900212 bytes
data/images/a65420883cb64d52d995bf05.jpg | Bin 0 -> 37018 bytes
data/images/a6c2b277c006cae54ecf9693.jpg | Bin 0 -> 126120 bytes
data/images/a9ea4d406363057edacb7374.jpg | Bin 0 -> 102646 bytes
data/images/aa72b4d241ff62d6db375671.jpg | Bin 0 -> 376176 bytes
data/images/ad8ece98c5c1b89ba27a8d25.jpg | Bin 0 -> 55117 bytes
data/images/adea914ec8333f341be544a9.jpg | Bin 0 -> 59986 bytes
data/images/b3d584f58bafaab635d7f163.png | Bin 0 -> 414364 bytes
data/images/b8c0278d1658dbac496e0ec9.jpg | Bin 0 -> 628510 bytes
data/images/be51644c19d367d060b5d000.jpg | Bin 0 -> 12571 bytes
data/images/c13b05772b18a142f0336ec7.jpg | Bin 0 -> 330540 bytes
data/images/c14aad170cd82cb71f8be5bd.jpg | Bin 0 -> 338439 bytes
data/images/c1ae0a2f3988bd10c1cdde1a.jpg | Bin 0 -> 869526 bytes
data/images/c2821ab7c799d75c5500802b.jpg | Bin 0 -> 598041 bytes
data/images/ce3466877b5e2c28cade8501.jpg | Bin 0 -> 47467 bytes
data/images/d55f68fc3dbf94434e03cff2.jpg | Bin 0 -> 139103 bytes
data/images/d57b617286902ce0da1bb251.jpg | Bin 0 -> 101498 bytes
data/images/d624bea44fe62b165261612a.jpg | Bin 0 -> 1022249 bytes
data/images/da3e038ca74a61db5394bc61.jpg | Bin 0 -> 48441 bytes
data/images/da744f3531167c5d7001261e.jpg | Bin 0 -> 136529 bytes
data/images/dee3d95f4cbedbc4994f979c.jpg | Bin 0 -> 64435 bytes
data/images/e19e8ee8bb7402e20565e131.jpg | Bin 0 -> 1191688 bytes
data/images/e57fdc4ec3fe336171017972.jpg | Bin 0 -> 111126 bytes
data/images/e5bf9b4dd404f89b7d348c12.jpg | Bin 0 -> 675722 bytes
data/images/e6678a79c0572cde599ee828.jpg | Bin 0 -> 105171 bytes
data/images/e6702a617db5c421a3510f48.jpg | Bin 0 -> 438607 bytes
data/images/e74737997b7c3f4c8ffa7ea7.jpg | Bin 0 -> 158702 bytes
data/images/e7b005f7b80c0ba4e53e97b3.jpg | Bin 0 -> 200965 bytes
data/images/e7bfe5e2f987a7673da6471a.png | Bin 0 -> 30109 bytes
data/images/ee9eab40f9d168aa9c549a84.png | Bin 0 -> 12620 bytes
data/images/eedd7a47590307fe54239b5e.jpg | Bin 0 -> 49816 bytes
data/images/efa91e02e3651fb87da539ea.jpg | Bin 0 -> 33685 bytes
data/images/f1c24f189a00d53ffee40fdc.jpg | Bin 0 -> 70296 bytes
data/images/f37e986168453dc4ca027ad0.png | Bin 0 -> 5553 bytes
data/images/f6af6c96c9b014194de9d35b.jpg | Bin 0 -> 81633 bytes
data/images/fd277d3e4a2f19326a5eb13f.png | Bin 0 -> 339930 bytes
data/images/fe45b775cea5b0a60432da73.png | Bin 0 -> 36167 bytes
data/images/ff314f9050050192460333b5.png | Bin 0 -> 985523 bytes
docker-compose.yml | 5 +-
src/app/NewsApplication.js | 14 +-
src/config/CategoryCatalog.js | 30 +-
src/config/ServiceConfig.js | 7 +-
src/services/NewsApiClient.js | 389 ++++++++++++++++++---
src/services/NewsStorageService.js | 5 +-
82 files changed, 414 insertions(+), 87 deletions(-)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/copilot.data.migration.ask2agent.xml
create mode 100644 data/images/00423321d15041b5393762d8.jpg
create mode 100644 data/images/03af58329dd7bd7fcd08caad.jpg
create mode 100644 data/images/0445b97587e4c18101545440.jpg
create mode 100644 data/images/0f96cb3f70a4acd146221745.jpg
create mode 100644 data/images/11778425c7e41f364095c173.jpg
create mode 100644 data/images/1bd919fe25561f244ba4bcde.jpg
create mode 100644 data/images/1e692bb0a695d254ec4c5b52.png
create mode 100644 data/images/21a2fb69ddc27788a8f90a2d.png
create mode 100644 data/images/29a20d669f90c51ca45028eb.jpg
create mode 100644 data/images/2c1f2057e6af366bf3015f4e.jpg
create mode 100644 data/images/2cf8458e423bfdbf34c2acee.png
create mode 100644 data/images/2d3065fcd29569d3e701f490.jpg
create mode 100644 data/images/2d963b28def0c168195ad9d8.jpg
create mode 100644 data/images/34197e5f6ef10ba5374ba06c.jpg
create mode 100644 data/images/343eccb6d55919e039fc623a.jpg
create mode 100644 data/images/348dc9cbc9f3bfcfb69faaf3.jpg
create mode 100644 data/images/36fd3a527a390add0e94e45a.png
create mode 100644 data/images/39d36e714c455c22a8ae33e8.jpg
create mode 100644 data/images/3b031723f9b8f70495cbe385.jpg
create mode 100644 data/images/3e05220de047caa3995223f7.jpg
create mode 100644 data/images/40f0e5b20b96a98d559b2393.jpg
create mode 100644 data/images/4e61d48bc97636e335c58571.jpg
create mode 100644 data/images/593d13ceade737dab3554b79.jpg
create mode 100644 data/images/594e056c755a3d8896657cb5.jpg
create mode 100644 data/images/6747eff8ce40e840a4bcc543.jpg
create mode 100644 data/images/6e1153f65f086156ab4507ff.jpg
create mode 100644 data/images/774506d32ba3ebee62d98b73.jpg
create mode 100644 data/images/8042891de0f32ce59c98bd0c.jpg
create mode 100644 data/images/8091fc1d13183104e622930b.png
create mode 100644 data/images/8425db5d40cdea4ebc5e48f3.png
create mode 100644 data/images/878e7cffa8e291d9522789eb.jpg
create mode 100644 data/images/8b832a8f758e51991a9d806b.jpg
create mode 100644 data/images/8c36e3ba8584a98cf35d5cc1.jpg
create mode 100644 data/images/91beb422e27fa644a3ded9d8.jpg
create mode 100644 data/images/a3b1c1c137445c6a9f013faa.png
create mode 100644 data/images/a65420883cb64d52d995bf05.jpg
create mode 100644 data/images/a6c2b277c006cae54ecf9693.jpg
create mode 100644 data/images/a9ea4d406363057edacb7374.jpg
create mode 100644 data/images/aa72b4d241ff62d6db375671.jpg
create mode 100644 data/images/ad8ece98c5c1b89ba27a8d25.jpg
create mode 100644 data/images/adea914ec8333f341be544a9.jpg
create mode 100644 data/images/b3d584f58bafaab635d7f163.png
create mode 100644 data/images/b8c0278d1658dbac496e0ec9.jpg
create mode 100644 data/images/be51644c19d367d060b5d000.jpg
create mode 100644 data/images/c13b05772b18a142f0336ec7.jpg
create mode 100644 data/images/c14aad170cd82cb71f8be5bd.jpg
create mode 100644 data/images/c1ae0a2f3988bd10c1cdde1a.jpg
create mode 100644 data/images/c2821ab7c799d75c5500802b.jpg
create mode 100644 data/images/ce3466877b5e2c28cade8501.jpg
create mode 100644 data/images/d55f68fc3dbf94434e03cff2.jpg
create mode 100644 data/images/d57b617286902ce0da1bb251.jpg
create mode 100644 data/images/d624bea44fe62b165261612a.jpg
create mode 100644 data/images/da3e038ca74a61db5394bc61.jpg
create mode 100644 data/images/da744f3531167c5d7001261e.jpg
create mode 100644 data/images/dee3d95f4cbedbc4994f979c.jpg
create mode 100644 data/images/e19e8ee8bb7402e20565e131.jpg
create mode 100644 data/images/e57fdc4ec3fe336171017972.jpg
create mode 100644 data/images/e5bf9b4dd404f89b7d348c12.jpg
create mode 100644 data/images/e6678a79c0572cde599ee828.jpg
create mode 100644 data/images/e6702a617db5c421a3510f48.jpg
create mode 100644 data/images/e74737997b7c3f4c8ffa7ea7.jpg
create mode 100644 data/images/e7b005f7b80c0ba4e53e97b3.jpg
create mode 100644 data/images/e7bfe5e2f987a7673da6471a.png
create mode 100644 data/images/ee9eab40f9d168aa9c549a84.png
create mode 100644 data/images/eedd7a47590307fe54239b5e.jpg
create mode 100644 data/images/efa91e02e3651fb87da539ea.jpg
create mode 100644 data/images/f1c24f189a00d53ffee40fdc.jpg
create mode 100644 data/images/f37e986168453dc4ca027ad0.png
create mode 100644 data/images/f6af6c96c9b014194de9d35b.jpg
create mode 100644 data/images/fd277d3e4a2f19326a5eb13f.png
create mode 100644 data/images/fe45b775cea5b0a60432da73.png
create mode 100644 data/images/ff314f9050050192460333b5.png
diff --git a/.env.example b/.env.example
index eef1f81..ce11921 100644
--- a/.env.example
+++ b/.env.example
@@ -1,7 +1,4 @@
PORT=3100
-NEWS_API_KEY=03f614876f0645948cb9bbce1661f4b2
-NEWS_API_BASE_URL=https://newsapi.org/v2/everything
-NEWS_API_LANGUAGE=ko
NEWS_PAGE_SIZE=20
NEWS_REFRESH_CRON=0 * * * *
-DATA_DIR=./data
\ No newline at end of file
+DATA_DIR=./data
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml
new file mode 100644
index 0000000..1f2ea11
--- /dev/null
+++ b/.idea/copilot.data.migration.ask2agent.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 70d5f2a..29a2b68 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# News Service
-独立新闻微服务,负责周期性从 NewsAPI 拉取新闻并落盘为 JSON 文件,再通过 HTTP 接口提供给前端。
+独立新闻微服务,负责周期性从 Naver Stock 新闻接口拉取新闻并落盘为 JSON 文件,再通过 HTTP 接口提供给前端。
## 功能
@@ -12,20 +12,20 @@
## 分类
-- finance
-- business
-- technology
-- market
+- flashnews
+- mainnews
+- ranknews
+- worldnews
## 目录
```text
news_service/
data/
- finance.json
- business.json
- technology.json
- market.json
+ flashnews.json
+ mainnews.json
+ ranknews.json
+ worldnews.json
src/
app/
config/
@@ -76,15 +76,15 @@ GET /api/news/categories
### 获取指定分类新闻
```http
-GET /api/news?category=finance&limit=10
-GET /api/news/finance?limit=10
+GET /api/news?category=flashnews&limit=10
+GET /api/news/flashnews?limit=10
```
### 兼容前端现有 NewsAPI 调用
```http
-GET /v2/everything?q=finance&language=ko&pageSize=10&page=1
-GET /v2/top-headlines?category=business&country=ko&pageSize=10
+GET /v2/everything?q=flashnews&language=ko&pageSize=10&page=1
+GET /v2/top-headlines?category=mainnews&country=ko&pageSize=10
```
返回结构与前端当前使用的 NewsAPI 结构保持一致:
@@ -107,7 +107,7 @@ GET /api/news/all?limit=10
```http
POST /api/news/refresh
-POST /api/news/refresh?category=finance
+POST /api/news/refresh?category=flashnews
```
## Docker
@@ -123,8 +123,8 @@ cd /Users/wjp/Projects/juYou
docker compose -f docker-compose.news-stack.yml up -d --build
```
-这样前端容器中的 Nginx 会把同源路径 `/newsapi/*` 代理到容器网络中的 `news-service:3100`,浏览器不会直接访问 NewsAPI,因此不会触发跨域限制。
+这样前端容器中的 Nginx 会把同源路径 `/newsapi/*` 代理到容器网络中的 `news-service:3100`,浏览器不会直接访问外部新闻接口,因此不会触发跨域限制。
## 前端接入建议
-前端如果继续使用原来的 `/newsapi/v2/*` 请求方式,只需要把代理目标指向本服务即可,不需要修改新闻请求代码。
\ No newline at end of file
+前端如果继续使用原来的 `/newsapi/v2/*` 请求方式,只需要把代理目标指向本服务即可,不需要修改新闻请求代码。
diff --git a/data/images/00423321d15041b5393762d8.jpg b/data/images/00423321d15041b5393762d8.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e7e4ec33db806230d7b0f411e2a5d324780a447b
GIT binary patch
literal 90709
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