diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java index ac795e86..b5a63c35 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java @@ -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 acquireOaToken(@Valid @RequestBody IWorkOaTokenReqVO reqVO) { + IWorkOaRawResponse resp = integrationService.getOaToken(reqVO); + return buildOaResponse(resp); + } + + @PostMapping("/oa/check") + @Operation(summary = "透传校验 OA Token") + public ResponseEntity checkOaToken(@Valid @RequestBody IWorkOaCheckTokenReqVO reqVO) { + IWorkOaRawResponse resp = integrationService.checkOaToken(reqVO); + return buildOaResponse(resp); + } + @PostMapping("/user/resolve") @Operation(summary = "根据外部标识获取 iWork 用户编号") public CommonResult resolveUser(@Valid @RequestBody IWorkUserInfoReqVO reqVO) { @@ -122,4 +138,20 @@ public class IWorkIntegrationController { public CommonResult fullSyncUsers(@Valid @RequestBody IWorkFullSyncReqVO reqVO) { return success(syncService.fullSyncUsers(reqVO)); } + + private ResponseEntity 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()); + } } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkFileCallbackReqVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkFileCallbackReqVO.java index 58519d84..12a5d2b5 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkFileCallbackReqVO.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkFileCallbackReqVO.java @@ -18,4 +18,7 @@ public class IWorkFileCallbackReqVO { @Schema(description = "文件名称,可选", example = "合同附件.pdf") private String fileName; + + @Schema(description = "OA 单点下载使用的 ssoToken,可选", example = "6102A7C13F09DD6B1AF06CDA0E479AC8...") + private String ssoToken; } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaCheckTokenReqVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaCheckTokenReqVO.java new file mode 100644 index 00000000..be77880b --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaCheckTokenReqVO.java @@ -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; +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaRawResponse.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaRawResponse.java new file mode 100644 index 00000000..45b5fc53 --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaRawResponse.java @@ -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 headers; +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaTokenReqVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaTokenReqVO.java new file mode 100644 index 00000000..bfbd488f --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOaTokenReqVO.java @@ -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; +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/framework/integration/iwork/config/IWorkProperties.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/framework/integration/iwork/config/IWorkProperties.java index 6097f31a..dde38deb 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/framework/integration/iwork/config/IWorkProperties.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/framework/integration/iwork/config/IWorkProperties.java @@ -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); } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java index 3cf54bee..ae4d35d0 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java @@ -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()); // 校验父部门的有效性 diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java index 90755ba2..5988e851 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java @@ -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); } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java index ef43ce49..445af73b 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java @@ -182,18 +182,83 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { } AtomicReference attachmentIdRef = new AtomicReference<>(); - TenantUtils.execute(tenantId, () -> attachmentIdRef.set(saveCallbackAttachment(fileUrl, reqVO.getFileName(), referenceBusinessFile))); + TenantUtils.execute(tenantId, () -> attachmentIdRef.set(saveCallbackAttachment(fileUrl, reqVO.getFileName(), referenceBusinessFile, reqVO.getSsoToken()))); return attachmentIdRef.get(); } - private Long saveCallbackAttachment(String fileUrl, String overrideFileName, BusinessFileRespDTO referenceBusinessFile) { + @Override + public IWorkOaRawResponse getOaToken(IWorkOaTokenReqVO reqVO) { + IWorkProperties.Oa oa = properties.getOa(); + if (oa == null) { + throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "OA 配置未初始化"); + } + String loginId = Optional.ofNullable(reqVO) + .map(IWorkOaTokenReqVO::getLoginId) + .map(String::trim) + .orElse(""); + if (!StringUtils.hasText(loginId)) { + throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "loginId 不能为空"); + } + String appId = Optional.ofNullable(reqVO) + .map(IWorkOaTokenReqVO::getAppId) + .filter(StringUtils::hasText) + .map(StringUtils::trimWhitespace) + .orElseGet(() -> StringUtils.trimWhitespace(oa.getAppId())); + if (!StringUtils.hasText(appId)) { + throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "OA appid 未配置"); + } + + String path = requireOaPath(oa.getPaths().getGetToken(), "iwork.oa.paths.get-token"); + + FormBody formBody = new FormBody.Builder() + .add("loginid", loginId) + .add("appid", appId) + .build(); + + Request request = new Request.Builder() + .url(resolveOaUrl(path)) + .post(formBody) + .build(); + + return executeOaRequest(request); + } + + @Override + public IWorkOaRawResponse checkOaToken(IWorkOaCheckTokenReqVO reqVO) { + IWorkProperties.Oa oa = properties.getOa(); + if (oa == null) { + throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "OA 配置未初始化"); + } + String token = Optional.ofNullable(reqVO) + .map(IWorkOaCheckTokenReqVO::getToken) + .map(String::trim) + .orElse(""); + if (!StringUtils.hasText(token)) { + throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "token 不能为空"); + } + + String path = requireOaPath(oa.getPaths().getCheckToken(), "iwork.oa.paths.check-token"); + + FormBody formBody = new FormBody.Builder() + .add("token", token) + .build(); + + Request request = new Request.Builder() + .url(resolveOaUrl(path)) + .post(formBody) + .build(); + + return executeOaRequest(request); + } + + private Long saveCallbackAttachment(String fileUrl, String overrideFileName, BusinessFileRespDTO referenceBusinessFile, String ssoToken) { Long businessId = referenceBusinessFile.getBusinessId(); FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO(); fileCreateReqDTO.setName(resolveFileName(overrideFileName, fileUrl)); fileCreateReqDTO.setDirectory(null); fileCreateReqDTO.setType(null); - fileCreateReqDTO.setContent(downloadFileBytes(fileUrl)); + fileCreateReqDTO.setContent(downloadFileBytes(fileUrl, ssoToken)); CommonResult fileResult = fileApi.createFileWithReturn(fileCreateReqDTO); if (fileResult == null || !fileResult.isSuccess() || fileResult.getData() == null) { @@ -232,9 +297,12 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return businessFile; } - private byte[] downloadFileBytes(String fileUrl) { + private byte[] downloadFileBytes(String fileUrl, String ssoToken) { + // 如果回调已提供 ssoToken,按需拼接后下载 OA 附件 + String finalUrl = appendSsoTokenIfNeeded(fileUrl, ssoToken); + OkHttpClient client = okHttpClient(); - Request request = new Request.Builder().url(fileUrl).get().build(); + Request request = new Request.Builder().url(finalUrl).get().build(); try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) { throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "下载文件失败,HTTP 状态码: " + response.code()); @@ -249,6 +317,22 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { } } + private String appendSsoTokenIfNeeded(String fileUrl, String ssoToken) { + // 未提供 token 或 URL 为空,直接返回原链接 + if (!StringUtils.hasText(ssoToken) || !StringUtils.hasText(fileUrl)) { + return fileUrl; + } + // 已包含 ssoToken(不区分大小写)则不重复添加 + String lower = fileUrl.toLowerCase(); + if (lower.contains("ssotoken=")) { + return fileUrl; + } + // 简单拼接查询参数 + return fileUrl.contains("?") + ? fileUrl + "&ssoToken=" + ssoToken + : fileUrl + "?ssoToken=" + ssoToken; + } + private String resolveFileName(String overrideName, String fileUrl) { if (StringUtils.hasText(overrideName)) { return overrideName; @@ -852,6 +936,30 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return baseUrl + path; } + private String resolveOaUrl(String path) { + IWorkProperties.Oa oa = properties.getOa(); + if (oa == null || !StringUtils.hasText(oa.getBaseUrl())) { + throw ServiceExceptionUtil.exception(IWORK_BASE_URL_MISSING, "iwork.oa.base-url 未配置"); + } + String baseUrl = oa.getBaseUrl(); + boolean baseEndsWithSlash = baseUrl.endsWith("/"); + boolean pathStartsWithSlash = StringUtils.hasText(path) && path.startsWith("/"); + if (baseEndsWithSlash && pathStartsWithSlash) { + return baseUrl + path.substring(1); + } + if (!baseEndsWithSlash && !pathStartsWithSlash) { + return baseUrl + "/" + path; + } + return baseUrl + path; + } + + private String requireOaPath(String path, String propertyPath) { + if (!StringUtils.hasText(path)) { + throw ServiceExceptionUtil.exception(IWORK_CONFIGURATION_INVALID, propertyPath + " 未配置"); + } + return StringUtils.trimWhitespace(path); + } + private String executeRequest(Request request, ErrorCode errorCode) { logCurlCommand(request); try (Response response = okHttpClient().newCall(request).execute()) { @@ -867,6 +975,47 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { } } + private IWorkOaRawResponse executeOaRequest(Request request) { + long start = System.currentTimeMillis(); + try (Response response = okHttpClient().newCall(request).execute()) { + ResponseBody responseBody = response.body(); + okhttp3.MediaType okhttpMediaType = responseBody != null ? responseBody.contentType() : null; + String bodyString = responseBody != null ? responseBody.string() : null; + + MediaType contentType = null; + if (okhttpMediaType != null) { + try { + contentType = MediaType.parseMediaType(okhttpMediaType.toString()); + } catch (Exception ignored) { + // ignore parse error + } + } + + Map headers = new LinkedHashMap<>(); + Headers respHeaders = response.headers(); + for (String name : respHeaders.names()) { + headers.put(name, respHeaders.get(name)); + } + + long duration = System.currentTimeMillis() - start; + String briefBody = abbreviate(bodyString, 200); + if (response.isSuccessful()) { + log.info("[OA] {} {} -> {} ({}ms)", request.method(), request.url(), response.code(), duration); + } else { + log.warn("[OA] {} {} -> {} ({}ms) body={}", request.method(), request.url(), response.code(), duration, briefBody); + } + + return IWorkOaRawResponse.builder() + .statusCode(response.code()) + .body(bodyString) + .contentType(contentType) + .headers(headers) + .build(); + } catch (IOException ex) { + throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "调用 OA 接口失败: " + ex.getMessage()); + } + } + private ServiceException buildRemoteException(ErrorCode errorCode, int statusCode, String responseBody) { String detail = buildRemoteErrorDetail(statusCode, responseBody); if (!StringUtils.hasText(detail)) { diff --git a/zt-module-system/zt-module-system-server/src/main/resources/application.yaml b/zt-module-system/zt-module-system-server/src/main/resources/application.yaml index 3369dc0d..2b0a2558 100644 --- a/zt-module-system/zt-module-system-server/src/main/resources/application.yaml +++ b/zt-module-system/zt-module-system-server/src/main/resources/application.yaml @@ -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 远程调用相关配置 #################### diff --git a/zt-server/src/main/resources/application.yaml b/zt-server/src/main/resources/application.yaml index da5fa087..5f303e9c 100644 --- a/zt-server/src/main/resources/application.yaml +++ b/zt-server/src/main/resources/application.yaml @@ -3,7 +3,7 @@ spring: name: zt-server profiles: - active: ${env.name} + active: dev main: allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 @@ -100,6 +100,12 @@ iwork: sync-user: workflow: seal-workflow-id: + 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 eplat: share: