feat(server): 更新默认端口为 5000 并支持环境变量配置

- 将 Web 服务器默认端口从 3000 更改为 5000
- 支持通过环境变量 PORT 自定义端口
- 添加 dotenv 依赖以加载环境变量
- 更新 README.md 中的所有相关端口说明
- 配置文件 config.json 加入 .gitignore 以防止敏感信息泄露
- 前端 API 地址改为自动检测当前域名和端口,提升部署灵活性
```
This commit is contained in:
2025-12-15 15:58:48 +08:00
parent 00658a3445
commit f35d4575c8
8 changed files with 48 additions and 6 deletions

11
.env.example Normal file
View File

@@ -0,0 +1,11 @@
# 服务器端口配置
PORT=5000
# 环境说明:
# - 开发环境:通常使用 5000
# - 生产环境:可以使用 80、8080 等
#
# 使用方法:
# 1. 复制此文件为 .env
# 2. 修改端口号
# 3. 启动服务时会自动读取

3
.gitignore vendored
View File

@@ -12,6 +12,9 @@ pnpm-debug.log*
.env.local .env.local
.env.*.local .env.*.local
# 配置文件(包含敏感信息)
config.json
# 编辑器目录和文件 # 编辑器目录和文件
.vscode/ .vscode/
.idea/ .idea/

View File

@@ -52,7 +52,7 @@ npm start
### 2. 访问界面 ### 2. 访问界面
打开浏览器访问: **http://localhost:3000** 打开浏览器访问: **http://localhost:5000** (或您配置的端口)
### 3. 功能介绍 ### 3. 功能介绍
@@ -230,7 +230,7 @@ POST /api/run-scheduled-task
### 通过 Web 界面配置(推荐) ### 通过 Web 界面配置(推荐)
1. 访问 `http://localhost:3000` 1. 访问 `http://localhost:5000` (或您配置的端口)
2. 切换到 **"定时任务"** 标签 2. 切换到 **"定时任务"** 标签
3. 配置以下选项: 3. 配置以下选项:
- **启用定时任务**:勾选启用 - **启用定时任务**:勾选启用
@@ -349,7 +349,7 @@ sudo systemctl status gjzx-scraper
-**无需数据库**:项目采用无数据库架构,轻量部署 -**无需数据库**:项目采用无数据库架构,轻量部署
-**配置持久化**:所有配置保存在 `config.json` 文件中 -**配置持久化**:所有配置保存在 `config.json` 文件中
-**进程保活**:使用 PM2 或 systemd 确保进程持续运行 -**进程保活**:使用 PM2 或 systemd 确保进程持续运行
- ⚠️ **防火墙**:确保 3000 端口可访问 - ⚠️ **防火墙**:确保配置的端口可访问(默认 5000
- ⚠️ **配置安全**:不要将 `config.json` 提交到公开仓库 - ⚠️ **配置安全**:不要将 `config.json` 提交到公开仓库
## 技术栈 ## 技术栈
@@ -405,7 +405,7 @@ sudo systemctl status gjzx-scraper
1. **采集速度**:已限制为每条延迟 500ms-1s避免请求过快 1. **采集速度**:已限制为每条延迟 500ms-1s避免请求过快
2. **域名支持**:仅支持 gjzx.nanjing.gov.cn 域名的详情页解析 2. **域名支持**:仅支持 gjzx.nanjing.gov.cn 域名的详情页解析
3. **金额提取**:基于正则匹配,支持多种格式(预算金额、最高限价等) 3. **金额提取**:基于正则匹配,支持多种格式(预算金额、最高限价等)
4. **端口配置**Web 服务器默认端口 3000可在 server.js 中修改 4. **端口配置**Web 服务器默认端口 5000支持通过环境变量 PORT 修改
5. **智能停止**:按时间范围采集会在检测到所有公告早于起始日期时自动停止 5. **智能停止**:按时间范围采集会在检测到所有公告早于起始日期时自动停止
6. **编码处理**:自动识别,支持 GBK 和 UTF-8 网页 6. **编码处理**:自动识别,支持 GBK 和 UTF-8 网页
7. **配置安全**config.json 包含敏感信息,已加入 .gitignore不要提交到公开仓库 7. **配置安全**config.json 包含敏感信息,已加入 .gitignore不要提交到公开仓库

12
node_modules/.package-lock.json generated vendored
View File

@@ -440,6 +440,18 @@
"url": "https://github.com/fb55/domutils?sponsor=1" "url": "https://github.com/fb55/domutils?sponsor=1"
} }
}, },
"node_modules/dotenv": {
"version": "17.2.3",
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-17.2.3.tgz",
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": { "node_modules/dunder-proto": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",

13
package-lock.json generated
View File

@@ -12,6 +12,7 @@
"cheerio": "^1.0.0-rc.12", "cheerio": "^1.0.0-rc.12",
"cors": "^2.8.5", "cors": "^2.8.5",
"docx": "^9.5.1", "docx": "^9.5.1",
"dotenv": "^17.2.3",
"express": "^5.2.1", "express": "^5.2.1",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"node-cron": "^4.2.1", "node-cron": "^4.2.1",
@@ -599,6 +600,18 @@
"url": "https://github.com/fb55/domutils?sponsor=1" "url": "https://github.com/fb55/domutils?sponsor=1"
} }
}, },
"node_modules/dotenv": {
"version": "17.2.3",
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-17.2.3.tgz",
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": { "node_modules/dunder-proto": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",

View File

@@ -12,6 +12,7 @@
"cheerio": "^1.0.0-rc.12", "cheerio": "^1.0.0-rc.12",
"cors": "^2.8.5", "cors": "^2.8.5",
"docx": "^9.5.1", "docx": "^9.5.1",
"dotenv": "^17.2.3",
"express": "^5.2.1", "express": "^5.2.1",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"node-cron": "^4.2.1", "node-cron": "^4.2.1",

View File

@@ -1,4 +1,5 @@
const API_BASE = 'http://localhost:3000/api'; // 自动检测当前域名和端口,支持不同环境
const API_BASE = `${window.location.origin}/api`;
let currentReport = null; let currentReport = null;
let currentListPage = 1; let currentListPage = 1;

View File

@@ -1,3 +1,4 @@
import 'dotenv/config';
import express from 'express'; import express from 'express';
import cors from 'cors'; import cors from 'cors';
import axios from 'axios'; import axios from 'axios';
@@ -7,7 +8,7 @@ import { sendReportEmail } from './emailService.js';
import { initScheduler, runTaskNow, reloadScheduler, getSchedulerStatus } from './scheduler.js'; import { initScheduler, runTaskNow, reloadScheduler, getSchedulerStatus } from './scheduler.js';
const app = express(); const app = express();
const PORT = 3000; const PORT = process.env.PORT || 5000;
app.use(cors()); app.use(cors());
app.use(express.json()); app.use(express.json());