Merge branch 'dev' into test
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);
|
||||
}
|
||||
|
||||
@@ -182,18 +182,83 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
}
|
||||
|
||||
AtomicReference<Long> 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<FileRespDTO> 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<String, String> 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)) {
|
||||
|
||||
@@ -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 远程调用相关配置 ####################
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user