1. 新增 OA Token 获取与校验接口,更新相关配置

2. 设置组织可以设置为顶层组织
This commit is contained in:
chenbowen
2025-12-08 18:56:06 +08:00
parent 8ea3757105
commit 91c0cbc5d7
11 changed files with 333 additions and 13 deletions

View File

@@ -12,6 +12,8 @@ import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -45,6 +47,20 @@ public class IWorkIntegrationController {
return success(integrationService.acquireToken(reqVO));
}
@PostMapping("/oa/token")
@Operation(summary = "透传获取 OA Token")
public ResponseEntity<String> acquireOaToken(@Valid @RequestBody IWorkOaTokenReqVO reqVO) {
IWorkOaRawResponse resp = integrationService.getOaToken(reqVO);
return buildOaResponse(resp);
}
@PostMapping("/oa/check")
@Operation(summary = "透传校验 OA Token")
public ResponseEntity<String> checkOaToken(@Valid @RequestBody IWorkOaCheckTokenReqVO reqVO) {
IWorkOaRawResponse resp = integrationService.checkOaToken(reqVO);
return buildOaResponse(resp);
}
@PostMapping("/user/resolve")
@Operation(summary = "根据外部标识获取 iWork 用户编号")
public CommonResult<IWorkUserInfoRespVO> resolveUser(@Valid @RequestBody IWorkUserInfoReqVO reqVO) {
@@ -122,4 +138,20 @@ public class IWorkIntegrationController {
public CommonResult<IWorkFullSyncRespVO> fullSyncUsers(@Valid @RequestBody IWorkFullSyncReqVO reqVO) {
return success(syncService.fullSyncUsers(reqVO));
}
private ResponseEntity<String> buildOaResponse(IWorkOaRawResponse resp) {
if (resp == null) {
return ResponseEntity.internalServerError().body("OA 响应为空");
}
HttpHeaders headers = new HttpHeaders();
if (resp.getHeaders() != null) {
resp.getHeaders().forEach(headers::add);
}
if (resp.getContentType() != null) {
headers.setContentType(resp.getContentType());
}
return ResponseEntity.status(resp.getStatusCode())
.headers(headers)
.body(resp.getBody());
}
}

View File

@@ -18,4 +18,7 @@ public class IWorkFileCallbackReqVO {
@Schema(description = "文件名称,可选", example = "合同附件.pdf")
private String fileName;
@Schema(description = "OA 单点下载使用的 ssoToken可选", example = "6102A7C13F09DD6B1AF06CDA0E479AC8...")
private String ssoToken;
}

View File

@@ -0,0 +1,16 @@
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;
/**
* 校验 OA Token 的请求参数。
*/
@Data
public class IWorkOaCheckTokenReqVO {
@Schema(description = "需要校验的 OA token")
@NotBlank(message = "token 不能为空")
private String token;
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.MediaType;
import java.util.Map;
/**
* 封装 OA 接口的原始返回,用于透传 HTTP 状态与 body。
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IWorkOaRawResponse {
private int statusCode;
private String body;
private MediaType contentType;
private Map<String, String> headers;
}

View File

@@ -0,0 +1,19 @@
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;
/**
* 获取 OA Token 的请求参数。
*/
@Data
public class IWorkOaTokenReqVO {
@Schema(description = "OA 登录账号 loginid", example = "zixun004")
@NotBlank(message = "loginId 不能为空")
private String loginId;
@Schema(description = "应用 appid未填则使用配置默认值", example = "a17ca6ca-88b0-463e-bffa-7995086bf225")
private String appId;
}

View File

@@ -42,6 +42,7 @@ public class IWorkProperties {
private final Client client = new Client();
private final OrgRest org = new OrgRest();
private final Workflow workflow = new Workflow();
private final Oa oa = new Oa();
@Data
public static class Paths {
@@ -126,6 +127,34 @@ public class IWorkProperties {
private String sealWorkflowId;
}
@Data
public static class Oa {
/**
* OA 网关基础地址例如http://172.16.36.233:8080
*/
private String baseUrl;
/**
* 默认 appid调用方未传时使用。
*/
private String appId;
private final OaPaths paths = new OaPaths();
}
@Data
public static class OaPaths {
/**
* 获取 token 的接口路径,例如:/ssologin/getToken
*/
private String getToken;
/**
* 校验 token 的接口路径,例如:/ssologin/checkToken
*/
private String checkToken;
}
/**
* 是否显式配置了关键参数,用于判断是否需要提示用户。
*/
@@ -139,7 +168,8 @@ public class IWorkProperties {
|| client.getConnectTimeout() != null
|| client.getResponseTimeout() != null
|| hasText(org.getTokenSeed())
|| hasText(workflow.getSealWorkflowId());
|| hasText(workflow.getSealWorkflowId())
|| hasAnyOaConfigured();
}
/**
@@ -174,6 +204,20 @@ public class IWorkProperties {
if (!hasText(workflow.getSealWorkflowId())) {
issues.add("iwork.workflow.seal-workflow-id 未配置");
}
if (oa != null) {
if (!hasText(oa.getBaseUrl())) {
issues.add("iwork.oa.base-url 未配置");
}
if (!hasText(oa.getAppId())) {
issues.add("iwork.oa.app-id 未配置");
}
if (oa.getPaths() == null || !hasText(oa.getPaths().getGetToken())) {
issues.add("iwork.oa.paths.get-token 未配置");
}
if (oa.getPaths() == null || !hasText(oa.getPaths().getCheckToken())) {
issues.add("iwork.oa.paths.check-token 未配置");
}
}
return issues;
}
@@ -185,6 +229,13 @@ public class IWorkProperties {
|| hasText(paths.getVoidWorkflow());
}
private boolean hasAnyOaConfigured() {
return oa != null && (hasText(oa.getBaseUrl())
|| hasText(oa.getAppId())
|| (oa.getPaths() != null && (hasText(oa.getPaths().getGetToken())
|| hasText(oa.getPaths().getCheckToken()))));
}
private boolean hasText(String value) {
return StringUtils.hasText(value);
}

View File

@@ -66,9 +66,8 @@ public class DeptServiceImpl implements DeptService {
@CacheEvict(cacheNames = RedisKeyConstants.DEPT_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个部门,涉及到多个缓存
public Long createDept(DeptSaveReqVO createReqVO) {
if (createReqVO.getParentId() == null) {
createReqVO.setParentId(DeptDO.PARENT_ID_ROOT);
}
// 允许上级组织为空,视为顶级组织
createReqVO.setParentId(normalizeParentId(createReqVO.getParentId()));
// 创建时默认有效
createReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
// 校验父部门的有效性
@@ -113,9 +112,8 @@ public class DeptServiceImpl implements DeptService {
allEntries = true) // allEntries 清空所有缓存,因为操作一个部门,涉及到多个缓存
@DataPermission(enable = false) // 禁用数据权限,避免确实上级部门导致无法保存
public void updateDept(DeptSaveReqVO updateReqVO) {
if (updateReqVO.getParentId() == null) {
updateReqVO.setParentId(DeptDO.PARENT_ID_ROOT);
}
// 允许上级组织为空,视为顶级组织
updateReqVO.setParentId(normalizeParentId(updateReqVO.getParentId()));
// 校验自己存在
DeptDO originalDept = getRequiredDept(updateReqVO.getId());
// 校验父部门的有效性

View File

@@ -6,6 +6,9 @@ import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkAuth
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkAuthTokenRespVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkFileCallbackReqVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOperationRespVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOaCheckTokenReqVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOaRawResponse;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOaTokenReqVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkUserInfoReqVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkUserInfoRespVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkWorkflowCreateReqVO;
@@ -48,4 +51,14 @@ public interface IWorkIntegrationService {
* @return 创建的业务附件关联记录 ID 或附件 ID视实现而定
*/
Long handleFileCallback(IWorkFileCallbackReqVO reqVO);
/**
* 透传调用 OA 获取 token。
*/
IWorkOaRawResponse getOaToken(IWorkOaTokenReqVO reqVO);
/**
* 透传调用 OA 校验 token。
*/
IWorkOaRawResponse checkOaToken(IWorkOaCheckTokenReqVO reqVO);
}

View File

@@ -134,6 +134,12 @@ iwork:
sync-user: /api/hrm/resful/synHrmresource
workflow:
seal-workflow-id: "1753"
oa:
base-url: http://172.16.36.233:8080
app-id: a17ca6ca-88b0-463e-bffa-7995086bf225
paths:
get-token: /ssologin/getToken
check-token: /ssologin/checkToken
--- #################### RPC 远程调用相关配置 ####################