first commit
This commit is contained in:
commit
73feff4dbb
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
*.log
|
||||
|
||||
.vscode
|
||||
180
pom.xml
Normal file
180
pom.xml
Normal file
@ -0,0 +1,180 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>DiagnoseApiServer</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.7</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.2.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.31</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>3.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast</artifactId>
|
||||
<version>5.3.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast-sql</artifactId>
|
||||
<version>5.3.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast-spring</artifactId>
|
||||
<version>5.3.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
<!--https://doc.xiaominfo.com/knife4j/documentation/-->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>30.1.1-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ahocorasick</groupId>
|
||||
<artifactId>ahocorasick</artifactId>
|
||||
<version>0.6.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.9.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<!-- go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version. -->
|
||||
<!-- 请到https://search.maven.org/search?q=tencentcloud-sdk-java查询所有版本,最新版本如下 -->
|
||||
<version>3.1.1142</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SLF4J API: 用于记录日志 -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.36</version> <!-- 使用适合你项目的版本 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Logback Classic: 提供 Logback 日志实现 -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.11</version> <!-- 使用适合你项目的版本 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Logback Core: Logback 的核心库 -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>1.2.11</version> <!-- 使用适合你项目的版本 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Logback Slf4j binding (可以让 SLF4J 使用 Logback 作为日志实现) -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.7.36</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.syzb.startup.Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>thin-jar</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.syzb.startup.Main</mainClass>
|
||||
<layout>ZIP</layout>
|
||||
<includes>
|
||||
<include>
|
||||
<groupId>nothing</groupId>
|
||||
<artifactId>nothing</artifactId>
|
||||
</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
51
src/main/java/com/diagnose/common/aspect/AuthAspect.java~
Normal file
51
src/main/java/com/diagnose/common/aspect/AuthAspect.java~
Normal file
@ -0,0 +1,51 @@
|
||||
package com.common.aspect;
|
||||
|
||||
import com.common.annotation.Auth;
|
||||
import com.common.constant.AccessRole;
|
||||
import com.common.vo.BackendUserVO;
|
||||
import com.rbac.service.AuthService;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class AuthAspect {
|
||||
|
||||
@Resource
|
||||
AuthService authService;
|
||||
|
||||
@Pointcut("@annotation(com.common.annotation.Auth)")
|
||||
private void pointcut() {
|
||||
}
|
||||
|
||||
// 前置通知
|
||||
@Before("pointcut()")
|
||||
public void beforeCall(JoinPoint joinPoint) {
|
||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||
HttpServletRequest request = requestAttributes.getRequest();
|
||||
BackendUserVO backendUser = (BackendUserVO) request.getAttribute("backendUser");
|
||||
// 获取注解中的参数值
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
// 获取注解
|
||||
Auth annotation = method.getAnnotation(Auth.class);
|
||||
// 获取注解参数的值
|
||||
AccessRole role = annotation.role();
|
||||
// 验证帐号的合法性
|
||||
authService.checkUserStatus(backendUser, role);
|
||||
String callUrl = request.getRequestURI();
|
||||
// 校验权限
|
||||
//authService.checkUserPermission(backendUser, callUrl);
|
||||
}
|
||||
|
||||
}
|
||||
45
src/main/java/com/diagnose/common/aspect/TaskAspect.java
Normal file
45
src/main/java/com/diagnose/common/aspect/TaskAspect.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.diagnose.common.aspect;
|
||||
|
||||
import com.diagnose.common.util.RequestIdUtil;
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class TaskAspect {
|
||||
|
||||
@Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)")
|
||||
private void scheduledPointcut() {
|
||||
}
|
||||
|
||||
// 前置通知
|
||||
@Before("scheduledPointcut()")
|
||||
public void beforeCall(JoinPoint joinPoint) {
|
||||
RequestIdUtil.setTime();
|
||||
RequestIdUtil.setValue("TIME");
|
||||
// 获取注解中的参数值
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
LoggerUtil.data.info(String.format("定时任务:%s:启动了", method.getName()));
|
||||
}
|
||||
|
||||
// 最终通知
|
||||
@AfterReturning(pointcut = "scheduledPointcut()")
|
||||
public void afterReturningCall(JoinPoint joinPoint) {
|
||||
long start = RequestIdUtil.getTime();
|
||||
long time = new Date().getTime() - start;
|
||||
// 获取注解中的参数值
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
LoggerUtil.data.info(String.format("定时任务:%s:耗时:%d", method.getName(), time));
|
||||
}
|
||||
}
|
||||
82
src/main/java/com/diagnose/common/aspect/WebLogAspect.java
Normal file
82
src/main/java/com/diagnose/common/aspect/WebLogAspect.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.diagnose.common.aspect;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.diagnose.common.util.RequestIdUtil;
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class WebLogAspect {
|
||||
|
||||
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
|
||||
private void requestPointcut() {
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
|
||||
private void getPointcut() {
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
|
||||
private void postPointcut() {
|
||||
}
|
||||
|
||||
// 前置通知
|
||||
@Before("requestPointcut() || getPointcut() || postPointcut()")
|
||||
public void beforeCall(JoinPoint joinPoint) {
|
||||
RequestIdUtil.setTime();
|
||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||
HttpServletRequest request = requestAttributes.getRequest();
|
||||
Object[] args = joinPoint.getArgs();
|
||||
List<Object> arguments = new ArrayList<>();
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof ServletRequest || arg instanceof ServletResponse || arg instanceof MultipartFile) {
|
||||
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
|
||||
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
|
||||
continue;
|
||||
}
|
||||
arguments.add(arg);
|
||||
}
|
||||
if (!request.getRequestURI().contains("/swagger") && !request.getRequestURI().contains("/v3/api-docs")) {
|
||||
LoggerUtil.data.info(String.format("%s:param:%s", request.getRequestURI(), JSONObject.toJSONString(arguments)));
|
||||
}
|
||||
}
|
||||
|
||||
// 最终通知
|
||||
@AfterReturning(returning = "returnOb", pointcut = "requestPointcut() || getPointcut() || postPointcut())")
|
||||
public void afterReturningCall(JoinPoint joinPoint, Object returnOb) {
|
||||
long start = RequestIdUtil.getTime();
|
||||
long time = new Date().getTime() - start;
|
||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||
HttpServletRequest request = requestAttributes.getRequest();
|
||||
if (!request.getRequestURI().contains("/swagger") && !request.getRequestURI().contains("/v3/api-docs") && !(returnOb instanceof HttpEntity)) {
|
||||
LoggerUtil.data.info(String.format("%s:耗时:%d", request.getRequestURI(), time));
|
||||
LoggerUtil.data.info(String.format("%s:result:%s", request.getRequestURI(), JSONObject.toJSONString(returnOb)));
|
||||
}
|
||||
}
|
||||
|
||||
// 异常通知
|
||||
@AfterThrowing(value = "requestPointcut() || getPointcut() || postPointcut()", throwing = "ex")
|
||||
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
|
||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||
HttpServletRequest request = requestAttributes.getRequest();
|
||||
if (!request.getRequestURI().contains("/swagger") && !request.getRequestURI().contains("/v3/api-docs")) {
|
||||
LoggerUtil.data.info(String.format("%s:exception:%s", request.getRequestURI(), ExceptionUtils.getStackTrace(ex)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
47
src/main/java/com/diagnose/common/config/JsonConfig.java
Normal file
47
src/main/java/com/diagnose/common/config/JsonConfig.java
Normal file
@ -0,0 +1,47 @@
|
||||
package com.diagnose.common.config;
|
||||
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class JsonConfig {
|
||||
|
||||
static {
|
||||
ParserConfig.getGlobalInstance().setSafeMode(true);
|
||||
}
|
||||
|
||||
@Bean // 使用@Bean注入fastJsonHttpMessageConvert
|
||||
public HttpMessageConverters fastJsonHttpMessageConverters() {
|
||||
// 1.需要定义一个Convert转换消息的对象
|
||||
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
|
||||
|
||||
// 2.添加fastjson的配置信息,比如是否要格式化返回的json数据
|
||||
FastJsonConfig fastJsonConfig = new FastJsonConfig();
|
||||
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段
|
||||
SerializerFeature.WriteNullListAsEmpty, // 将Collection类型字段的字段空值输出为[]
|
||||
// SerializerFeature.WriteNullNumberAsZero, // 将数值类型字段的空值输出为0
|
||||
SerializerFeature.DisableCircularReferenceDetect, // 禁用循环引用
|
||||
SerializerFeature.WriteDateUseDateFormat); //时间格式化
|
||||
|
||||
// 中文乱码解决方案
|
||||
List<MediaType> mediaTypes = new ArrayList<>();
|
||||
mediaTypes.add(new MediaType("application", "json", StandardCharsets.UTF_8));//设定json格式且编码为UTF-8
|
||||
fastConverter.setSupportedMediaTypes(mediaTypes);
|
||||
|
||||
// 3.在convert中添加配置信息
|
||||
fastConverter.setFastJsonConfig(fastJsonConfig);
|
||||
|
||||
return new HttpMessageConverters(fastConverter);
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/com/diagnose/common/config/ScheduleConfig.java
Normal file
22
src/main/java/com/diagnose/common/config/ScheduleConfig.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.diagnose.common.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "scheduledEnable", havingValue = "true")
|
||||
@EnableScheduling
|
||||
public class ScheduleConfig implements SchedulingConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
|
||||
// 开启定时任务多线程,防止默认单线程阻塞问题,超过核心线程数后,还是会阻塞
|
||||
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
|
||||
}
|
||||
|
||||
}
|
||||
47
src/main/java/com/diagnose/common/config/Swagger3Config.java
Normal file
47
src/main/java/com/diagnose/common/config/Swagger3Config.java
Normal file
@ -0,0 +1,47 @@
|
||||
package com.diagnose.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* 利用swagger3构建API
|
||||
*
|
||||
* @author yuanchao
|
||||
*/
|
||||
@Configuration
|
||||
public class Swagger3Config {
|
||||
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.apiInfo(apiInfo())
|
||||
.enable(true)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com")) //扫描该包下的所有需要在Swagger中展示的API,@ApiIgnore注解标注的除外
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.ignoredParameterTypes(HttpSession.class, HttpServletRequest.class, HttpServletResponse.class)
|
||||
.ignoredParameterTypes(ApiIgnore.class);
|
||||
}
|
||||
|
||||
//创建API的基本信息,这些信息会在Swagger UI中进行显示
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("数据应用API")
|
||||
.description("数据应用API")
|
||||
.version("1.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.diagnose.common.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@Configuration
|
||||
public class UpCorsConfiguration {
|
||||
|
||||
@Bean("upCorsFilter")
|
||||
@ConditionalOnProperty(name = "cors.enable", havingValue = "true")
|
||||
public CorsFilter corsFilter() {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
//1,允许任何来源
|
||||
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
|
||||
//2,允许任何请求头
|
||||
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
|
||||
//3,允许任何方法
|
||||
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
|
||||
//4,允许凭证
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", corsConfiguration);
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
|
||||
}
|
||||
47
src/main/java/com/diagnose/common/config/cache/CacheConfig.java
vendored
Normal file
47
src/main/java/com/diagnose/common/config/cache/CacheConfig.java
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package com.diagnose.common.config.cache;
|
||||
|
||||
import com.hazelcast.config.InMemoryFormat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.diagnose.common.config.cache.CacheKey.*;
|
||||
|
||||
public class CacheConfig {
|
||||
|
||||
public static final String DEFAULT_MAP_NAME = "default";
|
||||
|
||||
public static class LocalMapConfig {
|
||||
public final int maxSize;
|
||||
public final int liveSeconds;
|
||||
public final InMemoryFormat inMemoryFormat;
|
||||
|
||||
LocalMapConfig(int maxSize, int liveSeconds) {
|
||||
this.maxSize = maxSize;
|
||||
this.liveSeconds = liveSeconds;
|
||||
this.inMemoryFormat = InMemoryFormat.BINARY;
|
||||
}
|
||||
|
||||
LocalMapConfig(int maxSize, int liveSeconds, InMemoryFormat inMemoryFormat) {
|
||||
this.maxSize = maxSize;
|
||||
this.liveSeconds = liveSeconds;
|
||||
this.inMemoryFormat = inMemoryFormat;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, LocalMapConfig> getConfigMap() {
|
||||
// 设置近地缓存实时同步,不采用批量提交策略
|
||||
System.setProperty("hazelcast.map.invalidation.batch.enabled", "false");
|
||||
// PER_NODE:max-size指定单个集群成员中map条目的最大数量。这是max-size的默认策略。如果使用这个配置,需要注意max-size的值必须大于分区的数量(默认为271)。
|
||||
// PER_PARTITION:max-size指定每个分区存储的map条目最大数。这个策略建议不要在小规模的集群中使用,因为小规模的集群,单个节点包含了大量的分区,在执行回收策略时,会去按照分区的划分组个检查回收条件,导致效率低下。
|
||||
// USED_HEAP_SIZE:指在每个Hazelcast实例中,max-size指定map所占用的内存堆的(以megabytes计算,兆字节)最大值。需要注意这个策略不能工作在in-memory-format=OBJECT,因为当数据被设置为OBJECT时,无法确定所占用的内存大小。
|
||||
// USED_HEAP_PERCENTAGE:每个Hazelcast实例中,max-size指定map占用内存堆的百分比。例如,JVM被设置有1000MB,而这个值设置为max-size=10,当map条目数占用的堆数据超过100MB时,Hazelcast开始执行数据释放工作。需要注意的是当使用这个策略时,不能将in-memory-format设置为OBJECT,理由同上。
|
||||
// FREE_HEAP_SIZE:max-size指定了单个JVM的堆最小空闲空间,单位为megabytes。
|
||||
// FREE_HEAP_PERCENTAGE:max-size指定单个JVM的最小空闲空间的百分比。例如JVM分配了1000MB的空间,这个值设置为10,当空闲堆只有100MB时,会引发map的数据清除放行为。
|
||||
// 当map条数超过10000,会引发map的数据清除行为
|
||||
Map<String, LocalMapConfig> configMap = new HashMap<>();
|
||||
configMap.put(DISTRIBUTED_LOCK, new LocalMapConfig(1000, 0));
|
||||
|
||||
return configMap;
|
||||
}
|
||||
}
|
||||
72
src/main/java/com/diagnose/common/config/cache/CacheConfig.java~
vendored
Normal file
72
src/main/java/com/diagnose/common/config/cache/CacheConfig.java~
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
package com.diagnose.common.config.cache;
|
||||
|
||||
import com.hazelcast.config.InMemoryFormat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.diagnose.common.config.cache.CacheKey.*;
|
||||
|
||||
public class CacheConfig {
|
||||
|
||||
public static final String DEFAULT_MAP_NAME = "default";
|
||||
|
||||
public static class LocalMapConfig {
|
||||
public final int maxSize;
|
||||
public final int liveSeconds;
|
||||
public final InMemoryFormat inMemoryFormat;
|
||||
|
||||
LocalMapConfig(int maxSize, int liveSeconds) {
|
||||
this.maxSize = maxSize;
|
||||
this.liveSeconds = liveSeconds;
|
||||
this.inMemoryFormat = InMemoryFormat.BINARY;
|
||||
}
|
||||
|
||||
LocalMapConfig(int maxSize, int liveSeconds, InMemoryFormat inMemoryFormat) {
|
||||
this.maxSize = maxSize;
|
||||
this.liveSeconds = liveSeconds;
|
||||
this.inMemoryFormat = inMemoryFormat;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, LocalMapConfig> getConfigMap() {
|
||||
// 设置近地缓存实时同步,不采用批量提交策略
|
||||
System.setProperty("hazelcast.map.invalidation.batch.enabled", "false");
|
||||
// PER_NODE:max-size指定单个集群成员中map条目的最大数量。这是max-size的默认策略。如果使用这个配置,需要注意max-size的值必须大于分区的数量(默认为271)。
|
||||
// PER_PARTITION:max-size指定每个分区存储的map条目最大数。这个策略建议不要在小规模的集群中使用,因为小规模的集群,单个节点包含了大量的分区,在执行回收策略时,会去按照分区的划分组个检查回收条件,导致效率低下。
|
||||
// USED_HEAP_SIZE:指在每个Hazelcast实例中,max-size指定map所占用的内存堆的(以megabytes计算,兆字节)最大值。需要注意这个策略不能工作在in-memory-format=OBJECT,因为当数据被设置为OBJECT时,无法确定所占用的内存大小。
|
||||
// USED_HEAP_PERCENTAGE:每个Hazelcast实例中,max-size指定map占用内存堆的百分比。例如,JVM被设置有1000MB,而这个值设置为max-size=10,当map条目数占用的堆数据超过100MB时,Hazelcast开始执行数据释放工作。需要注意的是当使用这个策略时,不能将in-memory-format设置为OBJECT,理由同上。
|
||||
// FREE_HEAP_SIZE:max-size指定了单个JVM的堆最小空闲空间,单位为megabytes。
|
||||
// FREE_HEAP_PERCENTAGE:max-size指定单个JVM的最小空闲空间的百分比。例如JVM分配了1000MB的空间,这个值设置为10,当空闲堆只有100MB时,会引发map的数据清除放行为。
|
||||
// 当map条数超过10000,会引发map的数据清除行为
|
||||
Map<String, LocalMapConfig> configMap = new HashMap<>();
|
||||
configMap.put(DISTRIBUTED_LOCK, new LocalMapConfig(1000, 0));
|
||||
|
||||
configMap.put(DEPT, new LocalMapConfig(10000, 3600));
|
||||
configMap.put(TAG, new LocalMapConfig(10000, 3600));
|
||||
configMap.put(ADVISOR_INFO, new LocalMapConfig(10000, 300));
|
||||
|
||||
configMap.put(RECOMMEND, new LocalMapConfig(10000, 300));
|
||||
configMap.put(USER, new LocalMapConfig(10000, 3600));
|
||||
configMap.put(CAPTCHA, new LocalMapConfig(10000, 300));
|
||||
configMap.put(RBAC, new LocalMapConfig(10000, 300));
|
||||
|
||||
configMap.put(URL_MAP, new LocalMapConfig(10000, 300, InMemoryFormat.OBJECT));
|
||||
configMap.put(SCREEN, new LocalMapConfig(1000, 10, InMemoryFormat.OBJECT));
|
||||
configMap.put(VIDEO_TX_ONLINE, new LocalMapConfig(1000, 20, InMemoryFormat.OBJECT));
|
||||
configMap.put(VIDEO_LIVE_MESSAGE, new LocalMapConfig(10000, 86400));
|
||||
configMap.put(VIDEO_LIVE, new LocalMapConfig(10000, 300));
|
||||
configMap.put(VIDEO_LIVE_DELAY, new LocalMapConfig(10000, 10));
|
||||
configMap.put(VIDEO_LIVE_COLUMN, new LocalMapConfig(10000, 300));
|
||||
configMap.put(VIDEO_ACTIVITY, new LocalMapConfig(1000, 300));
|
||||
configMap.put(VIDEO_LIVE_LIBRARY, new LocalMapConfig(1000, 300));
|
||||
configMap.put(VIDEO_LIVE_USER_MAP, new LocalMapConfig(10000, 300));
|
||||
configMap.put(CUSTOMER_MAP, new LocalMapConfig(10000, 3600));
|
||||
configMap.put(QUESTION, new LocalMapConfig(1000, 30));
|
||||
|
||||
configMap.put(COURSE, new LocalMapConfig(10000, 300));
|
||||
configMap.put(GROUP, new LocalMapConfig(10000, 300));
|
||||
configMap.put(WX_USER, new LocalMapConfig(10000, 3600));
|
||||
return configMap;
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/diagnose/common/config/cache/CacheKey.java
vendored
Normal file
25
src/main/java/com/diagnose/common/config/cache/CacheKey.java
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package com.diagnose.common.config.cache;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class CacheKey {
|
||||
|
||||
public static class OnlyKeyObj implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof OnlyKeyObj;
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存空对象,防止缓存穿透
|
||||
public static final Object ONLY_KEY_OBJ = new OnlyKeyObj();
|
||||
|
||||
// 分布式锁
|
||||
public static final String DISTRIBUTED_LOCK = "distributed_lock";
|
||||
|
||||
public static class LockKey {
|
||||
}
|
||||
|
||||
}
|
||||
373
src/main/java/com/diagnose/common/config/cache/CacheKey.java~
vendored
Normal file
373
src/main/java/com/diagnose/common/config/cache/CacheKey.java~
vendored
Normal file
@ -0,0 +1,373 @@
|
||||
package com.diagnose.common.config.cache;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class CacheKey {
|
||||
|
||||
public static class OnlyKeyObj implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof OnlyKeyObj;
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存空对象,防止缓存穿透
|
||||
public static final Object ONLY_KEY_OBJ = new OnlyKeyObj();
|
||||
|
||||
// 分布式锁
|
||||
public static final String DISTRIBUTED_LOCK = "distributed_lock";
|
||||
|
||||
public static class LockKey {
|
||||
// 清除多余定时器日志
|
||||
public static final String CLEAR_HISTORY_SCHEDULE_LOG = "clearHistoryScheduleLog";
|
||||
// 结束直播中/暂停中的直播 分布式锁(字符串常量)
|
||||
public static final String STOP_LIVING_VIDEO_LOCK = "stop_living_video_lock";
|
||||
// 刷新视频直播状态 分布式锁(字符串常量)
|
||||
public static final String UPDATE_VIDEO_LIVE_STATUS_LOCK = "update_video_live_status_lock";
|
||||
// 从cache刷新视频直播播放量到DB 分布式锁(字符串常量)
|
||||
public static final String SAVE_VIDEO_COUNT_TO_DB_LOCK = "save_video_count_to_db_lock";
|
||||
// 购物车分布式锁
|
||||
public static final String VIDEO_LIVE_HISTORY_LOCK = "video_live_history_lock";
|
||||
public static final String SAVE_VIDEO_USER_DATA_TO_DB_LOCK = "save_video_user_data_to_db_lock";
|
||||
public static final String SAVE_VIDEO_CUSTOMER_DATA_TO_DB_LOCK = "save_video_customer_data_to_db_lock";
|
||||
public static final String LIVE_NOTIFY_LOCK = "live_notify_lock";
|
||||
public static final String REFRESH_TRANSCODE_STATUS = "refresh_transcode_status";
|
||||
public static final String SAVE_SHORT_VIDEO_WATCH_SECONDS = "save_short_video_watch_seconds";
|
||||
|
||||
public static final String COLLECT_LAST_WEEK_LOCK = "collect_last_week_lock";
|
||||
|
||||
public static final String COLLECT_LIVING_VIDEO_LOCK = "collect_living_video_lock";
|
||||
public static final String COLLECT_RECENT_END_VIDEO_LOCK = "collect_recent_end_video_lock";
|
||||
|
||||
public static final String LOAD_USER_BLACK_LIST = "load_user_black_list";
|
||||
public static final String SAVE_MESSAGE_READ = "save_message_read";
|
||||
public static final String SAVE_GROUP_USER = "save_group_user";
|
||||
public static final String COLLECT_GROUP_DATA = "collect_group_data";
|
||||
public static final String SYNC_ORDER = "sync_order";
|
||||
public static final String SYNC_MODULE_USER = "sync_module_user";
|
||||
}
|
||||
|
||||
// 消息主题
|
||||
public static class MessageTopicKey {
|
||||
public static final String VIDEO_MSG = "video_msg";
|
||||
public static final String VIDEO_NOTIFY = "video_notify";
|
||||
public static final String ADMIN_USER = "admin_user";
|
||||
public static final String VIDEO_REPORT = "video_report";
|
||||
public static final String PC_ADVISOR = "pc_advisor";
|
||||
public static final String PC_AUDIENCE = "pc_audience";
|
||||
public static final String SESSION_VIDEO_MSG = "session_video_msg";
|
||||
}
|
||||
|
||||
// 后台用户
|
||||
public static final String USER = "user";
|
||||
|
||||
public static final class UserKey {
|
||||
// userId -> userName
|
||||
public static final String USER_MAP = "user_map";
|
||||
// staffNo -> User
|
||||
public static final String STAFF_MAP = "staff_map";
|
||||
public static final String JWT_EXPIRE_MAP = "jwt_expire_map";
|
||||
public static final String LOGOUT_JWT_MAP = "logout_jwt_map";
|
||||
public static final String USER_DEPT_MAP = "user_dept_map";
|
||||
public static final String USER_BLACK_LIST = "user_black_list";
|
||||
public static final String USER_LOGIN_MAP = "user_login_map";
|
||||
}
|
||||
|
||||
// 部门(营业部/分公司)
|
||||
public static final String DEPT = "dept";
|
||||
|
||||
public static class DeptKey {
|
||||
// deptId -> deptName
|
||||
public static final String DEPT_MAP = "dept_map";
|
||||
// advisorId -> dept
|
||||
public static final String ADVISOR_DEPT_MAP = "advisor_dept_map";
|
||||
// advisorId -> deptId
|
||||
public static final String ADVISOR_DEPT_ID_MAP = "advisor_dept_id_map";
|
||||
// advisorId -> dept
|
||||
public static final String ADVISOR_RELATION_DEPT_MAP = "advisor_relation_dept_map";
|
||||
// userId -> deptId
|
||||
public static final String USER_DEPT_MAP = "user_dept_map";
|
||||
}
|
||||
|
||||
// RBAC权限
|
||||
public static final String RBAC = "rbac";
|
||||
|
||||
public static class RbacKey {
|
||||
public static final String ROLE_PERMISSIONS_URL = "role_permissions_url|";
|
||||
public static final String ALL_PERMISSIONS_URL = "all_permissions_url|";
|
||||
}
|
||||
|
||||
// 管理后台图形验证码
|
||||
public static final String CAPTCHA = "captcha";
|
||||
|
||||
// 标签
|
||||
public static final String TAG = "tag";
|
||||
|
||||
public static class TagKey {
|
||||
// tagId -> tagName
|
||||
public static final String TAG_MAP = "tag_map";
|
||||
}
|
||||
|
||||
// 投顾信息
|
||||
public static final String ADVISOR_INFO = "advisor_info";
|
||||
|
||||
public static final class AdvisorInfoKey {
|
||||
// advisorId -> AdvisorBasic
|
||||
public static final String ADVISOR_MAP = "advisor_map";
|
||||
// advisorId -> AdvisorBasicVO
|
||||
public static final String ADVISOR_VO_MAP = "advisor_vo_map";
|
||||
// userId -> AdvisorBasic
|
||||
public static final String USER_ADVISOR_MAP = "user_advisor_map";
|
||||
// SortedMap<AdvisorSortEntity, Integer> (followCount, advisorId) -> advisorId
|
||||
public static final String APP_FOLLOW_COUNT_LIST = "app_follow_count_list";
|
||||
// SortedMap<AdvisorSortEntity, Integer> (readCount, advisorId) -> advisorId
|
||||
public static final String APP_READ_COUNT_LIST = "app_read_count_list";
|
||||
// SortedMap<AdvisorSortEntity, Integer> (productCount, advisorId) -> advisorId
|
||||
public static final String APP_PRODUCT_COUNT_LIST = "app_product_count_list";
|
||||
// AdvisorInfoAppVO
|
||||
public static final String APP_OBJ = "app_obj|";
|
||||
// advisorId -> PN Counter<followCount>
|
||||
public static final String APP_FOLLOW_COUNT = "app_follow_count|";
|
||||
// userId -> List<AdvisorFollow>
|
||||
public static final String USER_FOLLOW_ADVISOR = "user_follow_advisor|";
|
||||
public static final String USER_ADVISOR_DEPT_MAP = "user_advisor_dept_map";
|
||||
}
|
||||
|
||||
public static final String ADVERT = "advert";
|
||||
|
||||
public static class AdvertKey {
|
||||
public static final String APP_ADVERT_LIST = "app_advert_list|";
|
||||
}
|
||||
|
||||
public static final String RECOMMEND = "recommend";
|
||||
|
||||
public static class RecommendKey {
|
||||
public static final String APP_RECOMMEND_LIST = "app_recommend_list|";
|
||||
}
|
||||
|
||||
// 视频直播信息
|
||||
public static final String VIDEO_LIVE = "video_live";
|
||||
// 视频直播自定义缓存过期时间(put方法设置的过期时间不生效,所以这样处理)
|
||||
public static final String VIDEO_LIVE_DELAY = "video_live_delay";
|
||||
|
||||
public static class VideoLiveKey {
|
||||
// videoId -> VideoLive
|
||||
public static final String VIDEO_INFO = "video_info|";
|
||||
// videoId -> VideoLive 10s缓存
|
||||
public static final String VIDEO_INFO_DELAY = "video_info_delay|";
|
||||
// SortedSet<VideoSortEntity> (startTime auditTime)
|
||||
public static final String APP_LIST = "app_list";
|
||||
public static final String APP_VIDEO_CART = "app_video_cart|";
|
||||
public static final String APP_VIDEO_TAG = "app_video_tag|";
|
||||
public static final String VIDEO_INFO_TAG = "video_info_tag|";
|
||||
public static final String ADVISOR_NO_PLAY_LIST = "advisor_no_play_list";
|
||||
// 与直播相关产品的权限
|
||||
public static final String VIDEO_OTHER_AUTH = "video_other_auth|";
|
||||
public static final String VIDEO_LIVE_RECENT_PUSH_CART = "video_live_recent_push_cart|";
|
||||
public static final String ONLINE_COUNT = "online_count|";
|
||||
public static final String APP_ADVISOR_LIST = "app_advisor_list|";
|
||||
public static final String APP_DEPT_LIST = "app_dept_list|";
|
||||
public static final String APP_ADVISOR_KEY_SET = "app_advisor_key_set|";
|
||||
public static final String APP_DEPT_KEY_SET = "app_dept_key_set|";
|
||||
}
|
||||
|
||||
// 视频直播专栏
|
||||
public static final String VIDEO_LIVE_COLUMN = "video_live_column";
|
||||
|
||||
public static class VideoLiveColumnKey {
|
||||
// List<columnId>
|
||||
public static final String COLUMN_IDS = "column_ids";
|
||||
// columnId -> VideoLiveColumn
|
||||
public static final String COLUMN_INFO = "column_info|";
|
||||
// columnId -> Sort<Integer> (videoId)
|
||||
public static final String VIDEO_IDS = "video_ids|";
|
||||
public static final String LATEST_LIVING_VIDEO = "latest_living_video|";
|
||||
public static final String HIS_GUEST = "his_guest|";
|
||||
public static final String APP_FOLLOW_COUNT = "app_follow_count|";
|
||||
public static final String APP_PLAN_LIST = "app_plan_list";
|
||||
public static final String VIDEO_COLUMN = "video_column";
|
||||
}
|
||||
|
||||
// 视频直播资源
|
||||
public static final String VIDEO_LIVE_LIBRARY = "video_live_library";
|
||||
|
||||
public static class VideoLiveLibraryKey {
|
||||
// libraryId -> VideoLiveLibrary
|
||||
public static final String LIBRARY_INFO = "library_info|";
|
||||
// videoId -> List<libraryId>
|
||||
public static final String LIBRARY_IDS = "library_ids|";
|
||||
}
|
||||
|
||||
public static class VideoRecordKey {
|
||||
// 购物车点击数
|
||||
public static final String CART_READ_COUNT = "cart_read_count|";
|
||||
// 浏览数
|
||||
// videoId -> PV Counter<Integer>
|
||||
public static final String READ_COUNT = "read_count|";
|
||||
// 用户点赞
|
||||
// videoId -> UV Counter<Integer>
|
||||
public static final String FAVOR_USER_COUNT = "favor_user_count|";
|
||||
// videoId -> Set<Integer> (userId)
|
||||
public static final String USER_FAVOR_IDS = "user_favor_ids|";
|
||||
// 视频分享
|
||||
// videoId -> PV Counter<Integer>
|
||||
public static final String SHARE_COUNT = "share_count|";
|
||||
// 视频评论
|
||||
// videoId -> PV Counter<Integer>
|
||||
public static final String MESS_COUNT = "mess_count|";
|
||||
// 用户预约
|
||||
// userId -> Set<Integer> (videoId)
|
||||
public static final String USER_SUBSCRIBE_IDS = "user_subscribe_ids|";
|
||||
// videoId -> Set<String> (userId)
|
||||
public static final String VIDEO_SUBSCRIBE_IDS = "user_subscribe_ids|";
|
||||
public static final String USER_BROWSE_IDS = "user_browse_ids|";
|
||||
public static final String USER_FOLLOW_COLUMN = "user_follow_column|";
|
||||
public static final String TEMP_FAVOR_LIST = "temp_favor_list";
|
||||
// 投顾关注
|
||||
// advisorId -> Set<String> (userId)
|
||||
public static final String ADVISOR_FOLLOW_IDS = "advisor_follow_ids|";
|
||||
}
|
||||
|
||||
// 视频互动消息
|
||||
public static final String VIDEO_LIVE_MESSAGE = "video_live_message";
|
||||
|
||||
public static class VideoLiveMessageKey {
|
||||
// messageId -> VideoLiveMessage
|
||||
public static final String MESSAGE_INFO = "message_info|";
|
||||
// videoId -> List<Integer>(messageId)
|
||||
public static final String MESSAGE_IDS = "message_ids|";
|
||||
public static final String MESSAGE_IDS_ADVISOR = "message_ids_advisor|";
|
||||
// 互动人数
|
||||
// videoId -> UV Counter<Integer>
|
||||
public static final String USER_COUNT = "read_user_count|";
|
||||
public static final String MESSAGE_TOP_20 = "message_top_20|";
|
||||
public static final String MESSAGE_ADVISOR_TOP_20 = "message_advisor_top_20|";
|
||||
public static final String MESSAGE_COUNT = "message_count|";
|
||||
}
|
||||
|
||||
// 评论
|
||||
public static final String COMMENT = "comment";
|
||||
|
||||
public static class CommentKey {
|
||||
public static final String APP_COMMENT_SORT_LIST = "app_comment_sort_list|";
|
||||
public static final String APP_COMMENT_OBJ = "app_comment_obj|";
|
||||
}
|
||||
|
||||
// 评论禁言
|
||||
public static final String COMMENT_BLACK = "comment_black";
|
||||
|
||||
public static class CommentBlackKey {
|
||||
public static final String ALL_BLACK_COMMENT = "all_black_comment";
|
||||
public static final String ALL_BLACK_USER = "all_black_user";
|
||||
}
|
||||
|
||||
public static final String VIDEO_ACTIVITY = "video_activity";
|
||||
|
||||
public static class VideoActivityKey {
|
||||
public static final String VIDEO_ACTIVITY_LIST = "video_activity_list";
|
||||
public static final String VIDEO_ACTIVITY_OBJ = "video_activity_obj|";
|
||||
}
|
||||
|
||||
public static final String VIDEO_LIVE_HIS_DATE = "video_live_his_date";
|
||||
|
||||
public static final String QUESTION = "question";
|
||||
|
||||
public static class QuestionKey {
|
||||
public static final String QUESTION_DETAILS = "question_details|";
|
||||
}
|
||||
|
||||
public static final class OnlineLineKey {
|
||||
public static final String USER_VIDEO_TOTAL_ONLINE = "user_video_total_online|";
|
||||
}
|
||||
|
||||
public static final String URL_MAP = "url_map";
|
||||
|
||||
public static final class URL_KEY {
|
||||
public static final String URL_KEY = "url_key|";
|
||||
public static final String URL_KEY_VIDEO_ID = "url_key_video_id|";
|
||||
public static final String URL_KEY_SHORT_VIDEO_ID = "url_key_short_video_id|";
|
||||
}
|
||||
|
||||
public static final String VIDEO_TX_ONLINE = "video_tx_online|";
|
||||
|
||||
public static final class TXKey {
|
||||
public static final String VIDEO_ONLINE_TX = "video_online_tx|";
|
||||
}
|
||||
|
||||
public static final String CUSTOMER_MAP = "customer_map";
|
||||
|
||||
public static final class CustomerKey {
|
||||
public static final String CUSTOMER_DETAILS = "customer_details|";
|
||||
public static final String VIDEO_CUSTOMER_SET = "video_customer_set";
|
||||
public static final String VIDEO_CUSTOMER_SALE_SET = "video_customer_sale_set";
|
||||
public static final String CUSTOMER_SALE = "customer_sale|";
|
||||
}
|
||||
|
||||
public static final String WX_USER = "wx_user";
|
||||
|
||||
public static final class WxUserKey {
|
||||
public static final String USER = "user|";
|
||||
}
|
||||
|
||||
public static final String SCREEN = "screen";
|
||||
|
||||
public static final class ScreenKey {
|
||||
public static final String SCREEN_VIDEO_INFO = "screen_video_info|";
|
||||
}
|
||||
|
||||
public static final String VIDEO_LIVE_USER_MAP = "video_live_user_map";
|
||||
|
||||
public static final class VideoLiveUserKey {
|
||||
public static final String LIVE_USER_OBJ = "live_user_obj|";
|
||||
}
|
||||
|
||||
public static final String COURSE = "course";
|
||||
|
||||
public static final class CourseKey {
|
||||
public static final String COURSE_INFO = "course_info|";
|
||||
public static final String COURSE_CONTENT = "course_content|";
|
||||
public static final String SERIAL_INFO = "serial_info|";
|
||||
public static final String SERIAL_CONTENT = "serial_content|";
|
||||
public static final String PAGE = "page|";
|
||||
public static final String SHORT_VIDEO = "short_video|";
|
||||
public static final String SHORT_VIDEO_FAVOR_USER_IDS = "favor_user_ids|";
|
||||
public static final String MAIN_TAB = "main_tab|";
|
||||
public static final String MAIN_COURSE_LIST = "main_course_list|";
|
||||
public static final String MAIN_SHORT_VIDEO_LIST = "main_short_video_list|";
|
||||
public static final String PC_COURSE_LIST = "pc_course_list|";
|
||||
public static final String SALE_USER_WORK_WEIXIN_QRCODE_IMAGE = "sale_user_work_weixin_qrcode_image|";
|
||||
public static final String SHORT_VIDEO_WATCH_LIST = "short_video_watch_list";
|
||||
public static final String COURSE_PACKAGE = "course_package|";
|
||||
public static final String COURSE_PACKAGE_CONTENT = "course_package_content|";
|
||||
}
|
||||
|
||||
public static final String GROUP = "group";
|
||||
|
||||
// 消息主题
|
||||
public static class GroupMessageTopicKey {
|
||||
public static final String ADMIN_GROUP_TOPIC = "admin_group_topic";
|
||||
public static final String ADMIN_PRIVATE_TOPIC = "admin_private_topic";
|
||||
public static final String ADMIN_SESSION_TOPIC = "admin_session_topic";
|
||||
public static final String APP_GROUP_TOPIC = "app_group_topic";
|
||||
public static final String APP_PRIVATE_TOPIC = "app_private_topic";
|
||||
public static final String APP_SESSION_TOPIC = "app_session_topic";
|
||||
}
|
||||
|
||||
public static class GroupKey {
|
||||
public static final String GROUP_INFO = "group_info|";
|
||||
public static final String MAIN_GROUP_LIST = "group_main_list|";
|
||||
public static final String GROUP_MESSAGE_LIST = "group_message_list|";
|
||||
public static final String GROUP_MESSAGE_DETAIL = "group_message_detail|";
|
||||
public static final String USER_TOTAL_ONLINE = "user_total_online|";
|
||||
public static final String TEMP_READ_LIST = "temp_read_list";
|
||||
public static final String GROUP_MESSAGE_DATE_ID_MAP = "group_message_date_id_map|";
|
||||
public static final String ONLINE_COUNT = "online_count|";
|
||||
}
|
||||
|
||||
public static final String GROUP_ONLINE_USER = "group_online_user";
|
||||
|
||||
public static final String VIDEO_ONLINE_USER = "video_online_user";
|
||||
|
||||
}
|
||||
91
src/main/java/com/diagnose/common/config/cache/HazelcastConfiguration.java
vendored
Normal file
91
src/main/java/com/diagnose/common/config/cache/HazelcastConfiguration.java
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
package com.diagnose.common.config.cache;
|
||||
|
||||
import com.hazelcast.config.*;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.util.*;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastConfiguration {
|
||||
|
||||
@Value("${hazelcast.members}")
|
||||
private String members;
|
||||
|
||||
@Value("${hazelcast.serverPort}")
|
||||
private Integer serverPort;
|
||||
|
||||
private Set<String> cacheNameSet = new HashSet<>();
|
||||
|
||||
@Bean
|
||||
public HazelcastInstance hazelcastInstance() {
|
||||
List<String> memberList = Arrays.asList(members.split(","));
|
||||
Config config = new Config();
|
||||
// hazelcast作为缓存服务端监听的端口
|
||||
config.getNetworkConfig().setPort(serverPort);
|
||||
// 如果目标缓存端口被占用,禁止重试其他端口
|
||||
config.getNetworkConfig().setPortAutoIncrement(false);
|
||||
config.getNetworkConfig().getJoin().getAutoDetectionConfig().setEnabled(false);
|
||||
config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true).setMembers(memberList);
|
||||
config.getJetConfig().setEnabled(true);
|
||||
String clusterName = "hazelcast-cluster";
|
||||
String instanceName = clusterName + "." + "localIP";
|
||||
config.setInstanceName(instanceName);
|
||||
config.setClusterName(clusterName);
|
||||
for (Map.Entry<String, CacheConfig.LocalMapConfig> entry : CacheConfig.getConfigMap().entrySet()) {
|
||||
String cacheName = entry.getKey();
|
||||
cacheNameSet.add(cacheName);
|
||||
config.addMapConfig(new MapConfig()
|
||||
.setName(cacheName)
|
||||
.setEvictionConfig(new EvictionConfig()
|
||||
.setEvictionPolicy(EvictionPolicy.LRU)
|
||||
.setSize(entry.getValue().maxSize)
|
||||
.setMaxSizePolicy(MaxSizePolicy.PER_NODE))
|
||||
.setTimeToLiveSeconds(entry.getValue().liveSeconds)
|
||||
// 近地缓存设置
|
||||
.setNearCacheConfig(new NearCacheConfig()
|
||||
.setInMemoryFormat(entry.getValue().inMemoryFormat)
|
||||
.setCacheLocalEntries(true)
|
||||
.setTimeToLiveSeconds(entry.getValue().liveSeconds / 2)
|
||||
.setEvictionConfig(new EvictionConfig()
|
||||
.setMaxSizePolicy(MaxSizePolicy.ENTRY_COUNT)
|
||||
.setSize(entry.getValue().maxSize / 2))
|
||||
// 预加载近地缓存,防止近地缓存穿透(暂时不启用)
|
||||
// .setPreloaderConfig(new NearCachePreloaderConfig()
|
||||
// .setEnabled(true))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// 默认map配置,主要用于USER_VIDEO_TOTAL_ONLINE + videoId
|
||||
config.addMapConfig(new MapConfig()
|
||||
.setName(CacheConfig.DEFAULT_MAP_NAME)
|
||||
.setNearCacheConfig(new NearCacheConfig()
|
||||
.setInMemoryFormat(InMemoryFormat.OBJECT)
|
||||
.setCacheLocalEntries(true)
|
||||
.setTimeToLiveSeconds(3600 * 10)
|
||||
.setMaxIdleSeconds(3600 * 2)
|
||||
.setEvictionConfig(new EvictionConfig()
|
||||
.setMaxSizePolicy(MaxSizePolicy.ENTRY_COUNT)
|
||||
.setSize(100000))
|
||||
));
|
||||
HazelcastInstance instance = Hazelcast.newHazelcastInstance(config);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void cleanCache() {
|
||||
for (String cacheName : cacheNameSet) {
|
||||
hazelcastInstance().getMap(cacheName).clear();
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
hazelcastInstance().shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.diagnose.common.config.mybatis;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EasySqlInjector extends DefaultSqlInjector {
|
||||
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||
methodList.add(new InsertBatchSomeColumn());
|
||||
methodList.add(new SaveBatchSomeColumn(i -> i.getFieldFill() == FieldFill.INSERT_UPDATE));
|
||||
methodList.add(new Save());
|
||||
return methodList;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.diagnose.common.config.mybatis;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@MapperScan("com.diagnose")
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EasySqlInjector easySqlInjector() {
|
||||
return new EasySqlInjector();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.diagnose.common.config.mybatis;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@MapperScan("com.syzb")
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EasySqlInjector easySqlInjector() {
|
||||
return new EasySqlInjector();
|
||||
}
|
||||
|
||||
}
|
||||
64
src/main/java/com/diagnose/common/config/mybatis/Save.java
Normal file
64
src/main/java/com/diagnose/common/config/mybatis/Save.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.diagnose.common.config.mybatis;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
|
||||
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
||||
import org.apache.ibatis.executor.keygen.KeyGenerator;
|
||||
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlSource;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Save extends AbstractMethod {
|
||||
|
||||
public static final String saveSql = "<script>\nINSERT INTO %s %s VALUES %s ON DUPLICATE KEY UPDATE %s\n</script>";
|
||||
|
||||
public static final String methodName = "save";
|
||||
|
||||
public Save() {
|
||||
super(methodName);
|
||||
}
|
||||
|
||||
public Save(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;
|
||||
String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumnMaybeIf(null),
|
||||
LEFT_BRACKET, RIGHT_BRACKET, null, COMMA);
|
||||
String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlPropertyMaybeIf(null),
|
||||
LEFT_BRACKET, RIGHT_BRACKET, null, COMMA);
|
||||
String updateScript = tableInfo.getFieldList().stream().map(TableFieldInfo::getColumn).map(column ->
|
||||
String.format("<if test=\"%s != null\">%s = VALUES(%s),</if>", column, column, column)
|
||||
).collect(Collectors.joining(NEWLINE));
|
||||
updateScript = SqlScriptUtils.convertTrim(updateScript, EMPTY, EMPTY, null, COMMA);
|
||||
String keyProperty = null;
|
||||
String keyColumn = null;
|
||||
// 表包含主键处理逻辑,如果不包含主键当普通字段处理
|
||||
if (StrUtil.isNotBlank(tableInfo.getKeyProperty())) {
|
||||
if (tableInfo.getIdType() == IdType.AUTO) {
|
||||
/* 自增主键 */
|
||||
keyGenerator = Jdbc3KeyGenerator.INSTANCE;
|
||||
keyProperty = tableInfo.getKeyProperty();
|
||||
keyColumn = tableInfo.getKeyColumn();
|
||||
} else {
|
||||
if (null != tableInfo.getKeySequence()) {
|
||||
keyGenerator = TableInfoHelper.genKeyGenerator(methodName, tableInfo, builderAssistant);
|
||||
keyProperty = tableInfo.getKeyProperty();
|
||||
keyColumn = tableInfo.getKeyColumn();
|
||||
}
|
||||
}
|
||||
}
|
||||
String sql = String.format(saveSql, tableInfo.getTableName(), columnScript, valuesScript, updateScript);
|
||||
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
|
||||
return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource, keyGenerator, keyProperty, keyColumn);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
package com.diagnose.common.config.mybatis;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
|
||||
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
||||
import org.apache.ibatis.executor.keygen.KeyGenerator;
|
||||
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SaveBatchSomeColumn extends AbstractMethod {
|
||||
|
||||
private static final String methodName = "saveBatchSomeColumn";
|
||||
|
||||
/**
|
||||
* 字段筛选条件
|
||||
*/
|
||||
private Predicate<TableFieldInfo> predicate;
|
||||
|
||||
public Predicate<TableFieldInfo> getPredicate() {
|
||||
return predicate;
|
||||
}
|
||||
|
||||
public void setPredicate(Predicate<TableFieldInfo> predicate) {
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认方法名
|
||||
*/
|
||||
public SaveBatchSomeColumn() {
|
||||
super(methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认方法名
|
||||
*
|
||||
* @param predicate 字段筛选条件
|
||||
*/
|
||||
public SaveBatchSomeColumn(Predicate<TableFieldInfo> predicate) {
|
||||
super(methodName);
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name 方法名
|
||||
* @param predicate 字段筛选条件
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public SaveBatchSomeColumn(String name, Predicate<TableFieldInfo> predicate) {
|
||||
super(name);
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;
|
||||
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
|
||||
String insertSqlColumn = tableInfo.getKeyInsertSqlColumn(true, false) +
|
||||
this.filterTableFieldInfo(fieldList, predicate, TableFieldInfo::getInsertSqlColumn, EMPTY);
|
||||
String columnScript = LEFT_BRACKET + (insertSqlColumn.isEmpty() ? "" : insertSqlColumn.substring(0, insertSqlColumn.length() - 1)) + RIGHT_BRACKET;
|
||||
String insertSqlProperty = tableInfo.getKeyInsertSqlProperty(true, ENTITY_DOT, false) +
|
||||
this.filterTableFieldInfo(fieldList, predicate, i -> i.getInsertSqlProperty(ENTITY_DOT), EMPTY);
|
||||
insertSqlProperty = LEFT_BRACKET + (insertSqlProperty.isEmpty() ? "" : insertSqlProperty.substring(0, insertSqlProperty.length() - 1)) + RIGHT_BRACKET;
|
||||
String valuesScript = SqlScriptUtils.convertForeach(insertSqlProperty, "list", null, ENTITY, COMMA);
|
||||
String updateScript = fieldList.stream().filter(predicate == null ? x -> true : predicate).map(TableFieldInfo::getColumn).map(column ->
|
||||
String.format("%s = VALUES(%s),", column, column)).collect(Collectors.joining(NEWLINE));
|
||||
updateScript = SqlScriptUtils.convertTrim(updateScript, EMPTY, EMPTY, null, COMMA);
|
||||
String keyProperty = null;
|
||||
String keyColumn = null;
|
||||
// 表包含主键处理逻辑,如果不包含主键当普通字段处理
|
||||
if (tableInfo.havePK()) {
|
||||
if (tableInfo.getIdType() == IdType.AUTO) {
|
||||
/* 自增主键 */
|
||||
keyGenerator = Jdbc3KeyGenerator.INSTANCE;
|
||||
keyProperty = tableInfo.getKeyProperty();
|
||||
keyColumn = tableInfo.getKeyColumn();
|
||||
} else {
|
||||
if (null != tableInfo.getKeySequence()) {
|
||||
keyGenerator = TableInfoHelper.genKeyGenerator(methodName, tableInfo, builderAssistant);
|
||||
keyProperty = tableInfo.getKeyProperty();
|
||||
keyColumn = tableInfo.getKeyColumn();
|
||||
}
|
||||
}
|
||||
}
|
||||
String sql = String.format(Save.saveSql, tableInfo.getTableName(), columnScript, valuesScript, updateScript);
|
||||
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
|
||||
return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource, keyGenerator, keyProperty, keyColumn);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.diagnose.common.constant;
|
||||
|
||||
public enum ScheduleLogResult {
|
||||
|
||||
RUNNING(1, "执行中"),
|
||||
SUCCESS(2, "成功"),
|
||||
FAILURE(3, "失败");
|
||||
public final Integer value;
|
||||
|
||||
public final String name;
|
||||
|
||||
ScheduleLogResult(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
208
src/main/java/com/diagnose/common/entity/ScheduleLog.java
Normal file
208
src/main/java/com/diagnose/common/entity/ScheduleLog.java
Normal file
@ -0,0 +1,208 @@
|
||||
package com.diagnose.common.entity;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.diagnose.common.constant.ScheduleLogResult;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2022-11-09
|
||||
*/
|
||||
public class ScheduleLog implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 同步记录ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 服务名
|
||||
*/
|
||||
@TableField("server_name")
|
||||
private String serverName;
|
||||
|
||||
/**
|
||||
* 定时任务名称
|
||||
*/
|
||||
@TableField("schedule_name")
|
||||
private String scheduleName;
|
||||
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private LocalDate date;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
@TableField("start_time")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
@TableField("end_time")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
/**
|
||||
* 执行结果:1:执行中 2:成功 3:失败
|
||||
*/
|
||||
private Integer result;
|
||||
|
||||
/**
|
||||
* 附加信息json
|
||||
*/
|
||||
private String ext;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 执行机器IP
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
public static ScheduleLog start(String scheduleName, String ip) {
|
||||
String server = System.getProperty("server.server");
|
||||
ScheduleLog log = new ScheduleLog();
|
||||
log.setServerName(server);
|
||||
log.setScheduleName(scheduleName);
|
||||
log.setDate(LocalDate.now());
|
||||
log.setStartTime(LocalDateTime.now());
|
||||
log.setResult(ScheduleLogResult.RUNNING.value);
|
||||
log.setIp(ip);
|
||||
return log;
|
||||
}
|
||||
|
||||
public static ScheduleLog success(Integer id, String ext) {
|
||||
ScheduleLog log = new ScheduleLog();
|
||||
log.setId(id);
|
||||
log.setEndTime(LocalDateTime.now());
|
||||
log.setResult(ScheduleLogResult.SUCCESS.value);
|
||||
if (StrUtil.isNotEmpty(ext)) {
|
||||
log.setExt(ext);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
public static ScheduleLog error(Integer id, String error) {
|
||||
ScheduleLog log = new ScheduleLog();
|
||||
log.setId(id);
|
||||
log.setEndTime(LocalDateTime.now());
|
||||
log.setResult(ScheduleLogResult.FAILURE.value);
|
||||
if (StrUtil.isNotEmpty(error)) {
|
||||
log.setError(error);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
public String getScheduleName() {
|
||||
return scheduleName;
|
||||
}
|
||||
|
||||
public void setScheduleName(String scheduleName) {
|
||||
this.scheduleName = scheduleName;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(LocalDateTime startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(LocalDateTime endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public Integer getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Integer result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getExt() {
|
||||
return ext;
|
||||
}
|
||||
|
||||
public void setExt(String ext) {
|
||||
this.ext = ext;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScheduleLog{" +
|
||||
"id=" + id +
|
||||
", serverName=" + serverName +
|
||||
", scheduleName=" + scheduleName +
|
||||
", date=" + date +
|
||||
", startTime=" + startTime +
|
||||
", endTime=" + endTime +
|
||||
", result=" + result +
|
||||
", ext=" + ext +
|
||||
", error=" + error +
|
||||
", ip=" + ip +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.diagnose.common.generator;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||
import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.*;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
|
||||
public class CodeGenerator {
|
||||
|
||||
public static String scanner(String tip) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String help = "请输入" + tip + ":";
|
||||
System.out.println(help);
|
||||
if (scanner.hasNext()) {
|
||||
String ipt = scanner.nextLine();
|
||||
if (StrUtil.isNotBlank(ipt)) {
|
||||
return ipt;
|
||||
}
|
||||
}
|
||||
throw new MybatisPlusException("请输入正确的" + tip + "!");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataSourceConfig dsc = new DataSourceConfig
|
||||
.Builder("jdbc:mysql://47.96.178.171:3306/db_upsync?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8",
|
||||
"eason",
|
||||
"mysql2025easonzhu")
|
||||
// .Builder("jdbc:mysql://172.16.9.44:3306/db_crm_dyqh?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false",
|
||||
// "taf",
|
||||
// "taf2015")
|
||||
.build();
|
||||
// 代码生成器
|
||||
AutoGenerator mpg = new AutoGenerator(dsc);
|
||||
|
||||
String moduleName = scanner("模块名");
|
||||
String projectPath = System.getProperty("user.dir") + "";
|
||||
|
||||
// 全局配置
|
||||
GlobalConfig globalConfig = new GlobalConfig
|
||||
.Builder()
|
||||
.outputDir(projectPath + "/src/main/java")
|
||||
.author("helloSyzb")
|
||||
.openDir(false)
|
||||
.fileOverride()
|
||||
.build();
|
||||
|
||||
// 包配置
|
||||
PackageConfig packageConfig = new PackageConfig
|
||||
.Builder()
|
||||
.parent("com.diagnose")
|
||||
.moduleName(moduleName)
|
||||
.build();
|
||||
|
||||
// 配置模板
|
||||
TemplateConfig templateConfig = new TemplateConfig
|
||||
.Builder()
|
||||
.mapperXml(null)
|
||||
.service(null, null)
|
||||
.controller(null)
|
||||
.build();
|
||||
|
||||
// 策略配置
|
||||
StrategyConfig strategyConfig = new StrategyConfig
|
||||
.Builder()
|
||||
.addInclude(scanner("表名,多个英文逗号分割").split(","))
|
||||
.entityBuilder()
|
||||
.naming(NamingStrategy.underline_to_camel)
|
||||
.controllerBuilder()
|
||||
.enableRestStyle()
|
||||
.build();
|
||||
|
||||
mpg.global(globalConfig);
|
||||
mpg.packageInfo(packageConfig);
|
||||
mpg.template(templateConfig);
|
||||
mpg.strategy(strategyConfig);
|
||||
mpg.execute(new FreemarkerTemplateEngine());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.diagnose.common.generator;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||
import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.*;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
|
||||
public class CodeGenerator {
|
||||
|
||||
public static String scanner(String tip) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String help = "请输入" + tip + ":";
|
||||
System.out.println(help);
|
||||
if (scanner.hasNext()) {
|
||||
String ipt = scanner.nextLine();
|
||||
if (StrUtil.isNotBlank(ipt)) {
|
||||
return ipt;
|
||||
}
|
||||
}
|
||||
throw new MybatisPlusException("请输入正确的" + tip + "!");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataSourceConfig dsc = new DataSourceConfig
|
||||
.Builder("jdbc:mysql://47.96.178.171:3306/db_upsync?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8",
|
||||
"eason",
|
||||
"mysql2025easonzhu")
|
||||
// .Builder("jdbc:mysql://172.16.9.44:3306/db_crm_dyqh?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false",
|
||||
// "taf",
|
||||
// "taf2015")
|
||||
.build();
|
||||
// 代码生成器
|
||||
AutoGenerator mpg = new AutoGenerator(dsc);
|
||||
|
||||
String moduleName = scanner("模块名");
|
||||
String projectPath = System.getProperty("user.dir") + "";
|
||||
|
||||
// 全局配置
|
||||
GlobalConfig globalConfig = new GlobalConfig
|
||||
.Builder()
|
||||
.outputDir(projectPath + "/src/main/java")
|
||||
.author("helloSyzb")
|
||||
.openDir(false)
|
||||
.fileOverride()
|
||||
.build();
|
||||
|
||||
// 包配置
|
||||
PackageConfig packageConfig = new PackageConfig
|
||||
.Builder()
|
||||
.parent("com.syzb")
|
||||
.moduleName(moduleName)
|
||||
.build();
|
||||
|
||||
// 配置模板
|
||||
TemplateConfig templateConfig = new TemplateConfig
|
||||
.Builder()
|
||||
.mapperXml(null)
|
||||
.service(null, null)
|
||||
.controller(null)
|
||||
.build();
|
||||
|
||||
// 策略配置
|
||||
StrategyConfig strategyConfig = new StrategyConfig
|
||||
.Builder()
|
||||
.addInclude(scanner("表名,多个英文逗号分割").split(","))
|
||||
.entityBuilder()
|
||||
.naming(NamingStrategy.underline_to_camel)
|
||||
.controllerBuilder()
|
||||
.enableRestStyle()
|
||||
.build();
|
||||
|
||||
mpg.global(globalConfig);
|
||||
mpg.packageInfo(packageConfig);
|
||||
mpg.template(templateConfig);
|
||||
mpg.strategy(strategyConfig);
|
||||
mpg.execute(new FreemarkerTemplateEngine());
|
||||
}
|
||||
|
||||
}
|
||||
72
src/main/java/com/diagnose/common/handler/BizException.java
Normal file
72
src/main/java/com/diagnose/common/handler/BizException.java
Normal file
@ -0,0 +1,72 @@
|
||||
package com.diagnose.common.handler;
|
||||
|
||||
import com.diagnose.common.result.ResponseStatus;
|
||||
|
||||
public class BizException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
protected Integer errorCode = -1;
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
protected String errorMsg;
|
||||
|
||||
public BizException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BizException(ResponseStatus responseStatus) {
|
||||
super(responseStatus.code.toString() + "," + responseStatus.message);
|
||||
this.errorCode = responseStatus.code;
|
||||
this.errorMsg = responseStatus.message;
|
||||
}
|
||||
|
||||
public BizException(ResponseStatus responseStatus, String extendMsg) {
|
||||
super(responseStatus.code.toString() + "," + responseStatus.message + "," + extendMsg);
|
||||
this.errorCode = responseStatus.code;
|
||||
this.errorMsg = extendMsg;
|
||||
}
|
||||
|
||||
public BizException(ResponseStatus responseStatus, Throwable cause) {
|
||||
super(responseStatus.code.toString() + "," + responseStatus.message, cause);
|
||||
this.errorCode = responseStatus.code;
|
||||
this.errorMsg = responseStatus.message;
|
||||
}
|
||||
|
||||
public BizException(String errorMsg) {
|
||||
super(errorMsg);
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public BizException(Integer errorCode, String errorMsg) {
|
||||
super(errorCode.toString() + "," + errorMsg);
|
||||
this.errorCode = errorCode;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public BizException(Integer errorCode, String errorMsg, Throwable cause) {
|
||||
super(errorCode.toString() + "," + errorMsg, cause);
|
||||
this.errorCode = errorCode;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public Integer getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public void setErrorCode(Integer errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
72
src/main/java/com/diagnose/common/handler/BizException.java~
Normal file
72
src/main/java/com/diagnose/common/handler/BizException.java~
Normal file
@ -0,0 +1,72 @@
|
||||
package com.diagnose.common.handler;
|
||||
|
||||
import com.syzb.common.result.ResponseStatus;
|
||||
|
||||
public class BizException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
protected Integer errorCode = -1;
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
protected String errorMsg;
|
||||
|
||||
public BizException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BizException(ResponseStatus responseStatus) {
|
||||
super(responseStatus.code.toString() + "," + responseStatus.message);
|
||||
this.errorCode = responseStatus.code;
|
||||
this.errorMsg = responseStatus.message;
|
||||
}
|
||||
|
||||
public BizException(ResponseStatus responseStatus, String extendMsg) {
|
||||
super(responseStatus.code.toString() + "," + responseStatus.message + "," + extendMsg);
|
||||
this.errorCode = responseStatus.code;
|
||||
this.errorMsg = extendMsg;
|
||||
}
|
||||
|
||||
public BizException(ResponseStatus responseStatus, Throwable cause) {
|
||||
super(responseStatus.code.toString() + "," + responseStatus.message, cause);
|
||||
this.errorCode = responseStatus.code;
|
||||
this.errorMsg = responseStatus.message;
|
||||
}
|
||||
|
||||
public BizException(String errorMsg) {
|
||||
super(errorMsg);
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public BizException(Integer errorCode, String errorMsg) {
|
||||
super(errorCode.toString() + "," + errorMsg);
|
||||
this.errorCode = errorCode;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public BizException(Integer errorCode, String errorMsg, Throwable cause) {
|
||||
super(errorCode.toString() + "," + errorMsg, cause);
|
||||
this.errorCode = errorCode;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public Integer getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public void setErrorCode(Integer errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
package com.diagnose.common.handler;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.diagnose.common.result.CommonResult;
|
||||
import com.diagnose.common.result.ResponseStatus;
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import java.util.Set;
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理自定义的业务异常
|
||||
*
|
||||
* @param req
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(value = BizException.class)
|
||||
@ResponseBody
|
||||
public CommonResult<Void> bizExceptionHandler(HttpServletRequest req, BizException e) {
|
||||
LoggerUtil.error("发生业务异常:" + req.getRequestURI() + ":" + ExceptionUtils.getStackTrace(e));
|
||||
return CommonResult.error(e.getErrorCode(), e.getErrorMsg());
|
||||
}
|
||||
|
||||
@ExceptionHandler({ConstraintViolationException.class})
|
||||
@org.springframework.web.bind.annotation.ResponseStatus(HttpStatus.OK)
|
||||
@ResponseBody
|
||||
public CommonResult<Void> handleConstraintViolationException(HttpServletRequest req, ConstraintViolationException ex) {
|
||||
LoggerUtil.error("GET参数异常:" + req.getRequestURI() + ":" + ExceptionUtils.getStackTrace(ex));
|
||||
return CommonResult.error(ResponseStatus.PARM_ERROR.code, ex.getMessage());
|
||||
}
|
||||
|
||||
// 入参错误返回200,统一定义返回信息
|
||||
@ExceptionHandler({MethodArgumentNotValidException.class})
|
||||
@org.springframework.web.bind.annotation.ResponseStatus(HttpStatus.OK)
|
||||
@ResponseBody
|
||||
public CommonResult<Void> handleMethodArgumentNotValidException(HttpServletRequest req, MethodArgumentNotValidException ex) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (FieldError err : ex.getBindingResult().getFieldErrors()) {
|
||||
sb.append("字段:")
|
||||
.append(err.getField())
|
||||
.append(",传入值:")
|
||||
.append(err.getRejectedValue())
|
||||
.append(",")
|
||||
.append(err.getDefaultMessage())
|
||||
.append("; ");
|
||||
}
|
||||
LoggerUtil.error("POST参数异常:" + req.getRequestURI() + ":" + ExceptionUtils.getStackTrace(ex));
|
||||
return CommonResult.error(ResponseStatus.PARM_ERROR.code, sb.toString());
|
||||
}
|
||||
|
||||
@ExceptionHandler({MissingServletRequestParameterException.class})
|
||||
@org.springframework.web.bind.annotation.ResponseStatus(HttpStatus.OK)
|
||||
@ResponseBody
|
||||
public CommonResult<Void> handleMissingServletRequestParameterException(HttpServletRequest req, MissingServletRequestParameterException ex) {
|
||||
StringBuilder sb = new StringBuilder("字段:")
|
||||
.append(ex.getParameterName())
|
||||
.append(",类型:")
|
||||
.append(ex.getParameterType())
|
||||
.append(":")
|
||||
.append(ex.getMessage())
|
||||
.append(".");
|
||||
LoggerUtil.error("入参缺失:" + req.getRequestURI() + ":" + ExceptionUtils.getStackTrace(ex));
|
||||
return CommonResult.error(ResponseStatus.PARM_ERROR.code, sb.toString());
|
||||
}
|
||||
|
||||
@ExceptionHandler({HttpMessageNotReadableException.class})
|
||||
@org.springframework.web.bind.annotation.ResponseStatus(HttpStatus.OK)
|
||||
@ResponseBody
|
||||
public CommonResult<Void> handleHttpMessageNotReadableException(HttpServletRequest req, HttpMessageNotReadableException ex) {
|
||||
StringBuilder sb = new StringBuilder("入参格式或类型错误:")
|
||||
.append(ex.getMessage());
|
||||
LoggerUtil.error("入参格式或类型错误:" + req.getRequestURI() + ":" + ExceptionUtils.getStackTrace(ex));
|
||||
return CommonResult.error(ResponseStatus.PARM_ERROR.code, sb.toString());
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = Exception.class)
|
||||
@ResponseBody
|
||||
public CommonResult<Void> doHandlerException(HttpServletRequest req, Exception e) {
|
||||
LoggerUtil.error("全局异常捕获:" + req.getRequestURI() + ":" + ExceptionUtils.getStackTrace(e));
|
||||
return CommonResult.error(ResponseStatus.SYS_BUSY);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.diagnose.common.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.diagnose.common.entity.ScheduleLog;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2021-11-23
|
||||
*/
|
||||
public interface ScheduleLogMapper extends BaseMapper<ScheduleLog> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.syzb.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class AppUserInfoQuery {
|
||||
|
||||
@ApiModelProperty("登录方式 1:用户名密码 2:token")
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(2)
|
||||
private Integer loginType;
|
||||
|
||||
@ApiModelProperty("用户名")
|
||||
private String userName;
|
||||
|
||||
@ApiModelProperty("密码")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty("token")
|
||||
private String token;
|
||||
|
||||
@ApiModelProperty("refreshToken")
|
||||
private String refreshToken;
|
||||
|
||||
@ApiModelProperty("客户类型 1:H5 2:Web")
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(2)
|
||||
private Integer clientType;
|
||||
|
||||
public Integer getLoginType() {
|
||||
return loginType;
|
||||
}
|
||||
|
||||
public void setLoginType(Integer loginType) {
|
||||
this.loginType = loginType;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public Integer getClientType() {
|
||||
return clientType;
|
||||
}
|
||||
|
||||
public void setClientType(Integer clientType) {
|
||||
this.clientType = clientType;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.syzb.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class BaseProductQuery implements IProduct {
|
||||
|
||||
@ApiModelProperty("产品id")
|
||||
private Integer productId;
|
||||
|
||||
@ApiModelProperty("产品类型:1观点包 2单篇观点 3视频 5交易圈 6图文直播间 7组合 8锦囊")
|
||||
private Integer productType;
|
||||
|
||||
public BaseProductQuery(Integer productId, Integer productType) {
|
||||
this.productId = productId;
|
||||
this.productType = productType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(Integer productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getProductType() {
|
||||
return productType;
|
||||
}
|
||||
|
||||
public void setProductType(Integer productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.diagnose.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class KeywordPageQuery extends PageQuery {
|
||||
|
||||
@ApiModelProperty("关键词")
|
||||
private String keyword;
|
||||
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public void setKeyword(String keyword) {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.syzb.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class ListAdvertQuery extends PageQuery {
|
||||
|
||||
@ApiModelProperty("产品类型:0投顾 1观点包 2单篇观点 3视频 5交易圈 6图文直播间 7组合 8锦囊 10H5")
|
||||
private Integer productType;
|
||||
|
||||
@ApiModelProperty("产品ID")
|
||||
private Integer productId;
|
||||
|
||||
@ApiModelProperty("名称 仅H5")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("位置 1:投顾首页 2:App首页 3:小程序首页")
|
||||
private Integer position;
|
||||
|
||||
@ApiModelProperty("创建者")
|
||||
private Integer createUserId;
|
||||
|
||||
public Integer getProductType() {
|
||||
return productType;
|
||||
}
|
||||
|
||||
public void setProductType(Integer productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
|
||||
public Integer getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(Integer productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(Integer position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Integer getCreateUserId() {
|
||||
return createUserId;
|
||||
}
|
||||
|
||||
public void setCreateUserId(Integer createUserId) {
|
||||
this.createUserId = createUserId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.diagnose.common.query;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class ListScheduleLogQuery {
|
||||
|
||||
private String serverName;
|
||||
|
||||
private String scheduleName;
|
||||
|
||||
@NotEmpty
|
||||
@NotNull
|
||||
private LocalDate date;
|
||||
|
||||
private Integer result;
|
||||
|
||||
@NotEmpty
|
||||
@NotNull
|
||||
private String token;
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
public String getScheduleName() {
|
||||
return scheduleName;
|
||||
}
|
||||
|
||||
public void setScheduleName(String scheduleName) {
|
||||
this.scheduleName = scheduleName;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public Integer getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Integer result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
}
|
||||
29
src/main/java/com/diagnose/common/query/OnlyIdPageQuery.java
Normal file
29
src/main/java/com/diagnose/common/query/OnlyIdPageQuery.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.diagnose.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class OnlyIdPageQuery extends PageQuery {
|
||||
|
||||
@ApiModelProperty("ID")
|
||||
@NotNull
|
||||
@Min(1)
|
||||
private Integer id;
|
||||
|
||||
public OnlyIdPageQuery() {
|
||||
}
|
||||
|
||||
public OnlyIdPageQuery(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
29
src/main/java/com/diagnose/common/query/OnlyIdQuery.java
Normal file
29
src/main/java/com/diagnose/common/query/OnlyIdQuery.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.diagnose.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class OnlyIdQuery {
|
||||
|
||||
@ApiModelProperty("ID")
|
||||
@NotNull
|
||||
@Min(1)
|
||||
private Integer id;
|
||||
|
||||
public OnlyIdQuery() {
|
||||
}
|
||||
|
||||
public OnlyIdQuery(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/diagnose/common/query/PageQuery.java
Normal file
40
src/main/java/com/diagnose/common/query/PageQuery.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.diagnose.common.query;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
|
||||
public class PageQuery {
|
||||
|
||||
@ApiModelProperty("当前页数")
|
||||
@Min(1)
|
||||
private Integer current = 1;
|
||||
|
||||
@ApiModelProperty("每页记录数")
|
||||
@Min(1)
|
||||
private Integer size = 10;
|
||||
|
||||
// public Page toPage() {
|
||||
// return new Page(this.getCurrent(), this.getSize());
|
||||
// }
|
||||
public <T> Page<T> toPage() {
|
||||
return new Page<>(this.getCurrent(), this.getSize());
|
||||
}
|
||||
|
||||
public Integer getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public void setCurrent(Integer current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public Integer getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Integer size) {
|
||||
this.size = size;
|
||||
}
|
||||
}
|
||||
114
src/main/java/com/diagnose/common/query/SaveAdvertQuery.java~
Normal file
114
src/main/java/com/diagnose/common/query/SaveAdvertQuery.java~
Normal file
@ -0,0 +1,114 @@
|
||||
package com.diagnose.common.query;
|
||||
|
||||
import com.syzb.common.constant.AdvertPosition;
|
||||
import com.syzb.common.entity.Advert;
|
||||
import com.syzb.common.validation.EnumValidator;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class SaveAdvertQuery implements IProduct {
|
||||
|
||||
@ApiModelProperty("位置 1:投顾首页 2:App首页 3:小程序首页")
|
||||
@NotNull
|
||||
@EnumValidator(AdvertPosition.class)
|
||||
private Integer position;
|
||||
|
||||
@ApiModelProperty("权重")
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(100)
|
||||
private Integer weight;
|
||||
|
||||
@ApiModelProperty("产品类型:0投顾 1观点包 2单篇观点 3视频 5交易圈 6图文直播间 7组合 8锦囊 10H5")
|
||||
@Min(0)
|
||||
private Integer productType;
|
||||
|
||||
@ApiModelProperty("产品ID")
|
||||
@Min(1)
|
||||
private Integer productId;
|
||||
|
||||
@ApiModelProperty("名称 仅H5类型")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("URL 仅H5类型")
|
||||
private String url;
|
||||
|
||||
@ApiModelProperty("图片URL")
|
||||
@NotBlank
|
||||
private String imgUrl;
|
||||
|
||||
public Advert toPO(Integer createUserId) {
|
||||
Advert advert = new Advert();
|
||||
advert.setPosition(this.position);
|
||||
advert.setWeight(this.weight);
|
||||
advert.setProductType(this.productType);
|
||||
advert.setProductId(this.productId);
|
||||
advert.setName(this.name);
|
||||
advert.setUrl(this.url);
|
||||
advert.setImgUrl(this.imgUrl);
|
||||
advert.setCreateUserId(createUserId);
|
||||
advert.setCreateTime(LocalDateTime.now());
|
||||
return advert;
|
||||
}
|
||||
|
||||
public Integer getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(Integer position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public Integer getProductType() {
|
||||
return productType;
|
||||
}
|
||||
|
||||
public void setProductType(Integer productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
|
||||
public Integer getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(Integer productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getImgUrl() {
|
||||
return imgUrl;
|
||||
}
|
||||
|
||||
public void setImgUrl(String imgUrl) {
|
||||
this.imgUrl = imgUrl;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.syzb.common.query;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class SetCommentTopQuery {
|
||||
|
||||
@ApiModelProperty("评论id")
|
||||
@NotNull
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("置顶: 1设置置顶 2取消置顶")
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(2)
|
||||
private Integer flag;
|
||||
|
||||
@ApiModelProperty("置顶权重")
|
||||
@NotNull
|
||||
@Min(0)
|
||||
@Max(1000)
|
||||
private Integer weight;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(Integer flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
41
src/main/java/com/diagnose/common/result/AppPager.java
Normal file
41
src/main/java/com/diagnose/common/result/AppPager.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.diagnose.common.result;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AppPager<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<T> list;
|
||||
|
||||
private boolean hasNext;
|
||||
|
||||
public static <T> AppPager<T> emptyPager() {
|
||||
return (AppPager<T>) EMPTY_PAGER;
|
||||
}
|
||||
|
||||
public static final AppPager EMPTY_PAGER = new AppPager<>(Collections.emptyList(), false);
|
||||
|
||||
public AppPager(List<T> list, boolean hasNext) {
|
||||
this.list = list;
|
||||
this.hasNext = hasNext;
|
||||
}
|
||||
|
||||
public List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public boolean isHasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
public void setHasNext(boolean hasNext) {
|
||||
this.hasNext = hasNext;
|
||||
}
|
||||
}
|
||||
87
src/main/java/com/diagnose/common/result/CommonResult.java
Normal file
87
src/main/java/com/diagnose/common/result/CommonResult.java
Normal file
@ -0,0 +1,87 @@
|
||||
package com.diagnose.common.result;
|
||||
|
||||
import com.diagnose.common.util.RequestIdUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class CommonResult<T> {
|
||||
|
||||
@ApiModelProperty(value = "状态码", name = "code")
|
||||
private Integer code;
|
||||
|
||||
@ApiModelProperty(value = "消息", name = "message")
|
||||
private String message;
|
||||
|
||||
@ApiModelProperty(value = "数据体", name = "data")
|
||||
private T data;
|
||||
|
||||
@ApiModelProperty(value = "请求id", name = "requestId")
|
||||
private String requestId;
|
||||
|
||||
public CommonResult(Integer code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
this.requestId = RequestIdUtil.getValue();
|
||||
}
|
||||
|
||||
public static CommonResult<Void> error(Integer code, String message) {
|
||||
return new CommonResult(code, message, null);
|
||||
}
|
||||
|
||||
public static CommonResult<Void> error(ResponseStatus responseStatus) {
|
||||
return new CommonResult(responseStatus.code, responseStatus.message, null);
|
||||
}
|
||||
|
||||
public static CommonResult<Void> success() {
|
||||
return CommonResult.success(null);
|
||||
}
|
||||
|
||||
public static <T> CommonResult<T> success(T data) {
|
||||
return new CommonResult(ResponseStatus.OK.code, ResponseStatus.OK.message, data);
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return ResponseStatus.OK.code.equals(this.code);
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
public void setRequestId(String requestId) {
|
||||
this.requestId = requestId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CommonResult{" +
|
||||
"code=" + code +
|
||||
", message='" + message + '\'' +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/diagnose/common/result/Pager.java
Normal file
49
src/main/java/com/diagnose/common/result/Pager.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.diagnose.common.result;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Pager<T> {
|
||||
|
||||
private List<T> list;
|
||||
|
||||
private long total;
|
||||
|
||||
public static <T> Pager<T> emptyPager() {
|
||||
return (Pager<T>) EMPTY_PAGER;
|
||||
}
|
||||
|
||||
public static final Pager EMPTY_PAGER = new Pager<>(Collections.emptyList(), 0);
|
||||
|
||||
public Pager(List<T> list, long total) {
|
||||
this.list = list;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Pager(Page<T> page) {
|
||||
this.list = page.getRecords();
|
||||
this.total = page.getTotal();
|
||||
}
|
||||
|
||||
public static Pager fromPage(Page page) {
|
||||
return new Pager(page);
|
||||
}
|
||||
|
||||
public List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
}
|
||||
59
src/main/java/com/diagnose/common/result/ResponseStatus.java
Normal file
59
src/main/java/com/diagnose/common/result/ResponseStatus.java
Normal file
@ -0,0 +1,59 @@
|
||||
package com.diagnose.common.result;
|
||||
|
||||
/**
|
||||
* 0: 成功
|
||||
* 1000——1999: 认证相关错误码
|
||||
* 2000——2999: 会话相关错误码
|
||||
* 3000——3999: 外部系统相关错误码
|
||||
* 4000——4999: 参数相关错误码
|
||||
* 5000——5999: 系统内部相关错误码
|
||||
* 6000——6999:业务相关错误码
|
||||
*/
|
||||
public enum ResponseStatus {
|
||||
/*********************成功*************************/
|
||||
OK(0, "OK"),
|
||||
|
||||
/*********************认证**************************/
|
||||
AUTH_FAIL(1000, "认证失败"),
|
||||
AUTH_FAIL_CAPTCHA(1001, "认证码错误"),
|
||||
PERMISSION_ERROR(1007, "权限不足"),
|
||||
DATA_PERMISSION_ERROR(1008, "数据权限不足"),
|
||||
PASSWORD_ERROR(1011, "密码错误"),
|
||||
|
||||
/*********************SESSIION********************/
|
||||
SESSION_EXPIRY(2000, "未登录,不允许操作"),
|
||||
SESSION_EXCEED(2001, "登录超时,请重新登录"),
|
||||
SESSION_PASSWORD_RESET(2002, "密码被重置,请重新登录"),
|
||||
PHONE_NOT_LOGIN(2003, "手机号未登录,不允许操作"),
|
||||
SESSION_USER_LOGOUT(2007, "账户已退出,请重新登陆"),
|
||||
|
||||
/*********************外部系统***********************/
|
||||
OUTSYS_ERROR(3000, "外部系统错误"),
|
||||
|
||||
/*********************入参系统***********************/
|
||||
PARM_ERROR(4000, "入参错误"),
|
||||
|
||||
/*********************内部系统***********************/
|
||||
SYS_BUSY(5000, "系统忙,请稍后重试"),
|
||||
|
||||
/*********************业务***********************/
|
||||
/**
|
||||
* 自定义响应信息
|
||||
*/
|
||||
STATUS_ERROR(6006, "操作状态不对,不允许操作"),
|
||||
;
|
||||
// 成员变量
|
||||
public final Integer code;
|
||||
public final String message;
|
||||
|
||||
ResponseStatus(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
//覆盖方法
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.code + "_" + this.message;
|
||||
}
|
||||
}
|
||||
317
src/main/java/com/diagnose/common/service/CacheService.java
Normal file
317
src/main/java/com/diagnose/common/service/CacheService.java
Normal file
@ -0,0 +1,317 @@
|
||||
package com.diagnose.common.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.diagnose.common.entity.ScheduleLog;
|
||||
import com.hazelcast.collection.ISet;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.crdt.pncounter.PNCounter;
|
||||
import com.hazelcast.instance.impl.HazelcastInstanceProxy;
|
||||
import com.hazelcast.map.IMap;
|
||||
import com.diagnose.common.config.cache.CacheKey;
|
||||
import com.diagnose.common.handler.BizException;
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.diagnose.common.config.cache.CacheKey.ONLY_KEY_OBJ;
|
||||
|
||||
@Component
|
||||
public class CacheService {
|
||||
|
||||
@Resource
|
||||
private ScheduleLogService scheduleLogService;
|
||||
|
||||
@Resource
|
||||
private HazelcastInstance hazelcastInstance;
|
||||
|
||||
private static final int UNLOCK_SLEEP_TIME = 5000;
|
||||
|
||||
private static final Set<String> loadedSet = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 从缓存加载数据,未找到则执行load回调
|
||||
*
|
||||
* @param mapName cacheMap的名字
|
||||
* @param key cacheKey
|
||||
* @param load 加载数据回调
|
||||
* @param <T> 数据类型
|
||||
* @return
|
||||
*/
|
||||
public <T> T get(String mapName, String key, Callable<T> load) {
|
||||
Map<String, Object> cacheMap = hazelcastInstance.getMap(mapName);
|
||||
return this.get(cacheMap, key, load);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存加载数据,未找到则执行load回调
|
||||
*
|
||||
* @param cacheMap cacheMap
|
||||
* @param key cacheKey
|
||||
* @param load 加载数据回调
|
||||
* @param <T> 数据类型
|
||||
* @return
|
||||
*/
|
||||
public <T> T get(Map<String, Object> cacheMap, String key, Callable<T> load) {
|
||||
Object obj = cacheMap.get(key);
|
||||
if (obj == null) {
|
||||
T result;
|
||||
try {
|
||||
result = load.call();
|
||||
} catch (BizException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (result == null) {
|
||||
// 防止缓存穿透
|
||||
cacheMap.put(key, ONLY_KEY_OBJ);
|
||||
return null;
|
||||
}
|
||||
cacheMap.put(key, result);
|
||||
return result;
|
||||
} else if (ONLY_KEY_OBJ.equals(obj)) {
|
||||
return null;
|
||||
}
|
||||
return (T) obj;
|
||||
}
|
||||
|
||||
public <T> ISet<T> getSet(String key, Callable<Set<T>> load) {
|
||||
ISet<T> iSet = hazelcastInstance.getSet(key);
|
||||
if (loadedSet.contains(key) || !iSet.isEmpty()) {
|
||||
loadedSet.add(key);
|
||||
return iSet;
|
||||
}
|
||||
simpleLock("task-getSet-" + key,
|
||||
0, TimeUnit.SECONDS,
|
||||
10, TimeUnit.SECONDS,
|
||||
() -> {
|
||||
try {
|
||||
Set<T> set = load.call();
|
||||
iSet.addAll(set);
|
||||
loadedSet.add(key);
|
||||
} catch (BizException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
return iSet;
|
||||
}
|
||||
|
||||
public <K, V> IMap<K, V> getMap(String key, Callable<Map<K, V>> load) {
|
||||
IMap<K, V> iMap = hazelcastInstance.getMap(key);
|
||||
if (loadedSet.contains(key) || !iMap.isEmpty()) {
|
||||
loadedSet.add(key);
|
||||
return iMap;
|
||||
}
|
||||
simpleLock("task-getMap-" + key,
|
||||
0, TimeUnit.SECONDS,
|
||||
10, TimeUnit.SECONDS,
|
||||
() -> {
|
||||
try {
|
||||
Map<K, V> map = load.call();
|
||||
iMap.clear();
|
||||
iMap.putAll(map);
|
||||
loadedSet.add(key);
|
||||
} catch (BizException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
return iMap;
|
||||
}
|
||||
|
||||
public Integer getLong(String key, Callable<Integer> load, int delta) {
|
||||
PNCounter counter = hazelcastInstance.getPNCounter(key);
|
||||
long v = counter.get();
|
||||
if (loadedSet.contains(key) || v != 0) {
|
||||
loadedSet.add(key);
|
||||
if (delta == 0) {
|
||||
return (int) v;
|
||||
}
|
||||
return (int) counter.addAndGet(delta);
|
||||
}
|
||||
simpleLock("task-getLong-" + key,
|
||||
0, TimeUnit.SECONDS,
|
||||
10, TimeUnit.SECONDS,
|
||||
() -> {
|
||||
try {
|
||||
int value = load.call();
|
||||
counter.reset();
|
||||
counter.addAndGet(value + delta);
|
||||
loadedSet.add(key);
|
||||
} catch (BizException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
return (int) counter.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果key不存在则执行load回调并返回执行结果,如果存在返回默认值(一般用于防止缓存穿透)
|
||||
*
|
||||
* @param cacheMap cacheMap
|
||||
* @param key cacheKey
|
||||
* @param load 回调方法
|
||||
* @param defaultValue 默认值
|
||||
* @param <T> 数据类型
|
||||
* @return
|
||||
*/
|
||||
public <T> T runNx(Map<String, Object> cacheMap, String key, Callable<T> load, T defaultValue) {
|
||||
Object obj = cacheMap.get(key);
|
||||
if (obj == null) {
|
||||
T result;
|
||||
try {
|
||||
result = load.call();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 防止缓存穿透
|
||||
cacheMap.put(key, ONLY_KEY_OBJ);
|
||||
return result;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多线程锁
|
||||
*
|
||||
* @param taskName 任务名字
|
||||
* @param time 加锁时间值
|
||||
* @param timeunit 加锁时间类型
|
||||
* @param leaseTime 自动释放时间值
|
||||
* @param leaseTimeunit 自动释放时间类型
|
||||
* @param fn 加锁成功后执行的方法
|
||||
* @param <T> 类型
|
||||
*/
|
||||
public <T> void lock(String taskName,
|
||||
long time, @Nullable TimeUnit timeunit,
|
||||
long leaseTime, @Nullable TimeUnit leaseTimeunit,
|
||||
Callable<T> fn) {
|
||||
try {
|
||||
IMap<String, Integer> map = hazelcastInstance.getMap(CacheKey.DISTRIBUTED_LOCK);
|
||||
boolean lock = map.tryLock(taskName, time, timeunit, leaseTime, leaseTimeunit);
|
||||
if (lock) {
|
||||
String host = ((HazelcastInstanceProxy) hazelcastInstance).getOriginal().getLocalEndpoint().getAddress().getHost();
|
||||
Integer logId = null;
|
||||
long runTime = 0;
|
||||
try {
|
||||
logId = scheduleLogService.save(ScheduleLog.start(taskName, host));
|
||||
long startTime = System.currentTimeMillis();
|
||||
LoggerUtil.data.info(taskName + "-开始");
|
||||
T result = fn.call();
|
||||
runTime = System.currentTimeMillis() - startTime;
|
||||
String resultJSON = JSONObject.toJSONString(result);
|
||||
LoggerUtil.data.info(taskName + "-结束:" + runTime, resultJSON);
|
||||
scheduleLogService.save(ScheduleLog.success(logId, result == null ? null : resultJSON));
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error.error(taskName + "-异常:" + ExceptionUtils.getStackTrace(e));
|
||||
scheduleLogService.save(ScheduleLog.error(logId, ExceptionUtils.getStackTrace(e)));
|
||||
} finally {
|
||||
if (runTime >= UNLOCK_SLEEP_TIME) {
|
||||
map.forceUnlock(taskName);
|
||||
} else if (lock) {
|
||||
TimeUnit.MILLISECONDS.sleep(UNLOCK_SLEEP_TIME - runTime);
|
||||
if (map.isLocked(taskName)) {
|
||||
map.unlock(taskName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error.error(taskName + "-异常:" + ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多线程锁
|
||||
*
|
||||
* @param taskName 任务名字
|
||||
* @param time 加锁时间值
|
||||
* @param timeunit 加锁时间类型
|
||||
* @param leaseTime 自动释放时间值
|
||||
* @param leaseTimeunit 自动释放时间类型
|
||||
* @param fn 加锁成功后执行的方法
|
||||
*/
|
||||
public void lock(String taskName,
|
||||
long time, @Nullable TimeUnit timeunit,
|
||||
long leaseTime, @Nullable TimeUnit leaseTimeunit,
|
||||
Runnable fn) {
|
||||
try {
|
||||
IMap<String, Integer> map = hazelcastInstance.getMap(CacheKey.DISTRIBUTED_LOCK);
|
||||
long runTime = 0;
|
||||
boolean lock = map.tryLock(taskName, time, timeunit, leaseTime, leaseTimeunit);
|
||||
if (lock) {
|
||||
String host = ((HazelcastInstanceProxy) hazelcastInstance).getOriginal().getLocalEndpoint().getAddress().getHost();
|
||||
Integer logId = null;
|
||||
try {
|
||||
logId = scheduleLogService.save(ScheduleLog.start(taskName, host));
|
||||
long startTime = System.currentTimeMillis();
|
||||
LoggerUtil.data.info(taskName + "-开始");
|
||||
fn.run();
|
||||
runTime = System.currentTimeMillis() - startTime;
|
||||
LoggerUtil.data.info(taskName + "-结束:" + runTime);
|
||||
scheduleLogService.save(ScheduleLog.success(logId, null));
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error.error(taskName + "-异常:" + ExceptionUtils.getStackTrace(e));
|
||||
scheduleLogService.save(ScheduleLog.error(logId, ExceptionUtils.getStackTrace(e)));
|
||||
} finally {
|
||||
if (runTime >= UNLOCK_SLEEP_TIME) {
|
||||
map.forceUnlock(taskName);
|
||||
} else if (lock) {
|
||||
TimeUnit.MILLISECONDS.sleep(UNLOCK_SLEEP_TIME - runTime);
|
||||
if (map.isLocked(taskName)) {
|
||||
map.unlock(taskName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error.error(taskName + "-异常:" + ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
|
||||
public void simpleLock(String key, long time, @Nullable TimeUnit timeunit, long leaseTime, @Nullable TimeUnit leaseTimeunit, Runnable fn) {
|
||||
IMap<String, Integer> map = hazelcastInstance.getMap(CacheKey.DISTRIBUTED_LOCK);
|
||||
boolean lock = false;
|
||||
try {
|
||||
lock = map.tryLock(key, time, timeunit, leaseTime, leaseTimeunit);
|
||||
if (lock) {
|
||||
fn.run();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (lock && map.isLocked(key)) {
|
||||
map.unlock(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getLong(String cacheKey, int delta) {
|
||||
PNCounter counter = hazelcastInstance.getPNCounter(cacheKey);
|
||||
return (int) counter.addAndGet(delta);
|
||||
}
|
||||
|
||||
public void clearCache(String mapName, List<String> cacheKeys) {
|
||||
Map<String, Object> cacheMap = hazelcastInstance.getMap(mapName);
|
||||
cacheKeys.forEach(cacheMap::remove);
|
||||
}
|
||||
|
||||
public void clearCache(String mapName, String cacheKey) {
|
||||
Map<String, Object> cacheMap = hazelcastInstance.getMap(mapName);
|
||||
cacheMap.remove(cacheKey);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,285 @@
|
||||
package com.diagnose.common.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Table;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.map.IMap;
|
||||
import com.syzb.common.constant.CommentBlackScope;
|
||||
import com.syzb.common.constant.CommentBlackStatus;
|
||||
import com.syzb.common.constant.CommentBlackType;
|
||||
import com.syzb.common.entity.CommentBlack;
|
||||
import com.syzb.common.handler.BizException;
|
||||
import com.syzb.common.mapper.CommentBlackMapper;
|
||||
import com.syzb.common.query.AddCommentBlackQuery;
|
||||
import com.syzb.common.query.BaseProductQuery;
|
||||
import com.syzb.common.query.CommentBlackQuery;
|
||||
import com.syzb.common.query.RemoveCommentBlackQuery;
|
||||
import com.syzb.common.result.Pager;
|
||||
import com.syzb.common.result.ResponseStatus;
|
||||
import com.syzb.common.util.logger.LoggerUtil;
|
||||
import com.syzb.common.vo.BackendUserVO;
|
||||
import com.syzb.common.vo.CommentBlackVO;
|
||||
import com.syzb.common.vo.MergeProductInfoVO;
|
||||
import com.syzb.rbac.entity.Dept;
|
||||
import com.syzb.rbac.entity.UserDept;
|
||||
import com.syzb.rbac.service.DeptService;
|
||||
import com.syzb.rbac.service.UserService;
|
||||
import com.syzb.rbac.service.WxUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.syzb.common.config.cache.CacheKey.COMMENT_BLACK;
|
||||
import static com.syzb.common.config.cache.CacheKey.CommentBlackKey.ALL_BLACK_COMMENT;
|
||||
import static com.syzb.common.config.cache.CacheKey.CommentBlackKey.ALL_BLACK_USER;
|
||||
|
||||
@Service
|
||||
public class CommentBlackService {
|
||||
|
||||
@Resource
|
||||
private CommentBlackMapper commentBlackMapper;
|
||||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Resource
|
||||
private MergeProductService mergeProductService;
|
||||
|
||||
@Resource
|
||||
private HazelcastInstance hazelcastInstance;
|
||||
|
||||
@Resource
|
||||
private CacheService cacheService;
|
||||
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
|
||||
@Resource
|
||||
private WxUserService wxUserService;
|
||||
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer addCommentBlack(BackendUserVO backendUserVO, AddCommentBlackQuery query) {
|
||||
String userPhone = query.getUserPhone();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
//禁言开始时间-1s
|
||||
now = now.minusSeconds(1L);
|
||||
QueryWrapper<CommentBlack> wrapper = Wrappers.query();
|
||||
wrapper.eq("phone", userPhone)
|
||||
.in("status", Arrays.asList(CommentBlackStatus.EFFECT.value, CommentBlackStatus.EXPIRED.value))
|
||||
.lt("start_time", now)
|
||||
.ge("end_time", now);
|
||||
long validSize = commentBlackMapper.selectCount(wrapper);
|
||||
if (validSize > 0) {
|
||||
throw new BizException(ResponseStatus.REPETITIVE_ERROR);
|
||||
}
|
||||
CommentBlack commentBlack = query.toPO();
|
||||
commentBlack.setStartTime(now);
|
||||
commentBlack.setStatus(CommentBlackStatus.EFFECT.value);
|
||||
commentBlack.setOperatorId(backendUserVO.getUserId());
|
||||
commentBlack.setUpdateTime(now);
|
||||
commentBlack.setAdvisorId(backendUserVO.getAdvisorId());
|
||||
if (CommentBlackType.DAY.value.equals(commentBlack.getType())) {
|
||||
commentBlack.setEndTime(now.plusDays(1));
|
||||
} else if (CommentBlackType.MONTH.value.equals(commentBlack.getType())) {
|
||||
commentBlack.setEndTime(now.plusMonths(1));
|
||||
} else {
|
||||
commentBlack.setEndTime(now.plusYears(100));
|
||||
}
|
||||
int count = commentBlackMapper.insert(commentBlack);
|
||||
if (count < 1) {
|
||||
throw new BizException(ResponseStatus.DB_SAVE_ERROR);
|
||||
}
|
||||
this.clearCache(ALL_BLACK_USER, ALL_BLACK_COMMENT);
|
||||
return commentBlack.getId();
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void removeCommentBlack(BackendUserVO backendUserVO, RemoveCommentBlackQuery query) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
QueryWrapper<CommentBlack> wrapper = Wrappers.query();
|
||||
wrapper.eq("phone", query.getUserPhone())
|
||||
.eq("product_id", query.getProductId())
|
||||
.eq("product_type", query.getProductType())
|
||||
.in("status", Arrays.asList(CommentBlackStatus.EFFECT.value, CommentBlackStatus.EXPIRED.value))
|
||||
.lt("start_time", now)
|
||||
.ge("end_time", now);
|
||||
List<CommentBlack> commentBlackList = commentBlackMapper.selectList(wrapper);
|
||||
if (CollectionUtils.isEmpty(commentBlackList)) {
|
||||
throw new BizException(ResponseStatus.REMOVE_BLACK_USER_ERROR);
|
||||
}
|
||||
for (CommentBlack commentBlack : commentBlackList) {
|
||||
CommentBlack updateObj = new CommentBlack();
|
||||
updateObj.setId(commentBlack.getId());
|
||||
updateObj.setStatus(CommentBlackStatus.REMOVED.value);
|
||||
updateObj.setUpdateTime(now);
|
||||
updateObj.setEndTime(now);
|
||||
int count = commentBlackMapper.updateById(updateObj);
|
||||
if (count < 1) {
|
||||
throw new BizException(ResponseStatus.DB_SAVE_ERROR);
|
||||
}
|
||||
}
|
||||
this.clearCache(ALL_BLACK_USER, ALL_BLACK_COMMENT);
|
||||
}
|
||||
|
||||
public Pager<CommentBlackVO> queryCommentBlackList(BackendUserVO backendUserVO, CommentBlackQuery query) {
|
||||
LocalDateTime startTime = null;
|
||||
LocalDateTime endTime = null;
|
||||
LocalDateTime startOpTime = null;
|
||||
LocalDateTime endOpTime = null;
|
||||
if (StrUtil.isNotEmpty(query.getStartTime())) {
|
||||
startTime = LocalDateTime.parse(query.getStartTime(), formatter);
|
||||
}
|
||||
if (StrUtil.isNotEmpty(query.getEndTime())) {
|
||||
endTime = LocalDateTime.parse(query.getEndTime(), formatter);
|
||||
}
|
||||
if (StrUtil.isNotEmpty(query.getStartOpTime())) {
|
||||
startOpTime = LocalDateTime.parse(query.getStartOpTime(), formatter);
|
||||
}
|
||||
if (StrUtil.isNotEmpty(query.getEndOpTime())) {
|
||||
endOpTime = LocalDateTime.parse(query.getEndOpTime(), formatter);
|
||||
}
|
||||
QueryWrapper<CommentBlack> wrapper = Wrappers.query();
|
||||
wrapper.like(StrUtil.isNotEmpty(query.getUserName()), "user_name", query.getUserName())
|
||||
.eq(StrUtil.isNotEmpty(query.getPhone()), "phone", query.getPhone())
|
||||
.eq(query.getStatus() != null, "status", query.getStatus())
|
||||
.eq(query.getType() != null, "type", query.getType())
|
||||
.eq(query.getProductType() != null, "product_type", query.getProductType())
|
||||
.eq(query.getProductType() != null && query.getProductId() != null, "product_id", query.getProductId())
|
||||
.like(StrUtil.isNotBlank(query.getContent()), "content", query.getContent())
|
||||
.like(StrUtil.isNotEmpty(query.getReason()), "reason", query.getReason())
|
||||
.eq(query.getOperatorId() != null, "operator_id", query.getOperatorId())
|
||||
.ge(startTime != null, "start_time", startTime)
|
||||
.lt(endTime != null, "start_time", endTime)
|
||||
.ge(startOpTime != null, "end_time", startOpTime)
|
||||
.lt(endOpTime != null, "end_time", endOpTime);
|
||||
wrapper.orderByDesc("start_time");
|
||||
Page<CommentBlack> page = commentBlackMapper.selectPage(query.toPage(), wrapper);
|
||||
List<CommentBlack> list = page.getRecords();
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return Pager.emptyPager();
|
||||
}
|
||||
List<BaseProductQuery> baseProductQueryList = list.stream().map(commentBlack -> {
|
||||
if (commentBlack.getProductId() != null && commentBlack.getProductType() != null) {
|
||||
return new BaseProductQuery(commentBlack.getProductId(), commentBlack.getProductType());
|
||||
}
|
||||
return null;
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
Table<Integer, Integer, MergeProductInfoVO> productTable = mergeProductService.queryMergeProductInfo(baseProductQueryList);
|
||||
Map<Integer, UserDept> userMap = userService.getUserMap();
|
||||
Map<String, Dept> deptMap = deptService.getDeptMap();
|
||||
List<CommentBlackVO> voList = list.stream().map(CommentBlackVO::new).collect(Collectors.toList());
|
||||
for (CommentBlackVO commentBlackVO : voList) {
|
||||
// 查询产品信息
|
||||
if (commentBlackVO.getProductId() != null && commentBlackVO.getProductType() != null) {
|
||||
MergeProductInfoVO mergeProductInfoVO = productTable.get(commentBlackVO.getProductType(), commentBlackVO.getProductId());
|
||||
if (mergeProductInfoVO != null) {
|
||||
commentBlackVO.setProductName(mergeProductInfoVO.getProductName());
|
||||
}
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (CommentBlackStatus.EFFECT.value.equals(commentBlackVO.getStatus()) && now.isAfter(commentBlackVO.getEndTime())) {
|
||||
commentBlackVO.setStatus(CommentBlackStatus.EXPIRED.value);
|
||||
}
|
||||
UserDept user = userMap.get(commentBlackVO.getOperatorId());
|
||||
if (user != null) {
|
||||
commentBlackVO.setOperatorName(user.getName());
|
||||
}
|
||||
if (StrUtil.isNotEmpty(commentBlackVO.getUserOrgNo())) {
|
||||
Dept dept = deptMap.get(commentBlackVO.getUserOrgNo());
|
||||
if (dept != null) {
|
||||
commentBlackVO.setUserOrgName(dept.getName());
|
||||
}
|
||||
}
|
||||
commentBlackVO.setUserHeadPic(wxUserService.getHeadPic(commentBlackVO.getPhone()));
|
||||
}
|
||||
return new Pager<>(voList, page.getTotal());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否禁言
|
||||
*/
|
||||
public boolean checkIsBlack(String phone, Integer productId, Integer productType) {
|
||||
// 判断是否禁言用户
|
||||
Set<String> blackUsers = getAllBlackUser();
|
||||
if (!blackUsers.contains(phone)) {
|
||||
return false;
|
||||
}
|
||||
List<CommentBlack> blackComments = getAllBlackComment();
|
||||
if (CollectionUtils.isEmpty(blackComments)) {
|
||||
return false;
|
||||
}
|
||||
for (CommentBlack commentBlack : blackComments) {
|
||||
if (commentBlack.getPhone().equals(phone)) {
|
||||
if (CommentBlackScope.PRODUCT.value.equals(commentBlack.getScope())) {
|
||||
if (commentBlack.getProductId().equals(productId) && commentBlack.getProductType().equals(productType)) {
|
||||
return true;
|
||||
}
|
||||
} else if (CommentBlackScope.PRODUCT_TYPE.value.equals(commentBlack.getScope())) {
|
||||
if (commentBlack.getProductType().equals(productType)) {
|
||||
return true;
|
||||
}
|
||||
} else if (CommentBlackScope.GLOBAL.value.equals(commentBlack.getScope())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Set<String> getAllBlackUser() {
|
||||
return cacheService.get(COMMENT_BLACK, ALL_BLACK_USER, () ->
|
||||
getAllBlackComment().stream().map(CommentBlack::getPhone).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
private List<CommentBlack> getAllBlackComment() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
return cacheService.get(COMMENT_BLACK, ALL_BLACK_COMMENT, () -> {
|
||||
QueryWrapper<CommentBlack> wrapper = Wrappers.<CommentBlack>query()
|
||||
.in("status", Arrays.asList(CommentBlackStatus.EFFECT.value, CommentBlackStatus.EXPIRED.value))
|
||||
.lt("start_time", now)
|
||||
.gt("end_time", now);
|
||||
List<CommentBlack> commentBlackList = commentBlackMapper.selectList(wrapper);
|
||||
LoggerUtil.info("db当前黑名单用户:" + JSONObject.toJSONString(commentBlackList));
|
||||
return commentBlackList;
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> getBlackUserIds(Integer productId, Integer productType) {
|
||||
Set<String> blackUsers = new HashSet<>();
|
||||
List<CommentBlack> blackComments = getAllBlackComment();
|
||||
for (CommentBlack commentBlack : blackComments) {
|
||||
if (CommentBlackScope.PRODUCT.value.equals(commentBlack.getScope())) {
|
||||
if (commentBlack.getProductId().equals(productId) && commentBlack.getProductType().equals(productType)) {
|
||||
blackUsers.add(commentBlack.getPhone());
|
||||
}
|
||||
} else if (CommentBlackScope.PRODUCT_TYPE.value.equals(commentBlack.getScope())) {
|
||||
if (commentBlack.getProductType().equals(productType)) {
|
||||
blackUsers.add(commentBlack.getPhone());
|
||||
}
|
||||
} else if (CommentBlackScope.GLOBAL.value.equals(commentBlack.getScope())) {
|
||||
blackUsers.add(commentBlack.getPhone());
|
||||
}
|
||||
}
|
||||
return blackUsers;
|
||||
}
|
||||
|
||||
private void clearCache(String... cacheKeys) {
|
||||
IMap<String, Object> cacheMap = hazelcastInstance.getMap(COMMENT_BLACK);
|
||||
for (String key : cacheKeys) {
|
||||
cacheMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package com.diagnose.common.service;
|
||||
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Table;
|
||||
import com.syzb.advisor.entity.AdvisorBasic;
|
||||
import com.syzb.advisor.service.AdvisorInfoService;
|
||||
import com.syzb.advisor.vo.AdvisorInfoAppVO;
|
||||
import com.syzb.common.constant.ProductType;
|
||||
import com.syzb.common.query.IProduct;
|
||||
import com.syzb.common.util.CollectUtil;
|
||||
import com.syzb.common.vo.MergeProductInfoVO;
|
||||
import com.syzb.course.query.IdAndSaleUserQuery;
|
||||
import com.syzb.course.service.ShortVideoService;
|
||||
import com.syzb.course.vo.ShortVideoVO;
|
||||
import com.syzb.video.service.app.AppVideoColumnService;
|
||||
import com.syzb.video.service.app.AppVideoInfoService;
|
||||
import com.syzb.video.vo.column.VideoColumnAppVO;
|
||||
import com.syzb.video.vo.info.VideoInfoAppVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MergeProductService {
|
||||
|
||||
@Resource
|
||||
private AdvisorInfoService advisorInfoService;
|
||||
|
||||
@Resource
|
||||
private AppVideoInfoService appVideoInfoService;
|
||||
|
||||
@Resource
|
||||
private AppVideoColumnService appVideoColumnService;
|
||||
|
||||
@Resource
|
||||
private ShortVideoService shortVideoService;
|
||||
|
||||
public Table<Integer, Integer, MergeProductInfoVO> queryMergeProductInfo(List<? extends IProduct> productQueryList) {
|
||||
Table<Integer, Integer, MergeProductInfoVO> voTable = HashBasedTable.create();
|
||||
Table<Integer, Integer, Object> objTable = this.queryMergeProductInfo(productQueryList, false);
|
||||
objTable.cellSet().forEach(cell -> voTable.put(cell.getRowKey(), cell.getColumnKey(), (MergeProductInfoVO) cell.getValue()));
|
||||
return voTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询产品信息
|
||||
*
|
||||
* @param productQueryList
|
||||
* @return productType、productId、MergeProductInfoVO
|
||||
*/
|
||||
public Table<Integer, Integer, Object> queryMergeProductInfo(List<? extends IProduct> productQueryList, boolean returnDetail) {
|
||||
Table<Integer, Integer, Object> table = HashBasedTable.create();
|
||||
if (CollectionUtils.isEmpty(productQueryList)) {
|
||||
return table;
|
||||
}
|
||||
// 去重
|
||||
productQueryList = productQueryList.stream().filter(product -> product.getProductType() != null && product.getProductId() != null).filter(CollectUtil.distinctByKey(product -> product.getProductType() + ":" + product.getProductId())).collect(Collectors.toList());
|
||||
Map<Integer, AdvisorBasic> advisorBasicMap = advisorInfoService.getAdvisorMap();
|
||||
productQueryList.forEach(product -> {
|
||||
// 查询产品信息,投顾信息,团队信息
|
||||
if (ProductType.ADVISOR_INFO.value.equals(product.getProductType())) {
|
||||
AdvisorInfoAppVO advisorInfoVO = advisorInfoService.getForApp(product.getProductId(), null);
|
||||
if (advisorInfoVO != null) {
|
||||
Object value = returnDetail ? advisorInfoVO : new MergeProductInfoVO(product.getProductId(), advisorInfoVO.getShowName(), advisorInfoVO.getProfile(), advisorInfoVO.getStatus(), null, advisorInfoVO.getCreateTime(), advisorInfoVO.getPublishTime(), advisorBasicMap.get(product.getProductId()), ProductType.ADVISOR_INFO.value, null, null, null);
|
||||
table.put(product.getProductType(), product.getProductId(), value);
|
||||
}
|
||||
} else if (ProductType.VIDEO_SINGLE.value.equals(product.getProductType())) {
|
||||
VideoInfoAppVO videoInfoVO = appVideoInfoService.getVideoInfo(product.getProductId(), null);
|
||||
if (videoInfoVO != null) {
|
||||
Object value;
|
||||
if (returnDetail) {
|
||||
value = videoInfoVO;
|
||||
} else {
|
||||
MergeProductInfoVO vo = new MergeProductInfoVO(product.getProductId(), videoInfoVO.getTitle(), videoInfoVO.getViewPoint(),
|
||||
videoInfoVO.getStatus(), videoInfoVO.getRiskLevel(), videoInfoVO.getCreateTime(), videoInfoVO.getAuditTime(), advisorBasicMap.get(videoInfoVO.getAdvisorId()),
|
||||
ProductType.VIDEO_SINGLE.value, null, null, null
|
||||
);
|
||||
vo.setVideoPlayType(videoInfoVO.getPlayType());
|
||||
value = vo;
|
||||
}
|
||||
table.put(product.getProductType(), product.getProductId(), value);
|
||||
}
|
||||
} else if (ProductType.VIDEO_COLUMN.value.equals(product.getProductType())) {
|
||||
VideoColumnAppVO columnVO = appVideoColumnService.getColumnDetail(product.getProductId(), null);
|
||||
if (columnVO != null) {
|
||||
Object value;
|
||||
if (returnDetail) {
|
||||
value = columnVO;
|
||||
} else {
|
||||
value = new MergeProductInfoVO(product.getProductId(), columnVO.getName(), columnVO.getIntroduce(),
|
||||
columnVO.getStatus(), null, null, null, null,
|
||||
ProductType.VIDEO_COLUMN.value, null, null, null
|
||||
);
|
||||
}
|
||||
table.put(product.getProductType(), product.getProductId(), value);
|
||||
}
|
||||
} else if (ProductType.SHORT_VIDEO.value.equals(product.getProductType())) {
|
||||
ShortVideoVO shortVideoVO = shortVideoService.getForApp(new IdAndSaleUserQuery(product.getProductId()), null, false);
|
||||
Object value = returnDetail ? shortVideoVO : new MergeProductInfoVO(product.getProductId(), shortVideoVO.getTitle(), shortVideoVO.getViewPoint(),
|
||||
shortVideoVO.getStatus(), shortVideoVO.getRiskLevel(), shortVideoVO.getCreateTime(), shortVideoVO.getAuditTime(), advisorBasicMap.get(shortVideoVO.getAdvisorId()),
|
||||
ProductType.SHORT_VIDEO.value, null, null, null);
|
||||
table.put(product.getProductType(), product.getProductId(), value);
|
||||
}
|
||||
});
|
||||
return table;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.diagnose.common.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.diagnose.common.entity.ScheduleLog;
|
||||
import com.diagnose.common.handler.BizException;
|
||||
import com.diagnose.common.mapper.ScheduleLogMapper;
|
||||
import com.diagnose.common.query.ListScheduleLogQuery;
|
||||
import com.diagnose.common.result.ResponseStatus;
|
||||
import com.diagnose.common.util.CodecUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ScheduleLogService {
|
||||
|
||||
private static final String salt = "UP_OEM_SCHEDULE_LOG";
|
||||
|
||||
@Resource
|
||||
private ScheduleLogMapper scheduleLogMapper;
|
||||
|
||||
public List<ScheduleLog> list(ListScheduleLogQuery query) {
|
||||
checkToken(query);
|
||||
String serverName = query.getServerName();
|
||||
String scheduleName = query.getScheduleName();
|
||||
LocalDate date = query.getDate();
|
||||
Integer result = query.getResult();
|
||||
QueryWrapper<ScheduleLog> wrapper = Wrappers.query();
|
||||
wrapper.eq(StrUtil.isNotEmpty(serverName), "server_name", serverName)
|
||||
.eq(StrUtil.isNotEmpty(scheduleName), "schedule_name", scheduleName)
|
||||
.eq(date != null, "date", date)
|
||||
.eq(result != null && result != 0, "result", result);
|
||||
return scheduleLogMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Integer save(ScheduleLog log) {
|
||||
if (log.getId() == null) {
|
||||
scheduleLogMapper.insert(log);
|
||||
} else {
|
||||
scheduleLogMapper.updateById(log);
|
||||
}
|
||||
return log.getId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void clearHistory(int saveDays) {
|
||||
LocalDate saveDate = LocalDate.now().minusDays(saveDays);
|
||||
QueryWrapper<ScheduleLog> wrapper = Wrappers.query();
|
||||
wrapper.lt("date", saveDate);
|
||||
scheduleLogMapper.delete(wrapper);
|
||||
}
|
||||
|
||||
private void checkToken(ListScheduleLogQuery query) {
|
||||
String token = query.getToken();
|
||||
LocalDate date = query.getDate();
|
||||
String dateStr = date.format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
String hash = CodecUtil.md5(dateStr + salt);
|
||||
if (!hash.equals(token)) {
|
||||
throw new BizException(ResponseStatus.AUTH_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
58
src/main/java/com/diagnose/common/util/CodecUtil.java
Normal file
58
src/main/java/com/diagnose/common/util/CodecUtil.java
Normal file
@ -0,0 +1,58 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class CodecUtil {
|
||||
|
||||
public static String md5(String src) {
|
||||
return new BigInteger(1, DigestUtils.md5Digest(src.getBytes(Charsets.UTF_8))).toString(16);
|
||||
}
|
||||
|
||||
public static String md5(byte[] src) {
|
||||
return new BigInteger(1, DigestUtils.md5Digest(src)).toString(16);
|
||||
}
|
||||
|
||||
private static byte[] byteMerger(byte[] byte1, byte[] byte2) {
|
||||
byte[] byte3 = new byte[byte1.length + byte2.length];
|
||||
System.arraycopy(byte1, 0, byte3, 0, byte1.length);
|
||||
System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
|
||||
return byte3;
|
||||
}
|
||||
|
||||
public static String sha1(String key, String str) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), mac.getAlgorithm());
|
||||
mac.init(secretKeySpec);
|
||||
|
||||
byte[] hash = mac.doFinal(str.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] sigBuf = byteMerger(hash, str.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(sigBuf);
|
||||
}
|
||||
|
||||
public static String mobileEncrypt(String mobile) {
|
||||
if (StrUtil.isEmpty(mobile) || (mobile.length() != 11)) {
|
||||
return "";
|
||||
}
|
||||
return mobile.replaceAll("(\\w{3})\\w*(\\w{4})", "$1****$2");
|
||||
}
|
||||
|
||||
// 带盐值的MD5加密
|
||||
public static String md5WithSalt(String key, String salt) {
|
||||
return md5(key + salt);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String sign = md5WithSalt("video_demo", "1615860427");
|
||||
System.out.println(sign);
|
||||
}
|
||||
}
|
||||
15
src/main/java/com/diagnose/common/util/CollectUtil.java
Normal file
15
src/main/java/com/diagnose/common/util/CollectUtil.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class CollectUtil {
|
||||
|
||||
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
|
||||
Map<Object, Boolean> seen = new HashMap<>();
|
||||
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
|
||||
}
|
||||
|
||||
}
|
||||
48
src/main/java/com/diagnose/common/util/Debounce.java
Normal file
48
src/main/java/com/diagnose/common/util/Debounce.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Debounce {
|
||||
|
||||
// 线程池用于调度任务
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
|
||||
// 保存当前的调度任务
|
||||
private ScheduledFuture<?> future;
|
||||
|
||||
// 防抖函数
|
||||
public void debounce(Runnable task, long delayInMillis) {
|
||||
// 如果之前有未执行的任务,取消它
|
||||
if (future != null && !future.isDone()) {
|
||||
future.cancel(false);
|
||||
}
|
||||
|
||||
// 调度新的任务
|
||||
future = scheduler.schedule(task, delayInMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
// 用于关闭线程池
|
||||
public void shutdown() {
|
||||
scheduler.shutdown();
|
||||
}
|
||||
|
||||
// public static void main(String[] args) throws InterruptedException {
|
||||
// Debounce debounce = new Debounce();
|
||||
//
|
||||
// // 模拟多次快速调用
|
||||
// for (int i = 1; i <= 5; i++) {
|
||||
// int j = i;
|
||||
// // 应该只答应最后一次任务的序号
|
||||
// debounce.debounce(() -> System.out.println("Task executed!" + j), 500);
|
||||
// Thread.sleep(100); // 每100毫秒触发一次
|
||||
// }
|
||||
//
|
||||
// // 给出足够时间执行最后一次任务
|
||||
// Thread.sleep(1100);
|
||||
//
|
||||
// debounce.shutdown();
|
||||
// }
|
||||
}
|
||||
28
src/main/java/com/diagnose/common/util/HideUtils.java
Normal file
28
src/main/java/com/diagnose/common/util/HideUtils.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
public class HideUtils {
|
||||
|
||||
public static String hidePhoneNo(String phoneNo) {
|
||||
if (StrUtil.isBlank(phoneNo)) {
|
||||
return phoneNo;
|
||||
}
|
||||
if (phoneNo.length() >= 7) {
|
||||
//前三后四
|
||||
return phoneNo.substring(0, 3) + "****" +
|
||||
phoneNo.substring(phoneNo.length() - 4);
|
||||
} else {
|
||||
return phoneNo;
|
||||
}
|
||||
}
|
||||
|
||||
public static String maskLastName(String name) {
|
||||
if (StrUtil.isBlank(name)) {
|
||||
return null;
|
||||
}
|
||||
int length = name.length();
|
||||
return name.substring(0, length - 1) + "*";
|
||||
}
|
||||
|
||||
}
|
||||
39
src/main/java/com/diagnose/common/util/IPUtil.java
Normal file
39
src/main/java/com/diagnose/common/util/IPUtil.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Component
|
||||
public class IPUtil {
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
if ("0:0:0:0:0:0:0:1".equals(ip)) {
|
||||
ip = "127.0.0.1";
|
||||
}
|
||||
if (ip.split(",").length > 1) {
|
||||
ip = ip.split(",")[0];
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
||||
41
src/main/java/com/diagnose/common/util/RequestIdUtil.java
Normal file
41
src/main/java/com/diagnose/common/util/RequestIdUtil.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class RequestIdUtil {
|
||||
|
||||
public static void setValue(String str) {
|
||||
String requestId = RandomUtil.randomString(6);
|
||||
MDC.put("requestId", str + "-" + requestId);
|
||||
}
|
||||
|
||||
public static void setValue() {
|
||||
String requestId = RandomUtil.randomString(6);
|
||||
MDC.put("requestId", requestId);
|
||||
}
|
||||
|
||||
public static String getValue() {
|
||||
String requestId = MDC.get("requestId");
|
||||
return StrUtil.isNotEmpty(requestId) ? requestId : "";
|
||||
}
|
||||
|
||||
public static void removeValue() {
|
||||
MDC.remove("requestId");
|
||||
}
|
||||
|
||||
public static void setTime() {
|
||||
MDC.put("requestTime", String.valueOf(new Date().getTime()));
|
||||
}
|
||||
|
||||
public static long getTime() {
|
||||
return Long.parseLong(MDC.get("requestTime"));
|
||||
}
|
||||
|
||||
public static void removeTime() {
|
||||
MDC.remove("requestTime");
|
||||
}
|
||||
}
|
||||
41
src/main/java/com/diagnose/common/util/RequestIdUtil.java~
Normal file
41
src/main/java/com/diagnose/common/util/RequestIdUtil.java~
Normal file
@ -0,0 +1,41 @@
|
||||
package com.syzb.common.util;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class RequestIdUtil {
|
||||
|
||||
public static void setValue(String str) {
|
||||
String requestId = RandomUtil.randomString(6);
|
||||
MDC.put("requestId", str + "-" + requestId);
|
||||
}
|
||||
|
||||
public static void setValue() {
|
||||
String requestId = RandomUtil.randomString(6);
|
||||
MDC.put("requestId", requestId);
|
||||
}
|
||||
|
||||
public static String getValue() {
|
||||
String requestId = MDC.get("requestId");
|
||||
return StrUtil.isNotEmpty(requestId) ? requestId : "";
|
||||
}
|
||||
|
||||
public static void removeValue() {
|
||||
MDC.remove("requestId");
|
||||
}
|
||||
|
||||
public static void setTime() {
|
||||
MDC.put("requestTime", String.valueOf(new Date().getTime()));
|
||||
}
|
||||
|
||||
public static long getTime() {
|
||||
return Long.parseLong(MDC.get("requestTime"));
|
||||
}
|
||||
|
||||
public static void removeTime() {
|
||||
MDC.remove("requestTime");
|
||||
}
|
||||
}
|
||||
145
src/main/java/com/diagnose/common/util/RsaUtil.java
Normal file
145
src/main/java/com/diagnose/common/util/RsaUtil.java
Normal file
@ -0,0 +1,145 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class RsaUtil {
|
||||
|
||||
/**
|
||||
* RSA最大加密大小
|
||||
*/
|
||||
private final static int MAX_ENCRYPT_BLOCK = 117;
|
||||
|
||||
/**
|
||||
* **
|
||||
* RSA最大解密大小
|
||||
*/
|
||||
private final static int MAX_DECRYPT_BLOCK = 128;
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param pubKey 公钥字符串
|
||||
* @param str 需要加密操作的字符串
|
||||
* @return 结果再Base64加密后的字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String pubKeyEncryption(String pubKey, String str) {
|
||||
try {
|
||||
// String 转 公钥
|
||||
PublicKey rsaPublicKey = getPublicKey(pubKey);
|
||||
//公钥加密
|
||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
byte[] inputArray = str.getBytes();
|
||||
int inputLength = inputArray.length;
|
||||
// 分段加密
|
||||
int offSet = 0;
|
||||
byte[] resultBytes = {};
|
||||
byte[] cache;
|
||||
while (inputLength - offSet > 0) {
|
||||
if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
|
||||
offSet += MAX_ENCRYPT_BLOCK;
|
||||
} else {
|
||||
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
|
||||
offSet = inputLength;
|
||||
}
|
||||
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
|
||||
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
|
||||
}
|
||||
return Base64.encode(resultBytes);
|
||||
} catch (Exception exception) {
|
||||
LoggerUtil.info("RsaUtil.pubKeyEncryption异常:" + ExceptionUtils.getStackTrace(exception));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用私钥 解密
|
||||
*
|
||||
* @param priKey 私钥字符串
|
||||
* @param encryptionBase64Str RSA加密后又base64编码后的字符串
|
||||
* @return 解密结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String priKeyDecryption(String priKey, String encryptionBase64Str) {
|
||||
try {
|
||||
// base64 解码
|
||||
byte[] base64 = Base64.decode(encryptionBase64Str);
|
||||
// String 转 私钥
|
||||
PrivateKey rsaPrivateKey = getPrivateKey(priKey);
|
||||
//私钥解密
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
// 返回UTF-8编码的解密信息
|
||||
int inputLen = base64.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(base64, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(base64, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
out.close();
|
||||
return out.toString(StandardCharsets.UTF_8);
|
||||
} catch (Exception exception) {
|
||||
LoggerUtil.info("RsaUtil.priKeyDecryption异常:" + ExceptionUtils.getStackTrace(exception));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String转公钥PublicKey
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static PublicKey getPublicKey(String key) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(key);
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
return keyFactory.generatePublic(keySpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* String转私钥PrivateKey
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static PrivateKey getPrivateKey(String key) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(key);
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
return keyFactory.generatePrivate(keySpec);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.codec.Base62;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.HashUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
public class ShortUrlGenerator {
|
||||
|
||||
public static String generateShortUrl(String url) {
|
||||
int hash = HashUtil.bkdrHash(url);
|
||||
byte[] hashBytes = Convert.intToBytes(hash);
|
||||
byte[] randomBytes = RandomUtil.randomBytes(1);
|
||||
return Base62.encode(ArrayUtil.addAll(hashBytes, randomBytes));
|
||||
}
|
||||
|
||||
}
|
||||
28
src/main/java/com/diagnose/common/util/TextUtil.java
Normal file
28
src/main/java/com/diagnose/common/util/TextUtil.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.safety.Whitelist;
|
||||
|
||||
public class TextUtil {
|
||||
|
||||
public static String removeHtmlTags(String text) {
|
||||
text = Jsoup.parse(text).text();
|
||||
return text.replaceAll("\\s*|\t|\r|\n| ", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理富文本中的XSS攻击内容
|
||||
*
|
||||
* @param unsafeHtml 富文本内容
|
||||
* @return 清洗后的文本内容
|
||||
*/
|
||||
public static String cleanUnsafeHtml(String unsafeHtml) {
|
||||
if (StrUtil.isEmpty(unsafeHtml)) {
|
||||
return unsafeHtml;
|
||||
}
|
||||
Whitelist whitelist = Whitelist.relaxed();
|
||||
return Jsoup.clean(unsafeHtml, whitelist);
|
||||
}
|
||||
|
||||
}
|
||||
142
src/main/java/com/diagnose/common/util/UpDes.java
Normal file
142
src/main/java/com/diagnose/common/util/UpDes.java
Normal file
@ -0,0 +1,142 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Key;
|
||||
import java.util.Base64;
|
||||
|
||||
public class UpDes {
|
||||
|
||||
private static final byte[] DEFAULT_IV = {0x75, 0x70, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x31};
|
||||
|
||||
private Key mKey;
|
||||
|
||||
public UpDes() {
|
||||
}
|
||||
|
||||
public UpDes(String strKey) {
|
||||
setKey(strKey); // 生成密匙
|
||||
}
|
||||
|
||||
public Key getKey() {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数生成 KEY
|
||||
*/
|
||||
public void setKey(String strKey) {
|
||||
try {
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||
DESKeySpec keySpec = new DESKeySpec(strKey.getBytes());
|
||||
keyFactory.generateSecret(keySpec);
|
||||
mKey = keyFactory.generateSecret(keySpec);
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("UpDes.setKey:" + ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密 String 明文输入 ,String 密文输出
|
||||
*/
|
||||
public String encryptStr(String strMing) {
|
||||
return encryptStr(strMing, DEFAULT_IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密 String 明文输入 ,String 密文输出
|
||||
*/
|
||||
public String encryptStr(String strMing, byte[] biv) {
|
||||
byte[] byteMi;
|
||||
byte[] byteMing;
|
||||
String strMi = "";
|
||||
try {
|
||||
byteMing = strMing.getBytes();
|
||||
byteMi = this.encryptByte(byteMing, biv);
|
||||
strMi = Base64.getEncoder().encodeToString(byteMi);
|
||||
} catch (Throwable t) {
|
||||
LoggerUtil.error("UpDes.encryptStr:" + ExceptionUtils.getStackTrace(t));
|
||||
}
|
||||
return strMi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密以 byte[] 明文输入 ,byte[] 密文输出
|
||||
*
|
||||
* @param byteS byteS
|
||||
* @return byte
|
||||
*/
|
||||
private byte[] encryptByte(byte[] byteS, byte[] biv) {
|
||||
byte[] byteFina = null;
|
||||
Cipher cipher;
|
||||
try {
|
||||
IvParameterSpec iv = new IvParameterSpec(biv);
|
||||
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, mKey, iv);
|
||||
byteFina = cipher.doFinal(byteS);
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("UpDes.encryptByte:" + ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
return byteFina;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密 以 String 密文输入 ,String 明文输出
|
||||
*
|
||||
* @param strMi strMi
|
||||
* @return String
|
||||
*/
|
||||
public String decryptStr(String strMi) {
|
||||
return decryptStr(strMi, DEFAULT_IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密 以 String 密文输入 ,String 明文输出
|
||||
*
|
||||
* @param strMi strMi
|
||||
* @param biv biv
|
||||
* @return String
|
||||
*/
|
||||
public String decryptStr(String strMi, byte[] biv) {
|
||||
byte[] byteMing;
|
||||
byte[] byteMi;
|
||||
String strMing = "";
|
||||
try {
|
||||
byteMi = Base64.getDecoder().decode(strMi);
|
||||
byteMing = this.decryptByte(byteMi, biv);
|
||||
strMing = new String(byteMing, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("UpDes.decryptStr:" + ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
return strMing;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密以 byte[] 密文输入 , 以 byte[] 明文输出
|
||||
*
|
||||
* @param byteD byteD
|
||||
* @param biv biv
|
||||
* @return byte
|
||||
*/
|
||||
private byte[] decryptByte(byte[] byteD, byte[] biv) {
|
||||
Cipher cipher;
|
||||
byte[] byteFina = null;
|
||||
try {
|
||||
|
||||
IvParameterSpec iv = new IvParameterSpec(biv);
|
||||
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, mKey, iv);
|
||||
byteFina = cipher.doFinal(byteD);
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("UpDes.decryptByte:" + ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
return byteFina;
|
||||
}
|
||||
|
||||
}
|
||||
32
src/main/java/com/diagnose/common/util/WebServerInfo.java
Normal file
32
src/main/java/com/diagnose/common/util/WebServerInfo.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.diagnose.common.util;
|
||||
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import com.diagnose.common.util.logger.LoggerUtil;
|
||||
import org.springframework.boot.web.context.WebServerApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@Component
|
||||
public class WebServerInfo {
|
||||
|
||||
@Resource
|
||||
private WebServerApplicationContext webServerApplicationContext;
|
||||
|
||||
public String getServerIp() {
|
||||
// 获取本地的 IP 地址,Spring Boot 默认会绑定到 0.0.0.0(所有网络接口)
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getLocalHost();
|
||||
return inetAddress.getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
LoggerUtil.error(ExceptionUtil.stacktraceToString(e));
|
||||
}
|
||||
return "0.0.0.0";
|
||||
}
|
||||
|
||||
public int getServerPort() {
|
||||
return webServerApplicationContext.getWebServer().getPort();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.diagnose.common.util.logger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LoggerAgent {
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
private LoggerAgent(String name) {
|
||||
logger = LoggerFactory.getLogger(name);
|
||||
}
|
||||
|
||||
public static LoggerAgent build(String name) {
|
||||
return new LoggerAgent(name);
|
||||
}
|
||||
|
||||
public void info(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
public void info(Object... message) {
|
||||
logger.info(Arrays.stream(message).filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining( )));
|
||||
}
|
||||
|
||||
public void error(String message) {
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
public void error(Object... message) {
|
||||
logger.error(Arrays.stream(message).filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining( )));
|
||||
}
|
||||
|
||||
public void warn(String message) {
|
||||
logger.warn(message);
|
||||
}
|
||||
|
||||
public void warn(Object... message) {
|
||||
logger.warn(Arrays.stream(message).filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining( )));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.diagnose.common.util.logger;
|
||||
|
||||
public class LoggerUtil {
|
||||
|
||||
public static final LoggerAgent video = LoggerAgent.build("video");
|
||||
|
||||
public static final LoggerAgent data = LoggerAgent.build("data");
|
||||
|
||||
public static final LoggerAgent error = LoggerAgent.build("error");
|
||||
|
||||
public static final LoggerAgent websocket = LoggerAgent.build("websocket");
|
||||
|
||||
public static final LoggerAgent auth = LoggerAgent.build("auth");
|
||||
|
||||
public static final LoggerAgent api = LoggerAgent.build("api");
|
||||
|
||||
public static void info(String message) {
|
||||
data.info(message);
|
||||
}
|
||||
|
||||
public static void info(Object... message) {
|
||||
data.info(message);
|
||||
}
|
||||
|
||||
public static void error(String message) {
|
||||
error.error(message);
|
||||
}
|
||||
|
||||
public static void error(Object... message) {
|
||||
error.error(message);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.diagnose.common.validation;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Documented
|
||||
@Constraint(validatedBy = EnumChecker.class)
|
||||
@Target({METHOD, FIELD, ANNOTATION_TYPE, PARAMETER, CONSTRUCTOR})
|
||||
@Retention(RUNTIME)
|
||||
public @interface EnumValidator {
|
||||
|
||||
String message() default "不符合枚举值定义";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
Class<? extends Enum<?>> value();
|
||||
|
||||
}
|
||||
|
||||
class EnumChecker implements ConstraintValidator<EnumValidator, Integer> {
|
||||
|
||||
private Set<Integer> AVAILABLE_ENUM_VALUES;
|
||||
|
||||
public static Set<Integer> getValuesSet(Class<? extends Enum<?>> enumClass, Field valueField) throws IllegalAccessException {
|
||||
Enum<?>[] enums = enumClass.getEnumConstants();
|
||||
Set<Integer> valuesSet = Sets.newHashSetWithExpectedSize(enums.length);
|
||||
for (Enum<?> e : enums) {
|
||||
Object valueObj = valueField.get(e);
|
||||
valuesSet.add((Integer) valueObj);
|
||||
}
|
||||
return valuesSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(EnumValidator validator) {
|
||||
try {
|
||||
Class<? extends Enum<?>> enumClass = validator.value();
|
||||
Field valueField = enumClass.getField("value");
|
||||
AVAILABLE_ENUM_VALUES = getValuesSet(enumClass, valueField);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (value == null) {
|
||||
return true;
|
||||
} else {
|
||||
return AVAILABLE_ENUM_VALUES.contains(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.diagnose.common.validation;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Documented
|
||||
@Constraint(validatedBy = IntArrayChecker.class)
|
||||
@Target({METHOD, FIELD, ANNOTATION_TYPE, PARAMETER, CONSTRUCTOR})
|
||||
@Retention(RUNTIME)
|
||||
public @interface IntArrayValidator {
|
||||
|
||||
String message() default "不符合取值范围";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
int[] value();
|
||||
|
||||
}
|
||||
|
||||
class IntArrayChecker implements ConstraintValidator<IntArrayValidator, Integer> {
|
||||
|
||||
private Set<Integer> AVAILABLE_VALUES;
|
||||
|
||||
@Override
|
||||
public void initialize(IntArrayValidator validator) {
|
||||
int[] values = validator.value();
|
||||
Set<Integer> valuesSet = Sets.newHashSetWithExpectedSize(values.length);
|
||||
for (int value : values) {
|
||||
valuesSet.add(value);
|
||||
}
|
||||
AVAILABLE_VALUES = valuesSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (value == null) {
|
||||
return true;
|
||||
} else {
|
||||
return AVAILABLE_VALUES.contains(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
73
src/main/java/com/diagnose/common/vo/AdvertAppVO.java~
Normal file
73
src/main/java/com/diagnose/common/vo/AdvertAppVO.java~
Normal file
@ -0,0 +1,73 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import com.diagnose.common.entity.Advert;
|
||||
import com.diagnose.common.query.IProduct;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class AdvertAppVO implements IProduct, Serializable {
|
||||
|
||||
@ApiModelProperty("产品类型:0投顾 1观点包 2单篇观点 3视频 5交易圈 6图文直播间 7组合 8锦囊 10H5")
|
||||
private Integer productType;
|
||||
|
||||
@ApiModelProperty("产品ID")
|
||||
private Integer productId;
|
||||
|
||||
@ApiModelProperty("名称 仅H5类型")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("URL 仅H5类型")
|
||||
private String url;
|
||||
|
||||
@ApiModelProperty("图片URL")
|
||||
private String imgUrl;
|
||||
|
||||
public AdvertAppVO(Advert advert) {
|
||||
this.productType = advert.getProductType();
|
||||
this.productId = advert.getProductId();
|
||||
this.name = advert.getName();
|
||||
this.url = advert.getUrl();
|
||||
this.imgUrl = advert.getImgUrl();
|
||||
}
|
||||
|
||||
public Integer getProductType() {
|
||||
return productType;
|
||||
}
|
||||
|
||||
public void setProductType(Integer productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
|
||||
public Integer getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(Integer productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getImgUrl() {
|
||||
return imgUrl;
|
||||
}
|
||||
|
||||
public void setImgUrl(String imgUrl) {
|
||||
this.imgUrl = imgUrl;
|
||||
}
|
||||
}
|
||||
108
src/main/java/com/diagnose/common/vo/AppCUserInfoVO.java~
Normal file
108
src/main/java/com/diagnose/common/vo/AppCUserInfoVO.java~
Normal file
@ -0,0 +1,108 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import com.syzb.business.vo.BusinessUserVO;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class AppCUserInfoVO {
|
||||
|
||||
@ApiModelProperty("用户id")
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty("用户名")
|
||||
private String userName;
|
||||
|
||||
@ApiModelProperty("昵称")
|
||||
private String nickName;
|
||||
|
||||
@ApiModelProperty("用户头像")
|
||||
private String imgUrl;
|
||||
|
||||
@ApiModelProperty("客户类型 1:H5 2:Web")
|
||||
private Integer clientType;
|
||||
|
||||
@ApiModelProperty("token")
|
||||
private String token;
|
||||
|
||||
@ApiModelProperty("refreshToken")
|
||||
private String refreshToken;
|
||||
|
||||
@ApiModelProperty("upToken")
|
||||
private String upToken;
|
||||
|
||||
public AppCUserInfoVO() {
|
||||
}
|
||||
|
||||
public AppCUserInfoVO(String token, String refreshToken, BusinessUserVO userVO, Integer clientType) {
|
||||
this.userId = userVO.getUserId().toString();
|
||||
this.userName = userVO.getUsername();
|
||||
this.nickName = userVO.getNickName();
|
||||
this.imgUrl = userVO.getHeadPicUrl();
|
||||
this.clientType = clientType;
|
||||
this.token = token;
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public String getImgUrl() {
|
||||
return imgUrl;
|
||||
}
|
||||
|
||||
public void setImgUrl(String imgUrl) {
|
||||
this.imgUrl = imgUrl;
|
||||
}
|
||||
|
||||
public Integer getClientType() {
|
||||
return clientType;
|
||||
}
|
||||
|
||||
public void setClientType(Integer clientType) {
|
||||
this.clientType = clientType;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public String getUpToken() {
|
||||
return upToken;
|
||||
}
|
||||
|
||||
public void setUpToken(String upToken) {
|
||||
this.upToken = upToken;
|
||||
}
|
||||
}
|
||||
81
src/main/java/com/diagnose/common/vo/AppUserInfoVO.java~
Normal file
81
src/main/java/com/diagnose/common/vo/AppUserInfoVO.java~
Normal file
@ -0,0 +1,81 @@
|
||||
package com.syzb.common.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class AppUserInfoVO {
|
||||
|
||||
@ApiModelProperty("用户姓名")
|
||||
private String userName;
|
||||
|
||||
@ApiModelProperty("客户风险等级,1保守型2谨慎型3稳健型4积极型5激进型-1最低风险类型")
|
||||
private String corpRiskLevel;
|
||||
|
||||
@ApiModelProperty("客户风险测评日,YYYYMMDD")
|
||||
private String corpBeginDate;
|
||||
|
||||
@ApiModelProperty("客户风险到期日,YYYYMMDD")
|
||||
private String corpEndDate;
|
||||
|
||||
@ApiModelProperty("营业部编号")
|
||||
private String branchNo;
|
||||
|
||||
@ApiModelProperty("机构标志:0个人 1机构 2自营 3产品 4特法户 5产品(机构端)6机构(机构端)")
|
||||
public String organFlag;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public AppUserInfoVO(String userName, String corpRiskLevel, String corpBeginDate, String corpEndDate, String branchNo, String organFlag) {
|
||||
this.userName = userName;
|
||||
this.corpRiskLevel = corpRiskLevel;
|
||||
this.corpBeginDate = corpBeginDate;
|
||||
this.corpEndDate = corpEndDate;
|
||||
this.branchNo = branchNo;
|
||||
this.organFlag = organFlag;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getCorpRiskLevel() {
|
||||
return corpRiskLevel;
|
||||
}
|
||||
|
||||
public void setCorpRiskLevel(String corpRiskLevel) {
|
||||
this.corpRiskLevel = corpRiskLevel;
|
||||
}
|
||||
|
||||
public String getCorpBeginDate() {
|
||||
return corpBeginDate;
|
||||
}
|
||||
|
||||
public void setCorpBeginDate(String corpBeginDate) {
|
||||
this.corpBeginDate = corpBeginDate;
|
||||
}
|
||||
|
||||
public String getCorpEndDate() {
|
||||
return corpEndDate;
|
||||
}
|
||||
|
||||
public void setCorpEndDate(String corpEndDate) {
|
||||
this.corpEndDate = corpEndDate;
|
||||
}
|
||||
|
||||
public String getBranchNo() {
|
||||
return branchNo;
|
||||
}
|
||||
|
||||
public void setBranchNo(String branchNo) {
|
||||
this.branchNo = branchNo;
|
||||
}
|
||||
|
||||
public String getOrganFlag() {
|
||||
return organFlag;
|
||||
}
|
||||
|
||||
public void setOrganFlag(String organFlag) {
|
||||
this.organFlag = organFlag;
|
||||
}
|
||||
}
|
||||
68
src/main/java/com/diagnose/common/vo/AuthVO.java~
Normal file
68
src/main/java/com/diagnose/common/vo/AuthVO.java~
Normal file
@ -0,0 +1,68 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import com.syzb.advisor.vo.AdvisorInfoAdminVO;
|
||||
import com.syzb.rbac.entity.UserLogin;
|
||||
import com.syzb.rbac.vo.UserAdminVO;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AuthVO {
|
||||
|
||||
@ApiModelProperty("用户信息")
|
||||
private UserAdminVO user;
|
||||
|
||||
@ApiModelProperty("投顾信息")
|
||||
private AdvisorInfoAdminVO advisorInfo;
|
||||
|
||||
@ApiModelProperty("角色权限名列表")
|
||||
private List<String> roles;
|
||||
|
||||
@ApiModelProperty("token")
|
||||
private String token;
|
||||
|
||||
public AuthVO(UserLogin user, String token) {
|
||||
this.user = new UserAdminVO(user);
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public AuthVO(UserAdminVO user, AdvisorInfoAdminVO advisorInfo, List<String> roles, String token) {
|
||||
this.user = user;
|
||||
this.advisorInfo = advisorInfo;
|
||||
this.roles = roles;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public UserAdminVO getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserAdminVO user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public AdvisorInfoAdminVO getAdvisorInfo() {
|
||||
return advisorInfo;
|
||||
}
|
||||
|
||||
public void setAdvisorInfo(AdvisorInfoAdminVO advisorInfo) {
|
||||
this.advisorInfo = advisorInfo;
|
||||
}
|
||||
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(List<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/com/diagnose/common/vo/CountVO.java
Normal file
21
src/main/java/com/diagnose/common/vo/CountVO.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class CountVO {
|
||||
|
||||
@ApiModelProperty("执行动作后的数量")
|
||||
private Integer count;
|
||||
|
||||
public Integer getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public CountVO(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
24
src/main/java/com/diagnose/common/vo/IdCountVO.java
Normal file
24
src/main/java/com/diagnose/common/vo/IdCountVO.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
public class IdCountVO {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private Integer count;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
34
src/main/java/com/diagnose/common/vo/IdNameVO.java
Normal file
34
src/main/java/com/diagnose/common/vo/IdNameVO.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class IdNameVO implements Serializable {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
public IdNameVO() {
|
||||
}
|
||||
|
||||
public IdNameVO(Integer id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
21
src/main/java/com/diagnose/common/vo/InsertIdVO.java
Normal file
21
src/main/java/com/diagnose/common/vo/InsertIdVO.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class InsertIdVO {
|
||||
|
||||
@ApiModelProperty("ID")
|
||||
private Integer id;
|
||||
|
||||
public InsertIdVO(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/diagnose/common/vo/OnlyBoolVO.java
Normal file
25
src/main/java/com/diagnose/common/vo/OnlyBoolVO.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class OnlyBoolVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("ID")
|
||||
private Boolean result;
|
||||
|
||||
public OnlyBoolVO(Boolean result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Boolean getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Boolean result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/diagnose/common/vo/OnlyIdVO.java
Normal file
25
src/main/java/com/diagnose/common/vo/OnlyIdVO.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class OnlyIdVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("ID")
|
||||
private Integer id;
|
||||
|
||||
public OnlyIdVO(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
153
src/main/java/com/diagnose/common/vo/SafetyConfigVO.java~
Normal file
153
src/main/java/com/diagnose/common/vo/SafetyConfigVO.java~
Normal file
@ -0,0 +1,153 @@
|
||||
package com.syzb.common.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SafetyConfigVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("密码有效天数")
|
||||
private Integer passwordPeriod;
|
||||
|
||||
@ApiModelProperty("密码组成:1大写字母 2小写字母 3数字 4特殊字母,逗号隔开")
|
||||
private String passwordComposition;
|
||||
|
||||
@ApiModelProperty("密码组成正则表达式")
|
||||
private String regexPattern;
|
||||
|
||||
@ApiModelProperty("密码到期前多少天提醒用户")
|
||||
private Integer expirationReminder;
|
||||
|
||||
@ApiModelProperty("密码最大长度")
|
||||
private Integer passwordMax;
|
||||
|
||||
@ApiModelProperty("密码最小长度")
|
||||
private Integer passwordMin;
|
||||
|
||||
@ApiModelProperty("密码不能与前多少次旧密码相同")
|
||||
private Integer passwordSame;
|
||||
|
||||
@ApiModelProperty("登录多少分钟后未操作,强制离线")
|
||||
private Integer maxLeftTime;
|
||||
|
||||
@ApiModelProperty("登录失败多少次会被锁定")
|
||||
private Integer errorCount;
|
||||
|
||||
@ApiModelProperty("登录失败N次后,锁定的时间,分钟")
|
||||
private Integer lockTime;
|
||||
|
||||
@ApiModelProperty("中台登录是否开启短信验证:0未开启 1已开启")
|
||||
private Integer checkMessage;
|
||||
|
||||
@ApiModelProperty("短信开启后,用户白名单")
|
||||
private String messageWhite;
|
||||
|
||||
@ApiModelProperty("短信有效期多长时间,分钟")
|
||||
private Integer messageValidTime;
|
||||
|
||||
public Integer getPasswordPeriod() {
|
||||
return passwordPeriod;
|
||||
}
|
||||
|
||||
public void setPasswordPeriod(Integer passwordPeriod) {
|
||||
this.passwordPeriod = passwordPeriod;
|
||||
}
|
||||
|
||||
public String getPasswordComposition() {
|
||||
return passwordComposition;
|
||||
}
|
||||
|
||||
public void setPasswordComposition(String passwordComposition) {
|
||||
this.passwordComposition = passwordComposition;
|
||||
}
|
||||
|
||||
public Integer getExpirationReminder() {
|
||||
return expirationReminder;
|
||||
}
|
||||
|
||||
public void setExpirationReminder(Integer expirationReminder) {
|
||||
this.expirationReminder = expirationReminder;
|
||||
}
|
||||
|
||||
public Integer getPasswordMax() {
|
||||
return passwordMax;
|
||||
}
|
||||
|
||||
public void setPasswordMax(Integer passwordMax) {
|
||||
this.passwordMax = passwordMax;
|
||||
}
|
||||
|
||||
public Integer getPasswordMin() {
|
||||
return passwordMin;
|
||||
}
|
||||
|
||||
public void setPasswordMin(Integer passwordMin) {
|
||||
this.passwordMin = passwordMin;
|
||||
}
|
||||
|
||||
public Integer getPasswordSame() {
|
||||
return passwordSame;
|
||||
}
|
||||
|
||||
public void setPasswordSame(Integer passwordSame) {
|
||||
this.passwordSame = passwordSame;
|
||||
}
|
||||
|
||||
public Integer getMaxLeftTime() {
|
||||
return maxLeftTime;
|
||||
}
|
||||
|
||||
public void setMaxLeftTime(Integer maxLeftTime) {
|
||||
this.maxLeftTime = maxLeftTime;
|
||||
}
|
||||
|
||||
public Integer getErrorCount() {
|
||||
return errorCount;
|
||||
}
|
||||
|
||||
public void setErrorCount(Integer errorCount) {
|
||||
this.errorCount = errorCount;
|
||||
}
|
||||
|
||||
public Integer getLockTime() {
|
||||
return lockTime;
|
||||
}
|
||||
|
||||
public void setLockTime(Integer lockTime) {
|
||||
this.lockTime = lockTime;
|
||||
}
|
||||
|
||||
public Integer getCheckMessage() {
|
||||
return checkMessage;
|
||||
}
|
||||
|
||||
public void setCheckMessage(Integer checkMessage) {
|
||||
this.checkMessage = checkMessage;
|
||||
}
|
||||
|
||||
public String getMessageWhite() {
|
||||
return messageWhite;
|
||||
}
|
||||
|
||||
public void setMessageWhite(String messageWhite) {
|
||||
this.messageWhite = messageWhite;
|
||||
}
|
||||
|
||||
public Integer getMessageValidTime() {
|
||||
return messageValidTime;
|
||||
}
|
||||
|
||||
public void setMessageValidTime(Integer messageValidTime) {
|
||||
this.messageValidTime = messageValidTime;
|
||||
}
|
||||
|
||||
public String getRegexPattern() {
|
||||
return regexPattern;
|
||||
}
|
||||
|
||||
public void setRegexPattern(String regexPattern) {
|
||||
this.regexPattern = regexPattern;
|
||||
}
|
||||
}
|
||||
48
src/main/java/com/diagnose/common/vo/SensitiveWordVO.java~
Normal file
48
src/main/java/com/diagnose/common/vo/SensitiveWordVO.java~
Normal file
@ -0,0 +1,48 @@
|
||||
package com.diagnose.common.vo;
|
||||
|
||||
import com.diagnose.common.entity.SensitiveWord;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class SensitiveWordVO {
|
||||
|
||||
@ApiModelProperty("ID")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("内容")
|
||||
private String word;
|
||||
|
||||
@ApiModelProperty("添加时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
public SensitiveWordVO(SensitiveWord sensitive) {
|
||||
setId(sensitive.getId());
|
||||
setWord(sensitive.getWord());
|
||||
setCreateTime(sensitive.getCreateTime());
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
public void setWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(LocalDateTime createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
}
|
||||
19
src/main/java/com/diagnose/constant/MktNum.java
Normal file
19
src/main/java/com/diagnose/constant/MktNum.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.diagnose.constant;
|
||||
|
||||
// 股票所属市场 0:深圳 1:上海 7:北京
|
||||
public enum MktNum {
|
||||
|
||||
SZ(0, "深圳"),
|
||||
SH(1, "上海"),
|
||||
BJ(7, "北京"),
|
||||
;
|
||||
|
||||
public final Integer value;
|
||||
public final String name;
|
||||
|
||||
MktNum(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/com/diagnose/constant/MktTypePar.java
Normal file
19
src/main/java/com/diagnose/constant/MktTypePar.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.diagnose.constant;
|
||||
|
||||
// 证券市场 1:深圳证券交易所 2:上海证券交易所 190:北京证券交易所
|
||||
public enum MktTypePar {
|
||||
|
||||
SZ(1, "深圳"),
|
||||
SH(2, "上海"),
|
||||
BJ(190, "北京"),
|
||||
;
|
||||
|
||||
public final Integer value;
|
||||
public final String name;
|
||||
|
||||
MktTypePar(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
41
src/main/java/com/diagnose/constant/RiskLevel.java~
Normal file
41
src/main/java/com/diagnose/constant/RiskLevel.java~
Normal file
@ -0,0 +1,41 @@
|
||||
package com.syzb.common.constant;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum RiskLevel {
|
||||
|
||||
LOW_RISK(1, "低风险"),
|
||||
LOW_MIDDLE_RISK(2, "中低风险"),
|
||||
MIDDLE_RISK(3, "中风险"),
|
||||
MIDDLE_HIGH_RISK(4, "中高风险"),
|
||||
HIGH_RISK(5, "高风险"),
|
||||
;
|
||||
public final Integer value;
|
||||
|
||||
public final String name;
|
||||
|
||||
RiskLevel(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取风险等级描述
|
||||
*
|
||||
* @param riskLevel 风险等级code
|
||||
* @return 风险等级描述
|
||||
*/
|
||||
public static String parseName(Integer riskLevel) {
|
||||
return Arrays.stream(RiskLevel.values())
|
||||
.filter(s -> s.value.equals(riskLevel)).findFirst()
|
||||
.map(logicType -> logicType.name).orElse(null);
|
||||
}
|
||||
}
|
||||
19
src/main/java/com/diagnose/constant/SecMarPar.java
Normal file
19
src/main/java/com/diagnose/constant/SecMarPar.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.diagnose.constant;
|
||||
|
||||
// 股票市场 1:深圳 2:上海 8:北京
|
||||
public enum SecMarPar {
|
||||
|
||||
SZ(1, "深圳"),
|
||||
SH(2, "上海"),
|
||||
BJ(8, "北京"),
|
||||
;
|
||||
|
||||
public final Integer value;
|
||||
public final String name;
|
||||
|
||||
SecMarPar(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.diagnose.controller;
|
||||
|
||||
import com.diagnose.common.result.CommonResult;
|
||||
import com.diagnose.service.SearchService;
|
||||
import com.diagnose.service.StockService;
|
||||
import com.diagnose.vo.ComprehensiveEvaluationVO;
|
||||
import com.diagnose.vo.FinancialValuationVO;
|
||||
import com.diagnose.vo.StockVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "投顾")
|
||||
@RestController
|
||||
public class DiagnoseController {
|
||||
|
||||
@Resource
|
||||
private SearchService searchService;
|
||||
|
||||
@Resource
|
||||
private StockService stockService;
|
||||
|
||||
@ApiOperation("综合搜索")
|
||||
@GetMapping("/diagnose/search")
|
||||
public CommonResult<List<StockVO>> search(@RequestParam("关键词") @Validated @NotBlank @ApiParam(required = true) String keyword) {
|
||||
List<StockVO> list = searchService.search(keyword);
|
||||
return CommonResult.success(list);
|
||||
}
|
||||
|
||||
@ApiOperation("综合评分")
|
||||
@GetMapping("/diagnose/comprehensiveEvaluation")
|
||||
public CommonResult<ComprehensiveEvaluationVO> comprehensiveEvaluation(@RequestParam("证券统一编码") @Validated @NotNull @ApiParam(required = true) Long stkUniCode) {
|
||||
ComprehensiveEvaluationVO vo = stockService.comprehensiveEvaluation(stkUniCode);
|
||||
return CommonResult.success(vo);
|
||||
}
|
||||
|
||||
@ApiOperation("财务估值")
|
||||
@GetMapping("/diagnose/financialValuation")
|
||||
public CommonResult<FinancialValuationVO> financialValuation(@RequestParam("证券统一编码") @Validated @NotNull @ApiParam(required = true) Long stkUniCode) {
|
||||
FinancialValuationVO vo = stockService.financialValuation(stkUniCode);
|
||||
return CommonResult.success(vo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
92
src/main/java/com/diagnose/entity/CommentSortEntity.java~
Normal file
92
src/main/java/com/diagnose/entity/CommentSortEntity.java~
Normal file
@ -0,0 +1,92 @@
|
||||
package com.syzb.common.entity;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class CommentSortEntity implements Serializable, Comparable<CommentSortEntity> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("评论id")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("评论时间")
|
||||
private LocalDateTime commentTime;
|
||||
|
||||
@ApiModelProperty("置顶权重")
|
||||
private Integer weight;
|
||||
|
||||
@ApiModelProperty("用户id")
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty("是否公开:1是 2否")
|
||||
private Integer isOpen;
|
||||
|
||||
public CommentSortEntity() {
|
||||
}
|
||||
|
||||
public CommentSortEntity(Comment comment) {
|
||||
this.id = comment.getId();
|
||||
this.commentTime = comment.getCommentTime();
|
||||
this.weight = comment.getWeight();
|
||||
this.userId = comment.getUserId();
|
||||
this.isOpen = comment.getIsOpen();
|
||||
}
|
||||
|
||||
public CommentSortEntity(LocalDateTime commentTime, Integer weight) {
|
||||
this.commentTime = commentTime;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(CommentSortEntity o) {
|
||||
// 倒序 加-号
|
||||
return -ComparisonChain.start()
|
||||
.compare(this.weight == null ? (Integer) 0 : this.weight, o.weight == null ? (Integer) 0 : o.weight)
|
||||
.compare(this.commentTime, o.commentTime).result();
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public LocalDateTime getCommentTime() {
|
||||
return commentTime;
|
||||
}
|
||||
|
||||
public void setCommentTime(LocalDateTime commentTime) {
|
||||
this.commentTime = commentTime;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getIsOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
public void setIsOpen(Integer isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
|
||||
}
|
||||
92
src/main/java/com/diagnose/entity/RiskLevel.java~
Normal file
92
src/main/java/com/diagnose/entity/RiskLevel.java~
Normal file
@ -0,0 +1,92 @@
|
||||
package com.syzb.common.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 风险等级配置
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2022-11-09
|
||||
*/
|
||||
public class RiskLevel implements Serializable {
|
||||
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 1观点包 2单篇观点 3视频 5交易圈 6图文直播间 7组合 8锦囊 21三方产品-增值产品 22三方产品-课程 23三方产品-ETF专区 24三方产品-选股工具 25三方产品-小飞机理财
|
||||
*/
|
||||
@TableField("product_type")
|
||||
private Integer productType;
|
||||
|
||||
/**
|
||||
* 风险等级:1低风险 2中低风险 3中风险 4中高风险 5高风险
|
||||
*/
|
||||
@TableField("risk_level")
|
||||
private Integer riskLevel;
|
||||
|
||||
@TableField("update_user_id")
|
||||
private Integer updateUserId;
|
||||
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getProductType() {
|
||||
return productType;
|
||||
}
|
||||
|
||||
public void setProductType(Integer productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
|
||||
public Integer getRiskLevel() {
|
||||
return riskLevel;
|
||||
}
|
||||
|
||||
public void setRiskLevel(Integer riskLevel) {
|
||||
this.riskLevel = riskLevel;
|
||||
}
|
||||
|
||||
public Integer getUpdateUserId() {
|
||||
return updateUserId;
|
||||
}
|
||||
|
||||
public void setUpdateUserId(Integer updateUserId) {
|
||||
this.updateUserId = updateUserId;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(LocalDateTime updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RiskLevel{" +
|
||||
"id=" + id +
|
||||
", productType=" + productType +
|
||||
", riskLevel=" + riskLevel +
|
||||
", updateUserId=" + updateUserId +
|
||||
", updateTime=" + updateTime +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
208
src/main/java/com/diagnose/entity/ScheduleLog.java~
Normal file
208
src/main/java/com/diagnose/entity/ScheduleLog.java~
Normal file
@ -0,0 +1,208 @@
|
||||
package com.diagnose.common.entity;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.syzb.common.constant.ScheduleLogResult;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2022-11-09
|
||||
*/
|
||||
public class ScheduleLog implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 同步记录ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 服务名
|
||||
*/
|
||||
@TableField("server_name")
|
||||
private String serverName;
|
||||
|
||||
/**
|
||||
* 定时任务名称
|
||||
*/
|
||||
@TableField("schedule_name")
|
||||
private String scheduleName;
|
||||
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private LocalDate date;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
@TableField("start_time")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
@TableField("end_time")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
/**
|
||||
* 执行结果:1:执行中 2:成功 3:失败
|
||||
*/
|
||||
private Integer result;
|
||||
|
||||
/**
|
||||
* 附加信息json
|
||||
*/
|
||||
private String ext;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 执行机器IP
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
public static ScheduleLog start(String scheduleName, String ip) {
|
||||
String server = System.getProperty("server.server");
|
||||
ScheduleLog log = new ScheduleLog();
|
||||
log.setServerName(server);
|
||||
log.setScheduleName(scheduleName);
|
||||
log.setDate(LocalDate.now());
|
||||
log.setStartTime(LocalDateTime.now());
|
||||
log.setResult(ScheduleLogResult.RUNNING.value);
|
||||
log.setIp(ip);
|
||||
return log;
|
||||
}
|
||||
|
||||
public static ScheduleLog success(Integer id, String ext) {
|
||||
ScheduleLog log = new ScheduleLog();
|
||||
log.setId(id);
|
||||
log.setEndTime(LocalDateTime.now());
|
||||
log.setResult(ScheduleLogResult.SUCCESS.value);
|
||||
if (StrUtil.isNotEmpty(ext)) {
|
||||
log.setExt(ext);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
public static ScheduleLog error(Integer id, String error) {
|
||||
ScheduleLog log = new ScheduleLog();
|
||||
log.setId(id);
|
||||
log.setEndTime(LocalDateTime.now());
|
||||
log.setResult(ScheduleLogResult.FAILURE.value);
|
||||
if (StrUtil.isNotEmpty(error)) {
|
||||
log.setError(error);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
public String getScheduleName() {
|
||||
return scheduleName;
|
||||
}
|
||||
|
||||
public void setScheduleName(String scheduleName) {
|
||||
this.scheduleName = scheduleName;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(LocalDateTime startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(LocalDateTime endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public Integer getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Integer result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getExt() {
|
||||
return ext;
|
||||
}
|
||||
|
||||
public void setExt(String ext) {
|
||||
this.ext = ext;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScheduleLog{" +
|
||||
"id=" + id +
|
||||
", serverName=" + serverName +
|
||||
", scheduleName=" + scheduleName +
|
||||
", date=" + date +
|
||||
", startTime=" + startTime +
|
||||
", endTime=" + endTime +
|
||||
", result=" + result +
|
||||
", ext=" + ext +
|
||||
", error=" + error +
|
||||
", ip=" + ip +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
70
src/main/java/com/diagnose/entity/SensitiveWord.java~
Normal file
70
src/main/java/com/diagnose/entity/SensitiveWord.java~
Normal file
@ -0,0 +1,70 @@
|
||||
package com.syzb.common.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2022-08-26
|
||||
*/
|
||||
public class SensitiveWord implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 敏感词
|
||||
*/
|
||||
private String word;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
public void setWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(LocalDateTime createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SensitiveWord{" +
|
||||
"id=" + id +
|
||||
", word=" + word +
|
||||
", createTime=" + createTime +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
57
src/main/java/com/diagnose/entity/ShortUrl.java~
Normal file
57
src/main/java/com/diagnose/entity/ShortUrl.java~
Normal file
@ -0,0 +1,57 @@
|
||||
package com.syzb.common.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2024-07-02
|
||||
*/
|
||||
public class ShortUrl implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 哈希后得短链
|
||||
*/
|
||||
@TableId("resize_url")
|
||||
private String resizeUrl;
|
||||
|
||||
/**
|
||||
* 原始链接
|
||||
*/
|
||||
private String url;
|
||||
|
||||
public ShortUrl(String resizeUrl, String url) {
|
||||
this.resizeUrl = resizeUrl;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getResizeUrl() {
|
||||
return resizeUrl;
|
||||
}
|
||||
|
||||
public void setResizeUrl(String resizeUrl) {
|
||||
this.resizeUrl = resizeUrl;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ShortUrl{" +
|
||||
"resizeUrl=" + resizeUrl +
|
||||
", url=" + url +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/diagnose/mapper/CommentMapper.java~
Normal file
25
src/main/java/com/diagnose/mapper/CommentMapper.java~
Normal file
@ -0,0 +1,25 @@
|
||||
package com.diagnose.common.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.syzb.common.entity.Comment;
|
||||
import com.syzb.common.vo.IdCountVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 评论表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author helloSyzb
|
||||
* @since 2024-04-25
|
||||
*/
|
||||
public interface CommentMapper extends BaseMapper<Comment> {
|
||||
|
||||
@Select("select ${ew.sqlSelect} from comment ${ew.customSqlSegment}")
|
||||
List<IdCountVO> selectCommentCount(@Param(Constants.WRAPPER) Wrapper<Comment> wrapper);
|
||||
}
|
||||
34
src/main/java/com/diagnose/mapper/DiagnoseMapper.java
Normal file
34
src/main/java/com/diagnose/mapper/DiagnoseMapper.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.diagnose.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.diagnose.vo.DiagnoseBackTestVO;
|
||||
import com.diagnose.vo.DiagnoseRankVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public interface DiagnoseMapper extends BaseMapper<DiagnoseRankVO> {
|
||||
|
||||
@Select("SELECT * FROM (" +
|
||||
" SELECT *, ROW_NUMBER() OVER (PARTITION BY stk_uni_code ORDER BY trade_date DESC) AS rn\n" +
|
||||
" FROM _fe_stk_diag_rank\n" +
|
||||
" WHERE stk_uni_code = #{stkUniCode} AND isvalid = 1\n" +
|
||||
") t WHERE t.rn = 1")
|
||||
DiagnoseRankVO selectRank(@Param("stkUniCode") Long stkUniCode);
|
||||
|
||||
@Select("SELECT max(total_indu_rank) AS _total_indu_rank FROM _fe_stk_diag_rank WHERE plate_uni_code = #{plateUniCode}")
|
||||
Integer selectTotalInduCount(@Param("plateUniCode") Long plateUniCode);
|
||||
|
||||
@Select("SELECT max(total_mkt_rank) AS _total_mkt_rank FROM _fe_stk_diag_rank")
|
||||
Integer selectTotalMktCount();
|
||||
|
||||
@Select("SELECT * FROM (" +
|
||||
" SELECT *, RANK() OVER (ORDER BY trade_date DESC) AS rk\n" +
|
||||
" FROM _fe_stk_diag_backtest\n" +
|
||||
" WHERE star = #{star} AND isvalid = 1\n" +
|
||||
") t WHERE t.rk = 1")
|
||||
List<DiagnoseBackTestVO> selectBackTest(@Param("star") BigDecimal star);
|
||||
|
||||
}
|
||||
35
src/main/java/com/diagnose/mapper/FinanceMapper.java
Normal file
35
src/main/java/com/diagnose/mapper/FinanceMapper.java
Normal file
@ -0,0 +1,35 @@
|
||||
package com.diagnose.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.diagnose.vo.FinanceCashShortVO;
|
||||
import com.diagnose.vo.FinanceIndexAnalysisVO;
|
||||
import com.diagnose.vo.FinancialValuationVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface FinanceMapper extends BaseMapper<FinancialValuationVO> {
|
||||
|
||||
@Select("SELECT * FROM (" +
|
||||
" SELECT fin_sum_mac, score, ROW_NUMBER() OVER (PARTITION BY stk_code, mkt_num ORDER BY trd_date DESC) AS rn\n" +
|
||||
" FROM _fin_val_fac\n" +
|
||||
" WHERE stk_code = #{stkCode} AND mkt_num = #{mktNum}\n" +
|
||||
") t WHERE t.rn = 1")
|
||||
FinancialValuationVO selectFinancialValuation(@Param("stkCode") String stkCode, @Param("mktNum") Integer mktNum);
|
||||
|
||||
@Select("SELECT * FROM (" +
|
||||
" SELECT *, ROW_NUMBER() OVER (PARTITION BY stk_code, sec_mar_par ORDER BY end_date DESC) AS rn\n" +
|
||||
" FROM _fin_idx_ana\n" +
|
||||
" WHERE stk_code = #{stkCode} AND sec_mar_par = #{secMarPar}\n" +
|
||||
") t WHERE t.rn <= 5")
|
||||
List<FinanceIndexAnalysisVO> selectFinanceIndexAnalysis(@Param("stkCode") String stkCode, @Param("secMarPar") Integer secMarPar);
|
||||
|
||||
@Select("SELECT * FROM (" +
|
||||
" SELECT *, ROW_NUMBER() OVER (PARTITION BY stk_code, sec_mar_par ORDER BY end_date DESC) AS rn\n" +
|
||||
" FROM _fin_cash_short\n" +
|
||||
" WHERE stk_code = #{stkCode} AND sec_mar_par = #{secMarPar}\n" +
|
||||
") t WHERE t.rn <= 5")
|
||||
List<FinanceCashShortVO> selectFinanceCashShort(@Param("stkCode") String stkCode, @Param("secMarPar") Integer secMarPar);
|
||||
|
||||
}
|
||||
19
src/main/java/com/diagnose/mapper/StockMapper.java
Normal file
19
src/main/java/com/diagnose/mapper/StockMapper.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.diagnose.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.diagnose.vo.StockVO;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StockMapper extends BaseMapper<StockVO> {
|
||||
|
||||
@Select("SELECT sc.sec_uni_code, sc.sec_code, sc.sec_short_name, sc.sec_spe_short_name, sc.mkt_type_par, pi.plate_uni_code, pi.plate_name, pi.plate_code\n" +
|
||||
"FROM _pub_sec_code sc\n" +
|
||||
"JOIN _pub_sec_plate sp\n" +
|
||||
"ON sc.sec_uni_code = sp.sec_uni_code\n" +
|
||||
"JOIN pub_plate_info pi\n" +
|
||||
"ON sp.plate_uni_code = pi.plate_uni_code")
|
||||
List<StockVO> selectAllStock();
|
||||
|
||||
}
|
||||
18
src/main/java/com/diagnose/mapper/UnionMapper.java~
Normal file
18
src/main/java/com/diagnose/mapper/UnionMapper.java~
Normal file
@ -0,0 +1,18 @@
|
||||
package com.diagnose.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.diagnose.common.vo.CountVO;
|
||||
import com.diagnose.vo.StockVO;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UnionMapper extends BaseMapper<CountVO> {
|
||||
|
||||
@Select("SELECT sc.sec_uni_code, sc.sec_code, sc.sec_short_name, sc.sec_spe_short_name, sc.mkt_type_par, pi.plate_uni_code, pi.plate_name, pi.plate_code FROM _pub_sec_code sc\n" +
|
||||
"JOIN _pub_sec_plate sp\n" +
|
||||
"ON sc.SEC_UNI_CODE = sp.SEC_UNI_CODE\n" +
|
||||
"JOIN pub_plate_info pi\n" +
|
||||
"ON sp.PLATE_UNI_CODE = pi.PLATE_UNI_CODE")
|
||||
List<StockVO> selectAllStock();
|
||||
}
|
||||
36
src/main/java/com/diagnose/service/SearchService.java
Normal file
36
src/main/java/com/diagnose/service/SearchService.java
Normal file
@ -0,0 +1,36 @@
|
||||
package com.diagnose.service;
|
||||
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import com.diagnose.vo.StockVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Service
|
||||
public class SearchService {
|
||||
|
||||
private static final int limit = 10;
|
||||
|
||||
@Resource
|
||||
private StockService stockService;
|
||||
|
||||
public List<StockVO> search(String keyword) {
|
||||
String keywordTrim = keyword.trim();
|
||||
List<StockVO> allStockList = stockService.selectALlStockCache();
|
||||
Stream<StockVO> parallelStream = allStockList.parallelStream();
|
||||
if (Validator.isNumber(keywordTrim)) {
|
||||
parallelStream = parallelStream.filter(stock -> stock.getSecCode().contains(keywordTrim));
|
||||
} else if (Validator.isWord(keywordTrim)) {
|
||||
String keywordUpper = keywordTrim.toUpperCase();
|
||||
parallelStream = parallelStream.filter(stock -> stock.getSecSpeShortName().contains(keywordUpper) );
|
||||
} else {
|
||||
parallelStream = parallelStream.filter(stock -> stock.getSecShortName().contains(keywordTrim));
|
||||
}
|
||||
return parallelStream.limit(limit).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
38
src/main/java/com/diagnose/service/SearchService.java~
Normal file
38
src/main/java/com/diagnose/service/SearchService.java~
Normal file
@ -0,0 +1,38 @@
|
||||
package com.diagnose.service;
|
||||
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import com.diagnose.vo.StockVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Service
|
||||
public class SearchService {
|
||||
|
||||
private static final int limit = 10;
|
||||
|
||||
@Resource
|
||||
private StockService stockService;
|
||||
|
||||
public List<StockVO> search(String keyword) {
|
||||
String keywordTrim = keyword.trim();
|
||||
List<StockVO> allStockList = stockService.selectALlStockCache();
|
||||
Stream<StockVO> parallelStream = allStockList.parallelStream();
|
||||
if (Validator.isNumber(keywordTrim)) {
|
||||
parallelStream = parallelStream.filter(stock -> stock.getSecCode().contains(keywordTrim));
|
||||
} else if (Validator.isWord(keywordTrim)) {
|
||||
String keywordUpper = keywordTrim.toUpperCase();
|
||||
parallelStream = parallelStream.filter(stock -> stock.getSecSpeShortName().contains(keywordUpper) );
|
||||
} else {
|
||||
parallelStream = parallelStream.filter(stock -> stock.getSecShortName().contains(keywordTrim));
|
||||
}
|
||||
return parallelStream.limit(limit).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<StockVO> rank(@NotNull Long stkUniCode) {
|
||||
}
|
||||
}
|
||||
109
src/main/java/com/diagnose/service/StockService.java
Normal file
109
src/main/java/com/diagnose/service/StockService.java
Normal file
@ -0,0 +1,109 @@
|
||||
package com.diagnose.service;
|
||||
|
||||
import com.diagnose.mapper.DiagnoseMapper;
|
||||
import com.diagnose.mapper.FinanceMapper;
|
||||
import com.diagnose.mapper.StockMapper;
|
||||
import com.diagnose.vo.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class StockService {
|
||||
|
||||
private static final long cacheExpires = 60 * 60 * 1000;
|
||||
|
||||
private static long cacheTime = 0;
|
||||
|
||||
private List<StockVO> stockListCache = null;
|
||||
|
||||
private Map<Long, StockVO> stockMapCache = null; // <stkUniCode, StockVO>
|
||||
|
||||
@Resource
|
||||
private StockMapper stockMapper;
|
||||
|
||||
@Resource
|
||||
private FinanceMapper financeMapper;
|
||||
|
||||
@Resource
|
||||
private DiagnoseMapper diagnoseMapper;
|
||||
|
||||
public List<StockVO> selectAllStock() {
|
||||
return stockMapper.selectAllStock();
|
||||
}
|
||||
|
||||
public synchronized List<StockVO> selectALlStockCache () {
|
||||
long now = System.currentTimeMillis();
|
||||
if (stockListCache == null || now - cacheTime > cacheExpires) {
|
||||
stockListCache = selectAllStock();
|
||||
cacheTime = now;
|
||||
}
|
||||
return stockListCache;
|
||||
}
|
||||
|
||||
public StockVO getStock(Long stkUniCode) {
|
||||
if (stockMapCache == null) {
|
||||
stockMapCache = selectALlStockCache().stream().collect(Collectors.toMap(StockVO::getSecUniCode, Function.identity()));
|
||||
}
|
||||
return stockMapCache.get(stkUniCode);
|
||||
}
|
||||
|
||||
public DiagnoseRankVO rank(StockVO stock) {
|
||||
DiagnoseRankVO diagnoseRankVO = diagnoseMapper.selectRank(stock.getSecUniCode());
|
||||
Integer totalInduCount = diagnoseMapper.selectTotalInduCount(stock.getPlateUniCode());
|
||||
Integer totalMktCount = diagnoseMapper.selectTotalMktCount();
|
||||
diagnoseRankVO.setTotalInduCount(totalInduCount);
|
||||
diagnoseRankVO.setTotalMktCount(totalMktCount);
|
||||
return diagnoseRankVO;
|
||||
}
|
||||
|
||||
public ComprehensiveEvaluationVO comprehensiveEvaluation(Long stkUniCode) {
|
||||
StockVO stock = getStock(stkUniCode);
|
||||
if (stock == null) {
|
||||
return null;
|
||||
}
|
||||
DiagnoseRankVO diagnoseRankVO = rank(stock);
|
||||
BigDecimal star = diagnoseRankVO.getTotalStar();
|
||||
if (star == null) {
|
||||
return null;
|
||||
}
|
||||
List<DiagnoseBackTestVO> backTestList = diagnoseMapper.selectBackTest(star);
|
||||
ComprehensiveEvaluationVO vo = new ComprehensiveEvaluationVO();
|
||||
vo.setStock(stock);
|
||||
vo.setRank(diagnoseRankVO);
|
||||
vo.setBackTestList(backTestList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
public FinancialValuationVO financialValuation(Long stkUniCode) {
|
||||
StockVO stock = getStock(stkUniCode);
|
||||
if (stock == null) {
|
||||
return null;
|
||||
}
|
||||
String secCode = stock.getSecCode();
|
||||
Integer mktNum = stock.getMktNum();
|
||||
FinancialValuationVO vo = financeMapper.selectFinancialValuation(secCode, mktNum);
|
||||
Integer secMarPar = stock.getSecMarPar();
|
||||
List<FinanceIndexAnalysisVO> financeIndexAnalysisList = financeMapper.selectFinanceIndexAnalysis(secCode, secMarPar);
|
||||
financeIndexAnalysisList.forEach(fiaVO -> {
|
||||
if (fiaVO.getEndDate() != null && fiaVO.getEndDate().length() > 10) {
|
||||
fiaVO.setEndDate(fiaVO.getEndDate().substring(0, 10));
|
||||
}
|
||||
});
|
||||
vo.setFinanceIndexAnalysisList(financeIndexAnalysisList);
|
||||
List<FinanceCashShortVO> financeCashShortList = financeMapper.selectFinanceCashShort(secCode, secMarPar);
|
||||
financeCashShortList.forEach(fcsVO -> {
|
||||
if (fcsVO.getEndDate() != null && fcsVO.getEndDate().length() > 10) {
|
||||
fcsVO.setEndDate(fcsVO.getEndDate().substring(0, 10));
|
||||
}
|
||||
});
|
||||
vo.setFinanceCashShortList(financeCashShortList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/com/diagnose/startup/Main.java
Normal file
25
src/main/java/com/diagnose/startup/Main.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.diagnose.startup;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@ComponentScan("com.diagnose")
|
||||
@SpringBootApplication
|
||||
@EnableCaching
|
||||
@EnableTransactionManagement
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||
@EnableAsync
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication app = new SpringApplication(Main.class);
|
||||
app.setRegisterShutdownHook(true);
|
||||
app.run(args);
|
||||
}
|
||||
|
||||
}
|
||||
48
src/main/java/com/diagnose/test3.java~
Normal file
48
src/main/java/com/diagnose/test3.java~
Normal file
@ -0,0 +1,48 @@
|
||||
package com.diagnose;
|
||||
|
||||
import org.ahocorasick.trie.Emit;
|
||||
import org.ahocorasick.trie.Trie;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class test3 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 示例数据
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("hello world");
|
||||
list.add("java programming");
|
||||
list.add("ahocorasick algorithm");
|
||||
list.add("substring matching");
|
||||
list.add("performance optimization");
|
||||
list.add("data structures");
|
||||
list.add("algorithm design");
|
||||
list.add("string search");
|
||||
list.add("efficient matching");
|
||||
list.add("aho-corasick implementation");
|
||||
list.add("another example");
|
||||
list.add("yet another example");
|
||||
list.add("example");
|
||||
list.add("abcexample");
|
||||
list.add("abcexampledef");
|
||||
|
||||
// 目标子串
|
||||
String input = "example";
|
||||
|
||||
Trie trie = Trie.builder()
|
||||
.ignoreOverlaps()
|
||||
.addKeyword(input) // 将目标子串作为模式插入
|
||||
.build();
|
||||
|
||||
// 匹配字符串
|
||||
Collection<Emit> emits = trie.parseText(input);
|
||||
|
||||
// 输出结果
|
||||
System.out.println("匹配到的字符串:");
|
||||
for (Emit emit : emits) {
|
||||
System.out.println(emit.getKeyword());
|
||||
}
|
||||
}
|
||||
}
|
||||
80
src/main/java/com/diagnose/util/StringMatcher.java
Normal file
80
src/main/java/com/diagnose/util/StringMatcher.java
Normal file
@ -0,0 +1,80 @@
|
||||
package com.diagnose.util;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StringMatcher {
|
||||
|
||||
private final int GRAM_SIZE = 1;
|
||||
|
||||
private Map<String, Set<Integer>> indexMap = new HashMap<>();
|
||||
private List<String> dataList;
|
||||
|
||||
public StringMatcher(List<String> dataList) {
|
||||
this.dataList = dataList;
|
||||
buildIndex();
|
||||
}
|
||||
|
||||
private void buildIndex() {
|
||||
// 为了平衡性能和内存,可以考虑只索引n-gram
|
||||
for (int i = 0; i < dataList.size(); i++) {
|
||||
String s = dataList.get(i);
|
||||
// 生成所有可能的子串或n-gram
|
||||
for (int j = 0; j < s.length() - GRAM_SIZE + 1; j++) {
|
||||
String gram = s.substring(j, j + GRAM_SIZE); // n-gram
|
||||
indexMap.computeIfAbsent(gram, k -> new HashSet<>()).add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> search(String query, int limit) {
|
||||
// 如果查询字符串长度小于GRAM_SIZE,使用简单遍历
|
||||
if (query.length() < GRAM_SIZE) {
|
||||
return simpleSearch(query, limit);
|
||||
}
|
||||
|
||||
Set<Integer> candidates = null;
|
||||
|
||||
// 使用查询的n-gram找候选集
|
||||
for (int i = 0; i <= query.length() - GRAM_SIZE; i++) {
|
||||
String gram = query.substring(i, i + GRAM_SIZE);
|
||||
Set<Integer> indices = indexMap.getOrDefault(gram, Collections.emptySet());
|
||||
|
||||
if (candidates == null) {
|
||||
candidates = new HashSet<>(indices);
|
||||
} else {
|
||||
candidates.retainAll(indices);
|
||||
}
|
||||
|
||||
if (candidates.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
// 验证候选集
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Integer idx : candidates) {
|
||||
if (dataList.get(idx).contains(query)) {
|
||||
result.add(dataList.get(idx));
|
||||
if (result.size() >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> simpleSearch(String query, int limit) {
|
||||
// 简单遍历法
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String s : dataList) {
|
||||
if (s.contains(query)) {
|
||||
result.add(s);
|
||||
if (result.size() >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
34
src/main/java/com/diagnose/util/TestSearch.java
Normal file
34
src/main/java/com/diagnose/util/TestSearch.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.diagnose.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TestSearch {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 示例数据
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("hello world");
|
||||
list.add("java programming");
|
||||
list.add("ahocorasick algorithm");
|
||||
list.add("substring matching");
|
||||
list.add("performance optimization");
|
||||
list.add("data structures");
|
||||
list.add("algorithm design");
|
||||
list.add("string search");
|
||||
list.add("efficient matching");
|
||||
list.add("aho-corasick implementation");
|
||||
list.add("another example");
|
||||
list.add("yet another example");
|
||||
list.add("example");
|
||||
list.add("abcexample");
|
||||
list.add("abcexampledef");
|
||||
|
||||
StringMatcher matcher = new StringMatcher(list);
|
||||
List<String> results = matcher.search("example", 10);
|
||||
|
||||
for (String result : results) {
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/main/java/com/diagnose/vo/ComprehensiveEvaluationVO.java
Normal file
43
src/main/java/com/diagnose/vo/ComprehensiveEvaluationVO.java
Normal file
@ -0,0 +1,43 @@
|
||||
package com.diagnose.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("综合评分")
|
||||
public class ComprehensiveEvaluationVO {
|
||||
|
||||
@ApiModelProperty("股票基本信息")
|
||||
private StockVO stock;
|
||||
|
||||
@ApiModelProperty("评分排名")
|
||||
private DiagnoseRankVO rank;
|
||||
|
||||
@ApiModelProperty("回测列表")
|
||||
private List<DiagnoseBackTestVO> backTestList;
|
||||
|
||||
public DiagnoseRankVO getRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
public void setRank(DiagnoseRankVO rank) {
|
||||
this.rank = rank;
|
||||
}
|
||||
|
||||
public StockVO getStock() {
|
||||
return stock;
|
||||
}
|
||||
|
||||
public void setStock(StockVO stock) {
|
||||
this.stock = stock;
|
||||
}
|
||||
|
||||
public List<DiagnoseBackTestVO> getBackTestList() {
|
||||
return backTestList;
|
||||
}
|
||||
|
||||
public void setBackTestList(List<DiagnoseBackTestVO> backTestList) {
|
||||
this.backTestList = backTestList;
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/diagnose/vo/DiagnoseBackTestVO.java
Normal file
44
src/main/java/com/diagnose/vo/DiagnoseBackTestVO.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.diagnose.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("回测分析")
|
||||
public class DiagnoseBackTestVO implements Serializable {
|
||||
|
||||
@ApiModelProperty("持仓周期")
|
||||
private String timeSpan;
|
||||
|
||||
@ApiModelProperty("平均超额收益率")
|
||||
private String avgExcessRet;
|
||||
|
||||
@ApiModelProperty("胜率")
|
||||
private String winRate;
|
||||
|
||||
public String getTimeSpan() {
|
||||
return timeSpan;
|
||||
}
|
||||
|
||||
public void setTimeSpan(String timeSpan) {
|
||||
this.timeSpan = timeSpan;
|
||||
}
|
||||
|
||||
public String getAvgExcessRet() {
|
||||
return avgExcessRet;
|
||||
}
|
||||
|
||||
public void setAvgExcessRet(String avgExcessRet) {
|
||||
this.avgExcessRet = avgExcessRet;
|
||||
}
|
||||
|
||||
public String getWinRate() {
|
||||
return winRate;
|
||||
}
|
||||
|
||||
public void setWinRate(String winRate) {
|
||||
this.winRate = winRate;
|
||||
}
|
||||
|
||||
}
|
||||
133
src/main/java/com/diagnose/vo/DiagnoseRankVO.java
Normal file
133
src/main/java/com/diagnose/vo/DiagnoseRankVO.java
Normal file
@ -0,0 +1,133 @@
|
||||
package com.diagnose.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@ApiModel("得分排名")
|
||||
public class DiagnoseRankVO implements Serializable {
|
||||
|
||||
@ApiModelProperty("行业排名")
|
||||
private Integer totalInduRank;
|
||||
|
||||
@ApiModelProperty("行业总数")
|
||||
private Integer totalInduCount;
|
||||
|
||||
@ApiModelProperty("市场排名")
|
||||
private Integer totalMktRank;
|
||||
|
||||
@ApiModelProperty("市场总数")
|
||||
private Integer totalMktCount;
|
||||
|
||||
@ApiModelProperty("综合得分")
|
||||
private BigDecimal totalScore;
|
||||
|
||||
@ApiModelProperty("综合星级")
|
||||
private BigDecimal totalStar;
|
||||
|
||||
@ApiModelProperty("财务得分")
|
||||
private BigDecimal finScore;
|
||||
|
||||
@ApiModelProperty("量化得分")
|
||||
private BigDecimal volScore;
|
||||
|
||||
@ApiModelProperty("市场热度得分")
|
||||
private BigDecimal mhotScore;
|
||||
|
||||
@ApiModelProperty("主力得分")
|
||||
private BigDecimal mainScore;
|
||||
|
||||
@ApiModelProperty("题材得分")
|
||||
private BigDecimal mqScore;
|
||||
|
||||
public Integer getTotalInduRank() {
|
||||
return totalInduRank;
|
||||
}
|
||||
|
||||
public void setTotalInduRank(Integer totalInduRank) {
|
||||
this.totalInduRank = totalInduRank;
|
||||
}
|
||||
|
||||
public Integer getTotalInduCount() {
|
||||
return totalInduCount;
|
||||
}
|
||||
|
||||
public void setTotalInduCount(Integer totalInduCount) {
|
||||
this.totalInduCount = totalInduCount;
|
||||
}
|
||||
|
||||
public Integer getTotalMktRank() {
|
||||
return totalMktRank;
|
||||
}
|
||||
|
||||
public void setTotalMktRank(Integer totalMktRank) {
|
||||
this.totalMktRank = totalMktRank;
|
||||
}
|
||||
|
||||
public Integer getTotalMktCount() {
|
||||
return totalMktCount;
|
||||
}
|
||||
|
||||
public void setTotalMktCount(Integer totalMktCount) {
|
||||
this.totalMktCount = totalMktCount;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalScore() {
|
||||
return totalScore;
|
||||
}
|
||||
|
||||
public void setTotalScore(BigDecimal totalScore) {
|
||||
this.totalScore = totalScore;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalStar() {
|
||||
return totalStar;
|
||||
}
|
||||
|
||||
public void setTotalStar(BigDecimal totalStar) {
|
||||
this.totalStar = totalStar;
|
||||
}
|
||||
|
||||
public BigDecimal getFinScore() {
|
||||
return finScore;
|
||||
}
|
||||
|
||||
public void setFinScore(BigDecimal finScore) {
|
||||
this.finScore = finScore;
|
||||
}
|
||||
|
||||
public BigDecimal getVolScore() {
|
||||
return volScore;
|
||||
}
|
||||
|
||||
public void setVolScore(BigDecimal volScore) {
|
||||
this.volScore = volScore;
|
||||
}
|
||||
|
||||
public BigDecimal getMhotScore() {
|
||||
return mhotScore;
|
||||
}
|
||||
|
||||
public void setMhotScore(BigDecimal mhotScore) {
|
||||
this.mhotScore = mhotScore;
|
||||
}
|
||||
|
||||
public BigDecimal getMainScore() {
|
||||
return mainScore;
|
||||
}
|
||||
|
||||
public void setMainScore(BigDecimal mainScore) {
|
||||
this.mainScore = mainScore;
|
||||
}
|
||||
|
||||
public BigDecimal getMqScore() {
|
||||
return mqScore;
|
||||
}
|
||||
|
||||
public void setMqScore(BigDecimal mqScore) {
|
||||
this.mqScore = mqScore;
|
||||
}
|
||||
|
||||
}
|
||||
51
src/main/java/com/diagnose/vo/FinanceCashShortVO.java
Normal file
51
src/main/java/com/diagnose/vo/FinanceCashShortVO.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.diagnose.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class FinanceCashShortVO {
|
||||
|
||||
@ApiModelProperty("截止日期")
|
||||
private String endDate;
|
||||
|
||||
@ApiModelProperty("经营活动现金流量净额")
|
||||
private String cs10000;
|
||||
|
||||
@ApiModelProperty("投资活动现金流量净额")
|
||||
private String cs20000;
|
||||
|
||||
@ApiModelProperty("筹资活动现金流量净额")
|
||||
private String cs30000;
|
||||
|
||||
public String getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(String endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public String getCs10000() {
|
||||
return cs10000;
|
||||
}
|
||||
|
||||
public void setCs10000(String cs10000) {
|
||||
this.cs10000 = cs10000;
|
||||
}
|
||||
|
||||
public String getCs20000() {
|
||||
return cs20000;
|
||||
}
|
||||
|
||||
public void setCs20000(String cs20000) {
|
||||
this.cs20000 = cs20000;
|
||||
}
|
||||
|
||||
public String getCs30000() {
|
||||
return cs30000;
|
||||
}
|
||||
|
||||
public void setCs30000(String cs30000) {
|
||||
this.cs30000 = cs30000;
|
||||
}
|
||||
|
||||
}
|
||||
110
src/main/java/com/diagnose/vo/FinanceIndexAnalysisVO.java
Normal file
110
src/main/java/com/diagnose/vo/FinanceIndexAnalysisVO.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.diagnose.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@ApiModel("财务指标分析")
|
||||
public class FinanceIndexAnalysisVO {
|
||||
|
||||
@ApiModelProperty("截止日期")
|
||||
private String endDate;
|
||||
|
||||
@ApiModelProperty("销售净利率")
|
||||
private BigDecimal salNpr;
|
||||
|
||||
@ApiModelProperty("销售毛利率")
|
||||
private BigDecimal salGir;
|
||||
|
||||
@ApiModelProperty("净资产收益率")
|
||||
private BigDecimal roea;
|
||||
|
||||
@ApiModelProperty("净利润同比增长率_同比")
|
||||
private BigDecimal npYoy;
|
||||
|
||||
@ApiModelProperty("营业收入 同比")
|
||||
private BigDecimal orYoy;
|
||||
|
||||
@ApiModelProperty("总资产周转率")
|
||||
private BigDecimal taRate;
|
||||
|
||||
@ApiModelProperty("应付账款周转率")
|
||||
private BigDecimal apRate;
|
||||
|
||||
@ApiModelProperty("资产负债率")
|
||||
private BigDecimal assDebt;
|
||||
|
||||
public String getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(String endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public BigDecimal getSalNpr() {
|
||||
return salNpr;
|
||||
}
|
||||
|
||||
public void setSalNpr(BigDecimal salNpr) {
|
||||
this.salNpr = salNpr;
|
||||
}
|
||||
|
||||
public BigDecimal getSalGir() {
|
||||
return salGir;
|
||||
}
|
||||
|
||||
public void setSalGir(BigDecimal salGir) {
|
||||
this.salGir = salGir;
|
||||
}
|
||||
|
||||
public BigDecimal getRoea() {
|
||||
return roea;
|
||||
}
|
||||
|
||||
public void setRoea(BigDecimal roea) {
|
||||
this.roea = roea;
|
||||
}
|
||||
|
||||
public BigDecimal getNpYoy() {
|
||||
return npYoy;
|
||||
}
|
||||
|
||||
public void setNpYoy(BigDecimal npYoy) {
|
||||
this.npYoy = npYoy;
|
||||
}
|
||||
|
||||
public BigDecimal getOrYoy() {
|
||||
return orYoy;
|
||||
}
|
||||
|
||||
public void setOrYoy(BigDecimal orYoy) {
|
||||
this.orYoy = orYoy;
|
||||
}
|
||||
|
||||
public BigDecimal getTaRate() {
|
||||
return taRate;
|
||||
}
|
||||
|
||||
public void setTaRate(BigDecimal taRate) {
|
||||
this.taRate = taRate;
|
||||
}
|
||||
|
||||
public BigDecimal getApRate() {
|
||||
return apRate;
|
||||
}
|
||||
|
||||
public void setApRate(BigDecimal apRate) {
|
||||
this.apRate = apRate;
|
||||
}
|
||||
|
||||
public BigDecimal getAssDebt() {
|
||||
return assDebt;
|
||||
}
|
||||
|
||||
public void setAssDebt(BigDecimal assDebt) {
|
||||
this.assDebt = assDebt;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user