SEAL_DEPLOYMENT.md 8.4 KB

审批印章模块部署说明

新增模块的接口地址为:

POST /api/changguchuan/seal/approval-complete
GET  /api/changguchuan/seal/health

按审批记录生成个人时间戳印章

新增接口:POST /api/changguchuan/seal/approval-records。只需传业务表单的宜搭数据 ID,不需要传审批人、审批时间、节点或模板 URL:

{
  "formInstanceId": "FINST-实际业务数据ID"
}

也支持 query 参数 formInstanceId,以及 formInstId、instanceId、processInstanceId 同义字段。 如果已设置 SEAL_CONNECTOR_TOKEN,同样需要请求头 X-Seal-Connector-Token。

处理范围固定为以下用户指定的表单和字段:

用途 表单 / 字段
业务审批表单 FORM-64A9D5065C234383AB2ACF7AB4F20975DW6M
审批人个人模板表单 FORM-EADCA8349AB34236A8873ECA7BCFBE7CDMG4
模板人员字段 employeeField_mv7hjsv3,按审批人的钉钉 userId 精确匹配
模板图片字段 imageField_mubc5ugk
回写子表 tableField_mv7h9ypq
子表节点名称 textField_mv7h9yps
子表时间戳印章 imageField_mv7h9ypr,图片对象数组

接口先通过 v2.0 流程实例详情取得真实 processInstanceId 并验证所属表单,再通过 GetOperationRecords(/v1.0/yida/processes/operationRecords)获取审批历史。 会签 domainList 会展开为每个实际审批人;同意及拒绝/驳回记录均保留,并在返回值中标明 approvalAction。提交、抄送、转交和待审批记录不会盖章。同一人在不同节点或重新审批时 分别保留,只有完全相同的任务、人员、时间、节点和动作才去重,结果按实际审批时间升序排列。

图片使用该审批人的模板,日期和时分秒分两行绘制(yyyy-MM-dd / HH:mm:ss),默认时区 Asia/Shanghai。带时区时间和 Unix 时间戳先转换至配置时区,无偏移的时间文本按配置时区 解读。审批时间缺失或无法解析会报错,不使用服务器当前日期代替。

所有图片生成成功后,通过流程 UpdateInstance 一次性回写完整子表,仅提交该子表字段。 这会替换指定子表的原有行,而不是追加;请将该子表作为此接口生成的审批印章明细使用。 模板缺失、模板不唯一、图片为空、下载失败或没有已执行审批记录时返回错误,不写入部分列表, 也不清空已有子表。个人模板下载失败不会使用旧接口的固定底图或本地通用底图替代。 错误发生前已生成的本地图片可能留在 sealFile 中;重复请求会重新生成图片并替换子表行。

成功返回的 data.list 示例(省略图片文件大小等元数据):

{
  "success": true,
  "code": 200,
  "data": {
    "formInstanceId": "FINST-实际业务数据ID",
    "list": [
      {
        "approverUserId": "钉钉userId",
        "approverName": "审批人姓名",
        "approvalTime": "2026-10-14 09:02:03",
        "approvalAction": "agree",
        "nodeName": "部门审核",
        "fileUrl": "http://139.196.11.100:8101/sealFile/2026/10/14/seal-FINST-xxx-uuid.png",
        "sealImages": [{"url": "http://139.196.11.100:8101/sealFile/2026/10/14/seal-FINST-xxx-uuid.png"}]
      }
    ]
  }
}

服务仍使用现有 seal.yida.* 凭证和 sealFile 静态目录。目标应用需授权流程实例读取、审批记录 读取、模板表单查询、图片免登以及流程实例更新权限。首次联调使用真实业务数据 ID,验证返回的 节点、审批时间和个人印章,以及宜搭子表的显示;本地测试均使用模拟宜搭响应,没有修改线上记录。

验证命令(只运行隔离的印章测试,避免执行旧的真实接口测试):

mvn "-Dtest=ApprovalRecordParserTest,SealApprovalRecordsServiceTest,SealApprovalRecordsControllerTest,SealControllerTest,SealServiceImplTest" test
mvn clean package -DskipTests

原审批通过单张印章接口

原 approval-complete 接口的请求体最少需要传入当前宜搭流程实例 ID:

{
  "processInstanceId": "${当前流程实例ID}",
  "approvalTime": "2026-09-21"
}

Windows 配置

