迅捷应用平台

SKILL效率
效率 未标注权限 许可证不明确
安装这个技能

迅捷应用平台的表单系统(填单/查单/发起流程/审批)。当用户想发起报销/请假/审批流程、查询单据数据、查看待办、或让 AI 代填表单时使用。

一句话选型结论

按资料字段整理

迅捷应用平台是效率类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类效率 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_e1d46ddd/xj-form-agent
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

效率
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_e1d46ddd仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791732723
正文体量48.3 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
整理待办与日程

把零散任务收进清单,排出优先级。

批量处理重复任务

把固定动作做成模板,重复执行。

把流程写成清单

把口头流程整理成可复用的步骤。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在效率场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
迅捷应用平台当前 未标注权限 未标注 未标注 未标注 有
Nano PDF 文档 联网访问 ClawHub 市场 424.9 万 OpenClaw 有
自动更新程序 浏览器控制 ClawHub 市场 296.4 万 OpenClaw 有
Gemini 助手 联网访问 ClawHub 市场 254.7 万 OpenClaw 有
word DOCX 文档 联网访问 ClawHub 市场 239.6 万 OpenClaw 有
Excel XLSX 前端 联网访问 ClawHub 市场 227.0 万 OpenClaw 有

SKILL.md 全文

48.3 KB
模型实际读到的说明书原文,来自技能仓库

迅捷应用平台 · Agent 操作技能

本文档指导 Agent 调用迅捷应用平台的表单能力:填单、查单、发起流程、查询待办等。

何时触发

以下意图应使用本技能(而不是凭空编造):
- 发起/填写某个业务表单或审批流程("帮我发起一笔差旅报销""提交请假审批")。
- 查询表单数据 / 我的待办 / 可发起的流程("查我上个月提交的单""看看我的待办")。
- 获取某个单据的表单结构、字段编辑权限。
- 查询我有哪些授权的应用/菜单(业务列表页)("我有权限看哪些列表""能找到发票列表吗""进发票列表查数据")——见「枚举我的授权应用/菜单」SOP 与 references/authorized-menus.md。
- 关联选择/带出关联字段("选一下发票""把发票信息带出来""关联选一张采购单")——见「带出关联字段(关联选择)」SOP 与 references/relation-select.md。
- 查统计结果/执行报表/看汇总数据/报表下钻("执行部门报销统计看看各部合计""跑一下这份关联查询""这份统计下钻到原始单据")——见「执行统计报表取数」SOP。

业务场景索引(命中场景先读对应 SOP 再动手):

场景 触发词示例 场景 SOP
报销单填写(发票关联/现场上传发票入票夹) "报销""贴发票""上传发票然后报销""发起报销单" examples/reimbursement-invoice/SKILL.md

以下情况不要触发:涉及密码/验证码、越权数据、未绑定身份时。


接入方式(先读这里,决定要不要走「一、配置与认证」)

本技能有两种运行方式,凭据处理完全不同,先认清自己在哪种:

运行方式 谁持有 bindSecret Agent 要做什么
A · MCP 宿主/连接器(如 WorkBuddy 等) 用户在 MCP 宿主侧已配置并连接 xunjie MCP 服务(连接时填了 HHD_BIND_SECRET),h-design-mcp 自动 exchange 换 token 并注入 先探测(见下方判定)确认 MCP 可用后,直接调用「二、可用工具」。不要引导用户重新创建绑定、不要写 scripts/config.json、不要跑 agent.mjs auth、不要持久化 bindSecret。报「未认证」时让用户在宿主的连接配置中重新填/刷新 bindSecret
B · 自托管 CLI(Claude Code 等非 MCP 宿主,走 scripts/agent.mjs / curl) Agent 侧持有:须手动绑定 + agent.mjs 持久化后复用 按「一、配置与认证」手动完成绑定后才能调用

> 判定(先探测,不要假设自己处于哪种方式):
> 1. 查 MCP 服务:检查本会话是否已连接名为 xunjie 的 MCP 服务(宿主的 MCP/连接器列表里能找到,且能列出本 skill 的平台工具)。也可以直接试调一个无参轻量读工具(如 list_my_menus)——返回正常数据即方式 A 可用,整节跳过「一、配置与认证」,直接看「二、可用工具」及各 SOP。新增「处理一张待办/发起流程」等 SOP 前的"配置"一律视为已就绪。
> 2. 探测不到就走方式 B:没有 xunjie MCP、服务未连接、试调报「无可用工具/超时/未认证且无法刷新」——视为 MCP 不可用,走方式 B(自托管 CLI):按「一、配置与认证」完成绑定后经 scripts/agent.mjs 调用。
> 3. 两种方式下工具名与参数完全一致,仅认证方式不同。
>
> 工具范围(scope):MCP 连接配置的「工具范围」字段填 agent 时,连接只暴露本 skill 的运行时类工具(填单/查单/流程/审批/报表取数,含 shared)——推荐本 skill 的连接统一填 agent,避免无关工具干扰。留空=全部工具;/call 不做强制隔离,误调 designer 侧工具只是浪费不会破坏。


一、配置与认证(仅方式 B:自托管 CLI 需要;方式 A(MCP) 已由连接器完成,跳过本节)

系统不要求 Agent 持有账号密码。Agent 通过一个代表某系统用户的令牌来调用工具,该令牌由 bindSecret 换取得到,且所有请求必须携带。

1) 拿到令牌(唯一方式:bindSecret 换取,两端通用)

① 绑定(用户在系统 UI 完成,Agent 负责引导)
- 用户在 web 顶部「第三方Agent绑定」菜单点「创建绑定并生成密钥」,得到唯一的 bindSecret(等价登录凭证),交给宿主持有。
- 绑定页复制的内容同时包含连接地址与 bindSecret(形如 HHD_BASE_URL=…、HHD_BIND_SECRET=…),两者都要留存。

