云南 12345 一键诉求助手
只做一件事:把云南的事,用一份要素齐全、地点准确、经本人确认的工单,送进云南 12345。
- 免登录:云南 12345 支持匿名提交(全国少见),本技能走匿名通道
- 一键:
run一条命令跑完「定地点 → 写正文 → 填表 → 出确认卡」 - 不代你提交:没有你的明确确认,脚本不会点提交(硬闸门,见下)
快速开始
cd scripts
npm install playwright # 只需一次;未下载浏览器时用 PW_CHROME_PATH 指向本机 Chrome
# ① 一键:定地点 + 写正文 + 填表(不会提交)
node scripts/yn12345.js run --text "昆明市五华区人民中路128号工地夜里施工,已经三晚" \
--phone 13800138000
# ② 用户明确同意后提交
node scripts/yn12345.js confirm --id Y-xxxx --by 王大爷 --submit
# 或者真「一键」:run 挂起等确认,同一会话内直接提交
node scripts/yn12345.js run --facts facts.json --phone 13800138000 --wait-confirm
facts.json 模板见 examples/facts.example.json——把八要素填进去,草稿直接可用。
工作流
run
├─ ① route 云南 16 州市/区县路由
│ └─ 地点不明 ──▶ [ASK] 追问(州市?区县?街道?)──▶ 用户回答后重跑
├─ ② compose 八要素正文 + 缺项追问 + 语气/字数校验
│ └─ 必填缺 ──▶ [ASK] 逐条问用户 ──▶ 补齐后重跑
├─ ③ 预填(Playwright 实名填表,停在三步向导的留言页)
│ └─ 输出 [预览] 字段+正文全文+截图 + [待确认] Y-xxxx
└─ 若 --wait-confirm:挂起等 state/pending/Y-xxxx.confirm(内容 "CONFIRM:确认人")
└─ 收到 → 滑块 → 短信码 → 勾选 → 提交 → 受理编号
不确定就停:[ASK] 一律退出码 2,Agent 必须去问用户,不得自行假定地点或替用户补事实。
命令
| 命令 | 作用 | 关键参数 |
|------|------|---------|
| run | 一键:路由+起草+填表(默认不提交) | --text / --facts、--phone、--district、--wait-confirm |
| confirm | 记录用户确认 | --id Y-xxxx --by 王大爷 [--submit] |
| submit | 提交已确认的预览单 | --id Y-xxxx、--prefill-only(只复填截图,不提交,用于排查选择器) |
| query | 查办理进度 | --code 受理编号 --phone 手机号 |
| pending | 列出预览单 | [--all] |
| doctor | 环境自检 | — |
区划写法三选一(越完整越省事):
--district "昆明市/五华区/护国街道" # 完整路径,脚本直接点到叶子(推荐)
--district "五华区" # 只给区县,自动补州市,街道需在浏览器内点选
--text "昆明市五华区人民中路128号…" # 从描述里识别
验证码与滑块
--sms-code 123456 # 直接给短信码
--sms-code-file state/sms.txt # Agent 场景:把码写进文件,脚本轮询
--slider-vision-dir state/vision # 滑块视觉模式(headless 可用)
--no-headless # 滑块人工兜底 / 需要人眼看表单
确认闸门(不可绕过)
| 环节 | 规则 |
|------|------|
| 默认行为 | run 只填表,不点提交、不请求短信 |
| 提交前提 | 必须有 approval 记录(confirm --by),且确认未过期(默认 24h) |
| 内容一致性 | 提交时对「正文/区划/地址/手机号」做 SHA-256 逐字比对;改一个字即拒绝,必须重新预填并再确认 |
| 防重放 | 提交成功即标记 CONSUMED,同一确认不能二次提交 |
| 留痕 | state/audit.log 记录 pending-created / approved / consumed |
Agent 侧判定「用户已确认」的严格标准:
- ✅ 「确认」「可以提交」「就按这个发」
- ❌ 沉默、只回表情、「嗯」、"看起来还行"、以及针对上一次预览的旧同意
- ❌ 用户同时提出修改 → 先改,重新
run预填,再问一次
云南平台技术要点(改代码前必读)
- 双重防盗链:页面 HTML 需要外层门户 Referer 放行,但滑块静态资源反而拒绝该 Referer。
必须用
lib/browser.js的gotoEntry()两跳导航(先门户、后系统); 禁止全局extraHTTPHeaders注入 Referer,否则滑块图片 403、滑块永远出不来、短信永远发不出。 - 行政区划必须选到叶子:Element Plus cascader 默认
checkStrictly=false,点非叶子只展开不选中; 末级常是街道/社区(滇池旅游度假区下有 27 个小区级叶子)。 选中后输入框 placeholder 被清空,读值要用.el-cascader input.el-input__inner。 - 短信前置滑块:点「获取短信验证码」先弹拼图滑块,通过后短信才发出。三档:视觉模式 → 模板匹配 → 人工拖。
- 隐私勾选:
.el-checkbox__original被隐藏且移出视口,要点击可见包裹层 + JS 兜底。 - 四步向导:certification(选「直接提交」=匿名)→ personal(姓名默认匿名 + 手机必填)→ message(区划/地址/正文≤2000字/短信码/隐私勾选)→ finish(受理编号)。
- 附件最多 5 个、单个 ≤10MB(本技能不代传附件,需要时在页面手工添加)。
Agent 集成协议
| stdout 标记 | 含义 | 动作 |
|------------|------|------|
| [路由] | 地点已定(含 [区划路径]) | 继续 |
| [ASK] | 缺地点/缺要素/缺手机号(退出码 2) | 把 [问题] 抛给用户,等答复后重跑 run |
| [草稿-开始]…[草稿-结束] | 正文定稿 | 给用户过目 |
| [缺要素] | 逐条待问 | 按顺序问用户(每项带示例答案) |
| [预览] + [待确认] Y-xxxx + [截图] | 已填未提交 | 把字段、正文全文、截图给用户,问「可以提交吗」 |
| [等待确认] | --wait-confirm 挂起中 | 把 CONFIRM:<确认人> 写入 state/pending/Y-xxxx.confirm |
| [已确认] / [审批] | 确认已记录/核验通过 | 继续等待提交结果 |
| [HITL] | 需人工点选区划或输验证码 | 截图给用户;短信码以 --sms-code 或 --sms-code-file 回填 |
| [完成] / [错误] | 终态 | 转述受理编号 / 报告原因 |
诉求写作要点(详见 references/complaint-writing.md)
- 八要素:时间 / 地点 / 涉及单位 / 经过 / 影响 / 证据 / 前期反映 / 诉求
- 事实与推断分离:推断写「疑似/据了解/请核实」,不写成事实
- 诉求 = 动作 + 对象 + 时限 + 可核查结果(「3 个工作日内书面告知」而非「尽快」)
- 不写身份证号、银行卡号、他人姓名电话;手机号只填表单字段,不进正文
- 正文上限 2000 字,超限用
--compact段落版
合规红线
- 仅限本人使用:为本人提交诉求、查询本人进度;禁止代投、批量提交、刷单
- 确认必须来自用户本人:Agent 不得代点确认,不得因「之前说过要提交」跳过本次确认
- 不伪造事实:不编时间、单位、金额、单号、法条
- 短信验证码真人接收:不接码、不共享手机号
- 平台有频控,同一问题重复提交会被拒;政府网站改版会导致选择器失效(报「页面结构可能已改版」时需更新
lib/platform.js的 SEL)
目录结构
yunnan-12345-oneclick/
├── SKILL.md # 本文件
├── README.md # 安装、自测、限制
├── examples/facts.example.json
├── references/complaint-writing.md
├── config/districts.json # 云南 16 州市 + 区县 + 别名(路由数据)
├── scripts/
│ ├── yn12345.js # 一键入口:run / confirm / submit / query / pending / doctor
│ └── lib/
│ ├── route.js # 州市/区县路由 + 追问决策
│ ├── compose.js # 八要素正文 + 校验
│ ├── approval.js # 两阶段确认 + 哈希核验 + 防重放
│ ├── platform.js # 云南平台三段操作(openWizard/fillMessage/submitCurrent)
│ ├── browser.js # 两跳导航 + 截图 + 会话
│ ├── captcha.js # 短信码 HITL
│ └── slider.js # 滑块三档:视觉模式 / 模板匹配 / 人工
└── state/ # pending/ 预览单、shots/ 截图、audit.log(运行时,勿提交)
Scan to join WeChat group