主题
增量/全量拉取待办数据
为了解决业务方推送待办到待办中心异常情况,待办中心提供补偿轮询机制,需要业务方按照一下规则实现接口。
业务系统需要按照以下接口标准提供增量/全量同步待办数据接口
接口定义
| 接口名称 | url | 请求方式 | 请求数据类型 |
|---|---|---|---|
| 获取增量/全量待办列表 | 业务系统定义 | GET | multipart/form-data |
请求参数
| 参数名称 | 参数说明 | 是否必填 | 数据类型 | 备注说明 |
|---|---|---|---|---|
| appId | 应用id | 是 | string | 分配的应用ID |
| startTime | 开始时间戳 | 是 | long | 起始时间 这个时间的查询逻辑是数据最后更新时间 时间跨度 不大于30天 |
| endTime | 结束时间戳 | 是 | long | 结束时间 这个时间的查询逻辑是数据最后更新时间 时间跨度 不大于30天 |
| receptionId | 接收人ID | 否 | String | 接收用户工号 |
| deal | 处理状态 | 否 | Integer | 0 待处理 1.已处理 |
| page | 当前页 | 是 | long | 当前页 |
| size | 每页条数 | 是 | long | 每页条数 (不大于500条) |
| sign | 加签校验 | 是 | string | 业务系统根据加签规则生成值进行校验,具体生成方法如下示例 |
| signTime | 加签生成时间戳 | 是 | string | 加签生成时间戳 |
返回值
| 参数名称 | 参数说明 | 数据类型 | 备注说明 |
|---|---|---|---|
| appId | 应用id | string | 分配的应用ID |
| type | 待办类型 | Integer | 0 审批类;1: 通知类; |
| deal | 处理状态 | Integer | 0表示未办,1表示已办 |
| status | 待办状态 | Integer | 10.待审批,11.待阅,20.通过,21.已阅,30.拒绝,31.驳回,32.撤销 |
| sourceId | 业务记录ID | String | 在同一批次下的唯一标识- |
| batchId | 批次ID | String | 批次ID-标识是同一条审批流程的编号-在同一审批中这个应该唯一,(如果新增待办的时候没有传这个参数 补偿的时候也不需要返回) |
| content | 消息内容 | string | 消息内容 |
| title | 标题 | string | 标题 |
| receptionId | 接收人id | string | 接收人id 内部员工工号,三方人员为人员组织中心中顾问工号 |
| senderId | 发送人id | string | 内部员工工号,三方人员为人员组织中心中顾问工号 如果没有发起人 传0为系统发起 |
| startTime | 流程开始时间 | string | 流程开始时间 ‘2025-04-01 10:00:00’ |
| moduleSource | 模块来源 | string | 模块来源 |
| url | pc跳转地址 | string | 用户在待办中心点击待办时跳转地址,跳转时会根据应用注册协议拼接凭证到URL后面,业务系统可根据统一认证相关接口获取用户信息 |
| urlApp | app跳转地址 | string | 用户在待办中心点击待办时跳转地址 |
| processStatus | 待办中心是否可处理 | Integer | 0-不可以处理(默认),1-可以处理 (如果设置为1 那么待办中心可以处理待办并修改待办状态,为0则不允许待办中心处理待办。设置为1需要提供回调接口 对接待办中心处理后回调同步待办状态) |
| sysTag | 系统标识 | string | 系统标识 标识子系统 |
json
{
"code":200,
"count":总数,
"data":[{
"appId":"注册应用返回的client_id",
"type": "1",
"deal": "0",
"status":"11",
"sourceId":"应用待办的唯一编号",
"batchId":"标识是同一条审批流程的编号,同一流程实例不同节点批次ID相同",
"content":"消息内容",
"title":"标题",
"receptionId":"接收人id",
"senderId":"发送人id",
"startTime":"流程开始时间",
"asterisk":"星标",
"moduleSource":"模块来源",
"url":"pc跳转地址",
"urlApp":"app跳转地址",
"passUrl":"待办中心处理待办数据回调接口"
}]
}请求示例
json
curl --request GET \
--url 'http://127.0.0.1:8009/api/todo-manage/app/info/open/pullTodoData?appId=1109453752143708160&startTime=1760947769862&endTime=1761034170323&page=1&size=50&signTime=1761035753955&sign=%20vxO%2FrnUF9ltPpDt3YDIegn0aEs%3D' \
--header 'Accept: */*' \
--header 'Accept-Encoding: gzip, deflate, br' \
--header 'Connection: keep-alive' \
--header 'User-Agent: PostmanRuntime-ApipostRuntime/1.1.0'加签验证代码
java
public static void main(String[] args) throws Exception {
this.validateTimeStamp(sginTime);
Map<String, String> parameter = new HashMap<>();
parameter.put("clientId", appId);
parameter.put("timestamp", sginTime);// 根据传来的参sginTime
String sign = this.generateSign(parameter, GET, secret);
}
public static final String ALGORITHM = "HmacSHA1";
public static String validateTimeStamp(String timestamp) {
if (!org.springframework.util.StringUtils.hasText(timestamp)) {
return "timestamp不能为空"; //"timestamp不能为空"
}
if (!isNumeric(timestamp)) {
return "timestamp必须是数字";//"timestamp必须是数字"
}
// 时间戳验证 当前时间 - 请求时间戳
if (Math.abs(System.currentTimeMillis() - Long.parseLong(timestamp)) > DEFAULT_TIME_STAMP_180_000) {
return "时间戳3分钟内有效";
}
return "success";
}
/**
* 构建签名数据
*
* @return 签名数据
*/
public static String buildSigningString(Map<String, String> parameters, String httpMethod) {
// 排序请求参数
String[] sortedKeys = parameters.keySet().toArray(new String[]{});
Arrays.sort(sortedKeys);
StringBuilder stringToSign = new StringBuilder();
if(StringUtils.isNotBlank(httpMethod)) {
stringToSign.append(httpMethod).append(CommonConstants.Symbol.SEPARATOR);
}
StringBuilder canonicalizedQueryString = new StringBuilder();
for (String key : sortedKeys) {
if (StringUtils.isBlank(parameters.get(key))) {
continue;
}
canonicalizedQueryString.append(CommonConstants.Symbol.SEPARATOR)
.append(percentEncode(key)).append("=")
.append(percentEncode(parameters.get(key)));
}
stringToSign.append(percentEncode(canonicalizedQueryString.substring(1)));
return stringToSign.toString();
}
public static String percentEncode(String value) {
return value != null ? URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
}
/**
* 生成 HMAC-SHA1 签名
*/
public static String generateSign(Map<String, String> parameters, String httpMethod, String secret) throws Exception {
String data = buildSigningString(parameters, httpMethod);
return generateSign(data, secret);
}
/**
* 生成 HMAC-SHA1 签名
*/
public static String generateSign(String data, String secret) throws Exception {
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), ALGORITHM));
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}