workbuddy.xpcool.com/招聘考试功能总计划书.md

292 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 招聘考试信息聚合系统 · 总计划书(设计稿 v0.1
> 状态:**设计/规划阶段,暂不开发**。本文档用于锁定范围、对齐架构、暴露风险,并列出需你拍板的关键决策。
> 落点:作为 **service.xpcool.comGo 后端模块)** + **admin.xpcool.comVue 管理/可视化前端模块)** 的一个功能模块。
> 默认地区:**贵阳市**;架构需天然支持全省 9 个市州 + 省直,便于后续扩展。
---
## 0. 文档约定
- 术语:**发布主体**(谁发的,可能是机关/事业单位/国企/央企/私企)、**考试分类**(公务员/事业单位/国企/央企/私企/其他)、**公告**(一条招聘考试信息)。两者解耦,才能支撑你想要的"按企业 + 按分类"双重筛选。
- 时间基线2026-08-27。历史全量定义为"近 2 年"2024-08 起)。
- 所有域名/接口形态均来自 2026-08 真实联网核查,标注【已核验】;其余为规划假设,需 POC 验证。
---
## 1. 业务目标与成功标准
**你要做的事(复述对齐):**
1. 爬取贵州各地区**官方渠道**发布的招聘考试信息。
2. 默认聚焦贵阳,支持多分类筛选:公务员、事业单位、国企、央企、私企等。
3. 先做一次**近两年全量历史**回溯,再**每天增量**抓取最新。
4. 每天早上诉**Bark** 推送给你。
5. 在 admin 里做**可视化展示 + 数据分析**。
**成功标准(建议,可调整):**
- 贵阳 + 公务员/事业单位/国企/央企 四类,官方源覆盖率 ≥ 90%,公告从发布到入库延迟 < 24h
- 每日早上推送稳定到达失败有兜底告警)。
- 去重准确率 99%同一公告多站转发不重复计)。
- admin 可对任意"地区 × 分类 × 时间"组合做筛选与趋势分析
---
## 2. 数据源调研(贵州真实官方渠道)【已核验 2026-08】
### 2.1 省级统一门户
| 名称 | 域名 | 形态 | 覆盖分类 | 备注 |
|---|---|---|---|---|
| 贵州人事考试信息网 | `gzrsks.com.cn`已核验 | **SPAhash 路由)** | 公务员招录事业单位招聘资格考试、"三支一扶" | 全省最核心门户**是前端渲染需找底层 JSON 接口或用 headless 渲染** |
| 贵州省公务员局 | `gzzzb.gov.cn`已核验 | 静态列表页 | 公务员///乡四级联考遴选 | 公告 + 职位表链接常回链到 gzrsks 专题页 |
| 贵州人力资源社会保障网 | `rst.guizhou.gov.cn` | 静态 | 省直事业单位人才引进 | 省本级发布渠道 |
### 2.2 贵阳市(默认地区,已核验可抓)
| 名称 | 域名 | 栏目/路径 | 覆盖 |
|---|---|---|---|
| 贵阳市人力资源和社会保障局 | `rsj.guiyang.gov.cn`已核验 | `rszk` 人事招考 | 事业单位教师卫健、"三支一扶"、局属单位 |
| 贵阳市人民政府 | `guiyang.gov.cn`已核验 | 人事招考 / 招聘信息 | 转发市直单位招聘公告 |
### 2.3 其他地区9 市州 + 省直,需 POC 验证)
架构预留首批不做后续按"市州人社局官网 + 市政府门户人事招考栏目"模式复制
**遵义、六盘水、安顺、毕节、铜仁、黔东南州、黔南州、黔西南州** + **省直**已在 2.1 覆盖)。
> 注意:部分市州门户为静态、部分也是 SPA难度不一需逐个 POC。
### 2.4 国企 / 央企【已核验】
| 渠道 | 域名 / 地址 | 备注 |
|---|---|---|
| 贵州省国资委国资央企招聘平台 | `cujiuye.iguopin.com`已核验 | 243 家国企夏季招聘茅台旅投磷化乌江能源盐业路桥…),规模大 |
| 中国贵州茅台集团 | `moutaichina.com` / `moutai.com.cn`已核验 | 高层次人才/应届引才附件多xlsx/docx |
| 贵州电网 | 南网招聘系统 `zhaopin.csg.cn`已核验 | 公告常经 gov /聚合站转发源头在系统内需登录 |
| 其他省属/在黔央企 | 各集团官网"人才招聘"栏目 | 名单见国资委平台逐一登记 |
### 2.5 私企 / 其他 —— **明显的覆盖缺口,需你决策**
- 纯私企几乎**不在政府官网**"招聘考试"。其信息散落在:① 企业自己官网"招聘/校园招聘"栏目;② 招聘聚合站智联BOSS猎聘高校人才网等);③ 微信公众号
- 建议分期首批**只做官方/半官方源**公务员/事业/国企/央企"私企"作为**二期**来源改为"知名民营企业官网招聘页 + 1~2 个可信聚合站"并明确标注来源为非官方
- 风险聚合站有版权与反爬限制且信息噪声大需更强的清洗与去重
### 2.6 数据源分级(决定技术难度)
- **A 静态列表页**goquery 直接解析 rsj.guiyang.gov.cn)。最易
- **B SPA / JS 渲染**需定位底层 API headless 渲染 gzrsks.com.cn)。**最难是工期主要风险点。**
- **C 需登录/验证码**如南网招聘系统部分企业内网首批排除人工或后续对接
- **D 附件型**公告正文在 PDF/Word如茅台 xlsx 岗位表)。需附件解析抽取关键字段
---
## 3. 整体技术架构
### 3.1 部署拓扑(复用现有底座)
- 复用腾讯云 `193.112.118.168`CentOS StreamSSH 22025账号 xxcool)。
- 复用 Docker + `xpcool-net` 网络 + 宿主机 Nginx
- **后端模块**挂进现有 `service.xpcool.com:new` 容器已有 `127.0.0.1:10100:10100`env `GF_GCFG_ENV=prod` + `DB_DSN`(须带 `mysql:` 前缀) + `JWT_SECRET`且容器内必须有 `manifest/config/config.yaml`)。
- **前端模块**挂进 `admin.xpcool.com`Nginx 落点 `/data/www/admin.xpcool.com/`
- **Bark**建议与现有服务同机或独立容器部署 §6)。
### 3.2 模块划分
```
[数据源网站]
│ (HTTP / API / headless)
[Crawler 爬虫引擎] ── 调度器(cron, 每日凌晨) ──┐
│ 去重/字段抽取/附件解析 │
▼ │
[MySQL 存储] ◀── 读写 ── [service 后端 API 模块 /recruitment/*]
│ │
│ [admin 前端模块]
│ │
[Bark 推送器] ◀── 每日早报任务 ────────────────┘
```
### 3.3 技术选型(对齐现有底座)
- 后端**Go + com.lib.gf.v2 + com.lib.v2** service 同源复用 ORM/配置/日志/JWT)。新增 `recruitment` 模块包
- 前端**Vue + TDesign**admin 现有约定写组件前先走 TDesign MCP 查官方文档)。
- 存储**MySQL**复用 service 或独立 `recruitment` ——见决策点)。
- 调度Go 内置 cron gocron常驻于 service 进程或系统 crontab 调内部 API二选一)。
- 动态渲染**Playwright**Python/Node sidecar CLI B SPA 按需调用避免全量上浏览器
---
## 4. 数据模型设计(草案)
> 发布主体与考试分类解耦,支撑"按企业 + 按分类"双重筛选。
**recruitment_info公告主表**
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint PK | |
| title | varchar | 标题 |
| source_id | bigint FK | 数据源(crawl_source) |
| org_id | bigint FK | 发布主体(organization) |
| category | tinyint | 考试分类(1公务员/2事业单位/3国企/4央企/5私企/6其他) |
| region | varchar | 地区(贵阳/省直/遵义…)支持多级 |
| publish_date | date | 发布日期 |
| deadline | date NULL | 报名/截止日期(抽取) |
| exam_date | date NULL | 笔试日期(抽取) |
| url | varchar | 原文链接(唯一性依据之一) |
| content | longtext | 正文/摘要 |
| attachments | json NULL | 附件链接与解析结果 |
| status | tinyint | 0有效/1已更正/2已失效/3已删除 |
| fingerprint | varchar | 去重指纹 |
| created_at / updated_at | datetime | |
**organization发布主体**id, name, type(机关/事业/国企/央企/私企/其他), official_site, region
**crawl_source数据源配置**id, name, base_url, type(A/B/C/D), list_selector/api_path, cron_expr, enabled, last_success_at, fail_count
**crawl_log抓取日志**id, source_id, run_at, fetched, new, updated, error
**push_subscription推送订阅**id, device_key(Bark), regions(json), categories(json), only_new(bool), push_time
**push_log推送记录**id, subscription_id, push_at, title, body, result
索引url(唯一)、fingerprint(唯一)、(region, category, publish_date) 复合索引支撑筛选与趋势
---
## 5. 爬虫设计
### 5.1 抓取策略
- **全量历史首跑**对每个 A/B/C 类源按列表分页从当前回溯到 2024-08D 类附件一并下载解析
- **增量每日**每日凌晨对全部 enabled 源巡检列表前 N 覆盖当天新发入库新公告 / 更新已存在公告的 status官网更正/取消时标记而非硬删)。
### 5.2 解析方式(按源分级)
- A goquery CSS 选择器解析列表 + 详情
- B SPA先抓 XHR/JSON浏览器 DevTools 看接口拿不到再走 Playwright 渲染后抽取
- D 下载 PDF/Word 文本抽取 正则提"报名/笔试/截止"日期与岗位数
### 5.3 去重与更新
- 指纹 = `hash(source_id + normalize(title) + publish_date + url)`;同公告多站转发视为多条**不同来源记录**但关联同一 `group_key` `hash(title+publish_date)`前端可按 group 聚合展示"多家来源"。
- 更新检测再次抓取时比对 content 哈希变化则更新 + crawl_log
### 5.4 反爬与稳定性
- 统一限速每源间隔 2~5s)、随机 UA超时重试指数退避)、失败计数
- 连续失败 阈值标记源异常 + **Bark/邮件告警**避免静默失效)。
- 代理池可选IP 被封时启用)。
### 5.5 字段抽取难点
- 截止/笔试日期招聘人数学历要求正文正则 + 模板兜底首批对样本做人工校验调置信度
- 地区推断优先取源所属地区正文含"贵阳/遵义…"可校正
### 5.6 调度
- 每日 02:0005:00 增量巡检错峰规避官网高峰)。
- 首跑全量可手动触发 + 分批按源按月份防止单次过长
---
## 6. Bark 每日推送设计
### 6.1 自建 vs 公共(决策点)
- **公共 `api.day.app`**零部署POST `https://api.day.app/push` `{device_key,title,body,group,url}` 即可代价通知文本经第三方。**推荐先走公共版跑通再决定是否自建。**
- **自建 `finab/bark-server`Docker**隐私可控**必须配置 APNs 证书p8+KeyID+TeamID才能真正推到 iPhone**且需域名+HTTPS运维成本更高
- 你的腾讯云同机部署可行另开端口或子域名 + Caddy 自动证书)。
### 6.2 每日早报模板(建议)
```
【贵州招聘早报 · 2026-08-27 · 贵阳】
昨日新增:公务员 0 · 事业单位 3 · 国企 1 · 央企 0 · 私企 0
🔥 重点关注:
· 贵阳贵安2026事业单位面试公告截止 08-30
· 贵州电网春招补录(截止 09-05
👉 点击查看详情https://admin.xpcool.com/recruitment
```
- `group=recruit_daily` 分组`level=active``url` 深链到 admin 对应筛选页
### 6.3 订阅过滤
- `push_subscription`可配置"仅贵阳""仅公务员+事业单位""仅推送新公告"。
- 多设备/多人可扩展家人/同事各一 key)。
### 6.4 时机与兜底
- 默认 **每天早上 08:00** 推送可配置)。
- 推送失败记录 push_log + 重试 1 + 仍失败则 Bark 告警自身用另一个 key/渠道)。
---
## 7. 可视化与数据分析admin 模块)
- **仪表盘**总公告数 30 天新增按分类占比环图按地区柱状今日/昨日新增卡片
- **列表 + 筛选**地区多级)、分类多选)、发布时间范围关键词标题/正文/单位全文检索)、状态有效/已失效表格 + 详情抽屉原文链接附件多来源聚合)。
- **趋势分析**按月/按地区/按分类的时间序列折线支持导出 Excel/CSV
- **爬虫运维面板**各源最后成功时间失败次数今日抓取量手动触发按钮日志查看
- **权限**复用 admin 现有 JWT + `admin_menu`(type=2) 路由注册path 须与实际前端路由匹配历史踩坑点)。
---
## 8. 你没想到 / 容易踩的坑(重点补充)
**法律与合规**
1. **robots.txt 与版权**政府官网通常允许转载但需注明来源逐站评估使用条款正文展示标注"来源XXX"并链回原文
2. **个人隐私边界**只聚合"公告本身"**绝不抓取报名系统表单/考生个人信息**。
3. **数据使用边界**仅作个人/内部信息聚合展示不篡改不商业化转售
**反爬与可用性(最大的技术风险)**
4. **SPA 抓不到正文**gzrsks.com.cn hash 路由 SPA HTTP 拿不到内容——必须先做接口逆向或上 Playwright**这是首跑 POC 的第一关**。
5. **IP 被封 / 频率限制**需限速随机 UA代理池退避重试
6. **网站改版**模板一变解析器即失效"解析失败即告警"而非静默
7. **登录/验证码源**南网招聘系统等首批排除避免卡住整体进度
**数据质量**
8. **去重准确性**同公告多站转发 重复 group_key 聚合 fingerprint 防真重复
9. **公告变更/撤回**官网更正或取消招聘应标记 `status`已更正/已失效**不要硬删**否则趋势断裂
10. **日期/人数抽取易错**正文格式多样首批必须人工抽检样本校准正则
11. **附件解析**PDF/Word 岗位表里的关键信息特别是茅台类需单独抽取管线
**覆盖与完整性**
12. **历史全量能否拿到**部分官网旧公告会被归档或删除近两年回溯可能不完整POC 阶段就要验证"能回溯到多久"。
13. **增量漏抓补偿**某天爬虫失败次日需补抓而非只抓"今天"设计成"按发布日期窗口回扫"。
14. **新源发现机制**新出现的发布渠道如何纳入——"候选源登记 + 人工审核"流程而非自动信任
15. **私企覆盖缺口**无官方源需明确二期方案与来源可信度标注 §2.5)。
**运维与告警**
16. **爬虫失败必须告警**某源连续失败 N Bark/邮件通知否则你以为在跑其实已挂
17. **推送本身要可观测**push_log + 失败重试 + 独立告警通道
**产品与体验**
18. **搜索是刚需**标题/正文/单位全文检索否则数据多了找不到
19. **收藏/关注**可标记"关注的单位/分类"推送可只推关注的
20. **数据导出**Excel/CSV 供你自己分析
21. **移动端查看**admin 是否要移动适配你主要手机看推送但详情可能在 admin)。
**集成与部署**
22. **与现有 service/admin 权限体系对接**复用 JWT、`admin_menu` 路由type=2 path 匹配历史坑)、`xpcool-net` 网络envDB_DSN `mysql:` 前缀JWT_SECRET)。
23. **爬虫常驻 vs 独立容器**放进 service 进程省运维面 SPA 渲染要 Playwright sidecar——资源与隔离如何权衡见决策点)。
24. **配置外置**爬虫源Bark key推送时间地区默认走配置/环境变量不写死代码
**技术决策点(待你拍板)**
25. 爬虫语言/形态** Go 适配器** vs **Python 爬虫微服务**写同一库Go 同源易部署但 SPA/Playwright 生态弱Python 爬虫生态成熟但多一个服务
26. 存储**复用 service ** vs **独立 recruitment 库**独立库隔离风险便于单独备份与扩容
---
## 9. 分阶段实施计划(开发期,本节为后续开发用)
- **阶段 0 · 数据源 POC 1 **对贵阳 4 + gzrsks SPA 做可行性验证拿到真实接口/选择器确认近两年可回溯性。**POC 不过则方案需调整。**
- **阶段 1 · 数据模型 + 贵阳 MVP公务员/事业单位**建表Go 爬虫适配器A 类优先)、基础列表 APIadmin 列表页
- **阶段 2 · 全量历史回溯**跑近两年全量去重与字段校准人工抽检
- **阶段 3 · 增量 + Bark 每日推送**调度器 + 推送器 + 订阅过滤 + 失败告警
- **阶段 4 · admin 可视化与分析**仪表盘趋势图筛选增强爬虫运维面板权限接入
- **阶段 5 · 扩展**国企/央企源私企二期全省 9 市州搜索/收藏/导出
每阶段结束有"冒烟验证 + 数据抽检报告"再进下一阶段契合你一贯的"非侵入最小改动迭代"偏好)。
---
## 10. 需你拍板的关键问题Decision Points
1. **私企范围**首批只做官方/半官方公务员/事业/国企/央企私企放二期——可以吗
2. **Bark**先公共 `api.day.app` 跑通还是直接自建需你提供 APNs 证书或授权我部署
3. **爬虫形态** Go 适配器推荐运维面小还是 Python 微服务SPA 处理强
4. **存储**复用 service 还是 独立 recruitment
5. **默认推送时间**每天早上几点建议 08:00
6. **是否要移动端适配 admin**还是推送里给深链电脑看详情即可
7. **推送粒度**每日汇总早报还是"有新公告实时推"建议每日汇总避免打扰
---
## 11. 附录:接口草图(仅供讨论)
```
GET /api/service/admin/recruitment/list?region=贵阳&category=2&from=2026-08-01&q=教师
GET /api/service/admin/recruitment/stats?range=30d
GET /api/service/admin/recruitment/sources # 爬虫源状态
POST /api/service/admin/recruitment/crawl/trigger # 手动触发
POST /api/service/admin/recruitment/push/test # 测试 Bark
```
---
*本文档为设计稿,待你确认决策点后进入阶段 0 POC。*