② base URL 配置(首次必做)
- 把用户复制内容里的连接地址写入本 skill 的 scripts/config.json(文件不存在则创建):{ "baseUrl": "<复制的地址>" }。
- 优先级:scripts/config.json 的 baseUrl > 环境变量 HHD_BASE_URL > 默认值。首次配置后必须写入,否则可能连到错误环境。

③ 换取(宿主做)
- 宿主调用 POST /api/agent/bind/exchange(免登录、免租户),请求体只需 { "bindSecret": "<密钥>" },响应含 token + username + tenantId(多租户时返回,单体版为空) + agentName + expiresIn。

④ 调用
- 之后所有 /api/agent/form/* 调用带 X-Access-Token: <token>;且若返回了 tenantId,必须带 X-Tenant-Id: <tenantId>。
- token 过期(默认30分钟)后用同一个 bindSecret 重新 exchange。

无 bindSecret 的处理(重要):当用户让 Agent 操作表单(查待办/发起/审批等)、但 Agent 侧还没有 bindSecret 时,不要擅自执行——先引导用户:「请在系统右上角『第三方Agent绑定』创建绑定,把复制出的连接地址和 bindSecret 都提供给我」。拿到后:先把连接地址写入 scripts/config.json,再 exchange 换取 token 并继续执行任务。已有 bindSecret 则直接 exchange → 正常执行。

记住 bindSecret(跨会话复用,务必做):一旦用户提供了 bindSecret(或新绑定生成),立刻持久化,不让它只存在于当前会话:
- 优先写入宿主持久记忆 / 全局配置(如 Claude Code 的全局记忆、宿主的环境配置),记下 HHD_BIND_SECRET=<值>;
- 终端宿主同时把它写进 shell 配置文件(如 ~/.bashrc/~/.bash_profile 追加 export HHD_BIND_SECRET="<值>"),这样每次新会话自动继承;
- 之后任何会话无需用户再给 bindSecret,直接读 HHD_BIND_SECRET → exchange 拿新 token 即可;只有 bindSecret 失效(提示"bindSecret 无效")才重新找用户绑定/换。
> ⚠️ bindSecret 等价登录凭证,持久化时注意存放位置;若感觉泄露风险,提醒用户去 UI 解绑重绑刷新。

> channel(WorkBuddy/企微/钉钉/自定义)仅在绑定时作标签,换 token 不涉及。

2) 请求约定

  • base URL:优先级为 scripts/config.json 的 baseUrl(skill 本地指定)> 环境变量 ${HHD_BASE_URL} > 默认 http://localhost:8082/dzkjdap。所有工具端点挂在 /api/agent/form/* 下。
  • 认证头:X-Access-Token: <用户令牌/JWT>(必要)。
  • 租户头:X-Tenant-Id: <租户ID>(多租户环境必要,取值与用户绑定的租户一致,同浏览器登录请求)。
  • Content-Type:application/json。

> 多租户说明:X-Tenant-Id 与当前用户所属租户必须匹配,否则数据源/数据权限会错租户。若不确定租户 ID,可在登录请求的响应或用户信息接口取;skills 里应把它也放进环境变量(如 HHD_TENANT_ID)一并传递。
> 绑定/换取流程换到的 token 即 X-Access-Token,返回的 tenantId 即应作为 X-Tenant-Id 附带(单体版可为空)。

3) 验证登录

调 POST /api/agent/form/tools 能成功返回工具列表,即令牌有效;返回"未认证"则用 bindSecret 重新 exchange(或检查 bindSecret 是否仍有效/key 是否泄露需重新绑定)。


二、可用工具

工具端点:POST /api/agent/form/call,body:{ "name": "<工具名>", "arguments": { ... } }。
先用 POST /api/agent/form/tools 拉取每个工具的最新参数 schema(本文件为概要)。

工具 用途 关键参数
get_form_definition 取表单结构 schema(字段必填配置在 actions[].fieldActions[].required,按 fieldId 对应、按 actionId 区分动作) formDefinitionId
get_form_definition_by_key 按 key 取结构 key
load_manual_auth 字段级编辑权限 formDefinitionId
init_form_data 算默认值/初始化 formDefinitionId, actionId?
check_rules 校验(dry-run),返回 {rules:规则/唯一性校验, required:必填校验} formDefinitionId, formModel{field:value}, actionId?
load_form_data 加载一条单据数据 id(单据数据主键 formDataId,不是流程/待办行 id), formDefinitionId
form_menu_search 通用查单(菜单维度)。userConditions[] 每项 {fieldName, fieldValue, condition, joinType}:condition 仅支持 like/notLike/equal/notEqual/great/greatEqual/less/lessEqual/in/isNull(范围用 greatEqual+lessEqual 两条);fieldName 用 get_form_definition 里 fields[].fieldName(不要用字段的 id/modelFieldName);joinType 用小写 and/or。「待发/已发/待办/已办」类菜单会自动按菜单类型返回对应范围数据,无需再手工按流程状态过滤 formMenuId, userConditions[], page{current,pageSize}
list_my_flow_templates 可发起的流程 businessSpaceId?
submit_form 一次性保存/提交表单(⚠️ 全量语义:formData 没传的字段会被清空(含流程状态字段)、需 _auth 副字段、不触发字段联动/子表/关联;普通填单请用会话语;修改已有单据用 agent_form_update_data) formData{field:value}, formDefinitionId, triggerEnable?
start_flow 一次性发起流程(⚠️ 同上:不触发联动/关联;优先用会话语 start_session→...→submit) formData, formDefinitionId, flowId
preview_flow 一次性发起前预检(dry-run),同 start_flow 同 start_flow
agent_form_update_data 【修改已有单据】patch 语义更新(含已完结流程单据回填):后端自动保留系统状态字段,只传变更字段即可,漏传不会清空。修改已完结单据前先向用户确认 formDataId, formDefinitionId, formDataPatch{field:value}, actionId?

协作中心(个人全局维度:我的待办/已办/待发/已发)

工具 用途 关键参数
list_my_todo 我的待办(全局,含 formId/pcView/pcAction/actionAuth,可直接打开审批单) pageNo?, pageSize?, businessSpaceId?
list_my_done 我的已办(附当前审批人/流程历史) 同上
list_my_wait_send 我的待发/草稿(save/toForm/withdraw) 同上, formDefinitionId?
list_my_sent 我的已发(running/approve/end,附当前审批人)。⚠️ 行的 id 是已发记录主键,formDataId 才是单据数据 id(要加载单据用 formDataId) 同上, formDefinitionId?
list_my_todos 按菜单查待办(需 formMenuId),与全局 list_my_todo 区分 formMenuId(必填), userConditions[]
list_my_menus 当前用户授权应用/菜单树(业务列表页节点带 formMenuId/flowId) businessSpaceId?(可选)

> 说明:全局待办请用 list_my_todo;list_my_todos 是"某个表单菜单(formMenu)内的待办查询",二者不同。

单位(查询 / 切换账号当前单位)

工具 用途 关键参数
list_my_departs 查询当前账号所有可用单位,返回 [{id, orgCode, departName, current}](current 为当前所在单位)。用户想换单位操作时,先查本工具拿可选单位 keyword?
switch_depart 把当前账号的单位切到目标单位(orgCode 取自 list_my_departs)。⚠️ 账号级全局生效,等价 Web 端顶栏切换单位:菜单、数据权限、以及该账号后续触发的定时自动化任务都按新单位解析,且 Web 该账号下次登录也在新单位——属全局操作,执行前先与用户确认目标单位 orgCode(必填)

会话语工具(推荐发起路径:与人工在页面上提单的行为一致,带逐字段联动)

工具 用途 关键参数
agent_form_start_session 打开单据建会话:不传 formDataId 新建空单;传 formDataId 编辑已有单据(无流程表直接编辑;流程表仅草稿态可编辑,见「编辑已有单据」SOP);传 flowUserTaskId 建审批会话(见「审批时补充字段后审批」SOP),与 formDataId 互斥 formDefinitionId, actionId, flowId?, formDataId?, flowUserTaskId?
agent_form_set_field 设单字段+触发联动 sessionId, fieldName, value, rowId?
agent_form_patch_form 批量设字段+一次联动。主表字段 {fieldName:value};子表新增/整表替换传 {子表字段:[{字段:值}]},新增行不传 id(系统自动分配行 id,从返回 formModel 里取行 id 供后续 rowId 用),更新已有行带原行 id sessionId, formDataPatch
agent_form_remove_sub_row 【子表删行】删除子表中的一行(误加行纠错),返回更新后的 formModel sessionId, subFormId(get_form_definition 里 subForms[].id), rowId(该行 id)
agent_form_prepare_submit 提交前 dry-run,返回 {rules, required, preStart}:rules 规则/唯一性校验、required 必填校验、preStart 预启动(含待选人)。以校验结果为准:通过即可提交,无需再向用户确认必填情况;仅当报错时才让用户补充/修正 sessionId, remark?
agent_form_submit 【仅流程表】正式发起流程(提交),发起成功生成待办。无流程表不要用 sessionId, remark?, userManualSelect?
agent_form_save_data 【无流程表专用】保存并落库,新增/保存(提交即保存),非草稿、非流程。成功返回 formDataId sessionId, remark?
agent_form_save_draft 保存会话数据为草稿:流程表暂存草稿用;无流程表请用 agent_form_save_data。成功返回 formDataId;保存后在同一会话继续编辑再 submit 即可 sessionId, remark?
agent_form_delete_draft 【删除草稿】删除一条「待提交」状态的草稿单据(flowStatus=save 且未发起流程,否则拒绝删除)。formDataId 取 list_my_wait_send 返回行的 formDataId(不是行主键 id)。删除前先向用户确认 formDataId, formDefinitionId
agent_form_get_dict 取字典项 dictCode, dictType?
agent_form_upload_attachment 【附件上传】上传一个文件返回 attachmentId(返回 {id, originName, fileSize, ext})。⚠️ 文件内容由宿主从用户本地文件读取后以 base64 填入 contentBase64,LLM 不要自行生成/转码字节。单文件解码后上限 20MB;更大文件由脚本走 multipart 端点 fileName(含扩展名), contentBase64
agent_form_attach_file 把已上传附件(attachmentId)绑定到附件字段 sessionId, fieldName, attachmentIds[], rowId?
agent_form_get_attachment 按 attachmentId 获取附件元信息+可打开的 downloadUrl(预览/下载) attachmentId
agent_form_query_relation_candidates 查手动关联(关联选择)的候选列表。返回 records(键为目标表字段 id)+ columns([{fieldId,label}] 列说明,用于解读 records)。候选多时传 searchKey 按该关联配置的可搜索字段模糊过滤 sessionId, manualId, searchKey?, relationId?, rowId?, pageNo?/pageSize?
agent_form_select_relation 把选中候选交给后端 → 按 fieldBinds 带出+写 _relation。行级关联(按钮在明细表/manualSelectorType=2,或 fieldBinds.sourceFormId 指向子表)必传 rowId(目标子表行 id,新行先用 patch_form 建行取行 id);带出字段全在主表的关联不要传 rowId sessionId, manualId, relationData(单选)或relationDataArray(多选), rowId?, actionId?, targetFormDefinitionId?
agent_form_clear_relation 清空已带出的关联映射字段 sessionId, manualId, rowId?

> 附件上传有两条等价路径,按接入形态选择:
> - MCP/宿主形态(方式 A):用 agent_form_upload_attachment(fileName, contentBase64) —— 文件内容由宿主从用户本地文件读取后 base64 编码填入,LLM 不要自行生成/转码字节。返回 {id, ...} 即 attachmentId。单文件解码后上限 20MB。
> - 脚本形态(方式 B):用 multipart POST /form/attachment/upload(字段名 file,带 X-Access-Token/X-Tenant-Id,见 agent.mjs upload / tools/upload-attachment.sh),返回 result.id 即 attachmentId。无 20MB 限制,大文件走这条。
>
> 拿到 attachmentId 后:附件字段(get_form_definition 里 component=uploadFile)用 agent_form_attach_file 绑定,随提交落库。详见「填单带附件」SOP。
> 图片字段:component=picture 的字段值本身就是 attachmentId,上传拿 id 后直接 agent_form_set_field(sessionId, fieldName, attachmentId) 即可(不用 attach_file)。
> 预览/下载:agent_form_get_attachment(attachmentId) 返回带 token/租户的 downloadUrl,宿主持它在用户本地打开即可预览或下载(同前端 PictureField 拼 URL 的方式)。入参兼容:附件主键 id(图片字段的值、load_form_data 返回的 _attachment.attachments[].id)、或附件字段的字段值(32 位槽位 key,此时返回该字段挂载的全部附件数组)。
> ⚠️ 附件字段的字段值是 32 位槽位 key(fieldValue,与前端语义一致),真实附件关系在 _attachment.attachmentRelations——不要用 set_field/agent_form_update_data 手改附件字段值(会把槽位改坏导致附件解析不到、提交后"丢"附件);换附件走会话:上传新文件 → agent_form_attach_file。

审批处理工具(处理待办审批时用)

工具 用途 关键参数
agent_form_load_todo 打开一张待办(加载单据数据提醒) flowUserTaskId(将 list_my_todo 返回的待办行 id)
agent_form_pre_complete 审批前 dry-run 预检(返回待选人 userManualSelect) flowUserTaskId, formModel, comment?
agent_form_approve 审批通过(同意,进入下一节点)。补字段场景传 sessionId(审批会话,formModel 随审批落库);纯审批传 flowUserTaskId+formModel sessionId?, flowUserTaskId?, formModel?, comment?, userManualSelect?
agent_form_reject 审批不通过(终止流程)。同样支持 sessionId(审批会话) sessionId?, flowUserTaskId?, formModel?, comment?
agent_form_to_form 回退到发起人(toForm) flowUserTaskId, formModel, comment?
agent_form_withdraw 撤回已发流程(发起人) processInstanceId, comment?

进阶审批工具(退回指定节点/转交/加签/知会/减签)

工具 用途 关键参数
agent_form_to_node_candidates 查询可回退节点(拿 selectedNodeId) flowUserTaskId
agent_form_to_node 退回指定节点 flowUserTaskId, selectedNodeId, formModel, comment?
agent_form_transfer 转交给指定用户 flowUserTaskId, userId, username, comment?
agent_form_count_sign 加签(添加会签人) flowUserTaskId, userTask, comment?
agent_form_notify 知会/抄送(用户/部门/角色) flowUserTaskId, userConfigs[], comment?
agent_form_subtract_sign_candidates 查询可减签节点(拿 userTaskId) flowUserTaskId
agent_form_subtract_sign 减签(移除某节点会签人) flowUserTaskId, userTaskId

统计报表取数(执行已保存的统计/关联查询,只读)

> 报表 id(singleStatId/queryId)不知道时:用 xj-form-designer skill 的 list_single_stats/list_form_queries 按关键词查询,或直接让用户提供报表名称/在平台「报表」页签查看。报表的创建与修改也在 xj-form-designer skill,本节只负责执行取数。

工具 用途 关键参数
search_single_stat 执行已保存的单表统计(实体统计),返回分页统计结果(列头摘要 + records + total) singleStatId, pageNo?(默认1), pageSize?(默认50), conditions?([{label, value}] 按报表筛选列 label 传值)
search_form_query 执行已保存的关联查询,返回分页结果。⚠️ 当前仅支持 join(queryType=relation)类型;数据合并(merge)类型执行返回「暂不支持」——平台运行时链路尚未开放 merge,报错时如实告知用户 queryId, pageNo?, pageSize?, conditions?([{label, value}]), orderLabel?, orderType?(asc|desc)
search_stat_records 统计下钻:按条件返回命中统计的原始单据记录(穿透)。部分场景可能不支持(报错时如实告知用户并建议到平台报表页查看) singleStatId, conditions?([{label, value}]), pageNo?, pageSize?

通用调用模板(带认证)

curl -X POST "$HHD_BASE_URL/api/agent/form/call" \
  -H "X-Access-Token: $HHD_AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "get_form_definition",
        "arguments": { "formDefinitionId": "<表单定义ID>" }
      }'

三、典型 SOP

发起一个流程(推荐:会话语路径)

  1. list_my_flow_templates → 找到目标流程的 flowId(=id)、formDefinitionId(=formType)、actionId(如需)。
  2. agent_form_start_session(formDefinitionId, actionId, flowId) → 后端初始化空单,返回 sessionId。
  3. get_form_definition(或会话返回字段)→ 确认字段名;同时扫描 relations[]:凡有 relationType==='manual' 的关联,把"挂靠/带出字段"标记出来(方法见「带出关联字段」)。
  4. 凡字段是关联带出字段(被某 manual 的 fieldBinds.sourceFieldId 引用,或挂靠了选择按钮),一律走「查候选 → 选候选 → apply 后端返回值」,绝不把文本/数值直接 set_field/patch_form 塞给它。 只有当确认字段不是关联带出字段时,才正常直接填。
  5. 逐字段 agent_form_set_field(sessionId, fieldName, value)(每次触发联动,自动带出关联字段);批量用 agent_form_patch_form。
  6. 填子表(明细):agent_form_patch_form(sessionId, { <子表字段>: [ { <字段>: 值, ... } ] })——新增行不传 id(系统自动分配行 id,从返回 formModel 里取),整表替换该子表;行带原 id 才是更新已有行。删行用 agent_form_remove_sub_row。
  7. agent_form_prepare_submit(sessionId, remark?) → dry-run 校验 + 预启动;以校验结果为准,通过即可提交;rules/required 报错时才让用户补充/修正。
  8. agent_form_submit(sessionId, remark?, userManualSelect?) → 正式发起(userManualSelect 取 prepare_submit 预启动的选人结果,若有)。
  9. 向用户反馈发起结果(单号/待办)。

> 说明:会话语工具与人工在页面上提单的行为一致(含校验、关联带出),比一次性 start_flow 更可靠。一次性 start_flow(formData,...) 仍可用(不触发联动)。

无流程表:直接新增 / 保存(hasFlow=false,不发起审批)

> 表单分两类:流程表(hasFlow=true,填单后走审批)和无流程表(hasFlow=false,填好就保存、没有审批流程)。get_form_definition 返回的 hasFlow=false 即无流程表。无流程表新增/保存(提交即保存)不走"发起流程"。注意:无流程表同样可能配置字段联动(autoRelation)、子表、关联选择,这些照常要检查、要处理,处理方式与流程表完全一致(见「填子表」「带出关联字段」「发起一个流程」各节)。

  • 会话语(推荐,唯一能触发联动/子表/关联的保存方式):
    1. agent_form_start_session(formDefinitionId, actionId)——不传 flowId(无流程表没有 flow)。
    2. agent_form_set_field / agent_form_patch_form 逐字段填写——每次都会触发字段联动(autoRelation 自动带出);子表用 patch_form 传数组;关联选择用 query_relation_candidates / select_relation(照「带出关联字段」 SOP)。
    3. agent_form_save_data 保存落库(新增/保存即落表单数据,非草稿、非流程)。
  • ⚠️ 不要用 agent_form_submit:无流程表没有审批流程,会报"没有找到流程"。无流程表保存一律用 agent_form_save_data(把下面各 SOP 里收尾的 agent_form_submit 换成它)。
  • 无流程表的新增/保存就这一条路径(会话语 + agent_form_save_data)。submit_form/start_flow 是一次性、不触发联动/子表/关联、还要自己拼 _auth,普通填单不要用(见工具表说明)。
  • 保存后单据出现在该无流程表的业务列表里,可用 form_menu_search 反查。

编辑已有单据(会话语 + formDataId,推荐)

> 场景:修改一张已存在的单据——无流程表的存量数据、流程表的草稿/暂存单、被撤回/被退回(回退到发起人)的单。编辑后可继续保存或重新发起。

  1. form_menu_search / load_form_data / list_my_wait_send 定位目标单据,拿到 formDataId(是单据数据 id,不是列表行主键/流程 id)。
  2. agent_form_start_session(formDefinitionId, actionId, flowId?, formDataId) → 返回的 formModel 即库中数据(含 _attachment/_relation 等副结构),editingExisting=true。
    - 守卫(系统强制):无流程表直接放行;流程表仅草稿态可编辑(暂存/撤回/回退后的单 processInstanceId 已清空),流程进行中或已结束的单据会直接报错拒绝。
    - 流程表编辑后要重新发起,flowId 要照常传(草稿里虽有原 flowId,显式传更稳)。
  3. 之后与新建完全一致:set_field/patch_form(触发联动)、子表整表替换、query_relation_candidates/select_relation 带出关联、attach_file 换附件。
  4. 收尾:流程表 prepare_submit → agent_form_submit(对原单重新发起流程);无流程表 agent_form_save_data;想继续留草稿就 agent_form_save_draft(更新原草稿,不会新增脏数据)。

> ⚠️ 替换附件字段的正确路径就是这个:开会话(传 formDataId)→ 上传新文件拿 attachmentId → agent_form_attach_file(sessionId, fieldName, [新 attachmentId]) → 保存/提交。不要用 agent_form_update_data 直接改附件字段值——那只改字段值不建关联行,页面附件会静默消失。
> ⚠️ 一次性 agent_form_update_data(下方 SOP)仍适合"已完结/进行中单据回填个别文本字段",但它改不了附件/关联;两者按场景选择。

流程表单字段回填(修改已完结/进行中的已有单据)

> 场景:往一张已存在的单据(含流程已结束的)回填/修正个别字段,如"把 AI 评估意见写回问题跟踪单"。

  1. form_menu_search / load_form_data 定位目标单据,拿到 formDataId;确认要改的 fieldName。
  2. 向用户确认要写入的内容(修改已完结单据属敏感操作)。
  3. agent_form_update_data({ formDataId, formDefinitionId, formDataPatch: { <fieldName>: <值> } }) —— 后端加载库中完整数据、自动保留 flowStatus/processInstanceId/_auth/附件等系统字段,只合并你传的变更字段。
  4. load_form_data 复查确认变更落库、流程状态未被破坏。

> ⚠️ 不要用 submit_form 做这件事:它是全量语义,formData 里没传的字段(含 flowStatus/processInstanceId 等流程状态)会被清空,曾导致单据流程状态丢失。如果平台只有 submit_form 可用(旧版本),必须传 load_form_data 拉到的完整原始 formModel(原样保留全部系统字段),只修改目标字段,且改完后复查流程状态。
> ⚠️ 大 payload(含 base64 附件等)不要走命令行 --args:用 agent.mjs call --name <工具名> --args-file <json路径> 或 cat payload.json | agent.mjs call --name <工具名>。

填单带附件(重要:附件不靠 LLM 搬字节)

  1. 用 get_form_definition(或会话返回字段)找出 component=uploadFile 的附件字段 fieldName。
  2. 上传(宿主/脚本做,LLM 不搬字节),按接入形态二选一:
    - MCP/宿主形态:agent_form_upload_attachment({ fileName: "<含扩展名>", contentBase64: "<宿主读用户本地文件后 base64>" }) → 返回 {id} = attachmentId;
    - 脚本形态:把真实文件用 multipart 调用 POST /form/attachment/upload(curl -F "file=@<路径>",带 X-Access-Token/X-Tenant-Id),返回 result.id = attachmentId。
  3. agent_form_attach_file(sessionId, fieldName, [attachmentId]) → 绑定到附件字段,随提交落库。
  4. 其余字段照常 set_field/patch_form,最后 submit,附件随单落库。
    > 注意:不要试图把文件 base64/字节塞进 formModel 或 patch 里;附件必须先上传(agent_form_upload_attachment 或 multipart 端点)拿到 attachmentId 后以 id 引用。

填单带图片(component=picture)

  • 图片字段的字段值 = attachmentId(单个)。上传拿 id 后直接 agent_form_set_field(sessionId, fieldName, attachmentId),无需 attach_file。

带出关联字段(关联选择)

> 业务表单常见"关联选择"按钮:如报销单里点「选择发票」→ 系统从发票单带出发票编号/金额。其定义在表单定义的 relations 字段(relationType==='manual'),本质是"查候选列表 → 选一行 → 系统把目标字段回填到当前表单"。详见 references/relation-select.md(含 relations 结构说明)。

判别:get_form_definition 返回的 relations[] 里 enable===true && relationType==='manual' 的项即关联选择按钮。auto 类型由后端字段变更自动带出,Agent 无需处理(set_field 已触发)。

> ⚠️ 硬性规则:某字段命中某 manual 的 manualSelectorFieldId,或被其任一 fieldBinds[].sourceFieldId 引用,它就是一个"关联带出字段"。凡是这类字段——即使用户给的值看起来能直接写——一律走「查候选 → 选候选 → apply 后端返回值」。绝不把文本/数值直接 set_field/patch_form 塞进去(那样没有 _relation、带出字段/联动不生效、无法穿透回看)。

SOP(推荐会话语路径)
1. agent_form_start_session 开单 → 拿 sessionId。
2. get_form_definition 解析 relations:找到目标 manual(如选发票),记下 manualId、挂靠字段 manualSelectorFieldId、fieldBinds(sourceFieldId→目标表单 targetFieldId)。
3. agent_form_query_relation_candidates(sessionId, manualId, searchKey?, pageNo?, pageSize?) → 候选列表(发票,已过滤数据权限/公式)。候选多时传 searchKey 模糊过滤;用返回的 columns(fieldId→中文标签)解读 records。
4. 挑一条候选,把选中的候选数据作为 relationData(整行或其中被选的那一字段值均可)调 agent_form_select_relation(sessionId, manualId, relationData, rowId?)。
5. 用 select_relation 返回的更新后字段(被带出的发票编号/金额等,后端已写 _relation)→ 向用户回显确认。不要用自己拼的值。
6. 继续填其余字段 → agent_form_prepare_submit 预检 → 流程表 agent_form_submit;无流程表 agent_form_save_data;关联数据随单落库可穿透回看。

用户给的值不在关联可选项里(候选不匹配)怎么处理
- 先判断目标字段身份:它到底是不是关联带出字段?
- 不是(不在任何 manual 的 fieldBinds.sourceFieldId、也不是 manualSelectorFieldId,例如"事由/备注/自填金额"):这就是普通字段,直接 set_field/patch_form 正常填,不用查关联。很多"不知道填哪"其实是这一步没分清楚。
- 是:见下。
- 是关联带出字段,但用户想要的值在候选里没有匹配:
- query_relation_candidates 拿到候选后,若候选里有用户指的那张票据/单据(如用户点名了发票号/供应商名),就选中它走 select_relation,带出的值以该候选为准——即使带出的金额/编号和用户随口说的不完全一样,也该以所选单据为准并告知用户。
- 候选里确实没有匹配的单据:看该 manual 的 manualEditTargetField——
- false/未开(该字段只能由关联决定,不允许手填):不要编造值硬填,如实告知用户「<字段> 必须通过选择 <关联>(XXXX)带出,当前候选里没有 <期望值> 的单据」,并把候选可选值列出来让用户挑 / 请用户提供正确的单据。
- true(允许手改):仍先走关联带出保住 _relation,再按需 set_field 覆写成用户期望的值。

  • 行级关联:manualSelectorType=2 或 fieldBinds 的 sourceFormId 指向子表时,select_relation 要传目标子表行的 rowId;候选查询同理。
  • 多选:manual 支持多选且发票多张时,传 relationDataArray 再 select_relation。
  • 不要绕过工具:关联操作一律通过上述会话工具完成,不要直连平台内部接口或自行拼值绕过(会丢失关联记录、校验不生效)。

预览 / 下载附件给用户

  • 需要让用户在本地看某个附件/图片:agent_form_get_attachment(attachmentId) → 拿到 downloadUrl,把 URL 交给宿主/浏览器直接打开即预览,或下载到本地。
  • attachmentId 来源:图片字段的值、load_form_data 返回的 _attachment.attachments[].id、上传(agent_form_upload_attachment 的 id / multipart 的 result.id)。

脚本方式(推荐:统一 .mjs 入口,跨会话复用 bindSecret)

skill 包内 scripts/agent.mjs(Node,无依赖,Node 18+)是首选执行入口,自动完成"读 bindSecret → exchange 换 token+租户 → 调接口"。bindSecret 加密存于 .auth/binding.json,新会话直接复用,不丢失。

# 首次:用 bindSecret 换取并持久化(之后任何会话无需再给 bindSecret)
node scripts/agent.mjs auth <bindSecret>

# 之后每次操作(mjs 自动用本地 bindSecret 换 token)
node scripts/agent.mjs call --name list_my_todo --args '{"pageSize":5}'
node scripts/agent.mjs get "/form/queryByMenuId?formMenuId=<id>"                  # 查询类端点(路径里 __token__ 替换为当前 token)
node scripts/agent.mjs post "/form/formMenu/search" --data '{"formMenuId":"<id>","page":{"current":1,"pageSize":20}}'   # 直连 POST 查询端点(带 token/租户)
node scripts/agent.mjs tools --full                               # 列工具(带完整参数 Schema;不带 --full 只有名字)
node scripts/agent.mjs upload ./发票.pdf                          # 上传 → attachmentId
node scripts/agent.mjs download <attachmentId> ./本地.pdf          # 下载/预览
node scripts/agent.mjs attach --session <id> --field <fieldName> --attachment <id>
node scripts/agent.mjs status                                      # 看是否已绑定(不泄露凭证)
  • 环境变量:HHD_BASE_URL(优先级低于 scripts/config.json 的 baseUrl;默认 http://localhost:8082/dzkjdap)、HHD_BIND_SECRET(也可直接设它,跳过 auth)。
  • 若宿主不便跑 Node,可用 tools/*.sh(exchange-token.sh / upload-attachment.sh / download-attachment.sh)作为等价替代。
  • MCP/连接器形态(方式 A)不走上述任何本地脚本:上传用 agent_form_upload_attachment(base64,宿主填内容),下载用 agent_form_get_attachment 返回的 downloadUrl。

处理一张待办(审批)

  1. list_my_todo → 拿到目标待办的 id(= flowUserTaskId)、pcView/pcAction、actionAuth(注意:是待办行的 id,不是 taskInstanceId)。
  2. agent_form_load_todo(flowUserTaskId) → 加载单据,返回 formModel + viewId/actionId(后端按该待办实例取视图)。
  3. (可选)纯文本/数值类小改动可直接改写 formModel 回传。
  4. 通过:agent_form_pre_complete 预检 → 拿到待选人 userManualSelect(若有)→ agent_form_approve。
    不通过:agent_form_reject;回退发起人:agent_form_to_form。
  5. 进阶动作(如需):agent_form_to_node(退回指定节点,先 to_node_candidates 拿节点)/ agent_form_transfer(转交)/ agent_form_count_sign(加签)/ agent_form_notify(知会)/ agent_form_subtract_sign(减签,先 subtract_sign_candidates 拿节点)。
  6. 向用户反馈审批结果。
    > 审批是单步无状态动作,不需会话;flowUserTaskId 取自 list_my_todo 返回待办行的 id(不是 taskInstanceId)。

审批时补充字段后审批(审批会话,推荐)

> 场景:审批人打开待办后需要补充/修正字段(各种类型:普通字段、子表、关联选择、附件等),再点审核通过。字段较多或涉及关联/附件时必须走会话,否则联动不触发、关联/附件落不了库。

  1. list_my_todo → 拿到 flowUserTaskId(待办行 id)。
  2. agent_form_start_session(flowUserTaskId) → 建审批会话:返回待办的 formModel,动作/视图自动取审批节点的 pcAction/pcView(审批节点的字段权限),返回 approvalTask=true。
  3. 补充字段——与填单 SOP 完全一致:agent_form_set_field / agent_form_patch_form(触发联动)、子表用 patch_form 传数组、关联选择走 query_relation_candidates / select_relation(照「带出关联字段」SOP)、附件走 agent_form_upload_attachment(或脚本 multipart)+ agent_form_attach_file。
  4. 提交审批:agent_form_approve(sessionId, comment?, userManualSelect?) → 以会话当前 formModel 随审批落库并推进流程;不通过则 agent_form_reject(sessionId, comment)(formModel 同样落库)。
    - 也可先 agent_form_pre_complete(flowUserTaskId, formModel) 预检拿待选人。
  5. 成功后会话自动销毁;失败保留会话可修正重试。
    > ⚠️ 审批会话不支持 save_draft/save_data/submit/prepare_submit——运行中的单据不允许绕过审批单独落库,提交一律走 approve/reject(会报错提示)。
    > ⚠️ flowUserTaskId 与 formDataId 互斥;审批会话返回的 formModel 已带单据 id,approve 时按原单更新,不会新增数据。

查待办 / 已办 / 待发 / 已发

  • 全局个人维度:list_my_todo(待办)、list_my_done(已办)、list_my_wait_send(待发/草稿)、list_my_sent(已发)。
  • 每条待办 Record 带 formId/formTypeId/pcView/pcAction/actionAuth,可直接用这些定位并打开审批单。
  • 按表单菜单查待办用 list_my_todos(formMenuId, ...);通用查单用 form_menu_search(formMenuId, userConditions)。
  • 要加载/打开某条已发/查到的单据详情:load_form_data(formDataId, formDefinitionId)。formDataId 取自返回行的 formDataId 字段——list_my_sent / 已发记录的 id 是"已发记录主键"、form_menu_search 返回的 id 才是单据数据主键,都别和流程/待办 id 混。
  • 结果只含该用户数据权限内的数据,异常情况如实告知用户,不要静默降权。

枚举我的授权应用 / 菜单(业务列表页)

> 用于"我有权限看哪些列表/进这个列表查数据"。直接用 list_my_menus 工具(按当前用户授权返回菜单树),无需解析菜单地址。详见 references/authorized-menus.md。

  1. 调 list_my_menus → 返回 result.menus(应用→子菜单嵌套树)。业务列表页节点:type=form_menu,带 formMenuId(可直接查数)与 title;type=flow_menu 带 flowId;type=form_query 带 formQueryId;其余 folder 为目录/分组。
  2. 把"应用 → 里面的业务列表页(formMenuId)"整理给用户;用户指定进哪个后:
    - 查该列表数据:form_menu_search({ formMenuId, page, userConditions? });
    - 该菜单待办:list_my_todos(formMenuId);
    - 某条详情/编辑:load_form_data(id, formDefinitionId)。
  3. 只报授权内的;无权限的列表页不编造,如实告知。

执行统计报表取数(查统计结果 / 关联查询 / 下钻)

> 场景:用户要看某个已保存统计报表的数据("跑一下部门报销统计""这份关联查询出个结果""下钻看原始单据")。报表的创建/修改归 xj-form-designer skill;这里只执行取数。

  1. 拿报表 id:用户报得出 id 就直接用;报不出时用 xj-form-designer skill 的 list_single_stats(appId, keyword?) / list_form_queries(appId, keyword?) 按名称搜(返回 id/statTitle/queryTitle),列候选让用户选;两边都拿不到就引导用户到平台「报表」页签确认。不要编造 id。
  2. 执行:
    - 单表统计:search_single_stat({ singleStatId, conditions?, pageNo?, pageSize? })。
    - 关联查询(join 类型):search_form_query({ queryId, conditions?, orderLabel?, orderType? })。⚠️ 数据合并(merge)类型暂不支持执行(平台运行时链路未开放)。
    - conditions 按报表筛选列的 label 传值(如 [{ "label": "报销日期", "value": "..." }]);不确定报表有哪些筛选列时先不传 conditions 跑全量,或向用户确认过滤条件。
  3. 解读返回:返回为裁剪后的 列头摘要 + records + total(不回传内部字段 id)。把列头名与数值整理成表格/要点向用户汇报;total 超过单页条数时翻页(pageNo)或按用户口径加 conditions 收窄。
  4. 下钻:用户要看某组数字背后的原始单据 → search_stat_records({ singleStatId, conditions? }),把命中的原始单据记录(单号/金额/日期等)呈现给用户。
  5. 结果只含当前绑定用户数据权限内的数据;查不到/报错如实反馈,不编造数据。

四、权限与安全边界(必读)

  • 每个工具都绑定到发起用户的系统账号;数据权限、字段级 auth 由后端基于该用户判定。
  • 不要尝试:越权查询他人数据、绕过 check_rules、向未认证端点裸调。
  • 令牌属于敏感凭证,不要在日志/代码仓库明文暴露,优先用环境变量。
  • 如遇"未认证 / 越权",如实反馈并提示用户检查 bindSecret 是否有效(或用 bindSecret 重新 exchange),不自行降权绕过。

已知约束(联调记录)

  • 读类工具(get_form_definition / load_manual_auth / load_form_data / form_menu_search / list_my_todos / list_my_flow_templates / list_my_todo / list_my_done / list_my_wait_send / list_my_sent)已联调通过,只读 success=true。
  • 写/校验类工具(init_form_data / check_rules / submit_form / start_flow / preview_flow)需要 actionId + 完整 formModel(含 _auth 副字段);只传 formDefinitionId 或空 formModel 会报错。正确用法:先 get_form_definition 拿动作/字段,用真实 actionId 与按字段构造的 model 再调。这些待用真实单据样本校准后,再在文档补示例。
  • 审批类工具(agent_form_load_todo / agent_form_pre_complete / agent_form_approve / agent_form_reject / agent_form_to_form / agent_form_withdraw)已实现并经真实单验证通过。flowUserTaskId = list_my_todo 待办行的 id(已实测)。
  • 进阶审批工具(agent_form_to_node_candidates / agent_form_to_node / agent_form_transfer / agent_form_count_sign / agent_form_notify / agent_form_subtract_sign_candidates / agent_form_subtract_sign)已实现,待联调校准:用真实待办样本走一遍候选查询→执行后,再补示例。
  • 关联选择(manual relation,如选发票带出字段):agent_form_query_relation_candidates(sessionId, manualId) 查候选 → agent_form_select_relation(sessionId, manualId, relationData, rowId?) 带出;清空用 agent_form_clear_relation(sessionId, manualId, rowId?)。子表关联时 rowId 传对应明细行。详见 §三「带出关联字段」。
  • 草稿保存 → 提交:agent_form_save_draft 保存成功后返回 formDataId,之后继续在同一会话内编辑并 agent_form_submit 即可,无需重新开会话。若提交时报重复数据类错误,说明当前会话状态已不可用,放弃该会话重新发起,不要在同一会话反复重试提交。

五、接入调试

连不上/参数报错时按顺序检查:
1. scripts/config.json 的 baseUrl / HHD_BASE_URL 是否设置、后端是否可达。
2. X-Access-Token 是否正确粘贴。
3. 用 /tools 核对工具名与参数 schema 是否与文档一致。
4. 看后端响应 { success, message, code } 的 message。


六、配套文件

  • tools/example-calls.sh:各工具带认证的 curl 调用示例。
  • scripts/agent.mjs:首选执行入口——bindSecret 换 token + call/get/upload/download/attach 统一命令(get 调查询类端点,__token__ 自动替换),bindSecret 加密持久化跨会话复用。
  • tools/exchange-token.sh:bindSecret 换 token + 租户(export 到 shell,等价替代)。
  • tools/upload-attachment.sh:附件 multipart 上传,输出 attachmentId。
  • tools/download-attachment.sh:附件下载/预览(存文件或 stdout)。
  • references/form-schema-example.json:迅捷应用平台表单 schema 结构示例(与 get_form_definition 返回对齐),便于理解 formData / formModel 怎么组织。
  • references/relation-select.md:relations 字段结构与「关联选择(选单带出字段)」的完整说明(三类型、fieldBinds 映射语义、会话工具用法)。
  • references/authorized-menus.md:list_my_menus 返回的授权菜单树结构、识别业务列表页并提取 formMenuId 的方法。

常见问题

5 问
答案由本站依据条目字段整理
迅捷应用平台怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_e1d46ddd/xj-form-agent。安装方式为未标注。装完刷新技能列表或重开客户端。

迅捷应用平台支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

迅捷应用平台权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

迅捷应用平台收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

迅捷应用平台用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。