招聘判官 (Hire Fortune)
先看天命,再开工。打工人的招聘玄学搭子。
招聘判官是一个面向招聘 HR 的趣味玄学断案工具。选场景、点断案、看天命——经历 3 秒仪式动画后获得一份判词结果(天命指数、五维命盘、判官断语、建议、甩锅话术)。结果可分享、可复现。
功能特色
三大入口
| 入口 | 路由 | 说明 |
|---|---|---|
| 一键断案 | /judge |
选择招聘场景 → 3 秒召唤仪式 → 天命指数 + 五维命盘 + 判词 + 甩锅话术 |
| 今日天命 | /today |
每日招聘运势:星级 + 关键词 + 宜忌 + 贵人/业障 + 四维能量条 |
| 招聘测字 | /divine |
写一个字 → 拆字判语 + 四维星级 + 判官解字 + 宜忌 |
一键断案流程
- 选场景:6 个招聘场景(候选人/业务/Offer/面试官/HC/随机)
- 召唤仪式:Three.js 3D 罗盘旋转 + 粒子收敛 + GSAP 相机关键帧 + Bloom 后处理
- 天命已定:指针锁定随机方向,结果揭晓
- 结果卡:天命指数计数动画 + D3 雷达图 + 判词卷轴 + 甩锅话术 + 分享/反馈
天命等级
| 分数区间 | 等级 | 标签 |
|---|---|---|
| 90–100 | GREAT | 上上签 |
| 75–89 | GOOD | 上签 |
| 55–74 | NEUTRAL | 中签 |
| 35–54 | BAD | 下签 |
| 0–34 | WORST | 下下签 |
连续开工称号
| 连续天数 | 称号 |
|---|---|
| 1 | 刚入法门 |
| 3 | 初窥天机 |
| 7 | 招聘通灵E师 |
| 14 | 判官记名弟子 |
| 30 | 天命猎手 |
| 60 | 业障克星 |
| 100 | 招聘飞升者 |
其他特色
- 结果可复现:相同 seed + scene 产出完全相同结果,分享链接可扫码复现
- 分享卡:Canvas 2D 生成 1080×1920 品牌字体分享图 + QR 码 + 稀缺感文案
- 3D 罗盘:三环差速旋转(八卦/天干/地支)+ 阻尼指针 + RoomEnvironment 环境贴图
- 粒子能量场:三色三层(白热核心 + 金光中层 + 暗金余烬)
- 彩蛋:特定条件下触发特殊判语
- 降级策略:WebGL 不可用 → CSS 罗盘;数据加载失败 → 硬编码兜底;判词池空 → 相邻等级降级
- 可访问性:
prefers-reduced-motion支持、键盘 focus-visible、WCAG AA 对比度
技术栈
| 层 | 技术 |
|---|---|
| 前端 | 原生 HTML + CSS + vanilla JS(ES Modules) |
| 3D | Three.js 0.160.0(importmap CDN) |
| 图表 | D3.js(雷达图) |
| 动画 | GSAP 3.12.5(相机关键帧 + 时间线) |
| 后端 | Python 3.10+ / FastAPI / Uvicorn |
| 校验 | Pydantic v2 |
| CLI | Typer + Rich |
| 构建 | hatchling |
| 测试 | pytest + pytest-asyncio + httpx |
安装
从 PyPI 安装
pip install recruitment-judge
从源码安装
git clone https://github.com/recruitment-judge/recruitment-judge.git
cd recruitment-judge
pip install -e .
使用
启动 Web 服务
recruitment-judge web
启动后访问 http://localhost:8000
CLI 选项
recruitment-judge web --host 0.0.0.0 --port 8000 --reload
| 选项 | 说明 | 默认值 |
|---|---|---|
--host / -h |
监听地址 | 0.0.0.0 |
--port / -p |
监听端口 | 8000 |
--reload |
热重载(开发模式) | 关闭 |
环境变量
| 变量 | 说明 | 默认值 |
|---|---|---|
SERVER_HOST |
监听地址 | 0.0.0.0 |
SERVER_PORT |
监听端口 | 8000 |
MAX_EVENT_PAYLOAD_SIZE |
埋点 payload 最大字节 | 10240 |
开发模式
pip install -e ".[dev]"
pytest tests/ -v
API 端点
GET /api/v1/health
健康检查,返回服务状态、版本、运行时间。
{
"code": 0,
"message": "ok",
"data": { "status": "healthy", "version": "1.1.0", "uptime": 42 }
}
POST /api/v1/events
埋点收集,Rich 控制台打印 JSON 日志。
{
"event": "page_view",
"payload": { "path": "/" },
"timestamp": 1700000000000,
"client_id": "abc123"
}
支持的 event 类型:
page_view · scenario_select · fortune_start · fortune_complete · fortune_result · fortune_retry · fortune_share · fortune_feedback_positive · fortune_feedback_negative · special_judgement_trigger
统一响应格式
{ "code": 0, "message": "ok", "data": {} }
| code | 含义 |
|---|---|
| 0 | 成功 |
| 1001 | 请求格式错误 |
| 1002 | 校验错误 |
| 5000 | 内部错误 |
前端路由
| 路径 | 页面 | 说明 |
|---|---|---|
/ |
首页 | Logo + 标题 + 三入口卡片 |
/judge |
一键断案 | 场景选择器 + 断案按钮 |
/today |
今日天命 | 每日招聘运势完整卡 |
/divine |
招聘测字 | 单字输入 + 拆字结果 |
/result?scene=&seed= |
结果复现 | 通过 URL 参数复现断案结果 |
/share?char=&date=&seed= |
分享卡 | 测字结果分享页 |
招聘场景
| ID | 图标 | 名称 | 副标题 |
|---|---|---|---|
candidate |
👤 | 候选人 | 这人简历能信吗? |
business |
📊 | 业务 | 业务方到底要啥? |
offer |
📜 | Offer | 发了Offer会接吗? |
interviewer |
🎯 | 面试官 | 反馈靠谱不靠谱? |
hc |
💰 | HC | 编制能批下来吗? |
random |
🎲 | 随便算算 | 今天适合招人吗? |
目录结构
recruitment_judge/
├── pyproject.toml # 构建配置 + 依赖 + 入口点
├── scripts/publish.ps1 # PyPI 一键发布脚本
├── docs/ # 设计文档与评审报告
│ ├── visual_design_spec.md # 视觉设计规格(16 Task)
│ ├── judge_page_spec.md # 断案独立页面设计
│ ├── terms_review.md # 品牌文案评审
│ └── ...
├── src/recruitment_judge/
│ ├── __init__.py # 版本号
│ ├── __main__.py # python -m 入口
│ ├── cli.py # Typer CLI
│ ├── app.py # FastAPI 应用
│ ├── api/v1/
│ │ ├── health.py # GET /api/v1/health
│ │ └── events.py # POST /api/v1/events
│ ├── core/
│ │ ├── config.py # 环境变量配置
│ │ └── response.py # 统一响应模型
│ ├── models/
│ │ └── event.py # 埋点 Pydantic 模型
│ └── static/ # 前端静态文件
│ ├── index.html # SPA 主入口
│ ├── css/
│ │ ├── main.css # 设计令牌 + 基础组件
│ │ ├── home.css # 首页 + 场景卡
│ │ ├── judge.css # 断案页
│ │ ├── result.css # 结果卡
│ │ ├── daily_fortune.css # 今日天命
│ │ ├── character_divination.css # 测字
│ │ ├── share_card.css # 分享卡
│ │ └── animation.css # 动画 keyframes
│ └── js/
│ ├── main.js # 入口:Store + Router + 页面分发
│ ├── core/
│ │ ├── store.js # 状态机(Flux)
│ │ ├── router.js # 客户端路由(History API)
│ │ └── event_bus.js # 事件总线
│ ├── engine/ # 纯逻辑层(零视觉依赖)
│ │ ├── fortune_engine.js # 断案主编排
│ │ ├── daily_fortune_engine.js # 今日天命
│ │ ├── character_engine.js # 测字
│ │ ├── share_engine.js # 分享卡生成
│ │ ├── seed.js / random.js # 种子 + PRNG
│ │ ├── dimensions.js # 五维计算
│ │ ├── score.js # 天命指数
│ │ ├── level.js # 等级映射
│ │ ├── result_selector.js # 判词选择
│ │ ├── easter_egg.js # 彩蛋触发
│ │ └── duplicate_guard.js # 去重
│ ├── visual/ # 视觉表现层
│ │ ├── three_scene.js # Three.js 场景 + Bloom
│ │ ├── compass.js # 3D 罗盘
│ │ ├── particles.js # 粒子能量场
│ │ ├── radar.js # D3 雷达图
│ │ ├── share_image.js # Canvas 分享图
│ │ └── easter_egg_fx.js # 彩蛋特效
│ ├── animation/ # GSAP 时间线
│ │ ├── summon_timeline.js # 召唤仪式
│ │ ├── reveal_timeline.js # 结果揭示
│ │ ├── radar_timeline.js # 雷达图动画
│ │ └── opening_ritual.js # 开场仪式
│ ├── ui/ # UI 组件
│ │ ├── home_view.js # 首页
│ │ ├── judge_view.js # 断案页
│ │ ├── judge_flow.js # 断案流程
│ │ ├── result_card.js # 结果卡
│ │ ├── result_view.js # 结果页
│ │ ├── scene_selector.js # 场景选择器
│ │ ├── judge_button.js # 断案按钮
│ │ ├── daily_fortune_page.js # 今日天命页
│ │ ├── character_page_view.js # 测字页
│ │ ├── share_page_view.js # 分享页
│ │ └── feedback.js # 反馈组件
│ ├── data/ # 静态数据 + 兜底
│ │ ├── judgements.json # 判词库
│ │ ├── scenarios.json # 场景配置
│ │ ├── character_library.js # 100 字库
│ │ ├── title_table.js # 称号表
│ │ └── *_fallback.js # 硬编码兜底
│ ├── analytics/
│ │ └── analytics.js # 埋点上报
│ ├── state/
│ │ └── streak_store.js # 连续开工存储
│ └── utils/
│ ├── device.js # 设备检测
│ └── qrcode.js # QR 码生成
└── tests/
└── server/test_api.py # 6 个 API 测试
核心架构原则
- 算法与视觉彻底解耦:
engine/纯 JS 逻辑层零视觉依赖,可独立运行 - 判词必达:任意降级场景下(数据加载失败、判词池空),用户必定看到完整判词
- 结果可复现:相同 seed + scene 产出完全相同结果,URL 参数可复现
- 渐进增强:WebGL 不可用 → CSS 降级;Three.js 加载失败 → 跳过 3D
断案流程编排
用户点击"一键断案"
→ store.dispatch(JUDGE_START)
→ initThreeScene(canvas) // Three.js 场景初始化
→ createCompass() + createParticles() // 罗盘 + 粒子
→ animateCamera(gsap, camera) // GSAP 相机关键帧
→ renderLoop() // rAF: spinCompass + convergeParticles + composer.render
→ calculateFortune(input) // 纯逻辑:Seed → PRNG → 五维 → 天命指数 → 等级 → 判词
→ store.dispatch(JUDGE_CALCULATING)
→ playSummonTimeline() // GSAP 召唤动画
→ store.dispatch(JUDGE_REVEAL)
→ renderResultCard() // 结果卡渲染 + 雷达图 + 计数动画
→ store.dispatch(JUDGE_RESULT)
发布
一键发布脚本
./scripts/publish.ps1 # patch bump + 发布到 PyPI
./scripts/publish.ps1 -bump minor # minor bump + 发布
./scripts/publish.ps1 -bump none # 不改版本,直接发布
./scripts/publish.ps1 -test # 发布到 TestPyPI
./scripts/publish.ps1 -skipUpload # 仅构建不上传
脚本流程:版本 bump → 测试预检 → 清理 → 构建 sdist + wheel → twine check → 上传 PyPI → git tag
开发约定
- Python 变量:
UPPER_SNAKE_CASE - JS 文件名:
lower_snake_case.js - CSS 类名:
kebab-case - 判词 ID:
UPPER_TAG_DIGITS(如BUSINESS_003) - 设计令牌:
--color-*/--font-*/--space-*/--radius-*(定义于main.css)
生产部署
FastAPI 静态托管可无缝切换至 Nginx + CDN,前端无差异。伴生服务仅承担静态托管与埋点收集,不参与命运计算核心逻辑。
# Gunicorn + Uvicorn worker
gunicorn recruitment_judge.app:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file recruitment_judge-0.3.1.tar.gz.
File metadata
- Download URL: recruitment_judge-0.3.1.tar.gz
- Upload date:
- Size: 246.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ede1727a1dad0fcb2c10fb29b703e5ef99b042e62157a10a5b80433f11022d7e
|
|
| MD5 |
379a49be80276d19305a33b883a85e0b
|
|
| BLAKE2b-256 |
7085b9a2995f0eefbef0d4b566db09129b7d68710f5fd759cfa807d1a89278f9
|
File details
Details for the file recruitment_judge-0.3.1-py3-none-any.whl.
File metadata
- Download URL: recruitment_judge-0.3.1-py3-none-any.whl
- Upload date:
- Size: 118.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e1af8738e920bd92ea4d2a724f2014bf23fd736f6e04f1bcaedf41dd519e9da
|
|
| MD5 |
eb1c11dedc5d37fc1dbd726dae04c2e4
|
|
| BLAKE2b-256 |
109c7ec46cd076a3e7fa63bce7a98e8b893c3f20248b13301281797f3ebab14d
|