物达通 ERP 全产品 Skill
通过 erp-cli 命令管理物达通 ERP 系统能力。
安装
如果环境中没有 erp-cli,执行以下命令安装:
# 国内用户推荐使用淘宝镜像
npm install -g @windaka-erp/erp-cli --registry=https://registry.npmmirror.com
> 安装过程中 erp-cli 二进制文件会自动下载。如果 GitHub 下载失败,会自动回退到国内 Gitee 镜像源。
安装完成后验证:
erp-cli --help
你(AI Agent)是执行者:用户用自然语言描述需求,由你决定并执行对应的 CLI 命令。不要让用户自己输入命令。
严格禁止 (NEVER DO)
- 不要使用
erp-cli命令以外的方式操作(禁止直接 curl、HTTP API、浏览器) - 不要编造 ID、工单编号、用户名等标识符,必须从命令返回中提取
- 不要猜测字段名/参数值,操作前必须先查询确认
- 不要让用户自己运行
erp-cli命令,你来执行,用户只需要用自然语言描述需求
严格要求 (MUST DO)
- 所有命令的输出都是 JSON 信封格式:
{"ok": true, "data": {...}}或{"ok": false, "error": {...}} - 危险操作(创建/修改/删除)必须先向用户确认,用户同意后才执行
- 写操作可先用
--dry-run预览请求内容,再去掉--dry-run正式执行 - 备注/说明类字段(如
--remark):执行写操作前主动问用户是否需要填写备注,用户说了就填,用户说不填或不需要就不传。不要自己编造内容 - 操作前必须先读取对应产品的参考文件
产品总览
| 产品 | 命令 | 用途 | 参考文件 | 状态 |
|---|---|---|---|---|
| 认证 | auth |
Device Flow 登录/登出/状态查询、Token 自动管理 | global-reference.md | ✅ 已完成 |
| 配置 | config |
配置 ERP 后端地址、多环境(profile)管理 | global-reference.md | ✅ 已完成 |
| API 兜底 | api |
当 Shortcut 不满足需求时,直接调用 RuoYi API | global-reference.md | ✅ 已完成 |
| 工单 | workorder |
我的待办工单、创建工单、流程操作(分派/接单/处理/确认/回访等) | workorder.md | 🚧 部分完成 |
| OA | oa |
我的审批/流程待办 | oa.md | 🚧 部分完成 |
| 通讯录 | contact |
查询用户、部门、按姓名搜索员工 | — | ⏳ 待实现 |
| 项目 | project |
查询当前用户可用项目 | workorder.md | ✅ 已完成 |
| 房产 | property |
按用户输入的房产名称查询房产/车位 | workorder.md | ✅ 已完成 |
| 费用 | charge |
工单费用、缴费查询 | — | ⏳ 待实现 |
意图判断决策树
本 skill 只覆盖 ERP 系统操作。用户要查询/操作 ERP 系统里的数据时走对应 Shortcut;不在 ERP 操作范围内的问题(如纯知识问答、闲聊)不在本 skill 范围内,直接用通用知识回答。
用户的话包含明确的 ERP 操作关键词?
(我的工单/工单待办/我的 OA 待办/建工单/分派/接单/工单详情/登录/配置...)
→ 是 → 走对应 ERP Shortcut
→ 否 → 不在本 skill 范围,用通用知识回答
ERP 操作关键词:
优先规则:用户只说"我的待办",未出现工单、OA、审批或流程等范围词
→ 不执行 workorder +list、oa +handle-list 或其他列表命令
→ 只问:“你要查询工单待办,还是 OA 审批/流程待办?”
→ 用户明确选择工单后才执行 workorder +list;明确选择 OA 审批/流程后才执行 oa +handle-list
用户提到"工单/报修/维修/故障/工单待办/我的工单" → workorder
用户提到"被退回 OA/退回审批/退回待办/退回流程" → oa +return-list
用户提到"已超时 OA/超时审批/超时待办/逾期流程" → oa +timeout-list
用户提到"我经办的 OA/我处理过的审批/OA历史处理记录" → oa +done-list
用户提到"我的草稿/OA草稿/我保存未提交的流程" → oa +draft-list
用户提到"OA流程详情/审批记录/流程表单/填写数据" → oa +info(先从 OA 列表核对 ID;已知流程编号时使用对应列表的 --process-number 精确定位)
用户提到"我要请假/我要报销/发起 OA/申请 OA/新建审批流程" → 先 oa +available-processes 展示全部可发起模板,由用户明确选择 processId,再 oa +request-link --intent <意图> --process-id <processId> 生成网页填写链接;这是用户在页面填写并提交,不是 CLI 直接提交流程
用户提到"同意审批/审批通过" → 先从同一条 oa +handle-list 待办核对运行态上下文,再 oa +approve(dry-run 后确认)
用户提到"驳回审批/拒绝流程" → 先从同一条 oa +handle-list 待办核对上下文、收集用户原文理由,再 oa +reject(dry-run 后确认;仅当前节点为"审批"时可执行,处理/发起/抄送节点会被拒绝)
用户提到"转交 OA 审批/转交流程" → 先从同一条 oa +handle-list 或 oa +info 获取 topLevelId,再 oa +search-user --top-level-id <topLevelId> 明确选择人员,核对待办上下文后使用 oa +transfer(dry-run 后确认)
用户提到"给 OA 审批加签" → 先从同一条 oa +handle-list 或 oa +info 获取 topLevelId,再 oa +search-user --top-level-id <topLevelId> 明确选择人员和加签方式,核对待办上下文后使用 oa +add-sign(dry-run 后确认)
用户提到"退回某步/退回上一审批步骤/退回发起人" → 先 oa +return-step-options,再由用户按 taskDefKey 选择并用 oa +return-step(写操作,dry-run 后确认)
用户提到"退回重填/退回让发起人重填" → oa +return-for-refill(写操作;详情 handleWithdrawStart=1 且服务端候选恰有一个 start_user 时可用,dry-run 后确认)
用户提到"撤回 OA/撤销我发起的流程/撤回流程" → 先 oa +revoke-options,再由用户按 taskDefKey 选择并用 oa +revoke(详情 startWithdraw=1;写操作,dry-run 后确认)
用户提到"办理流程/处理 OA/处理完成" → oa +handle(仅详情 processBusinessType=2 的处理节点;写操作,dry-run 后确认)
用户提到"删除草稿/作废 OA 草稿" → oa +delete-draft(先核对 ID、dry-run,并取得确认)
用户提到"删除我发起的流程/删除待提交流程" → oa +delete(先从 +create-list 核对待提交 ID、dry-run,并取得确认)
用户提到"我能发起的流程/我可以发起什么流程/可发起流程/可申请的 OA 审批" → oa +available-processes(展示当前用户全部可发起流程,不做意图匹配)
用户提到"我发起的 OA/我提交的审批/我创建的流程" → oa +create-list
用户提到"抄送给我的/抄送审批/我收到的抄送" → oa +cc-list
用户提到"未读抄送" → oa +cc-list --read-status unread
用户提到"已读抄送" → oa +cc-list --read-status read
用户提到"我的 OA 待办/我的审批待办/待我处理的流程/OA待办/审批待办" → oa +handle-list(仅查询当前待处理 OA;“我要请假/报销/发起流程”走可发起流程路线,不走待办)
用户提到"OA/审批/流程"但无法判断是发起、查询还是处理 → 先澄清意图,不默认执行 oa +handle-list
用户提到"登录/登出/认证状态" → auth
用户提到"配置/切换环境/profile" → config
用户提到"找人/某员工/通讯录/部门" → contact(待实现)
用户提到"项目/小区/物业项目" → project +list
用户提到"房产/房号/车位" → property +search(须项目ID和用户输入的房产名称)
用户提到"费用/收费/缴费" → charge(待实现)
关键区分:
- 先判断产品范围,再判断动作;“工单待办”和“OA 审批待办”不是同一类待办,不能因为都出现“待办/处理”而互换。
- 用户说"查工单 / 我的工单 / 我有什么工单 / 工单待办 / 我的待办工单" → workorder +list(当前还在我手上的)
- 用户说"我的 OA 待办 / 我的审批待办 / 待我处理的 OA 流程" → oa +handle-list
- 用户只说"我的待办"且没有工单、OA、审批或流程范围词 → 只问“你要查询工单待办,还是 OA 审批/流程待办?”,不执行任何列表命令
- 用户说"我要请假/报销/发起 OA 流程" → 这是发起动作,不是待办查询;走 oa +available-processes → 用户选择 processId → oa +request-link
- 用户说"被退回的 OA 待办 / 退回给我的审批" → oa +return-list
- 用户说"已超时的 OA 待办 / 超时审批" → oa +timeout-list
- 用户说"我经办的 OA / 我处理过的审批 / OA 历史处理记录" → oa +done-list
- 用户说"我的草稿 / OA 草稿 / 我保存未提交的流程" → oa +draft-list
- 用户说"OA 流程详情 / 审批记录 / 流程表单 / 填写数据" → 先从 OA 列表核对 ID,再运行 oa +info --id <id>;有来源列表提供的当前步骤、任务和审批人上下文时一并传入,注意可能标记待办或抄送为已读
- 用户说"退回某步 / 退回上一审批步骤 / 退回发起人" → 先从同一待办核对任务上下文,运行 oa +return-step-options 展示候选;用户必须按 taskDefKey 明确选择,使用 oa +return-step --dry-run 预览并确认后才执行
- 用户说"退回重填 / 退回让发起人重填" → 使用 oa +return-for-refill --dry-run;仅当最新详情 handleWithdrawStart=1 且服务端当前候选恰有一个 start_user 才可预览和执行,候选不匹配时改走 +return-step-options 后按 taskDefKey 明确选择
- 用户说"撤回 OA / 撤销我发起的流程 / 撤回流程" → 先从同一待办核对 id、currentProcessBusinessId、字符串 currentTaskId 和 currentSequence,运行 oa +revoke-options --current-sequence <currentSequence> 展示候选;用户必须按 taskDefKey 明确选择,再用同一上下文运行 oa +revoke --current-sequence <currentSequence> --dry-run 预览并确认后才执行;最新详情必须 startWithdraw=1,详情不提供序号时不得猜测。待办查不到目标流程时(如已转交他人),从 oa +create-list --format json(我发起的)或 oa +done-list --format json(我经办的)按 processNumber 定位,取该行 currentProcessBusinessId/currentTaskId/currentSequence 作为撤回上下文
- 用户说"办理流程 / 处理 OA / 处理完成" → 使用 oa +handle --dry-run;仅最新详情 processBusinessType=2 的处理节点可用,命令自动提交 processBusinessStatus=2
- 用户说"删除草稿 / 作废 OA 草稿" → 先从 oa +draft-list 核对 ID,运行 oa +delete-draft --id <id> --dry-run,取得用户明确确认后才执行
- 用户说"删除我发起的流程 / 删除待提交流程" → 先从 oa +create-list 核对流程 ID 和状态为“待提交”,运行 oa +delete --id <id> --dry-run,取得用户明确确认后才执行
- 用户说"我能发起的流程 / 我可以发起什么流程 / 可发起流程 / 可申请的 OA 审批" → oa +available-processes;直接展示当前用户全部可发起流程,不按名称、标题、类型或意图筛选
- 用户说"我发起的 OA / 我提交的审批 / 我创建的流程" → oa +create-list
- 用户说"抄送给我的 / 抄送审批 / 我收到的抄送" → oa +cc-list
- 用户说"未读抄送" → oa +cc-list --read-status unread
- 用户说"已读抄送" → oa +cc-list --read-status read
- 用户只说"我的待办" → 不执行任何待办列表命令,只问:“你要查询工单待办,还是 OA 审批/流程待办?”;仅在用户明确选择后才路由到对应列表
- 用户说"我经办的工单 / 我处理过的工单 / 历史工单" → workorder +handle-list(含已完成历史)
- 用户说"这个工单什么情况 / 工单详情 / 处理记录" → workorder +info --id <id> --dept-id <deptId>
- 用户说"建工单/报修/创建工单/发一个工单申请链接/让现场人员自己填报修" → workorder +request-link(写操作,先确认;生成线上一次性申请链接;+create 仅为兼容别名)
- 用户说"延期/申请延期/延长工期" → workorder +postpone(写操作;仅处理中、未挂起的普通流程可申请)
- 用户说"分派/接单/处理工单" → 先看工单状态,再选对应 Shortcut(状态不对不能操作,如非待分派不能分派)
返回分页数据时:必须先告诉用户"共 X 条,当前第 Y 页,本页 Z 条",再展示工单详情,让用户知道是否需要翻页。
> 更多易混淆场景、跨产品工作流见 intent-guide.md
模块协作
ERP 各模块互相依赖,AI 经常需要跨模块组合调用:
| 场景 | 涉及模块 | 流程 |
|---|---|---|
| 查询 OA 列表 | auth + oa | 1) 仅在用户明确要查询 OA 待办、历史、草稿、我发起或抄送流程时选择对应列表 2) 运行 oa +handle-list、+return-list、+timeout-list、+done-list、+draft-list、+create-list 或 +cc-list 3) 三个待办列表默认已使用固定表头表格;先报告分页摘要,再展示列表 |
| 发起 OA 流程 | auth + oa | 1) 用户说请假、报销、发起或申请 OA 时先 oa +available-processes 2) 展示全部模板,用户明确选择 processId 3) 对 oa +request-link --intent <意图> --process-id <processId> 先 dry-run 并取得确认 4) 正式生成网页填写链接;用户在页面填写并提交 |
| 查询 OA 流程详情 | auth + oa | 1) 从 OA 列表核对流程任务 ID 2) 运行 oa +info --id <id> 3) 展示表单结构、填写数据和处理记录;带待办/抄送上下文时可能标记为已读 |
| 退回 OA 到指定步骤 | auth + oa | 1) +handle-list 核对任务上下文 2) 最新详情确认 handleWithdrawNode=1 3) +return-step-options 展示候选 4) 用户按 taskDefKey 选择 5) +return-step --dry-run 预览 6) 明确确认后执行;候选会在写入前重新验证 |
| 退回重填 | auth + oa | 1) +handle-list 核对任务上下文 2) 最新详情确认 handleWithdrawStart=1 3) +return-for-refill --dry-run 预览服务端唯一 start_user 发起节点 4) 明确确认后执行;无唯一候选时回退到通用退回选择 |
| 撤回 OA 流程 | auth + oa | 1) +handle-list 核对同一行的任务上下文和 currentSequence 2) +revoke-options --current-sequence <currentSequence>,最新详情确认 startWithdraw=1 3) 用户按 taskDefKey 选择 4) 用同一序号运行 +revoke --current-sequence <currentSequence> --dry-run 预览 5) 明确确认后执行;候选会在写入前重新验证 |
| 删除 OA 草稿 | auth + oa | 1) +draft-list 核对草稿 ID 2) +delete-draft --dry-run 预览 3) 获得明确确认后执行 +delete-draft |
| 删除我发起的 OA 流程 | auth + oa | 1) +create-list 核对待提交流程 ID 2) +delete --dry-run 预览 3) 获得明确确认后执行 +delete |
| 创建工单 | auth + workorder | 1) 确认已登录 2) 获得明确确认后运行 workorder +request-link 3) 打开立即生成的线上一次性链接填写并提交 |
| 线上自助申请工单 | auth + workorder | 1) 确认已登录 2) 获得明确确认后运行 workorder +request-link 3) 打开立即生成的线上一次性链接填写 |
| 分派工单给"张三"(如需指定处理人) | workorder | 1) +info 确认状态=1 并取 currentTaskId + 分类字段 2) +apportion(--work-order-class-id/--work-order-class-name 必填)第一次试不传处理人 3) 若返回 code=204 用 +search-user --nick-name 张三 拿 userId+userName 4) 二次调 +apportion 加 --process-business-id 和 --assignees userId:userName |
| 查工单详情含费用 | workorder + charge | 1) +info 查工单详情 2) api GET /workorder/master/getWorkOrderCharge?id=<id> 查关联费用 |
搜不到时不要猜,要问用户。 例如搜不到"张三"时,告诉用户"未找到此员工,请确认姓名或提供工号"。
命令格式
所有命令不带任何身份参数。一个环境(profile)只有一个登录 token。
- Token 存到
~/.erp-cli/tokens/<profile>.json(默认 profile 是default) - 多环境(prod/staging)用
--profile <name>切换,每个环境独立 token
认证流程(核心)
所有 ERP 操作前必须登录。Token 过期不会自动重新登录,业务命令会返回错误,AI 需要主动重新执行登录流程。
两步登录(推荐,AI Agent 必须使用)
# Step 1: 申请验证链接(立即返回,不阻塞)
erp-cli auth login-start
# → 返回 {"ok":true,"data":{"device_code":"dc_xxx","verification_uri_complete":"https://...","expires_in":300}}
# Step 2: 把链接发给用户,然后轮询等待授权结果
erp-cli auth login-wait --device-code dc_xxx
# → 阻塞等待,授权成功保存到当前 profile 的 token 文件
AI 执行流程:
1. 调 erp-cli auth login-start,立即拿到 URL + device_code
2. 立刻把 URL 发给用户:"请点击此链接完成登录"
3. 调 erp-cli auth login-wait --device-code <code>,阻塞等待
4. 拿到结果后告诉用户:成功→"登录成功!欢迎 xxx",超时→"授权超时,请重新登录"
❌ 严禁只调 login-start 就停止任务:那样 token 不会保存到本地,等于没登录。
一步登录(仅 CLI 直接使用)
erp-cli auth login # 一步完成:申请码 + 输出链接 + 轮询等待
适用于人工在终端直接运行。AI Agent 不要用这个命令(无法在中途把 URL 发给用户)。
查看登录状态
erp-cli auth status # 查看当前 profile 的登录状态
Token 过期处理
业务命令遇到 token 过期会直接返回错误:
{"ok":false,"error":{"type":"auth","code":3,"message":"token expired","hint":"run `erp-cli auth login-start` then `erp-cli auth login-wait`"}}
AI 拿到这个错误后,按 hint 提示重新执行两步登录流程。
详细认证规则见 global-reference.md。
危险操作确认
以下操作为写操作或不可逆操作,执行前必须先向用户展示操作摘要并获得明确同意,同意后才执行。
| 产品 | 命令 | 说明 |
|---|---|---|
workorder |
+request-link |
打开线上工单申请页(+create 为兼容别名) |
workorder |
+update-class |
修改工单分类 |
workorder |
+apportion |
分派工单 |
workorder |
+take |
接单工单 |
workorder |
+follow |
记录工单跟进 |
workorder |
+complete |
完成处理工单 |
workorder |
+confirm |
确认工单 |
workorder |
+visit |
回访工单 |
workorder |
+postpone |
申请延期工单 |
workorder |
+transfer |
转单 |
workorder |
+discard |
作废工单(不可恢复) |
workorder |
+approve |
审批工单 |
oa |
+delete-draft |
删除 OA 草稿(不可恢复) |
oa |
+delete |
删除本人待提交 OA 流程(不可恢复) |
oa |
+request-link |
生成一次性 OA 流程填写链接(正式生成前需确认;用户在网页填写并提交) |
oa |
+approve |
审批通过 OA 审批节点(仅详情 processBusinessType=1;可随操作传入 --cc-recipient) |
oa |
+handle |
办理 OA 处理节点(仅详情 processBusinessType=2;调用 handle 接口并自动传状态 2) |
oa |
+reject |
驳回 OA 待办(详情读取流程参数,列表提供运行态任务参数;可随操作传入 --cc-recipient) |
oa |
+add-sign |
OA 待办前/后加签(可随操作传入 --cc-recipient) |
oa |
+transfer |
转交 OA 待办(可随操作传入 --cc-recipient) |
oa |
+return-step |
退回 OA 待办到服务端允许且由用户明确选择的步骤 |
oa |
+return-for-refill |
退回重填到服务端唯一 start_user 发起步骤(要求详情 handleWithdrawStart=1) |
oa |
+revoke |
撤回 OA 到服务端允许且由用户明确选择的步骤(要求详情 startWithdraw=1) |
确认流程
Step 1 → 展示操作摘要(操作类型 + 目标工单 + 关键参数)
Step 2 → 用户明确回复确认(如"确认"/"好的")
Step 3 → 执行命令(可先用 --dry-run 预览请求体)
命令发现
erp-cli --help # 全局帮助
erp-cli <product> --help # 产品级帮助
erp-cli workorder +list --help # Shortcut 详细参数
错误处理
| 错误 | 原因 | 处理 |
|---|---|---|
config: not configured |
未初始化 | 执行 erp-cli config init |
auth: not logged in |
未登录 | 执行 erp-cli auth login-start + login-wait,把链接发给用户 |
auth: token expired / HTTP 401 |
Token 过期 | CLI 已自动触发登录,把新链接发给用户 |
HTTP 403 |
权限不足 | 告知用户联系管理员开通对应权限 |
validation: --xxx is required |
缺少必填参数 | 向用户询问后重新执行 |
安全规则
- 禁止向用户输出密码、Token 等敏感信息
- 写入/删除操作前必须确认用户意图
- Token 保存在
~/.erp-cli/tokens/目录下,仅当前用户可读
详细参考(按需读取)
- references/global-reference.md — 全局规则:认证、配置、Token 管理、API 兜底、退出码、输出格式
- references/intent-guide.md — 意图路由指南:易混淆场景对照、典型场景详解、跨产品工作流
- references/products/workorder.md — 工单产品详细参考
- references/products/oa.md — OA 审批/流程产品详细参考