From e071d36a3fd933a8ffd49976020c06b3a2630068 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=88=98=E6=B4=AA=E9=9D=92?= Date: Fri, 16 Aug 2019 09:39:49 +0800 Subject: [PATCH] =?utf8?q?feat:=20=E5=BA=94=E7=94=A8=E5=BC=80=E5=8F=91?= =?utf8?q?=E5=90=8E=E7=AB=AF=E5=9F=BA=E7=A1=80=E6=A1=86=E6=9E=B6=EF=BC=8C?= =?utf8?q?=E5=88=9D=E5=A7=8B=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- bff/admin/Dockerfile | 21 + bff/admin/pom.xml | 247 +++++++++++ .../backend/admin/bff/Application.java | 49 +++ .../admin/bff/apis/controller/.gitkeep | 0 .../controller/biz/AdminBizController.java | 17 + .../system/AdminSystemController.java | 17 + .../backend/admin/bff/apis/remote/.gitkeep | 0 .../backend/admin/bff/apis/service/.gitkeep | 0 .../backend/admin/bff/apis/vo/.gitkeep | 0 .../FeignBasicAuthRequestInterceptor.java | 77 ++++ .../configuration/GatewayFilterConfig.java | 16 + .../bff/configuration/GlobalFilterConfig.java | 16 + ...InfrasFilterSecurityInterceptorConfig.java | 53 +++ .../bff/configuration/ListenerConfig.java | 27 ++ .../configuration/PasswordEncoderConfig.java | 29 ++ .../UserDetailsServiceConfig.java | 31 ++ .../SimpleUserTransmitGlobalFilter.java | 60 +++ ...impleUserTransmitGatewayFilterFactory.java | 93 +++++ .../bff/gateway/route/CustomRouteLocator.java | 17 + ...SecurityMetadataSourceRefreshListener.java | 59 +++ .../InMemeryUserDetailsService.java | 72 ++++ .../bff/security/core/userdetails/MyUser.java | 60 +++ .../userdetails/MyUserDetailsService.java | 79 ++++ .../web/access/MyAccessDecisionManager.java | 48 +++ ...ilterInvocationSecurityMetadataSource.java | 76 ++++ ...ilterInvocationSecurityMetadataSource.java | 129 ++++++ .../MyFilterSecurityInterceptor.java | 78 ++++ .../admin/bff/utils/AuthenticationUtil.java | 91 +++++ .../src/main/resources/application-docker.yml | 81 ++++ bff/admin/src/main/resources/application.yml | 114 ++++++ bff/admin/src/main/resources/bootstrap.yml | 3 + bff/pom.xml | 35 ++ biz/api/pom.xml | 111 +++++ .../api/v1/admin/AdminHelloController.java | 26 ++ biz/domain/pom.xml | 102 +++++ biz/pom.xml | 36 ++ common/core/pom.xml | 74 ++++ .../annotation/EnableSimpleUserTransmit.java | 19 + .../SimpleUserTransmitAutoConfiguration.java | 27 ++ .../SimpleUserTransmitRequestInterceptor.java | 31 ++ .../filter/SimpleUserTransmitFilter.java | 55 +++ .../common/core/transmit/user/User.java | 17 + .../core/transmit/user/UserContext.java | 21 + common/framework/pom.xml | 80 ++++ .../common/framework/entity/ABaseEntity.java | 79 ++++ .../common/framework/entity/EntityUtils.java | 199 +++++++++ .../framework/exception/BaseException.java | 66 +++ .../common/framework/modal/ABaseModal.java | 10 + .../common/framework/modal/IModal.java | 7 + .../rabbitmq/constants/ExchangeNames.java | 13 + .../rabbitmq/constants/QueueNames.java | 21 + .../rabbitmq/constants/RoutingKeys.java | 20 + .../repo/ABaseJpaRepositoryImpl.java | 92 +++++ .../framework/repo/BaseJpaRepository.java | 123 ++++++ .../IgnoreCaseResultTransformer.java | 72 ++++ .../framework/service/ABaseService.java | 42 ++ .../vo/request/IApiCreateRequest.java | 5 + .../framework/vo/request/IApiLoadRequest.java | 9 + .../vo/request/IApiQueryRequest.java | 27 ++ .../vo/request/IApiRemoveRequest.java | 10 + .../framework/vo/request/IApiRequest.java | 7 + .../vo/request/IApiUpdateRequest.java | 9 + .../vo/response/AbstractApiResponse.java | 37 ++ .../vo/response/DefaultApiResponse.java | 59 +++ .../framework/vo/response/IApiResponse.java | 20 + .../response/data/IApiCreateResponseData.java | 7 + .../response/data/IApiLoadResponseData.java | 7 + .../response/data/IApiQueryResponseData.java | 58 +++ .../response/data/IApiRemoveResponseData.java | 7 + .../vo/response/data/IApiResponseData.java | 7 + .../response/data/IApiUpdateResponseData.java | 7 + common/pom.xml | 37 ++ common/utils/pom.xml | 68 +++ .../backend/common/util/DateUtil.java | 45 ++ .../backend/common/util/MapBeanUtils.java | 226 ++++++++++ .../backend/common/util/ReflectUtils.java | 386 ++++++++++++++++++ .../backend/common/util/UUIDUtils.java | 87 ++++ pom.xml | 204 +++++++++ sa/admin/Dockerfile | 21 + sa/admin/pom.xml | 201 +++++++++ .../backend/admin/sa/Application.java | 45 ++ .../sa/configuration/Swagger2Config.java | 63 +++ .../src/main/resources/application-docker.yml | 46 +++ sa/admin/src/main/resources/application.yml | 48 +++ sa/admin/src/main/resources/bootstrap.yml | 3 + sa/pom.xml | 35 ++ system/api/pom.xml | 111 +++++ .../api/v1/admin/AdminAccountController.java | 5 + .../api/v1/admin/AdminConfigController.java | 197 +++++++++ .../api/v1/admin/AdminFunctionController.java | 5 + .../api/v1/admin/AdminResourceController.java | 5 + .../api/v1/admin/AdminRoleController.java | 5 + system/domain/pom.xml | 102 +++++ .../backend/system/domain/entity/Config.java | 80 ++++ .../domain/exception/ConfigException.java | 12 + .../system/domain/repo/ConfigRepository.java | 77 ++++ .../system/domain/service/ConfigService.java | 26 ++ .../vo/request/ConfigCreateRequest.java | 21 + .../domain/vo/request/ConfigQueryRequest.java | 40 ++ .../vo/request/ConfigUpdateRequest.java | 29 ++ .../vo/response/ConfigCreateResponseData.java | 32 ++ .../vo/response/ConfigLoadResponseData.java | 34 ++ .../vo/response/ConfigQueryResponseData.java | 83 ++++ .../vo/response/ConfigRemoveResponseData.java | 36 ++ .../vo/response/ConfigUpdateResponseData.java | 33 ++ system/pom.xml | 36 ++ 106 files changed, 5798 insertions(+) create mode 100644 bff/admin/Dockerfile create mode 100644 bff/admin/pom.xml create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/.gitkeep create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/biz/AdminBizController.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/system/AdminSystemController.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/.gitkeep create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/service/.gitkeep create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/vo/.gitkeep create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GatewayFilterConfig.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GlobalFilterConfig.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/ListenerConfig.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/PasswordEncoderConfig.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/UserDetailsServiceConfig.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/SimpleUserTransmitGlobalFilter.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/factory/SimpleUserTransmitGatewayFilterFactory.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/route/CustomRouteLocator.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/listener/MyFilterInvocationSecurityMetadataSourceRefreshListener.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/InMemeryUserDetailsService.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUser.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUserDetailsService.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/MyAccessDecisionManager.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/InMemeryFilterInvocationSecurityMetadataSource.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterInvocationSecurityMetadataSource.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java create mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/AuthenticationUtil.java create mode 100644 bff/admin/src/main/resources/application-docker.yml create mode 100644 bff/admin/src/main/resources/application.yml create mode 100644 bff/admin/src/main/resources/bootstrap.yml create mode 100644 bff/pom.xml create mode 100644 biz/api/pom.xml create mode 100644 biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java create mode 100644 biz/domain/pom.xml create mode 100644 biz/pom.xml create mode 100644 common/core/pom.xml create mode 100644 common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java create mode 100644 common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java create mode 100644 common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java create mode 100644 common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java create mode 100644 common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java create mode 100644 common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java create mode 100644 common/framework/pom.xml create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/service/ABaseService.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java create mode 100644 common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java create mode 100644 common/pom.xml create mode 100644 common/utils/pom.xml create mode 100644 common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java create mode 100644 common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java create mode 100644 common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java create mode 100644 common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java create mode 100644 pom.xml create mode 100644 sa/admin/Dockerfile create mode 100644 sa/admin/pom.xml create mode 100644 sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java create mode 100644 sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java create mode 100644 sa/admin/src/main/resources/application-docker.yml create mode 100644 sa/admin/src/main/resources/application.yml create mode 100644 sa/admin/src/main/resources/bootstrap.yml create mode 100644 sa/pom.xml create mode 100644 system/api/pom.xml create mode 100644 system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminAccountController.java create mode 100644 system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminConfigController.java create mode 100644 system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminFunctionController.java create mode 100644 system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminResourceController.java create mode 100644 system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminRoleController.java create mode 100644 system/domain/pom.xml create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/entity/Config.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/exception/ConfigException.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/repo/ConfigRepository.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/service/ConfigService.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigCreateRequest.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigQueryRequest.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigUpdateRequest.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigCreateResponseData.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigLoadResponseData.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigQueryResponseData.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigRemoveResponseData.java create mode 100644 system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigUpdateResponseData.java create mode 100644 system/pom.xml diff --git a/bff/admin/Dockerfile b/bff/admin/Dockerfile new file mode 100644 index 0000000..4810f6b --- /dev/null +++ b/bff/admin/Dockerfile @@ -0,0 +1,21 @@ +FROM harbor.supwisdom.com/institute/openjdk:8-jre + +ENV ENABLE_JMX_SSL=false +ENV JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker +ENV SPRING_PROFILES_ACTIVE=docker + +ARG NAME +ARG VERSION +ARG JAR_FILE + +LABEL name=$NAME \ + version=$VERSION + +EXPOSE 8080 + +EXPOSE 8443 + +COPY --chown=java-app:java-app target/${JAR_FILE} /home/java-app/lib/app.jar + +COPY --chown=java-app:java-app target/doc /home/java-app/doc +COPY --chown=java-app:java-app target/api-docs /home/java-app/api-docs diff --git a/bff/admin/pom.xml b/bff/admin/pom.xml new file mode 100644 index 0000000..5bc267a --- /dev/null +++ b/bff/admin/pom.xml @@ -0,0 +1,247 @@ + + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-admin-bff + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework Admin Backend for Frontend + Supwisdom Backend Framework Admin Backend for Frontend project + + + com.supwisdom.institute.admin.bff.Application + + + + + + org.projectlombok + lombok + provided + + + + javax.servlet + javax.servlet-api + provided + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + + + + + + + com.supwisdom.infras + infras-security + + + org.springframework.boot + spring-boot-starter-web + + + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + org.springframework.security + spring-security-cas + + + + + com.supwisdom.institute + sw-backend-common-framework + + + + + com.alibaba + fastjson + + + + org.apache.httpcomponents + httpclient + + + + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + + + + org.springframework.boot + spring-boot-devtools + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + com.spotify + dockerfile-maven-plugin + + false + + + + + + + + diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java new file mode 100644 index 0000000..364ed0b --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java @@ -0,0 +1,49 @@ +package com.supwisdom.institute.backend.admin.bff; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +//import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Bean; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +//import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc; +import com.supwisdom.infras.security.configure.basic.EnableInfrasBasicApi; +import com.supwisdom.infras.security.configure.cas.EnableInfrasCasSecurity; +import com.supwisdom.infras.security.configure.jwt.EnableInfrasJWTApi; +import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit; + +@SpringBootApplication +//@EnableFeignClients + +@EnableSimpleUserTransmit + +//@EnableInfrasOnlineDoc + +@EnableInfrasCasSecurity + +@EnableInfrasBasicApi +@EnableInfrasJWTApi +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public CorsFilter corsFilter() { + final CorsConfiguration config = new CorsConfiguration(); + //config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/v2/api-docs", config); + source.registerCorsConfiguration("/api/**", config); // 对 /api/** 下的请求,支持 cors 跨域请求,如不需要可以注释 + + return new CorsFilter(source); + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/.gitkeep b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/biz/AdminBizController.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/biz/AdminBizController.java new file mode 100644 index 0000000..68bd37a --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/biz/AdminBizController.java @@ -0,0 +1,17 @@ +package com.supwisdom.institute.backend.admin.bff.apis.controller.biz; + +import org.springframework.util.MimeTypeUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/api/bff/v1/admin/biz") +public class AdminBizController { + + @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + public String biz() { + return "biz"; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/system/AdminSystemController.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/system/AdminSystemController.java new file mode 100644 index 0000000..84d0f3a --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/controller/system/AdminSystemController.java @@ -0,0 +1,17 @@ +package com.supwisdom.institute.backend.admin.bff.apis.controller.system; + +import org.springframework.util.MimeTypeUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/api/bff/v1/admin/system") +public class AdminSystemController { + + @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + public String hello() { + return "hello"; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/.gitkeep b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/service/.gitkeep b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/service/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/vo/.gitkeep b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/vo/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java new file mode 100644 index 0000000..2a22b46 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java @@ -0,0 +1,77 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.util.*; + +/** + * feign请求参数转化 + * @author fengpy + */ +@Configuration +public class FeignBasicAuthRequestInterceptor implements RequestInterceptor { + @Autowired + private ObjectMapper objectMapper; + + public FeignBasicAuthRequestInterceptor() {} + + @Override + public void apply(RequestTemplate template) { + ///**get-pojo贯穿*/ + if (template.method().equals("GET") && template.request().body() != null) { + try { + JsonNode jsonNode = objectMapper.readTree(template.request().body()); + //template.body(null); + Map> queries = new HashMap<>(); + //feign 不支持 GET 方法传 POJO, json body转query + buildQuery(jsonNode, "", queries); + template.queries(queries); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + //处理 get-pojo贯穿 + private void buildQuery(JsonNode jsonNode, String path, Map> queries) { + if (!jsonNode.isContainerNode()) { //叶子节点 + if (jsonNode.isNull()) { + return; + } + Collection values = queries.get(path); + if (null == values) { + values = new ArrayList<>(); + queries.put(path, values); + } + values.add(jsonNode.asText()); + return; + } + if (jsonNode.isArray()) { //数组节点 + Iterator it = jsonNode.elements(); + while (it.hasNext()) { + buildQuery(it.next(), path, queries); + } + } else { + Iterator> it = jsonNode.fields(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + if (StringUtils.hasText(path)) { + if ("mapBean".equals(path)||"orderBy".equals(path)||"sequence".equals(path)) { + buildQuery(entry.getValue(), path + "[" + entry.getKey() + "]", queries); + } else { + buildQuery(entry.getValue(), path + "." + entry.getKey(), queries); + } + } else { //根节点 + buildQuery(entry.getValue(), entry.getKey(), queries); + } + } + } + } +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GatewayFilterConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GatewayFilterConfig.java new file mode 100644 index 0000000..f475158 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GatewayFilterConfig.java @@ -0,0 +1,16 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.supwisdom.institute.backend.admin.bff.gateway.filter.factory.SimpleUserTransmitGatewayFilterFactory; + +@Configuration +public class GatewayFilterConfig { + + @Bean + public SimpleUserTransmitGatewayFilterFactory simpleUserTransmitGatewayFilterFactory() { + return new SimpleUserTransmitGatewayFilterFactory(); + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GlobalFilterConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GlobalFilterConfig.java new file mode 100644 index 0000000..e9e6282 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/GlobalFilterConfig.java @@ -0,0 +1,16 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.supwisdom.institute.backend.admin.bff.gateway.filter.SimpleUserTransmitGlobalFilter; + +@Configuration +public class GlobalFilterConfig { + + @Bean + public SimpleUserTransmitGlobalFilter simpleUserTransmitGlobalFilter() { + return new SimpleUserTransmitGlobalFilter(); + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java new file mode 100644 index 0000000..6c77526 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java @@ -0,0 +1,53 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; + +import com.supwisdom.infras.security.web.access.intercept.InfrasFilterSecurityInterceptor; +import com.supwisdom.institute.backend.admin.bff.security.web.access.MyAccessDecisionManager; +import com.supwisdom.institute.backend.admin.bff.security.web.access.intercept.InMemeryFilterInvocationSecurityMetadataSource; +import com.supwisdom.institute.backend.admin.bff.security.web.access.intercept.MyFilterSecurityInterceptor; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +public class InfrasFilterSecurityInterceptorConfig { + +// @Bean +// public FilterInvocationSecurityMetadataSource securityMetadataSource() { +// MyFilterInvocationSecurityMetadataSource securityMetadataSource = new MyFilterInvocationSecurityMetadataSource(); +// log.debug("InfrasFilterSecurityInterceptorConfig securityMetadataSource is {}", securityMetadataSource); +// +// return securityMetadataSource; +// } + + @Bean + public FilterInvocationSecurityMetadataSource securityMetadataSource() { + InMemeryFilterInvocationSecurityMetadataSource securityMetadataSource = new InMemeryFilterInvocationSecurityMetadataSource(); + log.debug("InfrasFilterSecurityInterceptorConfig securityMetadataSource is {}", securityMetadataSource); + + return securityMetadataSource; + } + + + @Bean + public AccessDecisionManager accessDecisionManager() { + MyAccessDecisionManager accessDecisionManager = new MyAccessDecisionManager(); + log.debug("InfrasFilterSecurityInterceptorConfig accessDecisionManager is {}", accessDecisionManager); + + return accessDecisionManager; + } + + @Bean + public InfrasFilterSecurityInterceptor infrasFilterSecurityInterceptor() throws Exception { + MyFilterSecurityInterceptor myFilterSecurityInterceptor = new MyFilterSecurityInterceptor(); + myFilterSecurityInterceptor.setRejectPublicInvocations(true); + log.debug("InfrasFilterSecurityInterceptorConfig infrasFilterSecurityInterceptor is {}", myFilterSecurityInterceptor); + + return myFilterSecurityInterceptor; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/ListenerConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/ListenerConfig.java new file mode 100644 index 0000000..3f94d53 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/ListenerConfig.java @@ -0,0 +1,27 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; + +import com.supwisdom.institute.backend.admin.bff.listener.MyFilterInvocationSecurityMetadataSourceRefreshListener; + +@Configuration +public class ListenerConfig { + + @Autowired + private FilterInvocationSecurityMetadataSource securityMetadataSource; + + @Bean + public ServletListenerRegistrationBean serssionListenerBean(){ + MyFilterInvocationSecurityMetadataSourceRefreshListener listener = new MyFilterInvocationSecurityMetadataSourceRefreshListener(); + listener.setSecurityMetadataSource(securityMetadataSource); + + ServletListenerRegistrationBean refreshListener = + new ServletListenerRegistrationBean(listener); + return refreshListener; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/PasswordEncoderConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/PasswordEncoderConfig.java new file mode 100644 index 0000000..b44d152 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/PasswordEncoderConfig.java @@ -0,0 +1,29 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +public class PasswordEncoderConfig { + + @Bean + public PasswordEncoder passwordEncoder() { + + PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + + if (passwordEncoder instanceof DelegatingPasswordEncoder) { + ((DelegatingPasswordEncoder)passwordEncoder).setDefaultPasswordEncoderForMatches(NoOpPasswordEncoder.getInstance()); + } + + log.debug("PasswordEncoderConfig passwordEncoder is {}", passwordEncoder); + return passwordEncoder; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/UserDetailsServiceConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/UserDetailsServiceConfig.java new file mode 100644 index 0000000..63945f4 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/UserDetailsServiceConfig.java @@ -0,0 +1,31 @@ +package com.supwisdom.institute.backend.admin.bff.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.supwisdom.institute.backend.admin.bff.security.core.userdetails.InMemeryUserDetailsService; +import com.supwisdom.institute.backend.admin.bff.security.core.userdetails.MyUserDetailsService; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +public class UserDetailsServiceConfig { + +// @Bean +// public MyUserDetailsService userDetailsService() throws Exception { +// MyUserDetailsService myUserDetailsService = new MyUserDetailsService(); +// log.debug("UserDetailsServiceConfig myUserDetailsService is {}", myUserDetailsService); +// +// return myUserDetailsService; +// } + + @Bean + public InMemeryUserDetailsService userDetailsService() throws Exception { + InMemeryUserDetailsService inMemeryUserDetailsService = new InMemeryUserDetailsService(); + log.debug("UserDetailsServiceConfig inMemeryUserDetailsService is {}", inMemeryUserDetailsService); + + return inMemeryUserDetailsService; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/SimpleUserTransmitGlobalFilter.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/SimpleUserTransmitGlobalFilter.java new file mode 100644 index 0000000..a9bf2ae --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/SimpleUserTransmitGlobalFilter.java @@ -0,0 +1,60 @@ +package com.supwisdom.institute.backend.admin.bff.gateway.filter; + +import java.net.URLDecoder; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.web.server.ServerWebExchange; + +import com.alibaba.fastjson.JSONObject; +import com.supwisdom.institute.backend.admin.bff.security.core.userdetails.MyUser; +import com.supwisdom.institute.backend.common.core.transmit.user.User; +import com.supwisdom.institute.backend.common.core.transmit.user.UserContext; + +import reactor.core.publisher.Mono; + +@Slf4j +public class SimpleUserTransmitGlobalFilter implements GlobalFilter, Ordered { + + @Override + public int getOrder() { + return 0; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + + return ReactiveSecurityContextHolder.getContext() + .filter(c -> c.getAuthentication() != null && c.getAuthentication().isAuthenticated() && c.getAuthentication().getPrincipal() instanceof MyUser) + .map(SecurityContext::getAuthentication) + .map(Authentication::getPrincipal) + .cast(MyUser.class) + .map(myUser -> { + try { + User user = new User(myUser.getUsername(), myUser.getRoles(), myUser.getAttributes()); + + String jsonUser = JSONObject.toJSONString(user); + log.info(jsonUser); + String headerValue = new String(URLDecoder.decode(jsonUser,"UTF-8")); + ServerHttpRequest request = exchange.getRequest().mutate() + .header(UserContext.KEY_USER_IN_HTTP_HEADER, headerValue) + .build(); + log.debug("User set ok"); + return exchange.mutate().request(request).build(); + } catch (Exception e) { + log.warn("User set error", e); + } + return exchange; + }) + .flatMap(ex -> chain.filter(ex)) + ; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/factory/SimpleUserTransmitGatewayFilterFactory.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/factory/SimpleUserTransmitGatewayFilterFactory.java new file mode 100644 index 0000000..6d0d981 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/filter/factory/SimpleUserTransmitGatewayFilterFactory.java @@ -0,0 +1,93 @@ +package com.supwisdom.institute.backend.admin.bff.gateway.filter.factory; + +import java.net.URLDecoder; + +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.security.core.context.SecurityContext; + +import com.alibaba.fastjson.JSONObject; +import com.supwisdom.institute.backend.admin.bff.security.core.userdetails.MyUser; +import com.supwisdom.institute.backend.common.core.transmit.user.User; +import com.supwisdom.institute.backend.common.core.transmit.user.UserContext; + +@Slf4j +public class SimpleUserTransmitGatewayFilterFactory extends AbstractGatewayFilterFactory { + + public SimpleUserTransmitGatewayFilterFactory() { + super(Config.class); + } + + @Override + public GatewayFilter apply(Config config) { + return (exchange, chain) -> { + + +// Mono m = Mono.fromCallable(() ->{ +// MyUser myUser = ReactiveSecurityContextHolder.getContext() +// .filter(c -> c.getAuthentication() != null) +// .map(SecurityContext::getAuthentication) +// .map(Authentication::getPrincipal) +// .cast(MyUser.class) +// .block() +// ; +// try { +// String jsonUser = JSONObject.toJSONString(myUser); +// log.info(jsonUser); +// String headerValue = new String(URLDecoder.decode(jsonUser,"UTF-8")); +// ServerHttpRequest request = exchange.getRequest().mutate() +// .header(UserContext.KEY_USER_IN_HTTP_HEADER, headerValue) +// .build(); +// log.debug("User set ok"); +// return exchange.mutate().request(request).build(); +// } catch (Exception e) { +// log.warn("User set error", e); +// } +// return exchange; +// }) +// .publishOn(Schedulers.elastic()) +// ; +// return m.flatMap(ex -> chain.filter(ex)); + + + return ReactiveSecurityContextHolder.getContext() + .filter(c -> c.getAuthentication() != null && c.getAuthentication().isAuthenticated() && c.getAuthentication().getPrincipal() instanceof MyUser) + .map(SecurityContext::getAuthentication) + .map(Authentication::getPrincipal) + .cast(MyUser.class) + .map(myUser -> { + try { + User user = new User(myUser.getUsername(), myUser.getRoles(), myUser.getAttributes()); + + String jsonUser = JSONObject.toJSONString(user); + log.info(jsonUser); + String headerValue = new String(URLDecoder.decode(jsonUser,"UTF-8")); + ServerHttpRequest request = exchange.getRequest().mutate() + .header(UserContext.KEY_USER_IN_HTTP_HEADER, headerValue) + .build(); + log.debug("User set ok"); + return exchange.mutate().request(request).build(); + } catch (Exception e) { + log.warn("User set error", e); + } + return exchange; + }) + .flatMap(ex -> chain.filter(ex)) + ; + }; + } + + public static class Config { + @Getter + @Setter + private String a; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/route/CustomRouteLocator.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/route/CustomRouteLocator.java new file mode 100644 index 0000000..fc90c15 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/gateway/route/CustomRouteLocator.java @@ -0,0 +1,17 @@ +package com.supwisdom.institute.backend.admin.bff.gateway.route; + +import org.springframework.cloud.gateway.route.Route; +import org.springframework.cloud.gateway.route.RouteLocator; + +import reactor.core.publisher.Flux; + +public class CustomRouteLocator implements RouteLocator { + + @Override + public Flux getRoutes() { + // TODO Auto-generated method stub + return null; + } + + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/listener/MyFilterInvocationSecurityMetadataSourceRefreshListener.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/listener/MyFilterInvocationSecurityMetadataSourceRefreshListener.java new file mode 100644 index 0000000..2c6d2bd --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/listener/MyFilterInvocationSecurityMetadataSourceRefreshListener.java @@ -0,0 +1,59 @@ +package com.supwisdom.institute.backend.admin.bff.listener; + +import java.util.Timer; +import java.util.TimerTask; + +import javax.servlet.ServletContextEvent; + +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; +import org.springframework.web.context.ContextLoaderListener; + +import com.supwisdom.institute.backend.admin.bff.security.web.access.intercept.MyFilterInvocationSecurityMetadataSource; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MyFilterInvocationSecurityMetadataSourceRefreshListener extends ContextLoaderListener { + + private FilterInvocationSecurityMetadataSource securityMetadataSource; + public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) { + this.securityMetadataSource = securityMetadataSource; + } + + private Timer timer = null; + + private int delay = 1; // 启动后,延迟1分钟 + private int period = 2; // 定时,每隔2分钟 + + @Override + public void contextInitialized(ServletContextEvent event) { + // super.contextInitialized(event); + log.info("MyFilterInvocationSecurityMetadataSourceRefreshListener.contextInitialized"); + + if (securityMetadataSource instanceof MyFilterInvocationSecurityMetadataSource) { + timer = new Timer("定时刷新权限信息", true); + + timer.scheduleAtFixedRate(new TimerTask() { + + @Override + public void run() { + ((MyFilterInvocationSecurityMetadataSource) securityMetadataSource).refreshRequestMap(); + } + + }, 1000 * 60 * delay, 1000 * 60 * period); + + } + + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + // super.contextDestroyed(event); + log.info("MyFilterInvocationSecurityMetadataSourceRefreshListener.contextDestroyed"); + + if (timer != null) { + timer.cancel(); + } + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/InMemeryUserDetailsService.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/InMemeryUserDetailsService.java new file mode 100644 index 0000000..bfe9a21 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/InMemeryUserDetailsService.java @@ -0,0 +1,72 @@ +package com.supwisdom.institute.backend.admin.bff.security.core.userdetails; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.ReactiveUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +import com.supwisdom.institute.backend.common.core.transmit.user.User; +import com.supwisdom.institute.backend.common.core.transmit.user.UserContext; + +import reactor.core.publisher.Mono; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class InMemeryUserDetailsService implements UserDetailsService, ReactiveUserDetailsService { + + @Autowired + PasswordEncoder passwordEncoder; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + + log.debug("InMemeryUserDetailsService.loadUserByUsername({})", username); + + List authorities = new ArrayList(); + authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); + authorities.add(new SimpleGrantedAuthority("administrator")); + authorities.add(new SimpleGrantedAuthority("user")); + + Map attributes = new HashMap(); + + MyUser myUser = new MyUser(username, passwordEncoder.encode(username), authorities, attributes); + log.debug("myUser is {}", myUser); + + return myUser; + } + + @Override + public Mono findByUsername(String username) { + + log.debug("InMemeryUserDetailsService.findByUsername({})", username); + + List authorities = new ArrayList(); + authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); + authorities.add(new SimpleGrantedAuthority("administrator")); + authorities.add(new SimpleGrantedAuthority("user")); + + Map attributes = new HashMap(); + + MyUser myUser = new MyUser(username, passwordEncoder.encode(username), authorities, attributes); + log.debug("myUser is {}", myUser); + + List roles = new ArrayList<>(); + roles.add("ROLE_ADMIN"); + roles.add("administrator"); + roles.add("user"); + User user = new User(username, roles, attributes); + UserContext.setUser(user); + + return Mono.just(myUser); + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUser.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUser.java new file mode 100644 index 0000000..b662422 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUser.java @@ -0,0 +1,60 @@ +package com.supwisdom.institute.backend.admin.bff.security.core.userdetails; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; + +public class MyUser extends User { + + /** + * + */ + private static final long serialVersionUID = 3195151947212484499L; + + public MyUser(String username, String password, + Collection authorities, + Map attributes) { + this(username, password, true, true, true, true, authorities, attributes); + } + + public MyUser(String username, String password, + boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, + Collection authorities, + Map attributes) { + super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + + this.attributes = attributes; + } + + private final Map attributes; + public Map getAttributes() { + return this.attributes; + } + + public List getRoles() { + List roles = new ArrayList<>(); + for (GrantedAuthority grantedAuthority : this.getAuthorities()) { + roles.add(grantedAuthority.getAuthority()); + } + + return roles; + } + + + public Object getAttribute(String key) { + if (attributes == null) { + return null; + } + + if (!attributes.containsKey(key)) { + return null; + } + + return attributes.get(key); + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUserDetailsService.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUserDetailsService.java new file mode 100644 index 0000000..110af6b --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/core/userdetails/MyUserDetailsService.java @@ -0,0 +1,79 @@ +package com.supwisdom.institute.backend.admin.bff.security.core.userdetails; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.ReactiveUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +import reactor.core.publisher.Mono; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MyUserDetailsService implements UserDetailsService, ReactiveUserDetailsService { + + @Autowired + PasswordEncoder passwordEncoder; + +// @Autowired +// AccountService accountService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO: + + log.debug("MyUserDetailsService.loadUserByUsername({})", username); + +// Account account = accountService.loadByUsername(username); +// if (account == null) { +// throw new UsernameNotFoundException(String.format("%s not found", username)); +// } +// +// List authorities = new ArrayList(); +//// for (Role role : securityUser.getRoles()) { +//// authorities.add(new SimpleGrantedAuthority(role.getCode())); +//// } +// // FIXME: +// authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); +// authorities.add(new SimpleGrantedAuthority("administrator")); +// authorities.add(new SimpleGrantedAuthority("user")); +// +// Map attributes = new HashMap(); +// attributes.put("userId", account.getUser().getId()); +// attributes.put("userUid", account.getUser().getUid()); +// +// MyUser myUser = new MyUser( +// account.getAccountName(), +// account.getUser().getPassWord(), +// account.getActivation() && "Normal".equals(account.getState()) ? true : false, +// account.getAccountExpiryDate() == null || Calendar.getInstance().getTime().before(account.getAccountExpiryDate()) ? true : false, +// true, +// true, +// authorities, +// attributes); +// +// log.debug("myUser is {}", myUser); + + MyUser myUser = null; + + return myUser; + } + + @Override + public Mono findByUsername(String username) { + log.debug("MyUserDetailsService.findByUsername({})", username); + + MyUser myUser = null; + + return Mono.just(myUser); + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/MyAccessDecisionManager.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/MyAccessDecisionManager.java new file mode 100644 index 0000000..56fe469 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/MyAccessDecisionManager.java @@ -0,0 +1,48 @@ +package com.supwisdom.institute.backend.admin.bff.security.web.access; + +import java.util.Collection; +import java.util.Iterator; + +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.authentication.InsufficientAuthenticationException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; + +public class MyAccessDecisionManager implements AccessDecisionManager { + + @Override + public void decide(Authentication authentication, Object object, Collection configAttributes) + throws AccessDeniedException, InsufficientAuthenticationException { + + if (null == configAttributes || configAttributes.size() <= 0) { + return; + } + + ConfigAttribute ca; + String needRole; + for (Iterator iter = configAttributes.iterator(); iter.hasNext();) { + ca = iter.next(); + needRole = ca.getAttribute(); + for (GrantedAuthority ga : authentication.getAuthorities()) { // authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合 + if (needRole.trim().equals(ga.getAuthority())) { + return; + } + } + } + + throw new AccessDeniedException("no right"); + } + + @Override + public boolean supports(ConfigAttribute attribute) { + return true; + } + + @Override + public boolean supports(Class clazz) { + return true; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/InMemeryFilterInvocationSecurityMetadataSource.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/InMemeryFilterInvocationSecurityMetadataSource.java new file mode 100644 index 0000000..5666b1a --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/InMemeryFilterInvocationSecurityMetadataSource.java @@ -0,0 +1,76 @@ +package com.supwisdom.institute.backend.admin.bff.security.web.access.intercept; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.SecurityConfig; +import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +public class InMemeryFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { + + private Map> requestMap = null; + + private void loadRequestMap() { + if (requestMap == null) { + requestMap = new LinkedHashMap>(); + + AntPathRequestMatcher requestMatcher0 = new AntPathRequestMatcher("/api/**"); + Collection attributes0 = new ArrayList(); // FIXME: 返回当前请求的url 对应的 角色代码 + attributes0.add(new SecurityConfig("user")); + requestMap.put(requestMatcher0, attributes0); + + + AntPathRequestMatcher requestMatcher = new AntPathRequestMatcher("/web/**"); + Collection attributes = new ArrayList(); // FIXME: 返回当前请求的url 对应的 角色代码 + attributes.add(new SecurityConfig("user")); + requestMap.put(requestMatcher, attributes); + } + } + + /** + * 获取当前请求关联的所有角色code {@link SecurityConfig} + * 用于和用户拥有的角色code 进行比对 + */ + @Override + public Collection getAttributes(Object object) throws IllegalArgumentException { + + if (requestMap == null) { + loadRequestMap(); + } + + HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); + + RequestMatcher requestMatcher; + for(Iterator iter = requestMap.keySet().iterator(); iter.hasNext(); ) { + requestMatcher = iter.next(); + + if(requestMatcher.matches(request)) { + return requestMap.get(requestMatcher); + } + } + + return null; + } + + @Override + public Collection getAllConfigAttributes() { + + return null; + } + + @Override + public boolean supports(Class clazz) { + + return true; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterInvocationSecurityMetadataSource.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterInvocationSecurityMetadataSource.java new file mode 100644 index 0000000..90f4b53 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterInvocationSecurityMetadataSource.java @@ -0,0 +1,129 @@ +package com.supwisdom.institute.backend.admin.bff.security.web.access.intercept; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.SecurityConfig; +import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { + +// @Autowired +// User1SecurityPermissionRemoteService user1SecurityPermissionRemoteService; + + private Map> requestMap = null; + + public void refreshRequestMap() { + + log.info("MyFilterInvocationSecurityMetadataSource.refreshRequestMap"); + + requestMap = null; + loadRequestMap(); + } + + private void loadRequestMap() { + synchronized (MyFilterInvocationSecurityMetadataSource.class) { + + if (requestMap == null) { + requestMap = new LinkedHashMap>(); + +// String applicationCode = Constants.APPLICATION_CODE; +// SecurityPermission securityPermission = user1SecurityPermissionRemoteService.loadPermissionsByAppcode(applicationCode, null); +// if (securityPermission == null) { +// return; +// } +// +// Map mapRoles = new HashMap(); +// for (Role r : securityPermission.getRoles()) { +// mapRoles.put(r.getId(), r.getCode()); +// } +// +// Map> permissionRoles = new HashMap>(); +// for (RolePermission rp : securityPermission.getRolePermissions()) { +// if (mapRoles.containsKey(rp.getRoleId())) { +// if (!permissionRoles.containsKey(rp.getPermissionId())) { +// permissionRoles.put(rp.getPermissionId(), new ArrayList()); +// } +// ConfigAttribute ca = new SecurityConfig(mapRoles.get(rp.getRoleId())); +// permissionRoles.get(rp.getPermissionId()).add(ca); +// } +// } +// +// for (Permission p : securityPermission.getPermissions()) { +// Collection attributes = permissionRoles.get(p.getId()); +// if (attributes == null) { +// attributes = new ArrayList(); +// } +// +// if (p.getUrl() == null || p.getUrl().isEmpty()) { +// continue; +// } +// +// String pattern = p.getUrl(); +// String httpMethod = null; +// +// if (pattern.startsWith("GET ") || pattern.startsWith("POST ") || pattern.startsWith("PUT ") || pattern.startsWith("DELETE ")) { +// httpMethod = pattern.substring(0, pattern.indexOf(" ")); +// pattern = pattern.substring(pattern.indexOf(" ")+1); +// } +// +// AntPathRequestMatcher requestMatcher = new AntPathRequestMatcher(pattern, httpMethod); +// +// requestMap.put(requestMatcher, attributes); +// } + } + + } + } + + /** + * 获取当前请求关联的所有角色code {@link SecurityConfig} 用于和用户拥有的角色code 进行比对 + */ + @Override + public Collection getAttributes(Object object) throws IllegalArgumentException { + + if (requestMap == null) { + loadRequestMap(); + } + + HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); + + RequestMatcher requestMatcher; + for (Iterator iter = requestMap.keySet().iterator(); iter.hasNext();) { + requestMatcher = iter.next(); + + if (requestMatcher.matches(request)) { + return requestMap.get(requestMatcher); + } + } + + return null; + } + + @Override + public Collection getAllConfigAttributes() { + + return null; + } + + @Override + public boolean supports(Class clazz) { + + return true; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java new file mode 100644 index 0000000..7cd74e2 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java @@ -0,0 +1,78 @@ +package com.supwisdom.institute.backend.admin.bff.security.web.access.intercept; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import javax.servlet.ServletException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.SecurityMetadataSource; +import org.springframework.security.access.intercept.InterceptorStatusToken; +import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; + +import com.supwisdom.infras.security.web.access.intercept.InfrasFilterSecurityInterceptor; +import com.supwisdom.institute.backend.admin.bff.utils.AuthenticationUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MyFilterSecurityInterceptor extends InfrasFilterSecurityInterceptor { + + @Autowired + private FilterInvocationSecurityMetadataSource securityMetadataSource; + + @Autowired + public void setAccessDecisionManager(AccessDecisionManager accessDecisionManager) { + + super.setAccessDecisionManager(accessDecisionManager); + } + + @Override + public void invoke(FilterInvocation fi) throws IOException, ServletException { + + Set noneSecurityUrl = new HashSet(); // FIXME: 对无须访问控制的url,支持可配置 + noneSecurityUrl.add("/web/login"); + noneSecurityUrl.add("/web/logout"); + noneSecurityUrl.add("/web/index"); + + if (fi.getRequest() != null) { + String requestUrl = fi.getRequestUrl(); log.debug("MyFilterSecurityInterceptor invoke requestUrl: {}", requestUrl); + if (noneSecurityUrl.contains(requestUrl)) { + fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); + return; + } + } + + if(AuthenticationUtil.isAdministrator()){ + fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); + return; + } + + // fi里面有一个被拦截的url + // 里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限 + // 再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够 + InterceptorStatusToken token = super.beforeInvocation(fi); + try { + // 执行下一个拦截器 + fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); + } finally { + super.afterInvocation(token, null); + } + } + + @Override + public Class getSecureObjectClass() { + + return FilterInvocation.class; + } + + @Override + public SecurityMetadataSource obtainSecurityMetadataSource() { + + return this.securityMetadataSource; + } + +} diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/AuthenticationUtil.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/AuthenticationUtil.java new file mode 100644 index 0000000..b2ab8e8 --- /dev/null +++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/AuthenticationUtil.java @@ -0,0 +1,91 @@ +package com.supwisdom.institute.backend.admin.bff.utils; + +import java.util.Collection; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; + +import com.supwisdom.institute.backend.admin.bff.security.core.userdetails.MyUser; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AuthenticationUtil { + + public static String currentUsername() { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication == null) { + log.error("authentication is null"); + return null; + } + + log.debug("authentication is {}", authentication.getPrincipal()); + + if (!authentication.isAuthenticated()) { + log.error("authentication is not authenticated"); + return null; + } + + if (authentication.getPrincipal() == null) { + log.error("authentication's principal is null"); + return null; + } + + log.debug("authentication's principal is {}", authentication.getPrincipal()); + + if (authentication.getPrincipal() instanceof MyUser) { + return ((MyUser) authentication.getPrincipal()).getUsername(); + } + + return null; + } + + public static MyUser currentUser() { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication == null) { + log.error("authentication is null"); + return null; + } + + log.debug("authentication is {}", authentication.getPrincipal()); + + if (!authentication.isAuthenticated()) { + log.error("authentication is not authenticated"); + return null; + } + + if (authentication.getPrincipal() == null) { + log.error("authentication's principal is null"); + return null; + } + + log.debug("authentication's principal is {}", authentication.getPrincipal()); + + if (authentication.getPrincipal() instanceof MyUser) { + return (MyUser) authentication.getPrincipal(); + } + + return null; + } + + public static boolean isAdministrator() { + MyUser myUser = AuthenticationUtil.currentUser(); + if (myUser != null) { + Collection grantedAuthoritys = myUser.getAuthorities(); + if (grantedAuthoritys != null && grantedAuthoritys.size() > 0) { + for (GrantedAuthority grantedAuthority : grantedAuthoritys) { + if ("administrator".equals(grantedAuthority.getAuthority())) { + return true; + } + } + } + } + return false; + } + +} diff --git a/bff/admin/src/main/resources/application-docker.yml b/bff/admin/src/main/resources/application-docker.yml new file mode 100644 index 0000000..cc5555e --- /dev/null +++ b/bff/admin/src/main/resources/application-docker.yml @@ -0,0 +1,81 @@ +server: + port: ${SERVER_PORT:8443} + ssl: + enabled: ${SSL_ENABLED:true} + clientAuth: NEED + key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore} + key-store-password: ${SSL_KEYSTORE_PASSWORD:} + trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore} + trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:} + tomcat: + accesslog: + enabled: ${TOMCAT_ACCESSLOG_ENABLED:false} + buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true} + directory: ${TOMCAT_ACCESSLOG_DIR:log} + prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog} + suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log} + file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd} + rotate: ${TOMCAT_ACCESSLOG_ROTATE:true} + + +## +# logging +# +logging: + level: + root: INFO + com.supwisdom: INFO + + +## +# infras.online-doc +# +infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false} +infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/} +infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/} + + +## +# infras.security basic +# +infras.security.basic.enabled: ${INFRAS_SECURITY_BASIC_ENABLED:true} + + +## +# infras.security jwt +# +infras.security.jwt.enabled: ${INFRAS_SECURITY_JWT_ENABLED:false} + +infras.security.jwt.public-key-pem: ${INFRAS_SECURITY_JWT_PUBLIC_KEY_PEM:} +infras.security.jwt.private-key-pem-pkcs8: ${INFRAS_SECURITY_JWT_PRIVATE_KEY_PEM_PKCS8:} + + +## +# infras.security cas +# +infras.security.cas.enabled: ${INFRAS_SECURITY_CAS_ENABLED:false} + +#应用访问地址 +app.server.host.url: ${APP_SERVER_HOST_URL:https://localhost:8443} +#应用登录地址 +app.login.url: ${APP_LOGIN_URL:/cas/login} +#应用登出地址 +app.logout.url: ${APP_LOGOUT_URL:/cas/logout} + +#CAS服务地址 +cas.server.host.url: ${CAS_SERVER_HOST_URL:https://cas-server/cas} + + +## +# server url for feign +# +sw-backend-api-admin: + server: + url: ${CASSERVER_SA_API_SERVER_URL:https://sw-backend/sa-api} + client-auth: + enabled: ${CASSERVER_SA_API_CLIENT_AUTH_ENABLED:true} + key-password: ${CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD:} + key-store: ${CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore} + key-store-password: ${CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD:} + trust-store: ${CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore} + trust-store-password: ${CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD:} diff --git a/bff/admin/src/main/resources/application.yml b/bff/admin/src/main/resources/application.yml new file mode 100644 index 0000000..d93888b --- /dev/null +++ b/bff/admin/src/main/resources/application.yml @@ -0,0 +1,114 @@ +server: + port: 8080 + + +## +# logging +# +logging: + level: + root: INFO + com.supwisdom: DEBUG +# org.springframework.web: INFO +# org.springframework.cloud.openfeign: INFO + + +spring: + jackson: + time-zone: Asia/Shanghai + +## +# spring cloud gateway +# + cloud: + gateway: + metrics: + enabled: true + routes: + - id: system-api + uri: http://localhost:8081 + predicates: + - Path=/api/system/** + filters: + - RewritePath=/api/system/(?.*), /$\{suffix} + - id: biz-api + uri: http://localhost:8081 + predicates: + - Path=/api/biz/** + filters: + - RewritePath=/api/biz/(?.*), /$\{suffix} + + +feign: + client: + config: + default: + #errorDecoder: com.supwisdom.leaveschool.common.config.BaseExceptionErrorDecoder + connectTimeout: 12000 + readTimeout: 12000 + loggerLevel: full + hystrix: + enabled: true + httpclient: + enabled: true + +hystrix: + command: + default: + execution: + timeout: + enabled: true + isolation: + thread: + timeoutInMilliseconds: 12000 + + +## +# infras.online-doc +# +infras.online-doc.enabled: false +infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/doc/ +infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/api-docs/ + + +## +# infras.security basic +# +infras.security.basic.enabled: true + + +## +# infras.security jwt +# +infras.security.jwt.enabled: false + +#infras.security.jwt.public-key-pem: |- +# -----BEGIN PUBLIC KEY----- +# MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBQw6TmvJ+nOuRaLoHsZJGIBzRg/wbskNv6UevL3/nQioYooptPfdIHVzPiKRVT5+DW5+nqzav3DOxY+HYKjO9nFjYdj0sgvRae6iVpa5Ji1wbDKOvwIDNukgnKbqvFXX2Isfl0RxeN3uEKdjeFGGFdr38I3ADCNKFNxtbmfqvjQIDAQAB +# -----END PUBLIC KEY----- +#infras.security.jwt.private-key-pem-pkcs8: |- +# -----BEGIN PRIVATE KEY----- +# MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMFDDpOa8n6c65FougexkkYgHNGD/BuyQ2/pR68vf+dCKhiiim0990gdXM+IpFVPn4Nbn6erNq/cM7Fj4dgqM72cWNh2PSyC9Fp7qJWlrkmLXBsMo6/AgM26SCcpuq8VdfYix+XRHF43e4Qp2N4UYYV2vfwjcAMI0oU3G1uZ+q+NAgMBAAECgYA7jA7UuhxXmMAYmJ0hO7xnMQPQJouqeP3AYK9+sfMF7WQNHR/r0vj7Vli/dUm1I4hxr+x8fAuomf+ve6gds7sm+v2JHLzEIyPPiogoC7IcBmjJ3yVzW/26cXeOmTiPC/fW2g4BpYxSM8HLDaSkrtqzy8e9ijlzMpHBvvwLikufnQJBAOXaqIPuZ7Vm/JwQHAmX2HV+Qk6GMi/H7mL8X0AaW68w+Iccdbz1hzmMBfdn5NMmx2AOwoBAVivgjt0a1OfksHMCQQDXPtXxwFy4dQ4TbPu8L38P8s/bPo9ib1YkEMp57yBw+IvxB7jnpA9rUYTfZM/HpVP7r9rfVEUylVXXzhz1qx//AkEApWJOTBdW8bQ3YEdLFS/3pJqDNSLjq3OMuBZkpqgQfh6bRAQbRynW8XYpuNk9URye6iPUmRkxp4J86ORseqoWtwJAJb5a/b1hhObhxP5DVkht23oUgLmDoxsq28AmASOxaJ3szCMyhUv7eDIfPp0K4lNXWrcHhkncqHYPS3xVD68mOQJAV4SRDdWpgAbQOUODotohE48RxrabHo0l228CJ/pnm0q7gplPs4iSNJ2eijFuOMXfKkq3z/vxiNSA59FcdoCOHQ== +# -----END PRIVATE KEY----- + + +## +# infras.security cas +# +infras.security.cas.enabled: false + +#应用访问地址 +app.server.host.url: http://localhost:8080 +#应用登录地址 +app.login.url: /cas/login +#应用登出地址 +app.logout.url: /cas/logout + +#CAS服务地址 +cas.server.host.url: https://cas.supwisdom.com/cas + + +## +# server url for feign +# +sw-backend-api-admin.server.url: http://localhost:8081 diff --git a/bff/admin/src/main/resources/bootstrap.yml b/bff/admin/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..2df1be7 --- /dev/null +++ b/bff/admin/src/main/resources/bootstrap.yml @@ -0,0 +1,3 @@ +spring: + application: + name: sw-backend-admin-bff diff --git a/bff/pom.xml b/bff/pom.xml new file mode 100644 index 0000000..8685014 --- /dev/null +++ b/bff/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + + + com.supwisdom.institute + sw-backend-bff-aggregator + 0.0.1-SNAPSHOT + pom + + Supwisdom Backend Framework Backend for Frontend Aggregator + Supwisdom Backend Framework Backend for Frontend Aggregator project + + + admin + + + + + + maven-deploy-plugin + + true + + + + + + diff --git a/biz/api/pom.xml b/biz/api/pom.xml new file mode 100644 index 0000000..3832ac9 --- /dev/null +++ b/biz/api/pom.xml @@ -0,0 +1,111 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-biz-api + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework BIZ API + Supwisdom Backend Framework BIZ API project + + + + + org.projectlombok + lombok + provided + + + + javax.servlet + javax.servlet-api + provided + + + + + com.supwisdom.institute + sw-backend-common-core + + + + com.supwisdom.institute + sw-backend-common-utils + + + + com.supwisdom.institute + sw-backend-common-framework + + + + + com.supwisdom.institute + sw-backend-biz-domain + + + + + org.springframework.boot + spring-boot-starter + + + + + com.supwisdom.infras + infras-mvc + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + diff --git a/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java b/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java new file mode 100644 index 0000000..a46c806 --- /dev/null +++ b/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java @@ -0,0 +1,26 @@ +package com.supwisdom.institute.backend.biz.api.v1.admin; + +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.util.MimeTypeUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.supwisdom.institute.backend.common.core.transmit.user.User; +import com.supwisdom.institute.backend.common.core.transmit.user.UserContext; + +@Api(value = "BizAdminHello", tags = { "BizAdminHello" }, description = "示例接口") +@Slf4j +@RestController +@RequestMapping("/v1/admin/hello") +public class AdminHelloController { + + @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + public User biz() { + User user = UserContext.getUser(); log.debug("{}", user); + return user; + } + +} diff --git a/biz/domain/pom.xml b/biz/domain/pom.xml new file mode 100644 index 0000000..3f8f044 --- /dev/null +++ b/biz/domain/pom.xml @@ -0,0 +1,102 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-biz-domain + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework BIZ Domain + Supwisdom Backend Framework BIZ Domain project + + + + + org.projectlombok + lombok + provided + + + + + com.supwisdom.institute + sw-backend-common-core + ${project.version} + + + + com.supwisdom.institute + sw-backend-common-utils + ${project.version} + + + + com.supwisdom.institute + sw-backend-common-framework + ${project.version} + + + + + org.springframework.boot + spring-boot-starter + + + + + com.supwisdom.infras + infras-data-jpa + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + diff --git a/biz/pom.xml b/biz/pom.xml new file mode 100644 index 0000000..52f8e2f --- /dev/null +++ b/biz/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + + + com.supwisdom.institute + sw-backend-biz-aggregator + 0.0.1-SNAPSHOT + pom + + Supwisdom Backend Framework BIZ Aggregator + Supwisdom Backend Framework BIZ Aggregator project + + + domain + api + + + + + + maven-deploy-plugin + + true + + + + + + diff --git a/common/core/pom.xml b/common/core/pom.xml new file mode 100644 index 0000000..d535132 --- /dev/null +++ b/common/core/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-common-core + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework Common Core + Supwisdom Backend Framework Common Core project + + + + + org.projectlombok + lombok + provided + + + + javax.servlet + javax.servlet-api + provided + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + com.alibaba + fastjson + + + + org.apache.commons + commons-lang3 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java new file mode 100644 index 0000000..5a094e9 --- /dev/null +++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java @@ -0,0 +1,19 @@ +package com.supwisdom.institute.backend.common.core.transmit.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Import; + +import com.supwisdom.institute.backend.common.core.transmit.config.SimpleUserTransmitAutoConfiguration; + +@Documented +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Import({SimpleUserTransmitAutoConfiguration.class}) +public @interface EnableSimpleUserTransmit { + +} diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java new file mode 100644 index 0000000..a3e11ce --- /dev/null +++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java @@ -0,0 +1,27 @@ +package com.supwisdom.institute.backend.common.core.transmit.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.supwisdom.institute.backend.common.core.transmit.feign.SimpleUserTransmitRequestInterceptor; +import com.supwisdom.institute.backend.common.core.transmit.filter.SimpleUserTransmitFilter; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +public class SimpleUserTransmitAutoConfiguration { + + @Bean + public SimpleUserTransmitRequestInterceptor simpleUserTransmitRequestInterceptor() { + log.debug("-----SimpleUserTransmitRequestInterceptor"); + return new SimpleUserTransmitRequestInterceptor(); + } + + @Bean + public SimpleUserTransmitFilter simpleUserTransmitFilter() { + log.debug("-----SimpleUserTransmitFilter"); + return new SimpleUserTransmitFilter(); + } + +} diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java new file mode 100644 index 0000000..be002db --- /dev/null +++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java @@ -0,0 +1,31 @@ +package com.supwisdom.institute.backend.common.core.transmit.feign; + +import java.net.URLDecoder; + +import lombok.extern.slf4j.Slf4j; + +import com.alibaba.fastjson.JSONObject; +import com.supwisdom.institute.backend.common.core.transmit.user.User; +import com.supwisdom.institute.backend.common.core.transmit.user.UserContext; + +import feign.RequestInterceptor; +import feign.RequestTemplate; + +@Slf4j +public class SimpleUserTransmitRequestInterceptor implements RequestInterceptor { + + @Override + public void apply(RequestTemplate template) { + User user = UserContext.getUser(); + if (user != null) { + try { + String jsonUser = JSONObject.toJSONString(user); + String headerValue = new String(URLDecoder.decode(jsonUser,"UTF-8")); + template.header(UserContext.KEY_USER_IN_HTTP_HEADER, headerValue); + } catch (Exception e) { + log.warn("User set error", e); + } + } + } + +} diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java new file mode 100644 index 0000000..4d8a2dc --- /dev/null +++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java @@ -0,0 +1,55 @@ +package com.supwisdom.institute.backend.common.core.transmit.filter; + +import java.io.IOException; +import java.net.URLDecoder; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; + +import com.alibaba.fastjson.JSONObject; +import com.supwisdom.institute.backend.common.core.transmit.user.User; +import com.supwisdom.institute.backend.common.core.transmit.user.UserContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SimpleUserTransmitFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + + String headerValue = request.getHeader(UserContext.KEY_USER_IN_HTTP_HEADER); + if (StringUtils.isNotBlank(headerValue)) { + try { + String jsonUser = URLDecoder.decode(headerValue,"UTF-8"); + + User user = JSONObject.parseObject(jsonUser, User.class); + + UserContext.setUser(user); + } catch (Exception e) { + log.warn("User get error", e); + } + } + + filterChain.doFilter(servletRequest, servletResponse); + } + + @Override + public void destroy() { + + } + +} diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java new file mode 100644 index 0000000..3d34bc4 --- /dev/null +++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java @@ -0,0 +1,17 @@ +package com.supwisdom.institute.backend.common.core.transmit.user; + +import java.util.List; +import java.util.Map; + +import lombok.Value; + +@Value +public class User { + + private String username; + + private List roles; + + private Map attributes; + +} diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java new file mode 100644 index 0000000..00f2e43 --- /dev/null +++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java @@ -0,0 +1,21 @@ +package com.supwisdom.institute.backend.common.core.transmit.user; + +public class UserContext { + + private static ThreadLocal user = new ThreadLocal(); + + public static String KEY_USER_IN_HTTP_HEADER = "X-FORWARD-USER"; + + private UserContext() { + + } + + public static User getUser() { + return user.get(); + } + + public static void setUser(User value) { + user.set(value); + } + +} diff --git a/common/framework/pom.xml b/common/framework/pom.xml new file mode 100644 index 0000000..328b83c --- /dev/null +++ b/common/framework/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-common-framework + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework Common Framework + Supwisdom Backend Framework Common Framework project + + + + + org.projectlombok + lombok + provided + + + + com.supwisdom.institute + sw-backend-common-core + + + com.supwisdom.institute + sw-backend-common-utils + + + + + org.apache.commons + commons-lang3 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + true + + + + + io.springfox + springfox-swagger2 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java new file mode 100644 index 0000000..3c14c25 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java @@ -0,0 +1,79 @@ +package com.supwisdom.institute.backend.common.framework.entity; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + +import lombok.Getter; +import lombok.Setter; + +@MappedSuperclass +public abstract class ABaseEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2613136930230449335L; + + @Id + @Column(name = "ID") + private String id; + + /** + * 获取主键 + */ + public String getId() { + return id; + } + + /** + * 设置ID属性,主要用于人工指定键值 + */ + public void setId(String id) { + this.id = id; + } + + @Getter + @Setter + @Column(name = "COMPANY_ID", nullable = true) + private String companyId = null; + + @Getter + @Setter + @Column(name = "DELETED") + private Boolean deleted = false; + + @Getter + @Setter + @Column(name = "ADD_ACCOUNT", nullable = true) + private String addAccount = null; + + @Getter + @Setter + @Column(name = "ADD_TIME", nullable = true) + private Date addTime = null; + + @Getter + @Setter + @Column(name = "EDIT_ACCOUNT", nullable = true) + private String editAccount = null; + + @Getter + @Setter + @Column(name = "EDIT_TIME", nullable = true) + private Date editTime = null; + + @Getter + @Setter + @Column(name = "DELETE_ACCOUNT", nullable = true) + private String deleteAccount = null; + + @Getter + @Setter + @Column(name = "DELETE_TIME", nullable = true) + private Date deleteTime = null; + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java new file mode 100644 index 0000000..662b24a --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java @@ -0,0 +1,199 @@ +package com.supwisdom.institute.backend.common.framework.entity; + +import java.lang.reflect.Field; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Id; + +import com.supwisdom.institute.backend.common.util.ReflectUtils; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 对 entity 的操作 如:复制、合并、转换等 + * + * @author loie + * + */ +public class EntityUtils { + + /** + * 合并 domain 中带有{@link Column}注解的字段值, 将 newEntity 中值为null的字段,使用 oldEntity 中的值 + * 进行覆盖 + * + * @param oldEntity + * ,覆盖的实体 + * @param newEntity + * ,待覆盖的实体 + * @return 合并后的newEntity + */ + public static T merge(T oldEntity, T newEntity) { + + for (Class clazz = oldEntity.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) { + for (Field field : clazz.getDeclaredFields()) { + Column[] annotations = field.getAnnotationsByType(Column.class); + if (annotations == null || annotations.length == 0) { + Id[] idAnnotations = field.getAnnotationsByType(Id.class); + if (idAnnotations == null || idAnnotations.length == 0) { + continue; + } + } + + String fieldName = field.getName(); + Object newFieldValue = ReflectUtils.getFieldValue(newEntity, fieldName); + + if (newFieldValue == null) { + Object oldFieldValue = ReflectUtils.getFieldValue(oldEntity, fieldName); + ReflectUtils.setFieldValue(newEntity, fieldName, oldFieldValue,field.getType()); + } + } + } + + return newEntity; + } + + public static T copy(S sourceEntity, T targetEntity) { + + for (Class clazz = targetEntity.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) { + for (Field field : clazz.getDeclaredFields()) { + Column[] annotations = field.getAnnotationsByType(Column.class); + if (annotations == null || annotations.length == 0) { + Id[] idAnnotations = field.getAnnotationsByType(Id.class); + if (idAnnotations == null || idAnnotations.length == 0) { + continue; + } + } + + String fieldName = field.getName(); + Object sFieldValue = ReflectUtils.getFieldValue(sourceEntity, fieldName); + + if (sFieldValue != null) { + ReflectUtils.setFieldValue(targetEntity, fieldName, sFieldValue,field.getType()); + } + } + } + + return targetEntity; + } + + public static T fatherToChild (S father, T child){ + for (Class clazz = child.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) { + for (Field field : clazz.getDeclaredFields()) { + String fieldName = field.getName(); + if(fieldName.equals("serialVersionUID")){continue;} + Object sFieldValue = ReflectUtils.getFieldValue(father, fieldName); + + if (sFieldValue != null) { + ReflectUtils.setFieldValue(child, fieldName, sFieldValue,field.getType()); + } + } + } + + return child; + } + + public static void main(String[] args) { + + Test target0 = new Test(); + target0.setId("id0"); + target0.setCode("code"); + target0.setName("name"); + target0.setDate(new Date()); + target0.setEnabled(false); + target0.setStatus(1); + + System.out.println("target0 == " + target0.toString()); + System.out.println(); + + Test source1 = new Test(); + // source1.setId("id1"); + source1.setCode("code1"); + // source1.setName("name"); + // source1.setDate(new Date()); + source1.setEnabled(true); + // source1.setStatus(1); + System.out.println("source1 == " + source1.toString()); + + Test target1 = EntityUtils.merge(source1, target0); + System.out.println("target0 == " + target0.toString()); + System.out.println("target1 == " + target1.toString()); + System.out.println(); + + Test source2 = new Test(); + // source2.setId("id2"); + source2.setCode("code2"); + source2.setName("name2"); + // source2.setDate(new Date()); + // source2.setEnabled(true); + source2.setStatus(2); + System.out.println("source2 == " + source2.toString()); + + Test target2 = EntityUtils.merge(source2, target0); + System.out.println("target0 == " + target0.toString()); + System.out.println("target2 == " + target2.toString()); + System.out.println(); + + + Test test = new Test(); + test.setId("id0"); + test.setCode("code"); + test.setName("name"); + test.setDate(new Date()); + test.setEnabled(false); + test.setStatus(1); + + Test2 test2 = new Test2(); + test2 = EntityUtils.copy(test, test2); + System.out.println("test == " + test.toString()); + System.out.println("test2 == " + test2.toString()); + System.out.println(); + + } + + @Getter + @Setter + @ToString + public static class Test extends ABaseEntity { + + /** + * + */ + private static final long serialVersionUID = -8348781653151879484L; + + @Column + private String code = null; + @Column + private String name = null; + @Column + private Date date = null; + @Column + private Boolean enabled = null; + @Column + private Integer status = null; + + } + + public static class Test2 extends ABaseEntity { + + /** + * + */ + private static final long serialVersionUID = -5565959639168005384L; + + @Column + private String name = null; + @Column + private String memo = null; + @Column + private Date date = null; + @Column + private Boolean enabled = null; + @Column + private Integer status = null; + + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java new file mode 100644 index 0000000..ee21f7a --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java @@ -0,0 +1,66 @@ +package com.supwisdom.institute.backend.common.framework.exception; + +public class BaseException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 2278568118369300446L; + + /** + * 异常信息 + */ + protected String msg; + + /** + * 具体异常码 + */ + protected int code = -1; + + public BaseException(int code, String msgFormat, Object... args) { + super(String.format(msgFormat, args)); + this.code = code; + this.msg = String.format(msgFormat, args); + } + + public BaseException() { + super(); + } + + public BaseException(String message, Throwable cause) { + super(message, cause); + } + + public BaseException(Throwable cause) { + super(cause); + } + + public BaseException(String message) { + super(message); + } + + public String getMsg() { + return msg; + } + + public int getCode() { + return code; + } + + /** + * 实例化异常 + * + * @param msgFormat + * @param args + * @return + */ + @Deprecated + public BaseException newInstance(String msgFormat, Object... args) { + return new BaseException(this.code, msgFormat, args); + } + + public BaseException newInstance(int code, String msgFormat, Object... args) { + return new BaseException(code, msgFormat, args); + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java new file mode 100644 index 0000000..3b8d6d3 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java @@ -0,0 +1,10 @@ +package com.supwisdom.institute.backend.common.framework.modal; + +public abstract class ABaseModal implements IModal { + + /** + * + */ + private static final long serialVersionUID = 8717041105592152819L; + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java new file mode 100644 index 0000000..cb6f72b --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.modal; + +import java.io.Serializable; + +public interface IModal extends Serializable { + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java new file mode 100644 index 0000000..1266710 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java @@ -0,0 +1,13 @@ +package com.supwisdom.institute.backend.common.framework.rabbitmq.constants; + +public class ExchangeNames { + + public static final String EXCHANGE_NAME_FANOUT = "fanout-exchange"; + + public static final String EXCHANGE_NAME_DIRECT = "direct-exchange"; + + public static final String EXCHANGE_NAME_TOPIC = "topic-exchange"; + + public static final String EXCHANGE_NAME_HEADERS = "headers-exchange"; + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java new file mode 100644 index 0000000..e2ed900 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java @@ -0,0 +1,21 @@ +package com.supwisdom.institute.backend.common.framework.rabbitmq.constants; + +public class QueueNames { + + /** + * 授权添加事件 + */ + public static final String QUEUE_NAME_GRANTED_ADDED = "granted-added"; + + /** + * 授权移除事件 + */ + public static final String QUEUE_NAME_GRANTED_REMOVED = "granted-removed"; + + + /** + * 授权操作日志记录事件 + */ + public static final String QUEUE_NAME_GRANT_OPERATE_LOGGING = "granted-operate-logging"; + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java new file mode 100644 index 0000000..dad0e02 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java @@ -0,0 +1,20 @@ +package com.supwisdom.institute.backend.common.framework.rabbitmq.constants; + +public class RoutingKeys { + + /** + * 授权添加事件 + */ + public static final String ROUTING_KEY_GRANTED_ADDED = "granted.added"; + + /** + * 授权移除事件 + */ + public static final String ROUTING_KEY_GRANTED_REMOVED = "granted.removed"; + + + /** + * 授权操作日志记录事件 + */ + public static final String ROUTING_KEY_GRANT_OPERATE_LOGGING = "grant.operate.logging"; +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java new file mode 100644 index 0000000..32e0e33 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java @@ -0,0 +1,92 @@ +package com.supwisdom.institute.backend.common.framework.repo; + +import java.util.Calendar; +import java.util.Map; +import java.util.Optional; + +import javax.persistence.EntityManager; +import javax.transaction.Transactional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.support.JpaEntityInformation; +import org.springframework.data.jpa.repository.support.SimpleJpaRepository; +import org.springframework.data.repository.NoRepositoryBean; + +import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity; + +@Transactional +@NoRepositoryBean +public class ABaseJpaRepositoryImpl extends SimpleJpaRepository implements BaseJpaRepository { + + @SuppressWarnings("unused") + private final EntityManager em; + + public ABaseJpaRepositoryImpl(Class domainClass, EntityManager em) { + super(domainClass, em); + this.em = em; + } + + public ABaseJpaRepositoryImpl(JpaEntityInformation information, EntityManager em) { + super(information, em); + this.em = em; + } + + public Page selectPageList(int pageIndex, int pageSize, Map mapBean) { + + PageRequest pageRequest = PageRequest.of(pageIndex, pageSize); + + Page page = this.findAll(pageRequest); + + return page; + } + + public E selectById(String id) { + + try { + Optional entity = this.findById(id); + + if (entity.isPresent()) { + return entity.get(); + } + } catch (RuntimeException e) { + System.out.println("RuntimeException:" + e.getMessage()); + } catch (Exception e) { + System.out.println("Exception:" + e.getMessage()); + } + + return null; + } + + public E insert(E entity) { + + if (entity.getCompanyId() == null || entity.getCompanyId().isEmpty()) { + entity.setCompanyId("1"); + } + + if (entity.getDeleted() == null) { + entity.setDeleted(false); + } + //entity.setAddAccount(AuthUtil.getRemoteUser()); // FIXME: setAddAccount + if (entity.getAddTime() == null) { + entity.setAddTime(Calendar.getInstance().getTime()); + } + + E e = this.save(entity); + + return e; + } + + public E update(E entity) { + + //entity.setEditAccount(AuthUtil.getRemoteUser()); // FIXME: setEditAccount + if (entity.getEditTime() == null) { + entity.setEditTime(Calendar.getInstance().getTime()); + } + + E e = this.save(entity); + + return e; + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java new file mode 100644 index 0000000..3451705 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java @@ -0,0 +1,123 @@ +package com.supwisdom.institute.backend.common.framework.repo; + +import java.util.Calendar; +import java.util.Map; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.NoRepositoryBean; + +import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity; +import com.supwisdom.institute.backend.common.util.UUIDUtils; + +@NoRepositoryBean +public interface BaseJpaRepository extends JpaRepository, JpaSpecificationExecutor { + + + /** + * 生成主键值。 默认使用方法 + * 如果需要生成主键,需要由子类重写此方法根据需要的方式生成主键值。 + * @param entity 要持久化的对象 + */ + public default String generateId() { + return UUIDUtils.create(); + } + + public default Page selectPageList(boolean loadAll, int pageIndex, int pageSize, Map mapBean, Map orderBy) { + + if (loadAll) { + pageIndex = 0; + pageSize = Integer.MAX_VALUE; + } + + PageRequest pageRequest = PageRequest.of(pageIndex, pageSize); + + Page page = this.findAll(pageRequest); + + return page; + } + + public default E selectById(String id) { + + try { + Optional entity = this.findById(id); + + if (entity.isPresent()) { + return entity.get(); + } + } catch (RuntimeException e) { + System.out.println("RuntimeException:" + e.getMessage()); + } catch (Exception e) { + System.out.println("Exception:" + e.getMessage()); + } + + return null; + } + + public default E insert(E entity) { + + if (entity.getId() == null || entity.getId().isEmpty()) { + entity.setId(generateId()); + } + + if (entity.getCompanyId() == null || entity.getCompanyId().isEmpty()) { + entity.setCompanyId("1"); + } + + if (entity.getDeleted() == null) { + entity.setDeleted(false); + } + if (entity.getAddAccount() == null) { + //entity.setAddAccount(AuthUtil.getRemoteUser()); // FIXME: setAddAccount + } + if (entity.getAddTime() == null) { + entity.setAddTime(Calendar.getInstance().getTime()); + } + + E e = this.save(entity); + + return e; + } + + public default E update(E entity) { + + if (entity.getEditAccount() == null) { + //entity.setEditAccount(AuthUtil.getRemoteUser()); // FIXME: setEditAccount + } + if (entity.getEditTime() == null) { + entity.setEditTime(Calendar.getInstance().getTime()); + } + + E e = this.save(entity); + + return e; + } + + + public default E remove(E entity) { + + if (entity.getDeleted() == null) { + entity.setDeleted(true); + } + if (entity.getDeleteAccount() == null) { + //entity.setDeleteAccount(AuthUtil.getRemoteUser()); // FIXME: setDeleteAccount + } + if (entity.getDeleteTime() == null) { + entity.setDeleteTime(Calendar.getInstance().getTime()); + } + + E e = this.save(entity); + + return e; + } + + + public default void delete(String id) { + + this.deleteById(id); + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java new file mode 100644 index 0000000..ee622bc --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java @@ -0,0 +1,72 @@ +package com.supwisdom.institute.backend.common.framework.repo.resultTransformer; + +import com.google.common.collect.Lists; +import com.supwisdom.institute.backend.common.util.ReflectUtils; + +import org.hibernate.HibernateException; +import org.hibernate.transform.ResultTransformer; + +import java.lang.reflect.Field; +import java.util.List; + +/** + *  + * 修正hibernate返回自定义pojo类型时找不到属性的BUG + * 主要发生在使用oracle或高版本的mysql时,查询返回的字段默认是大写的(除非SQL中指定了别名),这导致返回自定义pojo类型时会报找不到属性的错误,该类用于修正此BUG。 + * 使用该类时SQL返回的字段名大小写或者带"_"都会被忽略,如数据库字段为 USER_NAME,自定义pojo的属性名为username就可以使用 + *  + * @author feng*/ +public class IgnoreCaseResultTransformer implements ResultTransformer { + private static final long serialVersionUID = -3779317531110592988L; + private final Class resultClass; + private Field[] fields; + private List types = Lists.newArrayList(); + public IgnoreCaseResultTransformer(final Class resultClass) { + this.resultClass = resultClass; + List list = Lists.newArrayList(); + for (Class superClass = resultClass; superClass != Object.class; superClass = superClass.getSuperclass()) { + Field[] fs = superClass.getDeclaredFields(); + List newFs = Lists.newArrayList(); + for(int i=0;i> { + + public abstract REPO getRepo(); + + public Page selectPageList(boolean loadAll, int pageIndex, int pageSize, Map mapBean, Map orderBy) { + + return getRepo().selectPageList(loadAll, pageIndex, pageSize, mapBean, orderBy); + } + + public E selectById(String id) { + + return getRepo().selectById(id); + } + + public E insert(E entity) { + + return getRepo().insert(entity); + } + + public E update(E entity) { + + E ret = getRepo().update(entity); + getRepo().flush(); + + return ret; + } + + public void deleteById(String id) { + + getRepo().deleteById(id); + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java new file mode 100644 index 0000000..f118c4d --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java @@ -0,0 +1,5 @@ +package com.supwisdom.institute.backend.common.framework.vo.request; + +public interface IApiCreateRequest extends IApiRequest { + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java new file mode 100644 index 0000000..3cf62c4 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java @@ -0,0 +1,9 @@ +package com.supwisdom.institute.backend.common.framework.vo.request; + +public interface IApiLoadRequest extends IApiRequest { + + String getId(); + + void setId(String id); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java new file mode 100644 index 0000000..da3b638 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java @@ -0,0 +1,27 @@ +package com.supwisdom.institute.backend.common.framework.vo.request; + +import java.util.Map; + +public interface IApiQueryRequest extends IApiRequest { + + boolean isLoadAll(); + + void setLoadAll(boolean loadAll); + + int getPageIndex(); + + void setPageIndex(int pageIndex); + + int getPageSize(); + + void setPageSize(int pageSize); + + Map getMapBean(); + + void setMapBean(Map mapBean); + + Map getOrderBy(); + + void setOrderBy(Map orderBy); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java new file mode 100644 index 0000000..bda1e59 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java @@ -0,0 +1,10 @@ +package com.supwisdom.institute.backend.common.framework.vo.request; + +public interface IApiRemoveRequest extends IApiRequest { + + String getId(); + + + void setId(String id); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java new file mode 100644 index 0000000..71a4abd --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.vo.request; + +import java.io.Serializable; + +public interface IApiRequest extends Serializable { + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java new file mode 100644 index 0000000..9c491c4 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java @@ -0,0 +1,9 @@ +package com.supwisdom.institute.backend.common.framework.vo.request; + +public interface IApiUpdateRequest extends IApiRequest { + + String getId(); + + void setId(String id); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java new file mode 100644 index 0000000..8e979e3 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java @@ -0,0 +1,37 @@ +package com.supwisdom.institute.backend.common.framework.vo.response; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData; + +public abstract class AbstractApiResponse implements IApiResponse { + + /** + * + */ + private static final long serialVersionUID = 846108786006850165L; + + @JsonIgnore + @Deprecated + protected boolean acknowleged = true; + + @Override + @JsonIgnore + @Deprecated + public boolean isAcknowleged() { + return acknowleged; + } + + protected int code = 0; + protected String message = null; + + @Override + public int getCode() { + return code; + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java new file mode 100644 index 0000000..72ac7e2 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java @@ -0,0 +1,59 @@ +package com.supwisdom.institute.backend.common.framework.vo.response; + +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData; + +public class DefaultApiResponse extends AbstractApiResponse { + + /** + * + */ + private static final long serialVersionUID = 4380576799912565681L; + + protected T data; + + @Override + public T getData() { + return data; + } + +// public void setData(T data) { +// this.data = data; +// } +// +// public DefaultApiResponse() { +// +// } + + public DefaultApiResponse(T data) { + this(0, null, data); + } + + @Deprecated + public DefaultApiResponse(boolean acknowleged, T data) { + super.acknowleged = acknowleged; + if (super.acknowleged == false) { + super.code = -1; + super.message = "未知错误"; + } + + this.data = data; + } + + public DefaultApiResponse(int code, String message, T data) { + super.code = code; + super.message = message; + + if (code != 0) { + super.acknowleged = false; + } + + this.data = data; + } + + public static DefaultApiResponse build(T data) { + DefaultApiResponse defaultApiResponse = new DefaultApiResponse(data); + + return defaultApiResponse; + } + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java new file mode 100644 index 0000000..487183a --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java @@ -0,0 +1,20 @@ +package com.supwisdom.institute.backend.common.framework.vo.response; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData; + +public interface IApiResponse extends Serializable { + + @JsonIgnore + @Deprecated + boolean isAcknowleged(); + + int getCode(); + + String getMessage(); + + T getData(); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java new file mode 100644 index 0000000..05ab9d2 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.vo.response.data; + +public interface IApiCreateResponseData extends IApiResponseData { + + String getId(); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java new file mode 100644 index 0000000..8741959 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.vo.response.data; + +public interface IApiLoadResponseData extends IApiResponseData { + + String getId(); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java new file mode 100644 index 0000000..4e78c10 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java @@ -0,0 +1,58 @@ +package com.supwisdom.institute.backend.common.framework.vo.response.data; + +import java.util.List; +import java.util.Map; + +import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity; + +public interface IApiQueryResponseData extends IApiResponseData { + + /** + * 当前页码 + * @return + */ + int getPageIndex(); + + /** + * 每页记录数 + * @return + */ + int getPageSize(); + + /** + * 查询条件 + * @return + */ + Map getMapBean(); + + /** + * 排序字段 + * @return + */ + Map getOrderBy(); + + /** + * 总页数 + * @return + */ + int getPageCount(); + + /** + * 总记录数 + * @return + */ + long getRecordCount(); + + /** + * 返回记录数 + * @return + */ + int getCurrentItemCount(); + + /** + * 返回记录 + * @return + */ + List getItems(); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java new file mode 100644 index 0000000..820c62d --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.vo.response.data; + +public interface IApiRemoveResponseData extends IApiResponseData { + + String getId(); + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java new file mode 100644 index 0000000..56b9163 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.vo.response.data; + +import java.io.Serializable; + +public interface IApiResponseData extends Serializable { + +} diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java new file mode 100644 index 0000000..211c437 --- /dev/null +++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java @@ -0,0 +1,7 @@ +package com.supwisdom.institute.backend.common.framework.vo.response.data; + +public interface IApiUpdateResponseData extends IApiResponseData { + + String getId(); + +} diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000..22eb667 --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + + + com.supwisdom.institute + sw-backend-common + 0.0.1-SNAPSHOT + pom + + Supwisdom Backend Framework Common + Supwisdom Backend Framework Common project + + + core + utils + framework + + + + + + maven-deploy-plugin + + true + + + + + + diff --git a/common/utils/pom.xml b/common/utils/pom.xml new file mode 100644 index 0000000..36fec72 --- /dev/null +++ b/common/utils/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-common-utils + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework Common Utils + Supwisdom Backend Framework Common Utils project + + + + + org.projectlombok + lombok + provided + + + + org.springframework.boot + spring-boot-starter + + + + + org.apache.commons + commons-lang3 + + + + com.google.guava + guava + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java new file mode 100644 index 0000000..0f08910 --- /dev/null +++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java @@ -0,0 +1,45 @@ +package com.supwisdom.institute.backend.common.util; + +import java.text.ParseException; +import java.util.Date; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.commons.lang3.time.DateUtils; + +public class DateUtil { + + public static void main(String[] args) { + Date d0 = DateUtil.parseDate("2019-07-23 00:00:00", "yyyy-MM-dd HH:mm:ss"); + + Date d1 = DateUtil.parseDate("2019-07-23 23:59:59", "yyyy-MM-dd HH:mm:ss"); + + System.out.println(d0); + System.out.println(d1); + + String s0 = DateUtil.formatDate(DateUtil.now(), "yyyyMMddHHmmss"); + System.out.println(s0); + } + + public static Date parseDate(String source, String pattern) { + + try { + Date d = DateUtils.parseDate(source, pattern); + + return d; + } catch (ParseException e) { + e.printStackTrace(); + } + + return null; + } + + public static Date now() { + return new Date(); + } + + + public static String formatDate(Date date, String pattern) { + return DateFormatUtils.format(date, pattern); + } + +} diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java new file mode 100644 index 0000000..0a5f50f --- /dev/null +++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java @@ -0,0 +1,226 @@ +package com.supwisdom.institute.backend.common.util; + +import com.google.common.collect.Lists; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Map; + +public class MapBeanUtils { + + /** + * 判断 mapBean 中的 key 是否存在;若存在,则判断是否有值 + * + * @param mapBean + * @param key + * @return + */ + public static boolean containsValue(Map mapBean, String key) { + + if (!mapBean.containsKey(key)) { + return false; + } + + if (mapBean.get(key) == null) { + return false; + } + + if (String.valueOf(mapBean.get(key)).isEmpty()) { + return false; + } + + return true; + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 null + * + * @param mapBean + * @param key + * @return + */ + public static String getString(Map mapBean, String key) { + + return getString(mapBean, key, null); + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue + * + * @param mapBean + * @param key + * @param defaultValue + * @return + */ + public static String getString(Map mapBean, String key, String defaultValue) { + + if (containsValue(mapBean, key)) { + return String.valueOf(mapBean.get(key)); + } + + return defaultValue; + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 false + * + * @param mapBean + * @param key + * @return + */ + public static Boolean getBoolean(Map mapBean, String key) { + + return getBoolean(mapBean, key, null); + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue + * + * @param mapBean + * @param key + * @param defaultValue + * @return + */ + public static Boolean getBoolean(Map mapBean, String key, Boolean defaultValue) { + + if (containsValue(mapBean, key)) { + Boolean b = Boolean.valueOf(String.valueOf(mapBean.get(key))); + return b == null ? defaultValue : b; + } + + return defaultValue; + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 -1 + * + * @param mapBean + * @param key + * @return + */ + public static Integer getInteger(Map mapBean, String key) { + + return getInteger(mapBean, key, null); + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue + * + * @param mapBean + * @param key + * @param defaultValue + * @return + */ + public static Integer getInteger(Map mapBean, String key, Integer defaultValue) { + + if (containsValue(mapBean, key)) { + Integer i = Integer.valueOf(String.valueOf(mapBean.get(key))); + return i == null ? defaultValue : i; + } + + return defaultValue; + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 -1L + * + * @param mapBean + * @param key + * @return + */ + public static Long getLong(Map mapBean, String key) { + + return getLong(mapBean, key, null); + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue + * + * @param mapBean + * @param key + * @param defaultValue + * @return + */ + public static Long getLong(Map mapBean, String key, Long defaultValue) { + + if (containsValue(mapBean, key)) { + Long l = Long.valueOf(String.valueOf(mapBean.get(key))); + return l == null ? defaultValue : l; + } + + return defaultValue; + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 -1L + * + * @param mapBean + * @param key + * @return + */ + public static List getList(Map mapBean, String key) { + + return getList(mapBean, key, Lists.newArrayList()); + } + + /** + * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue + * + * @param mapBean + * @param key + * @param defaultValue + * @return + */ + public static List getList(Map mapBean, String key, List defaultValue) { + + if (containsValue(mapBean, key)) { + List l = (List)mapBean.get(key); + return l == null ? defaultValue : l; + } + + return defaultValue; + } + + /** + * 将一个 Map 对象转化为一个 JavaBean + * @param obj 要转化的对象 + * @param map 包含属性值的 map + * @return 转化出来的 JavaBean 对象 + * @throws IntrospectionException + * 如果分析类属性失败 + * @throws IllegalAccessException + * 如果实例化 JavaBean 失败 + * @throws InstantiationException + * 如果实例化 JavaBean 失败 + * @throws InvocationTargetException + * 如果调用属性的 setter 方法失败 + */ + public static Object convert2Bean(Object obj, Map map) + throws IntrospectionException, IllegalAccessException, + InstantiationException, InvocationTargetException { + BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // 获取类属性 + + // 给 JavaBean 对象的属性赋值 + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (int i = 0; i< propertyDescriptors.length; i++) { + PropertyDescriptor descriptor = propertyDescriptors[i]; + String propertyName = descriptor.getName(); + + if (map.containsKey(propertyName)) { + // 下面一句可以 try 起来,这样当一个属性赋值失败的时候就不会影响其他属性赋值。 + Object value = map.get(propertyName); + + Object[] args = new Object[1]; + args[0] = value; + + descriptor.getWriteMethod().invoke(obj, args); + } + } + return obj; + } + +} diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java new file mode 100644 index 0000000..1b9313e --- /dev/null +++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java @@ -0,0 +1,386 @@ +package com.supwisdom.institute.backend.common.util; + +import lombok.extern.slf4j.Slf4j; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.util.Assert; + +import java.lang.reflect.*; +import java.util.Date; + +/** + * 利用反射进行操作的一个工具类 + * + * @author fengpy + */ +@SuppressWarnings("rawtypes") +@Slf4j +public class ReflectUtils { + + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + /** + * 利用反射获取指定对象里面的指定属性 + * + * @param obj + * 目标对象 + * @param fieldName + * 目标属性 + * @return 目标字段 + */ + private static Field getField(Object obj, String fieldName) { + Field field = null; + for (Class clazz = obj.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) { + try { + field = clazz.getDeclaredField(fieldName); + break; + } catch (NoSuchFieldException e) { + // 这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。 + } + } + return field; + } + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + public static Object invokeGetter(Object obj, String propertyName) { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")){ + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, Object value, Class valueCla) throws IllegalAccessException, InstantiationException { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i=0; i[] parameterTypes, + final Object[] args) { + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) { + throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); + } + + try { + return method.invoke(obj, args); + } catch (Exception e) { + throw convertReflectionExceptionToUnchecked(e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { + Method method = getAccessibleMethodByName(obj, methodName); + if (method == null) { + throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); + } + + try { + return method.invoke(obj, args); + } catch (Exception e) { + throw convertReflectionExceptionToUnchecked(e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) { + Validate.notNull(obj, "object can't be null"); + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { + try { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } catch (NoSuchFieldException e) {//NOSONAR + // Field不在当前类定义,继续向上转型 + continue;// new add + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) { + Validate.notNull(obj, "object can't be null"); + Validate.notBlank(methodName, "methodName can't be blank"); + + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + try { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } catch (NoSuchMethodException e) { + // Method不在当前类定义,继续向上转型 + continue;// new add + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName) { + Validate.notNull(obj, "object can't be null"); + Validate.notBlank(methodName, "methodName can't be blank"); + + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(methodName)) { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier + .isFinal(field.getModifiers())) && !field.isAccessible()) { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + * eg. + * public UserDao extends HibernateDao + * + * @param clazz The class to introspect + * @return the first generic declaration, or Object.class if cannot be determined + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + * + * 如public UserDao extends HibernateDao + * + * @param clazz clazz The class to introspect + * @param index the Index of the generic ddeclaration,start from 0. + * @return the index generic declaration, or Object.class if cannot be determined + */ + public static Class getClassGenricType(final Class clazz, final int index) { + + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) { + log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) { + log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) { + log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) { + Assert.notNull(instance, "Instance must not be null"); + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) { + return new IllegalArgumentException(e); + } else if (e instanceof InvocationTargetException) { + return new RuntimeException(((InvocationTargetException) e).getTargetException()); + } else if (e instanceof RuntimeException) { + return (RuntimeException) e; + } + return new RuntimeException("Unexpected Checked Exception.", e); + } + + /** + * 类型转换 + * + * @param clazz + * :目标类型 + * @param source + * :待转换对象 + * @return :目标对象 + */ + public static Object typeConversion(Class clazz, String source) { + + if (clazz == null) { + throw new IllegalArgumentException("clazz should not be null"); + } + + Object targetObj = null; + String nameType = clazz.getName(); + + if ("java.lang.Integer".equals(nameType) || "int".equals(nameType)) { + targetObj = Integer.valueOf(source); + } else if ("java.lang.String".equals(nameType) || "string".equals(nameType)) { + targetObj = source; + } else if ("java.lang.Float".equals(nameType) || "float".equals(nameType)) { + targetObj = Float.valueOf(source); + } else if ("java.lang.Double".equals(nameType) || "double".equals(nameType)) { + targetObj = Double.valueOf(source); + } else if ("java.lang.Boolean".equals(nameType) || "boolean".equals(nameType)) { + targetObj = Boolean.valueOf(source); + } else if ("java.lang.Long".equals(nameType) || "long".equals(nameType)) { + targetObj = Long.valueOf(source); + } else if ("java.lang.Short".equals(nameType) || "short".equals(nameType)) { + targetObj = Short.valueOf(source); + } else if ("java.lang.Character".equals(nameType) || "char".equals(nameType)) { + targetObj = source.charAt(1); + }else if ("java.util.Date".equals(nameType)) { + targetObj = new Date(source); + } + + return targetObj; + } + + + /** + * 根据类的全路径获取class + * @param fullPath + * :类的全路径 + * @return :class + */ + public static Class fullPath2Class(String fullPath) { + Class cl = null; + try { + ClassLoader loader = ClassLoader.getSystemClassLoader(); + cl = loader.loadClass(fullPath); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return cl; + } + + private static Object doSpecial(Object value, Class valueCla){ + //TODO 针对sql脚本的类型和实体entity的类型不一致做的特殊处理(有待优化) + if(valueCla.equals(Boolean.class)&&value.getClass().equals(Integer.class)){ + value = typeConversion(Boolean.class,value.toString()); + } + return value; + } +} diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java new file mode 100644 index 0000000..d348d91 --- /dev/null +++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java @@ -0,0 +1,87 @@ +package com.supwisdom.institute.backend.common.util; + +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.locks.ReentrantLock; + +public class UUIDUtils { + + private static boolean IS_THREADLOCALRANDOM_AVAILABLE = false; + private static Random random; + private static final long leastSigBits; + private static final ReentrantLock lock = new ReentrantLock(); + private static long lastTime; + + static { + try { + IS_THREADLOCALRANDOM_AVAILABLE = null != UUIDUtils.class.getClassLoader().loadClass( + "java.util.concurrent.ThreadLocalRandom"); + } catch (ClassNotFoundException e) { + } + + byte[] seed = new SecureRandom().generateSeed(8); + leastSigBits = new BigInteger(seed).longValue(); + if (!IS_THREADLOCALRANDOM_AVAILABLE) { + random = new Random(leastSigBits); + } + } + + private UUIDUtils() {} + + /** + * 生成32位随机码 + * @return + */ + public static String random() { + byte[] randomBytes = new byte[16]; + if (IS_THREADLOCALRANDOM_AVAILABLE) { + java.util.concurrent.ThreadLocalRandom.current().nextBytes(randomBytes); + } else { + random.nextBytes(randomBytes); + } + + long mostSigBits = 0; + for (int i = 0; i < 8; i++) { + mostSigBits = (mostSigBits << 8) | (randomBytes[i] & 0xff); + } + long leastSigBits = 0; + for (int i = 8; i < 16; i++) { + leastSigBits = (leastSigBits << 8) | (randomBytes[i] & 0xff); + } + + return new UUID(mostSigBits, leastSigBits).toString().replaceAll("-", ""); + } + + /** + * 生成32位随机码 + * @return + */ + public static String create() { + long timeMillis = (System.currentTimeMillis() * 10000) + 0x01B21DD213814000L; + + lock.lock(); + try { + if (timeMillis > lastTime) { + lastTime = timeMillis; + } else { + timeMillis = ++lastTime; + } + } finally { + lock.unlock(); + } + + long mostSigBits = timeMillis << 32; + mostSigBits |= (timeMillis & 0xFFFF00000000L) >> 16; + mostSigBits |= 0x1000 | ((timeMillis >> 48) & 0x0FFF); + return new UUID(mostSigBits, leastSigBits).toString().replaceAll("-", ""); + + } + + public static void main(String[] args){ + System.out.println(random()); + System.out.println(create()); + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..af472b8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,204 @@ + + + 4.0.0 + + + com.supwisdom.buildcommons + spring-cloud-parent + Finchley.RELEASE-1.1 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + pom + + Supwisdom Backend Framework Parent + Supwisdom Backend Framework Parent project + + + common + + system + biz + + sa + bff + + + + + UTF-8 + 1.8 + + -Dfile.encoding=UTF-8 + + true + true + + ${java.version} + ${java.version} + + 1.4.8 + harbor.supwisdom.com + sw-backend + + 0.1.0-SNAPSHOT + + 2.9.2 + + 1.3.1 + + + + + + supwisdom-releases + internal release + https://app.supwisdom.com/nexus/content/repositories/releases + + + supwisdom-snapshots + internal snapshots + https://app.supwisdom.com/nexus/content/repositories/snapshots + + + + + + + true + + supwisdom + https://app.supwisdom.com/nexus/content/groups/public/ + + + + false + + central + http://repo.maven.apache.org/maven2 + + + + + + + + com.supwisdom.infras + infras-bom + ${infras.version} + pom + import + + + + + com.supwisdom.institute + sw-backend-common-core + ${project.version} + + + + com.supwisdom.institute + sw-backend-common-utils + ${project.version} + + + + com.supwisdom.institute + sw-backend-common-framework + ${project.version} + + + + com.supwisdom.institute + sw-backend-system-domain + ${project.version} + + + com.supwisdom.institute + sw-backend-system-api + ${project.version} + + + + com.supwisdom.institute + sw-backend-biz-domain + ${project.version} + + + com.supwisdom.institute + sw-backend-biz-api + ${project.version} + + + + + mysql + mysql-connector-java + 8.0.12 + + + + com.alibaba + fastjson + 1.2.56 + + + + + com.google.guava + guava + 28.0-jre + + + + io.springfox + springfox-swagger2 + ${io.springfox.version} + + + io.springfox + springfox-swagger-ui + ${io.springfox.version} + + + + + + + + + + com.spotify + dockerfile-maven-plugin + ${dockerfile-maven-plugin.version} + + ${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId} + ${project.version} + true + + ${project.build.finalName}.${project.packaging} + ${project.version} + ${project.artifactId} + + + + + + + + + com.spotify + dockerfile-maven-plugin + + true + + + + + + + diff --git a/sa/admin/Dockerfile b/sa/admin/Dockerfile new file mode 100644 index 0000000..4dc87c6 --- /dev/null +++ b/sa/admin/Dockerfile @@ -0,0 +1,21 @@ +FROM harbor.supwisdom.com/institute/openjdk:8-jre-alpine + +ENV ENABLE_JMX_SSL=false +ENV JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker +ENV SPRING_PROFILES_ACTIVE=docker + +ARG NAME +ARG VERSION +ARG JAR_FILE + +LABEL name=$NAME \ + version=$VERSION + +EXPOSE 8080 + +EXPOSE 8443 + +COPY --chown=java-app:java-app target/${JAR_FILE} /home/java-app/lib/app.jar + +COPY --chown=java-app:java-app target/doc /home/java-app/doc +COPY --chown=java-app:java-app target/api-docs /home/java-app/api-docs diff --git a/sa/admin/pom.xml b/sa/admin/pom.xml new file mode 100644 index 0000000..09c386c --- /dev/null +++ b/sa/admin/pom.xml @@ -0,0 +1,201 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-admin-sa + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework Admin Super Admin + Supwisdom Backend Framework Admin Super Admin project + + + com.supwisdom.institute.backend.admin.sa.Application + + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-web + + + + com.supwisdom.infras + infras-online-doc + + + + + com.supwisdom.infras + infras-mvc + + + + com.supwisdom.infras + infras-object-mapper + + + + com.supwisdom.infras + infras-i18n + + + + com.supwisdom.infras + infras-lang + + + + + com.supwisdom.institute + sw-backend-system-api + + + com.supwisdom.institute + sw-backend-biz-api + + + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + + + mysql + mysql-connector-java + runtime + + + + + org.springframework.boot + spring-boot-devtools + runtime + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + com.spotify + dockerfile-maven-plugin + + false + + + + + + + + diff --git a/sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java b/sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java new file mode 100644 index 0000000..252e9bf --- /dev/null +++ b/sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java @@ -0,0 +1,45 @@ +package com.supwisdom.institute.backend.admin.sa; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc; +import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit; + +@SpringBootApplication + +@EnableSimpleUserTransmit + +@EnableInfrasOnlineDoc + +@EntityScan(basePackages = {"com.supwisdom.**.domain.entity"}) // 扫描子项目下的实体 +@EnableJpaRepositories(basePackages = {"com.supwisdom.**.domain.repo"}) // 扫描子项目下的持久类 +@ComponentScan(basePackages = {"com.supwisdom"}) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public CorsFilter corsFilter() { + final CorsConfiguration config = new CorsConfiguration(); + // config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/v2/api-docs", config); + + return new CorsFilter(source); + } + +} diff --git a/sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java b/sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java new file mode 100644 index 0000000..1eb942e --- /dev/null +++ b/sa/admin/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java @@ -0,0 +1,63 @@ +package com.supwisdom.institute.backend.admin.sa.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class Swagger2Config { + + @Value("${swagger2.apis.basePackage:com.supwisdom.institute}") + private String basePackage; + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage(basePackage)) + .paths(PathSelectors.any()) + .build() + ; + } + + private ApiInfo apiInfo() { + Contact contact = new Contact("Backend Admin Super Admin", "https://sw-backend-sa.supwisdom.com/swagger-ui.html", ""); // name, url, email + return new ApiInfoBuilder() + .title("Backend Admin Super Admin APIs") + .description("管理后台 - 服务接口") + .termsOfServiceUrl("http://www.supwisdom.com/") + .contact(contact) + .version("1.0") + .build(); + } + + @Bean + UiConfiguration uiConfig() { + + return UiConfigurationBuilder.builder().build(); + +// return new UiConfiguration(null, // url +// "none", // docExpansion => none | list +// "alpha", // apiSorter => alpha +// "schema", // defaultModelRendering => schema +// UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS, +// false, // enableJsonEditor => true || false +// true, // showRequestHeaders => true | false +// 60000L); // requestTimeout => in milliseconds, defaults to null +// // (uses jquery xh timeout) + } + +} diff --git a/sa/admin/src/main/resources/application-docker.yml b/sa/admin/src/main/resources/application-docker.yml new file mode 100644 index 0000000..ba6bbce --- /dev/null +++ b/sa/admin/src/main/resources/application-docker.yml @@ -0,0 +1,46 @@ +server: + port: ${SERVER_PORT:8443} + ssl: + enabled: ${SSL_ENABLED:true} + clientAuth: NEED + key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore} + key-store-password: ${SSL_KEYSTORE_PASSWORD:} + trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore} + trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:} + tomcat: + accesslog: + enabled: ${TOMCAT_ACCESSLOG_ENABLED:false} + buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true} + directory: ${TOMCAT_ACCESSLOG_DIR:log} + prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog} + suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log} + file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd} + rotate: ${TOMCAT_ACCESSLOG_ROTATE:true} + + +## +# logging +# +logging: + level: + root: INFO + com.supwisdom: INFO + + +spring: + jackson: + time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai} + + datasource: + driver-class-name: ${JDBC_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.Driver} + url: ${JDBC_URL:jdbc:mysql://mysql-server:3306/user_authorization_service} + username: ${JDBC_USERNAME:user_authorization_service} + password: ${JDBC_PASSWORD:} + + +## +# online-doc +# +infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false} +infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/} +infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/} diff --git a/sa/admin/src/main/resources/application.yml b/sa/admin/src/main/resources/application.yml new file mode 100644 index 0000000..571cbd7 --- /dev/null +++ b/sa/admin/src/main/resources/application.yml @@ -0,0 +1,48 @@ +server: + port: 8081 + ssl: + enabled: false + + +## +# logging +# +logging: + level: + root: INFO + com.supwisdom: DEBUG +# org.springframework.web: INFO +# org.springframework.cloud.openfeign: INFO + + +spring: + jackson: + time-zone: Asia/Shanghai + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sw-backend + username: root + password: root + hikari: + data-source-properties: + useSSL: false + characterEncoding: utf8 + characterSetResults: utf8 + jpa: + hibernate: + ddl-auto: none + naming: + physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + show-sql: true + + +## +# infras.online-doc +# +infras.online-doc.enabled: false +infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/doc/ +infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/api-docs/ + + +swagger2.apis.basePackage: com.supwisdom.institute diff --git a/sa/admin/src/main/resources/bootstrap.yml b/sa/admin/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..5e82cca --- /dev/null +++ b/sa/admin/src/main/resources/bootstrap.yml @@ -0,0 +1,3 @@ +spring: + application: + name: sw-backend-admin-sa diff --git a/sa/pom.xml b/sa/pom.xml new file mode 100644 index 0000000..e4c2665 --- /dev/null +++ b/sa/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + + + com.supwisdom.institute + sw-backend-sa-aggregator + 0.0.1-SNAPSHOT + pom + + Supwisdom Backend Framework Super Admin Aggregator + Supwisdom Backend Framework Super Admin Aggregator project + + + admin + + + + + + maven-deploy-plugin + + true + + + + + + diff --git a/system/api/pom.xml b/system/api/pom.xml new file mode 100644 index 0000000..5f7637f --- /dev/null +++ b/system/api/pom.xml @@ -0,0 +1,111 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-system-api + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework System API + Supwisdom Backend Framework System API project + + + + + org.projectlombok + lombok + provided + + + + javax.servlet + javax.servlet-api + provided + + + + + com.supwisdom.institute + sw-backend-common-core + + + + com.supwisdom.institute + sw-backend-common-utils + + + + com.supwisdom.institute + sw-backend-common-framework + + + + + com.supwisdom.institute + sw-backend-system-domain + + + + + org.springframework.boot + spring-boot-starter + + + + + com.supwisdom.infras + infras-mvc + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + diff --git a/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminAccountController.java b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminAccountController.java new file mode 100644 index 0000000..d23f7c9 --- /dev/null +++ b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminAccountController.java @@ -0,0 +1,5 @@ +package com.supwisdom.institute.backend.system.api.v1.admin; + +public class AdminAccountController { + +} diff --git a/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminConfigController.java b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminConfigController.java new file mode 100644 index 0000000..9eac867 --- /dev/null +++ b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminConfigController.java @@ -0,0 +1,197 @@ +package com.supwisdom.institute.backend.system.api.v1.admin; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.util.MimeTypeUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse; +import com.supwisdom.institute.backend.system.domain.entity.Config; +import com.supwisdom.institute.backend.system.domain.exception.ConfigException; +import com.supwisdom.institute.backend.system.domain.service.ConfigService; +import com.supwisdom.institute.backend.system.domain.vo.request.ConfigCreateRequest; +import com.supwisdom.institute.backend.system.domain.vo.request.ConfigQueryRequest; +import com.supwisdom.institute.backend.system.domain.vo.request.ConfigUpdateRequest; +import com.supwisdom.institute.backend.system.domain.vo.response.ConfigCreateResponseData; +import com.supwisdom.institute.backend.system.domain.vo.response.ConfigLoadResponseData; +import com.supwisdom.institute.backend.system.domain.vo.response.ConfigQueryResponseData; +import com.supwisdom.institute.backend.system.domain.vo.response.ConfigUpdateResponseData; + +@Api(value = "SystemAdminConfig", tags = { "SystemAdminConfig" }, description = "配置项的操作接口") +@Slf4j +@RestController +@RequestMapping("/v1/admin/configs") +public class AdminConfigController { + + @Autowired + private ConfigService configService; + + + /** + * @param configQueryRequest + * @return + */ + @ApiOperation(value = "查询配置列表", notes = "查询配置列表", nickname = "systemAdminConfigQuery") + @ApiImplicitParams({ + @ApiImplicitParam(name = "loadAll", value = "是否加载全部", required = true, dataType = "boolean", paramType = "query", defaultValue = "false"), + @ApiImplicitParam(name = "pageIndex", value = "分页 - 页码", required = true, dataType = "int", paramType = "query", defaultValue = "0", example = "0"), + @ApiImplicitParam(name = "pageSize", value = "分页 - 每页记录数", required = true, dataType = "int", paramType = "query", defaultValue = "20", example = "20"), + @ApiImplicitParam(name = "mapBean[deleted]", value = "查询条件 - 删除状态 (精确)", required = false, dataType = "boolean", paramType = "query"), + @ApiImplicitParam(name = "mapBean[categoryCode]", value = "查询条件 - 分类代码 (精确)", required = false, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = "mapBean[categoryName]", value = "查询条件 - 分类名称 (模糊)", required = false, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = "mapBean[name]", value = "查询条件 - 名称 (模糊)", required = false, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = "mapBean[description]", value = "查询条件 - 描述 (模糊)", required = false, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = "mapBean[configKey]", value = "查询条件 - 配置Key (精确)", required = false, dataType = "string", paramType = "query"), + }) + @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + @ResponseStatus(value = HttpStatus.OK) + @ResponseBody + public DefaultApiResponse query(ConfigQueryRequest configQueryRequest) { + + Page page = configService.selectPageList( + configQueryRequest.isLoadAll(), + configQueryRequest.getPageIndex(), + configQueryRequest.getPageSize(), + configQueryRequest.getMapBean(), + configQueryRequest.getOrderBy()); + + ConfigQueryResponseData resp = ConfigQueryResponseData.of(configQueryRequest).build(page); + + return new DefaultApiResponse(resp); + } + + /** + * @param id + * @return + */ + @ApiOperation(value = "根据ID获取配置项", notes = "根据ID获取配置项", nickname="systemAdminConfigLoad") + @RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + @ResponseStatus(value = HttpStatus.OK) + @ResponseBody + public DefaultApiResponse load( + @PathVariable("id") String id) { + + if (id == null || id.length() == 0) { + throw new ConfigException().newInstance("exception.get.id.must.not.empty"); + } + + Config config = configService.selectById(id); + + if (config == null) { + throw new ConfigException().newInstance("exception.get.domain.not.exist"); + } + + ConfigLoadResponseData resp = ConfigLoadResponseData.build(config); + + return new DefaultApiResponse(resp); + } + + /** + * @param configCreateRequest + * @return + */ + @ApiOperation(value = "创建配置项", notes = "创建配置项", nickname = "systemAdminConfigCreate") + @RequestMapping(method = RequestMethod.POST, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + @ResponseStatus(value = HttpStatus.CREATED) + @ResponseBody + public DefaultApiResponse create( + @RequestBody ConfigCreateRequest configCreateRequest) { + + // FIXME: 验证数据有效性 + + Config entity = configCreateRequest.getEntity(); + + Config ret = configService.insert(entity); + + ConfigCreateResponseData resp = ConfigCreateResponseData.build(ret); + + return new DefaultApiResponse(resp); + } + + @ApiOperation(value = "更新配置项", notes = "更新配置项", nickname = "systemAdminConfigUpdate") + @RequestMapping(method = RequestMethod.PUT, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + @ResponseStatus(value = HttpStatus.OK) + @ResponseBody + public DefaultApiResponse update( + @PathVariable("id") String id, + @RequestBody ConfigUpdateRequest configUpdateRequest) { + + Config entity = configUpdateRequest.getEntity(); + + if (entity.getId() == null || entity.getId().length() == 0) { + throw new ConfigException().newInstance("exception.update.id.must.not.empty"); + } + + Config tmp = configService.selectById(entity.getId()); + if (tmp == null) { + throw new ConfigException().newInstance("exception.update.domain.not.exist"); + } + + if (!tmp.getEditable().booleanValue()) { + throw new ConfigException().newInstance("exception.editable.can.not.update"); + } + + entity = EntityUtils.merge(tmp, entity); + +// if (tmp.getEditable().booleanValue() != entity.getEditable().booleanValue()) { +// throw new ConfigException().newInstance("exception.editable.can.not.update"); +// } + + entity.setEditable(true); // 防止 可修改记录的 editable 被置为false + + Config ret = configService.update(entity); + + ConfigUpdateResponseData resp = ConfigUpdateResponseData.build(ret); + + return new DefaultApiResponse(resp); + } + + + /** + * @param categoryCode + * @param configKey + * @return + */ + @ApiOperation(value = "根据 categoryCode、configKey 获取配置项", notes = "根据 categoryCode、configKey 获取配置项", nickname = "systemAdminConfigLoadByCategoryKey") + @RequestMapping(method = RequestMethod.GET, path = "/loadByCategoryKey", produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + @ResponseStatus(value = HttpStatus.OK) + @ResponseBody + public DefaultApiResponse loadByCategoryKey( + @RequestParam("categoryCode") String categoryCode, + @RequestParam("configKey") String configKey + ) { + + if (categoryCode == null || categoryCode.length() == 0) { + throw new ConfigException().newInstance("exception.load.params.must.not.empty"); + } + if (configKey == null || configKey.length() == 0) { + throw new ConfigException().newInstance("exception.load.params.must.not.empty"); + } + + Config config = configService.selectByCategoryKey(categoryCode, configKey); + + if (config == null) { + throw new ConfigException().newInstance("exception.load.domain.not.exist"); + } + + ConfigLoadResponseData resp = ConfigLoadResponseData.build(config); + + return new DefaultApiResponse(resp); + } + +} diff --git a/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminFunctionController.java b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminFunctionController.java new file mode 100644 index 0000000..fcb3c6a --- /dev/null +++ b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminFunctionController.java @@ -0,0 +1,5 @@ +package com.supwisdom.institute.backend.system.api.v1.admin; + +public class AdminFunctionController { + +} diff --git a/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminResourceController.java b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminResourceController.java new file mode 100644 index 0000000..929d755 --- /dev/null +++ b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminResourceController.java @@ -0,0 +1,5 @@ +package com.supwisdom.institute.backend.system.api.v1.admin; + +public class AdminResourceController { + +} diff --git a/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminRoleController.java b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminRoleController.java new file mode 100644 index 0000000..4a7a517 --- /dev/null +++ b/system/api/src/main/java/com/supwisdom/institute/backend/system/api/v1/admin/AdminRoleController.java @@ -0,0 +1,5 @@ +package com.supwisdom.institute.backend.system.api.v1.admin; + +public class AdminRoleController { + +} diff --git a/system/domain/pom.xml b/system/domain/pom.xml new file mode 100644 index 0000000..8e8e2fb --- /dev/null +++ b/system/domain/pom.xml @@ -0,0 +1,102 @@ + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + ../../ + + + com.supwisdom.institute + sw-backend-system-domain + 0.0.1-SNAPSHOT + jar + + Supwisdom Backend Framework System Domain + Supwisdom Backend Framework System Domain project + + + + + org.projectlombok + lombok + provided + + + + + com.supwisdom.institute + sw-backend-common-core + ${project.version} + + + + com.supwisdom.institute + sw-backend-common-utils + ${project.version} + + + + com.supwisdom.institute + sw-backend-common-framework + ${project.version} + + + + + org.springframework.boot + spring-boot-starter + + + + + com.supwisdom.infras + infras-data-jpa + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/entity/Config.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/entity/Config.java new file mode 100644 index 0000000..16300ef --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/entity/Config.java @@ -0,0 +1,80 @@ +package com.supwisdom.institute.backend.system.domain.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +import lombok.Getter; +import lombok.Setter; + +import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity; + +/** + * @author loie + */ +@Entity +@Table(name = "TB_CONFIG") +public class Config extends ABaseEntity { + + /** + * + */ + private static final long serialVersionUID = -2721844710909809785L; + + /** + * 分类代码 + */ + @Getter + @Setter + @Column(name = "CATEGORY_CODE") + private String categoryCode; + + /** + * 分类名称 + */ + @Getter + @Setter + @Column(name = "CATEGORY_NAME") + private String categoryName; + + /** + * 名称 + */ + @Getter + @Setter + @Column(name = "NAME") + private String name; + + /** + * 描述 + */ + @Getter + @Setter + @Column(name = "DESCRIPTION") + private String description; + + /** + * 配置键 + */ + @Getter + @Setter + @Column(name = "CONFIG_KEY") + private String configKey; + + /** + * 配置值 + */ + @Getter + @Setter + @Column(name = "CONFIG_VALUE") + private String configValue; + + /** + * 是否可修改 + */ + @Getter + @Setter + @Column(name = "EDITABLE") + private Boolean editable; + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/exception/ConfigException.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/exception/ConfigException.java new file mode 100644 index 0000000..2a9957e --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/exception/ConfigException.java @@ -0,0 +1,12 @@ +package com.supwisdom.institute.backend.system.domain.exception; + +import com.supwisdom.institute.backend.common.framework.exception.BaseException; + +public class ConfigException extends BaseException { + + /** + * + */ + private static final long serialVersionUID = 8112079911386045865L; + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/repo/ConfigRepository.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/repo/ConfigRepository.java new file mode 100644 index 0000000..3d6ce38 --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/repo/ConfigRepository.java @@ -0,0 +1,77 @@ +package com.supwisdom.institute.backend.system.domain.repo; + +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Repository; + +import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository; +import com.supwisdom.institute.backend.common.util.MapBeanUtils; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +import java.util.Map; +import java.util.Optional; + +/** + * @author loie + */ +@Repository +public interface ConfigRepository extends BaseJpaRepository { + + public default Page selectPageList(boolean loadAll, int pageIndex, int pageSize, Map mapBean, Map orderBy) { + Config probe = new Config(); + if (mapBean != null) { + probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted")); + probe.setCategoryCode(MapBeanUtils.getString(mapBean, "categoryCode")); + probe.setCategoryName(MapBeanUtils.getString(mapBean, "categoryName")); + probe.setName(MapBeanUtils.getString(mapBean, "name")); + probe.setDescription(MapBeanUtils.getString(mapBean, "description")); + probe.setConfigKey(MapBeanUtils.getString(mapBean, "configKey")); + probe.setEditable(MapBeanUtils.getBoolean(mapBean, "editable")); + } + + ExampleMatcher matcher = ExampleMatcher.matching() + .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact()) + .withMatcher("categoryCode", ExampleMatcher.GenericPropertyMatchers.exact()) + .withMatcher("categoryName", ExampleMatcher.GenericPropertyMatchers.contains()) + .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains()) + .withMatcher("description", ExampleMatcher.GenericPropertyMatchers.contains()) + .withMatcher("configKey", ExampleMatcher.GenericPropertyMatchers.exact()) + .withMatcher("editable", ExampleMatcher.GenericPropertyMatchers.exact()) + ; + + if (loadAll) { + pageIndex = 0; + pageSize = Integer.MAX_VALUE; + } + + PageRequest pageRequest = PageRequest.of(pageIndex, pageSize); + Example example = Example.of(probe, matcher); + + Page page = this.findAll(example, pageRequest); + + return page; + } + + public default Config selectByCategoryKey(String categoryCode, String configKey) { + Config probe = new Config(); + + probe.setDeleted(false); + probe.setCategoryCode(categoryCode); + probe.setConfigKey(configKey); + + ExampleMatcher matcher = ExampleMatcher.matching() + .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact()) + .withMatcher("categoryCode", ExampleMatcher.GenericPropertyMatchers.exact()) + .withMatcher("configKey", ExampleMatcher.GenericPropertyMatchers.exact()) + ; + + Example example = Example.of(probe, matcher); + + Optional config = this.findOne(example); + + return config.isPresent() ? config.get() : null; + } + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/service/ConfigService.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/service/ConfigService.java new file mode 100644 index 0000000..858da54 --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/service/ConfigService.java @@ -0,0 +1,26 @@ +package com.supwisdom.institute.backend.system.domain.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.supwisdom.institute.backend.common.framework.service.ABaseService; +import com.supwisdom.institute.backend.system.domain.entity.Config; +import com.supwisdom.institute.backend.system.domain.repo.ConfigRepository; + +@Service +public class ConfigService extends ABaseService { + + @Autowired + private ConfigRepository configRepository; + + @Override + public ConfigRepository getRepo() { + return configRepository; + } + + public Config selectByCategoryKey(String categoryCode, String configKey) { + + return configRepository.selectByCategoryKey(categoryCode, configKey); + } + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigCreateRequest.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigCreateRequest.java new file mode 100644 index 0000000..8c741fe --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigCreateRequest.java @@ -0,0 +1,21 @@ +package com.supwisdom.institute.backend.system.domain.vo.request; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +/** + * @author loie + */ +public class ConfigCreateRequest extends Config implements IApiCreateRequest { + + /** + * + */ + private static final long serialVersionUID = 8380208871984763567L; + + public Config getEntity() { + return EntityUtils.copy(this, new Config()); + } + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigQueryRequest.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigQueryRequest.java new file mode 100644 index 0000000..e83083b --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigQueryRequest.java @@ -0,0 +1,40 @@ +package com.supwisdom.institute.backend.system.domain.vo.request; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; + +import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest; + +import io.swagger.annotations.ApiModelProperty; + +/** + * @author loie + */ +public class ConfigQueryRequest implements IApiQueryRequest { + + /** + * + */ + private static final long serialVersionUID = -1033044092932525382L; + + @Getter + @Setter + private boolean loadAll = false; + @Getter + @Setter + private int pageIndex = 0; + @Getter + @Setter + private int pageSize = 20; + @Getter + @Setter + @ApiModelProperty(hidden = true) + private Map mapBean; + @Getter + @Setter + @ApiModelProperty(hidden = true) + private Map orderBy; + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigUpdateRequest.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigUpdateRequest.java new file mode 100644 index 0000000..6f7e1a5 --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/request/ConfigUpdateRequest.java @@ -0,0 +1,29 @@ +package com.supwisdom.institute.backend.system.domain.vo.request; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author loie + */ +public class ConfigUpdateRequest extends Config implements IApiUpdateRequest { + + /** + * + */ + private static final long serialVersionUID = 6002556449210326472L; + + @Getter + @Setter + private String id; + + + public Config getEntity() { + return EntityUtils.copy(this, new Config()); + } + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigCreateResponseData.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigCreateResponseData.java new file mode 100644 index 0000000..a14a607 --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigCreateResponseData.java @@ -0,0 +1,32 @@ +package com.supwisdom.institute.backend.system.domain.vo.response; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author loie + */ +public class ConfigCreateResponseData extends Config implements IApiCreateResponseData { + + /** + * + */ + private static final long serialVersionUID = -2300091307366254182L; + + @Getter + @Setter + private String id; + + private ConfigCreateResponseData() { + + } + + public static ConfigCreateResponseData build(Config entity) { + ConfigCreateResponseData configCreateResponse = new ConfigCreateResponseData(); + return EntityUtils.copy(entity, configCreateResponse); + } +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigLoadResponseData.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigLoadResponseData.java new file mode 100644 index 0000000..a32312d --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigLoadResponseData.java @@ -0,0 +1,34 @@ +package com.supwisdom.institute.backend.system.domain.vo.response; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author loie + */ +public class ConfigLoadResponseData extends Config implements IApiLoadResponseData { + + /** + * + */ + private static final long serialVersionUID = -579946566129915779L; + + @Getter + @Setter + private String id; + + + private ConfigLoadResponseData() { + + } + + public static ConfigLoadResponseData build(Config entity) { + ConfigLoadResponseData configCreateResponse = new ConfigLoadResponseData(); + return EntityUtils.copy(entity, configCreateResponse); + } + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigQueryResponseData.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigQueryResponseData.java new file mode 100644 index 0000000..906d681 --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigQueryResponseData.java @@ -0,0 +1,83 @@ +package com.supwisdom.institute.backend.system.domain.vo.response; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import java.util.Map; + +import org.springframework.data.domain.Page; + +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData; +import com.supwisdom.institute.backend.system.domain.entity.Config; +import com.supwisdom.institute.backend.system.domain.vo.request.ConfigQueryRequest; + +/** + * @author loie + */ +public class ConfigQueryResponseData implements IApiQueryResponseData { + + /** + * + */ + private static final long serialVersionUID = 3188467441502226095L; + +// private ConfigQueryResponseData() { +// } + + public ConfigQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map mapBean, Map orderBy) { + this.loadAll = loadAll; + this.pageIndex = pageIndex; + this.pageSize = pageSize; + this.mapBean = mapBean; + this.orderBy = orderBy; + } + + public static ConfigQueryResponseData of(ConfigQueryRequest configQueryRequest) { + ConfigQueryResponseData configQueryResponse = new ConfigQueryResponseData( + configQueryRequest.isLoadAll(), + configQueryRequest.getPageIndex(), + configQueryRequest.getPageSize(), + configQueryRequest.getMapBean(), + configQueryRequest.getOrderBy() + ); + + return configQueryResponse; + } + + public ConfigQueryResponseData build(Page page) { + this.currentItemCount = page.getNumberOfElements(); + this.pageCount = page.getTotalPages(); + this.recordCount = page.getTotalElements(); + this.items = page.getContent(); + + return this; + } + + @Getter + private boolean loadAll; + @Getter + private int pageIndex; + @Getter + private int pageSize; + @Getter + private Map mapBean; + @Getter + private Map orderBy; + + @Getter + @Setter + private int pageCount; + @Getter + @Setter + private long recordCount; + + @Getter + @Setter + private int currentItemCount; + + @Getter + @Setter + private List items; + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigRemoveResponseData.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigRemoveResponseData.java new file mode 100644 index 0000000..556307b --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigRemoveResponseData.java @@ -0,0 +1,36 @@ +package com.supwisdom.institute.backend.system.domain.vo.response; + +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.Id; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +/** + * @author loie + */ +public class ConfigRemoveResponseData implements IApiRemoveResponseData { + + /** + * + */ + private static final long serialVersionUID = 8510464738198696332L; + + @Getter + @Setter + @Id + private String id; + + private ConfigRemoveResponseData() { + + } + + public static ConfigRemoveResponseData build(Config entity) { + ConfigRemoveResponseData configRemoveResponse = new ConfigRemoveResponseData(); + return EntityUtils.copy(entity, configRemoveResponse); + } + +} diff --git a/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigUpdateResponseData.java b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigUpdateResponseData.java new file mode 100644 index 0000000..51ca051 --- /dev/null +++ b/system/domain/src/main/java/com/supwisdom/institute/backend/system/domain/vo/response/ConfigUpdateResponseData.java @@ -0,0 +1,33 @@ +package com.supwisdom.institute.backend.system.domain.vo.response; + +import com.supwisdom.institute.backend.common.framework.entity.EntityUtils; +import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData; +import com.supwisdom.institute.backend.system.domain.entity.Config; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author loie + */ +public class ConfigUpdateResponseData extends Config implements IApiUpdateResponseData { + + /** + * + */ + private static final long serialVersionUID = 2798387429543859170L; + + @Getter + @Setter + private String id; + + private ConfigUpdateResponseData() { + + } + + public static ConfigUpdateResponseData build(Config entity) { + ConfigUpdateResponseData configUpdateResponse = new ConfigUpdateResponseData(); + return EntityUtils.copy(entity, configUpdateResponse); + } + +} diff --git a/system/pom.xml b/system/pom.xml new file mode 100644 index 0000000..d80ee43 --- /dev/null +++ b/system/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + + com.supwisdom.institute + sw-backend-parent + 0.0.1-SNAPSHOT + + + com.supwisdom.institute + sw-backend-system-aggregator + 0.0.1-SNAPSHOT + pom + + Supwisdom Backend Framework System Aggregator + Supwisdom Backend Framework System Aggregator project + + + domain + api + + + + + + maven-deploy-plugin + + true + + + + + + -- 2.17.1