Merge branch 'dev' into test

# Conflicts:
#	zt-module-template/zt-module-template-server/Dockerfile
This commit is contained in:
chenbowen
2025-12-03 18:02:24 +08:00
16 changed files with 99 additions and 123 deletions

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-gateway RUN mkdir -p /zt-gateway
@@ -11,15 +10,10 @@ COPY ./target/zt-gateway.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-gateway
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48080 EXPOSE 48080
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-module-ai-server RUN mkdir -p /zt-module-ai-server
@@ -11,15 +10,10 @@ COPY ./target/zt-module-ai-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-module-ai-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48090 EXPOSE 48090
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-module-bpm-server RUN mkdir -p /zt-module-bpm-server
@@ -11,15 +10,10 @@ COPY ./target/zt-module-bpm-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-module-bpm-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48083 EXPOSE 48083
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -59,7 +59,8 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final ApiGatewayAccessLogger accessLogger; private final ApiGatewayAccessLogger accessLogger;
private final AntPathMatcher pathMatcher = new AntPathMatcher(); private final AntPathMatcher pathMatcher = new AntPathMatcher();
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {}; private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {
};
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -68,32 +69,38 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
// 仅处理配置的 API 门户路径,不符合的请求直接放行 // 仅处理配置的 API 门户路径,不符合的请求直接放行
boolean matchesPortalPath = properties.getAllBasePaths() boolean matchesPortalPath = properties.getAllBasePaths()
.stream() .stream()
.map(this::normalizeBasePath)
.anyMatch(basePath -> pathMatcher.match(basePath + "/**", pathWithinApplication)); .anyMatch(basePath -> pathMatcher.match(basePath + "/**", pathWithinApplication));
if (!matchesPortalPath) { if (!matchesPortalPath) {
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
return; return;
} }
Long accessLogId = accessLogger.logEntrance(request); Long accessLogId = null;
// 校验访问 IP 是否落在允许范围内
if (!isIpAllowed(request)) {
log.warn("[API-PORTAL] 拦截来自 IP {} 访问 {} 的请求", request.getRemoteAddr(), pathWithinApplication);
response.sendError(HttpStatus.FORBIDDEN.value(), "IP 禁止访问");
accessLogger.finalizeEarly(request, HttpStatus.FORBIDDEN.value(), "IP 禁止访问");
return;
}
ApiGatewayProperties.Security security = properties.getSecurity(); ApiGatewayProperties.Security security = properties.getSecurity();
ApiClientCredentialDO credential = null; ApiClientCredentialDO credential = null;
if (!security.isEnabled()) { Long tenantId = null;
byte[] originalBody = StreamUtils.copyToByteArray(request.getInputStream());
CachedBodyHttpServletRequest passthroughRequest = new CachedBodyHttpServletRequest(request, originalBody);
ApiGatewayAccessLogger.propagateLogIdHeader(passthroughRequest, accessLogId);
filterChain.doFilter(passthroughRequest, response);
return;
}
boolean dispatchedToGateway = false; boolean dispatchedToGateway = false;
try { try {
Long tenantId = resolveTenantId(request); tenantId = resolveTenantId(request);
if (tenantId != null) {
// 绑定租户上下文,保证访问日志与后续数据库操作可写入 tenantId
TenantContextHolder.setTenantId(tenantId);
}
if (!isIpAllowed(request)) {
log.warn("[API-PORTAL] 拦截来自 IP {} 访问 {} 的请求", request.getRemoteAddr(), pathWithinApplication);
accessLogId = accessLogger.logEntrance(request);
response.sendError(HttpStatus.FORBIDDEN.value(), "IP 禁止访问");
accessLogger.finalizeEarly(request, HttpStatus.FORBIDDEN.value(), "IP 禁止访问");
return;
}
// IP 校验通过后再补录入口日志,避免无租户信息写库
accessLogId = accessLogger.logEntrance(request);
if (!security.isEnabled()) {
byte[] originalBody = StreamUtils.copyToByteArray(request.getInputStream());
CachedBodyHttpServletRequest passthroughRequest = new CachedBodyHttpServletRequest(request, originalBody);
ApiGatewayAccessLogger.propagateLogIdHeader(passthroughRequest, accessLogId);
filterChain.doFilter(passthroughRequest, response);
return;
}
// 从请求头解析 appId 并加载客户端凭证,包含匿名访问配置 // 从请求头解析 appId 并加载客户端凭证,包含匿名访问配置
String appId = requireHeader(request, APP_ID_HEADER, "缺少应用标识"); String appId = requireHeader(request, APP_ID_HEADER, "缺少应用标识");
credential = credentialService.findActiveCredential(appId) credential = credentialService.findActiveCredential(appId)
@@ -144,17 +151,27 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
responseWrapper.copyBodyToResponse(); responseWrapper.copyBodyToResponse();
} }
} catch (SecurityValidationException ex) { } catch (SecurityValidationException ex) {
if (accessLogId == null) {
accessLogId = accessLogger.logEntrance(request);
}
log.warn("[API-PORTAL] 安全校验失败: {}", ex.getMessage()); log.warn("[API-PORTAL] 安全校验失败: {}", ex.getMessage());
writeErrorResponse(response, security, credential, ex.status(), ex.getMessage()); writeErrorResponse(response, security, credential, ex.status(), ex.getMessage());
if (!dispatchedToGateway) { if (!dispatchedToGateway) {
accessLogger.finalizeEarly(request, ex.status().value(), ex.getMessage()); accessLogger.finalizeEarly(request, ex.status().value(), ex.getMessage());
} }
} catch (Exception ex) { } catch (Exception ex) {
if (accessLogId == null) {
accessLogId = accessLogger.logEntrance(request);
}
log.error("[API-PORTAL] 处理安全校验时出现异常", ex); log.error("[API-PORTAL] 处理安全校验时出现异常", ex);
writeErrorResponse(response, security, credential, HttpStatus.INTERNAL_SERVER_ERROR, "网关安全校验失败"); writeErrorResponse(response, security, credential, HttpStatus.INTERNAL_SERVER_ERROR, "网关安全校验失败");
if (!dispatchedToGateway) { if (!dispatchedToGateway) {
accessLogger.finalizeEarly(request, HttpStatus.INTERNAL_SERVER_ERROR.value(), "网关安全校验失败"); accessLogger.finalizeEarly(request, HttpStatus.INTERNAL_SERVER_ERROR.value(), "网关安全校验失败");
} }
} finally {
if (tenantId != null) {
TenantContextHolder.clear();
}
} }
} }
@@ -177,15 +194,6 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
return requestUri; return requestUri;
} }
private String normalizeBasePath(String basePath) {
String candidate = StringUtils.hasText(basePath) ? basePath : ApiGatewayProperties.DEFAULT_BASE_PATH;
candidate = candidate.startsWith("/") ? candidate : "/" + candidate;
if (candidate.endsWith("/")) {
candidate = candidate.substring(0, candidate.length() - 1);
}
return candidate;
}
private Long resolveTenantId(HttpServletRequest request) { private Long resolveTenantId(HttpServletRequest request) {
if (!properties.isEnableTenantHeader()) { if (!properties.isEnableTenantHeader()) {
return null; return null;
@@ -306,7 +314,6 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
}); });
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
log.debug("[API-PORTAL] 解析查询串 {} 失败", queryString, ex); log.debug("[API-PORTAL] 解析查询串 {} 失败", queryString, ex);
target.put("query", queryString);
} }
} }
@@ -321,7 +328,7 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
if (bodyText.startsWith("{")) { if (bodyText.startsWith("{")) {
try { try {
Map<String, Object> bodyMap = objectMapper.readValue(bodyText, MAP_TYPE); Map<String, Object> bodyMap = objectMapper.readValue(bodyText, MAP_TYPE);
bodyMap.forEach((key, value) -> target.put(key, normalizeValue(value))); target.putAll(bodyMap);
return; return;
} catch (JsonProcessingException ex) { } catch (JsonProcessingException ex) {
log.debug("[API-PORTAL] 解析请求体 JSON 失败", ex); log.debug("[API-PORTAL] 解析请求体 JSON 失败", ex);
@@ -330,20 +337,6 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
target.put("body", bodyText); target.put("body", bodyText);
} }
private Object normalizeValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Map || value instanceof List) {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException ex) {
return value.toString();
}
}
return value;
}
private String resolveEncryptionType(ApiClientCredentialDO credential, ApiGatewayProperties.Security security) { private String resolveEncryptionType(ApiClientCredentialDO credential, ApiGatewayProperties.Security security) {
if (credential != null && StringUtils.hasText(credential.getEncryptionType())) { if (credential != null && StringUtils.hasText(credential.getEncryptionType())) {
return credential.getEncryptionType(); return credential.getEncryptionType();
@@ -481,12 +474,12 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
response.resetBuffer(); response.resetBuffer();
response.setStatus(status.value()); response.setStatus(status.value());
String resolvedMessage = StringUtils.hasText(message) ? message : status.getReasonPhrase(); String resolvedMessage = StringUtils.hasText(message) ? message : status.getReasonPhrase();
String traceId = TracerUtils.getTraceId(); String traceId = TracerUtils.getTraceId();
ApiGatewayResponse envelope = ApiGatewayResponse.builder() ApiGatewayResponse envelope = ApiGatewayResponse.builder()
.code(status.value()) .code(status.value())
.message(resolvedMessage) .message(resolvedMessage)
.response(null) .response(null)
.traceId(traceId) .traceId(traceId)
.build(); .build();
if (shouldEncryptErrorResponse(security, credential)) { if (shouldEncryptErrorResponse(security, credential)) {
String encryptionKey = credential.getEncryptionKey(); String encryptionKey = credential.getEncryptionKey();

View File

@@ -24,6 +24,11 @@ public class BusinessFileRespDTO implements Serializable {
*/ */
private Long id; private Long id;
/**
* 租户编号
*/
private Long tenantId;
/** /**
* 业务Id * 业务Id
*/ */

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-module-infra-server RUN mkdir -p /zt-module-infra-server
@@ -11,15 +10,10 @@ COPY ./target/zt-module-infra-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-module-infra-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48082 EXPOSE 48082
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -16,6 +16,10 @@ public class BusinessFileRespVO {
@ExcelProperty("主键ID") @ExcelProperty("主键ID")
private Long id; private Long id;
@Schema(description = "租户编号", example = "1024")
@ExcelProperty("租户编号")
private Long tenantId;
@Schema(description = "业务Id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24322") @Schema(description = "业务Id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24322")
@ExcelProperty("业务Id") @ExcelProperty("业务Id")
private Long businessId; private Long businessId;

View File

@@ -24,6 +24,11 @@ public class BusinessFileDO extends BaseDO {
@TableId(type = IdType.ASSIGN_ID) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
/** /**
* 租户编号
*/
@TableField("TENANT_ID")
private Long tenantId;
/**
* 业务Id * 业务Id
*/ */
@TableField("BSN_ID") @TableField("BSN_ID")

View File

@@ -5,6 +5,7 @@ import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils; import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.common.util.user.UserNameEnrichUtils; import com.zt.plat.framework.common.util.user.UserNameEnrichUtils;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.framework.tenant.core.aop.TenantIgnore;
import com.zt.plat.module.infra.controller.admin.businessfile.vo.BusinessFilePageReqVO; import com.zt.plat.module.infra.controller.admin.businessfile.vo.BusinessFilePageReqVO;
import com.zt.plat.module.infra.controller.admin.businessfile.vo.BusinessFileRespVO; import com.zt.plat.module.infra.controller.admin.businessfile.vo.BusinessFileRespVO;
import com.zt.plat.module.infra.controller.admin.businessfile.vo.BusinessFileSaveReqVO; import com.zt.plat.module.infra.controller.admin.businessfile.vo.BusinessFileSaveReqVO;
@@ -101,6 +102,7 @@ public class BusinessFileServiceImpl implements BusinessFileService {
} }
@Override @Override
@TenantIgnore
public BusinessFileDO getBusinessFileByBusinessCode(String businessCode) { public BusinessFileDO getBusinessFileByBusinessCode(String businessCode) {
if (!StringUtils.hasText(businessCode)) { if (!StringUtils.hasText(businessCode)) {
throw exception(BUSINESS_FILE_NOT_EXISTS); throw exception(BUSINESS_FILE_NOT_EXISTS);

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
## 感谢复旦核博士的建议!灰子哥,牛皮! ## 感谢复旦核博士的建议!灰子哥,牛皮!
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-module-mp-server RUN mkdir -p /zt-module-mp-server
@@ -11,15 +10,10 @@ COPY ./target/zt-module-mp-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-module-mp-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48086 EXPOSE 48086
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-module-report-server RUN mkdir -p /zt-module-report-server
@@ -11,15 +10,10 @@ COPY ./target/zt-module-report-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-module-report-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48084 EXPOSE 48084
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-module-system-server RUN mkdir -p /zt-module-system-server
@@ -11,15 +10,10 @@ COPY ./target/zt-module-system-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-module-system-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48081 EXPOSE 48081
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -1,12 +1,14 @@
package com.zt.plat.module.system.controller.admin.integration.iwork; package com.zt.plat.module.system.controller.admin.integration.iwork;
import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.tenant.core.aop.TenantIgnore;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.*; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.*;
import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService; import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService;
import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService; import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService;
import com.zt.plat.module.system.service.integration.iwork.IWorkSyncService; import com.zt.plat.module.system.service.integration.iwork.IWorkSyncService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -14,7 +16,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.security.PermitAll;
import static com.zt.plat.framework.common.pojo.CommonResult.success; import static com.zt.plat.framework.common.pojo.CommonResult.success;
@@ -57,6 +58,7 @@ public class IWorkIntegrationController {
} }
@PermitAll @PermitAll
@TenantIgnore
@PostMapping("/callback/file") @PostMapping("/callback/file")
@Operation(summary = "iWork 文件回调:根据文件 URL 保存为附件并创建业务附件关联") @Operation(summary = "iWork 文件回调:根据文件 URL 保存为附件并创建业务附件关联")
public CommonResult<Long> callbackFile(@Valid @RequestBody IWorkFileCallbackReqVO reqVO) { public CommonResult<Long> callbackFile(@Valid @RequestBody IWorkFileCallbackReqVO reqVO) {

View File

@@ -19,6 +19,7 @@ import com.zt.plat.module.infra.api.file.dto.FileRespDTO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.*; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.*;
import com.zt.plat.module.system.framework.integration.iwork.config.IWorkProperties; import com.zt.plat.module.system.framework.integration.iwork.config.IWorkProperties;
import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService; import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService;
import com.zt.plat.framework.tenant.core.util.TenantUtils;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -37,6 +38,7 @@ import java.security.*;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.time.Instant; import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import static com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationErrorCodeConstants.*; import static com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationErrorCodeConstants.*;
@@ -171,11 +173,21 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
} }
BusinessFileRespDTO referenceBusinessFile = loadBusinessFileByBusinessCode(businessCode); BusinessFileRespDTO referenceBusinessFile = loadBusinessFileByBusinessCode(businessCode);
Long tenantId = referenceBusinessFile.getTenantId();
if (tenantId == null) {
throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "业务附件缺少租户信息,无法创建回调附件: " + businessCode);
}
AtomicReference<Long> attachmentIdRef = new AtomicReference<>();
TenantUtils.execute(tenantId, () -> attachmentIdRef.set(saveCallbackAttachment(fileUrl, reqVO.getFileName(), referenceBusinessFile)));
return attachmentIdRef.get();
}
private Long saveCallbackAttachment(String fileUrl, String overrideFileName, BusinessFileRespDTO referenceBusinessFile) {
Long businessId = referenceBusinessFile.getBusinessId(); Long businessId = referenceBusinessFile.getBusinessId();
// 通过文件 API 创建文件
FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO(); FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO();
fileCreateReqDTO.setName(resolveFileName(reqVO.getFileName(), fileUrl)); fileCreateReqDTO.setName(resolveFileName(overrideFileName, fileUrl));
fileCreateReqDTO.setDirectory(null); fileCreateReqDTO.setDirectory(null);
fileCreateReqDTO.setType(null); fileCreateReqDTO.setType(null);
fileCreateReqDTO.setContent(downloadFileBytes(fileUrl)); fileCreateReqDTO.setContent(downloadFileBytes(fileUrl));
@@ -188,8 +200,8 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
Long fileId = fileResult.getData().getId(); Long fileId = fileResult.getData().getId();
BusinessFileSaveReqDTO businessReq = BusinessFileSaveReqDTO.builder() BusinessFileSaveReqDTO businessReq = BusinessFileSaveReqDTO.builder()
.businessId(businessId) .businessId(businessId)
.businessCode(referenceBusinessFile.getBusinessCode()) .businessCode(referenceBusinessFile.getBusinessCode())
.fileId(fileId) .fileId(fileId)
.fileName(fileResult.getData().getName()) .fileName(fileResult.getData().getName())
.source("iwork") .source("iwork")

View File

@@ -10,7 +10,7 @@ COPY ./target/zt-module-template-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m" ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
## 暴露后端项目的 48080 端口 ## 暴露后端项目的 48080 端口
EXPOSE 48100 EXPOSE 48100

View File

@@ -1,7 +1,6 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性 ## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
ARG BASE_IMAGE=172.16.46.66:10043/base-service/skywalking-agent-jre:9.7.0 FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
FROM ${BASE_IMAGE}
## 创建目录,并使用它作为工作目录 ## 创建目录,并使用它作为工作目录
RUN mkdir -p /zt-server RUN mkdir -p /zt-server
@@ -12,11 +11,7 @@ COPY ./target/zt-server.jar app.jar
## 设置 TZ 时区 ## 设置 TZ 时区
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV JAVA_OPTS="-Xms512m -Xmx512m -Djava.security.egd=file:/dev/./urandom" ENV JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom"
ENV SW_AGENT_HOME=/opt/skywalking/agent
ENV SW_AGENT_NAME=zt-server
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.46.63:30201
ENV AGENT_JAVA_OPTS="-javaagent:${SW_AGENT_HOME}/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES}"
## 应用参数 ## 应用参数
ENV ARGS="" ENV ARGS=""
@@ -25,4 +20,4 @@ ENV ARGS=""
EXPOSE 48080 EXPOSE 48080
## 启动后端项目 ## 启动后端项目
CMD java ${AGENT_JAVA_OPTS} ${JAVA_OPTS} -jar app.jar $ARGS CMD java ${JAVA_OPTS} -jar app.jar $ARGS