From 00290755429de1524a1bbe11b7267a411c67bf55 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 10 Oct 2024 16:50:11 +0800 Subject: [PATCH 01/49] =?UTF-8?q?feat(=E8=B0=83=E7=94=A8=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E5=BE=AE=E6=9C=8D=E5=8A=A1):=20=E5=A4=84=E7=90=86Sent?= =?UTF-8?q?inel=E8=AF=B7=E6=B1=82=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 识别到Sentinel请求时,调用Sentinel登录接口获取Token并写入到Cookie中,用于Sentinel后续接口的鉴权操作 Signed-off-by: OTTO <731554297@qq.com> --- .../system/api/RemoteGatewayService.java | 23 ++++++++++ .../system/api/RemoteZoneService.java | 4 +- .../factory/RemoteGatewayFallbackFactory.java | 29 ++++++++++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../core/constant/ServiceNameConstants.java | 4 ++ .../common/core/constant/TokenConstants.java | 4 ++ .../common/core/utils/CookieUtil.java | 40 +++++++++++++++++ .../gateway/filter/AuthFilter.java | 44 ++++++++++++++++++- 8 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java create mode 100644 microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java create mode 100644 microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/utils/CookieUtil.java diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java new file mode 100644 index 000000000..661f3ebc9 --- /dev/null +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java @@ -0,0 +1,23 @@ +package com.microservices.system.api; + +import com.microservices.common.core.constant.ServiceNameConstants; +import com.microservices.system.api.factory.RemoteGatewayFallbackFactory; +import feign.Response; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +/** + * 网关 + * + * @author microservices + */ +@FeignClient(contextId = "remoteGatewayService", value = ServiceNameConstants.GATEWAY_SERVICE, fallbackFactory = RemoteGatewayFallbackFactory.class) +public interface RemoteGatewayService { + /** + * 登录Sentinel + * + * @return 响应 + */ + @PostMapping("/sentinel/auth/login?password=sentinel&username=sentinel") + public Response loginSentinel(); +} diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteZoneService.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteZoneService.java index 9663b6317..257f50f09 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteZoneService.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteZoneService.java @@ -4,7 +4,7 @@ import com.microservices.common.core.constant.SecurityConstants; import com.microservices.common.core.constant.ServiceNameConstants; import com.microservices.common.core.domain.R; import com.microservices.system.api.domain.SysDept; -import com.microservices.system.api.factory.RemoteCmsFallbackFactory; +import com.microservices.system.api.factory.RemoteZoneFallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; @@ -15,7 +15,7 @@ import java.util.List; * * @author microservices */ -@FeignClient(contextId = "remoteZoneService", value = ServiceNameConstants.ZONE_SERVICE, fallbackFactory = RemoteCmsFallbackFactory.class) +@FeignClient(contextId = "remoteZoneService", value = ServiceNameConstants.ZONE_SERVICE, fallbackFactory = RemoteZoneFallbackFactory.class) public interface RemoteZoneService { /** * 新增组织时自动创建特色专区 diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java new file mode 100644 index 000000000..85d534e6a --- /dev/null +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java @@ -0,0 +1,29 @@ +package com.microservices.system.api.factory; + +import com.microservices.system.api.RemoteGatewayService; +import feign.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * 用户服务降级处理 + * + * @author microservices + */ +@Component +public class RemoteGatewayFallbackFactory implements FallbackFactory { + private static final Logger log = LoggerFactory.getLogger(RemoteGatewayFallbackFactory.class); + + @Override + public RemoteGatewayService create(Throwable throwable) { + log.error("网关服务调用失败:{}", throwable.getMessage()); + return new RemoteGatewayService() { + @Override + public Response loginSentinel() { + return null; + } + }; + } +} diff --git a/microservices-api/microservices-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/microservices-api/microservices-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 4610a12d4..707296a15 100644 --- a/microservices-api/microservices-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/microservices-api/microservices-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -5,3 +5,4 @@ com.microservices.system.api.factory.RemoteFileFallbackFactory com.microservices.system.api.factory.RemoteCmsFallbackFactory com.microservices.system.api.factory.RemoteZoneFallbackFactory com.microservices.system.api.factory.RemotePmsFallbackFactory +com.microservices.system.api.factory.RemoteGatewayFallbackFactory diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ServiceNameConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ServiceNameConstants.java index 6b7f22b25..b212bedec 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ServiceNameConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ServiceNameConstants.java @@ -32,4 +32,8 @@ public class ServiceNameConstants { * 项目管理模块的serviceid */ public static final String PMS_SERVICE = "microservices-pms"; + /** + * 网关模块的serviceid + */ + public static final String GATEWAY_SERVICE = "microservices-gateway"; } diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java index a56358dc4..a74ad6b35 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java @@ -18,6 +18,10 @@ public class TokenConstants { * GitLink令牌标识 */ public static final String GitLink_Token_Key = "autologin_trustie="; + /** + * Sentinel令牌标识 + */ + public static final String Sentinel_Token_Key = "sentinel_dashboard_cookie"; /** * Cookie中令牌标识 */ diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/utils/CookieUtil.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/utils/CookieUtil.java new file mode 100644 index 000000000..d43cddcf0 --- /dev/null +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/utils/CookieUtil.java @@ -0,0 +1,40 @@ +package com.microservices.common.core.utils; + +import java.util.HashMap; + +public class CookieUtil { + + + public static HashMap getCookieMap(String cookie) { + HashMap map = new HashMap<>(); + if (cookie != null) { + String[] cookies = cookie.split(";"); + for (String cookieStr : cookies) { + String[] cookieArr = cookieStr.split("="); + String key = cookieArr[0].trim(); + String value = cookieArr[0].trim(); + map.put(key, value); + } + } + return map; + } + + public static String getCookieValue(String cookie, String key) { + HashMap map = getCookieMap(cookie); + return map.get(key); + } + + public static String removeCookieKey(String cookie, String key) { + HashMap map = getCookieMap(cookie); + map.remove(key); + return genCookieStr(map); + } + + private static String genCookieStr(HashMap cookieMap) { + StringBuilder stringBuilder = new StringBuilder(); + for (String key : cookieMap.keySet()) { + stringBuilder.append(key).append("=").append(cookieMap.get(key)).append(";"); + } + return stringBuilder.toString(); + } +} diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index 939ba5d3b..a0b8cdc88 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -6,14 +6,17 @@ import com.microservices.common.core.constant.SecurityConstants; import com.microservices.common.core.constant.TokenConstants; import com.microservices.common.core.domain.R; import com.microservices.common.core.exception.ServiceException; +import com.microservices.common.core.utils.CookieUtil; import com.microservices.common.core.utils.JwtUtils; import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.StringUtils; import com.microservices.common.redis.service.RedisService; import com.microservices.gateway.config.properties.IgnoreWhiteProperties; +import com.microservices.system.api.RemoteGatewayService; import com.microservices.system.api.RemoteUserService; import com.microservices.system.api.domain.SysUserDeptRole; import com.microservices.system.api.utils.FeignUtils; +import feign.Response; import io.jsonwebtoken.Claims; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,10 +30,13 @@ import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; /** * 网关鉴权 @@ -50,9 +56,43 @@ public class AuthFilter implements GlobalFilter, Ordered { @Lazy @Autowired private RemoteUserService remoteUserService; + @Lazy + @Autowired + private RemoteGatewayService remoteGatewayService; ExecutorService executorService = Executors.newFixedThreadPool(1); + /** + * 处理第三方工具请求 + */ + private void handleRequestForThirdPartyTools(ServerHttpRequest request, ServerHttpRequest.Builder mutate) { + String url = request.getURI().getPath(); + if (StringUtils.isEmpty(url)) { + return; + } + + if (url.toLowerCase().startsWith("/sentinel")) { + // 检查Cookie中是否携带sentinel cookie + String cookie = request.getHeaders().getFirst(TokenConstants.Cookie); + if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Sentinel_Token_Key))) { + cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Sentinel_Token_Key); + } + // 网关采用异步架构,所以此处需要通过异步请求获取本系统Token + Future future = executorService.submit(() -> remoteGatewayService.loginSentinel()); + try { + Response response = future.get(1, TimeUnit.SECONDS); + Map> header = response.headers(); + if (header != null && header.containsKey("set-cookie")) { + String sentinelCookie = header.get("set-cookie").iterator().next(); + ServletUtils.removeHeader(mutate, TokenConstants.Cookie); + mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, sentinelCookie)); + } + } catch (Exception e) { + log.error("获取Sentinel Token失败:{0}", e); + } + } + } + @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); @@ -105,6 +145,8 @@ public class AuthFilter implements GlobalFilter, Ordered { ServletUtils.addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username); // 内部请求来源参数清除 ServletUtils.removeHeader(mutate, SecurityConstants.FROM_SOURCE); + + handleRequestForThirdPartyTools(request, mutate); return chain.filter(exchange.mutate().request(mutate.build()).build()); } @@ -130,7 +172,7 @@ public class AuthFilter implements GlobalFilter, Ordered { } private String genCookieByToken(String token) { - return String.format("%s%s;",TokenConstants.GitLink_Token_Key, token); + return String.format("%s%s;", TokenConstants.GitLink_Token_Key, token); } private String getGitLinkRequestCookie(ServerHttpRequest request) { From de9f31a1033c15ffdee5dfe2c1cc8625e42d89d0 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 11 Oct 2024 08:40:04 +0800 Subject: [PATCH 02/49] =?UTF-8?q?feat(=E8=B0=83=E7=94=A8=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E5=BE=AE=E6=9C=8D=E5=8A=A1):=20=E5=A4=84=E7=90=86Naco?= =?UTF-8?q?s=E8=AF=B7=E6=B1=82=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 识别到Nacos请求时,调用Nacos登录接口获取Token并写入到请求头中,用于Nacos后续接口的鉴权操作 Signed-off-by: OTTO <731554297@qq.com> --- .../system/api/RemoteGatewayService.java | 18 ++++++++++++-- .../factory/RemoteGatewayFallbackFactory.java | 8 ++++++- .../common/core/utils/CookieUtil.java | 2 +- .../gateway/filter/AuthFilter.java | 24 ++++++++++++++++--- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java index 661f3ebc9..b3088158f 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java @@ -2,15 +2,20 @@ package com.microservices.system.api; import com.microservices.common.core.constant.ServiceNameConstants; import com.microservices.system.api.factory.RemoteGatewayFallbackFactory; +import feign.Headers; import feign.Response; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; /** * 网关 * * @author microservices */ +@Component @FeignClient(contextId = "remoteGatewayService", value = ServiceNameConstants.GATEWAY_SERVICE, fallbackFactory = RemoteGatewayFallbackFactory.class) public interface RemoteGatewayService { /** @@ -18,6 +23,15 @@ public interface RemoteGatewayService { * * @return 响应 */ - @PostMapping("/sentinel/auth/login?password=sentinel&username=sentinel") - public Response loginSentinel(); + @PostMapping("/sentinel/auth/login") + Response loginSentinel(@RequestParam("username") String username, @RequestParam("password") String password); + + /** + * 登录Nacos + * + * @return 响应 + */ + @PostMapping("/nacos/v1/auth/users/login") + @Headers("Content-Type: application/x-www-form-urlencoded") + Response loginNacos(@RequestPart("username") String username, @RequestPart("password") String password); } diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java index 85d534e6a..a09370d31 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java @@ -20,8 +20,14 @@ public class RemoteGatewayFallbackFactory implements FallbackFactory future = executorService.submit(() -> remoteGatewayService.loginSentinel()); + // 网关采用异步架构,所以此处需要通过异步请求获取Sentinel Token + Future future = executorService.submit(() -> remoteGatewayService.loginSentinel("sentinel", "sentinel")); try { Response response = future.get(1, TimeUnit.SECONDS); Map> header = response.headers(); @@ -91,6 +94,21 @@ public class AuthFilter implements GlobalFilter, Ordered { log.error("获取Sentinel Token失败:{0}", e); } } + // 处理Nacos请求 + if (url.toLowerCase().startsWith("/nacos")) { + // 网关采用异步架构,所以此处需要通过异步请求获取Nacos Token + Future future = executorService.submit(() -> remoteGatewayService.loginNacos("nacos", "nacos")); + try { + Response res = future.get(1, TimeUnit.SECONDS); + StringWriter writer = new StringWriter(); + IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); + String str = writer.toString(); + System.out.println(str); + } catch (Exception e) { + log.error("获取Nacos Token失败:{0}", e); + } + } + } @Override From 57a10a1a983bbbc6b68489af3a11dc195944c26a Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 18 Oct 2024 09:40:20 +0800 Subject: [PATCH 03/49] =?UTF-8?q?feat(=E8=B0=83=E7=94=A8=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E5=BE=AE=E6=9C=8D=E5=8A=A1):=20=E5=A4=84=E7=90=86Naco?= =?UTF-8?q?s=E8=AF=B7=E6=B1=82=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Feign支持Form表单提交 Signed-off-by: OTTO <731554297@qq.com> --- .../security/feign/FeignAutoConfiguration.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/microservices-common/microservices-common-security/src/main/java/com/microservices/common/security/feign/FeignAutoConfiguration.java b/microservices-common/microservices-common-security/src/main/java/com/microservices/common/security/feign/FeignAutoConfiguration.java index bb17e5244..ba6f95f20 100644 --- a/microservices-common/microservices-common-security/src/main/java/com/microservices/common/security/feign/FeignAutoConfiguration.java +++ b/microservices-common/microservices-common-security/src/main/java/com/microservices/common/security/feign/FeignAutoConfiguration.java @@ -1,9 +1,16 @@ package com.microservices.common.security.feign; import feign.RequestInterceptor; +import feign.codec.Encoder; +import feign.form.FormEncoder; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; + /** * Feign 配置注册 * @@ -12,9 +19,20 @@ import org.springframework.context.annotation.Configuration; @Configuration public class FeignAutoConfiguration { + // 这里会由容器自动注入HttpMessageConverters的对象工厂 + @Autowired + private ObjectFactory messageConverters; @Bean public RequestInterceptor requestInterceptor() { return new FeignRequestInterceptor(); } + + // new一个form编码器,实现支持form表单提交 + // 注意这里方法名称,也就是bean的名称是什么不重要, + // 重要的是返回类型要是 Encoder 并且实现类必须是 FormEncoder 或者其子类 + @Bean + public Encoder feignFormEncoder() { + return new FormEncoder(new SpringEncoder(messageConverters)); + } } From 62495f0f33988d6e524a5cb368dd8d373edf1727 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 18 Oct 2024 09:41:05 +0800 Subject: [PATCH 04/49] =?UTF-8?q?feat(=E8=B0=83=E7=94=A8=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E5=BE=AE=E6=9C=8D=E5=8A=A1):=20=E5=A4=84=E7=90=86Naco?= =?UTF-8?q?s=E8=AF=B7=E6=B1=82=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nacos登录接口:用户名/密码调整为表单提交 Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/system/api/RemoteGatewayService.java | 9 ++++----- .../system/api/factory/RemoteGatewayFallbackFactory.java | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java index b3088158f..e6103bbff 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java @@ -2,13 +2,13 @@ package com.microservices.system.api; import com.microservices.common.core.constant.ServiceNameConstants; import com.microservices.system.api.factory.RemoteGatewayFallbackFactory; -import feign.Headers; import feign.Response; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; + +import java.util.Map; /** * 网关 @@ -31,7 +31,6 @@ public interface RemoteGatewayService { * * @return 响应 */ - @PostMapping("/nacos/v1/auth/users/login") - @Headers("Content-Type: application/x-www-form-urlencoded") - Response loginNacos(@RequestPart("username") String username, @RequestPart("password") String password); + @PostMapping(value = "/nacos/v1/auth/users/login", consumes = {"application/x-www-form-urlencoded"}) + Response loginNacos(Map formParams); } diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java index a09370d31..2a8391a8f 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java @@ -7,6 +7,8 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; +import java.util.Map; + /** * 用户服务降级处理 * @@ -27,7 +29,7 @@ public class RemoteGatewayFallbackFactory implements FallbackFactory formParams) { return null; } }; From e2138020be6d7fa3b357a8bb35db1fb07a5aa803 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 18 Oct 2024 09:43:46 +0800 Subject: [PATCH 05/49] =?UTF-8?q?feat(=E8=B0=83=E7=94=A8=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E5=BE=AE=E6=9C=8D=E5=8A=A1):=20=E5=A4=84=E7=90=86Naco?= =?UTF-8?q?s=E8=AF=B7=E6=B1=82=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 调用Nacos登录接口后将响应结果中的accessToken添加到请求头中 2. 增加Redis对Sentinel和Nacos的Token进行缓存,减少登录接口重复调用次数,加快第三方开源软件调用的响应速度 Signed-off-by: OTTO <731554297@qq.com> --- .../common/core/constant/CacheConstants.java | 11 +++ .../common/core/constant/TokenConstants.java | 4 + .../gateway/CustomExecutorFactory.java | 35 ++++++++ .../gateway/filter/AuthFilter.java | 90 ++++++++++++------- 4 files changed, 110 insertions(+), 30 deletions(-) create mode 100644 microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java index 60c443219..22ed5c915 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java @@ -208,4 +208,15 @@ public class CacheConstants public static String getGitlinkOrgIdOpenEnterpriseKey(Long gitlinkOrgId) { return GITLINK_ORG_ID_OPEN_ENTERPRISE_KEY + gitlinkOrgId; } + + /** + * Sentinel Token缓存Key + */ + public final static String SENTINEL_TOKEN = "sentinel_token"; + + + /** + * Nacos Token缓存Key + */ + public static final String NACOS_TOKEN = "nacos_token"; } diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java index a74ad6b35..e9349b3aa 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java @@ -22,6 +22,10 @@ public class TokenConstants { * Sentinel令牌标识 */ public static final String Sentinel_Token_Key = "sentinel_dashboard_cookie"; + /** + * Sentinel令牌标识 + */ + public static final String Nacos_Token_Key = "Accesstoken"; /** * Cookie中令牌标识 */ diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java b/microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java new file mode 100644 index 000000000..c18c39865 --- /dev/null +++ b/microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java @@ -0,0 +1,35 @@ +package com.microservices.gateway; + +import com.microservices.common.core.exception.ServiceException; +import com.microservices.common.core.threadPool.ThreadPoolExecutorWrap; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * @author OTTO + */ +public class CustomExecutorFactory { + /** + * 创建线程池 + * 存在并发处理的情况,设置核心线程为2,设置有界队列长度为100,最大线程数为10 + * 当超出队列已满且达到最大线程数时抛出异常 + * Ncpu=CPU数量 + * Ucpu=目标CPU的使用率,0<=Ucpu<=1 + * W/C=任务等待时间与任务计算时间的比率 + * Nthreads =Ncpu*Ucpu*(1+W/C) + */ + public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutorWrap( + 4 + , 10 + , 10 + , TimeUnit.SECONDS + , new ArrayBlockingQueue<>(100) + , Executors.defaultThreadFactory() + , (r, executor) -> { + throw new ServiceException("目前处理的人太多了,请稍后再试"); + } + ); +} diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index 7b1483a24..ab176a9ca 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -1,5 +1,6 @@ package com.microservices.gateway.filter; +import com.alibaba.fastjson2.JSONObject; import com.microservices.common.core.constant.CacheConstants; import com.microservices.common.core.constant.HttpStatus; import com.microservices.common.core.constant.SecurityConstants; @@ -11,6 +12,7 @@ import com.microservices.common.core.utils.JwtUtils; import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.StringUtils; import com.microservices.common.redis.service.RedisService; +import com.microservices.gateway.CustomExecutorFactory; import com.microservices.gateway.config.properties.IgnoreWhiteProperties; import com.microservices.system.api.RemoteGatewayService; import com.microservices.system.api.RemoteUserService; @@ -31,15 +33,14 @@ import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; +import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; /** * 网关鉴权 @@ -63,7 +64,7 @@ public class AuthFilter implements GlobalFilter, Ordered { @Autowired private RemoteGatewayService remoteGatewayService; - ExecutorService executorService = Executors.newFixedThreadPool(1); + ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; /** * 处理第三方工具请求 @@ -80,35 +81,64 @@ public class AuthFilter implements GlobalFilter, Ordered { if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Sentinel_Token_Key))) { cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Sentinel_Token_Key); } - // 网关采用异步架构,所以此处需要通过异步请求获取Sentinel Token - Future future = executorService.submit(() -> remoteGatewayService.loginSentinel("sentinel", "sentinel")); - try { - Response response = future.get(1, TimeUnit.SECONDS); - Map> header = response.headers(); - if (header != null && header.containsKey("set-cookie")) { - String sentinelCookie = header.get("set-cookie").iterator().next(); - ServletUtils.removeHeader(mutate, TokenConstants.Cookie); - mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, sentinelCookie)); + String sentinelCookie = null; + if (redisService.hasKey(CacheConstants.SENTINEL_TOKEN)) { + sentinelCookie = redisService.getCacheObject(CacheConstants.SENTINEL_TOKEN); + } else { + // 网关采用异步架构,所以此处需要通过异步请求获取Sentinel Token + Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginSentinel("sentinel", "sentinel")); + try { + Response response = future.get(1, TimeUnit.SECONDS); + Map> header = response.headers(); + if (header != null && header.containsKey("set-cookie")) { + sentinelCookie = header.get("set-cookie").iterator().next(); + redisService.setCacheObject(CacheConstants.SENTINEL_TOKEN, sentinelCookie, 12L, TimeUnit.HOURS); + } + } catch (TimeoutException e) { + log.error("获取Sentinel Token超时"); + } catch (InterruptedException | ExecutionException e) { + log.error("获取Sentinel Token失败:{}", e.getMessage()); } - } catch (Exception e) { - log.error("获取Sentinel Token失败:{0}", e); + } + if (StringUtils.isNotEmpty(sentinelCookie)) { + ServletUtils.removeHeader(mutate, TokenConstants.Cookie); + mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, sentinelCookie)); } } // 处理Nacos请求 if (url.toLowerCase().startsWith("/nacos")) { - // 网关采用异步架构,所以此处需要通过异步请求获取Nacos Token - Future future = executorService.submit(() -> remoteGatewayService.loginNacos("nacos", "nacos")); - try { - Response res = future.get(1, TimeUnit.SECONDS); - StringWriter writer = new StringWriter(); - IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); - String str = writer.toString(); - System.out.println(str); - } catch (Exception e) { - log.error("获取Nacos Token失败:{0}", e); + String nacosToken = null; + if (redisService.hasKey(CacheConstants.NACOS_TOKEN)) { + nacosToken = redisService.getCacheObject(CacheConstants.NACOS_TOKEN); + } else { + Map nacosMap = new HashMap<>(); + nacosMap.put("username", "nacos"); + nacosMap.put("password", "nacos"); + // 网关采用异步架构,所以此处需要通过异步请求获取Nacos Token + Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginNacos(nacosMap)); + try { + Response res = future.get(1, TimeUnit.SECONDS); + StringWriter writer = new StringWriter(); + IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); + String str = writer.toString(); + JSONObject resJsonObject = JSONObject.parseObject(str); + nacosToken = resJsonObject.getString("accessToken"); + Long tokenTtl = resJsonObject.getLong("tokenTtl"); + if (nacosToken != null && tokenTtl != null) { + redisService.setCacheObject(CacheConstants.NACOS_TOKEN, nacosToken, tokenTtl - 10, TimeUnit.SECONDS); + } else { + throw new ServiceException("Nacos服务获取Token失败"); + } + } catch (TimeoutException e) { + log.error("获取Nacos Token超时"); + } catch (InterruptedException | ExecutionException | IOException | NullPointerException e) { + log.error("获取Nacos Token失败:{}", e.getMessage()); + } + } + if (StringUtils.isNotEmpty(nacosToken)) { + mutate.header(TokenConstants.Nacos_Token_Key, nacosToken); } } - } @Override @@ -176,7 +206,7 @@ public class AuthFilter implements GlobalFilter, Ordered { boolean hasUserIdentifyList = redisService.hasKey(redisKey); if (!hasUserIdentifyList) { // 网关采用异步架构,所以此处需要通过异步请求获取本系统Token - Future>> future = executorService.submit( + Future>> future = threadPoolExecutor.submit( () -> remoteUserService.getSysUserDeptRoleListByUserName(username, SecurityConstants.INNER)); try { List feignResult = FeignUtils.getReturnData( @@ -201,7 +231,7 @@ public class AuthFilter implements GlobalFilter, Ordered { String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION); if (token != null) { // 网关采用异步架构,所以此处需要通过异步请求获取本系统Token - Future> future = executorService.submit( + Future> future = threadPoolExecutor.submit( () -> remoteUserService.checkGitLinkUserLogin(token, SecurityConstants.INNER)); try { Boolean feignResult = FeignUtils.getReturnData( @@ -254,7 +284,7 @@ public class AuthFilter implements GlobalFilter, Ordered { private String getGitLinkToken(String cookie) { if (StringUtils.isNotEmpty(cookie)) { // 网关采用异步架构,所以此处需要通过异步请求获取本系统Token - Future> future = executorService.submit(() -> remoteUserService + Future> future = threadPoolExecutor.submit(() -> remoteUserService .getSysUserTokenByGitLinkCookie(cookie, SecurityConstants.INNER)); R feignResult; try { From a44127858e0137ce6d2ab78119d6a378279cd103 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Sat, 19 Oct 2024 14:04:04 +0800 Subject: [PATCH 06/49] =?UTF-8?q?feat(=E8=B0=83=E7=94=A8=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E5=BE=AE=E6=9C=8D=E5=8A=A1):=20=E5=A4=84=E7=90=86Port?= =?UTF-8?q?ainer=E8=AF=B7=E6=B1=82=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 识别到Portainer请求时,调用Portainer登录接口获取Token并写入到请求头中,解析Token的过期时间,将Token存储到Redis中,以便后续Portainer接口鉴权使用 Signed-off-by: OTTO <731554297@qq.com> --- .../system/api/RemoteGatewayService.java | 10 + .../factory/RemoteGatewayFallbackFactory.java | 7 + .../common/core/constant/CacheConstants.java | 5 + .../gateway/config/FeignConfig.java | 11 ++ .../gateway/filter/AuthFilter.java | 94 +--------- .../service/ThirdPartyToolService.java | 19 ++ .../impl/ThirdPartyToolServiceImpl.java | 173 ++++++++++++++++++ 7 files changed, 231 insertions(+), 88 deletions(-) create mode 100644 microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java create mode 100644 microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java index e6103bbff..341ce2cfd 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/RemoteGatewayService.java @@ -1,11 +1,13 @@ package com.microservices.system.api; +import com.alibaba.fastjson2.JSONObject; import com.microservices.common.core.constant.ServiceNameConstants; import com.microservices.system.api.factory.RemoteGatewayFallbackFactory; import feign.Response; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import java.util.Map; @@ -33,4 +35,12 @@ public interface RemoteGatewayService { */ @PostMapping(value = "/nacos/v1/auth/users/login", consumes = {"application/x-www-form-urlencoded"}) Response loginNacos(Map formParams); + + /** + * 登录Portainer + * + * @return 响应 + */ + @PostMapping("/portainer/api/auth") + Response loginPortainer(@RequestBody JSONObject loginBody); } diff --git a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java index 2a8391a8f..044d8e211 100644 --- a/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java +++ b/microservices-api/microservices-api-system/src/main/java/com/microservices/system/api/factory/RemoteGatewayFallbackFactory.java @@ -1,5 +1,6 @@ package com.microservices.system.api.factory; +import com.alibaba.fastjson2.JSONObject; import com.microservices.system.api.RemoteGatewayService; import feign.Response; import org.slf4j.Logger; @@ -32,6 +33,12 @@ public class RemoteGatewayFallbackFactory implements FallbackFactory formParams) { return null; } + + @Override + public Response loginPortainer(JSONObject loginBody) { + System.out.println(throwable.getMessage()); + return null; + } }; } } diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java index 22ed5c915..bd45f6119 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java @@ -219,4 +219,9 @@ public class CacheConstants * Nacos Token缓存Key */ public static final String NACOS_TOKEN = "nacos_token"; + + /** + * Portainer Token缓存Key + */ + public static final String PORTAINER_TOKEN = "portainer_token"; } diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/config/FeignConfig.java b/microservices-gateway/src/main/java/com/microservices/gateway/config/FeignConfig.java index df8de2118..f5d452a25 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/config/FeignConfig.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/config/FeignConfig.java @@ -2,13 +2,18 @@ package com.microservices.gateway.config; import feign.codec.Decoder; import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import java.util.stream.Collectors; + /** * @author otto */ @@ -25,4 +30,10 @@ public class FeignConfig { (new MappingJackson2HttpMessageConverter()); return () -> httpMessageConverters; } + + @Bean + @ConditionalOnMissingBean + public HttpMessageConverters messageConverters(ObjectProvider> converters) { + return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList())); + } } \ No newline at end of file diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index ab176a9ca..69ce7a78e 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -1,26 +1,22 @@ package com.microservices.gateway.filter; -import com.alibaba.fastjson2.JSONObject; import com.microservices.common.core.constant.CacheConstants; import com.microservices.common.core.constant.HttpStatus; import com.microservices.common.core.constant.SecurityConstants; import com.microservices.common.core.constant.TokenConstants; import com.microservices.common.core.domain.R; import com.microservices.common.core.exception.ServiceException; -import com.microservices.common.core.utils.CookieUtil; import com.microservices.common.core.utils.JwtUtils; import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.StringUtils; import com.microservices.common.redis.service.RedisService; import com.microservices.gateway.CustomExecutorFactory; import com.microservices.gateway.config.properties.IgnoreWhiteProperties; -import com.microservices.system.api.RemoteGatewayService; +import com.microservices.gateway.service.ThirdPartyToolService; import com.microservices.system.api.RemoteUserService; import com.microservices.system.api.domain.SysUserDeptRole; import com.microservices.system.api.utils.FeignUtils; -import feign.Response; import io.jsonwebtoken.Claims; -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -33,14 +29,9 @@ import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.concurrent.*; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; /** * 网关鉴权 @@ -60,86 +51,13 @@ public class AuthFilter implements GlobalFilter, Ordered { @Lazy @Autowired private RemoteUserService remoteUserService; + @Lazy @Autowired - private RemoteGatewayService remoteGatewayService; + private ThirdPartyToolService thirdPartyToolService; ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; - /** - * 处理第三方工具请求 - */ - private void handleRequestForThirdPartyTools(ServerHttpRequest request, ServerHttpRequest.Builder mutate) { - String url = request.getURI().getPath(); - if (StringUtils.isEmpty(url)) { - return; - } - // 处理Sentinel请求 - if (url.toLowerCase().startsWith("/sentinel")) { - // 检查Cookie中是否携带sentinel cookie - String cookie = request.getHeaders().getFirst(TokenConstants.Cookie); - if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Sentinel_Token_Key))) { - cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Sentinel_Token_Key); - } - String sentinelCookie = null; - if (redisService.hasKey(CacheConstants.SENTINEL_TOKEN)) { - sentinelCookie = redisService.getCacheObject(CacheConstants.SENTINEL_TOKEN); - } else { - // 网关采用异步架构,所以此处需要通过异步请求获取Sentinel Token - Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginSentinel("sentinel", "sentinel")); - try { - Response response = future.get(1, TimeUnit.SECONDS); - Map> header = response.headers(); - if (header != null && header.containsKey("set-cookie")) { - sentinelCookie = header.get("set-cookie").iterator().next(); - redisService.setCacheObject(CacheConstants.SENTINEL_TOKEN, sentinelCookie, 12L, TimeUnit.HOURS); - } - } catch (TimeoutException e) { - log.error("获取Sentinel Token超时"); - } catch (InterruptedException | ExecutionException e) { - log.error("获取Sentinel Token失败:{}", e.getMessage()); - } - } - if (StringUtils.isNotEmpty(sentinelCookie)) { - ServletUtils.removeHeader(mutate, TokenConstants.Cookie); - mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, sentinelCookie)); - } - } - // 处理Nacos请求 - if (url.toLowerCase().startsWith("/nacos")) { - String nacosToken = null; - if (redisService.hasKey(CacheConstants.NACOS_TOKEN)) { - nacosToken = redisService.getCacheObject(CacheConstants.NACOS_TOKEN); - } else { - Map nacosMap = new HashMap<>(); - nacosMap.put("username", "nacos"); - nacosMap.put("password", "nacos"); - // 网关采用异步架构,所以此处需要通过异步请求获取Nacos Token - Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginNacos(nacosMap)); - try { - Response res = future.get(1, TimeUnit.SECONDS); - StringWriter writer = new StringWriter(); - IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); - String str = writer.toString(); - JSONObject resJsonObject = JSONObject.parseObject(str); - nacosToken = resJsonObject.getString("accessToken"); - Long tokenTtl = resJsonObject.getLong("tokenTtl"); - if (nacosToken != null && tokenTtl != null) { - redisService.setCacheObject(CacheConstants.NACOS_TOKEN, nacosToken, tokenTtl - 10, TimeUnit.SECONDS); - } else { - throw new ServiceException("Nacos服务获取Token失败"); - } - } catch (TimeoutException e) { - log.error("获取Nacos Token超时"); - } catch (InterruptedException | ExecutionException | IOException | NullPointerException e) { - log.error("获取Nacos Token失败:{}", e.getMessage()); - } - } - if (StringUtils.isNotEmpty(nacosToken)) { - mutate.header(TokenConstants.Nacos_Token_Key, nacosToken); - } - } - } @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { @@ -194,7 +112,7 @@ public class AuthFilter implements GlobalFilter, Ordered { // 内部请求来源参数清除 ServletUtils.removeHeader(mutate, SecurityConstants.FROM_SOURCE); - handleRequestForThirdPartyTools(request, mutate); + thirdPartyToolService.handleRequestForThirdPartyTools(request, mutate); return chain.filter(exchange.mutate().request(mutate.build()).build()); } diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java new file mode 100644 index 000000000..efc7d4b58 --- /dev/null +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java @@ -0,0 +1,19 @@ +package com.microservices.gateway.service; + +import org.springframework.http.server.reactive.ServerHttpRequest; + +/** + * 第三方工具服务类 + * + * @author OTTO + */ +public interface ThirdPartyToolService { + + /** + * 处理第三方工具请求 + * + * @param request 请求 + * @param mutate 请求头获取器 + */ + void handleRequestForThirdPartyTools(ServerHttpRequest request, ServerHttpRequest.Builder mutate); +} diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java new file mode 100644 index 000000000..f6b2bca05 --- /dev/null +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -0,0 +1,173 @@ +package com.microservices.gateway.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.microservices.common.core.constant.CacheConstants; +import com.microservices.common.core.constant.TokenConstants; +import com.microservices.common.core.exception.ServiceException; +import com.microservices.common.core.utils.CookieUtil; +import com.microservices.common.core.utils.ServletUtils; +import com.microservices.common.core.utils.StringUtils; +import com.microservices.common.redis.service.RedisService; +import com.microservices.gateway.CustomExecutorFactory; +import com.microservices.gateway.service.ThirdPartyToolService; +import com.microservices.system.api.RemoteGatewayService; +import feign.Response; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.*; + +/** + * @author OTTO + */ +@Service +public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { + private static final Logger log = LoggerFactory.getLogger(ThirdPartyToolServiceImpl.class); + @Value("${thirdPartyTools.nacos.auth.username:}") + public String nacosUsername; + @Value("${thirdPartyTools.nacos.auth.password:}") + public String nacosPassword; + @Value("${thirdPartyTools.sentinel.auth.username:}") + public String sentinelUsername; + @Value("${thirdPartyTools.sentinel.auth.password:}") + public String sentinelPassword; + @Value("${thirdPartyTools.portainer.auth.username:}") + public String portainerUsername; + @Value("${thirdPartyTools.portainer.auth.password:}") + public String portainerPassword; + ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; + @Lazy + @Autowired + private RemoteGatewayService remoteGatewayService; + @Autowired + private RedisService redisService; + + /** + * 处理第三方工具请求 + */ + @Override + public void handleRequestForThirdPartyTools(ServerHttpRequest request, ServerHttpRequest.Builder mutate) { + String url = request.getURI().getPath(); + if (StringUtils.isEmpty(url)) { + return; + } + // 处理Sentinel请求 + if (url.toLowerCase().startsWith("/sentinel")) { + // 检查Cookie中是否携带sentinel cookie + String cookie = request.getHeaders().getFirst(TokenConstants.Cookie); + if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Sentinel_Token_Key))) { + cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Sentinel_Token_Key); + } + String sentinelCookie = null; + if (redisService.hasKey(CacheConstants.SENTINEL_TOKEN)) { + sentinelCookie = redisService.getCacheObject(CacheConstants.SENTINEL_TOKEN); + } else { + // 网关采用异步架构,所以此处需要通过异步请求获取Sentinel Token + Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginSentinel(sentinelUsername, sentinelPassword)); + try { + Response response = future.get(1, TimeUnit.SECONDS); + Map> header = response.headers(); + if (header != null && header.containsKey("set-cookie")) { + sentinelCookie = header.get("set-cookie").iterator().next(); + redisService.setCacheObject(CacheConstants.SENTINEL_TOKEN, sentinelCookie, 12L, TimeUnit.HOURS); + } + } catch (TimeoutException e) { + log.error("获取Sentinel Token超时"); + } catch (InterruptedException | ExecutionException e) { + log.error("获取Sentinel Token失败:{}", e.getMessage()); + } + } + if (StringUtils.isNotEmpty(sentinelCookie)) { + ServletUtils.removeHeader(mutate, TokenConstants.Cookie); + mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, sentinelCookie)); + } else { + throw new ServiceException("Sentinel服务获取Token失败"); + } + } + // 处理Nacos请求 + if (url.toLowerCase().startsWith("/nacos")) { + String nacosToken = null; + if (redisService.hasKey(CacheConstants.NACOS_TOKEN)) { + nacosToken = redisService.getCacheObject(CacheConstants.NACOS_TOKEN); + } else { + Map nacosMap = new HashMap<>(); + nacosMap.put("username", nacosUsername); + nacosMap.put("password", nacosPassword); + // 网关采用异步架构,所以此处需要通过异步请求获取Nacos Token + Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginNacos(nacosMap)); + try { + Response res = future.get(1, TimeUnit.SECONDS); + StringWriter writer = new StringWriter(); + IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); + String str = writer.toString(); + JSONObject resJsonObject = JSONObject.parseObject(str); + nacosToken = resJsonObject.getString("accessToken"); + Long tokenTtl = resJsonObject.getLong("tokenTtl"); + if (nacosToken != null && tokenTtl != null) { + redisService.setCacheObject(CacheConstants.NACOS_TOKEN, nacosToken, tokenTtl - 10, TimeUnit.SECONDS); + } + } catch (TimeoutException e) { + log.error("获取Nacos Token超时"); + } catch (InterruptedException | ExecutionException | IOException | NullPointerException e) { + log.error("获取Nacos Token失败:{}", e.getMessage()); + } + } + if (StringUtils.isNotEmpty(nacosToken)) { + mutate.header(TokenConstants.Nacos_Token_Key, nacosToken); + } else { + throw new ServiceException("Nacos服务获取Token失败"); + } + } + + // 处理Nacos请求 + if (url.toLowerCase().startsWith("/portainer")) { + String portainerToken = null; + if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) { + portainerToken = redisService.getCacheObject(CacheConstants.PORTAINER_TOKEN); + } else { + // 网关采用异步架构,所以此处需要通过异步请求获取Portainer Token + JSONObject loginPortainerBody = new JSONObject(); + loginPortainerBody.put("username", portainerUsername); + loginPortainerBody.put("password", portainerPassword); + Future future = threadPoolExecutor.submit(() -> remoteGatewayService.loginPortainer(loginPortainerBody)); + try { + Response res = future.get(1, TimeUnit.SECONDS); + StringWriter writer = new StringWriter(); + IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); + String str = writer.toString(); + JSONObject resJsonObject = JSONObject.parseObject(str); + portainerToken = resJsonObject.getString("jwt"); + String[] tokenSplit = portainerToken.split("\\."); + String tokenBodyStr = new String(Base64.getDecoder().decode(tokenSplit[1]), StandardCharsets.UTF_8); + JSONObject tokenBody = JSONObject.parseObject(tokenBodyStr); + Long expiration = tokenBody.getLong("exp"); + Long now = new Date().getTime() / 1000; + + long portainerTokenTtl = expiration - now; + if (portainerTokenTtl > 20) { + redisService.setCacheObject(CacheConstants.PORTAINER_TOKEN, portainerToken, portainerTokenTtl - 10, TimeUnit.SECONDS); + } + } catch (TimeoutException e) { + log.error("获取Portainer Token超时"); + } catch (InterruptedException | ExecutionException | IOException | NullPointerException e) { + log.error("获取Portainer Token失败:{}", e.getMessage()); + } + } + if (StringUtils.isNotEmpty(portainerToken)) { + mutate.header(TokenConstants.AUTHENTICATION, TokenConstants.PREFIX + portainerToken); + } else { + throw new ServiceException("Portainer服务获取Token失败"); + } + } + } +} From c900fed456651d7716a6dc3c303ef050f24900ee Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Sat, 19 Oct 2024 14:44:02 +0800 Subject: [PATCH 07/49] =?UTF-8?q?perf(=E7=BD=91=E5=85=B3=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?):=20=E4=BC=98=E5=8C=96=E7=BD=91=E5=85=B3=E6=9D=83=E9=99=90?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=BC=82=E5=B8=B8=E6=97=B6=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../main/java/com/microservices/gateway/filter/AuthFilter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index 69ce7a78e..b1502a6a1 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -81,6 +81,9 @@ public class AuthFilter implements GlobalFilter, Ordered { } if (StringUtils.isEmpty(token)) { + if (StringUtils.isNotEmpty(gitLinkCookie)) { + return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); + } return unauthorizedResponse(exchange, "令牌不能为空"); } Claims claims; From c0b4ddb86e371cde009fb1d7164a1f0bff61ac02 Mon Sep 17 00:00:00 2001 From: liuhuazhong Date: Thu, 28 Nov 2024 14:48:42 +0800 Subject: [PATCH 08/49] =?UTF-8?q?=E5=B0=86=E6=B5=81=E6=B0=B4=E7=BA=BFjson?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E8=A7=A3=E6=9E=90=E6=88=90yaml=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PmsCiPipelinesController.java | 8 + .../pms/pipeline/domain/vo/NodeActionVo.java | 120 ++++++++ .../pms/pipeline/domain/vo/PipelineVo.java | 284 ++++++++++++++++++ .../service/IPmsCiPipelinesService.java | 2 + .../impl/PmsCiPipelinesServiceImpl.java | 42 +++ .../com/microservices/pms/utils/YamlUtil.java | 58 ++++ 6 files changed, 514 insertions(+) create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/PipelineVo.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/YamlUtil.java diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java index 3aff4746a..284b8c247 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java @@ -204,6 +204,14 @@ public class PmsCiPipelinesController extends BaseController return success(pmsCiPipelinesService.savePipelineYamlByGraphicJson(id, pmsCiPipelineBuildInputVo)); } + @PostMapping(value = "/{id}/savePipelineYamlNew") + @ApiOperation("流水线图形构建声明式yaml并保存") + public AjaxResult savePipelineYamlNew(@ApiParam(name = "id", value = "流水线id")@PathVariable Long id, + @RequestBody @Validated PmsCiPipelineBuildYamlInputVo pmsCiPipelineBuildInputVo) + { + return success(pmsCiPipelinesService.savePipelineYamlByGraphicJsonNew(id, pmsCiPipelineBuildInputVo)); + } + /** * 启动流水线执行记录任务 */ diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java new file mode 100644 index 000000000..41cc9c0ad --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java @@ -0,0 +1,120 @@ +package com.microservices.pms.pipeline.domain.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +@Getter +@Setter +@NoArgsConstructor +public class NodeActionVo { + + private String name; + private final Map on = new LinkedHashMap<>(); + private final Map jobs = new LinkedHashMap<>(); + @JsonIgnore + private Map params = new LinkedHashMap<>(); + + public void buildName(String name) { + this.name = name; + } + + public void buildOn(PipelineVo.PipelineJson.Nodes node) { +// this.on.put("push", Collections.singletonMap("branches", Collections.singletonList(branchName))); + String fullName = node.getFull_name(); + Map step = new LinkedHashMap<>(); + + if (Objects.equals(fullName, "on-schedule")) { + List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()); + inputs.forEach(e -> { + step.put(e.getName(), e.getValue()); + }); + this.on.put(fullName.split("-")[1], step); + return; + } + + if (fullName.startsWith("on-")) { + List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()).stream().filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); + inputs.forEach(e -> { + step.put(e.getName(), e.getValue().replace("\'","").split(",")); + }); + + this.on.put(fullName.split("-")[1], step); + } + } + + public void buildJobs(String jobKey, String jobName, List> steps) { + if (steps.isEmpty()) return; + Map job = new LinkedHashMap<>(); + job.put("runs-on", "ubuntu-latest"); + job.put("name", jobName); + job.put("steps", steps); + this.jobs.put(jobKey, job); + } + + public void buildSetupStep(List> steps, PipelineVo.PipelineJson.Nodes node) { + String name = node.getName(); + Map step = new LinkedHashMap<>(); + if (name.startsWith("setup-java")) { + List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()).stream().filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); + + + Map name2Value = inputs.stream().collect(Collectors.toMap(e -> e.getName(), e -> e.getValue(), (o, n) -> n)); + + Map with = new LinkedHashMap<>(); + if (name2Value.containsKey("download_url") && StringUtils.isNotBlank(name2Value.get("download_url"))) { + steps.add(Collections.singletonMap("run", "download_url=" + name2Value.get("download_url") + " && " + "wget -O $RUNNER_TEMP/java_package.tar.gz $download_url")); + with.put("distribution", "jdkfile"); + with.put("jdkFile", "${{ runner.temp }}/java_package.tar.gz"); + } + step.put("name", node.getLabel()); + step.put("uses", node.getFull_name()); + if (!inputs.isEmpty()) { + + inputs.forEach(i -> { + with.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); + }); + + step.put("with", with); + } + steps.add(step); + return; + } + + if (name.startsWith("setup-")) { + List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()).stream().filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); + + step.put("name", node.getLabel()); + step.put("uses", node.getFull_name()); + if (!inputs.isEmpty()) { + Map with = new LinkedHashMap<>(); + inputs.forEach(i -> { + with.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); + }); + + step.put("with", with); + } + steps.add(step); + } + } + + public void buildShellStep(List> steps, PipelineVo.PipelineJson.Nodes node) { + String fullName = node.getFull_name(); + if (Objects.equals(fullName, "shell")) { + Map step = new LinkedHashMap<>(); + step.put("name", node.getLabel()); +// step.put("run",""); + List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()); + inputs.forEach(i -> { + step.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); + }); + + steps.add(step); + } + } +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/PipelineVo.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/PipelineVo.java new file mode 100644 index 000000000..c7781aba5 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/PipelineVo.java @@ -0,0 +1,284 @@ +package com.microservices.pms.pipeline.domain.vo; + +import java.io.Serializable; +import java.util.List; + +public class PipelineVo implements Serializable { + private String pipelineName; + + private PipelineJson pipelineJson; + + public String getPipelineName() { + return this.pipelineName; + } + + public void setPipelineName(String pipelineName) { + this.pipelineName = pipelineName; + } + + public PipelineJson getPipelineJson() { + return this.pipelineJson; + } + + public void setPipelineJson(PipelineJson pipelineJson) { + this.pipelineJson = pipelineJson; + } + + public static class PipelineJson implements Serializable { + private List nodes; + + private List edges; + + public List getNodes() { + return this.nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public List getEdges() { + return this.edges; + } + + public void setEdges(List edges) { + this.edges = edges; + } + + public static class Nodes implements Serializable { + private Integer action_node_types_id; + + private String img; + + private List inputs; + + private String icon; + + private String description; + + private String label; + + private String type; + + private Integer sort_no; + + private Integer use_count; + + private String full_name; + + private String name; + + private Integer x; + + private Double y; + + private String id; + + private Boolean isCluster; + + private String yaml; + + public Integer getAction_node_types_id() { + return this.action_node_types_id; + } + + public void setAction_node_types_id(Integer action_node_types_id) { + this.action_node_types_id = action_node_types_id; + } + + public String getImg() { + return this.img; + } + + public void setImg(String img) { + this.img = img; + } + + public List getInputs() { + return this.inputs; + } + + public void setInputs(List inputs) { + this.inputs = inputs; + } + + public String getIcon() { + return this.icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getLabel() { + return this.label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public Integer getSort_no() { + return this.sort_no; + } + + public void setSort_no(Integer sort_no) { + this.sort_no = sort_no; + } + + public Integer getUse_count() { + return this.use_count; + } + + public void setUse_count(Integer use_count) { + this.use_count = use_count; + } + + public String getFull_name() { + return this.full_name; + } + + public void setFull_name(String full_name) { + this.full_name = full_name; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getX() { + return this.x; + } + + public void setX(Integer x) { + this.x = x; + } + + public Double getY() { + return this.y; + } + + public void setY(Double y) { + this.y = y; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public Boolean getIsCluster() { + return this.isCluster; + } + + public void setIsCluster(Boolean isCluster) { + this.isCluster = isCluster; + } + + public String getYaml() { + return this.yaml; + } + + public void setYaml(String yaml) { + this.yaml = yaml; + } + + public static class Inputs implements Serializable { + private Boolean is_required; + + private String name; + + private String value; + + private String input_type; + + private Integer id; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Boolean getIs_required() { + return this.is_required; + } + + public void setIs_required(Boolean is_required) { + this.is_required = is_required; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getInput_type() { + return this.input_type; + } + + public void setInput_type(String input_type) { + this.input_type = input_type; + } + + public Integer getId() { + return this.id; + } + + public void setId(Integer id) { + this.id = id; + } + } + } + + public static class Edges implements Serializable { + private String source; + + private String target; + + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getTarget() { + return this.target; + } + + public void setTarget(String target) { + this.target = target; + } + } + } +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java index ce3e38f87..210ca4f0e 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java @@ -91,6 +91,8 @@ public interface IPmsCiPipelinesService JSONObject savePipelineYamlByGraphicJson(Long id, PmsCiPipelineBuildYamlInputVo pmsCiPipelineBuildInputVo); + JSONObject savePipelineYamlByGraphicJsonNew(Long id, PmsCiPipelineBuildYamlInputVo pmsCiPipelineBuildInputVo); + JSONObject reRunPipelineRunsJob(Long id, String run, String job); JSONObject reRunAllJobsInPipelineRun(Long id, String run); diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java index e7a758018..4f7ada59b 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java @@ -1,11 +1,16 @@ package com.microservices.pms.pipeline.service.impl; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import com.microservices.common.core.exception.ServiceException; import com.microservices.common.core.utils.DateUtils; import com.microservices.common.core.utils.StringUtils; @@ -23,6 +28,7 @@ import com.microservices.pms.pipeline.domain.vo.*; import com.microservices.pms.pipeline.service.IPmsCiPipelineGraphicsService; import com.microservices.pms.utils.PmsConstants; import com.microservices.pms.utils.PmsGitLinkRequestUrl; +import com.microservices.pms.utils.YamlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; @@ -363,6 +369,42 @@ public class PmsCiPipelinesServiceImpl implements IPmsCiPipelinesService { return result; } + @Override + public JSONObject savePipelineYamlByGraphicJsonNew(Long id, PmsCiPipelineBuildYamlInputVo pmsCiPipelineBuildInputVo) { + PmsCiPipelines pmsCiPipelines = pmsCiPipelinesMapper.selectPmsCiPipelinesById(id); + if (pmsCiPipelines == null) { + throw new ServiceException("该项目流水线不存在(流水线ID[%s])", id); + } + + try { + PipelineVo vo = JSON.parseObject(JSON.toJSONString(pmsCiPipelineBuildInputVo), PipelineVo.class); + NodeActionVo actionVo = getNodeActionVo(vo); + String yaml = YamlUtil.toYaml(actionVo); + JSONObject result = new JSONObject(); + result.put("pipeline_yaml", yaml); + return result; + } catch (Exception e) { + logger.error("流水线图形Json解析失败)", e); + return null; + } + } + + private NodeActionVo getNodeActionVo(PipelineVo vo) { + List nodes = vo.getPipelineJson().getNodes(); + String pipelineName = vo.getPipelineName(); + NodeActionVo actionVo = new NodeActionVo(); + actionVo.buildName(pipelineName); + AtomicInteger i = new AtomicInteger(); + nodes.forEach(s -> { + List> steps = new ArrayList<>(); + actionVo.buildOn(s); + actionVo.buildSetupStep(steps, s); + actionVo.buildShellStep(steps, s); + actionVo.buildJobs("job" + (i.getAndIncrement()), s.getLabel(), steps); + }); + return actionVo; + } + @Override public JSONObject reRunPipelineRunsJob(Long id, String run, String job) { PmsCiPipelines pmsCiPipelines = pmsCiPipelinesMapper.selectPmsCiPipelinesById(id); diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/YamlUtil.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/YamlUtil.java new file mode 100644 index 000000000..04e9deb67 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/YamlUtil.java @@ -0,0 +1,58 @@ +package com.microservices.pms.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import com.microservices.common.core.exception.ServiceException; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.StringWriter; + +@Slf4j +public class YamlUtil { + /** + * 将yaml字符串转成类对象 + * + * @param yamlStr 字符串 + * @param clazz 目标类 + * @param 泛型 + * @return 目标类 + */ + public static T toObject(String yamlStr, Class clazz) { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + mapper.findAndRegisterModules(); + try { + return mapper.readValue(yamlStr, clazz); + } catch (JsonProcessingException e) { + log.error("yaml文本解析成java对象错误:", e); + throw new ServiceException("yaml文本解析成java对象错误!"); + } + } + + /** + * 将类对象转yaml字符串 + * + * @param object 对象 + * @return yaml字符串 + */ + public static String toYaml(Object object) { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + mapper.findAndRegisterModules(); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + mapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)); + StringWriter stringWriter = new StringWriter(); + try { + mapper.writeValue(stringWriter, object); + return stringWriter.toString(); + } catch (IOException e) { + log.error("Java对象解析成Yaml文本错误", e); + } + return null; + } +} + + From da1ec52f91e4c531962aadd397ad2ec2de27b612 Mon Sep 17 00:00:00 2001 From: liuhuazhong Date: Fri, 29 Nov 2024 16:42:09 +0800 Subject: [PATCH 09/49] =?UTF-8?q?feat(=E6=B5=81=E6=B0=B4=E7=BA=BF=E8=A7=A3?= =?UTF-8?q?=E6=9E=90):=20=E5=A2=9E=E5=8A=A0=E5=AF=B9=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=E8=8A=82=E7=82=B9=E7=9A=84=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pms/pipeline/domain/vo/NodeActionVo.java | 110 +++++++++++------- .../impl/PmsCiPipelinesServiceImpl.java | 26 ++--- 2 files changed, 78 insertions(+), 58 deletions(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java index 41cc9c0ad..62f1a26e0 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/domain/vo/NodeActionVo.java @@ -24,28 +24,37 @@ public class NodeActionVo { this.name = name; } - public void buildOn(PipelineVo.PipelineJson.Nodes node) { -// this.on.put("push", Collections.singletonMap("branches", Collections.singletonList(branchName))); - String fullName = node.getFull_name(); - Map step = new LinkedHashMap<>(); + public void parse(List> steps, PipelineVo.PipelineJson.Nodes node){ + String nodeName = Optional.ofNullable(node.getName()).orElse(""); + if (nodeName.startsWith("on-")) { + buildOn(node); + }else if (nodeName.startsWith("setup-")) { + buildSetupStep(steps, node); + }else if (Objects.equals(nodeName,"shell")) { + buildShellStep(steps, node); + }else if (StringUtils.isNotEmpty(nodeName)) { + buildOtherStep(steps, node); + } + } - if (Objects.equals(fullName, "on-schedule")) { - List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()); + public void buildOn(PipelineVo.PipelineJson.Nodes node) { + String nodeName = node.getName(); + Map step = new LinkedHashMap<>(); + List inputs = getInputs(node); + + if (Objects.equals(nodeName, "on-schedule")) { inputs.forEach(e -> { step.put(e.getName(), e.getValue()); }); - this.on.put(fullName.split("-")[1], step); + this.on.put(nodeName.split("-")[1], step); return; } - if (fullName.startsWith("on-")) { - List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()).stream().filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); - inputs.forEach(e -> { - step.put(e.getName(), e.getValue().replace("\'","").split(",")); - }); + inputs.forEach(e -> { + step.put(e.getName(), e.getValue().replace("\'","").split(",")); + }); - this.on.put(fullName.split("-")[1], step); - } + this.on.put(nodeName.split("-")[1], step); } public void buildJobs(String jobKey, String jobName, List> steps) { @@ -54,17 +63,19 @@ public class NodeActionVo { job.put("runs-on", "ubuntu-latest"); job.put("name", jobName); job.put("steps", steps); - this.jobs.put(jobKey, job); + this.jobs.put(jobKey+(this.jobs.size()), job); } public void buildSetupStep(List> steps, PipelineVo.PipelineJson.Nodes node) { - String name = node.getName(); + String nodeName = node.getName(); Map step = new LinkedHashMap<>(); - if (name.startsWith("setup-java")) { - List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()).stream().filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); + List inputs = getInputs(node); - Map name2Value = inputs.stream().collect(Collectors.toMap(e -> e.getName(), e -> e.getValue(), (o, n) -> n)); + if (nodeName.startsWith("setup-java")) { + + Map name2Value = inputs.stream() + .collect(Collectors.toMap(e -> e.getName(), e -> e.getValue(), (o, n) -> n)); Map with = new LinkedHashMap<>(); if (name2Value.containsKey("download_url") && StringUtils.isNotBlank(name2Value.get("download_url"))) { @@ -73,7 +84,7 @@ public class NodeActionVo { with.put("jdkFile", "${{ runner.temp }}/java_package.tar.gz"); } step.put("name", node.getLabel()); - step.put("uses", node.getFull_name()); + step.put("uses", node.getFull_name().trim()); if (!inputs.isEmpty()) { inputs.forEach(i -> { @@ -86,35 +97,52 @@ public class NodeActionVo { return; } - if (name.startsWith("setup-")) { - List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()).stream().filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); + step.put("name", node.getLabel()); + step.put("uses", node.getFull_name().trim()); + if (!inputs.isEmpty()) { + Map with = new LinkedHashMap<>(); + inputs.forEach(i -> { + with.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); + }); - step.put("name", node.getLabel()); - step.put("uses", node.getFull_name()); - if (!inputs.isEmpty()) { - Map with = new LinkedHashMap<>(); - inputs.forEach(i -> { - with.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); - }); - - step.put("with", with); - } - steps.add(step); + step.put("with", with); } + steps.add(step); + } public void buildShellStep(List> steps, PipelineVo.PipelineJson.Nodes node) { - String fullName = node.getFull_name(); - if (Objects.equals(fullName, "shell")) { - Map step = new LinkedHashMap<>(); - step.put("name", node.getLabel()); -// step.put("run",""); - List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()); + Map step = new LinkedHashMap<>(); + step.put("name", node.getLabel()); + List inputs = Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()); + inputs.forEach(i -> { + step.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); + }); + + steps.add(step); + } + + public void buildOtherStep(List> steps, PipelineVo.PipelineJson.Nodes node) { + Map step = new LinkedHashMap<>(); + + List inputs = getInputs(node); + + step.put("name", node.getLabel()); + step.put("uses", node.getFull_name().trim()); + if (!inputs.isEmpty()) { + Map with = new LinkedHashMap<>(); inputs.forEach(i -> { - step.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); + with.put(i.getName(), Optional.ofNullable(i.getValue()).orElse("")); }); - steps.add(step); + step.put("with", with); } + steps.add(step); + } + + private List getInputs(PipelineVo.PipelineJson.Nodes node) { + return Optional.ofNullable(node.getInputs()).orElse(new ArrayList<>()) + .stream() + .filter(e -> StringUtils.isNotBlank(e.getValue())).collect(Collectors.toList()); } } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java index 4f7ada59b..d48bfbf49 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java @@ -378,7 +378,15 @@ public class PmsCiPipelinesServiceImpl implements IPmsCiPipelinesService { try { PipelineVo vo = JSON.parseObject(JSON.toJSONString(pmsCiPipelineBuildInputVo), PipelineVo.class); - NodeActionVo actionVo = getNodeActionVo(vo); + List nodes = vo.getPipelineJson().getNodes(); + String pipelineName = vo.getPipelineName(); + NodeActionVo actionVo = new NodeActionVo(); + actionVo.buildName(pipelineName); + nodes.forEach(s -> { + List> steps = new ArrayList<>(); + actionVo.parse(steps, s); + actionVo.buildJobs("job", s.getLabel()+String.format("[%s]",s.getId().trim()), steps); + }); String yaml = YamlUtil.toYaml(actionVo); JSONObject result = new JSONObject(); result.put("pipeline_yaml", yaml); @@ -389,22 +397,6 @@ public class PmsCiPipelinesServiceImpl implements IPmsCiPipelinesService { } } - private NodeActionVo getNodeActionVo(PipelineVo vo) { - List nodes = vo.getPipelineJson().getNodes(); - String pipelineName = vo.getPipelineName(); - NodeActionVo actionVo = new NodeActionVo(); - actionVo.buildName(pipelineName); - AtomicInteger i = new AtomicInteger(); - nodes.forEach(s -> { - List> steps = new ArrayList<>(); - actionVo.buildOn(s); - actionVo.buildSetupStep(steps, s); - actionVo.buildShellStep(steps, s); - actionVo.buildJobs("job" + (i.getAndIncrement()), s.getLabel(), steps); - }); - return actionVo; - } - @Override public JSONObject reRunPipelineRunsJob(Long id, String run, String job) { PmsCiPipelines pmsCiPipelines = pmsCiPipelinesMapper.selectPmsCiPipelinesById(id); From d4ba19f70789ae684ada741debfea7bd31081f0f Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Mon, 2 Dec 2024 11:42:05 +0800 Subject: [PATCH 10/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B=EF=BC=89:=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E3=80=81=E5=88=9B=E5=AE=A2=E7=A9=BA=E9=97=B4=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8F=AF=E8=A7=86=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/constant/CacheConstants.java | 7 + .../microservices-modules-dss/pom.xml | 137 +++++ .../dss/MicroservicesDssApplication.java | 25 + .../dss/enums/DssTaskStatus.java | 30 ++ .../controller/MakerSpaceDataController.java | 85 +++ .../dss/makerspace/domain/Tasks.java | 387 ++++++++++++++ .../domain/vo/MakerSpaceTotalDataVo.java | 21 + .../makerspace/domain/vo/TaskHeatInfoVo.java | 17 + .../dss/makerspace/mapper/TasksMapper.java | 43 ++ .../dss/makerspace/service/ITasksService.java | 28 + .../service/impl/TasksServiceImpl.java | 128 +++++ .../controller/ProjectDataController.java | 31 ++ .../dss/projects/domain/Commits.java | 95 ++++ .../domain/DeveloperNewDetailData.java | 77 +++ .../domain/DeveloperNewDetailDataByDate.java | 59 +++ .../dss/projects/domain/Issues.java | 315 ++++++++++++ .../dss/projects/domain/Journals.java | 205 ++++++++ .../projects/domain/PieChartNameAndValue.java | 24 + .../dss/projects/domain/Projects.java | 485 ++++++++++++++++++ .../dss/projects/domain/ProjectsActivity.java | 97 ++++ .../dss/projects/domain/PullRequests.java | 195 +++++++ .../dss/projects/domain/User.java | 483 +++++++++++++++++ .../domain/vo/DeveloperNewTotalDataVo.java | 51 ++ .../domain/vo/GlobalResourcesDataVo.java | 149 ++++++ .../vo/SingleProjectResourcesDataVo.java | 126 +++++ .../dss/projects/mapper/CommitsMapper.java | 14 + .../dss/projects/mapper/IssuesMapper.java | 11 + .../dss/projects/mapper/JournalsMapper.java | 11 + .../dss/projects/mapper/ProjectsMapper.java | 21 + .../projects/mapper/PullRequestsMapper.java | 14 + .../dss/projects/mapper/UserMapper.java | 16 + .../IProjectGlobalResourcesService.java | 10 + .../ProjectGlobalResourcesServiceImpl.java | 155 ++++++ .../dss/task/ProjectsGlobalResourcesTask.java | 40 ++ .../dss/utils/DataStructureConvertUtil.java | 44 ++ .../com/microservices/dss/utils/DateUtil.java | 62 +++ .../src/main/resources/bootstrap-prod.yml | 34 ++ .../src/main/resources/bootstrap.yml | 32 ++ .../src/main/resources/logback.xml | 101 ++++ .../resources/mapper/dss/CommitsMapper.xml | 33 ++ .../resources/mapper/dss/IssuesMapper.xml | 50 ++ .../resources/mapper/dss/JournalsMapper.xml | 39 ++ .../resources/mapper/dss/ProjectsMapper.xml | 102 ++++ .../mapper/dss/PullRequestsMapper.xml | 44 ++ .../main/resources/mapper/dss/TasksMapper.xml | 200 ++++++++ .../main/resources/mapper/dss/UserMapper.xml | 85 +++ microservices-modules/pom.xml | 1 + 47 files changed, 4419 insertions(+) create mode 100644 microservices-modules/microservices-modules-dss/pom.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/MicroservicesDssApplication.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/enums/DssTaskStatus.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/Tasks.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/MakerSpaceTotalDataVo.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Commits.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailData.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailDataByDate.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Issues.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Journals.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PieChartNameAndValue.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Projects.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/ProjectsActivity.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PullRequests.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/User.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/DeveloperNewTotalDataVo.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/GlobalResourcesDataVo.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/SingleProjectResourcesDataVo.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/CommitsMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/IssuesMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/JournalsMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/ProjectsMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/PullRequestsMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DataStructureConvertUtil.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DateUtil.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/bootstrap-prod.yml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/bootstrap.yml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/logback.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/CommitsMapper.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/IssuesMapper.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/JournalsMapper.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/ProjectsMapper.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/PullRequestsMapper.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml create mode 100644 microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java index 8b81ff6af..077e3511f 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/CacheConstants.java @@ -228,4 +228,11 @@ public class CacheConstants { public static String getAllZoneProjectSortByScore(Long zoneId) { return ZONE_PROJECT_SORT_BY_SCORE + "*:" + zoneId + ":*"; } + + // 全局资源数据缓存,最近一年统计数据 + public final static String GLOBAL_RESOURCES_DATA_KEY = "GLOBAL_RESOURCES_DATA:"; + + public static String getGlobalResourcesDataKey(String startDate, String endDate) { + return GLOBAL_RESOURCES_DATA_KEY + startDate + "_TO_" + endDate; + } } diff --git a/microservices-modules/microservices-modules-dss/pom.xml b/microservices-modules/microservices-modules-dss/pom.xml new file mode 100644 index 000000000..46f38149b --- /dev/null +++ b/microservices-modules/microservices-modules-dss/pom.xml @@ -0,0 +1,137 @@ + + + 4.0.0 + + com.microservices + microservices-modules + 3.6.2 + + + microservices-modules-dss + + + microservices-modules-dss数据统计模块data statistics module + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + mysql + mysql-connector-java + + + + + com.microservices + microservices-common-async + + + + + com.microservices + microservices-common-datasource + + + + + com.microservices + microservices-common-datascope + + + + + com.microservices + microservices-common-log + + + + + com.microservices + microservices-common-swagger + + + com.microservices + microservices-common-security + + + com.microservices + microservices-common-swagger + + + org.springframework.security + spring-security-core + + + com.microservices + microservices-common-core + + + org.projectlombok + lombok + + + + org.apache.httpcomponents + httpclient + 4.5.14 + + + com.microservices + microservices-common-httpClient + 3.6.2 + compile + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/MicroservicesDssApplication.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/MicroservicesDssApplication.java new file mode 100644 index 000000000..f7b65777e --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/MicroservicesDssApplication.java @@ -0,0 +1,25 @@ +package com.microservices.dss; + +import com.microservices.common.security.annotation.EnableCustomConfig; +import com.microservices.common.security.annotation.EnableRyFeignClients; +import com.microservices.common.swagger.annotation.EnableCustomSwagger2; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * 数据统计模块 + * + * @author wanjia + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +@EnableScheduling +public class MicroservicesDssApplication { + public static void main(String[] args) { + SpringApplication.run(MicroservicesDssApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 数据统计模块启动成功 ლ(´ڡ`ლ)゙ \n"); + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/enums/DssTaskStatus.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/enums/DssTaskStatus.java new file mode 100644 index 000000000..f55a7dc89 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/enums/DssTaskStatus.java @@ -0,0 +1,30 @@ +package com.microservices.dss.enums; + +public enum DssTaskStatus { + DRAFT(0, "草稿"), + AUDIT(1, "待审核"), + REJECTED(2, "已拒绝"), + PAPER_COLLECT(3, "成果征集中"), + PAPER_SELECT(4, "成果评选中"), + PUBLICITY(5, "公示中"), + CONTRACT(6, "协议签订中"), + PAYMENT(7, "支付中"), + COMPLETE(8, "已完成"), + REVISE(9, "待修缮"); + + private final int key; + private final String name; + + DssTaskStatus(int key, String name) { + this.key = key; + this.name = name; + } + + public int getKey() { + return key; + } + + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java new file mode 100644 index 000000000..3b0e23765 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java @@ -0,0 +1,85 @@ +package com.microservices.dss.makerspace.controller; + +import com.microservices.common.core.web.controller.BaseController; +import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.dss.makerspace.service.ITasksService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/makerSpace") +@Api(tags = "数据统计-创客空间相关接口") +public class MakerSpaceDataController extends BaseController { + + @Autowired + private ITasksService tasksService; + + @ApiOperation("创客空间全局资源获取") + @GetMapping(value = "/total") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getTotalData() { + return success(tasksService.getTotalStatisticalData()); + } + + @ApiOperation("创客任务新增趋势") + @GetMapping(value = "/task/trend") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getTaskTrendData() { + return success(tasksService.getTaskAdditionTrendData()); + } + + @ApiOperation("创客成果新增趋势") + @GetMapping(value = "/paper/trend") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getPaperTrendData() { + return success(tasksService.getPaperAdditionTrendData()); + } + + @ApiOperation("创客任务最新操作日志") + @GetMapping(value = "/task/operLog") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getPaperTrendData(@ApiParam("获取最新操作日志的数量") @RequestParam Integer topNum) { + return success(tasksService.getTaskOperLogTopN(topNum)); + } + + @ApiOperation("创客任务奖金分布") + @GetMapping(value = "/task/bountyDistribution") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getBountyDistribution() { + return success(tasksService.getBountyDistribution()); + } + + @ApiOperation("创客任务热度排行") + @GetMapping(value = "/task/heatRank") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getHeatTopN(@ApiParam("获取热度排行的数量") @RequestParam Integer topNum) { + return success(tasksService.getTaskHeatTopN(topNum)); + } + + @ApiOperation("创客类型分布统计(统筹/自主)") + @GetMapping(value = "/task/mode") +// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + public AjaxResult getTaskModeStatisticalData() { + return success(tasksService.getTaskModeStatisticalData()); + } + + @ApiOperation("创客任务-开启中状态任务数分布") + @GetMapping(value = "/task/statusDistribution/opening") + public AjaxResult getOpeningTaskStatusDistribution(@ApiParam("获取开启中状态任务分布的数量") @RequestParam Integer topNum) { + return success(tasksService.getOpeningTaskStatusDistribution(topNum)); + } + + @ApiOperation("创客任务-所有任务类型分布") + @GetMapping(value = "/task/categoryDistribution") + public AjaxResult getAllTaskCategoryDistribution() { + return success(tasksService.getAllTaskCategoryDistribution()); + } + + +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/Tasks.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/Tasks.java new file mode 100644 index 000000000..1edca5220 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/Tasks.java @@ -0,0 +1,387 @@ +package com.microservices.dss.makerspace.domain; + + +import java.math.BigDecimal; +import java.util.Date; + +public class Tasks { + private Integer id; + + private String name; + + private BigDecimal bounty; + + private String number; + + private Boolean published; + + private Integer visits; + + private Date expiredAt; + + private Date publishedAt; + + private Integer publishMode; + + private Integer collectionMode; + + private Integer showUserMode; + + private Integer status; + + private Integer papersCount; + + private Integer taskModeId; + + private Date createdAt; + + private Date updatedAt; + + private Integer categoryId; + + private Integer userId; + + private String enterpriseName; + + private String contactName; + + private String contactPhone; + + private Boolean showUserStatus; + + private Integer agreementSigning; + + private Boolean isDelete; + + private String ip; + + private Date paidAt; + + private Date makePublicAt; + + private Integer collectingDays; + + private Integer choosingDays; + + private Integer makePublicDays; + + private Integer signingDays; + + private Integer payingDays; + + private Boolean exceptClosedBoolean; + + private Boolean isProofBoolean; + + private Integer cancelStatus; + + private Integer isSigningUpload; + + private Boolean isPayingUpload; + + private Date uploadProofAt; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name == null ? null : name.trim(); + } + + public BigDecimal getBounty() { + return bounty; + } + + public void setBounty(BigDecimal bounty) { + this.bounty = bounty; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number == null ? null : number.trim(); + } + + public Boolean getPublished() { + return published; + } + + public void setPublished(Boolean published) { + this.published = published; + } + + public Integer getVisits() { + return visits; + } + + public void setVisits(Integer visits) { + this.visits = visits; + } + + public Date getExpiredAt() { + return expiredAt; + } + + public void setExpiredAt(Date expiredAt) { + this.expiredAt = expiredAt; + } + + public Date getPublishedAt() { + return publishedAt; + } + + public void setPublishedAt(Date publishedAt) { + this.publishedAt = publishedAt; + } + + public Integer getPublishMode() { + return publishMode; + } + + public void setPublishMode(Integer publishMode) { + this.publishMode = publishMode; + } + + public Integer getCollectionMode() { + return collectionMode; + } + + public void setCollectionMode(Integer collectionMode) { + this.collectionMode = collectionMode; + } + + public Integer getShowUserMode() { + return showUserMode; + } + + public void setShowUserMode(Integer showUserMode) { + this.showUserMode = showUserMode; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getPapersCount() { + return papersCount; + } + + public void setPapersCount(Integer papersCount) { + this.papersCount = papersCount; + } + + public Integer getTaskModeId() { + return taskModeId; + } + + public void setTaskModeId(Integer taskModeId) { + this.taskModeId = taskModeId; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Integer getCategoryId() { + return categoryId; + } + + public void setCategoryId(Integer categoryId) { + this.categoryId = categoryId; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public String getEnterpriseName() { + return enterpriseName; + } + + public void setEnterpriseName(String enterpriseName) { + this.enterpriseName = enterpriseName == null ? null : enterpriseName.trim(); + } + + public String getContactName() { + return contactName; + } + + public void setContactName(String contactName) { + this.contactName = contactName == null ? null : contactName.trim(); + } + + public String getContactPhone() { + return contactPhone; + } + + public void setContactPhone(String contactPhone) { + this.contactPhone = contactPhone == null ? null : contactPhone.trim(); + } + + public Boolean getShowUserStatus() { + return showUserStatus; + } + + public void setShowUserStatus(Boolean showUserStatus) { + this.showUserStatus = showUserStatus; + } + + public Integer getAgreementSigning() { + return agreementSigning; + } + + public void setAgreementSigning(Integer agreementSigning) { + this.agreementSigning = agreementSigning; + } + + public Boolean getIsDelete() { + return isDelete; + } + + public void setIsDelete(Boolean isDelete) { + this.isDelete = isDelete; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip == null ? null : ip.trim(); + } + + public Date getPaidAt() { + return paidAt; + } + + public void setPaidAt(Date paidAt) { + this.paidAt = paidAt; + } + + public Date getMakePublicAt() { + return makePublicAt; + } + + public void setMakePublicAt(Date makePublicAt) { + this.makePublicAt = makePublicAt; + } + + public Integer getCollectingDays() { + return collectingDays; + } + + public void setCollectingDays(Integer collectingDays) { + this.collectingDays = collectingDays; + } + + public Integer getChoosingDays() { + return choosingDays; + } + + public void setChoosingDays(Integer choosingDays) { + this.choosingDays = choosingDays; + } + + public Integer getMakePublicDays() { + return makePublicDays; + } + + public void setMakePublicDays(Integer makePublicDays) { + this.makePublicDays = makePublicDays; + } + + public Integer getSigningDays() { + return signingDays; + } + + public void setSigningDays(Integer signingDays) { + this.signingDays = signingDays; + } + + public Integer getPayingDays() { + return payingDays; + } + + public void setPayingDays(Integer payingDays) { + this.payingDays = payingDays; + } + + public Boolean getExceptClosedBoolean() { + return exceptClosedBoolean; + } + + public void setExceptClosedBoolean(Boolean exceptClosedBoolean) { + this.exceptClosedBoolean = exceptClosedBoolean; + } + + public Boolean getIsProofBoolean() { + return isProofBoolean; + } + + public void setIsProofBoolean(Boolean isProofBoolean) { + this.isProofBoolean = isProofBoolean; + } + + public Integer getCancelStatus() { + return cancelStatus; + } + + public void setCancelStatus(Integer cancelStatus) { + this.cancelStatus = cancelStatus; + } + + public Integer getIsSigningUpload() { + return isSigningUpload; + } + + public void setIsSigningUpload(Integer isSigningUpload) { + this.isSigningUpload = isSigningUpload; + } + + public Boolean getIsPayingUpload() { + return isPayingUpload; + } + + public void setIsPayingUpload(Boolean isPayingUpload) { + this.isPayingUpload = isPayingUpload; + } + + public Date getUploadProofAt() { + return uploadProofAt; + } + + public void setUploadProofAt(Date uploadProofAt) { + this.uploadProofAt = uploadProofAt; + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/MakerSpaceTotalDataVo.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/MakerSpaceTotalDataVo.java new file mode 100644 index 000000000..7e9dabf45 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/MakerSpaceTotalDataVo.java @@ -0,0 +1,21 @@ +package com.microservices.dss.makerspace.domain.vo; + +import lombok.Data; + +import java.util.List; + + +@Data +public class MakerSpaceTotalDataVo { + + private int totalTasks; + + private int totalApplicants; + + private int currentTotalAwardAmount; + + private List taskPublishedCountsByYear; + + private List taskBountyCountsByYear; + +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java new file mode 100644 index 000000000..d1e3ac447 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java @@ -0,0 +1,17 @@ +package com.microservices.dss.makerspace.domain.vo; + +import lombok.Data; + +import java.util.Date; + +@Data +public class TaskHeatInfoVo { + + private String taskName; + + private Date publishDate; + + private Integer participantCount; + + private String winnerNames; +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java new file mode 100644 index 000000000..264f1577a --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java @@ -0,0 +1,43 @@ +package com.microservices.dss.makerspace.mapper; + + +import com.microservices.dss.makerspace.domain.vo.TaskHeatInfoVo; +import com.microservices.dss.projects.domain.PieChartNameAndValue; +import org.apache.ibatis.annotations.MapKey; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface TasksMapper{ + + int getTotalTaskCount(); + + int getTotalApplicantCount(); + + int getCurrentTotalAwardAmount(); + + List getTaskPublishedCountsByYear(); + + List getTaskBountyCountsByYear(); + + List getNewAddedTasksByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); + + List getNewAddedPapersByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); + + List getTaskOperLogTopN(@Param("topNum") Integer topNum); + + List getOpeningTaskNumOfTaskStatus(@Param("topNum") Integer topNum); + + List getAllTaskNumOfTaskCategory(); + + List> getBountyDistribution(); + + Map getTotalCompletedBounty(); + + List getTaskInfoByVisits(@Param("topNum") Integer topNum); + + List> getTaskModeStatistic(); +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java new file mode 100644 index 000000000..b147ec69f --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java @@ -0,0 +1,28 @@ +package com.microservices.dss.makerspace.service; + +import com.microservices.dss.makerspace.domain.vo.MakerSpaceTotalDataVo; +import com.microservices.dss.makerspace.domain.vo.TaskHeatInfoVo; +import com.microservices.dss.projects.domain.PieChartNameAndValue; + +import java.util.List; +import java.util.Map; + +public interface ITasksService { + MakerSpaceTotalDataVo getTotalStatisticalData(); + + int[] getTaskAdditionTrendData(); + + int[] getPaperAdditionTrendData(); + + List getTaskOperLogTopN(Integer topNum); + + List getOpeningTaskStatusDistribution(Integer topNum); + + List getAllTaskCategoryDistribution(); + + List> getBountyDistribution(); + + List getTaskHeatTopN(Integer topNum); + + List> getTaskModeStatisticalData(); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java new file mode 100644 index 000000000..d217e477d --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java @@ -0,0 +1,128 @@ +package com.microservices.dss.makerspace.service.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microservices.common.core.exception.ServiceException; +import com.microservices.dss.enums.DssTaskStatus; +import com.microservices.dss.makerspace.domain.vo.MakerSpaceTotalDataVo; +import com.microservices.dss.makerspace.domain.vo.TaskHeatInfoVo; +import com.microservices.dss.makerspace.mapper.TasksMapper; +import com.microservices.dss.makerspace.service.ITasksService; +import com.microservices.dss.projects.domain.PieChartNameAndValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.ParseException; +import java.util.List; +import java.util.Map; + +import static com.microservices.dss.utils.DataStructureConvertUtil.MapInitByMonth; +import static com.microservices.dss.utils.DataStructureConvertUtil.dbResult2Array; +import static com.microservices.dss.utils.DateUtil.getFormattedCurrentDateTime; +import static com.microservices.dss.utils.DateUtil.getFormattedPreviousYearSameMonth; + +@Service +public class TasksServiceImpl implements ITasksService { + + private static final Logger logger = LoggerFactory.getLogger(TasksServiceImpl.class); + + @Resource + private TasksMapper tasksMapper; + + @Override + public MakerSpaceTotalDataVo getTotalStatisticalData() { + MakerSpaceTotalDataVo makerSpaceTotalDataVo = new MakerSpaceTotalDataVo(); + makerSpaceTotalDataVo.setTotalTasks(tasksMapper.getTotalTaskCount()); + makerSpaceTotalDataVo.setTotalApplicants(tasksMapper.getTotalApplicantCount()); + makerSpaceTotalDataVo.setCurrentTotalAwardAmount(tasksMapper.getCurrentTotalAwardAmount()/10000); + makerSpaceTotalDataVo.setTaskPublishedCountsByYear(tasksMapper.getTaskPublishedCountsByYear()); + makerSpaceTotalDataVo.setTaskBountyCountsByYear(tasksMapper.getTaskBountyCountsByYear()); + return makerSpaceTotalDataVo; + } + + @Override + public int[] getTaskAdditionTrendData() { + String startTime = getFormattedPreviousYearSameMonth(); + String endTime = getFormattedCurrentDateTime(); + try { + return getNewAddedTasksByMonth(startTime, endTime); + } catch (ParseException e) { + logger.error("ParseException occurred while getting task addition trend data", e); + throw new ServiceException("获取新增任务趋势数据失败"); + } catch (JsonProcessingException e) { + logger.error("JsonProcessingException occurred while getting task addition trend data", e); + throw new ServiceException("获取新增任务趋势数据失败"); + } + } + + @Override + public int[] getPaperAdditionTrendData() { + String startTime = getFormattedPreviousYearSameMonth(); + String endTime = getFormattedCurrentDateTime(); + try { + return getNewAddedPapersByMonth(startTime, endTime); + } catch (ParseException e) { + logger.error("ParseException occurred while getting paper addition trend data", e); + throw new ServiceException("获取新增成果趋势数据失败"); + } catch (JsonProcessingException e) { + logger.error("JsonProcessingException occurred while getting paper addition trend data", e); + throw new ServiceException("获取新增成果趋势数据失败"); + } + } + + @Override + public List getTaskOperLogTopN(Integer topNum) { + return tasksMapper.getTaskOperLogTopN(topNum); + } + + @Override + public List getOpeningTaskStatusDistribution(Integer topNum) { + List distribution = tasksMapper.getOpeningTaskNumOfTaskStatus(topNum); + for (PieChartNameAndValue pieChartNameAndValue : distribution) { + DssTaskStatus status = DssTaskStatus.values()[Integer.parseInt(pieChartNameAndValue.getName())]; + pieChartNameAndValue.setName(status.getName()); + } + return distribution; + } + + @Override + public List getAllTaskCategoryDistribution() { + return tasksMapper.getAllTaskNumOfTaskCategory(); + } + + @Override + public List> getBountyDistribution() { + List> bountyDistribution = tasksMapper.getBountyDistribution(); + Map totalCompletedBounty = tasksMapper.getTotalCompletedBounty(); + bountyDistribution.add(totalCompletedBounty); + return bountyDistribution; + } + + @Override + public List getTaskHeatTopN(Integer topNum) { + + return tasksMapper.getTaskInfoByVisits(topNum); + } + + @Override + public List> getTaskModeStatisticalData() { + return tasksMapper.getTaskModeStatistic(); + } + + private int[] getNewAddedTasksByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException { + int monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = tasksMapper.getNewAddedTasksByMonth(startTime, endTime); + int[] resultArray = new int[monthDiff+1]; + return dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + } + + private int[] getNewAddedPapersByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException { + int monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = tasksMapper.getNewAddedPapersByMonth(startTime, endTime); + int[] resultArray = new int[monthDiff+1]; + return dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java new file mode 100644 index 000000000..f08694864 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java @@ -0,0 +1,31 @@ +package com.microservices.dss.projects.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microservices.common.core.web.controller.BaseController; +import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.dss.projects.service.IProjectGlobalResourcesService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.text.ParseException; + +@RestController +@RequestMapping("/projects") +@Api(tags = "数据统计-开源项目相关接口") +public class ProjectDataController extends BaseController { + + @Autowired + private IProjectGlobalResourcesService projectGlobalResourcesService; + + @ApiOperation("开源项目全局资源获取") + @GetMapping(value = "/global-resources") +// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + public AjaxResult getGlobalResourcesData() throws ParseException, JsonProcessingException { + return success(projectGlobalResourcesService.getProjectGlobalResourcesData()); + } + +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Commits.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Commits.java new file mode 100644 index 000000000..44fd6ef48 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Commits.java @@ -0,0 +1,95 @@ +package com.microservices.dss.projects.domain; + +import java.util.Date; + +public class Commits { + private Integer id; + + private Integer repositoryId; + + private String version; + + private String committer; + + private Date committedOn; + + private Integer projectId; + + private Date createdAt; + + private Date updatedAt; + + private String comments; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getRepositoryId() { + return repositoryId; + } + + public void setRepositoryId(Integer repositoryId) { + this.repositoryId = repositoryId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version == null ? null : version.trim(); + } + + public String getCommitter() { + return committer; + } + + public void setCommitter(String committer) { + this.committer = committer == null ? null : committer.trim(); + } + + public Date getCommittedOn() { + return committedOn; + } + + public void setCommittedOn(Date committedOn) { + this.committedOn = committedOn; + } + + public Integer getProjectId() { + return projectId; + } + + public void setProjectId(Integer projectId) { + this.projectId = projectId; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments == null ? null : comments.trim(); + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailData.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailData.java new file mode 100644 index 000000000..fafd119c8 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailData.java @@ -0,0 +1,77 @@ +package com.microservices.dss.projects.domain; + +public class DeveloperNewDetailData { + + private int id; + private String userName; + private String nickName; + private int newTask; + private int completedTask; + private int newPrNum; + private int newCommitNum; + private int newCodeNum; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public int getNewTask() { + return newTask; + } + + public void setNewTask(int newTask) { + this.newTask = newTask; + } + + public int getCompletedTask() { + return completedTask; + } + + public void setCompletedTask(int completedTask) { + this.completedTask = completedTask; + } + + public int getNewPrNum() { + return newPrNum; + } + + public void setNewPrNum(int newPrNum) { + this.newPrNum = newPrNum; + } + + public int getNewCommitNum() { + return newCommitNum; + } + + public void setNewCommitNum(int newCommitNum) { + this.newCommitNum = newCommitNum; + } + + public int getNewCodeNum() { + return newCodeNum; + } + + public void setNewCodeNum(int newCodeNum) { + this.newCodeNum = newCodeNum; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailDataByDate.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailDataByDate.java new file mode 100644 index 000000000..181163fe6 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/DeveloperNewDetailDataByDate.java @@ -0,0 +1,59 @@ +package com.microservices.dss.projects.domain; + +public class DeveloperNewDetailDataByDate { + + private String date; + private int newTask; + private int completedTask; + private int newPrNum; + private int newCommitNum; + private int newCodeNum; + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public int getNewTask() { + return newTask; + } + + public void setNewTask(int newTask) { + this.newTask = newTask; + } + + public int getCompletedTask() { + return completedTask; + } + + public void setCompletedTask(int completedTask) { + this.completedTask = completedTask; + } + + public int getNewPrNum() { + return newPrNum; + } + + public void setNewPrNum(int newPrNum) { + this.newPrNum = newPrNum; + } + + public int getNewCommitNum() { + return newCommitNum; + } + + public void setNewCommitNum(int newCommitNum) { + this.newCommitNum = newCommitNum; + } + + public int getNewCodeNum() { + return newCodeNum; + } + + public void setNewCodeNum(int newCodeNum) { + this.newCodeNum = newCodeNum; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Issues.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Issues.java new file mode 100644 index 000000000..f7c250f88 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Issues.java @@ -0,0 +1,315 @@ +package com.microservices.dss.projects.domain; + +import java.util.Date; + +public class Issues { + private Integer id; + + private Integer trackerId; + + private Integer projectId; + + private String subject; + + private Date dueDate; + + private Integer categoryId; + + private Integer statusId; + + private Integer assignedToId; + + private Integer priorityId; + + private Integer fixedVersionId; + + private Integer authorId; + + private Date createdOn; + + private Date updatedOn; + + private Date startDate; + + private Integer doneRatio; + + private Float estimatedHours; + + private Integer parentId; + + private Integer rootId; + + private Integer lft; + + private Integer rgt; + + private Boolean isPrivate; + + private Date closedOn; + + private Integer projectIssuesIndex; + + private String issueType; + + private Integer token; + + private String issueTagsValue; + + private Boolean isLock; + + private String issueClassify; + + private String refName; + + private String branchName; + + private String description; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getTrackerId() { + return trackerId; + } + + public void setTrackerId(Integer trackerId) { + this.trackerId = trackerId; + } + + public Integer getProjectId() { + return projectId; + } + + public void setProjectId(Integer projectId) { + this.projectId = projectId; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject == null ? null : subject.trim(); + } + + public Date getDueDate() { + return dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + public Integer getCategoryId() { + return categoryId; + } + + public void setCategoryId(Integer categoryId) { + this.categoryId = categoryId; + } + + public Integer getStatusId() { + return statusId; + } + + public void setStatusId(Integer statusId) { + this.statusId = statusId; + } + + public Integer getAssignedToId() { + return assignedToId; + } + + public void setAssignedToId(Integer assignedToId) { + this.assignedToId = assignedToId; + } + + public Integer getPriorityId() { + return priorityId; + } + + public void setPriorityId(Integer priorityId) { + this.priorityId = priorityId; + } + + public Integer getFixedVersionId() { + return fixedVersionId; + } + + public void setFixedVersionId(Integer fixedVersionId) { + this.fixedVersionId = fixedVersionId; + } + + public Integer getAuthorId() { + return authorId; + } + + public void setAuthorId(Integer authorId) { + this.authorId = authorId; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public Date getUpdatedOn() { + return updatedOn; + } + + public void setUpdatedOn(Date updatedOn) { + this.updatedOn = updatedOn; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Integer getDoneRatio() { + return doneRatio; + } + + public void setDoneRatio(Integer doneRatio) { + this.doneRatio = doneRatio; + } + + public Float getEstimatedHours() { + return estimatedHours; + } + + public void setEstimatedHours(Float estimatedHours) { + this.estimatedHours = estimatedHours; + } + + public Integer getParentId() { + return parentId; + } + + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + public Integer getRootId() { + return rootId; + } + + public void setRootId(Integer rootId) { + this.rootId = rootId; + } + + public Integer getLft() { + return lft; + } + + public void setLft(Integer lft) { + this.lft = lft; + } + + public Integer getRgt() { + return rgt; + } + + public void setRgt(Integer rgt) { + this.rgt = rgt; + } + + public Boolean getIsPrivate() { + return isPrivate; + } + + public void setIsPrivate(Boolean isPrivate) { + this.isPrivate = isPrivate; + } + + public Date getClosedOn() { + return closedOn; + } + + public void setClosedOn(Date closedOn) { + this.closedOn = closedOn; + } + + public Integer getProjectIssuesIndex() { + return projectIssuesIndex; + } + + public void setProjectIssuesIndex(Integer projectIssuesIndex) { + this.projectIssuesIndex = projectIssuesIndex; + } + + public String getIssueType() { + return issueType; + } + + public void setIssueType(String issueType) { + this.issueType = issueType == null ? null : issueType.trim(); + } + + public Integer getToken() { + return token; + } + + public void setToken(Integer token) { + this.token = token; + } + + public String getIssueTagsValue() { + return issueTagsValue; + } + + public void setIssueTagsValue(String issueTagsValue) { + this.issueTagsValue = issueTagsValue == null ? null : issueTagsValue.trim(); + } + + public Boolean getIsLock() { + return isLock; + } + + public void setIsLock(Boolean isLock) { + this.isLock = isLock; + } + + public String getIssueClassify() { + return issueClassify; + } + + public void setIssueClassify(String issueClassify) { + this.issueClassify = issueClassify == null ? null : issueClassify.trim(); + } + + public String getRefName() { + return refName; + } + + public void setRefName(String refName) { + this.refName = refName == null ? null : refName.trim(); + } + + public String getBranchName() { + return branchName; + } + + public void setBranchName(String branchName) { + this.branchName = branchName == null ? null : branchName.trim(); + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description == null ? null : description.trim(); + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Journals.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Journals.java new file mode 100644 index 000000000..f7dbc16d0 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Journals.java @@ -0,0 +1,205 @@ +package com.microservices.dss.projects.domain; + +import java.util.Date; + +public class Journals { + private Integer id; + + private Integer journalizedId; + + private String journalizedType; + + private Integer userId; + + private String notes; + + private Date createdOn; + + private Boolean privateNotes; + + private Integer parentId; + + private Integer commentsCount; + + private Integer replyId; + + private Long reviewId; + + private String commitId; + + private String lineCode; + + private String path; + + private Integer state; + + private Date resolveAt; + + private Integer resolveerId; + + private Boolean needRespond; + + private Date updatedOn; + + private String diff; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getJournalizedId() { + return journalizedId; + } + + public void setJournalizedId(Integer journalizedId) { + this.journalizedId = journalizedId; + } + + public String getJournalizedType() { + return journalizedType; + } + + public void setJournalizedType(String journalizedType) { + this.journalizedType = journalizedType == null ? null : journalizedType.trim(); + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes == null ? null : notes.trim(); + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public Boolean getPrivateNotes() { + return privateNotes; + } + + public void setPrivateNotes(Boolean privateNotes) { + this.privateNotes = privateNotes; + } + + public Integer getParentId() { + return parentId; + } + + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + public Integer getCommentsCount() { + return commentsCount; + } + + public void setCommentsCount(Integer commentsCount) { + this.commentsCount = commentsCount; + } + + public Integer getReplyId() { + return replyId; + } + + public void setReplyId(Integer replyId) { + this.replyId = replyId; + } + + public Long getReviewId() { + return reviewId; + } + + public void setReviewId(Long reviewId) { + this.reviewId = reviewId; + } + + public String getCommitId() { + return commitId; + } + + public void setCommitId(String commitId) { + this.commitId = commitId == null ? null : commitId.trim(); + } + + public String getLineCode() { + return lineCode; + } + + public void setLineCode(String lineCode) { + this.lineCode = lineCode == null ? null : lineCode.trim(); + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path == null ? null : path.trim(); + } + + public Integer getState() { + return state; + } + + public void setState(Integer state) { + this.state = state; + } + + public Date getResolveAt() { + return resolveAt; + } + + public void setResolveAt(Date resolveAt) { + this.resolveAt = resolveAt; + } + + public Integer getResolveerId() { + return resolveerId; + } + + public void setResolveerId(Integer resolveerId) { + this.resolveerId = resolveerId; + } + + public Boolean getNeedRespond() { + return needRespond; + } + + public void setNeedRespond(Boolean needRespond) { + this.needRespond = needRespond; + } + + public Date getUpdatedOn() { + return updatedOn; + } + + public void setUpdatedOn(Date updatedOn) { + this.updatedOn = updatedOn; + } + + public String getDiff() { + return diff; + } + + public void setDiff(String diff) { + this.diff = diff == null ? null : diff.trim(); + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PieChartNameAndValue.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PieChartNameAndValue.java new file mode 100644 index 000000000..439a9cca6 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PieChartNameAndValue.java @@ -0,0 +1,24 @@ +package com.microservices.dss.projects.domain; + +public class PieChartNameAndValue { + + private String name; + + private Integer value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Projects.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Projects.java new file mode 100644 index 000000000..9deddb919 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/Projects.java @@ -0,0 +1,485 @@ +package com.microservices.dss.projects.domain; + +import java.util.Date; + +public class Projects { + private Integer id; + + private String name; + + private String homepage; + + private Boolean isPublic; + + private Integer parentId; + + private Date createdOn; + + private Date updatedOn; + + private String identifier; + + private Integer status; + + private Integer lft; + + private Integer rgt; + + private Boolean inheritMembers; + + private Integer projectType; + + private Boolean hiddenRepo; + + private Integer attachmenttype; + + private Integer userId; + + private Integer dtsTest; + + private String enterpriseName; + + private Integer organizationId; + + private Integer projectNewType; + + private Integer gpid; + + private Integer forkedFromProjectId; + + private Integer forkedCount; + + private Integer publishResource; + + private Integer visits; + + private Integer hot; + + private String inviteCode; + + private String qrcode; + + private Integer qrcodeExpiretime; + + private Byte trainingStatus; + + private String repIdentifier; + + private Integer projectCategoryId; + + private Integer projectLanguageId; + + private Integer licenseId; + + private Integer ignoreId; + + private Integer praisesCount; + + private Integer watchersCount; + + private Integer issuesCount; + + private Integer pullRequestsCount; + + private String language; + + private Integer versionsCount; + + private Integer issueTagsCount; + + private Integer closedIssuesCount; + + private Boolean openDevops; + + private Integer giteaWebhookId; + + private Integer openDevopsCount; + + private Boolean recommend; + + private Integer platform; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name == null ? null : name.trim(); + } + + public String getHomepage() { + return homepage; + } + + public void setHomepage(String homepage) { + this.homepage = homepage == null ? null : homepage.trim(); + } + + public Boolean getIsPublic() { + return isPublic; + } + + public void setIsPublic(Boolean isPublic) { + this.isPublic = isPublic; + } + + public Integer getParentId() { + return parentId; + } + + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public Date getUpdatedOn() { + return updatedOn; + } + + public void setUpdatedOn(Date updatedOn) { + this.updatedOn = updatedOn; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier == null ? null : identifier.trim(); + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getLft() { + return lft; + } + + public void setLft(Integer lft) { + this.lft = lft; + } + + public Integer getRgt() { + return rgt; + } + + public void setRgt(Integer rgt) { + this.rgt = rgt; + } + + public Boolean getInheritMembers() { + return inheritMembers; + } + + public void setInheritMembers(Boolean inheritMembers) { + this.inheritMembers = inheritMembers; + } + + public Integer getProjectType() { + return projectType; + } + + public void setProjectType(Integer projectType) { + this.projectType = projectType; + } + + public Boolean getHiddenRepo() { + return hiddenRepo; + } + + public void setHiddenRepo(Boolean hiddenRepo) { + this.hiddenRepo = hiddenRepo; + } + + public Integer getAttachmenttype() { + return attachmenttype; + } + + public void setAttachmenttype(Integer attachmenttype) { + this.attachmenttype = attachmenttype; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public Integer getDtsTest() { + return dtsTest; + } + + public void setDtsTest(Integer dtsTest) { + this.dtsTest = dtsTest; + } + + public String getEnterpriseName() { + return enterpriseName; + } + + public void setEnterpriseName(String enterpriseName) { + this.enterpriseName = enterpriseName == null ? null : enterpriseName.trim(); + } + + public Integer getOrganizationId() { + return organizationId; + } + + public void setOrganizationId(Integer organizationId) { + this.organizationId = organizationId; + } + + public Integer getProjectNewType() { + return projectNewType; + } + + public void setProjectNewType(Integer projectNewType) { + this.projectNewType = projectNewType; + } + + public Integer getGpid() { + return gpid; + } + + public void setGpid(Integer gpid) { + this.gpid = gpid; + } + + public Integer getForkedFromProjectId() { + return forkedFromProjectId; + } + + public void setForkedFromProjectId(Integer forkedFromProjectId) { + this.forkedFromProjectId = forkedFromProjectId; + } + + public Integer getForkedCount() { + return forkedCount; + } + + public void setForkedCount(Integer forkedCount) { + this.forkedCount = forkedCount; + } + + public Integer getPublishResource() { + return publishResource; + } + + public void setPublishResource(Integer publishResource) { + this.publishResource = publishResource; + } + + public Integer getVisits() { + return visits; + } + + public void setVisits(Integer visits) { + this.visits = visits; + } + + public Integer getHot() { + return hot; + } + + public void setHot(Integer hot) { + this.hot = hot; + } + + public String getInviteCode() { + return inviteCode; + } + + public void setInviteCode(String inviteCode) { + this.inviteCode = inviteCode == null ? null : inviteCode.trim(); + } + + public String getQrcode() { + return qrcode; + } + + public void setQrcode(String qrcode) { + this.qrcode = qrcode == null ? null : qrcode.trim(); + } + + public Integer getQrcodeExpiretime() { + return qrcodeExpiretime; + } + + public void setQrcodeExpiretime(Integer qrcodeExpiretime) { + this.qrcodeExpiretime = qrcodeExpiretime; + } + + public Byte getTrainingStatus() { + return trainingStatus; + } + + public void setTrainingStatus(Byte trainingStatus) { + this.trainingStatus = trainingStatus; + } + + public String getRepIdentifier() { + return repIdentifier; + } + + public void setRepIdentifier(String repIdentifier) { + this.repIdentifier = repIdentifier == null ? null : repIdentifier.trim(); + } + + public Integer getProjectCategoryId() { + return projectCategoryId; + } + + public void setProjectCategoryId(Integer projectCategoryId) { + this.projectCategoryId = projectCategoryId; + } + + public Integer getProjectLanguageId() { + return projectLanguageId; + } + + public void setProjectLanguageId(Integer projectLanguageId) { + this.projectLanguageId = projectLanguageId; + } + + public Integer getLicenseId() { + return licenseId; + } + + public void setLicenseId(Integer licenseId) { + this.licenseId = licenseId; + } + + public Integer getIgnoreId() { + return ignoreId; + } + + public void setIgnoreId(Integer ignoreId) { + this.ignoreId = ignoreId; + } + + public Integer getPraisesCount() { + return praisesCount; + } + + public void setPraisesCount(Integer praisesCount) { + this.praisesCount = praisesCount; + } + + public Integer getWatchersCount() { + return watchersCount; + } + + public void setWatchersCount(Integer watchersCount) { + this.watchersCount = watchersCount; + } + + public Integer getIssuesCount() { + return issuesCount; + } + + public void setIssuesCount(Integer issuesCount) { + this.issuesCount = issuesCount; + } + + public Integer getPullRequestsCount() { + return pullRequestsCount; + } + + public void setPullRequestsCount(Integer pullRequestsCount) { + this.pullRequestsCount = pullRequestsCount; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language == null ? null : language.trim(); + } + + public Integer getVersionsCount() { + return versionsCount; + } + + public void setVersionsCount(Integer versionsCount) { + this.versionsCount = versionsCount; + } + + public Integer getIssueTagsCount() { + return issueTagsCount; + } + + public void setIssueTagsCount(Integer issueTagsCount) { + this.issueTagsCount = issueTagsCount; + } + + public Integer getClosedIssuesCount() { + return closedIssuesCount; + } + + public void setClosedIssuesCount(Integer closedIssuesCount) { + this.closedIssuesCount = closedIssuesCount; + } + + public Boolean getOpenDevops() { + return openDevops; + } + + public void setOpenDevops(Boolean openDevops) { + this.openDevops = openDevops; + } + + public Integer getGiteaWebhookId() { + return giteaWebhookId; + } + + public void setGiteaWebhookId(Integer giteaWebhookId) { + this.giteaWebhookId = giteaWebhookId; + } + + public Integer getOpenDevopsCount() { + return openDevopsCount; + } + + public void setOpenDevopsCount(Integer openDevopsCount) { + this.openDevopsCount = openDevopsCount; + } + + public Boolean getRecommend() { + return recommend; + } + + public void setRecommend(Boolean recommend) { + this.recommend = recommend; + } + + public Integer getPlatform() { + return platform; + } + + public void setPlatform(Integer platform) { + this.platform = platform; + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/ProjectsActivity.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/ProjectsActivity.java new file mode 100644 index 000000000..a22db5860 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/ProjectsActivity.java @@ -0,0 +1,97 @@ +package com.microservices.dss.projects.domain; + +//项目活跃度相关数据 +public class ProjectsActivity { + + private int id; + private int projectId; + private String name; + private int activityScore; + private int visits; + private int watchersCount; + private int praisesCount; + private int issuesCount; + private int pullRequestsCount; + private int versionsCount; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getProjectId() { + return projectId; + } + + public void setProjectId(int projectId) { + this.projectId = projectId; + } + + public int getPullRequestsCount() { + return pullRequestsCount; + } + + public void setPullRequestsCount(int pullRequestsCount) { + this.pullRequestsCount = pullRequestsCount; + } + + public int getVisits() { + return visits; + } + + public void setVisits(int visits) { + this.visits = visits; + } + + public int getWatchersCount() { + return watchersCount; + } + + public void setWatchersCount(int watchersCount) { + this.watchersCount = watchersCount; + } + + public int getPraisesCount() { + return praisesCount; + } + + public void setPraisesCount(int praisesCount) { + this.praisesCount = praisesCount; + } + + public int getIssuesCount() { + return issuesCount; + } + + public void setIssuesCount(int issuesCount) { + this.issuesCount = issuesCount; + } + + public int getVersionsCount() { + return versionsCount; + } + + public void setVersionsCount(int versionsCount) { + this.versionsCount = versionsCount; + } + + public int getActivityScore() { + return activityScore; + } + + public void setActivityScore(int activityScore) { + this.activityScore = activityScore; + } +} + diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PullRequests.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PullRequests.java new file mode 100644 index 000000000..2a027fcc0 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/PullRequests.java @@ -0,0 +1,195 @@ +package com.microservices.dss.projects.domain; + +import java.util.Date; + +public class PullRequests { + private Integer id; + + private Integer pullRequestId; + + private Integer gpid; + + private Integer userId; + + private Date createdAt; + + private Date updatedAt; + + private Integer status; + + private Integer projectId; + + private String title; + + private Integer milestone; + + private String head; + + private String base; + + private Integer issueId; + + private Integer forkProjectId; + + private Boolean isOriginal; + + private Integer commentsCount; + + private Integer commitsCount; + + private Integer filesCount; + + private String body; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getPullRequestId() { + return pullRequestId; + } + + public void setPullRequestId(Integer pullRequestId) { + this.pullRequestId = pullRequestId; + } + + public Integer getGpid() { + return gpid; + } + + public void setGpid(Integer gpid) { + this.gpid = gpid; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getProjectId() { + return projectId; + } + + public void setProjectId(Integer projectId) { + this.projectId = projectId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title == null ? null : title.trim(); + } + + public Integer getMilestone() { + return milestone; + } + + public void setMilestone(Integer milestone) { + this.milestone = milestone; + } + + public String getHead() { + return head; + } + + public void setHead(String head) { + this.head = head == null ? null : head.trim(); + } + + public String getBase() { + return base; + } + + public void setBase(String base) { + this.base = base == null ? null : base.trim(); + } + + public Integer getIssueId() { + return issueId; + } + + public void setIssueId(Integer issueId) { + this.issueId = issueId; + } + + public Integer getForkProjectId() { + return forkProjectId; + } + + public void setForkProjectId(Integer forkProjectId) { + this.forkProjectId = forkProjectId; + } + + public Boolean getIsOriginal() { + return isOriginal; + } + + public void setIsOriginal(Boolean isOriginal) { + this.isOriginal = isOriginal; + } + + public Integer getCommentsCount() { + return commentsCount; + } + + public void setCommentsCount(Integer commentsCount) { + this.commentsCount = commentsCount; + } + + public Integer getCommitsCount() { + return commitsCount; + } + + public void setCommitsCount(Integer commitsCount) { + this.commitsCount = commitsCount; + } + + public Integer getFilesCount() { + return filesCount; + } + + public void setFilesCount(Integer filesCount) { + this.filesCount = filesCount; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body == null ? null : body.trim(); + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/User.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/User.java new file mode 100644 index 000000000..b1d49bb6e --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/User.java @@ -0,0 +1,483 @@ +package com.microservices.dss.projects.domain; + + +import java.util.Date; + +public class User { + + private Integer id; + + private String login; + + private String hashedPassword; + + private String firstname; + + private String lastname; + + private String mail; + + private Boolean admin; + + private Integer status; + + private Date lastLoginOn; + + private String language; + + private Integer authSourceId; + + private Date createdOn; + + private Date updatedOn; + + private String type; + + private String identityUrl; + + private String mailNotification; + + private String salt; + + private Integer gid; + + private Integer visits; + + private Integer excellentTeacher; + + private Integer excellentStudent; + + private String phone; + + private Boolean authentication; + + private Integer grade; + + private Integer experience; + + private String nickname; + + private Boolean showRealname; + + private Boolean professionalCertification; + + private String idNumber; + + private Integer certification; + + private Boolean homepageTeacher; + + private Boolean homepageEngineer; + + private Byte isTest; + + private Integer ecoderUserId; + + private Boolean business; + + private Boolean profileCompleted; + + private Long laboratoryId; + + private String platform; + + private String giteaToken; + + private Integer giteaUid; + + private Boolean isShixunMarker; + + private Boolean isSyncPwd; + + private Integer watchersCount; + + private Boolean enterpriseCertification; + + private Byte adminRole; + + private Integer devopsStep; + + public Boolean getShixunMarker() { + return isShixunMarker; + } + + public void setShixunMarker(Boolean shixunMarker) { + isShixunMarker = shixunMarker; + } + + public Boolean getSyncPwd() { + return isSyncPwd; + } + + public void setSyncPwd(Boolean syncPwd) { + isSyncPwd = syncPwd; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login == null ? null : login.trim(); + } + + public String getHashedPassword() { + return hashedPassword; + } + + public void setHashedPassword(String hashedPassword) { + this.hashedPassword = hashedPassword == null ? null : hashedPassword.trim(); + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname == null ? null : firstname.trim(); + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname == null ? null : lastname.trim(); + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail == null ? null : mail.trim(); + } + + public Boolean getAdmin() { + return admin; + } + + public void setAdmin(Boolean admin) { + this.admin = admin; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Date getLastLoginOn() { + return lastLoginOn; + } + + public void setLastLoginOn(Date lastLoginOn) { + this.lastLoginOn = lastLoginOn; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language == null ? null : language.trim(); + } + + public Integer getAuthSourceId() { + return authSourceId; + } + + public void setAuthSourceId(Integer authSourceId) { + this.authSourceId = authSourceId; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public Date getUpdatedOn() { + return updatedOn; + } + + public void setUpdatedOn(Date updatedOn) { + this.updatedOn = updatedOn; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type == null ? null : type.trim(); + } + + public String getIdentityUrl() { + return identityUrl; + } + + public void setIdentityUrl(String identityUrl) { + this.identityUrl = identityUrl == null ? null : identityUrl.trim(); + } + + public String getMailNotification() { + return mailNotification; + } + + public void setMailNotification(String mailNotification) { + this.mailNotification = mailNotification == null ? null : mailNotification.trim(); + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt == null ? null : salt.trim(); + } + + public Integer getGid() { + return gid; + } + + public void setGid(Integer gid) { + this.gid = gid; + } + + public Integer getVisits() { + return visits; + } + + public void setVisits(Integer visits) { + this.visits = visits; + } + + public Integer getExcellentTeacher() { + return excellentTeacher; + } + + public void setExcellentTeacher(Integer excellentTeacher) { + this.excellentTeacher = excellentTeacher; + } + + public Integer getExcellentStudent() { + return excellentStudent; + } + + public void setExcellentStudent(Integer excellentStudent) { + this.excellentStudent = excellentStudent; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone == null ? null : phone.trim(); + } + + public Boolean getAuthentication() { + return authentication; + } + + public void setAuthentication(Boolean authentication) { + this.authentication = authentication; + } + + public Integer getGrade() { + return grade; + } + + public void setGrade(Integer grade) { + this.grade = grade; + } + + public Integer getExperience() { + return experience; + } + + public void setExperience(Integer experience) { + this.experience = experience; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname == null ? null : nickname.trim(); + } + + public Boolean getShowRealname() { + return showRealname; + } + + public void setShowRealname(Boolean showRealname) { + this.showRealname = showRealname; + } + + public Boolean getProfessionalCertification() { + return professionalCertification; + } + + public void setProfessionalCertification(Boolean professionalCertification) { + this.professionalCertification = professionalCertification; + } + + public String getIdNumber() { + return idNumber; + } + + public void setIdNumber(String idNumber) { + this.idNumber = idNumber == null ? null : idNumber.trim(); + } + + public Integer getCertification() { + return certification; + } + + public void setCertification(Integer certification) { + this.certification = certification; + } + + public Boolean getHomepageTeacher() { + return homepageTeacher; + } + + public void setHomepageTeacher(Boolean homepageTeacher) { + this.homepageTeacher = homepageTeacher; + } + + public Boolean getHomepageEngineer() { + return homepageEngineer; + } + + public void setHomepageEngineer(Boolean homepageEngineer) { + this.homepageEngineer = homepageEngineer; + } + + public Byte getIsTest() { + return isTest; + } + + public void setIsTest(Byte isTest) { + this.isTest = isTest; + } + + public Integer getEcoderUserId() { + return ecoderUserId; + } + + public void setEcoderUserId(Integer ecoderUserId) { + this.ecoderUserId = ecoderUserId; + } + + public Boolean getBusiness() { + return business; + } + + public void setBusiness(Boolean business) { + this.business = business; + } + + public Boolean getProfileCompleted() { + return profileCompleted; + } + + public void setProfileCompleted(Boolean profileCompleted) { + this.profileCompleted = profileCompleted; + } + + public Long getLaboratoryId() { + return laboratoryId; + } + + public void setLaboratoryId(Long laboratoryId) { + this.laboratoryId = laboratoryId; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform == null ? null : platform.trim(); + } + + public String getGiteaToken() { + return giteaToken; + } + + public void setGiteaToken(String giteaToken) { + this.giteaToken = giteaToken == null ? null : giteaToken.trim(); + } + + public Integer getGiteaUid() { + return giteaUid; + } + + public void setGiteaUid(Integer giteaUid) { + this.giteaUid = giteaUid; + } + + public Boolean getIsShixunMarker() { + return isShixunMarker; + } + + public void setIsShixunMarker(Boolean isShixunMarker) { + this.isShixunMarker = isShixunMarker; + } + + public Boolean getIsSyncPwd() { + return isSyncPwd; + } + + public void setIsSyncPwd(Boolean isSyncPwd) { + this.isSyncPwd = isSyncPwd; + } + + public Integer getWatchersCount() { + return watchersCount; + } + + public void setWatchersCount(Integer watchersCount) { + this.watchersCount = watchersCount; + } + + public Boolean getEnterpriseCertification() { + return enterpriseCertification; + } + + public void setEnterpriseCertification(Boolean enterpriseCertification) { + this.enterpriseCertification = enterpriseCertification; + } + + public Byte getAdminRole() { + return adminRole; + } + + public void setAdminRole(Byte adminRole) { + this.adminRole = adminRole; + } + + public Integer getDevopsStep() { + return devopsStep; + } + + public void setDevopsStep(Integer devopsStep) { + this.devopsStep = devopsStep; + } +} \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/DeveloperNewTotalDataVo.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/DeveloperNewTotalDataVo.java new file mode 100644 index 000000000..0c7e3f1a7 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/DeveloperNewTotalDataVo.java @@ -0,0 +1,51 @@ +package com.microservices.dss.projects.domain.vo; + +//新增任务数,完成任务数,新增PR数,新增提交数,新增代码数。 +public class DeveloperNewTotalDataVo { + + private int[] newTask; + private int[] completedTask; + private int[] newPrNum; + private int[] newCommitNum; + private int[] newCodeNum; + + public int[] getNewTask() { + return newTask; + } + + public void setNewTask(int[] newTask) { + this.newTask = newTask; + } + + public int[] getCompletedTask() { + return completedTask; + } + + public void setCompletedTask(int[] completedTask) { + this.completedTask = completedTask; + } + + public int[] getNewPrNum() { + return newPrNum; + } + + public void setNewPrNum(int[] newPrNum) { + this.newPrNum = newPrNum; + } + + public int[] getNewCodeNum() { + return newCodeNum; + } + + public void setNewCodeNum(int[] newCodeNum) { + this.newCodeNum = newCodeNum; + } + + public int[] getNewCommitNum() { + return newCommitNum; + } + + public void setNewCommitNum(int[] newCommitNum) { + this.newCommitNum = newCommitNum; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/GlobalResourcesDataVo.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/GlobalResourcesDataVo.java new file mode 100644 index 000000000..b95618e35 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/GlobalResourcesDataVo.java @@ -0,0 +1,149 @@ +package com.microservices.dss.projects.domain.vo; + + +import com.microservices.dss.projects.domain.PieChartNameAndValue; + +import java.util.List; + +//1.总项目数,总成员数, +//2.新增项目数,新增成员数,新增代码提交次数,任务完成量 +public class GlobalResourcesDataVo { + + private int totalProjects; + private int totalMembers; + private int totalCommits; + private int totalPullRequest; + private int[] newAddedProjects; + private int[] newAddedMembers; + private int[] newCodeSubmissionTimes; + private int[] newPullRequestTimes; + private int[] newCommentTimes; + private int[] taskCompletion; + private int[] activeProjects; + private int[] activeUsers; + private String[] weeklyDates; + + private List programLanguagePieChart; + + private List projectCategoryPieChart; + + public int getTotalProjects() { + return totalProjects; + } + + public void setTotalProjects(int totalProjects) { + this.totalProjects = totalProjects; + } + + public int getTotalMembers() { + return totalMembers; + } + + public void setTotalMembers(int totalMembers) { + this.totalMembers = totalMembers; + } + + public int getTotalCommits() { + return totalCommits; + } + + public void setTotalCommits(int totalCommits) { + this.totalCommits = totalCommits; + } + + public int getTotalPullRequest() { + return totalPullRequest; + } + + public void setTotalPullRequest(int totalPullRequest) { + this.totalPullRequest = totalPullRequest; + } + + public int[] getNewAddedProjects() { + return newAddedProjects; + } + + public void setNewAddedProjects(int[] newAddedProjects) { + this.newAddedProjects = newAddedProjects; + } + + public int[] getNewAddedMembers() { + return newAddedMembers; + } + + public void setNewAddedMembers(int[] newAddedMembers) { + this.newAddedMembers = newAddedMembers; + } + + public int[] getNewCodeSubmissionTimes() { + return newCodeSubmissionTimes; + } + + public void setNewCodeSubmissionTimes(int[] newCodeSubmissionTimes) { + this.newCodeSubmissionTimes = newCodeSubmissionTimes; + } + + public int[] getNewPullRequestTimes() { + return newPullRequestTimes; + } + + public void setNewPullRequestTimes(int[] newPullRequestTimes) { + this.newPullRequestTimes = newPullRequestTimes; + } + + public int[] getNewCommentTimes() { + return newCommentTimes; + } + + public void setNewCommentTimes(int[] newCommentTimes) { + this.newCommentTimes = newCommentTimes; + } + + public int[] getTaskCompletion() { + return taskCompletion; + } + + public void setTaskCompletion(int[] taskCompletion) { + this.taskCompletion = taskCompletion; + } + + public int[] getActiveProjects() { + return activeProjects; + } + + public void setActiveProjects(int[] activeProjects) { + this.activeProjects = activeProjects; + } + + public int[] getActiveUsers() { + return activeUsers; + } + + public void setActiveUsers(int[] activeUsers) { + this.activeUsers = activeUsers; + } + + public String[] getWeeklyDates() { + return weeklyDates; + } + + public void setWeeklyDates(String[] weeklyDates) { + this.weeklyDates = weeklyDates; + } + + public List getProgramLanguagePieChart() { + return programLanguagePieChart; + } + + public void setProgramLanguagePieChart(List programLanguagePieChart) { + this.programLanguagePieChart = programLanguagePieChart; + } + + public List getProjectCategoryPieChart() { + return projectCategoryPieChart; + } + + public void setProjectCategoryPieChart(List projectCategoryPieChart) { + this.projectCategoryPieChart = projectCategoryPieChart; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/SingleProjectResourcesDataVo.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/SingleProjectResourcesDataVo.java new file mode 100644 index 000000000..a47919523 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/domain/vo/SingleProjectResourcesDataVo.java @@ -0,0 +1,126 @@ +package com.microservices.dss.projects.domain.vo; + +public class SingleProjectResourcesDataVo { + + private int totalWatcher; + private int totalPraise; + private int totalForked; + private int totalVisits; + + private int[] newDeveloperNum; + private int[] newCodeSubmissionTimes; + private int[] newPullRequestTimes; + private int[] newCommentTimes; + private int[] newIssueNum; + private int[] newForkNum; + private int[] newWatchNum; + private int[] newProjectTrendNum; + + + private String[] weeklyDates; + + + public int getTotalWatcher() { + return totalWatcher; + } + + public void setTotalWatcher(int totalWatcher) { + this.totalWatcher = totalWatcher; + } + + public int getTotalPraise() { + return totalPraise; + } + + public void setTotalPraise(int totalPraise) { + this.totalPraise = totalPraise; + } + + public int getTotalForked() { + return totalForked; + } + + public void setTotalForked(int totalForked) { + this.totalForked = totalForked; + } + + public int getTotalVisits() { + return totalVisits; + } + + public void setTotalVisits(int totalVisits) { + this.totalVisits = totalVisits; + } + + public int[] getNewDeveloperNum() { + return newDeveloperNum; + } + + public void setNewDeveloperNum(int[] newDeveloperNum) { + this.newDeveloperNum = newDeveloperNum; + } + + public int[] getNewCodeSubmissionTimes() { + return newCodeSubmissionTimes; + } + + public void setNewCodeSubmissionTimes(int[] newCodeSubmissionTimes) { + this.newCodeSubmissionTimes = newCodeSubmissionTimes; + } + + public int[] getNewPullRequestTimes() { + return newPullRequestTimes; + } + + public void setNewPullRequestTimes(int[] newPullRequestTimes) { + this.newPullRequestTimes = newPullRequestTimes; + } + + public int[] getNewCommentTimes() { + return newCommentTimes; + } + + public void setNewCommentTimes(int[] newCommentTimes) { + this.newCommentTimes = newCommentTimes; + } + + public int[] getNewIssueNum() { + return newIssueNum; + } + + public void setNewIssueNum(int[] newIssueNum) { + this.newIssueNum = newIssueNum; + } + + public int[] getNewForkNum() { + return newForkNum; + } + + public void setNewForkNum(int[] newForkNum) { + this.newForkNum = newForkNum; + } + + public String[] getWeeklyDates() { + return weeklyDates; + } + + public void setWeeklyDates(String[] weeklyDates) { + this.weeklyDates = weeklyDates; + } + + public int[] getNewWatchNum() { + return newWatchNum; + } + + public void setNewWatchNum(int[] newWatchNum) { + this.newWatchNum = newWatchNum; + } + + public int[] getNewProjectTrendNum() { + return newProjectTrendNum; + } + + public void setNewProjectTrendNum(int[] newProjectTrendNum) { + this.newProjectTrendNum = newProjectTrendNum; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/CommitsMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/CommitsMapper.java new file mode 100644 index 000000000..b6265dba7 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/CommitsMapper.java @@ -0,0 +1,14 @@ +package com.microservices.dss.projects.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface CommitsMapper { + + int selectTotalCommitCount(); + + List getNewCodeSubmissionTimesByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/IssuesMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/IssuesMapper.java new file mode 100644 index 000000000..b6f60bbd7 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/IssuesMapper.java @@ -0,0 +1,11 @@ +package com.microservices.dss.projects.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface IssuesMapper { + List getNewAddedIssuesCompletionByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/JournalsMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/JournalsMapper.java new file mode 100644 index 000000000..02a06d088 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/JournalsMapper.java @@ -0,0 +1,11 @@ +package com.microservices.dss.projects.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface JournalsMapper { + List getNewJournalsNumByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/ProjectsMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/ProjectsMapper.java new file mode 100644 index 000000000..631527be8 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/ProjectsMapper.java @@ -0,0 +1,21 @@ +package com.microservices.dss.projects.mapper; + +import com.microservices.dss.projects.domain.PieChartNameAndValue; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface ProjectsMapper { + + int selectProjectCount(); + + List getNewAddedProjectsByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); + + List getActiveProjectsByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); + + List getProjectNumOfDiffProgramLanguage(@Param("topNumber") Integer topNumber); + + List getProjectNumOfProjectCategory(@Param("topNumber") Integer topNumber); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/PullRequestsMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/PullRequestsMapper.java new file mode 100644 index 000000000..ee5e2cc97 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/PullRequestsMapper.java @@ -0,0 +1,14 @@ +package com.microservices.dss.projects.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface PullRequestsMapper { + + int selectTotalPullRequestCount(); + + List getNewPullRequestNumByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java new file mode 100644 index 000000000..356a14a57 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java @@ -0,0 +1,16 @@ +package com.microservices.dss.projects.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface UserMapper { + + int selectUserCount(); + + List getNewAddedMembersByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); + + List getActiveMembersByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java new file mode 100644 index 000000000..0d344dd9d --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java @@ -0,0 +1,10 @@ +package com.microservices.dss.projects.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microservices.dss.projects.domain.vo.GlobalResourcesDataVo; + +import java.text.ParseException; + +public interface IProjectGlobalResourcesService { + GlobalResourcesDataVo getProjectGlobalResourcesData() throws ParseException, JsonProcessingException; +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java new file mode 100644 index 000000000..af1953547 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java @@ -0,0 +1,155 @@ +package com.microservices.dss.projects.service.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microservices.common.core.constant.CacheConstants; +import com.microservices.dss.projects.domain.vo.GlobalResourcesDataVo; +import com.microservices.dss.projects.mapper.*; +import com.microservices.dss.projects.service.IProjectGlobalResourcesService; +import com.microservices.dss.utils.DateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import com.microservices.common.redis.service.RedisService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +import static com.microservices.dss.utils.DataStructureConvertUtil.MapInitByMonth; +import static com.microservices.dss.utils.DataStructureConvertUtil.dbResult2Array; +import static com.microservices.dss.utils.DateUtil.*; + +@Service +public class ProjectGlobalResourcesServiceImpl implements IProjectGlobalResourcesService { + @Autowired + private RedisService redisService; + + @Resource + private ProjectsMapper projectsMapper; + + @Resource + private UserMapper userMapper; + + @Resource + private CommitsMapper commitsMapper; + + @Resource + private PullRequestsMapper pullRequestsMapper; + + @Resource + private IssuesMapper issuesMapper; + + @Resource + private JournalsMapper journalsMapper; + + @Override + public GlobalResourcesDataVo getProjectGlobalResourcesData() throws ParseException, JsonProcessingException { + String currentYearMonth = currentYearMonth(); + String previousYearMonth = DateUtil.DateAddByYear(currentYearMonth, -1); + GlobalResourcesDataVo globalResourcesDataVo = new GlobalResourcesDataVo(); + String cacheKey = CacheConstants.getGlobalResourcesDataKey(previousYearMonth, currentYearMonth); + if (redisService.hasKey(cacheKey)) { + globalResourcesDataVo = redisService.getCacheObject(cacheKey); + return globalResourcesDataVo; + } + + String startTime = getFormattedPreviousYearSameMonth(); + String endTime = getFormattedCurrentDateTime(); + globalResourcesDataVo.setTotalProjects(this.getTotalProjects()); + globalResourcesDataVo.setTotalMembers(userMapper.selectUserCount()); + globalResourcesDataVo.setTotalCommits(commitsMapper.selectTotalCommitCount()); + globalResourcesDataVo.setTotalPullRequest(pullRequestsMapper.selectTotalPullRequestCount()); + globalResourcesDataVo.setNewAddedProjects(this.getNewAddedProjectsByMonth(startTime, endTime)); + globalResourcesDataVo.setNewAddedMembers(this.getNewAddedMembersByMonth(startTime, endTime)); + globalResourcesDataVo.setNewPullRequestTimes(this.getNewPrNumByMonth(startTime, endTime)); + globalResourcesDataVo.setNewCommentTimes(this.getNewCommentNumByMonth(startTime, endTime)); + globalResourcesDataVo.setActiveUsers(this.getActiveMembersByMonth(startTime, endTime)); + globalResourcesDataVo.setActiveProjects(this.getActiveProjectsByMonth(startTime, endTime)); + globalResourcesDataVo.setNewCodeSubmissionTimes(this.getNewCodeSubmissionTimesByMonth(startTime, endTime)); + globalResourcesDataVo.setTaskCompletion(this.getNewAddedIssuesCompletionByMonth(startTime,endTime)); + globalResourcesDataVo.setProgramLanguagePieChart(projectsMapper.getProjectNumOfDiffProgramLanguage(6)); + globalResourcesDataVo.setProjectCategoryPieChart(projectsMapper.getProjectNumOfProjectCategory(6)); + return globalResourcesDataVo; + } + + private int getTotalProjects() { + return projectsMapper.selectProjectCount(); + } + + private int[] getNewAddedProjectsByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException { + int monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = projectsMapper.getNewAddedProjectsByMonth(startTime, endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getNewAddedMembersByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException { + int monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = userMapper.getNewAddedMembersByMonth(startTime,endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getNewPrNumByMonth(String startTime, String endTime) throws JsonProcessingException, ParseException{ + int monthDiff; + monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = pullRequestsMapper.getNewPullRequestNumByMonth(startTime,endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getNewCommentNumByMonth(String startTime, String endTime) throws JsonProcessingException, ParseException { + int monthDiff; + monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = journalsMapper.getNewJournalsNumByMonth(startTime,endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getActiveMembersByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException { + int monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = userMapper.getActiveMembersByMonth(startTime,endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getActiveProjectsByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException { + int monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = projectsMapper.getActiveProjectsByMonth(startTime, endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getNewCodeSubmissionTimesByMonth(String startTime, String endTime) throws JsonProcessingException, ParseException { + int monthDiff; + monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = commitsMapper.getNewCodeSubmissionTimesByMonth(startTime,endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } + + private int[] getNewAddedIssuesCompletionByMonth(String startTime, String endTime) throws JsonProcessingException, ParseException { + int monthDiff; + monthDiff = 12; + Map map_init = MapInitByMonth(monthDiff,endTime); + List Db_result = issuesMapper.getNewAddedIssuesCompletionByMonth(startTime,endTime); + int[] resultArray = new int[monthDiff+1]; + int[] result = dbResult2Array(Db_result,"createTime","num",map_init,resultArray); + return result; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java new file mode 100644 index 000000000..5c2d44351 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java @@ -0,0 +1,40 @@ +package com.microservices.dss.task; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microservices.common.core.constant.CacheConstants; +import com.microservices.common.redis.service.RedisService; +import com.microservices.dss.projects.domain.vo.GlobalResourcesDataVo; +import com.microservices.dss.projects.service.IProjectGlobalResourcesService; +import com.microservices.dss.utils.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.concurrent.TimeUnit; + +@Component +public class ProjectsGlobalResourcesTask { + + private static final Logger log = LoggerFactory.getLogger(ProjectsGlobalResourcesTask.class); + + @Autowired + private IProjectGlobalResourcesService projectGlobalResourcesService; + + @Autowired + private RedisService redisService; + + @Scheduled(cron = "0 0 2 * * ?") + public void updateProjectsGlobalResources() throws ParseException, JsonProcessingException { + log.info("开始更新近一年全局资源数据"); + String currentDate = new SimpleDateFormat("yyyy-MM").format(Calendar.getInstance().getTime()); + String startTime = DateUtil.DateAddByYear(currentDate, -1); + GlobalResourcesDataVo globalResourcesDataVo = projectGlobalResourcesService.getProjectGlobalResourcesData(); + String cacheKey = CacheConstants.getGlobalResourcesDataKey(startTime, currentDate); + redisService.setCacheObject(cacheKey, globalResourcesDataVo, 24L, TimeUnit.HOURS); + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DataStructureConvertUtil.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DataStructureConvertUtil.java new file mode 100644 index 000000000..d56fb7be9 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DataStructureConvertUtil.java @@ -0,0 +1,44 @@ +package com.microservices.dss.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.text.ParseException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class DataStructureConvertUtil { + + public static Map MapInitByMonth(int monthDiff, String endTime) throws ParseException { + + Map map_init = new LinkedHashMap<>(); + //构建一个size为monthDiff,按顺序的日期作为key,value为0 + for(int i=-(monthDiff);i<=0;i++){ + map_init.put(DateUtil.OnlyYearMonthDateAddByMonth(endTime,i),0); + } + return map_init; + } + + public static int[] dbResult2Array(List db_result, String key, String value, Map map_init, int[] resultArray) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + + for (Object o : db_result) { + // 使用 ObjectMapper 直接将对象转为 Map + Map m = mapper.convertValue(o, Map.class); + Object mapKey = m.get(key); + if (map_init.containsKey(mapKey)) { + map_init.put(mapKey, m.get(value)); + } + } + + int index = 0; // 维护一个索引 + for (Object mapValue : map_init.values()) { + if (index < resultArray.length) { // 确保不会越界 + resultArray[index++] = Integer.parseInt(mapValue.toString()); + } + } + + return resultArray; + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DateUtil.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DateUtil.java new file mode 100644 index 000000000..2e9ded0e3 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DateUtil.java @@ -0,0 +1,62 @@ +package com.microservices.dss.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DateUtil { + + public static final String PATTERN_DATE_ONLY_YEAR_MONTH = "yyyy-MM"; + + /** + * @author wanjia + * Description 日期运算,加减年份 + * Date 2021/5/12 19:47 + * @param date 传入日期 yyyy-mm-dd + * @param i 被加数 + * @return java.lang.String + **/ + public static String DateAddByYear(String date,int i) throws ParseException { + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat df=new SimpleDateFormat("yyyy-MM"); + Date date1 = df.parse(date); + calendar.setTime(date1); + calendar.add(Calendar.YEAR,i); + return df.format(calendar.getTime()); + } + + public static String OnlyYearMonthDateAddByMonth(String date,int i) throws ParseException { + Calendar calendar; + calendar = Calendar.getInstance(); + SimpleDateFormat df=new SimpleDateFormat(PATTERN_DATE_ONLY_YEAR_MONTH); + Date date1 = df.parse(date); + calendar.setTime(date1); + calendar.add(Calendar.MONTH,i); + return df.format(calendar.getTime()); + } + + public static String currentYearMonth() { + return new SimpleDateFormat("yyyy-MM").format(Calendar.getInstance().getTime()); + } + + public static String getFormattedCurrentDate() { + return new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime()); + } + + /** + * 得到当前日期的结束时间 + */ + public static String getFormattedCurrentDateTime() { + return getFormattedCurrentDate() + " 23:59:59"; + } + + /** + * 得到当前时间前一年同月的第一天的日期 + **/ + public static String getFormattedPreviousYearSameMonth() { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.YEAR, -1); + return new SimpleDateFormat("yyyy-MM-01 00:00:00").format(calendar.getTime()); + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/bootstrap-prod.yml b/microservices-modules/microservices-modules-dss/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..dcfd83d0f --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,34 @@ +# Tomcat +server: + port: 9198 + +# Spring +spring: + application: + # 应用名称 + name: microservices-dss + config: + activate: + # 环境配置 + on-profile: + prod + cloud: + sentinel: + # 取消控制台懒加载 + eager: true + nacos: + discovery: + # 服务注册地址 + server-addr: ${nacos_ip}:${nacos_port} + username: ${nacos_username} + password: ${nacos_password} + config: + # 配置中心地址 + server-addr: ${nacos_ip}:${nacos_port} + username: ${nacos_username} + password: ${nacos_password} + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - { dataId: "application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}",refresh: true } diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/bootstrap.yml b/microservices-modules/microservices-modules-dss/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..4c613e389 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/bootstrap.yml @@ -0,0 +1,32 @@ +# Tomcat +server: + port: 9198 + +# Spring +spring: + application: + # 应用名称 + name: microservices-dss + profiles: + # 环境配置 + active: dev + cloud: + sentinel: + # 取消控制台懒加载 + eager: true + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + username: nacos + password: nacos + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + username: nacos + password: nacos + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - { dataId: "application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}",refresh: true } diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml b/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml new file mode 100644 index 000000000..8d66f2a37 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + { + "level": "%level", + "tid": "%tid", + "skyWalkingContext": "%sw_ctx", + "thread": "%thread", + "class": "%logger{1.}:%L", + "message": "%message", + "stackTrace": "%exception{10}" + } + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/CommitsMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/CommitsMapper.xml new file mode 100644 index 000000000..183d7df2b --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/CommitsMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/IssuesMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/IssuesMapper.xml new file mode 100644 index 000000000..9c022d180 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/IssuesMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/JournalsMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/JournalsMapper.xml new file mode 100644 index 000000000..e5e6ce42f --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/JournalsMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/ProjectsMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/ProjectsMapper.xml new file mode 100644 index 000000000..30c928a32 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/ProjectsMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/PullRequestsMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/PullRequestsMapper.xml new file mode 100644 index 000000000..24cd7ff7a --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/PullRequestsMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml new file mode 100644 index 000000000..fa7b9956e --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml new file mode 100644 index 000000000..7f4b033d7 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/pom.xml b/microservices-modules/pom.xml index 369267f6c..70605677d 100644 --- a/microservices-modules/pom.xml +++ b/microservices-modules/pom.xml @@ -17,6 +17,7 @@ microservices-modules-zone microservices-modules-pms microservices-modules-wiki + microservices-modules-dss microservices-modules From f3d772feb63aa772c47b5319fad3619e49801fb5 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Sat, 14 Dec 2024 11:29:37 +0800 Subject: [PATCH 11/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E9=A1=B9=E7=9B=AE=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E3=80=81=E9=A1=B9=E7=9B=AE=E6=8E=92=E8=A1=8C=E3=80=81?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=8E=92=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ProjectDataController.java | 26 +++++++++++ .../IProjectGlobalResourcesService.java | 7 +++ .../ProjectGlobalResourcesServiceImpl.java | 31 +++++++++++++ .../dss/utils/DssGitLinkRequestUrl.java | 45 +++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java index f08694864..bc5bbfad9 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java @@ -6,9 +6,11 @@ import com.microservices.common.core.web.domain.AjaxResult; import com.microservices.dss.projects.service.IProjectGlobalResourcesService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.text.ParseException; @@ -28,4 +30,28 @@ public class ProjectDataController extends BaseController { return success(projectGlobalResourcesService.getProjectGlobalResourcesData()); } + @ApiOperation("开源项目最新动态获取") + @GetMapping(value = "/latestActivities") +// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + public AjaxResult getLatestActivitiesData(@ApiParam("分页数") @RequestParam(value = "page", defaultValue = "1") int page, + @ApiParam("分页大小") @RequestParam(value = "limit", defaultValue = "4") int limit){ + return success(projectGlobalResourcesService.getLatestActivitiesData(page, limit)); + } + + @ApiOperation("开源项目-项目排行获取") + @GetMapping(value = "/projectRank") +// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + public AjaxResult getProjectRankData(@ApiParam("统计时间范围(天)") @RequestParam(value = "time", defaultValue = "365") int time, + @ApiParam("top数") @RequestParam(value = "limit", defaultValue = "5") int limit){ + return success(projectGlobalResourcesService.getProjectRankData(time, limit)); + } + + @ApiOperation("开源项目-用户排行获取") + @GetMapping(value = "/userRank") +// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + public AjaxResult getUserRankData(@ApiParam("统计时间范围(天)") @RequestParam(value = "time", defaultValue = "365") int time, + @ApiParam("top数") @RequestParam(value = "limit", defaultValue = "5") int limit){ + return success(projectGlobalResourcesService.getUserRankData(time, limit)); + } + } diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java index 0d344dd9d..526ac2663 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/IProjectGlobalResourcesService.java @@ -1,5 +1,6 @@ package com.microservices.dss.projects.service; +import com.alibaba.fastjson2.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.microservices.dss.projects.domain.vo.GlobalResourcesDataVo; @@ -7,4 +8,10 @@ import java.text.ParseException; public interface IProjectGlobalResourcesService { GlobalResourcesDataVo getProjectGlobalResourcesData() throws ParseException, JsonProcessingException; + + JSONObject getLatestActivitiesData(int page, int limit); + + JSONObject getProjectRankData(int time, int limit); + + JSONObject getUserRankData(int time, int limit); } diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java index af1953547..67d4fff63 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java @@ -1,12 +1,15 @@ package com.microservices.dss.projects.service.impl; +import com.alibaba.fastjson2.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.microservices.common.core.constant.CacheConstants; +import com.microservices.common.httpClient.util.GitLinkRequestHelper; import com.microservices.dss.projects.domain.vo.GlobalResourcesDataVo; import com.microservices.dss.projects.mapper.*; import com.microservices.dss.projects.service.IProjectGlobalResourcesService; import com.microservices.dss.utils.DateUtil; +import com.microservices.dss.utils.DssGitLinkRequestUrl; import org.springframework.beans.factory.annotation.Autowired; import com.microservices.common.redis.service.RedisService; import org.springframework.stereotype.Service; @@ -43,6 +46,9 @@ public class ProjectGlobalResourcesServiceImpl implements IProjectGlobalResource @Resource private JournalsMapper journalsMapper; + @Autowired + private GitLinkRequestHelper gitLinkRequestHelper; + @Override public GlobalResourcesDataVo getProjectGlobalResourcesData() throws ParseException, JsonProcessingException { String currentYearMonth = currentYearMonth(); @@ -73,6 +79,31 @@ public class ProjectGlobalResourcesServiceImpl implements IProjectGlobalResource return globalResourcesDataVo; } + @Override + public JSONObject getLatestActivitiesData(int page, int limit) { + JSONObject result = gitLinkRequestHelper.doGet(DssGitLinkRequestUrl.GET_LATEST_ACTIVITIES(page, limit)); + JSONObject latestActivities = new JSONObject(); + latestActivities.put("total_count", result.get("total_count")); + latestActivities.put("project_trends", result.getJSONArray("project_trends")); + return latestActivities; + } + + @Override + public JSONObject getProjectRankData(int time, int limit) { + JSONObject result = gitLinkRequestHelper.doGet(DssGitLinkRequestUrl.GET_PROJECT_RANK(time, limit)); + JSONObject projectRank = new JSONObject(); + projectRank.put("projects", result.getJSONArray("projects")); + return projectRank; + } + + @Override + public JSONObject getUserRankData(int time, int limit) { + JSONObject result = gitLinkRequestHelper.doGet(DssGitLinkRequestUrl.GET_USER_RANK(time, limit)); + JSONObject userRank = new JSONObject(); + userRank.put("users", result.getJSONArray("users")); + return userRank; + } + private int getTotalProjects() { return projectsMapper.selectProjectCount(); } diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java new file mode 100644 index 000000000..06deb1c37 --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java @@ -0,0 +1,45 @@ +package com.microservices.dss.utils; + +import com.alibaba.fastjson2.JSONObject; +import com.microservices.common.core.utils.DateUtils; +import com.microservices.common.core.utils.StringUtils; +import com.microservices.common.httpClient.domain.GitLinkRequestUrl; + +import java.net.URISyntaxException; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * @author otto + */ +public class DssGitLinkRequestUrl extends GitLinkRequestUrl { + /** + * 获取项目最新动态 + */ + public static GitLinkRequestUrl GET_LATEST_ACTIVITIES(int page, int limit) { + return getGitLinkRequestUrl( + String.format("/api/activity/last.json?page=%d&limit=%d", page, limit) + ); + } + + /** + * 获取项目排行列表 + */ + public static GitLinkRequestUrl GET_PROJECT_RANK(int time, int limit) { + return getGitLinkRequestUrl( + String.format("/api/project_rank.json?time=%d&limit=%d", time, limit) + ); + } + + /** + * 获取用户排行列表 + */ + public static GitLinkRequestUrl GET_USER_RANK(int time, int limit) { + return getGitLinkRequestUrl( + String.format("/api/user_rank.json?time=%d&limit=%d", time, limit) + ); + } +} From 8a3777e0f2b9fa6c1a38ed64ea03980540d41fe1 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Mon, 16 Dec 2024 13:46:54 +0800 Subject: [PATCH 12/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E5=88=9B=E5=AE=A2=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E8=BF=94=E5=9B=9E=E6=97=B6=E9=97=B4=EF=BC=8C=E5=B7=B2?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E6=80=BB=E9=87=91=E9=A2=9D=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dss/makerspace/mapper/TasksMapper.java | 2 +- .../dss/makerspace/service/ITasksService.java | 2 +- .../service/impl/TasksServiceImpl.java | 2 +- .../main/resources/mapper/dss/TasksMapper.xml | 20 ++++++++++++++----- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java index 264f1577a..053fd3484 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/mapper/TasksMapper.java @@ -27,7 +27,7 @@ public interface TasksMapper{ List getNewAddedPapersByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); - List getTaskOperLogTopN(@Param("topNum") Integer topNum); + List> getTaskOperLogTopN(@Param("topNum") Integer topNum); List getOpeningTaskNumOfTaskStatus(@Param("topNum") Integer topNum); diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java index b147ec69f..fdf7ef693 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/ITasksService.java @@ -14,7 +14,7 @@ public interface ITasksService { int[] getPaperAdditionTrendData(); - List getTaskOperLogTopN(Integer topNum); + List> getTaskOperLogTopN(Integer topNum); List getOpeningTaskStatusDistribution(Integer topNum); diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java index d217e477d..56d3fd9fb 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/service/impl/TasksServiceImpl.java @@ -72,7 +72,7 @@ public class TasksServiceImpl implements ITasksService { } @Override - public List getTaskOperLogTopN(Integer topNum) { + public List> getTaskOperLogTopN(Integer topNum) { return tasksMapper.getTaskOperLogTopN(topNum); } diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml index fa7b9956e..9779beb28 100644 --- a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml @@ -115,10 +115,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND parent_id = 0 GROUP BY createTime - + SELECT + log_desc as log_desc, + CASE + WHEN TIMESTAMPDIFF(MINUTE, oper_time, NOW()) = 0 THEN CONCAT(TIMESTAMPDIFF(SECOND, oper_time, NOW()), '秒前') + WHEN TIMESTAMPDIFF(HOUR, oper_time, NOW()) = 0 THEN CONCAT(TIMESTAMPDIFF(MINUTE, oper_time, NOW()), '分钟前') + WHEN TIMESTAMPDIFF(DAY, oper_time, NOW()) = 0 THEN CONCAT(TIMESTAMPDIFF(HOUR, oper_time, NOW()), '小时前') + ELSE CONCAT(TIMESTAMPDIFF(DAY, oper_time, NOW()), '天前') + END AS time_ago + FROM + task_oper_log + ORDER BY + id DESC + LIMIT #{topNum}; - SELECT SUM(bounty) as '已支付总金额' + SELECT SUM(bounty) as 'total_paid_bounty' FROM tasks WHERE is_delete = 0 AND `status` = 8; From 2fb09332c68af9339a822ad115336f059774bcf8 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Mon, 16 Dec 2024 13:48:56 +0800 Subject: [PATCH 13/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E6=9D=83=E9=99=90=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=EF=BC=8C=E5=8F=AF=E8=A7=86=E5=8C=96=E4=BB=85gitlink?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E5=8F=AF=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GitlinkAdminAccessInterceptor.java | 46 +++++++++++++++++++ .../GitlinkAdminAccessRequired.java | 10 ++++ .../microservices/dss/config/WebConfig.java | 21 +++++++++ .../controller/MakerSpaceDataController.java | 19 ++++---- .../controller/ProjectDataController.java | 11 +++-- .../dss/projects/mapper/UserMapper.java | 4 ++ .../main/resources/mapper/dss/UserMapper.xml | 10 ++++ 7 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/Interceptor/GitlinkAdminAccessInterceptor.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/annotation/GitlinkAdminAccessRequired.java create mode 100644 microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/config/WebConfig.java diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/Interceptor/GitlinkAdminAccessInterceptor.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/Interceptor/GitlinkAdminAccessInterceptor.java new file mode 100644 index 000000000..6bfeb21ff --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/Interceptor/GitlinkAdminAccessInterceptor.java @@ -0,0 +1,46 @@ +package com.microservices.dss.Interceptor; + +import com.microservices.common.core.utils.SpringUtils; +import com.microservices.dss.annotation.GitlinkAdminAccessRequired; +import com.microservices.dss.projects.mapper.UserMapper; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +import static com.microservices.common.security.auth.AuthUtil.getGitLinkRequestToken; + +@Component +public class GitlinkAdminAccessInterceptor implements HandlerInterceptor { + + public UserMapper userMapper = SpringUtils.getBean(UserMapper.class); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + if (method.isAnnotationPresent(GitlinkAdminAccessRequired.class)) { + String token = getGitLinkRequestToken(request); + Long userId = userMapper.getUserIdByToken(token); // 根据token获取用户ID + if (userId == null) { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403 Forbidden + return false; + } + Boolean isAdmin = userMapper.getAdminStatus(userId); // 根据用户ID获取admin字段值 + if (isAdmin == null || !isAdmin) { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403 Forbidden + return false; + } + } + } + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + // 可以在这里添加一些完成后的处理逻辑 + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/annotation/GitlinkAdminAccessRequired.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/annotation/GitlinkAdminAccessRequired.java new file mode 100644 index 000000000..c40631aeb --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/annotation/GitlinkAdminAccessRequired.java @@ -0,0 +1,10 @@ +package com.microservices.dss.annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface GitlinkAdminAccessRequired { +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/config/WebConfig.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/config/WebConfig.java new file mode 100644 index 000000000..9ea44d69b --- /dev/null +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/config/WebConfig.java @@ -0,0 +1,21 @@ +package com.microservices.dss.config; + +import com.microservices.dss.Interceptor.GitlinkAdminAccessInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(gitlinkAdminAccessInterceptor()) + .addPathPatterns("/**"); + } + + public GitlinkAdminAccessInterceptor gitlinkAdminAccessInterceptor() { + return new GitlinkAdminAccessInterceptor(); + } +} diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java index 3b0e23765..87f17e0e4 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/controller/MakerSpaceDataController.java @@ -2,6 +2,7 @@ package com.microservices.dss.makerspace.controller; import com.microservices.common.core.web.controller.BaseController; import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.dss.annotation.GitlinkAdminAccessRequired; import com.microservices.dss.makerspace.service.ITasksService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -13,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/makerSpace") +@RequestMapping("/open/makerSpace") @Api(tags = "数据统计-创客空间相关接口") public class MakerSpaceDataController extends BaseController { @@ -22,61 +23,63 @@ public class MakerSpaceDataController extends BaseController { @ApiOperation("创客空间全局资源获取") @GetMapping(value = "/total") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getTotalData() { return success(tasksService.getTotalStatisticalData()); } @ApiOperation("创客任务新增趋势") @GetMapping(value = "/task/trend") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getTaskTrendData() { return success(tasksService.getTaskAdditionTrendData()); } @ApiOperation("创客成果新增趋势") @GetMapping(value = "/paper/trend") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getPaperTrendData() { return success(tasksService.getPaperAdditionTrendData()); } @ApiOperation("创客任务最新操作日志") @GetMapping(value = "/task/operLog") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getPaperTrendData(@ApiParam("获取最新操作日志的数量") @RequestParam Integer topNum) { return success(tasksService.getTaskOperLogTopN(topNum)); } @ApiOperation("创客任务奖金分布") @GetMapping(value = "/task/bountyDistribution") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getBountyDistribution() { return success(tasksService.getBountyDistribution()); } @ApiOperation("创客任务热度排行") @GetMapping(value = "/task/heatRank") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getHeatTopN(@ApiParam("获取热度排行的数量") @RequestParam Integer topNum) { return success(tasksService.getTaskHeatTopN(topNum)); } @ApiOperation("创客类型分布统计(统筹/自主)") @GetMapping(value = "/task/mode") -// @RequiresPermissions(value = {"dss:dssMakerSpace:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getTaskModeStatisticalData() { return success(tasksService.getTaskModeStatisticalData()); } @ApiOperation("创客任务-开启中状态任务数分布") @GetMapping(value = "/task/statusDistribution/opening") + @GitlinkAdminAccessRequired public AjaxResult getOpeningTaskStatusDistribution(@ApiParam("获取开启中状态任务分布的数量") @RequestParam Integer topNum) { return success(tasksService.getOpeningTaskStatusDistribution(topNum)); } @ApiOperation("创客任务-所有任务类型分布") @GetMapping(value = "/task/categoryDistribution") + @GitlinkAdminAccessRequired public AjaxResult getAllTaskCategoryDistribution() { return success(tasksService.getAllTaskCategoryDistribution()); } diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java index bc5bbfad9..e04810d40 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java @@ -3,6 +3,7 @@ package com.microservices.dss.projects.controller; import com.fasterxml.jackson.core.JsonProcessingException; import com.microservices.common.core.web.controller.BaseController; import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.dss.annotation.GitlinkAdminAccessRequired; import com.microservices.dss.projects.service.IProjectGlobalResourcesService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -16,7 +17,7 @@ import org.springframework.web.bind.annotation.RestController; import java.text.ParseException; @RestController -@RequestMapping("/projects") +@RequestMapping("/open/projects") @Api(tags = "数据统计-开源项目相关接口") public class ProjectDataController extends BaseController { @@ -25,14 +26,14 @@ public class ProjectDataController extends BaseController { @ApiOperation("开源项目全局资源获取") @GetMapping(value = "/global-resources") -// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getGlobalResourcesData() throws ParseException, JsonProcessingException { return success(projectGlobalResourcesService.getProjectGlobalResourcesData()); } @ApiOperation("开源项目最新动态获取") @GetMapping(value = "/latestActivities") -// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getLatestActivitiesData(@ApiParam("分页数") @RequestParam(value = "page", defaultValue = "1") int page, @ApiParam("分页大小") @RequestParam(value = "limit", defaultValue = "4") int limit){ return success(projectGlobalResourcesService.getLatestActivitiesData(page, limit)); @@ -40,7 +41,7 @@ public class ProjectDataController extends BaseController { @ApiOperation("开源项目-项目排行获取") @GetMapping(value = "/projectRank") -// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getProjectRankData(@ApiParam("统计时间范围(天)") @RequestParam(value = "time", defaultValue = "365") int time, @ApiParam("top数") @RequestParam(value = "limit", defaultValue = "5") int limit){ return success(projectGlobalResourcesService.getProjectRankData(time, limit)); @@ -48,7 +49,7 @@ public class ProjectDataController extends BaseController { @ApiOperation("开源项目-用户排行获取") @GetMapping(value = "/userRank") -// @RequiresPermissions(value = {"dss:dssProjects:show"}, logical = Logical.OR) + @GitlinkAdminAccessRequired public AjaxResult getUserRankData(@ApiParam("统计时间范围(天)") @RequestParam(value = "time", defaultValue = "365") int time, @ApiParam("top数") @RequestParam(value = "limit", defaultValue = "5") int limit){ return success(projectGlobalResourcesService.getUserRankData(time, limit)); diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java index 356a14a57..6362fd3c6 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/mapper/UserMapper.java @@ -13,4 +13,8 @@ public interface UserMapper { List getNewAddedMembersByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); List getActiveMembersByMonth(@Param("startTime") String startTime, @Param("endTime") String endTime); + + Long getUserIdByToken(@Param("token") String token); + + Boolean getAdminStatus(@Param("userId") Long userId); } diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml index 7f4b033d7..64456a076 100644 --- a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/UserMapper.xml @@ -82,4 +82,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" SELECT DISTINCT user_id, DATE_FORMAT(updated_at, '%Y-%m-%d' ) as updated_on FROM commit_logs WHERE updated_at >= #{startTime,jdbcType=VARCHAR} AND updated_at <= #{endTime,jdbcType=VARCHAR} ) as t GROUP BY createTime + + \ No newline at end of file From 2165e73c88c0265230cc50a4d59f7336ad6689ff Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Mon, 16 Dec 2024 14:15:54 +0800 Subject: [PATCH 14/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E8=BA=AB=E4=BB=BD=E8=B0=83=E7=94=A8gitlink=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/microservices/dss/utils/DssGitLinkRequestUrl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java index 06deb1c37..ce6485b14 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/utils/DssGitLinkRequestUrl.java @@ -20,7 +20,7 @@ public class DssGitLinkRequestUrl extends GitLinkRequestUrl { * 获取项目最新动态 */ public static GitLinkRequestUrl GET_LATEST_ACTIVITIES(int page, int limit) { - return getGitLinkRequestUrl( + return getAdminGitLinkRequestUrl( String.format("/api/activity/last.json?page=%d&limit=%d", page, limit) ); } @@ -29,7 +29,7 @@ public class DssGitLinkRequestUrl extends GitLinkRequestUrl { * 获取项目排行列表 */ public static GitLinkRequestUrl GET_PROJECT_RANK(int time, int limit) { - return getGitLinkRequestUrl( + return getAdminGitLinkRequestUrl( String.format("/api/project_rank.json?time=%d&limit=%d", time, limit) ); } @@ -38,7 +38,7 @@ public class DssGitLinkRequestUrl extends GitLinkRequestUrl { * 获取用户排行列表 */ public static GitLinkRequestUrl GET_USER_RANK(int time, int limit) { - return getGitLinkRequestUrl( + return getAdminGitLinkRequestUrl( String.format("/api/user_rank.json?time=%d&limit=%d", time, limit) ); } From 54923e2b9667aee90146591523c2a304f9574bbd Mon Sep 17 00:00:00 2001 From: xxq250 Date: Wed, 18 Dec 2024 10:39:24 +0800 Subject: [PATCH 15/49] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E6=89=A7=E8=A1=8C=E6=B5=8B=E8=AF=95=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PmsCiPipelinesController.java | 12 ++++++++++++ .../service/IPmsCiPipelinesService.java | 2 ++ .../service/impl/PmsCiPipelinesServiceImpl.java | 17 +++++++++++++++++ .../pms/utils/PmsGitLinkRequestUrl.java | 4 ++++ 4 files changed, 35 insertions(+) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java index 284b8c247..b4d8778b8 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java @@ -259,4 +259,16 @@ public class PmsCiPipelinesController extends BaseController pmsCiPipelinesService.getPipelineRunJobLogs(id, run, job, response); } + /** + * 流水线执行测试报告结果查询 + */ + @PostMapping(value = "/{id}/actions/runs/{run}/results") + @ApiOperation("流水线执行测试报告结果查询") + public AjaxResult getPipelineRunResults(@ApiParam(name = "id", value = "流水线id")@PathVariable Long id, + @ApiParam(name = "run", value = "执行记录序号")@PathVariable String run) + { + return success(pmsCiPipelinesService.getPipelineRunResults(id, run)); + } + + } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java index 210ca4f0e..5552d1727 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java @@ -100,4 +100,6 @@ public interface IPmsCiPipelinesService void getPipelineRunJobLogs(Long id, String run, String job, HttpServletResponse response); JSONObject runPipelineRunsJob(Long id, String workflow, String ref); + + JSONObject getPipelineRunResults(Long id, String run); } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java index d48bfbf49..5c1cd2488 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/impl/PmsCiPipelinesServiceImpl.java @@ -448,6 +448,23 @@ public class PmsCiPipelinesServiceImpl implements IPmsCiPipelinesService { } } + + @Override + public JSONObject getPipelineRunResults(Long id, String run) { + PmsCiPipelines pmsCiPipelines = pmsCiPipelinesMapper.selectPmsCiPipelinesById(id); + if (pmsCiPipelines == null) { + throw new ServiceException("该项目流水线不存在(流水线ID[%s])", id); + } + try { + return gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_PIPELINE_RUN_RESULTS(pmsCiPipelines.getOwner(), + pmsCiPipelines.getRepoIdentifier(), + run)); + } catch (Exception e) { + logger.error(e.getMessage()); + throw new ServiceException("获取流水线运行结果信息失败"); + } + } + private void saveOrUpdateGraphicJsonToLocal(Long id, PmsCiPipelineBuildYamlInputVo pmsCiPipelineBuildInputVo) { PmsCiPipelineGraphics existentialPmsCiPipelineGraphics = pmsCiPipelineGraphicsService.selectPmsCiPipelineGraphicsByPmsCiPipelineId(id); PmsCiPipelineGraphics pmsCiPipelineGraphics = new PmsCiPipelineGraphics(); diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java index 56c37d119..c405e748e 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java @@ -362,4 +362,8 @@ public class PmsGitLinkRequestUrl extends GitLinkRequestUrl { public static GitLinkRequestUrl SAVE_PIPELINE_YAML(String owner, String repoIdentifier) { return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/pipelines/save_yaml", owner, repoIdentifier)); } + + public static GitLinkRequestUrl GET_PIPELINE_RUN_RESULTS(String owner, String repoIdentifier, String run){ + return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/pipelines/run_results.json?run_id=%s", owner, repoIdentifier, run)); + } } From ac7e9208cbfc74dbb2a192c972a776a94545697a Mon Sep 17 00:00:00 2001 From: xxq250 Date: Wed, 18 Dec 2024 10:49:50 +0800 Subject: [PATCH 16/49] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E6=89=A7=E8=A1=8C=E6=B5=8B=E8=AF=95=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E6=9F=A5=E8=AF=A2Get?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pms/pipeline/controller/PmsCiPipelinesController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java index b4d8778b8..a092c8b4a 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/controller/PmsCiPipelinesController.java @@ -262,7 +262,7 @@ public class PmsCiPipelinesController extends BaseController /** * 流水线执行测试报告结果查询 */ - @PostMapping(value = "/{id}/actions/runs/{run}/results") + @GetMapping(value = "/{id}/actions/runs/{run}/results") @ApiOperation("流水线执行测试报告结果查询") public AjaxResult getPipelineRunResults(@ApiParam(name = "id", value = "流水线id")@PathVariable Long id, @ApiParam(name = "run", value = "执行记录序号")@PathVariable String run) From b1a6100d4f57e0b63304fef964d85d3eebbee6c6 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Thu, 2 Jan 2025 16:48:49 +0800 Subject: [PATCH 17/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E5=BC=80=E6=BA=90=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=9C=80=E6=96=B0=E5=8A=A8=E6=80=81=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=9D=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dss/projects/controller/ProjectDataController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java index e04810d40..08e9f4dab 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/controller/ProjectDataController.java @@ -35,7 +35,7 @@ public class ProjectDataController extends BaseController { @GetMapping(value = "/latestActivities") @GitlinkAdminAccessRequired public AjaxResult getLatestActivitiesData(@ApiParam("分页数") @RequestParam(value = "page", defaultValue = "1") int page, - @ApiParam("分页大小") @RequestParam(value = "limit", defaultValue = "4") int limit){ + @ApiParam("分页大小") @RequestParam(value = "limit", defaultValue = "6") int limit){ return success(projectGlobalResourcesService.getLatestActivitiesData(page, limit)); } From 16137b91f025616c4cc7a27acc9d1ac72a882fd1 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Thu, 2 Jan 2025 16:49:09 +0800 Subject: [PATCH 18/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E5=88=9B=E5=AE=A2=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/mapper/dss/TasksMapper.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml index 9779beb28..d38f710d3 100644 --- a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml @@ -123,7 +123,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" WHEN TIMESTAMPDIFF(HOUR, oper_time, NOW()) = 0 THEN CONCAT(TIMESTAMPDIFF(MINUTE, oper_time, NOW()), '分钟前') WHEN TIMESTAMPDIFF(DAY, oper_time, NOW()) = 0 THEN CONCAT(TIMESTAMPDIFF(HOUR, oper_time, NOW()), '小时前') ELSE CONCAT(TIMESTAMPDIFF(DAY, oper_time, NOW()), '天前') - END AS time_ago + END AS time_ago, + task_id FROM task_oper_log ORDER BY From 456b0acd484ea355c29bc308e8af699962c45678 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Fri, 3 Jan 2025 14:44:51 +0800 Subject: [PATCH 19/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E5=88=9B=E5=AE=A2=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=BB=BB=E5=8A=A1=E6=8E=92=E8=A1=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dss/makerspace/domain/vo/TaskHeatInfoVo.java | 2 ++ .../src/main/resources/mapper/dss/TasksMapper.xml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java index d1e3ac447..d61b3b1c7 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/makerspace/domain/vo/TaskHeatInfoVo.java @@ -14,4 +14,6 @@ public class TaskHeatInfoVo { private Integer participantCount; private String winnerNames; + + private Integer taskId; } diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml index d38f710d3..343708236 100644 --- a/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml +++ b/microservices-modules/microservices-modules-dss/src/main/resources/mapper/dss/TasksMapper.xml @@ -185,12 +185,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" From c8827c7c565b2603396b272169c568e509220b09 Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Wed, 15 Jan 2025 11:27:41 +0800 Subject: [PATCH 20/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E6=97=A5=E5=BF=97=E5=AD=98?= =?UTF-8?q?=E6=94=BE=E4=BD=8D=E7=BD=AE=E6=A0=A1=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../microservices-modules-dss/src/main/resources/logback.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml b/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml index 8d66f2a37..2e33c078f 100644 --- a/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml +++ b/microservices-modules/microservices-modules-dss/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - + From 41e38174548297e827a2ecfebded98b35c4421df Mon Sep 17 00:00:00 2001 From: wanjia <553039491@qq.com> Date: Wed, 15 Jan 2025 15:24:29 +0800 Subject: [PATCH 21/49] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E6=B5=8B):=E5=BC=80=E6=BA=90=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=85=A8=E5=B1=80=E7=BB=9F=E8=AE=A1=E7=BC=93=E5=AD=98?= =?UTF-8?q?key=E6=95=B0=E6=8D=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ProjectGlobalResourcesServiceImpl.java | 2 +- .../microservices/dss/task/ProjectsGlobalResourcesTask.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java index 67d4fff63..9d5857493 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/projects/service/impl/ProjectGlobalResourcesServiceImpl.java @@ -51,7 +51,7 @@ public class ProjectGlobalResourcesServiceImpl implements IProjectGlobalResource @Override public GlobalResourcesDataVo getProjectGlobalResourcesData() throws ParseException, JsonProcessingException { - String currentYearMonth = currentYearMonth(); + String currentYearMonth = getFormattedCurrentDate(); String previousYearMonth = DateUtil.DateAddByYear(currentYearMonth, -1); GlobalResourcesDataVo globalResourcesDataVo = new GlobalResourcesDataVo(); String cacheKey = CacheConstants.getGlobalResourcesDataKey(previousYearMonth, currentYearMonth); diff --git a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java index 5c2d44351..0e3463aa9 100644 --- a/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java +++ b/microservices-modules/microservices-modules-dss/src/main/java/com/microservices/dss/task/ProjectsGlobalResourcesTask.java @@ -13,10 +13,10 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.concurrent.TimeUnit; +import static com.microservices.dss.utils.DateUtil.getFormattedCurrentDate; + @Component public class ProjectsGlobalResourcesTask { @@ -31,7 +31,7 @@ public class ProjectsGlobalResourcesTask { @Scheduled(cron = "0 0 2 * * ?") public void updateProjectsGlobalResources() throws ParseException, JsonProcessingException { log.info("开始更新近一年全局资源数据"); - String currentDate = new SimpleDateFormat("yyyy-MM").format(Calendar.getInstance().getTime()); + String currentDate = getFormattedCurrentDate(); String startTime = DateUtil.DateAddByYear(currentDate, -1); GlobalResourcesDataVo globalResourcesDataVo = projectGlobalResourcesService.getProjectGlobalResourcesData(); String cacheKey = CacheConstants.getGlobalResourcesDataKey(startTime, currentDate); From ca9d80e111d97f2a4ad3773cd2a1a683eadd2fd8 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Mon, 17 Feb 2025 15:07:18 +0800 Subject: [PATCH 22/49] =?UTF-8?q?fix(=E6=96=87=E4=BB=B6=E6=9C=8D=E5=8A=A1)?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E9=80=9A=E8=BF=87=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E4=B8=8B=E8=BD=BD=E6=8E=A5=E5=8F=A3=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/file/service/impl/SysFileInfoServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java b/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java index 8913d17c4..de51925f3 100644 --- a/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java +++ b/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java @@ -263,7 +263,7 @@ public class SysFileInfoServiceImpl implements ISysFileInfoService { @Override public void fileDownloadByIdentifier(String fileIdentifier, HttpServletResponse response, HttpServletRequest request) { SysFileInfo sysFileInfo = selectSysFileInfoByFileIdentifier(fileIdentifier); - if (StringUtils.isEmpty(sysFileInfo.getFilePath()) || !sysFileInfo.getFilePath().contains("/zone-identifier")) { + if (StringUtils.isEmpty(sysFileInfo.getFilePath())) { throw new ServiceException("当前文件无法下载"); } fileDownload(sysFileInfo, response); From ee558dd5bee34dc397272d6f35dddb2290ca78e0 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Mon, 17 Feb 2025 15:11:00 +0800 Subject: [PATCH 23/49] =?UTF-8?q?fix(=E6=96=87=E4=BB=B6=E6=9C=8D=E5=8A=A1)?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E9=80=9A=E8=BF=87=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E4=B8=8B=E8=BD=BD=E6=8E=A5=E5=8F=A3=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/file/service/impl/SysFileInfoServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java b/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java index 8913d17c4..de51925f3 100644 --- a/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java +++ b/microservices-modules/microservices-modules-file/src/main/java/com/microservices/file/service/impl/SysFileInfoServiceImpl.java @@ -263,7 +263,7 @@ public class SysFileInfoServiceImpl implements ISysFileInfoService { @Override public void fileDownloadByIdentifier(String fileIdentifier, HttpServletResponse response, HttpServletRequest request) { SysFileInfo sysFileInfo = selectSysFileInfoByFileIdentifier(fileIdentifier); - if (StringUtils.isEmpty(sysFileInfo.getFilePath()) || !sysFileInfo.getFilePath().contains("/zone-identifier")) { + if (StringUtils.isEmpty(sysFileInfo.getFilePath())) { throw new ServiceException("当前文件无法下载"); } fileDownload(sysFileInfo, response); From 9178cda28908a0c0ba5a9e8bef9e719f020ada07 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 21 Feb 2025 15:00:25 +0800 Subject: [PATCH 24/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E4=BC=98=E5=8C=96=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E6=96=B9=E5=B7=A5=E5=85=B7=E8=AF=B7=E6=B1=82=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E7=99=BB=E5=BD=95=E5=A4=B1=E8=B4=A5=E7=9A=84=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/filter/AuthFilter.java | 5 ++++- .../service/ThirdPartyToolService.java | 9 +++++--- .../impl/ThirdPartyToolServiceImpl.java | 22 ++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index b1502a6a1..8af4b7fa6 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -115,7 +115,10 @@ public class AuthFilter implements GlobalFilter, Ordered { // 内部请求来源参数清除 ServletUtils.removeHeader(mutate, SecurityConstants.FROM_SOURCE); - thirdPartyToolService.handleRequestForThirdPartyTools(request, mutate); + Mono thirdPartyRes = thirdPartyToolService.handleRequestForThirdPartyTools(exchange, request, mutate); + if (thirdPartyRes != null) { + return thirdPartyRes; + } return chain.filter(exchange.mutate().request(mutate.build()).build()); } diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java index efc7d4b58..601798b5e 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/ThirdPartyToolService.java @@ -1,6 +1,8 @@ package com.microservices.gateway.service; import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; /** * 第三方工具服务类 @@ -12,8 +14,9 @@ public interface ThirdPartyToolService { /** * 处理第三方工具请求 * - * @param request 请求 - * @param mutate 请求头获取器 + * @param exchange + * @param request 请求 + * @param mutate 请求头获取器 */ - void handleRequestForThirdPartyTools(ServerHttpRequest request, ServerHttpRequest.Builder mutate); + Mono handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate); } diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index f6b2bca05..b763db43c 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -1,5 +1,6 @@ package com.microservices.gateway.service.impl; +import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.microservices.common.core.constant.CacheConstants; import com.microservices.common.core.constant.TokenConstants; @@ -20,6 +21,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Service; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; import java.io.IOException; import java.io.StringWriter; @@ -56,10 +59,10 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { * 处理第三方工具请求 */ @Override - public void handleRequestForThirdPartyTools(ServerHttpRequest request, ServerHttpRequest.Builder mutate) { + public Mono handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate) { String url = request.getURI().getPath(); if (StringUtils.isEmpty(url)) { - return; + return null; } // 处理Sentinel请求 if (url.toLowerCase().startsWith("/sentinel")) { @@ -110,6 +113,9 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { StringWriter writer = new StringWriter(); IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); String str = writer.toString(); + if (!JSON.isValid(str)) { + return exceptionResponse(exchange, str, res.status()); + } JSONObject resJsonObject = JSONObject.parseObject(str); nacosToken = resJsonObject.getString("accessToken"); Long tokenTtl = resJsonObject.getLong("tokenTtl"); @@ -129,7 +135,7 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { } } - // 处理Nacos请求 + // 处理portainer请求 if (url.toLowerCase().startsWith("/portainer")) { String portainerToken = null; if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) { @@ -145,6 +151,9 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { StringWriter writer = new StringWriter(); IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name()); String str = writer.toString(); + if (!JSON.isValid(str)) { + return exceptionResponse(exchange, str, res.status()); + } JSONObject resJsonObject = JSONObject.parseObject(str); portainerToken = resJsonObject.getString("jwt"); String[] tokenSplit = portainerToken.split("\\."); @@ -169,5 +178,12 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { throw new ServiceException("Portainer服务获取Token失败"); } } + return null; + } + + + private Mono exceptionResponse(ServerWebExchange exchange, String msg, int code) { + log.error("[第三方工具请求处理异常]请求路径:{}", exchange.getRequest().getPath()); + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, code); } } From 61db706e02f01bcac093214ee23320c6e93c04c5 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Mon, 24 Feb 2025 17:02:53 +0800 Subject: [PATCH 25/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E5=BD=93=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E4=B8=BANacos=E6=97=B6=EF=BC=8CNacos=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84=E6=89=80=E6=9C=89=E9=9D=9EJSON=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E9=83=BD=E4=BC=9A=E8=A2=AB=E8=87=AA=E5=8A=A8=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=B8=BA=E7=BB=93=E6=9E=84=E5=8C=96=E7=9A=84=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=EF=BC=8C=E5=90=8C=E6=97=B6=E5=B0=86HTTP?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=A0=81=E8=AE=BE=E7=BD=AE=E4=B8=BA200?= =?UTF-8?q?=EF=BC=8C=E9=80=82=E5=90=88=E7=94=A8=E4=BA=8E=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E5=8C=96=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=9E=B6=E6=9E=84=E7=9A=84?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E6=A0=BC=E5=BC=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/filter/GlobalResponseFilter.java | 90 +++++++++++++++++++ .../handler/GatewayExceptionHandler.java | 23 ++--- 2 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java new file mode 100644 index 000000000..30730555f --- /dev/null +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -0,0 +1,90 @@ +package com.microservices.gateway.filter; + +import com.alibaba.fastjson2.JSON; +import com.microservices.common.core.web.domain.AjaxResult; +import lombok.extern.slf4j.Slf4j; +import org.reactivestreams.Publisher; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.http.server.reactive.ServerHttpResponseDecorator; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.nio.charset.StandardCharsets; + +@Slf4j +@Component +public class GlobalResponseFilter implements GlobalFilter, Ordered { + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + + String url = request.getURI().getPath(); + // 当请求为Nacos时,Nacos返回的所有非JSON响应都会被自动转换为结构化的错误信息,同时将HTTP状态码设置为200,适合用于规范化微服务架构的响应格式。 + if (url.toLowerCase().startsWith("/nacos")) { + ServerHttpResponse originalResponse = exchange.getResponse(); + DataBufferFactory bufferFactory = originalResponse.bufferFactory(); + + ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { + @Override + public Mono writeWith(Publisher body) { + MediaType contentType = getHeaders().getContentType(); + HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR; + + // 排除无内容响应和二进制类型 + if (status == HttpStatus.NO_CONTENT || + (contentType != null && (contentType.includes(MediaType.APPLICATION_OCTET_STREAM) || + contentType.includes(MediaType.MULTIPART_FORM_DATA)))) { + return super.writeWith(body); + } + + // 保留原始状态码 + originalResponse.setStatusCode(HttpStatus.OK); + getHeaders().setContentType(MediaType.APPLICATION_JSON); + + return Flux.from(body).handle((dataBuffer, synchronousSink) -> { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + //释放掉内存 + DataBufferUtils.release(dataBuffer); + String result = new String(bytes, StandardCharsets.UTF_8); + if (!JSON.isValid(result)) { + synchronousSink.next(result); + } else { + synchronousSink.complete(); + } + + }).flatMap(resBody -> { + byte[] bytes = JSON.toJSONBytes(AjaxResult.error(resBody)); + + getHeaders().setContentLength(bytes.length); + DataBuffer buffer = bufferFactory.wrap(bytes); + return super.writeWith(Mono.just(buffer)); + }).then(); + } + }; + + return chain.filter(exchange.mutate().response(decoratedResponse).build()); + } + return chain.filter(exchange); + + } + + @Override + public int getOrder() { + //WRITE_RESPONSE_FILTER 之前执行 + return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1; + } +} \ No newline at end of file diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/handler/GatewayExceptionHandler.java b/microservices-gateway/src/main/java/com/microservices/gateway/handler/GatewayExceptionHandler.java index ad2c1e300..10a161e2e 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/handler/GatewayExceptionHandler.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/handler/GatewayExceptionHandler.java @@ -1,5 +1,6 @@ package com.microservices.gateway.handler; +import com.microservices.common.core.exception.ServiceException; import com.microservices.common.core.utils.ServletUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,33 +20,27 @@ import reactor.core.publisher.Mono; */ @Order(-1) @Configuration -public class GatewayExceptionHandler implements ErrorWebExceptionHandler -{ +public class GatewayExceptionHandler implements ErrorWebExceptionHandler { private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class); @Override - public Mono handle(ServerWebExchange exchange, Throwable ex) - { + public Mono handle(ServerWebExchange exchange, Throwable ex) { ServerHttpResponse response = exchange.getResponse(); - if (exchange.getResponse().isCommitted()) - { + if (exchange.getResponse().isCommitted()) { return Mono.error(ex); } String msg; - if (ex instanceof NotFoundException) - { + if (ex instanceof NotFoundException) { msg = "服务未找到"; - } - else if (ex instanceof ResponseStatusException) - { + } else if (ex instanceof ServiceException) { + msg = ex.getMessage(); + } else if (ex instanceof ResponseStatusException) { ResponseStatusException responseStatusException = (ResponseStatusException) ex; msg = responseStatusException.getMessage(); - } - else - { + } else { msg = "内部服务器错误"; } From 1140566a512512029a01481066a191db699d8c38 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Tue, 25 Feb 2025 10:40:22 +0800 Subject: [PATCH 26/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E5=A4=84=E7=90=86Nacos?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=93=8D=E5=BA=94=E6=A0=BC=E5=BC=8F=E9=9D=9E?= =?UTF-8?q?=E6=A0=87=E5=87=86=E5=8C=96=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 限制仅当异常响应时才对错误信息进行标准化处理 Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/filter/GlobalResponseFilter.java | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java index 30730555f..2c5eb10d9 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -12,7 +12,6 @@ import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; @@ -40,35 +39,29 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { @Override public Mono writeWith(Publisher body) { - MediaType contentType = getHeaders().getContentType(); HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR; - - // 排除无内容响应和二进制类型 - if (status == HttpStatus.NO_CONTENT || - (contentType != null && (contentType.includes(MediaType.APPLICATION_OCTET_STREAM) || - contentType.includes(MediaType.MULTIPART_FORM_DATA)))) { + if (!status.isError()) { return super.writeWith(body); } - // 保留原始状态码 - originalResponse.setStatusCode(HttpStatus.OK); - getHeaders().setContentType(MediaType.APPLICATION_JSON); - return Flux.from(body).handle((dataBuffer, synchronousSink) -> { - byte[] bytes = new byte[dataBuffer.readableByteCount()]; - dataBuffer.read(bytes); - //释放掉内存 - DataBufferUtils.release(dataBuffer); - String result = new String(bytes, StandardCharsets.UTF_8); - if (!JSON.isValid(result)) { - synchronousSink.next(result); - } else { - synchronousSink.complete(); + if (status.isError()) { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + //释放掉内存 + DataBufferUtils.release(dataBuffer); + String result = new String(bytes, StandardCharsets.UTF_8); + if (!JSON.isValid(result)) { + synchronousSink.next(result); + return; + } } + synchronousSink.complete(); }).flatMap(resBody -> { + // 保留原始状态码 + originalResponse.setStatusCode(HttpStatus.OK); byte[] bytes = JSON.toJSONBytes(AjaxResult.error(resBody)); - getHeaders().setContentLength(bytes.length); DataBuffer buffer = bufferFactory.wrap(bytes); return super.writeWith(Mono.just(buffer)); From 2e44e2b24e998ef245d9e4b7a1a9ff21b11d92ab Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Mon, 3 Mar 2025 10:38:37 +0800 Subject: [PATCH 27/49] =?UTF-8?q?fix(=E5=88=B6=E5=93=81=E5=BA=93=E4=BC=98?= =?UTF-8?q?=E5=8C=96):=20=E4=BF=AE=E5=A4=8D=E4=BA=A7=E5=93=81=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E6=A0=87=E7=AD=BE=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../domain/PmsProductLibraryRepositories.java | 2 +- .../productLibrary/domain/vo/PmsProductLibraryDataVo.java | 2 +- .../domain/vo/PmsProductLibrarySimpleVo.java | 2 +- .../domain/vo/ProductRepositoriesInputVo.java | 7 ++++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/PmsProductLibraryRepositories.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/PmsProductLibraryRepositories.java index 53d2298b1..23b69b203 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/PmsProductLibraryRepositories.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/PmsProductLibraryRepositories.java @@ -100,7 +100,7 @@ public class PmsProductLibraryRepositories extends BaseEntity { private String version; - @ApiModelProperty(value = "产品版本标记") + @ApiModelProperty(value = "产品版本标签") private String tag; public RepoAttributesVo getRepoAttributes() { diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibraryDataVo.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibraryDataVo.java index 89fc55237..43aebfe52 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibraryDataVo.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibraryDataVo.java @@ -58,6 +58,6 @@ public class PmsProductLibraryDataVo { private String version; - @ApiModelProperty(value = "产品版本标记") + @ApiModelProperty(value = "产品版本标签") private String tag; } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibrarySimpleVo.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibrarySimpleVo.java index b96f3f7f0..5ee0c0db0 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibrarySimpleVo.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/PmsProductLibrarySimpleVo.java @@ -29,6 +29,6 @@ public class PmsProductLibrarySimpleVo extends PmsProductLibraryRepositoriesSimp private String version; - @ApiModelProperty(value = "产品版本标记") + @ApiModelProperty(value = "产品版本标签") private String tag; } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/ProductRepositoriesInputVo.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/ProductRepositoriesInputVo.java index f04a3a084..92cc22ca0 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/ProductRepositoriesInputVo.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/productLibrary/domain/vo/ProductRepositoriesInputVo.java @@ -17,9 +17,10 @@ import javax.validation.constraints.Pattern; @Data @ApiModel("产品库输入对象") public class ProductRepositoriesInputVo extends ProductRepositoriesOperateVo { - @ApiModelProperty(value = "产品版本标记", required = true) - @NotBlank(message = "产品版本标记不能为空") - @Pattern(regexp = "^[A-Za-z0-9](?!_)(?!\\.)[A-Za-z0-9_\\-.]*$", message = "产品版本标记不符合规范") + // 必填,以字母、数字开头,由字母、数字、下划线(_)、短横线(-)、点(.)组成; + @ApiModelProperty(value = "产品版本标签", required = true) + @NotBlank(message = "产品版本标签不能为空") + @Pattern(regexp = "^[A-Za-z0-9][A-Za-z0-9_\\-.]*$", message = "产品版本标签不符合规范") private String tag; @ApiModelProperty(value = "产品库名称", required = true) From 3b8e443296b9f4aaab5f5336a038a2fc2ed46c7a Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:37:44 +0800 Subject: [PATCH 28/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E5=A4=84=E7=90=86Nacos?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=93=8D=E5=BA=94=E6=A0=BC=E5=BC=8F=E9=9D=9E?= =?UTF-8?q?=E6=A0=87=E5=87=86=E5=8C=96=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将异常信息设置为常量,统一响应消息 Signed-off-by: OTTO <731554297@qq.com> --- .../core/constant/ExceptionMsgConstants.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ExceptionMsgConstants.java diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ExceptionMsgConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ExceptionMsgConstants.java new file mode 100644 index 000000000..e54ea63d8 --- /dev/null +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/ExceptionMsgConstants.java @@ -0,0 +1,17 @@ +package com.microservices.common.core.constant; + +/** + * 异常信息常量 + * + * @author otto + */ +public class ExceptionMsgConstants { + /** + * 平台通用异常 + */ + public static final String SYSTEM_EXEC_ERROR = "请求处理异常,请联系管理员处理"; + /** + * 重试异常 + */ + public static final String RETRY_ERROR = "请求发生异常,请重新请求"; +} From b5d2376bebd6e7d27223fc9aee0a749f42649739 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:40:21 +0800 Subject: [PATCH 29/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E4=BC=98=E5=8C=96=E5=BE=AE?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=B2=BB=E7=90=86=E5=B7=A5=E5=85=B7=E8=BD=AC?= =?UTF-8?q?=E5=8F=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 优化代码结构 2. 当对象不存在时返回标准的错误信息 Signed-off-by: OTTO <731554297@qq.com> --- .../impl/ThirdPartyToolServiceImpl.java | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index b763db43c..7520d037d 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -3,6 +3,7 @@ package com.microservices.gateway.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.microservices.common.core.constant.CacheConstants; +import com.microservices.common.core.constant.ExceptionMsgConstants; import com.microservices.common.core.constant.TokenConstants; import com.microservices.common.core.exception.ServiceException; import com.microservices.common.core.utils.CookieUtil; @@ -48,6 +49,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { public String portainerUsername; @Value("${thirdPartyTools.portainer.auth.password:}") public String portainerPassword; + @Value("${thirdPartyTools.portainer.endpoints:}") + public Integer portainerEndpoints; ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; @Lazy @Autowired @@ -60,12 +63,12 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { */ @Override public Mono handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate) { - String url = request.getURI().getPath(); - if (StringUtils.isEmpty(url)) { + String lowerUrl = request.getURI().getPath().toLowerCase(); + if (StringUtils.isEmpty(lowerUrl)) { return null; } // 处理Sentinel请求 - if (url.toLowerCase().startsWith("/sentinel")) { + if (lowerUrl.startsWith("/sentinel")) { // 检查Cookie中是否携带sentinel cookie String cookie = request.getHeaders().getFirst(TokenConstants.Cookie); if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Sentinel_Token_Key))) { @@ -98,7 +101,7 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { } } // 处理Nacos请求 - if (url.toLowerCase().startsWith("/nacos")) { + if (lowerUrl.startsWith("/nacos")) { String nacosToken = null; if (redisService.hasKey(CacheConstants.NACOS_TOKEN)) { nacosToken = redisService.getCacheObject(CacheConstants.NACOS_TOKEN); @@ -117,6 +120,9 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { return exceptionResponse(exchange, str, res.status()); } JSONObject resJsonObject = JSONObject.parseObject(str); + if (resJsonObject == null) { + return exceptionResponse(exchange, str, res.status()); + } nacosToken = resJsonObject.getString("accessToken"); Long tokenTtl = resJsonObject.getLong("tokenTtl"); if (nacosToken != null && tokenTtl != null) { @@ -136,7 +142,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { } // 处理portainer请求 - if (url.toLowerCase().startsWith("/portainer")) { + if (lowerUrl.startsWith("/portainer")) { + String portainerToken = null; if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) { portainerToken = redisService.getCacheObject(CacheConstants.PORTAINER_TOKEN); @@ -156,6 +163,9 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { } JSONObject resJsonObject = JSONObject.parseObject(str); portainerToken = resJsonObject.getString("jwt"); + if (portainerToken == null) { + return exceptionResponse(exchange, str, res.status()); + } String[] tokenSplit = portainerToken.split("\\."); String tokenBodyStr = new String(Base64.getDecoder().decode(tokenSplit[1]), StandardCharsets.UTF_8); JSONObject tokenBody = JSONObject.parseObject(tokenBodyStr); @@ -183,7 +193,7 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { private Mono exceptionResponse(ServerWebExchange exchange, String msg, int code) { - log.error("[第三方工具请求处理异常]请求路径:{}", exchange.getRequest().getPath()); - return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, code); + log.error("[第三方工具请求处理异常]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), msg); + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), ExceptionMsgConstants.SYSTEM_EXEC_ERROR, code); } } From d8645f34e44d799e1d923799d1ec9aeb9c400f76 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:41:35 +0800 Subject: [PATCH 30/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E7=BD=91=E5=85=B3=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=97=B6=E8=AE=B0=E5=BD=95=E9=94=99=E8=AF=AF=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../main/java/com/microservices/gateway/filter/AuthFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index 8af4b7fa6..ba6f31a77 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -90,6 +90,7 @@ public class AuthFilter implements GlobalFilter, Ordered { try { claims = JwtUtils.parseToken(token); } catch (Exception e) { + log.error("令牌解析失败:{}", e.getMessage()); return unauthorizedResponse(exchange, "令牌格式不正确!"); } if (claims == null) { From 5b43d5c33b2ddca7b2bb9b8abd0bed47fe3512c7 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:43:39 +0800 Subject: [PATCH 31/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E7=99=BB=E5=BD=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=BC=82=E5=B8=B8=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nacosToken失效时清理Redis中nacosToken并返回标准的状态码 Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/filter/GlobalResponseFilter.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java index 2c5eb10d9..eb2b6fac6 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -25,16 +25,18 @@ import java.nio.charset.StandardCharsets; @Slf4j @Component public class GlobalResponseFilter implements GlobalFilter, Ordered { + @Autowired + private RedisService redisService; @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); - String url = request.getURI().getPath(); + String lowerUrl = request.getURI().getPath().toLowerCase(); + ServerHttpResponse originalResponse = exchange.getResponse(); + DataBufferFactory bufferFactory = originalResponse.bufferFactory(); // 当请求为Nacos时,Nacos返回的所有非JSON响应都会被自动转换为结构化的错误信息,同时将HTTP状态码设置为200,适合用于规范化微服务架构的响应格式。 - if (url.toLowerCase().startsWith("/nacos")) { - ServerHttpResponse originalResponse = exchange.getResponse(); - DataBufferFactory bufferFactory = originalResponse.bufferFactory(); + if (lowerUrl.startsWith("/nacos")) { ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { @Override @@ -43,6 +45,22 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { if (!status.isError()) { return super.writeWith(body); } + if (status == HttpStatus.FORBIDDEN) { + // 设置新的状态码为 200 + setStatusCode(HttpStatus.OK); + // 设置响应内容类型为 JSON + getHeaders().setContentType(MediaType.APPLICATION_JSON); + // 清理Sentinel失效token + redisService.deleteObject(CacheConstants.NACOS_TOKEN); + // 创建自定义的 JSON 响应内容 + String jsonBody = JSON.toJSONString(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR)); + byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8); + getHeaders().setContentLength(bytes.length); + DataBuffer dataBuffer = bufferFactory.wrap(bytes); + + // 返回新的响应内容 + return super.writeWith(Mono.just(dataBuffer)); + } return Flux.from(body).handle((dataBuffer, synchronousSink) -> { if (status.isError()) { From e4264c87a06d240a8fec1bd567c97f7022a8419e Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:47:26 +0800 Subject: [PATCH 32/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E7=99=BB=E5=BD=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=BC=82=E5=B8=B8=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. portainer发生异常返回错误码时进行拦截,返回标准化错误信息,同时记录异常日志 2. portainer Token失效时,清理Redis中portainer Token 3. 检测到sentinel返回403状态码时(大概率为Toke失效或过期),清理Redis中sentinel Token,返回标准化错误信息,同时记录异常日志 Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/filter/GlobalResponseFilter.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java index eb2b6fac6..1057a4f5c 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -1,9 +1,15 @@ package com.microservices.gateway.filter; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.microservices.common.core.constant.CacheConstants; +import com.microservices.common.core.constant.ExceptionMsgConstants; +import com.microservices.common.core.utils.StringUtils; import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.common.redis.service.RedisService; import lombok.extern.slf4j.Slf4j; import org.reactivestreams.Publisher; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter; @@ -12,6 +18,7 @@ import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; @@ -89,6 +96,106 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { return chain.filter(exchange.mutate().response(decoratedResponse).build()); } + if (lowerUrl.startsWith("/portainer")) { + ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { + @Override + public Mono writeWith(Publisher body) { + HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR; + if (!status.isError()) { + return super.writeWith(body); + } + + return Flux.from(body).handle((dataBuffer, synchronousSink) -> { + if (status.isError()) { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + //释放掉内存 + DataBufferUtils.release(dataBuffer); + String result = new String(bytes, StandardCharsets.UTF_8); + synchronousSink.next(result); + } + synchronousSink.complete(); + }).flatMap(resStr -> { + log.error("Portainer响应处理异常,异常信息:{}", resStr); + originalResponse.setStatusCode(HttpStatus.OK); + byte[] bytes; + if (JSON.isValid(resStr)) { + JSONObject resJson = JSONObject.parseObject(resStr); + if (resJson.containsKey("message")) { + String message = resJson.getString("message"); + if (StringUtils.isNotBlank(message) && message.contains("A valid authorisation token is missing")) { + //token失效清除redis缓存 + redisService.deleteObject(CacheConstants.PORTAINER_TOKEN); + bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR)); + } else { + bytes = JSON.toJSONBytes(AjaxResult.error(message)); + } + } else { + bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.SYSTEM_EXEC_ERROR)); + } + } else { + bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.SYSTEM_EXEC_ERROR)); + } + getHeaders().setContentLength(bytes.length); + DataBuffer buffer = bufferFactory.wrap(bytes); + return super.writeWith(Mono.just(buffer)); + }).then(); + } + }; + + return chain.filter(exchange.mutate().response(decoratedResponse).build()); + } + if (lowerUrl.startsWith("/sentinel")) { + + ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { + @Override + public Mono writeWith(Publisher body) { + HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR; + if (!status.isError()) { + return super.writeWith(body); + } + if (status == HttpStatus.UNAUTHORIZED) { + // 设置新的状态码为 200 + setStatusCode(HttpStatus.OK); + // 设置响应内容类型为 JSON + getHeaders().setContentType(MediaType.APPLICATION_JSON); + // 清理Sentinel失效token + redisService.deleteObject(CacheConstants.SENTINEL_TOKEN); + // 创建自定义的 JSON 响应内容 + String jsonBody = JSON.toJSONString(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR)); + byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8); + getHeaders().setContentLength(bytes.length); + DataBuffer dataBuffer = bufferFactory.wrap(bytes); + + // 返回新的响应内容 + return super.writeWith(Mono.just(dataBuffer)); + } + + return Flux.from(body).handle((dataBuffer, synchronousSink) -> { + if (status.isError()) { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + //释放掉内存 + DataBufferUtils.release(dataBuffer); + String result = new String(bytes, StandardCharsets.UTF_8); + synchronousSink.next(result); + } + synchronousSink.complete(); + }).flatMap(resStr -> { + log.error("Sentinel响应处理异常,异常信息:{}", resStr); + byte[] bytes; + bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.SYSTEM_EXEC_ERROR)); + setStatusCode(HttpStatus.OK); + + getHeaders().setContentLength(bytes.length); + DataBuffer buffer = bufferFactory.wrap(bytes); + return super.writeWith(Mono.just(buffer)); + }).then(); + } + }; + + return chain.filter(exchange.mutate().response(decoratedResponse).build()); + } return chain.filter(exchange); } From 8dec06e52010ac895c6c95f7e963a8b39c966b47 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:49:29 +0800 Subject: [PATCH 33/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E7=99=BB=E5=BD=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=BC=82=E5=B8=B8=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 记录鉴权异常信息 Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/gateway/filter/GlobalResponseFilter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java index 1057a4f5c..5007553a4 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -53,6 +53,7 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { return super.writeWith(body); } if (status == HttpStatus.FORBIDDEN) { + log.error("nacos鉴权异常,已清理redis中nacos token"); // 设置新的状态码为 200 setStatusCode(HttpStatus.OK); // 设置响应内容类型为 JSON @@ -64,7 +65,6 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8); getHeaders().setContentLength(bytes.length); DataBuffer dataBuffer = bufferFactory.wrap(bytes); - // 返回新的响应内容 return super.writeWith(Mono.just(dataBuffer)); } @@ -123,6 +123,7 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { JSONObject resJson = JSONObject.parseObject(resStr); if (resJson.containsKey("message")) { String message = resJson.getString("message"); + log.error("Portainer鉴权异常,已清理redis中Portainer token"); if (StringUtils.isNotBlank(message) && message.contains("A valid authorisation token is missing")) { //token失效清除redis缓存 redisService.deleteObject(CacheConstants.PORTAINER_TOKEN); @@ -155,6 +156,7 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { return super.writeWith(body); } if (status == HttpStatus.UNAUTHORIZED) { + log.error("sentinel鉴权异常,已清理redis中sentinel token"); // 设置新的状态码为 200 setStatusCode(HttpStatus.OK); // 设置响应内容类型为 JSON @@ -166,7 +168,6 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8); getHeaders().setContentLength(bytes.length); DataBuffer dataBuffer = bufferFactory.wrap(bytes); - // 返回新的响应内容 return super.writeWith(Mono.just(dataBuffer)); } From 209c96bc48b10237bb4d0ec7c349c1252d0ca40f Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 6 Mar 2025 16:52:03 +0800 Subject: [PATCH 34/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E6=95=88=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/service/impl/ThirdPartyToolServiceImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index 7520d037d..af76cc522 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -49,8 +49,6 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { public String portainerUsername; @Value("${thirdPartyTools.portainer.auth.password:}") public String portainerPassword; - @Value("${thirdPartyTools.portainer.endpoints:}") - public Integer portainerEndpoints; ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; @Lazy @Autowired From d81093a51a6603681e9adb61126b6c420b07c8aa Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 7 Mar 2025 08:55:44 +0800 Subject: [PATCH 35/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E7=99=BB=E5=BD=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=BC=82=E5=B8=B8=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当Nacos返回异常状态码时,且body数据类型为JSON时,从JSON中取出message字段作为异常响应信息,若不存在该字段则返回默认的错误信息 Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/filter/GlobalResponseFilter.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java index 5007553a4..30c5a7905 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -76,17 +76,26 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { //释放掉内存 DataBufferUtils.release(dataBuffer); String result = new String(bytes, StandardCharsets.UTF_8); - if (!JSON.isValid(result)) { - synchronousSink.next(result); - return; - } + synchronousSink.next(result); + return; } synchronousSink.complete(); - }).flatMap(resBody -> { + }).flatMap(resStr -> { // 保留原始状态码 originalResponse.setStatusCode(HttpStatus.OK); - byte[] bytes = JSON.toJSONBytes(AjaxResult.error(resBody)); + String errMsg; + if (!JSON.isValid(resStr)) { + errMsg = resStr; + } else { + JSONObject resJson = JSONObject.parseObject(resStr); + if (resJson.containsKey("message")) { + errMsg = resJson.getString("message"); + } else { + errMsg = ExceptionMsgConstants.SYSTEM_EXEC_ERROR; + } + } + byte[] bytes = JSON.toJSONBytes(AjaxResult.error(errMsg)); getHeaders().setContentLength(bytes.length); DataBuffer buffer = bufferFactory.wrap(bytes); return super.writeWith(Mono.just(buffer)); From 5dbed2684cc8a666a9b23d4b5833e90b9a492d9d Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 7 Mar 2025 09:56:36 +0800 Subject: [PATCH 36/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../main/java/com/microservices/gateway/filter/AuthFilter.java | 2 +- .../gateway/service/impl/ThirdPartyToolServiceImpl.java | 2 +- .../gateway/{ => utils}/CustomExecutorFactory.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename microservices-gateway/src/main/java/com/microservices/gateway/{ => utils}/CustomExecutorFactory.java (96%) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java index ba6f31a77..4d6ac1316 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/AuthFilter.java @@ -10,9 +10,9 @@ import com.microservices.common.core.utils.JwtUtils; import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.StringUtils; import com.microservices.common.redis.service.RedisService; -import com.microservices.gateway.CustomExecutorFactory; import com.microservices.gateway.config.properties.IgnoreWhiteProperties; import com.microservices.gateway.service.ThirdPartyToolService; +import com.microservices.gateway.utils.CustomExecutorFactory; import com.microservices.system.api.RemoteUserService; import com.microservices.system.api.domain.SysUserDeptRole; import com.microservices.system.api.utils.FeignUtils; diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index af76cc522..784410533 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -10,8 +10,8 @@ import com.microservices.common.core.utils.CookieUtil; import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.StringUtils; import com.microservices.common.redis.service.RedisService; -import com.microservices.gateway.CustomExecutorFactory; import com.microservices.gateway.service.ThirdPartyToolService; +import com.microservices.gateway.utils.CustomExecutorFactory; import com.microservices.system.api.RemoteGatewayService; import feign.Response; import org.apache.commons.io.IOUtils; diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java b/microservices-gateway/src/main/java/com/microservices/gateway/utils/CustomExecutorFactory.java similarity index 96% rename from microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java rename to microservices-gateway/src/main/java/com/microservices/gateway/utils/CustomExecutorFactory.java index c18c39865..7a47fe94b 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/CustomExecutorFactory.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/utils/CustomExecutorFactory.java @@ -1,4 +1,4 @@ -package com.microservices.gateway; +package com.microservices.gateway.utils; import com.microservices.common.core.exception.ServiceException; import com.microservices.common.core.threadPool.ThreadPoolExecutorWrap; From c179173b74941659c2e4cf655cdacdcc5dd0c827 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 7 Mar 2025 11:07:05 +0800 Subject: [PATCH 37/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E4=BC=98=E5=8C=96portainer?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 清理用户Cookie中携带的portainer_api_key参数,防止该参数转发到portainer后导致的JWT Token无效的问题 2. 处理portainer指定endpoints的问题:拦截portainer中URL中携带endpoints的请求,将请求中的endpoints替换为Nacos中配置的参数,防止环境变更导致数据失效 Signed-off-by: OTTO <731554297@qq.com> --- .../common/core/constant/TokenConstants.java | 1 + .../impl/ThirdPartyToolServiceImpl.java | 36 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java index e9349b3aa..2dd66640b 100644 --- a/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java +++ b/microservices-common/microservices-common-core/src/main/java/com/microservices/common/core/constant/TokenConstants.java @@ -22,6 +22,7 @@ public class TokenConstants { * Sentinel令牌标识 */ public static final String Sentinel_Token_Key = "sentinel_dashboard_cookie"; + public static final String Portainer_Token_Key = "portainer_api_key"; /** * Sentinel令牌标识 */ diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index 784410533..fcee50528 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -27,9 +27,13 @@ import reactor.core.publisher.Mono; import java.io.IOException; import java.io.StringWriter; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author OTTO @@ -49,6 +53,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { public String portainerUsername; @Value("${thirdPartyTools.portainer.auth.password:}") public String portainerPassword; + @Value("${thirdPartyTools.portainer.endpoints:}") + public Integer portainerEndpoints; ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; @Lazy @Autowired @@ -61,7 +67,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { */ @Override public Mono handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate) { - String lowerUrl = request.getURI().getPath().toLowerCase(); + String url = request.getURI().getPath(); + String lowerUrl = url.toLowerCase(); if (StringUtils.isEmpty(lowerUrl)) { return null; } @@ -141,8 +148,32 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { // 处理portainer请求 if (lowerUrl.startsWith("/portainer")) { + // 处理portainer指定endpoints的问题 + if (lowerUrl.startsWith("/portainer/api/endpoints/")) { + String regex = "^/portainer/api/endpoints/\\d+/.*$"; + if (Pattern.matches(regex, lowerUrl)) { + // 替换掉endpoints + regex = "(^/portainer/api/endpoints/)(\\d+)(/.*$)"; + Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(url); + if (matcher.find()) { + // 替换数字部分 + url = matcher.replaceAll(matcher.group(1) + portainerEndpoints + matcher.group(3)); + try { + mutate.uri(new URI(url)); + } catch (URISyntaxException e) { + log.error("替换Portainer请求中Endpoints时发生异常:{}", e.getMessage()); + } + } + } + } String portainerToken = null; + String cookie = request.getHeaders().getFirst(TokenConstants.Cookie); + if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Portainer_Token_Key))) { + cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Portainer_Token_Key); + } + if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) { portainerToken = redisService.getCacheObject(CacheConstants.PORTAINER_TOKEN); } else { @@ -181,7 +212,10 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { } } if (StringUtils.isNotEmpty(portainerToken)) { + ServletUtils.removeHeader(mutate, TokenConstants.Cookie); + ServletUtils.removeHeader(mutate, TokenConstants.AUTHENTICATION); mutate.header(TokenConstants.AUTHENTICATION, TokenConstants.PREFIX + portainerToken); + mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, portainerToken)); } else { throw new ServiceException("Portainer服务获取Token失败"); } From 4c8be09a7218b80d2676d19aedf397063ed5c6bd Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 7 Mar 2025 14:00:16 +0800 Subject: [PATCH 38/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E4=BC=98=E5=8C=96portainer?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复拦截portainer中URL中携带endpoints的请求时,未考虑endpoints在末尾的情况 Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/gateway/filter/GlobalResponseFilter.java | 2 +- .../gateway/service/impl/ThirdPartyToolServiceImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java index 30c5a7905..2baa6963a 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/filter/GlobalResponseFilter.java @@ -132,8 +132,8 @@ public class GlobalResponseFilter implements GlobalFilter, Ordered { JSONObject resJson = JSONObject.parseObject(resStr); if (resJson.containsKey("message")) { String message = resJson.getString("message"); - log.error("Portainer鉴权异常,已清理redis中Portainer token"); if (StringUtils.isNotBlank(message) && message.contains("A valid authorisation token is missing")) { + log.error("Portainer鉴权异常,已清理redis中Portainer token"); //token失效清除redis缓存 redisService.deleteObject(CacheConstants.PORTAINER_TOKEN); bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR)); diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index fcee50528..bb60f28ba 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -150,10 +150,10 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { if (lowerUrl.startsWith("/portainer")) { // 处理portainer指定endpoints的问题 if (lowerUrl.startsWith("/portainer/api/endpoints/")) { - String regex = "^/portainer/api/endpoints/\\d+/.*$"; + String regex = "^/portainer/api/endpoints/\\d+(/?.*)"; if (Pattern.matches(regex, lowerUrl)) { // 替换掉endpoints - regex = "(^/portainer/api/endpoints/)(\\d+)(/.*$)"; + regex = "(^/portainer/api/endpoints/)(\\d+)(/?.*)"; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(url); if (matcher.find()) { From e40d58ae9d4a56a608f5fb63d18a97bfcbcd659f Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Fri, 7 Mar 2025 15:33:22 +0800 Subject: [PATCH 39/49] =?UTF-8?q?feat(=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=B2=BB?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=85=B7):=20=E4=BC=98=E5=8C=96Sentinel?= =?UTF-8?q?=E5=85=8D=E7=99=BB=E5=BD=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sentinel登录状态默认30分钟失效,将Sentinel Token缓存过期时间调整为28分钟 Signed-off-by: OTTO <731554297@qq.com> --- .../gateway/service/impl/ThirdPartyToolServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java index bb60f28ba..0cf7dfea7 100644 --- a/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java +++ b/microservices-gateway/src/main/java/com/microservices/gateway/service/impl/ThirdPartyToolServiceImpl.java @@ -90,7 +90,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService { Map> header = response.headers(); if (header != null && header.containsKey("set-cookie")) { sentinelCookie = header.get("set-cookie").iterator().next(); - redisService.setCacheObject(CacheConstants.SENTINEL_TOKEN, sentinelCookie, 12L, TimeUnit.HOURS); + //Sentinel登录状态默认30分钟失效,将Sentinel Token缓存过期时间调整为28分钟 + redisService.setCacheObject(CacheConstants.SENTINEL_TOKEN, sentinelCookie, 28L, TimeUnit.MINUTES); } } catch (TimeoutException e) { log.error("获取Sentinel Token超时"); From 7a4abfa7e9299f2aa416a836c705535a789232bd Mon Sep 17 00:00:00 2001 From: liuhuazhong Date: Tue, 11 Mar 2025 15:12:42 +0800 Subject: [PATCH 40/49] =?UTF-8?q?feat(=E8=BD=AF=E4=BB=B6=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1):=20=E4=BB=8A=E6=97=A5=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=80=81=E5=8A=BF=E3=80=81=E5=91=A8=E6=9C=88=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=80=81=E5=8A=BF=E3=80=81=E9=A1=B9=E7=9B=AE=E7=A0=94=E5=8F=91?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pms/specialArea/constant/Constant.java | 30 ++ .../SoftwareFactStatisticsController.java | 38 +++ .../pms/specialArea/domain/ForgeProject.java | 25 ++ .../specialArea/domain/ZonePmsProject.java | 42 +++ .../pms/specialArea/domain/vo/KeyValVO.java | 9 + .../domain/vo/ProjectSituationVO.java | 19 ++ .../mapper/SoftwareFactStatisForgeMapper.java | 19 ++ .../mapper/SoftwareFactStatisPmsMapper.java | 30 ++ .../SoftwareFactStatisticsServiceImpl.java | 276 ++++++++++++++++++ .../pms/SoftwareFactStatisForgeMapper.xml | 82 ++++++ .../pms/SoftwareFactStatisPmsMapper.xml | 89 ++++++ 11 files changed, 659 insertions(+) create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/constant/Constant.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ForgeProject.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ZonePmsProject.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/KeyValVO.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/ProjectSituationVO.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisForgeMapper.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisPmsMapper.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java create mode 100644 microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisForgeMapper.xml create mode 100644 microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/constant/Constant.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/constant/Constant.java new file mode 100644 index 000000000..bd9227093 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/constant/Constant.java @@ -0,0 +1,30 @@ +package com.microservices.pms.specialArea.constant; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + + private Constant() {} + + public static final List ISSUE_NOT_FINISHED = Arrays.asList(1,2); + public static final List ISSUE_FINISHED = Arrays.asList(3,5,6); + + public static final Integer NEED = 1; + public static final Integer TASK = 2; + public static final Integer BUG = 3; + + + public static final Integer TASK_CASE_STATUS_NOT_EXEC = 0; + public static final Integer TASK_CASE_STATUS_PASS = 1; + public static final Integer TASK_CASE_STATUS_FAIL = 2; + public static final Integer TASK_CASE_STATUS_BLOCK = 3; + public static final Integer TASK_CASE_STATUS_SKIP = 4; + + + public static final Integer SPRINT_STATUS_CLOSED = 2; + public static final Integer SPRINT_STATUS_PROCESSING = 1; + public static final Integer SPRINT_STATUS_NOT_START = 0; + + +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java new file mode 100644 index 000000000..90953edcf --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java @@ -0,0 +1,38 @@ +package com.microservices.pms.specialArea.controller; + +import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.pms.specialArea.service.SoftwareFactStatisticsServiceImpl; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController() +@RequestMapping("/specialArea/softwareFact/statis") +@Api(tags = "项目管理-软件工厂统计相关接口") +@RequiredArgsConstructor +public class SoftwareFactStatisticsController { + + private final SoftwareFactStatisticsServiceImpl softwareFactStatisticsService; + + @ApiOperation(value = "今日工作态势") + @GetMapping("/todayWorkSituation") + public AjaxResult todayWorkSituation(){ + return AjaxResult.success(softwareFactStatisticsService.todayWorkSituation()); + } + + @ApiOperation(value = "周、月工作态势") + @GetMapping("/weekMonthWorkSituation") + public AjaxResult weekMonthWorkSituation(String type){ + return AjaxResult.success(softwareFactStatisticsService.weekMonthWorkSituation(type)); + } + + @ApiOperation(value = "项目研发状态") + @GetMapping("/projectSituation") + public AjaxResult projectSituation(){ + return AjaxResult.success(softwareFactStatisticsService.projectSituation()); + } + +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ForgeProject.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ForgeProject.java new file mode 100644 index 000000000..e111a1ef3 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ForgeProject.java @@ -0,0 +1,25 @@ +package com.microservices.pms.specialArea.domain; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class ForgeProject { + + //项目ID + private Long pmProjectId; + // 需求1 任务2 缺陷3,默认为 1 + private Integer pmIssueType; + + //状态ID + private List statusIds; + //创建时间开始 + private Date createTimeS; + //创建时间结束 + private Date createTimeE; + //更新时间开始 + private Date updateTimeS; + private Date updateTimeE; +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ZonePmsProject.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ZonePmsProject.java new file mode 100644 index 000000000..619ed55e4 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/ZonePmsProject.java @@ -0,0 +1,42 @@ +package com.microservices.pms.specialArea.domain; + +import com.microservices.common.core.annotation.Excel; +import lombok.Data; + +@Data +public class ZonePmsProject { + + /** 项目ID */ + private Long id; + + /** + * 组织Id + */ + private Long deptId; + + /** 项目标识 */ + @Excel(name = "项目标识") + private String projectIdentifier; + + /** 项目名称 */ + @Excel(name = "项目名称") + private String projectName; + + /** 项目负责人 */ + @Excel(name = "项目负责人") + private Long projectAssigneeId; + + /** 项目负责人 */ + @Excel(name = "项目负责人") + private String projectAssigneeName; + /** 所属企业ID */ + @Excel(name = "所属企业ID") + private Long pmsEnterpriseId; + /** 所属企业ID */ + @Excel(name = "所属企业") + private String pmsEnterpriseName; + + /** 状态 0关闭 1开启 2暂停 */ + @Excel(name = "状态 0关闭 1开启 2暂停") + private String status; +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/KeyValVO.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/KeyValVO.java new file mode 100644 index 000000000..c45ea9b8b --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/KeyValVO.java @@ -0,0 +1,9 @@ +package com.microservices.pms.specialArea.domain.vo; + +import lombok.Data; + +@Data +public class KeyValVO { + private Integer key; + private Long val; +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/ProjectSituationVO.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/ProjectSituationVO.java new file mode 100644 index 000000000..f90e70baa --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/domain/vo/ProjectSituationVO.java @@ -0,0 +1,19 @@ +package com.microservices.pms.specialArea.domain.vo; + +import com.microservices.pms.specialArea.domain.ZonePmsProject; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class ProjectSituationVO extends ZonePmsProject { + private Long needCount; + private Long needFinishedCount; + private Long taskCount; + private Long taskFinishedCount; + private Long sprintCount; + private Long sprintFinishedCount; + private Long testCaseCount; + private Long testBugCount; + private Long notExecTestCaseCount; +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisForgeMapper.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisForgeMapper.java new file mode 100644 index 000000000..a58a5e647 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisForgeMapper.java @@ -0,0 +1,19 @@ +package com.microservices.pms.specialArea.mapper; + +import com.microservices.common.datasource.annotation.Slave; +import com.microservices.pms.specialArea.domain.ForgeProject; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +@Slave +public interface SoftwareFactStatisForgeMapper { + + List selectForgeProject(ForgeProject forgeProject); + + Long countForgeProject(ForgeProject forgeProject); + Long countForgeProjectByCUES(ForgeProject forgeProject); + Long countForgeProjectByProject(ForgeProject forgeProject); + Long countForgeProjectByAssigner(ForgeProject forgeProject); +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisPmsMapper.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisPmsMapper.java new file mode 100644 index 000000000..a9f75432f --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/mapper/SoftwareFactStatisPmsMapper.java @@ -0,0 +1,30 @@ +package com.microservices.pms.specialArea.mapper; + +import com.microservices.common.datasource.annotation.Master; +import com.microservices.pms.specialArea.domain.ForgeProject; +import com.microservices.pms.specialArea.domain.ZonePmsProject; +import com.microservices.pms.specialArea.domain.vo.KeyValVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Master +@Mapper +public interface SoftwareFactStatisPmsMapper { + + List selectPmsProjectList(); + + ZonePmsProject selectPmsProjectById(@Param("id") Long id); + // 状态 0待开始 1进行中 2已关闭 + List countSprintByStatus(Long projectId); + Long countSprintByCUES(ForgeProject forgeProject); + Long countTestCaseBy(Long projectId); + Long countTestCaseInSheet(ForgeProject forgeProject); + Long countTestCaseByCUES(ForgeProject forgeProject); + + String selectPmsUserByGitlinkId(@Param("gitlinkId") Long gitlinkId); + + List selectPmsProjectListByDict(); + +} diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java new file mode 100644 index 000000000..3f216f91b --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java @@ -0,0 +1,276 @@ +package com.microservices.pms.specialArea.service; + +import com.microservices.common.core.web.controller.BaseController; +import com.microservices.pms.specialArea.domain.ForgeProject; +import com.microservices.pms.specialArea.domain.ZonePmsProject; +import com.microservices.pms.specialArea.domain.vo.KeyValVO; +import com.microservices.pms.specialArea.domain.vo.ProjectSituationVO; +import com.microservices.pms.specialArea.mapper.SoftwareFactStatisForgeMapper; +import com.microservices.pms.specialArea.mapper.SoftwareFactStatisPmsMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +import static com.microservices.pms.specialArea.constant.Constant.*; + +@Service +@RequiredArgsConstructor +public class SoftwareFactStatisticsServiceImpl extends BaseController { + + private final SoftwareFactStatisPmsMapper statisPmsMapper; + private final SoftwareFactStatisForgeMapper statisForgeMapper; + + public static Date[] getDayStartAndEnd(int days) { + // 获取今天的日期 + LocalDate today = LocalDate.now(); + today = today.plusDays(days); + // 获取今天的开始时间(00:00:00) + LocalDateTime startOfDay = today.atStartOfDay(); + + // 获取今天的结束时间(23:59:59.999999999) + LocalDateTime endOfDay = today.atTime(LocalTime.MAX); + + // 转换为 Date 对象 + Date startDate = Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()); + Date endDate = Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()); + + return new Date[]{startDate, endDate}; + } + + public static Date[] getCurrentWeek() { + LocalDate today = LocalDate.now(); + LocalDate startOfWeek = today.with(java.time.DayOfWeek.MONDAY); + LocalDate endOfWeek = today.with(java.time.DayOfWeek.SUNDAY); + + LocalDateTime startDateTime = startOfWeek.atStartOfDay(); + LocalDateTime endDateTime = endOfWeek.atTime(23, 59, 59); + + return new Date[]{ + Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()), + Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant()) + }; + } + + public static Date[] getCurrentMonth() { + LocalDate today = LocalDate.now(); + LocalDate startOfMonth = today.withDayOfMonth(1); + LocalDate endOfMonth = today.withDayOfMonth(today.lengthOfMonth()); + + LocalDateTime startDateTime = startOfMonth.atStartOfDay(); + LocalDateTime endDateTime = endOfMonth.atTime(23, 59, 59); + + return new Date[]{ + Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()), + Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant()) + }; + } + + public Map todayWorkSituation() { + + Map res = new HashMap<>(); + + ForgeProject forgeProject = new ForgeProject(); + forgeProject.setStatusIds(ISSUE_NOT_FINISHED); + + //需求待评审 + forgeProject.setPmIssueType(NEED); + Long needNotFinishCount = statisForgeMapper.countForgeProject(forgeProject); + res.put("needNotFinishCount", needNotFinishCount); + + //任务待完成 + forgeProject.setPmIssueType(TASK); + Long taskNotFinishCount = statisForgeMapper.countForgeProject(forgeProject); + res.put("taskNotFinishCount", taskNotFinishCount); + + //缺陷待修复 + forgeProject.setPmIssueType(BUG); + Long bugNotFinishCount = statisForgeMapper.countForgeProject(forgeProject); + res.put("bugNotFinishCount", bugNotFinishCount); + //测试用例未执行数 + forgeProject.setStatusIds(Collections.singletonList(TASK_CASE_STATUS_NOT_EXEC)); + Long notExecTestCaseCount = statisPmsMapper.countTestCaseInSheet(forgeProject); + res.put("notExecTestCaseCount", notExecTestCaseCount); + + ForgeProject f2 = new ForgeProject(); + f2.setStatusIds(ISSUE_NOT_FINISHED); + f2.setPmIssueType(TASK); + //任务最多项目 + Long taskMaxProjectId = statisForgeMapper.countForgeProjectByProject(f2); + ZonePmsProject taskMaxProject = statisPmsMapper.selectPmsProjectById(taskMaxProjectId); + res.put("taskMaxProject", taskMaxProject == null ?"": taskMaxProject.getProjectName()); + //任务最多个人 + Long taskMaxAssignerId = statisForgeMapper.countForgeProjectByAssigner(f2); + String taskMaxAssigner = statisPmsMapper.selectPmsUserByGitlinkId(taskMaxAssignerId); + res.put("taskMaxAssigner", taskMaxAssigner); + f2.setPmIssueType(BUG); + //缺陷最多项目 + Long bugMaxProjectId = statisForgeMapper.countForgeProjectByProject(f2); + ZonePmsProject bugMaxProject = statisPmsMapper.selectPmsProjectById(bugMaxProjectId); + res.put("bugMaxProject", bugMaxProject == null ?"": bugMaxProject.getProjectName()); + //缺陷最多个人 + Long bugMaxAssignerId = statisForgeMapper.countForgeProjectByAssigner(f2); + String bugMaxAssigner = statisPmsMapper.selectPmsUserByGitlinkId(bugMaxAssignerId); + res.put("bugMaxAssigner", bugMaxAssigner); + + + // 昨日完成、昨日新增 + Date[] dayStartAndEnd = getDayStartAndEnd(-1); + ForgeProject forgeProjectTime = new ForgeProject(); + forgeProjectTime.setCreateTimeS(dayStartAndEnd[0]); + forgeProjectTime.setCreateTimeE(dayStartAndEnd[1]); + buildDayWeekMonthData(forgeProjectTime, res, dayStartAndEnd); + + return res; + } + + private void buildDayWeekMonthData(ForgeProject forgeProjectTime, Map res, Date[] dayStartAndEnd) { + // 昨日新增需求 + forgeProjectTime.setPmIssueType(NEED); + Long yesterdayAddNeed = statisForgeMapper.countForgeProject(forgeProjectTime); + res.put("yesterdayAddNeed", yesterdayAddNeed); +//昨日新增 任务 + forgeProjectTime.setPmIssueType(TASK); + Long yesterdayAddTask = statisForgeMapper.countForgeProject(forgeProjectTime); + res.put("yesterdayAddTask", yesterdayAddTask); +//昨日新增 缺陷 + forgeProjectTime.setPmIssueType(BUG); + Long yesterdayAddBug = statisForgeMapper.countForgeProject(forgeProjectTime); + res.put("yesterdayAddBug", yesterdayAddBug); + + ForgeProject forgeProjectFinish = new ForgeProject(); + forgeProjectFinish.setStatusIds(ISSUE_FINISHED); + forgeProjectFinish.setUpdateTimeS(dayStartAndEnd[0]); + forgeProjectFinish.setUpdateTimeE(dayStartAndEnd[1]); + //昨日任务完结 + forgeProjectFinish.setPmIssueType(TASK); + Long yesterdayFinishTask = statisForgeMapper.countForgeProject(forgeProjectFinish); + res.put("yesterdayFinishTask", yesterdayFinishTask); + //昨日缺陷关闭数 + forgeProjectFinish.setPmIssueType(BUG); + Long yesterdayFinishBug = statisForgeMapper.countForgeProject(forgeProjectFinish); + res.put("yesterdayFinishBug", yesterdayFinishBug); +// 昨日需求评审数 + forgeProjectFinish.setPmIssueType(NEED); + Long yesterdayFinishNeed = statisForgeMapper.countForgeProject(forgeProjectFinish); + res.put("yesterdayFinishNeed", yesterdayFinishNeed); + //昨日测试用例执行 + ForgeProject forgeProjectTest = new ForgeProject(); + forgeProjectFinish.setStatusIds(Arrays.asList(TASK_CASE_STATUS_PASS, TASK_CASE_STATUS_FAIL, TASK_CASE_STATUS_BLOCK, TASK_CASE_STATUS_SKIP)); + forgeProjectFinish.setUpdateTimeS(dayStartAndEnd[0]); + forgeProjectFinish.setUpdateTimeE(dayStartAndEnd[1]); + Long yesterdayTestCase = statisPmsMapper.countTestCaseInSheet(forgeProjectTest); + res.put("yesterdayTestCase", yesterdayTestCase); + + // 昨日最活跃项目 + List zonePmsProjects = statisPmsMapper.selectPmsProjectList(); + long pmsProjectIdMax = 0L, maxVal = -1L; + for (ZonePmsProject p : zonePmsProjects) { + ForgeProject f = new ForgeProject(); + f.setCreateTimeS(dayStartAndEnd[0]); + f.setCreateTimeE(dayStartAndEnd[1]); + f.setUpdateTimeS(dayStartAndEnd[0]); + f.setUpdateTimeE(dayStartAndEnd[1]); + f.setPmProjectId(p.getId()); + + f.setPmIssueType(NEED); + Long a = statisForgeMapper.countForgeProjectByCUES(f); + f.setPmIssueType(TASK); + Long b = statisForgeMapper.countForgeProjectByCUES(f); + f.setPmIssueType(BUG); + Long c = statisForgeMapper.countForgeProjectByCUES(f); + Long d = statisPmsMapper.countSprintByCUES(f); + Long e = statisPmsMapper.countTestCaseByCUES(f); + + long total = a + b + c + d + e; + if (total > maxVal) { + pmsProjectIdMax = p.getId(); + maxVal = total; + } + } + + ZonePmsProject zonePmsProjectMax = statisPmsMapper.selectPmsProjectById(pmsProjectIdMax); + res.put("zonePmsProjectMax", zonePmsProjectMax==null? "": zonePmsProjectMax.getProjectName()); + } + + public List projectSituation() { + + List zonePmsProjects = statisPmsMapper.selectPmsProjectList(); + List showProjectList = statisPmsMapper.selectPmsProjectListByDict() + .stream().filter(Objects::nonNull) + .collect(Collectors.toList()); + + if (!showProjectList.isEmpty()) { + zonePmsProjects = zonePmsProjects.stream().filter(e->showProjectList.contains(e.getId())) + .collect(Collectors.toList()); + } + List res = new ArrayList<>(); + zonePmsProjects.forEach(zonePmsProject -> { + + ProjectSituationVO vo = new ProjectSituationVO(); + BeanUtils.copyProperties(zonePmsProject, vo); + + Map sprintCountMap = statisPmsMapper.countSprintByStatus(zonePmsProject.getId()) + .stream() + .collect(Collectors.toMap(KeyValVO::getKey, KeyValVO::getVal, (o, n) -> n)); + + vo.setSprintFinishedCount(sprintCountMap.getOrDefault(SPRINT_STATUS_CLOSED,0L)); + vo.setSprintCount(sprintCountMap.values().stream().reduce(0L, Long::sum)); + + ForgeProject forgeProject = new ForgeProject(); + forgeProject.setPmProjectId(zonePmsProject.getId()); + forgeProject.setPmIssueType(NEED); + Long planCount = statisForgeMapper.countForgeProject(forgeProject); + vo.setNeedCount(planCount); + forgeProject.setStatusIds(ISSUE_FINISHED); + Long planFinishCount = statisForgeMapper.countForgeProject(forgeProject); + vo.setNeedFinishedCount(planFinishCount); + forgeProject.setPmIssueType(TASK); + Long taskFinishCount = statisForgeMapper.countForgeProject(forgeProject); + vo.setTaskFinishedCount(taskFinishCount); + forgeProject.setStatusIds(new ArrayList<>()); + Long taskCount = statisForgeMapper.countForgeProject(forgeProject); + vo.setTaskCount(taskCount); + + // 测试相关 + //测试用例数 + Long testCaseCount = statisPmsMapper.countTestCaseBy(zonePmsProject.getId()); + forgeProject.setPmIssueType(BUG); + forgeProject.setStatusIds(ISSUE_NOT_FINISHED); + vo.setTestCaseCount(testCaseCount); +// 测试缺陷数 + Long testBugCount = statisForgeMapper.countForgeProject(forgeProject); + vo.setTestBugCount(testBugCount); +// 测试用例未执行数 + forgeProject.setStatusIds(Collections.singletonList(TASK_CASE_STATUS_NOT_EXEC)); + Long notExecTestCaseCount = statisPmsMapper.countTestCaseInSheet(forgeProject); + vo.setNotExecTestCaseCount(notExecTestCaseCount); + + res.add(vo); + }); + + return res; + } + + public Map weekMonthWorkSituation(String type) { + Map res = new HashMap<>(); + Date[] dayStartAndEnd = getDayStartAndEnd(-1); + if (Objects.equals(type, "week")) { + dayStartAndEnd = getCurrentWeek(); + } else if (Objects.equals(type, "month")) { + dayStartAndEnd = getCurrentMonth(); + } + ForgeProject forgeProjectTime = new ForgeProject(); + forgeProjectTime.setCreateTimeS(dayStartAndEnd[0]); + forgeProjectTime.setCreateTimeE(dayStartAndEnd[1]); + buildDayWeekMonthData(forgeProjectTime, res, dayStartAndEnd); + + return res; + } +} diff --git a/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisForgeMapper.xml b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisForgeMapper.xml new file mode 100644 index 000000000..d82bf9417 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisForgeMapper.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml new file mode 100644 index 000000000..964903987 --- /dev/null +++ b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b8fbf94be61a201a55054d9376cb008449675b6f Mon Sep 17 00:00:00 2001 From: liuhuazhong Date: Thu, 13 Mar 2025 14:28:20 +0800 Subject: [PATCH 41/49] =?UTF-8?q?feat(=E4=B8=93=E5=8C=BA=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E8=83=BD=E5=8A=9B=E4=B8=8A=E7=BA=BF):=20?= =?UTF-8?q?=E8=BF=91=E4=B8=80=E5=91=A8=E7=9A=84=E6=96=87=E7=AB=A0=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=8F=91=E5=B8=83=E6=95=B0=E3=80=81=E8=BF=91=E4=B8=80?= =?UTF-8?q?=E5=91=A8PV=E6=95=B0=EF=BC=88=E6=80=BB=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E9=87=8F=EF=BC=89=E3=80=81=E8=BF=91=E4=B8=80=E5=91=A8UV?= =?UTF-8?q?=E6=95=B0=EF=BC=88=E7=82=B9=E5=87=BB=E5=8E=BB=E9=87=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/domain/vo/ZoneDetailDataVo.java | 18 + .../zone/detail/mapper/ZoneDetailMapper.java | 22 + .../service/impl/ZoneDetailServiceImpl.java | 37 +- .../mapper/zone/ZoneDetailMapper.xml | 432 +++++++++--------- 4 files changed, 299 insertions(+), 210 deletions(-) diff --git a/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/domain/vo/ZoneDetailDataVo.java b/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/domain/vo/ZoneDetailDataVo.java index 28d2e6f53..7a1fe28d2 100644 --- a/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/domain/vo/ZoneDetailDataVo.java +++ b/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/domain/vo/ZoneDetailDataVo.java @@ -247,4 +247,22 @@ public class ZoneDetailDataVo extends BaseEntity { */ @ApiModelProperty(value = "数据集板块标题") private String sectionDataSetTitle; + + /** + * 近一周的文章新增发布数 + */ + @ApiModelProperty(value = "近一周的文章新增发布数") + private Long weekArticles = 0L; + + /** + * 近一周UV数(点击去重) + */ + @ApiModelProperty(value = "近一周UV数(点击去重)") + private Long weekUV = 0L; + + /** + * 近一周PV数(总访问量) + */ + @ApiModelProperty(value = "近一周PV数(总访问量)") + private Long weekPV = 0L; } diff --git a/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/mapper/ZoneDetailMapper.java b/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/mapper/ZoneDetailMapper.java index 4b92aa8ad..b2a0eda48 100644 --- a/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/mapper/ZoneDetailMapper.java +++ b/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/mapper/ZoneDetailMapper.java @@ -2,9 +2,13 @@ package com.microservices.zone.detail.mapper; import com.microservices.common.datascope.annotation.DataScope; import com.microservices.zone.detail.domain.ZoneDetail; +import com.microservices.zone.detail.domain.vo.ZoneDetailDataVo; import com.microservices.zone.detail.domain.vo.ZoneDetailSearchVo; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.security.access.method.P; +import java.util.Date; import java.util.List; /** @@ -95,4 +99,22 @@ public interface ZoneDetailMapper { * @return */ ZoneDetail selectZoneDetailByName(String name); + + /** + * 专区文章数统计 + * @param createTimeS + * @param createTimeE + * @param key + * @return + */ + ZoneDetailDataVo countArticlesGroupByKey(@Param("createTimeS") Date createTimeS, @Param("createTimeE") Date createTimeE, @Param("key") String key); + + /** + * 专区浏览数据统计 + * @param createTimeS + * @param createTimeE + * @param key + * @return + */ + ZoneDetailDataVo countPUVsGroupByKey(@Param("createTimeS") Date createTimeS, @Param("createTimeE") Date createTimeE, @Param("key") String key); } diff --git a/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/service/impl/ZoneDetailServiceImpl.java b/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/service/impl/ZoneDetailServiceImpl.java index 7eb151787..a84b8dc0d 100644 --- a/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/service/impl/ZoneDetailServiceImpl.java +++ b/microservices-modules/microservices-modules-zone/src/main/java/com/microservices/zone/detail/service/impl/ZoneDetailServiceImpl.java @@ -57,10 +57,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; import java.util.stream.Collectors; /** @@ -198,6 +198,22 @@ public class ZoneDetailServiceImpl implements IZoneDetailService { gitLinkRequestHelper.gitLinkUrl + "/zone/" + zoneDetail.getKey() ) ); + + Date[] lastWeek = getLastWeek(); + //专区文章数统计 + ZoneDetailDataVo articlesGroupByKey = zoneDetailMapper + .countArticlesGroupByKey(lastWeek[0],lastWeek[1],zoneDetail.getKey()) ; + if (articlesGroupByKey != null) { + zoneDetailDataVo.setWeekArticles(articlesGroupByKey.getWeekArticles()); + } + //专区浏览数据统计 + ZoneDetailDataVo puVsGroupByKey = zoneDetailMapper + .countPUVsGroupByKey(lastWeek[0],lastWeek[1],zoneDetail.getKey()) ; + if (puVsGroupByKey != null) { + zoneDetailDataVo.setWeekPV(puVsGroupByKey.getWeekPV()); + zoneDetailDataVo.setWeekUV(puVsGroupByKey.getWeekUV()); + } + return zoneDetailDataVo; } @@ -776,4 +792,17 @@ public class ZoneDetailServiceImpl implements IZoneDetailService { return zoneStatisticsVo; } + public Date[] getLastWeek() { + LocalDate today = LocalDate.now(); + LocalDate startOfWeek = today.with(java.time.DayOfWeek.MONDAY).minusDays(7); + LocalDate endOfWeek = today.with(java.time.DayOfWeek.SUNDAY).minusDays(7); + + LocalDateTime startDateTime = startOfWeek.atStartOfDay(); + LocalDateTime endDateTime = endOfWeek.atTime(23, 59, 59); + + return new Date[]{ + Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()), + Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant()) + }; + } } diff --git a/microservices-modules/microservices-modules-zone/src/main/resources/mapper/zone/ZoneDetailMapper.xml b/microservices-modules/microservices-modules-zone/src/main/resources/mapper/zone/ZoneDetailMapper.xml index 9bdfbe0df..c7cddd80d 100644 --- a/microservices-modules/microservices-modules-zone/src/main/resources/mapper/zone/ZoneDetailMapper.xml +++ b/microservices-modules/microservices-modules-zone/src/main/resources/mapper/zone/ZoneDetailMapper.xml @@ -192,215 +192,235 @@ - - - - - + + + + + - - insert into zone_detail - - name, - `key`, - dept_id, - del_flag, - create_by, - create_time, - update_by, - update_time, - main_title, - sub_title, - first_title, - banner_list, - introduction_title, - introduction_content, - introduction_image, - homepage_membership_size, - homepage_cms_size, - homepage_project_size, - cms_project_id, - gitlink_project_keys, - cms_show, - project_show, - member_show, - partners_show, - special_project_show, - homepage_special_project_title, - resource_show, - homepage_resource_title, - homepage_cms_title, - homepage_project_title, - homepage_member_title, - homepage_partners_title, - template, - helper_title, - helper_show, - doc_need_audit, - resource_need_audit, - is_lock_cms, - section_cms_show, - section_project_show, - section_member_show, - section_helper_show, - section_homepage_show, - section_resource_show, - section_dataset_show, - section_cms_title, - section_project_title, - section_member_title, - section_helper_title, - section_homepage_title, - section_resource_title, - section_dataset_title, - - - #{name}, - #{key}, - #{deptId}, - #{delFlag}, - #{createBy}, - #{createTime}, - #{updateBy}, - #{updateTime}, - #{mainTitle}, - #{subTitle}, - #{firstTitle}, - #{bannerList}, - #{introductionTitle}, - #{introductionContent}, - #{introductionImage}, - #{homepageMembershipSize}, - #{homepageCmsSize}, - #{homepageProjectSize}, - #{cmsProjectId}, - #{gitlinkProjectKeys}, - #{cmsShow}, - #{projectShow}, - #{memberShow}, - #{partnersShow}, - #{specialProjectShow}, - #{homepageSpecialProjectTitle}, - #{resourceShow}, - #{homepageResourceTitle}, - #{homepageCmsTitle}, - #{homepageProjectTitle}, - #{homepageMemberTitle}, - #{homepagePartnersTitle}, - #{template}, - #{helperTitle}, - #{helperShow}, - #{docNeedAudit}, - #{resourceNeedAudit}, - #{isLockCms}, - #{sectionCmsShow}, - #{sectionProjectShow}, - #{sectionMemberShow}, - #{sectionHelperShow}, - #{sectionHomepageShow}, - #{sectionResourceShow}, - #{sectionDataSetShow}, - #{sectionCmsTitle}, - #{sectionProjectTitle}, - #{sectionMemberTitle}, - #{sectionHelperTitle}, - #{sectionHomepageTitle}, - #{sectionResourceTitle}, - #{sectionDataSetTitle}, - - + - - update zone_detail - - name = #{name}, - `key` = #{key}, - dept_id = #{deptId}, - del_flag = #{delFlag}, - create_by = #{createBy}, - create_time = #{createTime}, - update_by = #{updateBy}, - update_time = #{updateTime}, - main_title = #{mainTitle}, - sub_title = #{subTitle}, - first_title = #{firstTitle}, - banner_list = #{bannerList}, - introduction_title = #{introductionTitle}, - introduction_content = #{introductionContent}, - introduction_image = #{introductionImage}, - homepage_membership_size = #{homepageMembershipSize}, - homepage_cms_size = #{homepageCmsSize}, - homepage_project_size = #{homepageProjectSize}, - cms_project_id = #{cmsProjectId}, - gitlink_project_keys = #{gitlinkProjectKeys}, - is_publish = #{isPublish}, - cms_show = #{cmsShow}, - project_show = #{projectShow}, - member_show = #{memberShow}, - partners_show = #{partnersShow}, - special_project_show = #{specialProjectShow}, - homepage_special_project_title = - #{homepageSpecialProjectTitle}, - - resource_show = #{resourceShow}, - homepage_resource_title = - #{homepageResourceTitle}, - - homepage_cms_title = #{homepageCmsTitle}, - homepage_project_title = #{homepageProjectTitle}, - homepage_member_title = #{homepageMemberTitle}, - homepage_partners_title = #{homepagePartnersTitle}, - template = #{template}, - helper_show = #{helperShow}, - helper_title = #{helperTitle}, - doc_need_audit = #{docNeedAudit}, - resource_need_audit = #{resourceNeedAudit}, - is_lock_cms = #{isLockCms}, - section_cms_show = #{sectionCmsShow}, - section_project_show = #{sectionProjectShow}, - section_member_show = #{sectionMemberShow}, - section_helper_show = #{sectionHelperShow}, - section_homepage_show = #{sectionHomepageShow}, - section_resource_show = #{sectionResourceShow}, - section_dataset_show = #{sectionDataSetShow}, - section_cms_title = #{sectionCmsTitle}, - section_project_title = #{sectionProjectTitle}, - section_member_title = #{sectionMemberTitle}, - section_helper_title = #{sectionHelperTitle}, - section_homepage_title = #{sectionHomepageTitle}, - section_resource_title = #{sectionResourceTitle}, - section_dataset_title = #{sectionDataSetTitle}, - + + + + insert into zone_detail + + name, + `key`, + dept_id, + del_flag, + create_by, + create_time, + update_by, + update_time, + main_title, + sub_title, + first_title, + banner_list, + introduction_title, + introduction_content, + introduction_image, + homepage_membership_size, + homepage_cms_size, + homepage_project_size, + cms_project_id, + gitlink_project_keys, + cms_show, + project_show, + member_show, + partners_show, + special_project_show, + homepage_special_project_title, + resource_show, + homepage_resource_title, + homepage_cms_title, + homepage_project_title, + homepage_member_title, + homepage_partners_title, + template, + helper_title, + helper_show, + doc_need_audit, + resource_need_audit, + is_lock_cms, + section_cms_show, + section_project_show, + section_member_show, + section_helper_show, + section_homepage_show, + section_resource_show, + section_dataset_show, + section_cms_title, + section_project_title, + section_member_title, + section_helper_title, + section_homepage_title, + section_resource_title, + section_dataset_title, + + + #{name}, + #{key}, + #{deptId}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{mainTitle}, + #{subTitle}, + #{firstTitle}, + #{bannerList}, + #{introductionTitle}, + #{introductionContent}, + #{introductionImage}, + #{homepageMembershipSize}, + #{homepageCmsSize}, + #{homepageProjectSize}, + #{cmsProjectId}, + #{gitlinkProjectKeys}, + #{cmsShow}, + #{projectShow}, + #{memberShow}, + #{partnersShow}, + #{specialProjectShow}, + #{homepageSpecialProjectTitle}, + #{resourceShow}, + #{homepageResourceTitle}, + #{homepageCmsTitle}, + #{homepageProjectTitle}, + #{homepageMemberTitle}, + #{homepagePartnersTitle}, + #{template}, + #{helperTitle}, + #{helperShow}, + #{docNeedAudit}, + #{resourceNeedAudit}, + #{isLockCms}, + #{sectionCmsShow}, + #{sectionProjectShow}, + #{sectionMemberShow}, + #{sectionHelperShow}, + #{sectionHomepageShow}, + #{sectionResourceShow}, + #{sectionDataSetShow}, + #{sectionCmsTitle}, + #{sectionProjectTitle}, + #{sectionMemberTitle}, + #{sectionHelperTitle}, + #{sectionHomepageTitle}, + #{sectionResourceTitle}, + #{sectionDataSetTitle}, + + + + + update zone_detail + + name = #{name}, + `key` = #{key}, + dept_id = #{deptId}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + main_title = #{mainTitle}, + sub_title = #{subTitle}, + first_title = #{firstTitle}, + banner_list = #{bannerList}, + introduction_title = #{introductionTitle}, + introduction_content = #{introductionContent}, + introduction_image = #{introductionImage}, + homepage_membership_size = #{homepageMembershipSize}, + homepage_cms_size = #{homepageCmsSize}, + homepage_project_size = #{homepageProjectSize}, + cms_project_id = #{cmsProjectId}, + gitlink_project_keys = #{gitlinkProjectKeys}, + is_publish = #{isPublish}, + cms_show = #{cmsShow}, + project_show = #{projectShow}, + member_show = #{memberShow}, + partners_show = #{partnersShow}, + special_project_show = #{specialProjectShow}, + homepage_special_project_title = + #{homepageSpecialProjectTitle}, + + resource_show = #{resourceShow}, + homepage_resource_title = + #{homepageResourceTitle}, + + homepage_cms_title = #{homepageCmsTitle}, + homepage_project_title = #{homepageProjectTitle}, + homepage_member_title = #{homepageMemberTitle}, + homepage_partners_title = #{homepagePartnersTitle}, + template = #{template}, + helper_show = #{helperShow}, + helper_title = #{helperTitle}, + doc_need_audit = #{docNeedAudit}, + resource_need_audit = #{resourceNeedAudit}, + is_lock_cms = #{isLockCms}, + section_cms_show = #{sectionCmsShow}, + section_project_show = #{sectionProjectShow}, + section_member_show = #{sectionMemberShow}, + section_helper_show = #{sectionHelperShow}, + section_homepage_show = #{sectionHomepageShow}, + section_resource_show = #{sectionResourceShow}, + section_dataset_show = #{sectionDataSetShow}, + section_cms_title = #{sectionCmsTitle}, + section_project_title = #{sectionProjectTitle}, + section_member_title = #{sectionMemberTitle}, + section_helper_title = #{sectionHelperTitle}, + section_homepage_title = #{sectionHomepageTitle}, + section_resource_title = #{sectionResourceTitle}, + section_dataset_title = #{sectionDataSetTitle}, + - where id = #{id} - + where id = #{id} + - - delete - from zone_detail - where id = #{id} - + + delete + from zone_detail + where id = #{id} + - - delete from zone_detail where id in - - #{id} - - - \ No newline at end of file + + delete from zone_detail where id in + + #{id} + + + \ No newline at end of file From 99c029c59327f6a320a9152f67995623f405a2d8 Mon Sep 17 00:00:00 2001 From: liuhuazhong Date: Fri, 14 Mar 2025 09:22:17 +0800 Subject: [PATCH 42/49] =?UTF-8?q?=E8=BD=AF=E4=BB=B6=E5=B7=A5=E7=A8=8B?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=8E=A5=E5=8F=A3=EF=BC=8C=E7=A7=BB=E8=87=B3?= =?UTF-8?q?OpenController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pms/common/controller/OpenController.java | 24 ++++++++++++ .../SoftwareFactStatisticsController.java | 38 ------------------- 2 files changed, 24 insertions(+), 38 deletions(-) delete mode 100644 microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/common/controller/OpenController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/common/controller/OpenController.java index 6b14dde11..b9a1bedb6 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/common/controller/OpenController.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/common/controller/OpenController.java @@ -3,8 +3,10 @@ package com.microservices.pms.common.controller; import com.microservices.common.core.utils.html.EscapeUtil; import com.microservices.common.core.web.controller.BaseController; import com.microservices.common.core.web.domain.AjaxResult; +import com.microservices.pms.specialArea.service.SoftwareFactStatisticsServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; @@ -23,6 +25,9 @@ public class OpenController extends BaseController { @Value("${http.gitLinkUrl}") public String gitLinkUrl; + @Autowired + private SoftwareFactStatisticsServiceImpl softwareFactStatisticsService; + /** * 查询项目管理企业列表 */ @@ -33,4 +38,23 @@ public class OpenController extends BaseController { (Object) EscapeUtil.removeExtraSlashOfUrl(gitLinkUrl + "/login") ); } + + @ApiOperation(value = "今日工作态势") + @GetMapping("/specialArea/softwareFact/statis/todayWorkSituation") + public AjaxResult todayWorkSituation(){ + return AjaxResult.success(softwareFactStatisticsService.todayWorkSituation()); + } + + @ApiOperation(value = "周、月工作态势") + @GetMapping("/specialArea/softwareFact/statis/weekMonthWorkSituation") + public AjaxResult weekMonthWorkSituation(String type){ + return AjaxResult.success(softwareFactStatisticsService.weekMonthWorkSituation(type)); + } + + @ApiOperation(value = "项目研发状态") + @GetMapping("/specialArea/softwareFact/statis/projectSituation") + public AjaxResult projectSituation(){ + return AjaxResult.success(softwareFactStatisticsService.projectSituation()); + } + } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java deleted file mode 100644 index 90953edcf..000000000 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/controller/SoftwareFactStatisticsController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.microservices.pms.specialArea.controller; - -import com.microservices.common.core.web.domain.AjaxResult; -import com.microservices.pms.specialArea.service.SoftwareFactStatisticsServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController() -@RequestMapping("/specialArea/softwareFact/statis") -@Api(tags = "项目管理-软件工厂统计相关接口") -@RequiredArgsConstructor -public class SoftwareFactStatisticsController { - - private final SoftwareFactStatisticsServiceImpl softwareFactStatisticsService; - - @ApiOperation(value = "今日工作态势") - @GetMapping("/todayWorkSituation") - public AjaxResult todayWorkSituation(){ - return AjaxResult.success(softwareFactStatisticsService.todayWorkSituation()); - } - - @ApiOperation(value = "周、月工作态势") - @GetMapping("/weekMonthWorkSituation") - public AjaxResult weekMonthWorkSituation(String type){ - return AjaxResult.success(softwareFactStatisticsService.weekMonthWorkSituation(type)); - } - - @ApiOperation(value = "项目研发状态") - @GetMapping("/projectSituation") - public AjaxResult projectSituation(){ - return AjaxResult.success(softwareFactStatisticsService.projectSituation()); - } - -} From 509de16d62746d870b9386d9df4f1943aa5f2fb1 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Tue, 18 Mar 2025 10:20:26 +0800 Subject: [PATCH 43/49] =?UTF-8?q?feat(=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=BA=BF=E4=B8=8A=E7=8E=AF=E5=A2=83):=20?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E8=8B=A5=E5=B7=B2=E5=85=B3=E8=81=94=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E4=B8=8D=E5=85=81=E8=AE=B8=E5=8F=96=E6=B6=88=E6=88=96?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../pms/project/service/impl/PmsProjectServiceImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/impl/PmsProjectServiceImpl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/impl/PmsProjectServiceImpl.java index 1208e9350..ab4c215b4 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/impl/PmsProjectServiceImpl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/impl/PmsProjectServiceImpl.java @@ -283,6 +283,12 @@ public class PmsProjectServiceImpl implements IPmsProjectService { Long updatedPmsProjectId = pmsProjectUpdateVo.getId(); PmsProject oldProject = selectAndCheckPmsProjectById(updatedPmsProjectId); PmsUtils.validStartTimeAndEndTime(pmsProjectUpdateVo.getStartTime(), pmsProjectUpdateVo.getEndTime()); + // 项目若已关联产品不允许取消或修改关联 + if (oldProject.getPmsProductId() != null) { + if (!oldProject.getPmsProductId().equals(pmsProjectUpdateVo.getPmsProductId())) { + throw new ServiceException("项目已关联产品,不允许取消或修改关联"); + } + } pmsProjectUpdateVo.setUpdateTime(DateUtils.getNowDate()); int count = pmsProjectMapper.updatePmsProjectByUpdateInput(pmsProjectUpdateVo); From 06bf1c291076e2127e655ce75d8b4bae666f8e0b Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Tue, 18 Mar 2025 14:12:50 +0800 Subject: [PATCH 44/49] =?UTF-8?q?feat(=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=BA=BF=E4=B8=8A=E7=8E=AF=E5=A2=83):=20?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E8=AE=A1=E5=88=92=E9=80=BB=E8=BE=91=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 若项目未关联产品允许新增项目计划 2. 若项目未关联产品允许编辑项目计划 Signed-off-by: OTTO <731554297@qq.com> --- .../controller/PmsProjectIssuesController.java | 6 ------ .../project/service/PmsProjectIssuesService.java | 14 +++++++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java index 23eccf9f5..96e7e686a 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java @@ -2,7 +2,6 @@ package com.microservices.pms.project.controller; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.microservices.common.core.exception.ServiceException; import com.microservices.common.core.web.controller.BaseController; import com.microservices.common.core.web.domain.AjaxResult; import com.microservices.common.core.web.page.GenericsTableDataInfo; @@ -11,7 +10,6 @@ import com.microservices.common.security.annotation.RequiresPermissions; import com.microservices.pms.project.domain.vo.*; import com.microservices.pms.project.service.IPmsProjectTestsheetIssuesService; import com.microservices.pms.project.service.PmsProjectIssuesService; -import com.microservices.pms.utils.PmsConstants; import io.swagger.annotations.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -58,10 +56,6 @@ public class PmsProjectIssuesController extends BaseController { @PostMapping("/add") @ApiOperation(value = "新增项目工作项") public AjaxResult add(@RequestBody PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { - if (PmsConstants.PROJECT_ISSUE_TYPE_REQUIREMENT.equals(String.valueOf(pmsProjectIssuesInputVo.getPmIssueType())) - && pmsProjectIssuesInputVo.getRootId() == null) { - throw new ServiceException("项目计划仅能基于产品需求创建"); - } JSONObject result = pmsProjectIssuesService.insertPmsProjectIssues(pmsProjectIssuesInputVo); return success(result); } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java index f380df1cd..ff1a6cd76 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java @@ -100,14 +100,19 @@ public class PmsProjectIssuesService { } public JSONObject insertPmsProjectIssues(PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { - pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId()); + PmsProject pmsProject = pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId()); + if (pmsProject.getPmsProductId() != null + && PmsConstants.PROJECT_ISSUE_TYPE_REQUIREMENT.equals(String.valueOf(pmsProjectIssuesInputVo.getPmIssueType())) + && pmsProjectIssuesInputVo.getRootId() == null) { + throw new ServiceException("项目计划仅能基于产品需求创建"); + } JSONObject issueInput = convertPmsProjectIssuesInputVoToIssueInputJSON(pmsProjectIssuesInputVo); return gitLinkRequestHelper.doPost(PmsGitLinkRequestUrl.CREATE_ISSUE(), issueInput); } @Transactional(rollbackFor = Exception.class) public JSONObject updatePmsProjectIssues(Long id, PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { - pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId()); + PmsProject pmsProject = pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId()); JSONObject updatedIssue; try { updatedIssue = gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ISSUE(id, pmsProjectIssuesInputVo.getPmProjectId())); @@ -115,7 +120,8 @@ public class PmsProjectIssuesService { throw new RuntimeException(e); } // 项目计划不允许编辑标题、正文和附件 - if (PmsConstants.PROJECT_ISSUE_TYPE_REQUIREMENT.equals(updatedIssue.getString("pm_issue_type")) + if (pmsProject.getPmsProductId() != null + && PmsConstants.PROJECT_ISSUE_TYPE_REQUIREMENT.equals(updatedIssue.getString("pm_issue_type")) && updatedIssue.getString("root_id") == null) { if (pmsProjectIssuesInputVo.isChangeContent(updatedIssue)) { throw new ServiceException("项目计划不允许编辑标题、正文和附件"); @@ -140,8 +146,6 @@ public class PmsProjectIssuesService { } } } - - } if (PmsConstants.PROJECT_ISSUE_TYPE_WEEKLY_REPORT.equals(updatedIssue.getString("pm_issue_type")) && updatedIssue.getString("root_id") != null From 689229801c109590bc4dbeb1b01824969ad6a1e8 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Tue, 18 Mar 2025 17:07:55 +0800 Subject: [PATCH 45/49] =?UTF-8?q?feat(=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=BA=BF=E4=B8=8A=E7=8E=AF=E5=A2=83):=20?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=BB=E5=B9=B2=E5=88=86=E6=94=AF=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../pms/pipeline/service/IPmsCiPipelinesService.java | 2 -- .../com/microservices/pms/utils/PmsGitLinkRequestUrl.java | 5 ----- 2 files changed, 7 deletions(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java index 40dd2f9f0..023b73fa2 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/pipeline/service/IPmsCiPipelinesService.java @@ -104,8 +104,6 @@ public interface IPmsCiPipelinesService JSONObject getPipelineRunResults(Long id, String run); - JSONObject getPipelineRunResults(Long id, String run); - JSONObject getPipelineRubyIdByJavaId(Long javaId); JSONObject getPipelineId(String repoOwner, String repoIdentifier, String fileName); diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java index 588cc470c..0fb7f7861 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/utils/PmsGitLinkRequestUrl.java @@ -439,9 +439,4 @@ public class PmsGitLinkRequestUrl extends GitLinkRequestUrl { public static GitLinkRequestUrl GET_ACTION_RUN_DATA(String owner, String workflows) { return getGitLinkRequestUrl(String.format("/api/pm/action_runs?owner_id=%s&workflows=%s", owner, workflows), "data"); } - - - public static GitLinkRequestUrl GET_PIPELINE_RUN_RESULTS(String owner, String repoIdentifier, String run){ - return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/pipelines/run_results.json?run_id=%s", owner, repoIdentifier, run)); - } } From 729cdb80172e0f86f243f38657667ce945a3227f Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Wed, 19 Mar 2025 10:47:28 +0800 Subject: [PATCH 46/49] =?UTF-8?q?feat(=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=BA=BF=E4=B8=8A=E7=8E=AF=E5=A2=83):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9F=BA=E4=BA=8E=E4=BA=A7=E5=93=81=E9=9C=80?= =?UTF-8?q?=E6=B1=82=E5=88=9B=E5=BB=BA=E9=A1=B9=E7=9B=AE=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../pms/project/controller/PmsProjectIssuesController.java | 2 +- .../pms/project/service/PmsProjectIssuesService.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java index 96e7e686a..c1e4aedf2 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/controller/PmsProjectIssuesController.java @@ -56,7 +56,7 @@ public class PmsProjectIssuesController extends BaseController { @PostMapping("/add") @ApiOperation(value = "新增项目工作项") public AjaxResult add(@RequestBody PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { - JSONObject result = pmsProjectIssuesService.insertPmsProjectIssues(pmsProjectIssuesInputVo); + JSONObject result = pmsProjectIssuesService.insertPmsProjectIssuesRestricted(pmsProjectIssuesInputVo); return success(result); } diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java index ff1a6cd76..0b779aca9 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/project/service/PmsProjectIssuesService.java @@ -99,13 +99,18 @@ public class PmsProjectIssuesService { return issueListResult; } - public JSONObject insertPmsProjectIssues(PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { + public JSONObject insertPmsProjectIssuesRestricted(PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { PmsProject pmsProject = pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId()); if (pmsProject.getPmsProductId() != null && PmsConstants.PROJECT_ISSUE_TYPE_REQUIREMENT.equals(String.valueOf(pmsProjectIssuesInputVo.getPmIssueType())) && pmsProjectIssuesInputVo.getRootId() == null) { throw new ServiceException("项目计划仅能基于产品需求创建"); } + return insertPmsProjectIssues(pmsProjectIssuesInputVo); + } + + public JSONObject insertPmsProjectIssues(PmsProjectIssuesInputVo pmsProjectIssuesInputVo) { + pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId()); JSONObject issueInput = convertPmsProjectIssuesInputVoToIssueInputJSON(pmsProjectIssuesInputVo); return gitLinkRequestHelper.doPost(PmsGitLinkRequestUrl.CREATE_ISSUE(), issueInput); } From 123d967254e8a3cfff2f664a317e57c7bca9a5d2 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Wed, 19 Mar 2025 11:11:19 +0800 Subject: [PATCH 47/49] =?UTF-8?q?feat(=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=BA=BF=E4=B8=8A=E7=8E=AF=E5=A2=83):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=98=E6=9B=B4=E6=97=B6=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=99=84=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/pms/product/domain/PmsProductRequirement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/product/domain/PmsProductRequirement.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/product/domain/PmsProductRequirement.java index ef4480318..dd7da6355 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/product/domain/PmsProductRequirement.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/product/domain/PmsProductRequirement.java @@ -199,7 +199,7 @@ public class PmsProductRequirement extends BaseEntity if (StringUtils.isNotEmpty(productReqSpecsChangeVo.getContent())) { target.setContent(productReqSpecsChangeVo.getContent()); } - if (StringUtils.isNotEmpty(productReqSpecsChangeVo.getFileIdentifiers())) { + if (productReqSpecsChangeVo.getFileIdentifiers() != null) { target.setFileIdentifiers(productReqSpecsChangeVo.getFileIdentifiers()); } return target; From f0e01ecaf6281b96664af9589b1859f055c28494 Mon Sep 17 00:00:00 2001 From: OTTO <731554297@qq.com> Date: Thu, 20 Mar 2025 14:10:32 +0800 Subject: [PATCH 48/49] =?UTF-8?q?feat(=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=BA=BF=E4=B8=8A=E7=8E=AF=E5=A2=83):=20?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E8=AF=B7=E6=B1=82Forge=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: OTTO <731554297@qq.com> --- .../microservices/common/httpClient/service/HttpAPIService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/microservices-common/microservices-common-httpClient/src/main/java/com/microservices/common/httpClient/service/HttpAPIService.java b/microservices-common/microservices-common-httpClient/src/main/java/com/microservices/common/httpClient/service/HttpAPIService.java index 53fd61202..58a2e9503 100644 --- a/microservices-common/microservices-common-httpClient/src/main/java/com/microservices/common/httpClient/service/HttpAPIService.java +++ b/microservices-common/microservices-common-httpClient/src/main/java/com/microservices/common/httpClient/service/HttpAPIService.java @@ -283,6 +283,7 @@ public class HttpAPIService { if (length != 0L) { String result = EntityUtils.toString(httpEntity); if (!JSON.isValid(result)) { + logger.error("平台接口响应格式异常,状态码:{},响应内容:{}", httpStatusCode, result); throw new ServiceException("平台接口响应格式异常"); } Object resultObj = JSON.parse(result); From c0a5ff23fe054888358456fb362ac999589ff354 Mon Sep 17 00:00:00 2001 From: liuhuazhong Date: Tue, 25 Mar 2025 10:16:49 +0800 Subject: [PATCH 49/49] =?UTF-8?q?fix(=E8=BD=AF=E4=BB=B6=E5=B7=A5=E5=8E=82)?= =?UTF-8?q?:=20=E6=9C=80=E5=A4=9A=E7=BC=BA=E9=99=B7=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=9C=80=E5=A4=9A=E7=BC=BA=E9=99=B7=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=B8=AA=E4=BA=BA=EF=BC=9B=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E6=89=A7=E8=A1=8C=E6=95=B0=E7=BB=9F=E8=AE=A1=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/SoftwareFactStatisticsServiceImpl.java | 9 +++++---- .../mapper/pms/PmsProjectTestsheetCasesMapper.xml | 6 ++++++ .../resources/mapper/pms/SoftwareFactStatisPmsMapper.xml | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java index 3f216f91b..0cba35cf5 100644 --- a/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java +++ b/microservices-modules/microservices-modules-pms/src/main/java/com/microservices/pms/specialArea/service/SoftwareFactStatisticsServiceImpl.java @@ -114,7 +114,8 @@ public class SoftwareFactStatisticsServiceImpl extends BaseController { Long bugMaxProjectId = statisForgeMapper.countForgeProjectByProject(f2); ZonePmsProject bugMaxProject = statisPmsMapper.selectPmsProjectById(bugMaxProjectId); res.put("bugMaxProject", bugMaxProject == null ?"": bugMaxProject.getProjectName()); - //缺陷最多个人 + //缺陷解决最多个人 + f2.setStatusIds(ISSUE_FINISHED); Long bugMaxAssignerId = statisForgeMapper.countForgeProjectByAssigner(f2); String bugMaxAssigner = statisPmsMapper.selectPmsUserByGitlinkId(bugMaxAssignerId); res.put("bugMaxAssigner", bugMaxAssigner); @@ -162,9 +163,9 @@ public class SoftwareFactStatisticsServiceImpl extends BaseController { res.put("yesterdayFinishNeed", yesterdayFinishNeed); //昨日测试用例执行 ForgeProject forgeProjectTest = new ForgeProject(); - forgeProjectFinish.setStatusIds(Arrays.asList(TASK_CASE_STATUS_PASS, TASK_CASE_STATUS_FAIL, TASK_CASE_STATUS_BLOCK, TASK_CASE_STATUS_SKIP)); - forgeProjectFinish.setUpdateTimeS(dayStartAndEnd[0]); - forgeProjectFinish.setUpdateTimeE(dayStartAndEnd[1]); + forgeProjectTest.setStatusIds(Arrays.asList(TASK_CASE_STATUS_PASS, TASK_CASE_STATUS_FAIL, TASK_CASE_STATUS_BLOCK, TASK_CASE_STATUS_SKIP)); + forgeProjectTest.setUpdateTimeS(dayStartAndEnd[0]); + forgeProjectTest.setUpdateTimeE(dayStartAndEnd[1]); Long yesterdayTestCase = statisPmsMapper.countTestCaseInSheet(forgeProjectTest); res.put("yesterdayTestCase", yesterdayTestCase); diff --git a/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/PmsProjectTestsheetCasesMapper.xml b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/PmsProjectTestsheetCasesMapper.xml index b6552b4f6..44d6923e5 100644 --- a/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/PmsProjectTestsheetCasesMapper.xml +++ b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/PmsProjectTestsheetCasesMapper.xml @@ -93,6 +93,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" test_status, tester_id, step_status, + create_time, + create_by, #{projectTestsheetId}, @@ -100,6 +102,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{testStatus}, #{testerId}, #{stepStatus}, + #{createTime}, + #{createBy}, @@ -110,6 +114,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" project_testcase_id = #{projectTestcaseId}, test_status = #{testStatus}, step_status = #{stepStatus}, + update_time = #{updateTime}, + update_by = #{updateBy}, tester_id = #{testerId} where id = #{id} diff --git a/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml index 964903987..8b95d63aa 100644 --- a/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml +++ b/microservices-modules/microservices-modules-pms/src/main/resources/mapper/pms/SoftwareFactStatisPmsMapper.xml @@ -46,10 +46,10 @@ select id from pms_project_testsheet where pms_project_id = #{pmProjectId} ) - and created_on >= #{createTimeS} - and created_on <= #{createTimeE} - and updated_on >= #{updateTimeS} - and updated_on <= #{updateTimeE} + and create_time >= #{createTimeS} + and create_time <= #{createTimeE} + and update_time >= #{updateTimeS} + and update_time <= #{updateTimeE}