默认配置已经对应当前宜搭应用、底图表单和业务表单:

  • 应用:APP_RP2SE56YJWMECIWYN4BR
  • 底图表单:FORM-97B11108942B4DEA86E7207834FA76392Y23
  • 底图实例:FINST-F9D667D180C9S8YBMFJKL57SI9WL3EY87CBUM8UU
  • 底图字段:imageField_mubc5ugk
  • 业务表单:FORM-64A9D5065C234383AB2ACF7AB4F20975DW6M
  • 回写字段:imageField_mubc0xwk

服务会把图片写入运行目录下的 sealFile/yyyy/MM/dd/,并返回类似:

http://139.196.11.100:8101/sealFile/2026/09/21/seal-FINST-xxx-uuid.png

目标应用 APP_RP2SE56YJWMECIWYN4BR 必须配置它自己的宜搭 systemToken(应用密钥):

SEAL_YIDA_SYSTEM_TOKEN=目标应用的 systemToken

现有 myapp.yida.appSecret 属于旧应用时不能直接复用,否则宜搭会返回 HTTP 400。钉钉 AccessToken 仍由现有 AccessTokenService 获取。

钉钉 AccessToken 和宜搭 systemToken 是两种不同凭证:本服务会把钉钉 AccessToken 放到 x-acs-dingtalk-access-token 请求头,把目标宜搭应用密钥放到 systemToken 参数。 实例读取和表单回写使用宜搭 v2.0 接口,对应接口路径为 /v2.0/yida/...;不要再用旧的 v1.0 GetInstanceById 调用替代它。普通底图表单读取使用原始 HTTP 解析,因为当前 v2.0 SDK 的 GetFormDataByIDResponse 未映射 formData 字段。 审批流程实例读取使用 /v2.0/yida/processes/instancesInfos/{instanceId};印章底图是普通 表单实例,使用 /v2.0/yida/forms/instances/{formInstId} 读取。两者不能混用。 如果日志出现 code=innerError、statusCode=500、没有权限,而旧宜搭应用可以正常读取, 说明当前钉钉应用尚未被目标宜搭应用授权。需要在宜搭目标应用的开放接口/应用授权设置中, 授权当前 AccessTokenService 使用的钉钉应用,并开通表单实例读取和更新权限;这不是 Java 参数顺序问题。服务日志会输出脱敏参数和宜搭 requestId,便于在宜搭后台继续定位。

服务会优先调用宜搭官方 GetOpenUrl 免登文件接口,将底图地址换成临时 OSS URL 后下载,不依赖浏览器 Cookie。若目标应用权限或接口版本不支持免登地址,可把当前组织 Cookie 以环境变量 SEAL_YIDA_COOKIE 注入服务;也可以设置 SEAL_TEMPLATE_IMAGE_FILE 指向服务器上的底图 PNG 作为最终回退。不要把 Cookie 写进代码或提交到仓库。

可选的 Spring 环境变量:

SEAL_YIDA_COOKIE=...
SEAL_TEMPLATE_IMAGE_FILE=C:\\app\\sealFile\\template\\seal-template.png
SEAL_CONNECTOR_TOKEN=一段随机字符串
SEAL_PUBLIC_BASE_URL=http://139.196.11.100:8101/sealFile

如果设置了 SEAL_CONNECTOR_TOKEN,宜搭连接器需要增加同名请求头 X-Seal-Connector-Token。

Nginx

将下面的 alias 指向 Java 程序运行目录下的 sealFile;Nginx 对外监听 8101,Java 服务监听 8102:

location /sealFile/ {
    alias C:/app/changguchuan/sealFile/;
    try_files $uri =404;
    add_header Cache-Control "public, max-age=31536000";
}

location /api/changguchuan/ {
    proxy_pass http://127.0.0.1:8102/api/changguchuan/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

宜搭连接器和自动化

.cache/openyida/changguchuan/connector/seal-operations.json 是连接器动作定义。连接器域名使用 139.196.11.100:8101,基础路径填写 /api/changguchuan/,动作路径填写 seal/approval-complete,最终请求地址为 /api/changguchuan/seal/approval-complete,请求体映射:

  • processInstanceId:当前审批流程实例 ID(必填)
  • approvalTime:审批通过时间(可选)

在“禀议书”流程自动化中选择“审批通过”作为触发条件,再调用该连接器动作即可。接口会读取底图、叠加 yyyy-MM-dd 日期、保存图片,并把 URL 写入 imageField_mubc0xwk。

当前已创建并发布自动化逻辑流:

  • 逻辑流名称:审批通过生成印章
  • processCode:LPROC-PZA668C1YOF95MEJMNH236O34G1W2FTSMBCUMQ
  • 触发事件:processFinish
  • 审批动作:agree
  • 连接器参数:processInstanceId 映射为系统变量 __masterdata_form_inst_id