1. 新增 OA Token 获取与校验接口,更新相关配置
2. 设置组织可以设置为顶层组织
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,7 @@ public class IWorkFileCallbackReqVO {
|
||||
|
||||
@Schema(description = "文件名称,可选", example = "合同附件.pdf")
|
||||
private String fileName;
|
||||
|
||||
@Schema(description = "OA 单点下载使用的 ssoToken,可选", example = "6102A7C13F09DD6B1AF06CDA0E479AC8...")
|
||||
private String ssoToken;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
// 校验父部门的有效性
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 远程调用相关配置 ####################
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user