1. 清理 iwork 同步的旧逻辑
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 传递给 iWork 的单条明细记录。
|
||||
*/
|
||||
@Data
|
||||
public class IWorkDetailRecordVO {
|
||||
|
||||
@Schema(description = "记录序号,从 0 开始", example = "0")
|
||||
private Integer recordOrder;
|
||||
|
||||
@Schema(description = "明细字段列表")
|
||||
@NotEmpty(message = "明细字段不能为空")
|
||||
@Valid
|
||||
private List<IWorkFormFieldVO> fields;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* iWork 流程请求中的明细表定义。
|
||||
*/
|
||||
@Data
|
||||
public class IWorkDetailTableVO {
|
||||
|
||||
@Schema(description = "表名", example = "formtable_main_26_dt1")
|
||||
@NotBlank(message = "明细表名不能为空")
|
||||
private String tableDBName;
|
||||
|
||||
@Schema(description = "明细记录集合")
|
||||
@NotEmpty(message = "明细记录不能为空")
|
||||
@Valid
|
||||
private List<IWorkDetailRecordVO> records;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 提交给 iWork 的单个表单字段。
|
||||
*/
|
||||
@Data
|
||||
public class IWorkFormFieldVO {
|
||||
|
||||
@Schema(description = "字段名", example = "sqr")
|
||||
@NotBlank(message = "字段名不能为空")
|
||||
private String fieldName;
|
||||
|
||||
@Schema(description = "字段值", example = "张三")
|
||||
@NotBlank(message = "字段值不能为空")
|
||||
private String fieldValue;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -11,12 +12,49 @@ import java.util.Map;
|
||||
@Data
|
||||
public class IWorkOperationRespVO {
|
||||
|
||||
@Schema(description = "iWork 返回的原始数据")
|
||||
private Map<String, Object> payload;
|
||||
@Schema(description = "iWork 返回的原始数据结构")
|
||||
private Payload payload;
|
||||
|
||||
@Schema(description = "是否判断为成功")
|
||||
private boolean success;
|
||||
|
||||
@Schema(description = "返回提示信息")
|
||||
private String message;
|
||||
|
||||
@Data
|
||||
public static class Payload {
|
||||
|
||||
@Schema(description = "iWork 返回的业务状态码,例如 SUCCESS")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "iWork 返回的数据体")
|
||||
private PayloadData data;
|
||||
|
||||
@Schema(description = "错误信息对象,通常为空对象")
|
||||
private Map<String, Object> errMsg;
|
||||
|
||||
@Schema(description = "返回失败时的详细信息")
|
||||
private ReqFailMsg reqFailMsg;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PayloadData {
|
||||
|
||||
@Schema(description = "iWork 生成的请求编号 requestid")
|
||||
@JsonProperty("requestid")
|
||||
private Long requestId;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ReqFailMsg {
|
||||
|
||||
@Schema(description = "失败时的关键参数集合")
|
||||
private Map<String, Object> keyParameters;
|
||||
|
||||
@Schema(description = "失败消息对象")
|
||||
private Map<String, Object> msgInfo;
|
||||
|
||||
@Schema(description = "其他附加参数,例如 doAutoApprove")
|
||||
private Map<String, Object> otherParams;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 查询 iWork 人力组织信息所需的参数。
|
||||
*/
|
||||
@Data
|
||||
public class IWorkOrgQueryReqVO {
|
||||
|
||||
@Schema(description = "当前页码", example = "1")
|
||||
private Integer curpage;
|
||||
|
||||
@Schema(description = "每页条数", example = "10")
|
||||
private Integer pagesize;
|
||||
|
||||
// ================= 分部查询 =================
|
||||
|
||||
@Schema(description = "分部编码")
|
||||
private String subcompanyCode;
|
||||
|
||||
@Schema(description = "分部名称")
|
||||
private String subcompanyName;
|
||||
|
||||
// ================= 部门查询 =================
|
||||
|
||||
@Schema(description = "部门编码")
|
||||
private String departmentCode;
|
||||
|
||||
@Schema(description = "部门名称")
|
||||
private String departmentName;
|
||||
|
||||
@Schema(description = "所属分部ID")
|
||||
private String subcompanyId;
|
||||
|
||||
// ================= 岗位查询 =================
|
||||
|
||||
@Schema(description = "岗位编码")
|
||||
private String jobTitleCode;
|
||||
|
||||
@Schema(description = "岗位名称")
|
||||
private String jobTitleName;
|
||||
|
||||
// ================= 人员查询 =================
|
||||
|
||||
@Schema(description = "人员工号")
|
||||
private String workCode;
|
||||
|
||||
@Schema(description = "人员姓名")
|
||||
private String lastName;
|
||||
|
||||
@Schema(description = "所属部门ID")
|
||||
private String departmentId;
|
||||
|
||||
@Schema(description = "所属岗位ID")
|
||||
private String jobTitleId;
|
||||
|
||||
@Schema(description = "人员状态 (0:试用, 1:正式, 2:临时, 3:试用延期, 4:解聘, 5:离职, 6:退休, 7:无效)")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "查询参数(扩展用),将被序列化为 params 传给 iWork")
|
||||
private Map<String, Object> params;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 获取 iWork 会话令牌的请求载荷。
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class IWorkTokenApplyReqVO extends IWorkBaseReqVO {
|
||||
}
|
||||
@@ -97,11 +97,6 @@ public class IWorkProperties {
|
||||
*/
|
||||
@Min(value = 1, message = "iWork Token 有效期必须大于 0")
|
||||
private long ttlSeconds;
|
||||
/**
|
||||
* Token 过期前提前刷新的秒数。
|
||||
*/
|
||||
@Min(value = 0, message = "iWork Token 提前刷新秒数不能为负数")
|
||||
private long refreshAheadSeconds;
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.zt.plat.module.system.framework.integration.iwork.config.IWorkPropert
|
||||
import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import okio.Buffer;
|
||||
@@ -59,10 +58,6 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
private final FileApi fileApi;
|
||||
private final BusinessFileApi businessFileApi;
|
||||
|
||||
private final Cache<SessionKey, IWorkSession> sessionCache = Caffeine.newBuilder()
|
||||
.maximumSize(256)
|
||||
.build();
|
||||
|
||||
private final Cache<String, RegistrationState> registrationCache = Caffeine.newBuilder()
|
||||
.maximumSize(32)
|
||||
.build();
|
||||
@@ -104,7 +99,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
boolean force = forceRegistration || forceToken;
|
||||
|
||||
ClientKeyPair clientKeyPair = resolveClientKeyPair(appId, forceRegistration);
|
||||
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, force);
|
||||
IWorkSession session = createSession(appId, clientKeyPair, operatorUserId, force);
|
||||
|
||||
IWorkAuthTokenRespVO respVO = new IWorkAuthTokenRespVO();
|
||||
respVO.setAppId(appId);
|
||||
@@ -124,7 +119,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
String operatorUserId = resolveOperatorUserId(reqVO.getOperatorUserId());
|
||||
ensureIdentifier(reqVO.getIdentifierKey(), reqVO.getIdentifierValue());
|
||||
|
||||
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
IWorkSession session = createSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
Map<String, Object> payload = buildUserPayload(reqVO);
|
||||
String responseBody = executeJsonRequest(properties.getPaths().getUserInfo(), reqVO.getQueryParams(), appId, session, payload);
|
||||
|
||||
@@ -137,7 +132,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
String appId = resolveAppId();
|
||||
ClientKeyPair clientKeyPair = resolveClientKeyPair(appId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
String operatorUserId = resolveOperatorUserId(reqVO.getOperatorUserId());
|
||||
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
IWorkSession session = createSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
|
||||
Map<String, Object> payload = buildCreatePayload(reqVO);
|
||||
String responseBody = executeFormRequest(properties.getPaths().getCreateWorkflow(), null, appId, session, payload);
|
||||
@@ -153,7 +148,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
if (!StringUtils.hasText(reqVO.getRequestId())) {
|
||||
throw ServiceExceptionUtil.exception(IWORK_USER_IDENTIFIER_MISSING);
|
||||
}
|
||||
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
IWorkSession session = createSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||
|
||||
Map<String, Object> payload = buildVoidPayload(reqVO);
|
||||
String responseBody = executeJsonRequest(properties.getPaths().getVoidWorkflow(), null, appId, session, payload);
|
||||
@@ -308,26 +303,6 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
}
|
||||
}
|
||||
|
||||
private IWorkSession ensureSession(String appId, ClientKeyPair clientKeyPair, String operatorUserId, boolean forceRefresh) {
|
||||
SessionKey key = new SessionKey(appId, operatorUserId);
|
||||
Instant now = Instant.now();
|
||||
if (!forceRefresh) {
|
||||
IWorkSession cached = sessionCache.getIfPresent(key);
|
||||
if (cached != null && cached.isValid(now, properties.getToken().getRefreshAheadSeconds())) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
synchronized (key.intern()) {
|
||||
IWorkSession cached = sessionCache.getIfPresent(key);
|
||||
if (!forceRefresh && cached != null && cached.isValid(now, properties.getToken().getRefreshAheadSeconds())) {
|
||||
return cached;
|
||||
}
|
||||
IWorkSession session = createSession(appId, clientKeyPair, operatorUserId, forceRefresh);
|
||||
sessionCache.put(key, session);
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
private IWorkSession createSession(String appId, ClientKeyPair clientKeyPair, String operatorUserId, boolean forceRefreshRegistration) {
|
||||
RegistrationState registration = obtainRegistration(appId, clientKeyPair, forceRefreshRegistration);
|
||||
String encryptedSecret = encryptWithPublicKey(registration.secret(), registration.spk());
|
||||
@@ -651,7 +626,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
return respVO;
|
||||
}
|
||||
JsonNode node = parseJson(responseBody, IWORK_REMOTE_REQUEST_FAILED);
|
||||
respVO.setPayload(objectMapper.convertValue(node, MAP_TYPE));
|
||||
respVO.setPayload(objectMapper.convertValue(node, IWorkOperationRespVO.Payload.class));
|
||||
respVO.setSuccess(isSuccess(node));
|
||||
respVO.setMessage(resolveMessage(node));
|
||||
return respVO;
|
||||
@@ -992,46 +967,5 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
this.expiresAt = expiresAt;
|
||||
this.spk = spk;
|
||||
}
|
||||
|
||||
private boolean isValid(Instant now, long refreshAheadSeconds) {
|
||||
Instant refreshThreshold = expiresAt.minusSeconds(Math.max(0L, refreshAheadSeconds));
|
||||
return refreshThreshold.isAfter(now) && StringUtils.hasText(token) && StringUtils.hasText(encryptedUserId);
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
private static final class SessionKey {
|
||||
private final String appId;
|
||||
private final String operatorUserId;
|
||||
|
||||
private SessionKey(String appId, String operatorUserId) {
|
||||
this.appId = appId;
|
||||
this.operatorUserId = operatorUserId;
|
||||
}
|
||||
|
||||
private String cacheKey() {
|
||||
return appId + "::" + operatorUserId;
|
||||
}
|
||||
|
||||
private String intern() {
|
||||
return cacheKey().intern();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SessionKey that)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(appId, that.appId)
|
||||
&& Objects.equals(operatorUserId, that.operatorUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(appId, operatorUserId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,6 @@ iwork:
|
||||
void-workflow: /api/workflow/paService/doCancelRequest
|
||||
token:
|
||||
ttl-seconds: 3600
|
||||
refresh-ahead-seconds: 60
|
||||
client:
|
||||
connect-timeout: 60s
|
||||
response-timeout: 60s
|
||||
|
||||
Reference in New Issue
Block a user