408 lines
23 KiB
Markdown
408 lines
23 KiB
Markdown
# iWork 统一集成使用说明
|
||
|
||
本文档介绍如何在 System 模块中使用项目已实现的统一 iWork 流程发起能力(controller + service + properties)。内容包含:配置项、调用方式(内部 Java 调用 & 外部 HTTP 调用)、请求/响应示例、错误处理、缓存与 Token 生命周期、业务回调分发与重试、流程日志查询,以及典型问题与排查步骤。
|
||
|
||
---
|
||
|
||
## 概览
|
||
|
||
项目在 `system` 模块下实现了一套对外统一的 iWork 集成能力:
|
||
|
||
- 提供管理端接口(REST),路径前缀:`/system/integration/iwork`。
|
||
- 提供 Service 层 `IWorkIntegrationService`,供其它模块以 Spring Bean 注入方式直接调用。
|
||
- 使用 `IWorkProperties` 绑定 `application.yml` 中 `iwork` 的配置项。
|
||
- Token / 会话采用本地 Caffeine 缓存缓存(按 appId + operatorUserId 缓存 session),并在到期前按配置提前刷新。
|
||
- 使用统一配置的 appId、公钥以及默认流程编号,无需再维护多套凭证,所有调用强制使用配置的 appId,不再接受请求覆盖。
|
||
- 全链路以 requestId 作为唯一业务标识(发起返回、作废入参、日志查询、回调与重试均基于 requestId),workflowId 仅用于指定 iWork 模板。
|
||
- 支持业务回调标识 bizCallbackKey(字符串,≤255),发起时提交,回调时按标识分发业务回调并带自动重试与手工重试入口。
|
||
- 回调与日志记录会保存截断后的原始回调请求/响应文本(无需脱敏),无业务附件或处理异常时标记失败。
|
||
|
||
---
|
||
|
||
## 配置(YAML)
|
||
|
||
在 `application.yml`(或 profile)中,添加或修改如下项(示例摘自 `zt-server/src/main/resources/application.yaml`):
|
||
|
||
```yaml
|
||
iwork:
|
||
base-url: https://iwork.example.com
|
||
app-id: my-iwork-app # 固定使用的 iWork 应用编号
|
||
client-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A... # 与 iWork 约定的客户端公钥(Base64)
|
||
user-id: system # 默认操作用户(当调用未指定 operatorUserId 时使用)
|
||
org:
|
||
token-seed: 5936562a-d47c-4a29-9b74-b310e6c971b7
|
||
paths:
|
||
subcompany-page: /api/hrm/resful/getHrmsubcompanyWithPage
|
||
department-page: /api/hrm/resful/getHrmdepartmentWithPage
|
||
job-title-page: /api/hrm/resful/getJobtitleInfoWithPage
|
||
user-page: /api/hrm/resful/getHrmUserInfoWithPage
|
||
sync-subcompany: /api/hrm/resful/synSubcompany
|
||
sync-department: /api/hrm/resful/synDepartment
|
||
sync-job-title: /api/hrm/resful/synJobtitle
|
||
sync-user: /api/hrm/resful/synHrmresource
|
||
workflow-id: 54 # 当调用方未传 workflowId 时使用的默认流程编号
|
||
paths:
|
||
register: /api/ec/dev/auth/regist
|
||
apply-token: /api/ec/dev/auth/applytoken
|
||
user-info: /api/workflow/paService/getUserInfo
|
||
create-workflow: /api/workflow/paService/doCreateRequest
|
||
void-workflow: /api/workflow/paService/doCancelRequest
|
||
token:
|
||
ttl-seconds: 3600 # token 有效期(秒)
|
||
refresh-ahead-seconds: 60 # 在到期前多少秒认为需要刷新
|
||
callback:
|
||
retry:
|
||
max-attempts: 3 # 业务回调自动重试次数(默认 3 次,可调整)
|
||
delay-seconds: 5 # 业务回调自动重试间隔秒数(默认 5 秒,可调整)
|
||
client:
|
||
connect-timeout: 5s
|
||
response-timeout: 30s
|
||
```
|
||
|
||
说明:
|
||
|
||
- `base-url` 为 iWork 网关的基础地址,不能留空。
|
||
- `app-id` 与 `client-public-key` 共同构成注册/申请 token 所需的凭据信息,由配置统一提供,不再支持多套切换,系统强制使用配置的 appId,忽略请求中的 appId。
|
||
- `workflow-id` 提供全局默认流程编号,仅用于向 iWork 指定流程模板;流程标识、查询、补偿、回调与重试一律使用 requestId,不再以 workflowId 标识业务。
|
||
- 请求头键名固定为 `app-id`、`client-public-key`、`secret`、`token`、`time`、`user-id`,无需在配置中重复声明。
|
||
- `org.*` 配置负责 iWork 人力组织 REST 代理:`token-seed` 为与 iWork 约定的标识,系统会自动将其与毫秒时间戳拼接并计算 MD5 生成 `key`,无需额外传递 token。
|
||
- `callback.retry.*` 控制业务回调的自动重试次数与间隔,默认为 3 次、5 秒,可按需调整。
|
||
|
||
---
|
||
|
||
## 典型调用路径(Controller)
|
||
|
||
Controller 暴露的 REST 接口:
|
||
|
||
- POST /system/integration/iwork/user/resolve
|
||
- 说明:根据外部识别信息查找 iWork 的用户编号(userId)。
|
||
- 请求:见下方 `Resolve User` 示例。
|
||
|
||
- POST /system/integration/iwork/workflow/create
|
||
- 说明:在 iWork 中发起流程。
|
||
- 请求:见下方 `Create Workflow` 示例。
|
||
|
||
- POST /system/integration/iwork/workflow/void
|
||
- 说明:作废/干预流程。
|
||
- 请求:见下方 `Void Workflow` 示例。
|
||
|
||
这些接口的响应均使用项目的 `CommonResult` 封装,实际返回的业务对象在 `data` 字段。
|
||
|
||
---
|
||
|
||
### 人力组织 REST 接口(key + ts)
|
||
|
||
为对接 PDF 所述的人力组织 RESTFUL 接口,Controller 额外暴露了以下代理端点,用于通过 `key + ts` 生成的 token 与 iWork 交互:
|
||
|
||
- POST `/system/integration/iwork/hr/subcompany/page` —— 请求体传入 `params`(Map),对应 `getHrmsubcompanyWithPage`。
|
||
- POST `/system/integration/iwork/hr/department/page` —— 对应 `getHrmdepartmentWithPage`。
|
||
- POST `/system/integration/iwork/hr/job-title/page` —— 对应 `getJobtitleInfoWithPage`。
|
||
- POST `/system/integration/iwork/hr/user/page` —— 对应 `getHrmUserInfoWithPage`。
|
||
- POST `/system/integration/iwork/hr/subcompany/sync` —— 请求体传入 `data`(List<Map>),对应 `synSubcompany`。
|
||
- POST `/system/integration/iwork/hr/department/sync` —— 对应 `synDepartment`。
|
||
- POST `/system/integration/iwork/hr/job-title/sync` —— 对应 `synJobtitle`。
|
||
- POST `/system/integration/iwork/hr/user/sync` —— 对应 `synHrmresource`。
|
||
|
||
所有请求均自动封装为 `application/x-www-form-urlencoded`,并把 `token` 字段设置为 `{"key":"<md5>","ts":"<timestamp>"}`,无需调用方重复计算。
|
||
|
||
---
|
||
|
||
## 请求 VO 说明(重要字段)
|
||
|
||
- IWorkBaseReqVO(公用字段)
|
||
- `appId` (String):仅保留字段,系统强制使用配置项 `iwork.app-id`,忽略请求值。
|
||
- `operatorUserId` (String):在 iWork 内部代表操作人的用户编号(可为空,框架会使用 `properties.userId`)。
|
||
- `forceRefreshToken` (Boolean):是否强制刷新 token(例如遇到 token 错误时强制刷新)。
|
||
|
||
- IWorkUserInfoReqVO(用于解析用户)
|
||
- `identifierKey` (String):外部标识 key(必须,例如 "loginid")。
|
||
- `identifierValue` (String):外部标识值(必须,例如用户名)。
|
||
- `payload` (Map):额外的请求载荷,会与 identifier 合并后发送到 iWork。
|
||
- `queryParams` (Map):如果需要通过查询参数传递额外信息,可使用此字段。
|
||
|
||
- IWorkUserInfoRespVO(解析用户响应)
|
||
- `userId` (String):从 iWork 响应中解析出的用户编号(如果能解析到)。
|
||
- `success` / `message`:调用成功标志与提示信息。
|
||
|
||
- IWorkWorkflowCreateReqVO(统一用印流程发起)
|
||
- `workflowId` (String):流程模板 ID,必填,通常由配置 `iwork.workflow-id` 提供;仅用于向 iWork 指定模板,不再作为业务标识。
|
||
- `jbr`:用印申请人(iWork 人员 ID,必填)。
|
||
- `yybm`:用印部门 ID(必填)。
|
||
- `fb`:用印单位/分部 ID(必填)。
|
||
- `sqsj`:申请时间(yyyy-MM-dd,必填)。
|
||
- `yyqx`:用印去向(必填)。
|
||
- `yyfkUrl`:用印依据附件 URL(可选)。
|
||
- `yysy`:用印事由或摘要(可选)。
|
||
- `xyywjUrl`:用印材料附件 URL(必填)。
|
||
- `yysx`:用印事项(必填)。
|
||
- `ywxtdjbh`:业务系统单据编号(必填,同时用于生成流程标题“用印-{ywxtdjbh}”)。
|
||
- `bizCallbackKey` (String):业务回调标识,≤255 字符,回调时按该标识分发到对应业务回调入口(可选但推荐)。
|
||
- 额外字段不再支持,Service 会根据以上字段自动补齐固定流程类型 (`lclx=2979600781334966993`) 与签署动作 (`qsdz=CORPORATE`)。
|
||
|
||
- IWorkWorkflowVoidReqVO(作废)
|
||
- `requestId` (String):流程请求编号(必填,唯一标识)。
|
||
- `reason`、`extraParams`、`formExtras` 等用于传递作废原因或额外字段。
|
||
|
||
- IWorkFormFieldVO(表单字段)
|
||
- `fieldName` (String):字段名(必填),与 iWork 表单字段 key 对应。
|
||
- `fieldValue` (String):字段值(必填)。
|
||
|
||
- IWorkDetailRecordVO(明细记录)
|
||
- `recordOrder` (Integer):可选记录序号(从 0 开始),用于 iWork 明细排序。
|
||
- `fields` (List<IWorkFormFieldVO>):该明细行下的字段集合(必填)。
|
||
|
||
- IWorkDetailTableVO(明细表)
|
||
- `tableDBName` (String):iWork 明细表表名(必填,如 `formtable_main_26_dt1`)。
|
||
- `records` (List<IWorkDetailRecordVO>):明细记录集合(必填)。
|
||
|
||
---
|
||
|
||
## Java(内部)调用示例
|
||
|
||
项目同时提供 `IWorkIntegrationService` Bean,可直接注入并调用:
|
||
|
||
```java
|
||
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOperationRespVO;
|
||
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkWorkflowCreateReqVO;
|
||
import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService;
|
||
import lombok.RequiredArgsConstructor;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
@RequiredArgsConstructor
|
||
@Component
|
||
public class MyService {
|
||
private final IWorkIntegrationService iworkService;
|
||
|
||
public void startSealFlow() {
|
||
IWorkWorkflowCreateReqVO req = new IWorkWorkflowCreateReqVO();
|
||
req.setWorkflowId("54");
|
||
req.setJbr("1001");
|
||
req.setYybm("2001");
|
||
req.setFb("3001");
|
||
req.setSqsj("2025-01-01");
|
||
req.setYyqx("对外邮寄");
|
||
req.setYyfkUrl("https://files.example.com/evidence.pdf");
|
||
req.setYysy("与客户合同用印");
|
||
req.setXyywjUrl("https://files.example.com/contract.pdf");
|
||
req.setYysx("合同用印");
|
||
req.setYwxtdjbh("DJ-2025-0001");
|
||
|
||
IWorkOperationRespVO resp = iworkService.createWorkflow(req);
|
||
if (resp.isSuccess()) {
|
||
// 处理成功,例如记录 requestId
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
说明:
|
||
|
||
- 无需设置 appId,系统强制使用配置项 `iwork.app-id`。
|
||
- `workflowId` 通常来自配置 `iwork.workflow-id`,也可在请求中指定模板编号,但流程标识一律以返回的 requestId 为准。
|
||
- 可设置 `bizCallbackKey` 以便回调时分发到对应业务处理;建议在发起后立即记录响应中的 requestId 及 bizCallbackKey。
|
||
- 若希望以特定 iWork 操作人发起,可设置 `req.setOperatorUserId("1001")`。
|
||
|
||
---
|
||
|
||
## HTTP(外部)调用示例(cURL)
|
||
|
||
1. Resolve user
|
||
|
||
```bash
|
||
curl -X POST \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"identifierKey":"loginid",
|
||
"identifierValue":"zhangsan"
|
||
}' \
|
||
https://your-zt-server/admin-api/system/integration/iwork/user/resolve
|
||
```
|
||
|
||
成功返回示例(CommonResult 包装):
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"msg": "success",
|
||
"data": {
|
||
"userId": "1001",
|
||
"success": true,
|
||
"payload": { ... },
|
||
"rawBody": "{...}"
|
||
}
|
||
}
|
||
```
|
||
|
||
1. Create workflow
|
||
|
||
```bash
|
||
curl -X POST -H "Content-Type: application/json" -d '{
|
||
"workflowId":"54",
|
||
"jbr":"1001",
|
||
"yybm":"2001",
|
||
"fb":"3001",
|
||
"sqsj":"2025-01-01",
|
||
"yyqx":"对外邮寄",
|
||
"yyfkUrl":"https://files.example.com/evidence.pdf",
|
||
"yysy":"与客户合同用印",
|
||
"xyywjUrl":"https://files.example.com/contract.pdf",
|
||
"yysx":"合同用印",
|
||
"ywxtdjbh":"DJ-2025-0001",
|
||
"bizCallbackKey":"seal-flow-callback"
|
||
}' https://your-zt-server/admin-api/system/integration/iwork/workflow/create
|
||
```
|
||
|
||
> 说明:外部仍以 JSON 请求调用本服务,系统在向 iWork 转发时会自动将负载转换为 `application/x-www-form-urlencoded` 表单(含 `requestName`、`workflowId`、`mainData` 等字段)。
|
||
> 响应的 `data.requestId` 为唯一业务标识,请在业务侧保存;appId 始终取配置;`xyywjFileName` 不存储。
|
||
|
||
1. Void workflow
|
||
|
||
```bash
|
||
curl -X POST -H "Content-Type: application/json" -d '{
|
||
"requestId":"REQ-001",
|
||
"reason":"作废原因"
|
||
}' https://your-zt-server/admin-api/system/integration/iwork/workflow/void
|
||
```
|
||
|
||
---
|
||
|
||
## 核心逻辑与细节
|
||
|
||
1. 基础参数解析
|
||
appId:始终取配置 `iwork.app-id`,忽略请求值。
|
||
主标识:全链路仅使用 `requestId`(发起返回、作废入参、日志查询、回调分发、重试都基于 requestId)。
|
||
模板:`workflowId` 仅用于选择 iWork 模板,不作为业务标识。
|
||
业务回调标识:`bizCallbackKey`(字符串,≤255),发起时提交,回调按该标识分发到具体业务回调入口。
|
||
附件文件名:`xyywjFileName` 不存储也不参与处理;仅使用 `xyywjUrl`。
|
||
|
||
调用时可在请求体中指定 `workflowId` 以选择模板;若未显式传入,则回退到全局 `iwork.workflow-id`,若仍为空则抛出 `IWORK_WORKFLOW_ID_MISSING`。
|
||
POST `/system/integration/iwork/workflow/create`:发起用印流程,返回 `requestId`。
|
||
POST `/system/integration/iwork/workflow/void`:作废流程,请求需携带 `requestId`。
|
||
POST `/system/integration/iwork/callback/file`(上游回调):接收 iWork 回调,校验 `requestId`,若缺 `bizCallbackKey` 则记录失败但不中断附件保存;下载并落库附件,记录回调日志(截断原文),并在提供 `bizCallbackKey` 时通过 RocketMQ 分发业务回调(自动/手工重试)。
|
||
POST `/system/integration/iwork/log/page`:分页查询用印回调日志(requestId / 业务单号 / bizCallbackKey / 状态 / 时间段)。
|
||
POST `/system/integration/iwork/log/retry`:手工重试业务回调,需权限,入参 `requestId`(状态为失败/超重试时可用)。
|
||
1. 向 iWork 的 `register` 接口发起请求(Headers 包含 appId 与 clientPublicKey)。
|
||
2. 从注册响应中获取 `secret` 与 `spk`(服务端公钥),使用本地的 client 公钥做 RSA 加密(`spk` 用于加密),得到加密后的 secret 与 encryptedUserId。
|
||
发起:`workflowId`、`jbr`、`yybm`、`fb`、`sqsj`、`yyqx`、`xyywjUrl`、`yysx`、`ywxtdjbh` 必填;`bizCallbackKey` 可选但建议提供;appId 忽略。
|
||
作废:`requestId` 必填;`reason` 可选。
|
||
回调:若无法找到业务附件(或不存在),标记用印失败并记日志,不抛出未捕获异常;记录原始回调文本(截断)。
|
||
- 当 token 接近到期(`refresh-ahead-seconds`)时会在下一次请求触发刷新。
|
||
|
||
1) 发起:校验必填 → 使用配置 appId 与模板 workflowId → 申请/缓存 token → 以 form-urlencoded 调 iWork → 返回 `requestId`,记录发起日志状态。
|
||
2) 回调(/callback/file):校验 requestId + bizCallbackKey → 校验租户/必备字段 → 下载/保存附件(若缺业务附件则直接标记失败并记日志)→ 写入回调日志,保存原始回调请求/响应(截断)→ 通过 RocketMQ 发送业务回调消息(topic=`SYSTEM_IWORK_BIZ_CALLBACK`,tag=`bizCallbackKey`)。
|
||
3) 业务处理 & 结果上报(跨模块/跨进程):业务模块订阅 `SYSTEM_IWORK_BIZ_CALLBACK` 对应 tag 处理后,将结果发布到 `SYSTEM_IWORK_BIZ_CALLBACK_RESULT`(tag 同 bizCallbackKey,携带 requestId / bizCallbackKey / success / errorMessage / payload / attempt / maxAttempts),system 模块消费结果并更新日志,失败且未超限时由 system 端按配置延迟重试再次投递回调消息。
|
||
4) 重试:默认 3 次、间隔 5 秒,可配置(`iwork.callback.retry.*`),手工重试仍使用 `/log/retry`,由 system 模块重新投递 MQ 消息。
|
||
5) 手工重试:需具备 iWork 模块权限;根据 requestId 将任务重新投递至回调分发器,不增加自动重试计数,可在日志详情中发起。
|
||
|
||
1. 响应解析
|
||
`CREATE_PENDING` / `CREATE_SUCCESS` / `CREATE_FAILED`
|
||
`CALLBACK_PENDING` / `CALLBACK_SUCCESS` / `CALLBACK_FAILED`
|
||
`CALLBACK_RETRYING` / `CALLBACK_RETRY_FAILED`
|
||
|
||
---
|
||
|
||
## 用印流程日志与业务回调
|
||
|
||
### 范围与标识
|
||
|
||
- appId:始终取配置 `iwork.app-id`,忽略请求值。
|
||
- 主标识:全链路仅使用 `requestId`(发起返回、作废入参、日志查询、回调分发、重试都基于 requestId)。
|
||
- 模板:`workflowId` 仅用于选择 iWork 模板,不作为业务标识。
|
||
- 业务回调标识:`bizCallbackKey`(字符串,≤255),发起时提交,回调按该标识分发到具体业务回调入口。
|
||
- 附件文件名:`xyywjFileName` 不存储也不参与处理;仅使用 `xyywjUrl`。
|
||
|
||
### 入口(REST)
|
||
|
||
- POST `/system/integration/iwork/workflow/create`:发起用印流程,返回 `requestId`。
|
||
- POST `/system/integration/iwork/workflow/void`:作废流程,请求需携带 `requestId`。
|
||
- POST `/system/integration/iwork/callback/file`(上游回调):接收 iWork 回调,校验 `requestId`,若缺 `bizCallbackKey` 则记录失败但不中断附件保存;下载并落库附件,记录回调日志(截断原文),并在提供 `bizCallbackKey` 时通过 RocketMQ 分发业务回调(自动/手工重试)。
|
||
- POST `/system/integration/iwork/log/page`:分页查询用印回调日志(requestId / 业务单号 / bizCallbackKey / 状态 / 时间段)。
|
||
- POST `/system/integration/iwork/log/retry`:手工重试业务回调,需权限,入参 `requestId`(状态为失败/超重试时可用)。
|
||
|
||
### 必填/校验要点
|
||
|
||
- 发起:`workflowId`、`jbr`、`yybm`、`fb`、`sqsj`、`yyqx`、`xyywjUrl`、`yysx`、`ywxtdjbh` 必填;`bizCallbackKey` 可选但建议提供;appId 忽略。
|
||
- 作废:`requestId` 必填;`reason` 可选。
|
||
- 回调:若无法找到业务附件(或不存在),标记用印失败并记日志,不抛出未捕获异常;记录原始回调文本(截断)。
|
||
|
||
### 处理流程(摘要)
|
||
|
||
1) 发起:校验必填 → 使用配置 appId 与模板 workflowId → 申请/缓存 token → 以 form-urlencoded 调 iWork → 返回 `requestId`,记录发起日志状态。
|
||
2) 回调(/callback/file):校验 requestId + bizCallbackKey → 校验租户/必备字段 → 下载/保存附件(若缺业务附件则直接标记失败并记日志)→ 写入回调日志,保存原始回调请求/响应(截断)→ 通过 RocketMQ 发送业务回调消息(topic=`SYSTEM_IWORK_BIZ_CALLBACK`,tag=`bizCallbackKey`)。
|
||
3) 业务处理 & 结果上报(跨模块/跨进程):业务模块订阅 `SYSTEM_IWORK_BIZ_CALLBACK` 对应 tag 处理后,将结果发布到 `SYSTEM_IWORK_BIZ_CALLBACK_RESULT`(tag 同 bizCallbackKey,携带 requestId / bizCallbackKey / success / errorMessage / payload / attempt / maxAttempts),system 模块消费结果并更新日志,失败且未超限时由 system 端按配置延迟重试再次投递回调消息。
|
||
4) 重试:默认 3 次、间隔 5 秒,可配置(`iwork.callback.retry.*`),手工重试仍使用 `/log/retry`,由 system 模块重新投递 MQ 消息。
|
||
5) 手工重试:需具备 iWork 模块权限;根据 requestId 将任务重新投递至回调分发器,不增加自动重试计数,可在日志详情中发起。
|
||
|
||
### 状态字面量(示例)
|
||
|
||
- `CREATE_PENDING` / `CREATE_SUCCESS` / `CREATE_FAILED`
|
||
- `CALLBACK_PENDING` / `CALLBACK_SUCCESS` / `CALLBACK_FAILED`
|
||
- `CALLBACK_RETRYING` / `CALLBACK_RETRY_FAILED`
|
||
|
||
> 实际实现可根据需要细化,唯一标识均为 requestId。
|
||
|
||
### 重试与配置
|
||
|
||
- 自动重试:默认 `maxAttempts=3`、`delaySeconds=5`,可配置(示例键:`iwork.callback.retry.max-attempts`、`iwork.callback.retry.delay-seconds`)。
|
||
- 手工重试:权限校验(沿用 iWork 模块权限前缀);仅在失败/超重试状态下开放。
|
||
- 幂等:按 requestId + bizCallbackKey 进行幂等检查,成功后不再重复分发,除非手工强制重试。
|
||
|
||
### 日志存储
|
||
|
||
- 表:`system_iwork_seal_callback_log`(示例字段)
|
||
- `requestId`(PK)、`businessCode`(ywxtdjbh)、`bizCallbackKey`、`status`、`retryCount`、`lastErrorMessage`、`fileUrl`、`fileId`、`businessFileId`、`requestBody`、`responseBody`、`rawCallback`(截断保存原文)、`lastCallbackTime`、`creator`、`createTime`、`updateTime`。
|
||
- 字段要点:
|
||
- `rawCallback`:保存回调原始文本,截断存储(无需脱敏,不注明上限)。
|
||
- 无业务附件或保存失败:写 `status=CREATE_FAILED` / `CALLBACK_FAILED` 并记录错误原因。
|
||
|
||
### 查询与展示
|
||
|
||
- 分页:沿用 `PageParam` 约束,`pageNo` 默认 1、`pageSize` 默认 10、上限 10000,仅分页浏览不支持导出。
|
||
- 查询条件:`requestId`、`businessCode`(ywxtdjbh)、`bizCallbackKey`、`status`、时间范围(createTime / lastCallbackTime)。
|
||
- 列表字段:requestId、业务单号、bizCallbackKey、状态、重试次数、最后错误、更新时间。
|
||
- 详情:展示截断的回调原文(请求/响应)、错误原因、附件信息;提供“手工重试”按钮(需权限)。
|
||
|
||
---
|
||
|
||
## 常见错误与排查
|
||
|
||
- baseUrl 未配置(IWORK_BASE_URL_MISSING)
|
||
- 处理:确保 `iwork.base-url` 配置正确。
|
||
|
||
- 配置缺失(IWORK_CONFIGURATION_INVALID)
|
||
- 场景:`app-id`、`client-public-key`、`user-id` 等关键字段没有配置或只包含空白字符。
|
||
- 处理:在 `application.yml` 或配置中心中补充对应字段,确保它们与 iWork 侧一致。
|
||
|
||
- 用印必填字段缺失(IWORK_SEAL_REQUIRED_FIELD_MISSING)
|
||
- 场景:`workflowId`、`jbr`、`yybm`、`fb`、`sqsj`、`yyqx`、`xyywjUrl`、`yysx`、`ywxtdjbh` 等任一字段为空。
|
||
- 处理:根据返回的字段名称补齐相应值后重新发起。
|
||
|
||
- RSA 加密/注册/申请 token 失败(IWORK_REGISTER_FAILED / IWORK_APPLY_TOKEN_FAILED / IWORK_REMOTE_REQUEST_FAILED)
|
||
- 处理:通过日志查看 iWork 返回的 HTTP 状态码与 body,确认请求头/路径/参数是否匹配 iWork 网关要求。
|
||
|
||
- 用户解析失败
|
||
- 确认 `identifierKey`/`identifierValue` 是否正确填写并与 iWork 的查询接口契合;可启用 `forceRefreshToken` 触发 session 刷新以排除 token 过期造成的问题。
|
||
|
||
---
|
||
|
||
## 进阶主题
|
||
|
||
- 并发与缓存
|
||
- `sessionCache` 最大条目数为 256;若高并发/多凭证/多操作人场景,可能需调整容量。
|
||
|
||
- 超时与 HTTP 客户端
|
||
- `IWorkProperties.client.response-timeout` 可用于设定响应超时;连接超时通常由 Reactor Netty 全局配置控制。
|
||
|
||
- 单元测试
|
||
- 项目中已有 MockWebServer 测试样例(`IWorkIntegrationServiceImplTest`),可参考测试用例模拟 iWork 的注册、申请 token、用户查询、创建/作废流程的交互。
|
||
|
||
---
|
||
|
||
## 小结与建议
|
||
|
||
- 在配置中补齐 `iwork.app-id`、`iwork.client-public-key`、`iwork.user-id`、`iwork.workflow-id` 等关键字段,并按需配置回调重试参数(默认 3 次,5 秒间隔)。
|
||
- 优先在本地通过 `IWorkIntegrationService` Java API 调试,成功后再通过 Controller 的 REST 接口对外暴露;发起后请记录返回的 requestId(唯一标识)与 bizCallbackKey。
|
||
- 若遇到请求失败,查看应用日志(`[iWork]` 前缀的日志)与 iWork 网关返回 body;若业务回调失败,可在日志页面查看截断原文并按权限发起手工重试。
|
||
|
||
文档已生成并保存到:`docs/iWork集成说明.md`。
|