springcloud_k8s_panzhihuazhihuishequ/grid_app/pom.xml
New file @@ -0,0 +1,107 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.panzhihua</groupId> <artifactId>zhihuishequ</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.panzhihua</groupId> <artifactId>grid_app</artifactId> <version>0.0.1-SNAPSHOT</version> <name>grid_app</name> <description>网格治理-app</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.panzhihua</groupId> <artifactId>common</artifactId> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-javanica</artifactId> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.panzhihua.community_backstage.CommunityBackstageApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.2.0</version> <configuration> <imageName>registry.cn-chengdu.aliyuncs.com/panzhihua/community_backstage:v1</imageName> <serverId></serverId> <baseImage>java</baseImage> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project> springcloud_k8s_panzhihuazhihuishequ/grid_app/src/main/java/com/panzhihua/grid_app/GridAppApplication.java
New file @@ -0,0 +1,23 @@ package com.panzhihua.grid_app; import org.springframework.boot.SpringApplication; import org.springframework.cloud.client.SpringCloudApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 @SpringCloudApplication @EnableCircuitBreaker @EnableEurekaClient @EnableFeignClients(basePackages = {"com.panzhihua.common.service"}) @ComponentScan({"com.panzhihua.grid_app","com.panzhihua.common"}) public class GridAppApplication { public static void main(String[] args) { SpringApplication.run(GridAppApplication.class, args); } } springcloud_k8s_panzhihuazhihuishequ/grid_app/src/main/java/com/panzhihua/grid_app/aop/OperLogAspect.java
New file @@ -0,0 +1,227 @@ package com.panzhihua.grid_app.aop; import com.alibaba.fastjson.JSONObject; import com.panzhihua.common.constants.Constants; import com.panzhihua.common.constants.TokenConstant; import com.panzhihua.common.interfaces.OperLog; import com.panzhihua.common.model.vos.LoginUserInfoVO; import com.panzhihua.common.model.vos.user.SysOperLogVO; import com.panzhihua.common.service.user.UserService; import com.panzhihua.common.utlis.AES; import com.panzhihua.common.utlis.IPUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.lang.reflect.Method; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 切面处理类,操作日志异常日志记录处理 * * @author wu * @date 2019/03/21 */ @Slf4j @Aspect @Component public class OperLogAspect { @Resource private UserService userService; /** * 设置操作日志切入点 记录操作日志 在注解的位置切入代码 */ @Pointcut("@annotation(com.panzhihua.common.interfaces.OperLog)") public void operLogPoinCut() { } // /** // * 设置操作异常切入点记录异常日志 扫描所有controller包下操作 // */ // @Pointcut("execution(* com.hyd.zcar.cms.controller..*.*(..))") // public void operExceptionLogPoinCut() { // } /** * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行 * * @param joinPoint 切入点 * @param keys 返回结果 */ @AfterReturning(value = "operLogPoinCut()", returning = "keys") public void saveOperLog(JoinPoint joinPoint, Object keys) { log.info("进入切面"); // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); // 登录对象信息 String userInfo = request.getHeader(TokenConstant.TOKEN_USERINFO); boolean empty = ObjectUtils.isEmpty(userInfo); if (empty) { log.error("操作日志获取登录用户信息失败【{}】",joinPoint); return; } byte[] bytes = AES.parseHexStr2Byte(userInfo); byte[] decrypt = AES.decrypt(bytes, Constants.AES_KEY); userInfo=new String(decrypt); LoginUserInfoVO loginUserInfoVO= JSONObject.parseObject(userInfo,LoginUserInfoVO.class); SysOperLogVO operlog = new SysOperLogVO(); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method = signature.getMethod(); // 获取操作 OperLog opLog = method.getAnnotation(OperLog.class); if (opLog != null) { String operModul = opLog.operModul(); int operType = opLog.operType(); operlog.setTitle(operModul); // 操作模块 operlog.setBusinessType(operType); // 操作类型 } // 获取请求的类名 String className = joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName = method.getName(); methodName = className + "." + methodName; operlog.setMethod(methodName); // 请求方法 if (joinPoint.getArgs().length > 0) { for (Object o : joinPoint.getArgs()) { if (o instanceof HttpServletRequest || o instanceof HttpServletResponse) { continue; } operlog.setOperParam(JSONObject.toJSONString(o)); // 请求参数 } } operlog.setJsonResult(JSONObject.toJSONString(keys)); // 返回结果 operlog.setAccount(loginUserInfoVO.getAccount()); operlog.setOperName(loginUserInfoVO.getName()); // 请求用户名称 operlog.setOperIp(IPUtil.getIpAddress(request)); // 请求IP operlog.setOperUrl(request.getRequestURI()); // 请求URI operlog.setRequestMethod(request.getMethod()); operlog.setOperLocation(IPUtil.getIpBelongAddress(request)); operlog.setOperTime(new Date()); // 创建时间 operlog.setAccount(loginUserInfoVO.getAccount()); Long communityId = loginUserInfoVO.getCommunityId(); operlog.setCommunityId(null==communityId?0:communityId); userService.addOperLog(operlog); } catch (Exception e) { e.printStackTrace(); } } // /** // * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行 // * // * @param joinPoint 切入点 // * @param e 异常信息 // */ // @AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e") // public void saveExceptionLog(JoinPoint joinPoint, Throwable e) { // // 获取RequestAttributes // RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // // 从获取RequestAttributes中获取HttpServletRequest的信息 // HttpServletRequest request = (HttpServletRequest) requestAttributes // .resolveReference(RequestAttributes.REFERENCE_REQUEST); // // ExceptionLog excepLog = new ExceptionLog(); // try { // // 从切面织入点处通过反射机制获取织入点处的方法 // MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // // 获取切入点所在的方法 // Method method = signature.getMethod(); // excepLog.setExcId(UuidUtil.get32UUID()); // // 获取请求的类名 // String className = joinPoint.getTarget().getClass().getName(); // // 获取请求的方法名 // String methodName = method.getName(); // methodName = className + "." + methodName; // // 请求的参数 // Map<String, String> rtnMap = converMap(request.getParameterMap()); // // 将参数所在的数组转换成json // String params = JSON.toJSONString(rtnMap); // excepLog.setExcRequParam(params); // 请求参数 // excepLog.setOperMethod(methodName); // 请求方法名 // excepLog.setExcName(e.getClass().getName()); // 异常名称 // excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息 // excepLog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 操作员ID // excepLog.setOperUserName(UserShiroUtil.getCurrentUserName()); // 操作员名称 // excepLog.setOperUri(request.getRequestURI()); // 操作URI // excepLog.setOperIp(IPUtil.getRemortIP(request)); // 操作员IP // excepLog.setOperVer(operVer); // 操作版本号 // excepLog.setOperCreateTime(new Date()); // 发生异常时间 // // exceptionLogService.insert(excepLog); // // } catch (Exception e2) { // e2.printStackTrace(); // } // // } /** * 转换request 请求参数 * * @param paramMap request获取的参数数组 */ public Map<String, String> converMap(Map<String, String[]> paramMap) { Map<String, String> rtnMap = new HashMap<String, String>(); for (String key : paramMap.keySet()) { rtnMap.put(key, paramMap.get(key)[0]); } return rtnMap; } private String getPostData(HttpServletRequest request) { StringBuffer data = new StringBuffer(); String line = null; BufferedReader reader = null; try { reader = request.getReader(); while (null != (line = reader.readLine())) data.append(line); } catch (IOException e) { } finally { } return data.toString(); } /** * 转换异常信息为字符串 * * @param exceptionName 异常名称 * @param exceptionMessage 异常信息 * @param elements 堆栈信息 */ public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) { StringBuffer strbuff = new StringBuffer(); for (StackTraceElement stet : elements) { strbuff.append(stet + "\n"); } String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString(); return message; } } springcloud_k8s_panzhihuazhihuishequ/grid_app/src/main/java/com/panzhihua/grid_app/config/SFTPConfig.java
New file @@ -0,0 +1,30 @@ package com.panzhihua.grid_app.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; /** * @Author: llming * @Description: */ @Configuration @Data public class SFTPConfig { // FTP 登录用户名 @Value("${ftp.username}") private String userName; // FTP 登录密码 @Value("${ftp.password}") private String password; // FTP 服务器地址IP地址 @Value("${ftp.host}") private String host; // FTP 端口 @Value("${ftp.port}") private int port; @Value("${ftp.url}") private String url; @Value("${excel.userurl}") private String excelUrl; } springcloud_k8s_panzhihuazhihuishequ/grid_app/src/main/java/com/panzhihua/grid_app/config/SwaggerConfig.java
New file @@ -0,0 +1,40 @@ package com.panzhihua.grid_app.config; import io.swagger.annotations.ApiOperation; 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; /** * @program: springcloud_k8s_panzhihuazhihuishequ * @description: swagger3 * @author: huang.hongfa weixin hhf9596 qq 959656820 * @create: 2020-11-19 16:08 **/ @Configuration public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("网格app管理接口") .description("。") .contact(new Contact("Ray。", "http://www.ruiyeclub.cn", "ruiyeclub@foxmail.com")) .version("1.0") .build(); } } springcloud_k8s_panzhihuazhihuishequ/grid_app/src/main/resources/bootstrap.yml
New file @@ -0,0 +1,22 @@ spring: application: name: gridapp cloud: config: discovery: enabled: true service-id: config # 注册中心的服务名 profile: ${ENV:dev} # 指定配置文件的环境 uri: http://${CONFIG_URL:localhost}:8193/ profiles: active: ${ENV:dev} servlet: multipart: max-file-size: 10MB max-request-size: 10MB eureka: client: service-url: defaultZone: http://${EUREKA_URL:localhost}:8192/eureka springcloud_k8s_panzhihuazhihuishequ/grid_app/src/main/resources/logback-spring.xml
New file @@ -0,0 +1,51 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <springProfile name="dev"> <property name="LOG_HOME" value="F:/log" /> </springProfile> <springProfile name="test"> <property name="LOG_HOME" value="/mnt/data/gocd/log" /> </springProfile> <property name="LOG_HOME" value="/mnt/data/gocd/log" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/community_backstage.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!--myibatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <logger name="com.panzhihua.community_backstage" level="DEBUG"/> <!-- 日志输出级别 --> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration> springcloud_k8s_panzhihuazhihuishequ/grid_backstage/pom.xml
New file @@ -0,0 +1,107 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.panzhihua</groupId> <artifactId>zhihuishequ</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.panzhihua</groupId> <artifactId>grid_backstage</artifactId> <version>0.0.1-SNAPSHOT</version> <name>grid_backstage</name> <description>网格治理-后台</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.panzhihua</groupId> <artifactId>common</artifactId> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-javanica</artifactId> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.panzhihua.community_backstage.CommunityBackstageApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.2.0</version> <configuration> <imageName>registry.cn-chengdu.aliyuncs.com/panzhihua/community_backstage:v1</imageName> <serverId></serverId> <baseImage>java</baseImage> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project> springcloud_k8s_panzhihuazhihuishequ/grid_backstage/src/main/java/com/panzhihua/grid_backstage/GridBackstageApplication.java
New file @@ -0,0 +1,23 @@ package com.panzhihua.grid_backstage; import org.springframework.boot.SpringApplication; import org.springframework.cloud.client.SpringCloudApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 @SpringCloudApplication @EnableCircuitBreaker @EnableEurekaClient @EnableFeignClients(basePackages = {"com.panzhihua.common.service"}) @ComponentScan({"com.panzhihua.grid_backstage","com.panzhihua.common"}) public class GridBackstageApplication { public static void main(String[] args) { SpringApplication.run(GridBackstageApplication.class, args); } } springcloud_k8s_panzhihuazhihuishequ/grid_backstage/src/main/java/com/panzhihua/grid_backstage/aop/OperLogAspect.java
New file @@ -0,0 +1,227 @@ package com.panzhihua.grid_backstage.aop; import com.alibaba.fastjson.JSONObject; import com.panzhihua.common.constants.Constants; import com.panzhihua.common.constants.TokenConstant; import com.panzhihua.common.interfaces.OperLog; import com.panzhihua.common.model.vos.LoginUserInfoVO; import com.panzhihua.common.model.vos.user.SysOperLogVO; import com.panzhihua.common.service.user.UserService; import com.panzhihua.common.utlis.AES; import com.panzhihua.common.utlis.IPUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.lang.reflect.Method; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 切面处理类,操作日志异常日志记录处理 * * @author wu * @date 2019/03/21 */ @Slf4j @Aspect @Component public class OperLogAspect { @Resource private UserService userService; /** * 设置操作日志切入点 记录操作日志 在注解的位置切入代码 */ @Pointcut("@annotation(com.panzhihua.common.interfaces.OperLog)") public void operLogPoinCut() { } // /** // * 设置操作异常切入点记录异常日志 扫描所有controller包下操作 // */ // @Pointcut("execution(* com.hyd.zcar.cms.controller..*.*(..))") // public void operExceptionLogPoinCut() { // } /** * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行 * * @param joinPoint 切入点 * @param keys 返回结果 */ @AfterReturning(value = "operLogPoinCut()", returning = "keys") public void saveOperLog(JoinPoint joinPoint, Object keys) { log.info("进入切面"); // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); // 登录对象信息 String userInfo = request.getHeader(TokenConstant.TOKEN_USERINFO); boolean empty = ObjectUtils.isEmpty(userInfo); if (empty) { log.error("操作日志获取登录用户信息失败【{}】",joinPoint); return; } byte[] bytes = AES.parseHexStr2Byte(userInfo); byte[] decrypt = AES.decrypt(bytes, Constants.AES_KEY); userInfo=new String(decrypt); LoginUserInfoVO loginUserInfoVO= JSONObject.parseObject(userInfo,LoginUserInfoVO.class); SysOperLogVO operlog = new SysOperLogVO(); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method = signature.getMethod(); // 获取操作 OperLog opLog = method.getAnnotation(OperLog.class); if (opLog != null) { String operModul = opLog.operModul(); int operType = opLog.operType(); operlog.setTitle(operModul); // 操作模块 operlog.setBusinessType(operType); // 操作类型 } // 获取请求的类名 String className = joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName = method.getName(); methodName = className + "." + methodName; operlog.setMethod(methodName); // 请求方法 if (joinPoint.getArgs().length > 0) { for (Object o : joinPoint.getArgs()) { if (o instanceof HttpServletRequest || o instanceof HttpServletResponse) { continue; } operlog.setOperParam(JSONObject.toJSONString(o)); // 请求参数 } } operlog.setJsonResult(JSONObject.toJSONString(keys)); // 返回结果 operlog.setAccount(loginUserInfoVO.getAccount()); operlog.setOperName(loginUserInfoVO.getName()); // 请求用户名称 operlog.setOperIp(IPUtil.getIpAddress(request)); // 请求IP operlog.setOperUrl(request.getRequestURI()); // 请求URI operlog.setRequestMethod(request.getMethod()); operlog.setOperLocation(IPUtil.getIpBelongAddress(request)); operlog.setOperTime(new Date()); // 创建时间 operlog.setAccount(loginUserInfoVO.getAccount()); Long communityId = loginUserInfoVO.getCommunityId(); operlog.setCommunityId(null==communityId?0:communityId); userService.addOperLog(operlog); } catch (Exception e) { e.printStackTrace(); } } // /** // * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行 // * // * @param joinPoint 切入点 // * @param e 异常信息 // */ // @AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e") // public void saveExceptionLog(JoinPoint joinPoint, Throwable e) { // // 获取RequestAttributes // RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // // 从获取RequestAttributes中获取HttpServletRequest的信息 // HttpServletRequest request = (HttpServletRequest) requestAttributes // .resolveReference(RequestAttributes.REFERENCE_REQUEST); // // ExceptionLog excepLog = new ExceptionLog(); // try { // // 从切面织入点处通过反射机制获取织入点处的方法 // MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // // 获取切入点所在的方法 // Method method = signature.getMethod(); // excepLog.setExcId(UuidUtil.get32UUID()); // // 获取请求的类名 // String className = joinPoint.getTarget().getClass().getName(); // // 获取请求的方法名 // String methodName = method.getName(); // methodName = className + "." + methodName; // // 请求的参数 // Map<String, String> rtnMap = converMap(request.getParameterMap()); // // 将参数所在的数组转换成json // String params = JSON.toJSONString(rtnMap); // excepLog.setExcRequParam(params); // 请求参数 // excepLog.setOperMethod(methodName); // 请求方法名 // excepLog.setExcName(e.getClass().getName()); // 异常名称 // excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息 // excepLog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 操作员ID // excepLog.setOperUserName(UserShiroUtil.getCurrentUserName()); // 操作员名称 // excepLog.setOperUri(request.getRequestURI()); // 操作URI // excepLog.setOperIp(IPUtil.getRemortIP(request)); // 操作员IP // excepLog.setOperVer(operVer); // 操作版本号 // excepLog.setOperCreateTime(new Date()); // 发生异常时间 // // exceptionLogService.insert(excepLog); // // } catch (Exception e2) { // e2.printStackTrace(); // } // // } /** * 转换request 请求参数 * * @param paramMap request获取的参数数组 */ public Map<String, String> converMap(Map<String, String[]> paramMap) { Map<String, String> rtnMap = new HashMap<String, String>(); for (String key : paramMap.keySet()) { rtnMap.put(key, paramMap.get(key)[0]); } return rtnMap; } private String getPostData(HttpServletRequest request) { StringBuffer data = new StringBuffer(); String line = null; BufferedReader reader = null; try { reader = request.getReader(); while (null != (line = reader.readLine())) data.append(line); } catch (IOException e) { } finally { } return data.toString(); } /** * 转换异常信息为字符串 * * @param exceptionName 异常名称 * @param exceptionMessage 异常信息 * @param elements 堆栈信息 */ public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) { StringBuffer strbuff = new StringBuffer(); for (StackTraceElement stet : elements) { strbuff.append(stet + "\n"); } String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString(); return message; } } springcloud_k8s_panzhihuazhihuishequ/grid_backstage/src/main/java/com/panzhihua/grid_backstage/config/SFTPConfig.java
New file @@ -0,0 +1,30 @@ package com.panzhihua.grid_backstage.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; /** * @Author: llming * @Description: */ @Configuration @Data public class SFTPConfig { // FTP 登录用户名 @Value("${ftp.username}") private String userName; // FTP 登录密码 @Value("${ftp.password}") private String password; // FTP 服务器地址IP地址 @Value("${ftp.host}") private String host; // FTP 端口 @Value("${ftp.port}") private int port; @Value("${ftp.url}") private String url; @Value("${excel.userurl}") private String excelUrl; } springcloud_k8s_panzhihuazhihuishequ/grid_backstage/src/main/java/com/panzhihua/grid_backstage/config/SwaggerConfig.java
New file @@ -0,0 +1,40 @@ package com.panzhihua.grid_backstage.config; import io.swagger.annotations.ApiOperation; 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; /** * @program: springcloud_k8s_panzhihuazhihuishequ * @description: swagger3 * @author: huang.hongfa weixin hhf9596 qq 959656820 * @create: 2020-11-19 16:08 **/ @Configuration public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("网格治理后台管理接口") .description("。") .contact(new Contact("Ray。", "http://www.ruiyeclub.cn", "ruiyeclub@foxmail.com")) .version("1.0") .build(); } } springcloud_k8s_panzhihuazhihuishequ/grid_backstage/src/main/resources/bootstrap.yml
New file @@ -0,0 +1,22 @@ spring: application: name: gridbackstage cloud: config: discovery: enabled: true service-id: config # 注册中心的服务名 profile: ${ENV:dev} # 指定配置文件的环境 uri: http://${CONFIG_URL:localhost}:8193/ profiles: active: ${ENV:dev} servlet: multipart: max-file-size: 10MB max-request-size: 10MB eureka: client: service-url: defaultZone: http://${EUREKA_URL:localhost}:8192/eureka springcloud_k8s_panzhihuazhihuishequ/grid_backstage/src/main/resources/logback-spring.xml
New file @@ -0,0 +1,51 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <springProfile name="dev"> <property name="LOG_HOME" value="F:/log" /> </springProfile> <springProfile name="test"> <property name="LOG_HOME" value="/mnt/data/gocd/log" /> </springProfile> <property name="LOG_HOME" value="/mnt/data/gocd/log" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/community_backstage.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!--myibatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <logger name="com.panzhihua.community_backstage" level="DEBUG"/> <!-- 日志输出级别 --> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration> springcloud_k8s_panzhihuazhihuishequ/pom.xml
@@ -203,6 +203,12 @@ <module>service_community</module> <module>service_user</module> <module>shop_backstage</module> <!--网格治理-app--> <module>grid_app</module> <!--网格治理-后台--> <module>grid_backstage</module> <!--网格治理-基础服务service--> <module>service_grid</module> </modules> <packaging>pom</packaging> springcloud_k8s_panzhihuazhihuishequ/service_grid/pom.xml
New file @@ -0,0 +1,125 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.panzhihua</groupId> <artifactId>zhihuishequ</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.panzhihua</groupId> <artifactId>service_grid</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service_grid</name> <description>网格治理服务</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-javanica</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>com.panzhihua</groupId> <artifactId>common</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.panzhihua.service_community.ServiceCommunityApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.2.0</version> <configuration> <imageName>registry.cn-chengdu.aliyuncs.com/panzhihua/service_community:v1</imageName> <serverId></serverId> <baseImage>java</baseImage> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project> springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/ServiceGridApplication.java
New file @@ -0,0 +1,21 @@ package com.panzhihua.service_grid; import org.springframework.boot.SpringApplication; import org.springframework.cloud.client.SpringCloudApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; @SpringCloudApplication @EnableFeignClients(basePackages = {"com.panzhihua.common.service"}) @EnableEurekaClient @EnableCircuitBreaker @ComponentScan({"com.panzhihua.service_grid","com.panzhihua.common"}) public class ServiceGridApplication { public static void main(String[] args) { SpringApplication.run(ServiceGridApplication.class, args); } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/config/MyMetaObjectHandler.java
New file @@ -0,0 +1,40 @@ package com.panzhihua.service_grid.config; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.Date; /** * @program: springcloud_k8s_panzhihuazhihuishequ * @description: 自动填充 * @author: huang.hongfa weixin hhf9596 qq 959656820 * @create: 2020-12-11 14:23 **/ @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill ...."); // this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // 起始版本 3.3.0(推荐使用) // 或者 this.strictInsertFill(metaObject, "createAt", () -> new Date(), Date.class); // 起始版本 3.3.3(推荐) this.strictInsertFill(metaObject, "updateAt", () -> new Date(), Date.class); // 起始版本 3.3.3(推荐) // 或者 // this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug) } @Override public void updateFill(MetaObject metaObject) { log.info("start update fill ...."); // this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐) // 或者 this.strictUpdateFill(metaObject, "updateAt", () -> new Date(), Date.class); // 起始版本 3.3.3(推荐) // 或者 // this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug) } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/config/MybatisPlusConfig.java
New file @@ -0,0 +1,35 @@ package com.panzhihua.service_grid.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @program: springcloud_k8s_panzhihuazhihuishequ * @description: 分页 * @author: huang.hongfa weixin hhf9596 qq 959656820 * @create: 2020-11-30 16:26 **/ @Configuration public class MybatisPlusConfig { /** * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除) */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); return interceptor; } @Bean public ConfigurationCustomizer configurationCustomizer() { return configuration -> configuration.setUseDeprecatedExecutor(false); } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/model/dos/BaseDO.java
New file @@ -0,0 +1,25 @@ package com.panzhihua.service_grid.model.dos; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; import java.util.Date; /** * @Author: llming * @Description: */ @Data public class BaseDO { private Long createBy; @TableField(fill = FieldFill.INSERT) private Date createAt; private Long updateBy; @TableField(fill = FieldFill.INSERT) private Date updateAt; } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/model/helper/encrypt/ParammeterInterceptor.java
New file @@ -0,0 +1,114 @@ package com.panzhihua.service_grid.model.helper.encrypt; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; import com.panzhihua.common.model.helper.encrypt.EncryptQuery; import com.panzhihua.common.model.helper.encrypt.EncryptQueryClass; import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.binding.BindingException; import org.apache.ibatis.binding.MapperMethod; import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.plugin.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.sql.PreparedStatement; import java.util.*; /** * 加密拦截器 * 包含加密字段查询时 的加密步骤 * @author cedoo * @since 2021-4-1 10:40:52 */ @Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class), }) @ConditionalOnProperty(value = "domain.encrypt", havingValue = "true") @Component @Slf4j public class ParammeterInterceptor implements Interceptor { @Autowired private IEncryptDecrypt encryptDecrypt; @Override public Object intercept(Invocation invocation) throws Throwable { //拦截 ParameterHandler 的 setParameters 方法 动态设置参数 if (invocation.getTarget() instanceof ParameterHandler) { ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget(); PreparedStatement ps = (PreparedStatement) invocation.getArgs()[0]; // 反射获取 参数对像 Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject"); parameterField.setAccessible(true); Object parameterObject = parameterField.get(parameterHandler); if (Objects.nonNull(parameterObject)) { Class<?> parameterObjectClass = parameterObject.getClass(); EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(parameterObjectClass, EncryptDecryptClass.class); if (Objects.nonNull(encryptDecryptClass)) { Field[] declaredFields = parameterObjectClass.getDeclaredFields(); final Object encrypt = encryptDecrypt.encrypt(declaredFields, parameterObject); } /** * 通过加密字段查询时, 将查询参数中的加密字段加密后查询 */ if(parameterObjectClass == MapperMethod.ParamMap.class) { MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) parameterObject; boolean encrypted = false; try{ /** * 分页插件,会在分页查询时 进行多次查询,需要判断是否已对加密参数加密,防止多次加密后,查询失败 */ encrypted = paramMap.get("encrypted")!=null; }catch (BindingException be){ encrypted = false; } if(!encrypted) { Iterator iterator = paramMap.entrySet().iterator(); while(iterator.hasNext()){ Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iterator.next(); if (entry.getKey().startsWith("param")) { Object v = entry.getValue(); if(v!=null) { EncryptQueryClass encryptQueryClass = AnnotationUtils.findAnnotation(v.getClass(), EncryptQueryClass.class); if (Objects.nonNull(encryptQueryClass)) { Field[] declaredFields = v.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (field.isAnnotationPresent(EncryptQuery.class)) { try { final Object encrypt = encryptDecrypt.encrypt(new Field[]{field}, v); paramMap.put("encrypted", true); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } } } } } } return invocation.proceed(); } @Override public Object plugin(Object o) { return Plugin.wrap(o, this); } @Override public void setProperties(Properties properties) { } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/model/helper/encrypt/ResultInterceptor.java
New file @@ -0,0 +1,79 @@ package com.panzhihua.service_grid.model.helper.encrypt; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.sql.Statement; import java.util.ArrayList; import java.util.Objects; import java.util.Properties; /** * 解密拦截器 * * @author cedoo * @since 2021-4-1 10:40:52 */ @Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args={Statement.class}) }) @ConditionalOnProperty(value = "domain.decrypt", havingValue = "true") @Component @Slf4j @Order(110) public class ResultInterceptor implements Interceptor { @Autowired private IEncryptDecrypt encryptDecrypt; @Override public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); if (Objects.isNull(result)){ return null; } if (result instanceof ArrayList) { ArrayList resultList = (ArrayList) result; if (resultList!=null && resultList.size()>0 && needToDecrypt(resultList.get(0))){ for (int i = 0; i < resultList.size(); i++) { encryptDecrypt.decrypt(resultList.get(i)); } } }else { if (needToDecrypt(result)){ encryptDecrypt.decrypt(result); } } return result; } public boolean needToDecrypt(Object object){ if(object!=null) { Class<?> objectClass = object.getClass(); EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(objectClass, EncryptDecryptClass.class); if (Objects.nonNull(encryptDecryptClass)) { return true; } } return false; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/model/helper/sensitive/SensitiveInterceptor.java
New file @@ -0,0 +1,75 @@ package com.panzhihua.service_grid.model.helper.sensitive; import com.panzhihua.common.model.helper.sensitive.Sensitive; import com.panzhihua.common.model.helper.sensitive.SensitiveStrategy; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.sql.Statement; import java.util.List; import java.util.stream.Stream; /** * 字段脱敏拦截器 * @author cedoo * @since 2021-4-1 10:40:52 */ @Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})) @Slf4j @ConditionalOnProperty(value = "domain.sensitive", havingValue = "true") @Component @Order(120) public class SensitiveInterceptor implements Interceptor { @SuppressWarnings("unchecked") @Override public Object intercept(Invocation invocation) throws Throwable { //log.debug("脱敏拦截器"); List<Object> records = (List<Object>) invocation.proceed(); // 对结果集脱敏 records.forEach(this::sensitive); return records; } private void sensitive(Object source) { if(source!=null) { // 拿到返回值类型 Class<?> sourceClass = source.getClass(); // 初始化返回值类型的 MetaObject MetaObject metaObject = SystemMetaObject.forObject(source); // 捕捉到属性上的标记注解 @Sensitive 并进行对应的脱敏处理 Stream.of(sourceClass.getDeclaredFields()) .filter(field -> field.isAnnotationPresent(Sensitive.class)) .forEach(field -> doSensitive(metaObject, field)); } } private void doSensitive(MetaObject metaObject, Field field) { // 拿到属性名 String name = field.getName(); // 获取属性值 Object value = metaObject.getValue(name); // 只有字符串类型才能脱敏 而且不能为null if (String.class == metaObject.getGetterType(name) && value != null) { Sensitive annotation = field.getAnnotation(Sensitive.class); // 获取对应的脱敏策略 并进行脱敏 SensitiveStrategy type = annotation.strategy(); Object o = type.getDesensitizer().apply((String) value); // 把脱敏后的值塞回去 metaObject.setValue(name, o); } } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/java/com/panzhihua/service_grid/service/impl/ComActActivityServiceImpl.java
New file @@ -0,0 +1,441 @@ package com.panzhihua.service_grid.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.panzhihua.common.model.vos.IndexDataVO; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.model.vos.community.*; import com.panzhihua.service_community.dao.ComActActSignDAO; import com.panzhihua.service_community.dao.ComActActivityDAO; import com.panzhihua.service_community.dao.ComActDiscussOptionUserDAO; import com.panzhihua.service_community.model.dos.ComActActSignDO; import com.panzhihua.service_community.model.dos.ComActActivityDO; import com.panzhihua.service_community.service.ComActActivityService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.time.DateUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @program: springcloud_k8s_panzhihuazhihuishequ * @description: 社区活动 * @author: huang.hongfa weixin hhf9596 qq 959656820 * @create: 2020-12-07 14:35 **/ @Slf4j @Service public class ComActActivityServiceImpl extends ServiceImpl<ComActActivityDAO, ComActActivityDO> implements ComActActivityService { @Resource private ComActActivityDAO comActActivityDAO; @Resource private ComActActSignDAO comActActSignDAO; /** * 新增社区活动 * @param comActActivityVO 新增信息 * @return 新增结果 */ @Override public R addActivity(ComActActivityVO comActActivityVO) { ComActActivityDO comActActivityDO=new ComActActivityDO(); BeanUtils.copyProperties(comActActivityVO,comActActivityDO); Integer status = comActActivityVO.getStatus(); Date now = new Date(); if (status.intValue()!=1) { comActActivityDO.setPublishAt(now);//发布时间 } //如果发布时间大于现在时间状态改为进行中 /*if(now.getTime()<comActActivityVO.getBeginAt().getTime()){ comActActivityDO.setStatus(3); }*/ if(status.intValue()==2) {//点击‘保存并发布’ 按钮 //报名结束时间大于当前时间则设置为“进行中” if (comActActivityVO.getSignUpEnd() != null && now.getTime() < comActActivityVO.getSignUpEnd().getTime()) { comActActivityDO.setStatus(4); } } boolean save = this.save(comActActivityDO); if(!save){ return R.fail(); } ComActActivityDO one = this.getOne(new QueryWrapper<ComActActivityDO>().lambda().eq(ComActActivityDO::getActivityName, comActActivityDO.getActivityName()).orderByDesc(ComActActivityDO::getCreateAt).last(" limit 1 ")); Long activityId = one.getId(); return R.ok(activityId); } /** * 编辑社区活动 * * @param comActActivityVO 编辑内容 * @return 编辑结果 */ @Override public R putActivity(ComActActivityVO comActActivityVO) { ComActActivityDO comActActivityDO=new ComActActivityDO(); BeanUtils.copyProperties(comActActivityVO,comActActivityDO); //结束时间大于当前时间则设置为“进行中” Date now = new Date(); if(comActActivityVO.getSignUpEnd()!=null && now.getTime()<comActActivityVO.getSignUpEnd().getTime()){ comActActivityDO.setStatus(4); } boolean b = this.updateById(comActActivityDO); if (b) { return R.ok(); } return R.fail(); } /** * 分页查询社区活动 * * @param comActActivityVO 查询参数 * @return 分页集合 */ @Override public R pageActivity(ComActActivityVO comActActivityVO) { Page page = new Page<>(); Long pageNum = comActActivityVO.getPageNum(); Long pageSize = comActActivityVO.getPageSize(); if (null==pageNum||0==pageNum) { pageNum = 1l; } if (null==pageSize||0==pageSize) { pageSize = 10l; } page.setSize(pageSize); page.setCurrent(pageNum); IPage<ComActActivityVO> iPage = comActActivityDAO.pageActivity(page, comActActivityVO); List<ComActActivityVO> records = iPage.getRecords(); if (!ObjectUtils.isEmpty(records)) { records.forEach(comActActivityVO1 -> { Integer status = comActActivityVO1.getStatus(); if (status.intValue()==3) { comActActivityVO1.setStatus(4); } }); } return R.ok(iPage); } /** * 发布活动 * * @param comActActivityVO 主键id 发布时间 * @return 发布结果 */ @Override public R releaseActivity(ComActActivityVO comActActivityVO) { ComActActivityDO comActActivityDO=new ComActActivityDO(); comActActivityDO.setId(comActActivityVO.getId()); comActActivityDO.setPublishAt(comActActivityVO.getPublishAt()); comActActivityDO.setStatus(comActActivityVO.getStatus()); int update = comActActivityDAO.updateById(comActActivityDO); if (update>0) { return R.ok(); } return R.fail(); } /** * 取消活动 * * @param comActActivityVO 取消原因 * @return 取消结果 */ @Override public R cancelActivity(ComActActivityVO comActActivityVO) { ComActActivityDO comActActivityDO=new ComActActivityDO(); comActActivityDO.setId(comActActivityVO.getId()); comActActivityDO.setStatus(comActActivityVO.getStatus()); comActActivityDO.setCancelReason(comActActivityVO.getCancelReason()); int update = comActActivityDAO.updateById(comActActivityDO); if (update>0) { return R.ok(); } return R.fail(); } /** * 活动详情 * * @param id 活动id * @param userId * @return 详情 */ @Override public ComActActivityVO inforActivity(Long id, Long userId) { ComActActivityVO comActActivityVO=comActActivityDAO.inforActivity(id); if (!ObjectUtils.isEmpty(comActActivityVO)) { ComActActSignDO comActActSignDO = comActActSignDAO.selectOne(new QueryWrapper<ComActActSignDO>().lambda().eq(ComActActSignDO::getActivityId, id).eq(ComActActSignDO::getUserId, userId)); if (!ObjectUtils.isEmpty(comActActSignDO)) { comActActivityVO.setIsSign(1); comActActivityVO.setIsVolunteer(comActActSignDO.getIsVolunteer()); }else { } } return comActActivityVO; } /** * 活动报名名单 * * @param activitySignVO 查询参数 * @return 报名人员集合 */ @Override public R listActivitySign(ActivitySignVO activitySignVO) { List<ActivitySignVO> activitySignVOS = comActActSignDAO.listActivitySign(activitySignVO); return R.ok(activitySignVOS); } /** * 分页展示我的所有活动 时间倒序排列 * * @param comActActivityVO 分页参数 * @return 分页集合 */ @Override public R pageMyActivity(ComActActivityVO comActActivityVO) { Page page = new Page<>(); Long pageNum = comActActivityVO.getPageNum(); Long pageSize = comActActivityVO.getPageSize(); if (null==pageNum||0==pageNum) { pageNum = 1l; } if (null==pageSize||0==pageSize) { pageSize = 10l; } page.setSize(pageSize); page.setCurrent(pageNum); IPage<ComActActivityVO> iPage = comActActivityDAO.pageMyActivity(page, comActActivityVO); return R.ok(iPage); } /** * 报名/取消报名社区活动 * * @param signactivityVO 报名参数 * @return 报名 取消报名 结果 */ @Override public R signActivity(SignactivityVO signactivityVO) { Long activityId = signactivityVO.getActivityId(); Integer type = signactivityVO.getType(); Long userId = signactivityVO.getUserId(); Integer isVolunteer = signactivityVO.getIsVolunteer(); int num=0; if (1==type) { ComActActSignDO comActActSignDO=new ComActActSignDO(); comActActSignDO.setActivityId(activityId); comActActSignDO.setUserId(userId); comActActSignDO.setIsVolunteer(isVolunteer); try { num = comActActSignDAO.insert(comActActSignDO); } catch (Exception e) { if (e.getMessage().contains("unique_activity_id_user_id")) { return R.fail("已经报名过了,请勿重复提交"); } log.error(e.getMessage()); } } else { num = comActActSignDAO.delete(new QueryWrapper<ComActActSignDO>().lambda().eq(ComActActSignDO::getUserId, userId).eq(ComActActSignDO::getActivityId, activityId).eq(ComActActSignDO::getIsVolunteer, isVolunteer)); } if (num>0) { return R.ok(); } return R.fail(); } /** * 用户参加的所有社区活动 * * @param userId 用户id * @return 活动列表 */ @Override public R listActivity(Long userId) { List<ComActActSignDO> comActActSignDOS = comActActSignDAO.selectList(new QueryWrapper<ComActActSignDO>().lambda().eq(ComActActSignDO::getUserId, userId)); if (ObjectUtils.isEmpty(comActActSignDOS)) { return R.fail(); } List<Long> longs = comActActSignDOS.stream().map(comActActSignDO -> comActActSignDO.getActivityId()).collect(Collectors.toList()); List<ComActActivityDO> comActActivityDOS = comActActivityDAO.selectBatchIds(longs); List<ComActActivityVO>comActActivityVOS=new ArrayList<>(); comActActivityDOS.forEach(comActActivityDO -> { ComActActivityVO comActActivityVO=new ComActActivityVO(); BeanUtils.copyProperties(comActActivityDO,comActActivityVO); List<ComActActSignDO> collect = comActActSignDOS.stream().filter(comActActSignDO -> comActActSignDO.getActivityId().equals(comActActivityVO.getId())).limit(1).collect(Collectors.toList()); ComActActSignDO comActActSignDO = collect.get(0); Integer isVolunteer = comActActSignDO.getIsVolunteer(); if (isVolunteer.intValue()==1) { comActActivityVO.setType(1); }else{ comActActivityVO.setType(2); } Integer status = comActActivityVO.getStatus(); if (status.intValue()==3) { comActActivityVO.setStatus(4); } comActActivityVO.setSingDate(comActActSignDOS.stream().filter(comActActSignDO1 -> comActActSignDO1.getActivityId().equals(comActActivityVO.getId())).collect(Collectors.toList()).get(0).getCreateAt()); comActActivityVOS.add(comActActivityVO); }); return R.ok(comActActivityVOS); } /** * 查询志愿者参与的所有已经完成的活动 * * @param phone 用户手机号 * @return 所有活动集合 */ @Override public List<ComActActivityVO> listActivityByPhone(String phone) { List<ComActActivityVO> comActActivityVOS=comActActivityDAO.listActivityByPhone(phone); return comActActivityVOS; } /** * 定时任务查询所有要取消的社区活动 * * @return 社区活动集合 */ @Override public R timedTaskActActivity() { List<Long>longs=comActActivityDAO.selectTimedTaskActActivity(); if (ObjectUtils.isEmpty(longs)) { return R.fail("没有需要取消的社区活动"); } List<ComActActivityDO> comActActivityDOS = comActActivityDAO.selectBatchIds(longs); List<ComActActivityVO>comActActivityVOS=new ArrayList<>(); if (!ObjectUtils.isEmpty(comActActivityDOS)) { comActActivityDOS.forEach(comActActivityDO -> { ComActActivityVO comActActivityVO=new ComActActivityVO(); BeanUtils.copyProperties(comActActivityDO,comActActivityVO); List<ComActActSignDO> comActActSignDOS = comActActSignDAO.selectList(new QueryWrapper<ComActActSignDO>().lambda().eq(ComActActSignDO::getActivityId, comActActivityDO.getId())); if (!ObjectUtils.isEmpty(comActActSignDOS)) { List<ActivitySignVO> activitySignVOList=new ArrayList<>(); comActActSignDOS.forEach(comActActSignDO -> { ActivitySignVO activitySignVO=new ActivitySignVO(); BeanUtils.copyProperties(comActActSignDO,activitySignVO); activitySignVOList.add(activitySignVO); comActActivityVO.setActivitySignVOList(activitySignVOList); }); } comActActivityVOS.add(comActActivityVO); }); int num=comActActivityDAO.updateIdBatch(longs); log.info("定时任务--一共取消社区活动数量【{}】",num); } return R.ok(comActActivityVOS); } /** * 定时任务刷新社区活动的各个状态 除取消外 * * @return 更新结果 */ @Override public R timedTaskActActivityAll() { // 修改发布状态 变为未开始 int num=comActActivityDAO.updateStatusToNotBegin(); log.info("定时任务--修改社区活动发布状态活动数量【{}】",num); // 修改报名状态 变为报名中 int num1=comActActivityDAO.updateStatusToBeginSign(); log.info("定时任务--修改社区活动报名状态活动数量【{}】",num1); // 修改进行状态 变为进行中或者已结束 int num2=comActActivityDAO.updateStatusToBeginActiveOrEnd(); log.info("定时任务--修改社区活动进行状态活动数量【{}】",num2); int num3=comActActivityDAO.updateStatusToBeginAfterSingEnd(); log.info("定时任务--报名结束修改社区活动进行状态活动数量【{}】",num3); return R.ok(); } /** * 社区后台分页查询社区活动 * * @param comActActivityVO 查询参数 * @return 返回结果 */ @Override public R pageActivityCommunityBack(ComActActivityVO comActActivityVO) { Page page = new Page<>(); Long pageNum = comActActivityVO.getPageNum(); Long pageSize = comActActivityVO.getPageSize(); if (null==pageNum||0==pageNum) { pageNum = 1l; } if (null==pageSize||0==pageSize) { pageSize = 10l; } page.setSize(pageSize); page.setCurrent(pageNum); IPage<ComActActivityVO> iPage = comActActivityDAO.pageActivityCommunityBack(page, comActActivityVO); return R.ok(iPage); } /** * 首页图表数据汇总 * * @param communityId 社区id * @return 图表数据 IndexDataVO */ @Override public R indexDataCommunityBackstageEchart(Long communityId) { IndexDataVO indexDataVO=new IndexDataVO(); CommunityGovernanceTrendsVO communityGovernanceTrendsVO=new CommunityGovernanceTrendsVO(); List<CommunityActivitiesVO> communityActivitiesVOS=new ArrayList<>(); List<Date>dates=this.getServenDays(); String s=comActActivityDAO.selectCommunityGovernanceTrendsVO(communityId); List<String>y= Arrays.asList(s.split(",")); communityGovernanceTrendsVO.setY(y); communityGovernanceTrendsVO.setX(Arrays.asList(new String[]{"一起议","微心愿","随手拍","社区活动"})); dates.forEach(date -> { CommunityActivitiesVO communityActivitiesVO=comActActivityDAO.selectCommunityActivitiesVO(communityId,date); communityActivitiesVO.setDate(date); communityActivitiesVOS.add(communityActivitiesVO); }); indexDataVO.setCommunityGovernanceTrendsVO(communityGovernanceTrendsVO); indexDataVO.setCommunityActivitiesVOS(communityActivitiesVOS); return R.ok(indexDataVO); } /** * 获取最近七天的时间 * @return */ private List<Date> getServenDays() { List<Date> dates=new ArrayList<>(); Date date=new Date(); for(int i=6;i>=0;i--){ Date date1= DateUtils.addDays(date,-i); dates.add(date1); } return dates; } public static void main(String[] args) { List<Date> dates=new ArrayList<>(); Date date=new Date(); for(int i=6;i>=0;i--){ Date date1= DateUtils.addDays(date,-i); dates.add(date1); } System.out.println(dates); } } springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/resources/bootstrap.yml
New file @@ -0,0 +1,30 @@ spring: application: name: grid cloud: config: discovery: enabled: true service-id: config # 注册中心的服务名 profile: ${ENV:dev} # 指定配置文件的环境 uri: http://${CONFIG_URL:localhost}:8193/ profiles: active: ${ENV:dev} servlet: multipart: max-file-size: 10MB max-request-size: 10MB eureka: client: service-url: defaultZone: http://${EUREKA_URL:localhost}:8192/eureka #实体加密、解密、字段脱敏拦截设置 domain: decrypt: true encrypt: true aesKey: Ryo7M3n8loC5 sensitive: true springcloud_k8s_panzhihuazhihuishequ/service_grid/src/main/resources/logback-spring.xml
New file @@ -0,0 +1,51 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <springProfile name="dev"> <property name="LOG_HOME" value="F:/log" /> </springProfile> <springProfile name="test"> <property name="LOG_HOME" value="/mnt/data/gocd/log" /> </springProfile> <property name="LOG_HOME" value="/mnt/data/gocd/log" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/service_community.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!--myibatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <logger name="com.panzhihua.service_community" level="DEBUG"/> <!-- 日志输出级别 --> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration>