docs(iwork): 添加用印流程集成开发文档
- 新增完整的 iWork 用印流程集成开发文档 - 包含整体架构图和完整流程时序图 - 详细说明数据库设计和状态流转机制 - 提供 API 接口说明和请求参数定义 - 描述 MQ 消息机制和消息格式定义 - 编写业务模块接入指南和消费者实现示例 - 说明重试机制配置和手工重试接口 - 提供本地开发调试和常见问题解决方案 - 列出相关代码位置便于查阅和维护
This commit is contained in:
514
docs/iWork用印流程集成开发文档.md
Normal file
514
docs/iWork用印流程集成开发文档.md
Normal file
@@ -0,0 +1,514 @@
|
||||
# iWork 用印流程集成开发文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 ZT Cloud 平台与 iWork 系统的用印流程集成方案,包括流程发起、回调处理、消息通知及重试机制。
|
||||
|
||||
### 1.1 功能特性
|
||||
|
||||
- **流程发起**:支持用印专用流程和通用流程两种创建方式
|
||||
- **回调处理**:接收 iWork 回调,自动通知业务模块
|
||||
- **消息队列**:基于 RocketMQ 的异步消息通知机制
|
||||
- **自动重试**:失败回调自动重试,支持配置重试次数和间隔
|
||||
- **日志追踪**:完整记录流程创建和回调处理全生命周期
|
||||
|
||||
### 1.2 整体架构
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ 业务系统 │────▶│ System 模块 │────▶│ iWork 系统 │
|
||||
│ (调用方) │ │ (集成层) │ │ (OA 流程) │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
▲ ▲ │
|
||||
│ │ │
|
||||
│ └───────────────────────┘
|
||||
│ iWork 流程完成后回调
|
||||
│ ┌─────────────────┐
|
||||
│ │ RocketMQ │
|
||||
│ │ (消息队列) │
|
||||
└───────────────┴─────────────────┘
|
||||
```
|
||||
|
||||
### 1.3 完整流程时序图
|
||||
|
||||
```
|
||||
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
|
||||
│ 业务系统 │ │ System │ │ iWork │ │RocketMQ│ │业务消费者│
|
||||
└───┬────┘ └───┬────┘ └───┬────┘ └───┬────┘ └───┬────┘
|
||||
│ │ │ │ │
|
||||
│ 1.发起用印流程 │ │ │ │
|
||||
│──────────────▶│ │ │ │
|
||||
│ │ 2.创建流程 │ │ │
|
||||
│ │──────────────▶│ │ │
|
||||
│ │ 返回requestId│ │ │
|
||||
│ │◀──────────────│ │ │
|
||||
│ 返回结果 │ │ │ │
|
||||
│◀──────────────│ │ │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ 3.OA流程审批 │ │
|
||||
│ │ │ (异步进行) │ │
|
||||
│ │ │ │ │
|
||||
│ │ 4.流程完成回调 │ │ │
|
||||
│ │◀──────────────│ │ │
|
||||
│ │ │ │ │
|
||||
│ │ 5.发送MQ消息 │ │ │
|
||||
│ │──────────────────────────────▶│ │
|
||||
│ │ │ │ 6.投递消息 │
|
||||
│ │ │ │──────────────▶│
|
||||
│ │ │ │ │
|
||||
│ │ │ │ 7.返回处理结果 │
|
||||
│ │ │ │◀──────────────│
|
||||
│ │ 8.接收结果 │ │ │
|
||||
│ │◀──────────────────────────────│ │
|
||||
│ │ │ │ │
|
||||
│ │ 9.更新日志状态 │ │ │
|
||||
│ │ (成功/重试) │ │ │
|
||||
└───────────────┴───────────────┴───────────────┴───────────────┘
|
||||
```
|
||||
|
||||
**流程说明**:
|
||||
|
||||
1. **发起流程**:业务系统调用 System 模块的流程创建接口
|
||||
2. **创建流程**:System 模块调用 iWork API 创建 OA 流程,获取 `requestId`
|
||||
3. **OA 审批**:流程在 iWork 系统中流转(审批、签章等),此过程异步进行
|
||||
4. **iWork 回调**:流程完成后,iWork 系统主动回调 System 模块的回调接口
|
||||
5. **MQ 通知**:System 模块将回调数据通过 RocketMQ 发送给业务消费者
|
||||
6. **业务处理**:业务消费者接收消息并处理(如保存签章文件、更新业务状态)
|
||||
7. **返回结果**:业务消费者处理完成后,发送处理结果消息
|
||||
8. **接收结果**:System 模块接收处理结果
|
||||
9. **状态更新**:根据结果更新日志状态,失败则触发重试机制
|
||||
|
||||
## 2. 数据库设计
|
||||
|
||||
### 2.1 流程日志表 (system_iwork_workflow_log)
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| id | BIGINT | 主键 |
|
||||
| request_id | VARCHAR(128) | iWork 请求编号(唯一) |
|
||||
| workflow_id | BIGINT | 流程模板 ID |
|
||||
| business_code | VARCHAR(128) | 业务编码 |
|
||||
| biz_callback_key | VARCHAR(255) | 业务回调标识(MQ tag) |
|
||||
| raw_request | VARCHAR(2000) | 创建请求原文 |
|
||||
| status | VARCHAR(32) | 流程状态 |
|
||||
| callback_status | INTEGER | 回调处理状态 |
|
||||
| retry_count | INTEGER | 已重试次数 |
|
||||
| max_retry | INTEGER | 最大重试次数 |
|
||||
| last_error_message | VARCHAR(512) | 最后错误信息 |
|
||||
| raw_callback | VARCHAR(2000) | 回调原文 |
|
||||
| last_callback_time | TIMESTAMP | 最近回调时间 |
|
||||
| tenant_id | BIGINT | 租户编号 |
|
||||
|
||||
### 2.2 回调状态枚举 (callback_status)
|
||||
|
||||
| 值 | 状态 | 说明 |
|
||||
|----|------|------|
|
||||
| 0 | CREATE_PENDING | 创建中 |
|
||||
| 1 | CREATE_SUCCESS | 创建成功 |
|
||||
| 2 | CREATE_FAILED | 创建失败 |
|
||||
| 3 | CALLBACK_PENDING | 回调待处理 |
|
||||
| 4 | CALLBACK_SUCCESS | 回调处理成功 |
|
||||
| 5 | CALLBACK_FAILED | 回调处理失败 |
|
||||
| 6 | CALLBACK_RETRYING | 回调重试中 |
|
||||
| 7 | CALLBACK_RETRY_FAILED | 回调重试失败 |
|
||||
|
||||
### 2.3 状态流转图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 流程创建阶段 │
|
||||
│ ┌──────────┐ 成功 ┌──────────┐ │
|
||||
│ │ PENDING │ ─────────▶ │ SUCCESS │ │
|
||||
│ │ (0) │ │ (1) │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
│ │ │
|
||||
│ │ 失败 │
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ FAILED │ │
|
||||
│ │ (2) │ │
|
||||
│ └──────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ iWork 回调
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 回调处理阶段 │
|
||||
│ ┌──────────┐ 成功 ┌──────────┐ │
|
||||
│ │ CALLBACK │ ─────────▶ │ CALLBACK │ │
|
||||
│ │ PENDING │ │ SUCCESS │ │
|
||||
│ │ (3) │ │ (4) │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
│ │ │
|
||||
│ │ 失败 │
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ 重试中 ┌──────────┐ │
|
||||
│ │ CALLBACK │ ◀───────▶ │ CALLBACK │ │
|
||||
│ │ FAILED │ │ RETRYING │ │
|
||||
│ │ (5) │ │ (6) │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
│ │ │
|
||||
│ │ 重试次数耗尽 │
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ RETRY │ │
|
||||
│ │ FAILED(7)│ │
|
||||
│ └──────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 3. API 接口说明
|
||||
|
||||
### 3.1 用印流程创建
|
||||
|
||||
**接口地址**:`POST /admin-api/system/integration/iwork/workflow/create`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
```json
|
||||
{
|
||||
"operatorUserId": "1001",
|
||||
"jbr": "1001",
|
||||
"yybm": "2001",
|
||||
"fb": "3001",
|
||||
"sqsj": "2025-01-30",
|
||||
"yyqx": "内部使用",
|
||||
"yyfkUrl": "https://example.com/attachment.pdf",
|
||||
"yysy": "合同盖章",
|
||||
"xyywjUrl": "https://example.com/contract.pdf",
|
||||
"yysx": "公章",
|
||||
"ywxtdjbh": "DJ-2025-0001",
|
||||
"bizCallbackKey": "seal-callback"
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| operatorUserId | 是 | 操作人 iWork 用户 ID |
|
||||
| jbr | 是 | 用印申请人 |
|
||||
| yybm | 是 | 用印部门 ID |
|
||||
| fb | 是 | 用印单位(分部 ID) |
|
||||
| sqsj | 是 | 申请时间 (yyyy-MM-dd) |
|
||||
| yyqx | 是 | 用印去向 |
|
||||
| xyywjUrl | 是 | 用印材料附件 URL |
|
||||
| yysx | 是 | 用印事项 |
|
||||
| ywxtdjbh | 是 | 业务系统单据编号 |
|
||||
| bizCallbackKey | 否 | 业务回调标识 |
|
||||
| yyfkUrl | 否 | 用印依据附件 URL |
|
||||
| yysy | 否 | 用印事由 |
|
||||
|
||||
### 3.2 通用流程创建
|
||||
|
||||
**接口地址**:`POST /admin-api/system/integration/iwork/workflow/create-generic`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
```json
|
||||
{
|
||||
"operatorUserId": "1001",
|
||||
"workflowId": 54,
|
||||
"payload": {
|
||||
"requestName": "用印-DJ-2025-0001",
|
||||
"mainData": [
|
||||
{"fieldName": "jbr", "fieldValue": "1001"},
|
||||
{"fieldName": "yybm", "fieldValue": "2001"}
|
||||
]
|
||||
},
|
||||
"ywxtdjbh": "DJ-2025-0001",
|
||||
"bizCallbackKey": "seal-callback"
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| operatorUserId | 是 | 操作人 iWork 用户 ID |
|
||||
| workflowId | 是 | 流程模板 ID |
|
||||
| payload | 是 | 透传给 iWork 的业务参数 |
|
||||
| ywxtdjbh | 否 | 业务编码 |
|
||||
| bizCallbackKey | 否 | 业务回调标识 |
|
||||
|
||||
### 3.3 iWork 回调接口
|
||||
|
||||
**接口地址**:`POST /admin-api/system/integration/iwork/callback/file`
|
||||
|
||||
**说明**:此接口供 iWork 系统回调,无需认证(@PermitAll, @TenantIgnore)
|
||||
|
||||
**iWork 侧配置**:需要在 iWork 系统中配置回调地址,当流程完成时自动调用此接口。
|
||||
|
||||
**请求参数**:
|
||||
|
||||
```json
|
||||
{
|
||||
"requestId": "3603649",
|
||||
"businessCode": "DJ-2025-0001",
|
||||
"fileUrl": "https://iwork.example.com/signed-file.pdf",
|
||||
"fileName": "已签章合同.pdf",
|
||||
"status": "COMPLETED"
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| requestId | 是 | iWork 请求编号(与创建流程时返回的一致) |
|
||||
| businessCode | 是 | 业务编码(与创建流程时传入的 ywxtdjbh 一致) |
|
||||
| fileUrl | 是 | 签章后文件 URL |
|
||||
| fileName | 否 | 文件名称 |
|
||||
| status | 否 | 业务状态 |
|
||||
|
||||
**回调处理逻辑**:
|
||||
|
||||
1. 根据 `requestId` 查询流程创建日志,获取 `bizCallbackKey`
|
||||
2. 更新日志状态为 `CALLBACK_PENDING`
|
||||
3. 发送 MQ 消息通知业务模块(仅当 `bizCallbackKey` 存在时)
|
||||
4. 返回处理结果
|
||||
|
||||
## 4. MQ 消息机制
|
||||
|
||||
### 4.1 消息流程图
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ iWork 回调 │───▶│ System 模块 │───▶│ RocketMQ │───▶│ 业务消费者 │
|
||||
│ │ │ (Producer) │ │ │ │ │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ 更新日志状态 │◀───│ System 模块 │◀───│ RocketMQ │◀───│ 返回处理结果 │
|
||||
│ │ │ (Listener) │ │ │ │ │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
### 4.2 Topic 定义
|
||||
|
||||
| Topic | 说明 |
|
||||
|-------|------|
|
||||
| SYSTEM_IWORK_BIZ_CALLBACK | 回调通知消息(System → 业务模块) |
|
||||
| SYSTEM_IWORK_BIZ_CALLBACK_RESULT | 处理结果消息(业务模块 → System) |
|
||||
|
||||
### 4.3 回调通知消息 (IWorkBizCallbackMessage)
|
||||
|
||||
```java
|
||||
{
|
||||
"requestId": "3603649",
|
||||
"bizCallbackKey": "seal-callback",
|
||||
"payload": { /* 回调原始数据 */ },
|
||||
"attempt": 0,
|
||||
"maxAttempts": 3
|
||||
}
|
||||
```
|
||||
|
||||
**Tag 规则**:消息 tag = `bizCallbackKey`,业务模块按 tag 订阅
|
||||
|
||||
### 4.4 处理结果消息 (IWorkBizCallbackResultMessage)
|
||||
|
||||
```java
|
||||
{
|
||||
"requestId": "3603649",
|
||||
"bizCallbackKey": "seal-callback",
|
||||
"success": true,
|
||||
"errorMessage": null,
|
||||
"attempt": 0,
|
||||
"maxAttempts": 3,
|
||||
"payload": { /* 原始数据,用于重试 */ }
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 业务模块接入指南
|
||||
|
||||
### 5.1 添加依赖
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-module-system-api</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 5.2 实现消费者
|
||||
|
||||
```java
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@RocketMQMessageListener(
|
||||
topic = IWorkBizCallbackMessage.TOPIC,
|
||||
consumerGroup = IWorkBizCallbackMessage.TOPIC + "_YOUR_BIZ_KEY",
|
||||
selectorExpression = "your-biz-callback-key" // 与 bizCallbackKey 一致
|
||||
)
|
||||
public class YourBizCallbackConsumer implements RocketMQListener<IWorkBizCallbackMessage> {
|
||||
|
||||
private final RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
@Override
|
||||
public void onMessage(IWorkBizCallbackMessage message) {
|
||||
log.info("收到 iWork 回调: requestId={}", message.getRequestId());
|
||||
|
||||
IWorkBizCallbackResultMessage result;
|
||||
try {
|
||||
// 处理业务逻辑
|
||||
processCallback(message);
|
||||
|
||||
result = IWorkBizCallbackResultMessage.builder()
|
||||
.requestId(message.getRequestId())
|
||||
.bizCallbackKey(message.getBizCallbackKey())
|
||||
.success(true)
|
||||
.attempt(message.getAttempt())
|
||||
.maxAttempts(message.getMaxAttempts())
|
||||
.payload(message.getPayload())
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
log.error("处理回调失败", e);
|
||||
result = IWorkBizCallbackResultMessage.builder()
|
||||
.requestId(message.getRequestId())
|
||||
.bizCallbackKey(message.getBizCallbackKey())
|
||||
.success(false)
|
||||
.errorMessage(e.getMessage())
|
||||
.attempt(message.getAttempt())
|
||||
.maxAttempts(message.getMaxAttempts())
|
||||
.payload(message.getPayload())
|
||||
.build();
|
||||
}
|
||||
|
||||
// 发送处理结果
|
||||
rocketMQTemplate.syncSend(IWorkBizCallbackResultMessage.TOPIC, result);
|
||||
}
|
||||
|
||||
private void processCallback(IWorkBizCallbackMessage message) {
|
||||
// 业务处理逻辑
|
||||
// 1. 解析 payload 获取回调数据
|
||||
// 2. 更新业务状态
|
||||
// 3. 保存签章文件等
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 关键配置项
|
||||
|
||||
| 配置项 | 说明 |
|
||||
|--------|------|
|
||||
| consumerGroup | 消费者组,建议格式:`TOPIC + "_" + bizCallbackKey` |
|
||||
| selectorExpression | Tag 过滤,必须与发起流程时的 `bizCallbackKey` 一致 |
|
||||
|
||||
### 5.4 注意事项
|
||||
|
||||
1. **bizCallbackKey 唯一性**:每个业务场景使用独立的 bizCallbackKey
|
||||
2. **幂等处理**:消费者需实现幂等,同一 requestId 可能重复投递
|
||||
3. **必须返回结果**:处理完成后必须发送 `IWorkBizCallbackResultMessage`
|
||||
4. **错误信息**:失败时填写 errorMessage,便于问题排查
|
||||
|
||||
## 6. 重试机制
|
||||
|
||||
### 6.1 重试流程
|
||||
|
||||
```
|
||||
业务处理失败 → 返回 success=false → System Listener 接收
|
||||
↓
|
||||
检查 attempt < maxAttempts?
|
||||
↓ ↓
|
||||
是 否
|
||||
↓ ↓
|
||||
延迟后重新投递 标记最终失败
|
||||
```
|
||||
|
||||
### 6.2 配置参数
|
||||
|
||||
```yaml
|
||||
iwork:
|
||||
callback:
|
||||
retry:
|
||||
max-attempts: 3 # 最大重试次数
|
||||
delay-seconds: 5 # 重试间隔(秒)
|
||||
```
|
||||
|
||||
### 6.3 手工重试
|
||||
|
||||
**接口地址**:`POST /admin-api/system/integration/iwork/log/retry`
|
||||
|
||||
```json
|
||||
{
|
||||
"requestId": "3603649"
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 日志查询
|
||||
|
||||
### 7.1 分页查询接口
|
||||
|
||||
**接口地址**:`POST /admin-api/system/integration/iwork/log/page`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
```json
|
||||
{
|
||||
"requestId": "3603649",
|
||||
"businessCode": "DJ-2025-0001",
|
||||
"bizCallbackKey": "seal-callback",
|
||||
"status": 4,
|
||||
"pageNo": 1,
|
||||
"pageSize": 10
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 本地开发调试
|
||||
|
||||
### 8.1 隔离测试环境
|
||||
|
||||
为避免与测试环境消息冲突,本地开发时需修改:
|
||||
|
||||
1. **Listener 消费者组**:添加本地标识后缀
|
||||
```java
|
||||
consumerGroup = IWorkBizCallbackResultMessage.TOPIC + "_CONSUMER_local"
|
||||
```
|
||||
|
||||
2. **Listener Tag 过滤**:使用本地专用 tag
|
||||
```java
|
||||
selectorExpression = "local_test"
|
||||
```
|
||||
|
||||
3. **业务消费者**:同样使用本地专用 bizCallbackKey
|
||||
```java
|
||||
selectorExpression = "your-biz-key_local"
|
||||
```
|
||||
|
||||
4. **数据库记录**:将 `biz_callback_key` 设为本地专用值
|
||||
|
||||
### 8.2 调试建议
|
||||
|
||||
- 使用独立的 `bizCallbackKey` 避免消息串扰
|
||||
- 检查 RocketMQ 控制台确认消息投递情况
|
||||
- 关注日志中的 `requestId` 进行链路追踪
|
||||
|
||||
## 9. 常见问题
|
||||
|
||||
### Q1: 业务消费者收不到消息?
|
||||
|
||||
检查项:
|
||||
- `selectorExpression` 是否与 `bizCallbackKey` 一致
|
||||
- 消费者组名是否正确
|
||||
- RocketMQ 连接是否正常
|
||||
|
||||
### Q2: 收到重复消息?
|
||||
|
||||
可能原因:
|
||||
- 多个环境的 Listener 都在消费同一 topic
|
||||
- 解决:使用独立的消费者组和 tag 过滤
|
||||
|
||||
### Q3: 重试不生效?
|
||||
|
||||
检查项:
|
||||
- 是否正确返回了 `IWorkBizCallbackResultMessage`
|
||||
- `success` 字段是否为 `false`
|
||||
- 配置的 `max-attempts` 是否大于当前 `attempt`
|
||||
|
||||
## 10. 相关代码位置
|
||||
|
||||
| 组件 | 路径 |
|
||||
|------|------|
|
||||
| Controller | `zt-module-system-server/.../controller/admin/integration/iwork/IWorkIntegrationController.java` |
|
||||
| Service | `zt-module-system-server/.../service/integration/iwork/impl/IWorkIntegrationServiceImpl.java` |
|
||||
| 日志 Service | `zt-module-system-server/.../service/integration/iwork/impl/IWorkWorkflowLogServiceImpl.java` |
|
||||
| MQ Producer | `zt-module-system-server/.../mq/iwork/IWorkBizCallbackProducer.java` |
|
||||
| MQ Listener | `zt-module-system-server/.../mq/iwork/IWorkBizCallbackListener.java` |
|
||||
| 消息定义 | `zt-module-system-api/.../mq/iwork/IWorkBizCallbackMessage.java` |
|
||||
| 配置类 | `zt-module-system-server/.../framework/integration/iwork/config/IWorkProperties.java` |
|
||||
Reference in New Issue
Block a user