|
@@ -1,4 +1,4 @@
|
|
|
-# Glacier 公司管理系统 — 技术架构设计(草案 v0.3)
|
|
|
|
|
|
|
+# Glacier 公司管理系统 — 技术架构设计(草案 v0.4)
|
|
|
|
|
|
|
|
> 状态:设计阶段(已确认关键技术决策,见 §0),仅设计,不写代码。
|
|
> 状态:设计阶段(已确认关键技术决策,见 §0),仅设计,不写代码。
|
|
|
> 适用范围:Glacier 公司内部管理系统(首页 + 业务功能子空间 + 数据采集)。
|
|
> 适用范围:Glacier 公司内部管理系统(首页 + 业务功能子空间 + 数据采集)。
|
|
@@ -15,7 +15,8 @@
|
|
|
| 4 | 数据库 | **单库多表**(库名 `glacier`) | §3.5:统一表前缀约定,避免表名冲突 |
|
|
| 4 | 数据库 | **单库多表**(库名 `glacier`) | §3.5:统一表前缀约定,避免表名冲突 |
|
|
|
| 5 | 上传文件 | **本地磁盘**,但**规避直接访问** | §3.9:存 `storage/uploads/`(Web 根之外),经控制器鉴权下发 |
|
|
| 5 | 上传文件 | **本地磁盘**,但**规避直接访问** | §3.9:存 `storage/uploads/`(Web 根之外),经控制器鉴权下发 |
|
|
|
| 6 | 语言 / 时区 | **中文界面**,**UTC+8** | §3.4:全链路统一时区与字符集 |
|
|
| 6 | 语言 / 时区 | **中文界面**,**UTC+8** | §3.4:全链路统一时区与字符集 |
|
|
|
-| 7 | 数据来源 | **Python 爬虫**为可能的数据来源 | §3.8:独立 Python 采集管道,入库供系统展示 |
|
|
|
|
|
|
|
+| 7 | 数据来源 | **Python 爬虫**为可能的数据来源 | §3.8:采集入库供系统展示 |
|
|
|
|
|
+| 8 | 数据采集实现 | **采用现成框架**(Scrapy 等),**不自研** | §3.8:P6 暂缓;接入时遵循单写者原则 |
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
@@ -49,8 +50,9 @@
|
|
|
上传: storage/uploads (私有) │
|
|
上传: storage/uploads (私有) │
|
|
|
│
|
|
│
|
|
|
┌────────────┴────────────┐
|
|
┌────────────┴────────────┐
|
|
|
- │ Python 爬虫管道 (crawlers/) │
|
|
|
|
|
- │ 调度 → 采集 → 清洗/去重 → 入库 │
|
|
|
|
|
|
|
+ │ Python 数据采集 (crawlers/) │
|
|
|
|
|
+ │ 现成框架(Scrapy 等,不自研) │
|
|
|
|
|
+ │ 采集 → 清洗/去重 → 入库 │
|
|
|
└─────────────────────────┘
|
|
└─────────────────────────┘
|
|
|
```
|
|
```
|
|
|
|
|
|
|
@@ -77,7 +79,7 @@
|
|
|
| DB | PDO + prepared statement | 防注入、跨 MySQL/MariaDB 一致 |
|
|
| DB | PDO + prepared statement | 防注入、跨 MySQL/MariaDB 一致 |
|
|
|
| 会话 | 原生 Session 封装(可选 DB 存储) | 后期扩展权限体系 |
|
|
| 会话 | 原生 Session 封装(可选 DB 存储) | 后期扩展权限体系 |
|
|
|
| 复杂后端 | Go 独立二进制(按需) | 编译型、并发强、部署简单 |
|
|
| 复杂后端 | Go 独立二进制(按需) | 编译型、并发强、部署简单 |
|
|
|
-| 数据采集 | **Python 3.10+**(requests + BeautifulSoup/lxml 等轻量库) | 生态适合爬虫;不引重框架(无 Scrapy 起步) |
|
|
|
|
|
|
|
+| 数据采集 | **Python + 现成框架**(Scrapy 等,不自研) | 成熟框架自带调度/去重/并发/robots 支持;P6 暂缓,有明确目标时引入 |
|
|
|
| 前端 | 原生 HTML/CSS + 少量 JS;无前端框架 | 管理系统以表单/表格为主 |
|
|
| 前端 | 原生 HTML/CSS + 少量 JS;无前端框架 | 管理系统以表单/表格为主 |
|
|
|
| 生产反代 | Caddy | 自动 HTTPS、配置简单 |
|
|
| 生产反代 | Caddy | 自动 HTTPS、配置简单 |
|
|
|
| 开发 Web | WAMP Apache | 本机开发一致预览 |
|
|
| 开发 Web | WAMP Apache | 本机开发一致预览 |
|
|
@@ -121,10 +123,8 @@ glacier/
|
|
|
│ ├── uploads/ # 上传文件(本地磁盘,经控制器鉴权下发)
|
|
│ ├── uploads/ # 上传文件(本地磁盘,经控制器鉴权下发)
|
|
|
│ ├── cache/ # 模板/路由缓存
|
|
│ ├── cache/ # 模板/路由缓存
|
|
|
│ └── logs/ # 应用日志
|
|
│ └── logs/ # 应用日志
|
|
|
-├── crawlers/ # ★ Python 数据采集管道(见 §3.8)
|
|
|
|
|
-│ ├── requirements.txt # 依赖清单(轻量)
|
|
|
|
|
-│ ├── common/ # 公共:DB 连接、去重、日志、调度
|
|
|
|
|
-│ └── tasks/ # 各采集任务(按数据源划分)
|
|
|
|
|
|
|
+├── crawlers/ # ★ 数据采集(见 §3.8,采用现成框架如 Scrapy;P6 暂缓)
|
|
|
|
|
+│ └── (待引入框架项目结构:scrapy.cfg / pyproject.toml 等)
|
|
|
├── go/ # Go 复杂后端服务(独立 module,按需)
|
|
├── go/ # Go 复杂后端服务(独立 module,按需)
|
|
|
│ └── services/
|
|
│ └── services/
|
|
|
├── database/ # SQL 迁移脚本(版本化,单库多表)
|
|
├── database/ # SQL 迁移脚本(版本化,单库多表)
|
|
@@ -212,35 +212,19 @@ glacier/
|
|
|
- 适用场景(出现才引入):定时任务、队列/异步、报表聚合、外部 API 网关、并发同步、性能敏感接口。
|
|
- 适用场景(出现才引入):定时任务、队列/异步、报表聚合、外部 API 网关、并发同步、性能敏感接口。
|
|
|
- 形态:独立二进制 + systemd,监听内部端口/unix socket;PHP 经 cURL 调用(JSON、错误码、超时重试统一)。
|
|
- 形态:独立二进制 + systemd,监听内部端口/unix socket;PHP 经 cURL 调用(JSON、错误码、超时重试统一)。
|
|
|
|
|
|
|
|
-### 3.8 Python 爬虫数据管道(新增,数据来源)
|
|
|
|
|
|
|
+### 3.8 数据采集(Python 爬虫 — 采用现成框架,不自研)
|
|
|
|
|
|
|
|
**定位**:外部数据来源(如行业新闻、政策、竞品信息等)→ 采集 → 清洗/去重 → 入库 → 系统各模块展示。**爬虫只写数据库与私有存储,不提供 Web 页面、不碰会话**。
|
|
**定位**:外部数据来源(如行业新闻、政策、竞品信息等)→ 采集 → 清洗/去重 → 入库 → 系统各模块展示。**爬虫只写数据库与私有存储,不提供 Web 页面、不碰会话**。
|
|
|
|
|
|
|
|
-**管道结构**:
|
|
|
|
|
|
|
+**实现方式(v0.4 决策)**:**采用现成爬虫框架(如 Scrapy 等),不自研采集管道**。自研收益低、维护成本高;成熟框架自带调度、去重、并发、中间件与 robots 支持。
|
|
|
|
|
|
|
|
-```
|
|
|
|
|
-调度 (cron / systemd timer / 手动)
|
|
|
|
|
- │
|
|
|
|
|
- ▼
|
|
|
|
|
-采集任务 (crawlers/tasks/<source>.py, requests + 解析)
|
|
|
|
|
- │ · 遵守 robots.txt / 限速 / 超时 / 重试
|
|
|
|
|
- ▼
|
|
|
|
|
-清洗与去重 (crawlers/common)
|
|
|
|
|
- │ · 字段规范化 · 内容哈希去重 · 编码统一 utf8
|
|
|
|
|
- ▼
|
|
|
|
|
-入库 (写入 glacier 库 crawl_* 表, PDO/MySQL 驱动)
|
|
|
|
|
- │ · 只写库 + 私有存储 · 失败可重跑(幂等)
|
|
|
|
|
- ▼
|
|
|
|
|
-系统展示 (PHP 模块读 crawl_* 表渲染, 或经二次加工)
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-**设计约定**:
|
|
|
|
|
-- 目录:`crawlers/`(独立于 PHP 树);依赖 `requirements.txt`(轻量:requests、beautifulsoup4、lxml 起步,**不引 Scrapy 等重框架**,复杂再评估);
|
|
|
|
|
-- 运行环境:开发 Windows(venv + Python 3.10+)/ 生产 Debian(python3-venv + systemd timer 或 cron);
|
|
|
|
|
-- **单写者原则**:写库统一走 `crawlers/common/db.py`,表结构以 `database/` 迁移为准(schema 唯一来源);
|
|
|
|
|
-- 采集表归属 `crawl_` 前缀;字段含 `source_url`(唯一约束去重)、`content_hash`、`fetched_at`、`status`(new/processed/ignored);
|
|
|
|
|
-- **安全**:抓取内容入库前净化(防存储型 XSS,展示层 Twig 转义兜底);凭据(若需登录抓取)不入库不入仓库,.gitignore 排除;遵守目标站点 robots 与频率限制,避免法律与封禁风险;
|
|
|
|
|
-- **触发方式**:初期手动 + cron 定时;需要动态调度/复杂编排时再考虑 Go 服务或系统自带调度表。
|
|
|
|
|
|
|
+**框架接入约定**:
|
|
|
|
|
+- 框架项目位于 `crawlers/`(独立子项目,含 scrapy.cfg / pyproject.toml 等自身结构);
|
|
|
|
|
+- **单写者原则不变**:写库统一经采集项目的数据管道;表结构仍以 `database/` 迁移为唯一来源;
|
|
|
|
|
+- 采集表约定保留:`crawl_` 前缀(如 `crawl_sources` / `crawl_items`),字段含 `source_url`(唯一约束去重)、`content_hash`、`fetched_at`、`status`;
|
|
|
|
|
+- 运行环境:开发 Windows(venv)/ 生产 Debian(systemd timer 或 cron 触发框架命令);
|
|
|
|
|
+- **安全不变**:内容入库前净化(防存储型 XSS,展示层 Twig 转义兜底);凭据不入库不入仓库;遵守目标站点 robots 与频率限制;
|
|
|
|
|
+- **本阶段(P6)暂缓**:待有明确采集目标时再引入框架实施,不影响 PHP 侧开发。
|
|
|
|
|
|
|
|
### 3.9 上传与私有文件(本地磁盘,规避直接访问)
|
|
### 3.9 上传与私有文件(本地磁盘,规避直接访问)
|
|
|
|
|
|
|
@@ -308,12 +292,12 @@ glacier/
|
|
|
| **P3 数据层** | Database 封装 + 迁移机制 + 配置分层(dev/prod,UTC+8) | 迁移可在开发库执行;配置切换生效 |
|
|
| **P3 数据层** | Database 封装 + 迁移机制 + 配置分层(dev/prod,UTC+8) | 迁移可在开发库执行;配置切换生效 |
|
|
|
| **P4 模块机制** | modules/ 约定 + 模块路由挂载 + 模块声明 | 示例模块经 `/<name>` 可访问 |
|
|
| **P4 模块机制** | modules/ 约定 + 模块路由挂载 + 模块声明 | 示例模块经 `/<name>` 可访问 |
|
|
|
| **P5 会话与中间件** | Session 封装 + CSRF + auth/permission 空实现 | 中间件可挂载 |
|
|
| **P5 会话与中间件** | Session 封装 + CSRF + auth/permission 空实现 | 中间件可挂载 |
|
|
|
-| **P6 爬虫管道** | crawlers/ 骨架 + common(DB/去重/日志)+ 采集任务框架 + 入库表迁移(**采集目标待定,留空**) | 采集数据入库;重复抓取幂等 |
|
|
|
|
|
|
|
+| **P6 数据采集**(**暂缓**) | **采用现成框架**(Scrapy 等,不自研);待有明确采集目标时引入 | 有目标后:框架采集 → 清洗入库 crawl_* 表(迁移先行) |
|
|
|
| **P7 首个真实功能** | 选一个业务模块(如公司新闻,可消费采集数据)全链路 | 数据展示、模板渲染、权限挂载 |
|
|
| **P7 首个真实功能** | 选一个业务模块(如公司新闻,可消费采集数据)全链路 | 数据展示、模板渲染、权限挂载 |
|
|
|
| **P8 部署** | Caddyfile + systemd(PHP-FPM/Go/Python 任务)+ 部署脚本;生产试部署 | 生产 https 访问;rewrite 一致 |
|
|
| **P8 部署** | Caddyfile + systemd(PHP-FPM/Go/Python 任务)+ 部署脚本;生产试部署 | 生产 https 访问;rewrite 一致 |
|
|
|
| **P9 Go 集成(按需)** | 出现复杂需求再引入 Go | 内部接口连通 |
|
|
| **P9 Go 集成(按需)** | 出现复杂需求再引入 Go | 内部接口连通 |
|
|
|
|
|
|
|
|
-> 建议 P0→P8 顺序执行,P9 按需触发;每阶段一次 git 提交。
|
|
|
|
|
|
|
+> 建议 P0→P8 顺序执行,P9 按需触发;每阶段一次 git 提交。P6(数据采集)暂缓,不阻塞后续阶段。
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
@@ -326,7 +310,8 @@ glacier/
|
|
|
- ✅ 数据库:单库多表(`g_` / `<module>_` / `crawl_` 前缀)
|
|
- ✅ 数据库:单库多表(`g_` / `<module>_` / `crawl_` 前缀)
|
|
|
- ✅ 上传:本地磁盘 + 私有存储 + 控制器鉴权下发
|
|
- ✅ 上传:本地磁盘 + 私有存储 + 控制器鉴权下发
|
|
|
- ✅ 语言/时区:中文 + UTC+8(三层统一)
|
|
- ✅ 语言/时区:中文 + UTC+8(三层统一)
|
|
|
-- ✅ 数据来源:Python 爬虫管道(轻量库起步)
|
|
|
|
|
|
|
+- ✅ 数据来源:Python 爬虫(可能的数据来源)
|
|
|
|
|
+- ✅ 数据采集实现:**采用现成框架**(Scrapy 等),不自研;P6 暂缓,有明确目标时引入
|
|
|
|
|
|
|
|
### 待确认事项处理(v0.3 更新)
|
|
### 待确认事项处理(v0.3 更新)
|
|
|
1. **采集目标**:**留空(待定)** — 第一个爬虫的数据源与频率在 P6 实施前再定,不影响前期阶段。
|
|
1. **采集目标**:**留空(待定)** — 第一个爬虫的数据源与频率在 P6 实施前再定,不影响前期阶段。
|
|
@@ -345,6 +330,6 @@ glacier/
|
|
|
- **模块 = 子空间**:`/<name>` 即一个模块,收拢在 `app/modules/<name>/`。
|
|
- **模块 = 子空间**:`/<name>` 即一个模块,收拢在 `app/modules/<name>/`。
|
|
|
- **模板只做展示**:Twig 渲染,默认转义。
|
|
- **模板只做展示**:Twig 渲染,默认转义。
|
|
|
- **单库多表**:`glacier` 库 + 统一前缀(系统 `g_` / 模块 `<module>_` / 采集 `crawl_`)。
|
|
- **单库多表**:`glacier` 库 + 统一前缀(系统 `g_` / 模块 `<module>_` / 采集 `crawl_`)。
|
|
|
-- **Python 爬虫只写数据**:采集 → 清洗 → 入库,不提供页面。
|
|
|
|
|
|
|
+- **数据采集用现成框架**(Scrapy 等,不自研);爬虫只写数据不提供页面;P6 暂缓。
|
|
|
- **Go 按需引入**:不提前造复杂后端。
|
|
- **Go 按需引入**:不提前造复杂后端。
|
|
|
- **Session/权限后期做**:本期只留中间件接口。
|
|
- **Session/权限后期做**:本期只留中间件接口。
|