commit a62b515e492153447be4bf0103c67ccf46fc9a5d Author: alex_q <914269@qq.com> Date: Fri Jul 10 10:23:55 2026 +0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e0934da --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Created by .ignore support plugin (hsz.mobi) +### Example sysUserDetails template template +### Example sysUserDetails template + +# IntelliJ project files +.idea +*.iml +out +gen +target +*.log +logs \ No newline at end of file diff --git a/lib/HikariCP-5.0.1.jar b/lib/HikariCP-5.0.1.jar new file mode 100644 index 0000000..9d7eafb Binary files /dev/null and b/lib/HikariCP-5.0.1.jar differ diff --git a/lib/annotations-24.0.1.jar b/lib/annotations-24.0.1.jar new file mode 100644 index 0000000..a4198f7 Binary files /dev/null and b/lib/annotations-24.0.1.jar differ diff --git a/lib/classgraph-4.8.149.jar b/lib/classgraph-4.8.149.jar new file mode 100644 index 0000000..095f666 Binary files /dev/null and b/lib/classgraph-4.8.149.jar differ diff --git a/lib/commons-lang3-3.12.0.jar b/lib/commons-lang3-3.12.0.jar new file mode 100644 index 0000000..4d434a2 Binary files /dev/null and b/lib/commons-lang3-3.12.0.jar differ diff --git a/lib/fastjson-2.0.32.jar b/lib/fastjson-2.0.32.jar new file mode 100644 index 0000000..af12ab1 Binary files /dev/null and b/lib/fastjson-2.0.32.jar differ diff --git a/lib/fastjson2-2.0.32.jar b/lib/fastjson2-2.0.32.jar new file mode 100644 index 0000000..30e89ae Binary files /dev/null and b/lib/fastjson2-2.0.32.jar differ diff --git a/lib/fastjson2-extension-2.0.32.jar b/lib/fastjson2-extension-2.0.32.jar new file mode 100644 index 0000000..f408267 Binary files /dev/null and b/lib/fastjson2-extension-2.0.32.jar differ diff --git a/lib/jackson-annotations-2.15.0.jar b/lib/jackson-annotations-2.15.0.jar new file mode 100644 index 0000000..fc66d44 Binary files /dev/null and b/lib/jackson-annotations-2.15.0.jar differ diff --git a/lib/jackson-core-2.15.0.jar b/lib/jackson-core-2.15.0.jar new file mode 100644 index 0000000..574894d Binary files /dev/null and b/lib/jackson-core-2.15.0.jar differ diff --git a/lib/jackson-databind-2.15.0.jar b/lib/jackson-databind-2.15.0.jar new file mode 100644 index 0000000..b4d9383 Binary files /dev/null and b/lib/jackson-databind-2.15.0.jar differ diff --git a/lib/jackson-dataformat-yaml-2.15.0.jar b/lib/jackson-dataformat-yaml-2.15.0.jar new file mode 100644 index 0000000..e65e39e Binary files /dev/null and b/lib/jackson-dataformat-yaml-2.15.0.jar differ diff --git a/lib/jackson-datatype-jdk8-2.15.0.jar b/lib/jackson-datatype-jdk8-2.15.0.jar new file mode 100644 index 0000000..2bc4e32 Binary files /dev/null and b/lib/jackson-datatype-jdk8-2.15.0.jar differ diff --git a/lib/jackson-datatype-jsr310-2.15.0.jar b/lib/jackson-datatype-jsr310-2.15.0.jar new file mode 100644 index 0000000..b6e528d Binary files /dev/null and b/lib/jackson-datatype-jsr310-2.15.0.jar differ diff --git a/lib/jackson-module-parameter-names-2.15.0.jar b/lib/jackson-module-parameter-names-2.15.0.jar new file mode 100644 index 0000000..1a18cd3 Binary files /dev/null and b/lib/jackson-module-parameter-names-2.15.0.jar differ diff --git a/lib/jakarta.activation-api-2.1.2.jar b/lib/jakarta.activation-api-2.1.2.jar new file mode 100644 index 0000000..ea57b3e Binary files /dev/null and b/lib/jakarta.activation-api-2.1.2.jar differ diff --git a/lib/jakarta.annotation-api-2.1.1.jar b/lib/jakarta.annotation-api-2.1.1.jar new file mode 100644 index 0000000..e13b7df Binary files /dev/null and b/lib/jakarta.annotation-api-2.1.1.jar differ diff --git a/lib/jakarta.validation-api-3.0.2.jar b/lib/jakarta.validation-api-3.0.2.jar new file mode 100644 index 0000000..254c7a2 Binary files /dev/null and b/lib/jakarta.validation-api-3.0.2.jar differ diff --git a/lib/jakarta.xml.bind-api-4.0.0.jar b/lib/jakarta.xml.bind-api-4.0.0.jar new file mode 100644 index 0000000..b10d606 Binary files /dev/null and b/lib/jakarta.xml.bind-api-4.0.0.jar differ diff --git a/lib/jsoup-1.16.1.jar b/lib/jsoup-1.16.1.jar new file mode 100644 index 0000000..030d385 Binary files /dev/null and b/lib/jsoup-1.16.1.jar differ diff --git a/lib/jsqlparser-4.4.jar b/lib/jsqlparser-4.4.jar new file mode 100644 index 0000000..b3eeba5 Binary files /dev/null and b/lib/jsqlparser-4.4.jar differ diff --git a/lib/jul-to-slf4j-2.0.7.jar b/lib/jul-to-slf4j-2.0.7.jar new file mode 100644 index 0000000..11ed9ff Binary files /dev/null and b/lib/jul-to-slf4j-2.0.7.jar differ diff --git a/lib/knife4j-core-4.0.0.jar b/lib/knife4j-core-4.0.0.jar new file mode 100644 index 0000000..4bb92b7 Binary files /dev/null and b/lib/knife4j-core-4.0.0.jar differ diff --git a/lib/knife4j-openapi3-jakarta-spring-boot-starter-4.0.0.jar b/lib/knife4j-openapi3-jakarta-spring-boot-starter-4.0.0.jar new file mode 100644 index 0000000..2daa0aa Binary files /dev/null and b/lib/knife4j-openapi3-jakarta-spring-boot-starter-4.0.0.jar differ diff --git a/lib/knife4j-openapi3-ui-4.0.0.jar b/lib/knife4j-openapi3-ui-4.0.0.jar new file mode 100644 index 0000000..f5efac5 Binary files /dev/null and b/lib/knife4j-openapi3-ui-4.0.0.jar differ diff --git a/lib/log4j-api-2.20.0.jar b/lib/log4j-api-2.20.0.jar new file mode 100644 index 0000000..29d1b52 Binary files /dev/null and b/lib/log4j-api-2.20.0.jar differ diff --git a/lib/log4j-to-slf4j-2.20.0.jar b/lib/log4j-to-slf4j-2.20.0.jar new file mode 100644 index 0000000..5eb8bc8 Binary files /dev/null and b/lib/log4j-to-slf4j-2.20.0.jar differ diff --git a/lib/logback-classic-1.4.7.jar b/lib/logback-classic-1.4.7.jar new file mode 100644 index 0000000..20d5299 Binary files /dev/null and b/lib/logback-classic-1.4.7.jar differ diff --git a/lib/logback-core-1.4.7.jar b/lib/logback-core-1.4.7.jar new file mode 100644 index 0000000..34267ae Binary files /dev/null and b/lib/logback-core-1.4.7.jar differ diff --git a/lib/lombok-1.18.26.jar b/lib/lombok-1.18.26.jar new file mode 100644 index 0000000..8f95540 Binary files /dev/null and b/lib/lombok-1.18.26.jar differ diff --git a/lib/micrometer-commons-1.11.0.jar b/lib/micrometer-commons-1.11.0.jar new file mode 100644 index 0000000..9455d1b Binary files /dev/null and b/lib/micrometer-commons-1.11.0.jar differ diff --git a/lib/micrometer-observation-1.11.0.jar b/lib/micrometer-observation-1.11.0.jar new file mode 100644 index 0000000..b231d51 Binary files /dev/null and b/lib/micrometer-observation-1.11.0.jar differ diff --git a/lib/mybatis-3.5.10.jar b/lib/mybatis-3.5.10.jar new file mode 100644 index 0000000..0f941e0 Binary files /dev/null and b/lib/mybatis-3.5.10.jar differ diff --git a/lib/mybatis-plus-3.5.3.1.jar b/lib/mybatis-plus-3.5.3.1.jar new file mode 100644 index 0000000..d02f4ee Binary files /dev/null and b/lib/mybatis-plus-3.5.3.1.jar differ diff --git a/lib/mybatis-plus-annotation-3.5.3.1.jar b/lib/mybatis-plus-annotation-3.5.3.1.jar new file mode 100644 index 0000000..2de6716 Binary files /dev/null and b/lib/mybatis-plus-annotation-3.5.3.1.jar differ diff --git a/lib/mybatis-plus-boot-starter-3.5.3.1.jar b/lib/mybatis-plus-boot-starter-3.5.3.1.jar new file mode 100644 index 0000000..653c748 Binary files /dev/null and b/lib/mybatis-plus-boot-starter-3.5.3.1.jar differ diff --git a/lib/mybatis-plus-core-3.5.3.1.jar b/lib/mybatis-plus-core-3.5.3.1.jar new file mode 100644 index 0000000..4f8cde8 Binary files /dev/null and b/lib/mybatis-plus-core-3.5.3.1.jar differ diff --git a/lib/mybatis-plus-extension-3.5.3.1.jar b/lib/mybatis-plus-extension-3.5.3.1.jar new file mode 100644 index 0000000..333fa8e Binary files /dev/null and b/lib/mybatis-plus-extension-3.5.3.1.jar differ diff --git a/lib/mybatis-spring-2.0.7.jar b/lib/mybatis-spring-2.0.7.jar new file mode 100644 index 0000000..a930b60 Binary files /dev/null and b/lib/mybatis-spring-2.0.7.jar differ diff --git a/lib/mysql-connector-j-8.0.33.jar b/lib/mysql-connector-j-8.0.33.jar new file mode 100644 index 0000000..3f741f5 Binary files /dev/null and b/lib/mysql-connector-j-8.0.33.jar differ diff --git a/lib/reactive-streams-1.0.4.jar b/lib/reactive-streams-1.0.4.jar new file mode 100644 index 0000000..e58c483 Binary files /dev/null and b/lib/reactive-streams-1.0.4.jar differ diff --git a/lib/reactor-core-3.5.6.jar b/lib/reactor-core-3.5.6.jar new file mode 100644 index 0000000..f0635ac Binary files /dev/null and b/lib/reactor-core-3.5.6.jar differ diff --git a/lib/slf4j-api-2.0.7.jar b/lib/slf4j-api-2.0.7.jar new file mode 100644 index 0000000..be5447c Binary files /dev/null and b/lib/slf4j-api-2.0.7.jar differ diff --git a/lib/snakeyaml-1.33.jar b/lib/snakeyaml-1.33.jar new file mode 100644 index 0000000..5a95195 Binary files /dev/null and b/lib/snakeyaml-1.33.jar differ diff --git a/lib/spring-aop-6.0.9.jar b/lib/spring-aop-6.0.9.jar new file mode 100644 index 0000000..37d03c3 Binary files /dev/null and b/lib/spring-aop-6.0.9.jar differ diff --git a/lib/spring-beans-6.0.9.jar b/lib/spring-beans-6.0.9.jar new file mode 100644 index 0000000..737902e Binary files /dev/null and b/lib/spring-beans-6.0.9.jar differ diff --git a/lib/spring-boot-3.1.0.jar b/lib/spring-boot-3.1.0.jar new file mode 100644 index 0000000..2d74b13 Binary files /dev/null and b/lib/spring-boot-3.1.0.jar differ diff --git a/lib/spring-boot-autoconfigure-3.1.0.jar b/lib/spring-boot-autoconfigure-3.1.0.jar new file mode 100644 index 0000000..aaa7346 Binary files /dev/null and b/lib/spring-boot-autoconfigure-3.1.0.jar differ diff --git a/lib/spring-boot-jarmode-layertools-3.1.0.jar b/lib/spring-boot-jarmode-layertools-3.1.0.jar new file mode 100644 index 0000000..5f789f1 Binary files /dev/null and b/lib/spring-boot-jarmode-layertools-3.1.0.jar differ diff --git a/lib/spring-context-6.0.9.jar b/lib/spring-context-6.0.9.jar new file mode 100644 index 0000000..3e803ae Binary files /dev/null and b/lib/spring-context-6.0.9.jar differ diff --git a/lib/spring-core-6.0.9.jar b/lib/spring-core-6.0.9.jar new file mode 100644 index 0000000..10b52df Binary files /dev/null and b/lib/spring-core-6.0.9.jar differ diff --git a/lib/spring-expression-6.0.9.jar b/lib/spring-expression-6.0.9.jar new file mode 100644 index 0000000..fb5a330 Binary files /dev/null and b/lib/spring-expression-6.0.9.jar differ diff --git a/lib/spring-jcl-6.0.9.jar b/lib/spring-jcl-6.0.9.jar new file mode 100644 index 0000000..30f1328 Binary files /dev/null and b/lib/spring-jcl-6.0.9.jar differ diff --git a/lib/spring-jdbc-6.0.9.jar b/lib/spring-jdbc-6.0.9.jar new file mode 100644 index 0000000..48e130e Binary files /dev/null and b/lib/spring-jdbc-6.0.9.jar differ diff --git a/lib/spring-tx-6.0.9.jar b/lib/spring-tx-6.0.9.jar new file mode 100644 index 0000000..9d03c68 Binary files /dev/null and b/lib/spring-tx-6.0.9.jar differ diff --git a/lib/spring-web-6.0.9.jar b/lib/spring-web-6.0.9.jar new file mode 100644 index 0000000..3966adf Binary files /dev/null and b/lib/spring-web-6.0.9.jar differ diff --git a/lib/spring-webflux-6.0.9.jar b/lib/spring-webflux-6.0.9.jar new file mode 100644 index 0000000..befd6f7 Binary files /dev/null and b/lib/spring-webflux-6.0.9.jar differ diff --git a/lib/spring-webmvc-6.0.9.jar b/lib/spring-webmvc-6.0.9.jar new file mode 100644 index 0000000..fe5a143 Binary files /dev/null and b/lib/spring-webmvc-6.0.9.jar differ diff --git a/lib/springdoc-openapi-starter-common-2.0.0.jar b/lib/springdoc-openapi-starter-common-2.0.0.jar new file mode 100644 index 0000000..bc54576 Binary files /dev/null and b/lib/springdoc-openapi-starter-common-2.0.0.jar differ diff --git a/lib/springdoc-openapi-starter-webflux-api-2.0.0.jar b/lib/springdoc-openapi-starter-webflux-api-2.0.0.jar new file mode 100644 index 0000000..ad784f6 Binary files /dev/null and b/lib/springdoc-openapi-starter-webflux-api-2.0.0.jar differ diff --git a/lib/springdoc-openapi-starter-webflux-ui-2.0.0.jar b/lib/springdoc-openapi-starter-webflux-ui-2.0.0.jar new file mode 100644 index 0000000..6e95770 Binary files /dev/null and b/lib/springdoc-openapi-starter-webflux-ui-2.0.0.jar differ diff --git a/lib/springdoc-openapi-starter-webmvc-api-2.0.0.jar b/lib/springdoc-openapi-starter-webmvc-api-2.0.0.jar new file mode 100644 index 0000000..771fb25 Binary files /dev/null and b/lib/springdoc-openapi-starter-webmvc-api-2.0.0.jar differ diff --git a/lib/springdoc-openapi-starter-webmvc-ui-2.0.0.jar b/lib/springdoc-openapi-starter-webmvc-ui-2.0.0.jar new file mode 100644 index 0000000..a829d2f Binary files /dev/null and b/lib/springdoc-openapi-starter-webmvc-ui-2.0.0.jar differ diff --git a/lib/swagger-annotations-jakarta-2.2.7.jar b/lib/swagger-annotations-jakarta-2.2.7.jar new file mode 100644 index 0000000..29f10e3 Binary files /dev/null and b/lib/swagger-annotations-jakarta-2.2.7.jar differ diff --git a/lib/swagger-core-jakarta-2.2.7.jar b/lib/swagger-core-jakarta-2.2.7.jar new file mode 100644 index 0000000..a79bc31 Binary files /dev/null and b/lib/swagger-core-jakarta-2.2.7.jar differ diff --git a/lib/swagger-models-jakarta-2.2.7.jar b/lib/swagger-models-jakarta-2.2.7.jar new file mode 100644 index 0000000..723a390 Binary files /dev/null and b/lib/swagger-models-jakarta-2.2.7.jar differ diff --git a/lib/swagger-ui-4.15.5.jar b/lib/swagger-ui-4.15.5.jar new file mode 100644 index 0000000..b9371a1 Binary files /dev/null and b/lib/swagger-ui-4.15.5.jar differ diff --git a/lib/tomcat-embed-core-10.1.8.jar b/lib/tomcat-embed-core-10.1.8.jar new file mode 100644 index 0000000..664ed33 Binary files /dev/null and b/lib/tomcat-embed-core-10.1.8.jar differ diff --git a/lib/tomcat-embed-el-10.1.8.jar b/lib/tomcat-embed-el-10.1.8.jar new file mode 100644 index 0000000..54fde22 Binary files /dev/null and b/lib/tomcat-embed-el-10.1.8.jar differ diff --git a/lib/tomcat-embed-websocket-10.1.8.jar b/lib/tomcat-embed-websocket-10.1.8.jar new file mode 100644 index 0000000..60b2400 Binary files /dev/null and b/lib/tomcat-embed-websocket-10.1.8.jar differ diff --git a/lib/webjars-locator-core-0.52.jar b/lib/webjars-locator-core-0.52.jar new file mode 100644 index 0000000..ae5759b Binary files /dev/null and b/lib/webjars-locator-core-0.52.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..59452b3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.0 + + + com.datao + DataPro + 1.6.0 + DataPro + 数据处理 + + 17 + true + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-undertow + + + com.alibaba + fastjson + 2.0.32 + + + org.jetbrains + annotations + 24.0.1 + compile + + + org.jsoup + jsoup + 1.16.1 + + + com.mysql + mysql-connector-j + 8.2.0 + runtime + + + com.baomidou + mybatis-plus-boot-starter + 3.5.3.1 + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + 4.0.0 + + + org.projectlombok + lombok + true + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + ZIP + + + nothing + nothing + + + + + + + + diff --git a/src/main/java/com/datao/DataProApplication.java b/src/main/java/com/datao/DataProApplication.java new file mode 100644 index 0000000..ea87318 --- /dev/null +++ b/src/main/java/com/datao/DataProApplication.java @@ -0,0 +1,53 @@ +package com.datao; + +import com.datao.config.ScheduleConfig; +import com.datao.controller.DataServiceController; +import com.datao.service.*; +import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.scheduling.annotation.EnableScheduling; + +import javax.sql.DataSource; +import java.util.Arrays; + +@SpringBootApplication +@EnableScheduling +public class DataProApplication implements CommandLineRunner { + public static void main(String[] args) { + ConfigurableApplicationContext ac = SpringApplication.run(DataProApplication.class, args); + try { + // ===== 在项目初始化bean后检验数据库连接是否 + DataSource dataSource = (DataSource) ac.getBean("dataSource"); + dataSource.getConnection().close(); + } catch (Exception e) { + e.printStackTrace(); + // ===== 当检测数据库连接失败时, 停止项目启动 + System.exit(-1); + } + + ScheduleConfig schedule = ac.getBean(ScheduleConfig.class); + schedule.checkAutoScan(); + + if(Arrays.asList(args).contains("vhour")){ + Thread th = new HourThreadService(ac.getBean(MatchService.class), + ac.getBean(OurateService.class), + ac.getBean(OustatService.class)); + th.start(); + } + } + + @Autowired + private DataServiceController controller; + + @Override + public void run(String... args) throws Exception { + controller.startService(); + } +} + diff --git a/src/main/java/com/datao/config/MpConfig.java b/src/main/java/com/datao/config/MpConfig.java new file mode 100644 index 0000000..7ff2d71 --- /dev/null +++ b/src/main/java/com/datao/config/MpConfig.java @@ -0,0 +1,16 @@ +package com.datao.config; + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MpConfig { + @Bean // MP 3.5.2版格式 + public MybatisPlusInterceptor paginationInterceptor() { + MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor(); + mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); + return mpInterceptor; + } +} diff --git a/src/main/java/com/datao/config/PassToken.java b/src/main/java/com/datao/config/PassToken.java new file mode 100644 index 0000000..1b8db1a --- /dev/null +++ b/src/main/java/com/datao/config/PassToken.java @@ -0,0 +1,11 @@ +package com.datao.config; + +import java.lang.annotation.*; + +@Documented +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface PassToken { + boolean value() default true; +} + diff --git a/src/main/java/com/datao/config/ScheduleConfig.java b/src/main/java/com/datao/config/ScheduleConfig.java new file mode 100644 index 0000000..30368f6 --- /dev/null +++ b/src/main/java/com/datao/config/ScheduleConfig.java @@ -0,0 +1,64 @@ +package com.datao.config; + +import com.datao.domain.Scan; +import com.datao.service.FetchService; +import com.datao.service.ScanService; +import net.sf.jsqlparser.expression.DateTimeLiteralExpression; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; +import static java.lang.Thread.sleep; + +@Component +public class ScheduleConfig { + @Autowired + private ScanService scanService; + @Autowired + private FetchService fetchService; + + @Scheduled(cron = "0 0 7 * * ?") +// @Scheduled(cron = "0 0/1 * * * ?") + public void checkAutoScan(){ + Date now = new Date(); + System.out.println("[" + now + "] checkAutoScan started"); + List newScans = scanService.listAutoScan(); + for(int i=0; i hashMap = new HashMap<>(); + String token = request.getHeader("Authorization"); + if((token == null || token.isEmpty()) + && method.isAnnotationPresent(PassToken.class)) { //带有PassToken注解的方法不处理 + return true; + } + +// String msg = ""; +// try { +// if(token != null && token!="") { +// TokenUtil.verifyToken(token.substring(7)); +// return true; +// } +// else{ +// msg = "token无效"; +// } +// }catch (SignatureVerificationException e){ +//// e.printStackTrace(); +// msg = "签名不一致"; +// }catch (TokenExpiredException e){ +//// e.printStackTrace(); +// msg = "令牌过期异常"; +// }catch (AlgorithmMismatchException e) { +//// e.printStackTrace(); +// msg = "算法不匹配异常"; +// }catch (InvalidClaimException e){ +//// e.printStackTrace(); +// msg = "失效的claim异常"; +// }catch (Exception e){ +//// e.printStackTrace(); +// msg = "token无效"; +// } + +// AjaxResult result = new AjaxResult(HttpStatus.UNAUTHORIZED.value(),msg); +// +// String resultJson = JSON.toJSONString(result); +// response.setContentType("application/json;charset=utf-8"); +// response.getWriter().print(resultJson); + return false; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { +// System.out.println("postHandle"); + HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, + Object handler, Exception ex) throws Exception { +// System.out.println("afterCompletion"); + HandlerInterceptor.super.afterCompletion(request, response, handler, ex); + } +} diff --git a/src/main/java/com/datao/config/TokenWebMvcConfigurer.java b/src/main/java/com/datao/config/TokenWebMvcConfigurer.java new file mode 100644 index 0000000..41d9d5f --- /dev/null +++ b/src/main/java/com/datao/config/TokenWebMvcConfigurer.java @@ -0,0 +1,50 @@ +package com.datao.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +//import javax.annotation.Resource; +import java.util.ArrayList; + +//配置拦截事件 +//@Configuration +public class TokenWebMvcConfigurer implements WebMvcConfigurer { + + @Autowired + private TokenInterceptor tokenInterceptor; + + /** + * 配置跨域请求 + * + * @param registry + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + //定义哪些URL接受跨域 + registry.addMapping("/**") + //定义哪些origin可以跨域请求 +// .allowedOrigins("*") + .allowedOriginPatterns("*") + //定义接受的跨域请求方法 + .allowedMethods("POST", "GET", "PUT", "DELETE") + .exposedHeaders("Set-Token") + .allowCredentials(true) + .allowedHeaders("*") + .maxAge(3600); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + ArrayList list = new ArrayList<>(); + list.add("/error"); +// list.add("/Api/**"); + + registry.addInterceptor(tokenInterceptor) + .addPathPatterns("/**") + .excludePathPatterns(list); + } +} + diff --git a/src/main/java/com/datao/controller/DataServiceController.java b/src/main/java/com/datao/controller/DataServiceController.java new file mode 100644 index 0000000..78fac61 --- /dev/null +++ b/src/main/java/com/datao/controller/DataServiceController.java @@ -0,0 +1,246 @@ +package com.datao.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.datao.domain.*; +import com.datao.result.PageResult; +import com.datao.result.Result; +import com.datao.service.*; +import com.datao.vo.*; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@RestController +@RequiredArgsConstructor +public class DataServiceController { + private final FetchService fetchService; + private final ScanService scanService; + private final MatchService matchService; + private final OurateService rateService; + private final OustatService oustatService; + private final GameService gameService; + private final TeamService teamService; +// private final PredMatchService predMatchService; +// private final PredWjrulesService predWjRulesService; + + private DataThreadService thread = null; +// private static String startServiceTime = ""; +// private static String stopServiceTime = ""; +// private static String lastScanTime = ""; + + @GetMapping("/startService") + public Result startService() { + int res = 1; + if(thread == null){ + thread = new DataThreadService(fetchService,scanService,matchService, + rateService,oustatService);//,predMatchService,predWjRulesService); + thread.start(); + } + else{ + if(thread.isInterrupted()){ + thread = null; + res = -1; + } + } + + return Result.success(new ServiceVo(res)); + } + + @GetMapping("/stopService") + public Result stopService() { + int res = 0; + if(thread != null) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException e) { +// result = e.getMessage(); + e.printStackTrace(); + res = -1; + } + thread = null; + } + + return Result.success(new ServiceVo(res)); + } + + @GetMapping("/checkService") + public Result checkService() { + int res = 1; + if(thread == null){ + res = 0; + } + else{ + if(thread.isInterrupted()) { + res = -1; + } + } + + return Result.success(new ServiceVo(res)); + } + + @GetMapping("/scan") + public PageResult getScanPage(@ParameterObject BasePageQuery query) { + IPage page = scanService.page( + new Page<>(query.getPageNum(), query.getPageSize()), + new LambdaQueryWrapper() + .orderByDesc(Scan::getState) + .orderByDesc(Scan::getSeason) + .orderByAsc(Scan::getGid) + .orderByAsc(Scan::getSubid) + ); + return PageResult.success(page); + } + + @PutMapping("/scan") + public Result updateScan(@RequestBody @Validated Scan scanData) { + boolean result = scanService.updateById(scanData); + return Result.judge(result); + } + + @PostMapping("/scan") + public Result addScan(@RequestBody @Validated Scan scanData) { + boolean result = scanService.save(scanData); + return Result.judge(result); + } + + @GetMapping("/game") + public PageResult getGamePage(@ParameterObject BasePageQuery query) { + IPage page = gameService.page(new Page<>(query.getPageNum(), query.getPageSize()), + new QueryWrapper().orderByAsc("gid")); + return PageResult.success(page); + } + + @PostMapping("/game") + public Result saveGame(@RequestBody @Validated Game gameData) { + boolean result = gameService.saveOrUpdate(gameData); + return Result.judge(result); + } + + private QueryWrapper buildWrapper(OUStatQuery query){ + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.ge(ObjectUtils.isNotEmpty(query.getDtstart()),"time",query.getDtstart()) + .le(ObjectUtils.isNotEmpty(query.getDtend()),"time",query.getDtend()) + .eq(ObjectUtils.isNotEmpty(query.getIhand()),"ihand",query.getIhand()) + .eq(ObjectUtils.isNotEmpty(query.getEhand()),"ehand",query.getEhand()) + .eq(ObjectUtils.isNotEmpty(query.getHname()),"th.name",query.getHname()) + .in(ObjectUtils.isNotEmpty(query.getGids()),"g.gid", (Object[]) query.getGids()); + + if(ObjectUtils.isNotEmpty(query.getIorate())){ + wrapper.ge("iorate", query.getIorate() - query.getFluct()) + .le("iorate", query.getIorate() + query.getFluct()); + } + if(ObjectUtils.isNotEmpty(query.getIurate())){ + wrapper.ge("iurate", query.getIurate() - query.getFluct()) + .le("iurate", query.getIurate() + query.getFluct()); + } + if(ObjectUtils.isNotEmpty(query.getEorate())){ + wrapper.ge("eorate", query.getEorate() - query.getFluct()) + .le("eorate", query.getEorate() + query.getFluct()); + } + if(ObjectUtils.isNotEmpty(query.getEurate())){ + wrapper.ge("eurate", query.getEurate() - query.getFluct()) + .le("eurate", query.getEurate() + query.getFluct()); + } + if(ObjectUtils.isNotEmpty(query.getGoal())){ + String cmp = (query.getGoal()<5 ? "=" : ">="); + wrapper.apply("(hgoal+agoal)" + cmp + "{0}", query.getGoal()); + } + if(ObjectUtils.isNotEmpty(query.getChgnum())){ + String cmp = (query.getChgnum()<5 ? "=" : ">="); + wrapper.apply("chgnum" + cmp + "{0}", query.getChgnum()); + } + if(ObjectUtils.isNotEmpty(query.getVhour()) && query.getVhour()>0){ + int hrMax = query.getVhour() + query.getVhfluct() * 100, + hrMin = query.getVhour() - query.getVhfluct() * 100; + wrapper.isNotNull("vhour") + .ge("vhour", Math.max(hrMin, 0)) + .le("vhour", hrMax ); + } + + return wrapper; + } + + @PostMapping("/oustat") + public Result getOUStat(@RequestBody @Validated OUStatQuery query) { + QueryWrapper wrapper = buildWrapper(query); + wrapper.apply("LENGTH(hgoal)>0"); //只计算完场比赛 + + OUStatVo stat = matchService.getOUStat(wrapper); + return Result.success(stat); + } + + @PostMapping("/ouinfos") + public PageResult getOUInfoPage(@RequestBody @Validated OUInfoQuery query) { + QueryWrapper wrapper = buildWrapper(query); + wrapper.orderByDesc("time"); + + IPage page = matchService.getOUInfo(new Page<>(query.getPageNum(), query.getPageSize()), wrapper); + return PageResult.success(page); + } + + @GetMapping("/dbinfo") + public Result getDBInfo(){ + DBInfoVo dbInfo = new DBInfoVo(); + + dbInfo.setGameNum( (int)gameService.count() ); + dbInfo.setTeamNum( (int)teamService.count() ); + dbInfo.setMatchNum(matchService.getMatchCount()); + + Map map = matchService.getMap(new QueryWrapper().select("min(time) as dtMin, max(time) as dtMax")); + LocalDateTime dt = LocalDateTime.ofEpochSecond((Integer) map.get("dtMin"), 0, ZoneOffset.ofHours(8)); + dbInfo.setYearStart( dt.getYear() ); + dt = LocalDateTime.ofEpochSecond((Integer) map.get("dtMax"), 0, ZoneOffset.ofHours(8)); + dbInfo.setYearEnd( dt.getYear() ); + + return Result.success(dbInfo); + } + + @GetMapping("/ourate/{id}") + public Result getOurate(@Parameter @PathVariable Integer id){ + Ourate rate = rateService.getById(id); + return Result.success(rate); + } + +// @GetMapping("/predmatches") +// public Result> getPredMatches(@RequestParam(required=false) Integer sid){ +// List list = new ArrayList<>(); +// +// if(sid==null) +// sid = 20; +// +// LambdaQueryWrapper wrapper = sid==21 ? new LambdaQueryWrapper().gt(PredMatch::getWjstate, 0) +// : new LambdaQueryWrapper().eq(PredMatch::getState, 1); +// List matches = predMatchService.list(wrapper); +// for(PredMatch m : matches){ +// PredMatchVo vo = new PredMatchVo(); +// vo.setMid( m.getMid() ); +// vo.setLname( m.getLname() ); +// vo.setTime( m.getTime() ); +// vo.setHname( m.getHname() ); +// vo.setGname( m.getGname() ); +// vo.setPred( sid==21 ? m.getWjstate() : m.getPred() ); +// +// list.add( vo ); +// } +// +// return Result.success(list); +// } +} diff --git a/src/main/java/com/datao/dao/GameDao.java b/src/main/java/com/datao/dao/GameDao.java new file mode 100644 index 0000000..5af7a97 --- /dev/null +++ b/src/main/java/com/datao/dao/GameDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.Game; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface GameDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/MatchDao.java b/src/main/java/com/datao/dao/MatchDao.java new file mode 100644 index 0000000..1535733 --- /dev/null +++ b/src/main/java/com/datao/dao/MatchDao.java @@ -0,0 +1,56 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.datao.domain.Match; +import com.datao.vo.OUInfoVo; +import com.datao.vo.OUStatVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +@Mapper +public interface MatchDao extends BaseMapper { + String SELECTGOALS_SQL = """ + SELECT COUNT(*) total, + COUNT(hgoal+agoal=0 OR NULL) num0, + COUNT(hgoal+agoal=1 OR NULL) num1, + COUNT(hgoal+agoal=2 OR NULL) num2, + COUNT(hgoal+agoal=3 OR NULL) num3, + COUNT(hgoal+agoal=4 OR NULL) num4, + COUNT(hgoal+agoal>=5 OR NULL) num5 + FROM dg_match m + INNER JOIN dg_oustat s ON m.id=s.id + INNER JOIN dg_game g ON m.gid=g.gid + INNER JOIN dg_team th ON m.hid=th.id + ${ew.customSqlSegment}"""; + + String SELECTOUINFO_SQL = """ + SELECT m.id, g.abbr gname, time, sub, season, th.`name` hname, ta.`name` aname, + hgoal, agoal, ihand, iorate, iurate, ehand, eorate, eurate, chgnum, vhour, m.state + FROM dg_match m + INNER JOIN dg_oustat s ON m.id=s.id + INNER JOIN dg_game g ON m.gid=g.gid + INNER JOIN dg_team th ON m.hid=th.id + INNER JOIN dg_team ta ON m.aid=ta.id + ${ew.customSqlSegment}"""; + + String SELECTMATCHCOUNT_SQL = """ + SELECT count(m.id) + FROM dg_match m + INNER JOIN dg_oustat s ON m.id=s.id + INNER JOIN dg_game g ON m.gid=g.gid + """; + + @Select(SELECTGOALS_SQL) + OUStatVo selectGoals(@Param(Constants.WRAPPER) QueryWrapper wrapper); + + @Select(SELECTOUINFO_SQL) + IPage selectOUInfo(Page page, @Param(Constants.WRAPPER) QueryWrapper wrapper); + + @Select(SELECTMATCHCOUNT_SQL) + Integer selectMatchCount(); +} diff --git a/src/main/java/com/datao/dao/OurateDao.java b/src/main/java/com/datao/dao/OurateDao.java new file mode 100644 index 0000000..b6b378b --- /dev/null +++ b/src/main/java/com/datao/dao/OurateDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.Ourate; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface OurateDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/OustatDao.java b/src/main/java/com/datao/dao/OustatDao.java new file mode 100644 index 0000000..8088a47 --- /dev/null +++ b/src/main/java/com/datao/dao/OustatDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.Oustat; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface OustatDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/PredLeagueDao.java b/src/main/java/com/datao/dao/PredLeagueDao.java new file mode 100644 index 0000000..79c1c0c --- /dev/null +++ b/src/main/java/com/datao/dao/PredLeagueDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.PredLeague; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PredLeagueDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/PredMatchDao.java b/src/main/java/com/datao/dao/PredMatchDao.java new file mode 100644 index 0000000..53d9e3c --- /dev/null +++ b/src/main/java/com/datao/dao/PredMatchDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.PredMatch; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PredMatchDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/PredTeamDao.java b/src/main/java/com/datao/dao/PredTeamDao.java new file mode 100644 index 0000000..26ef75f --- /dev/null +++ b/src/main/java/com/datao/dao/PredTeamDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.PredTeam; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PredTeamDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/PredWjrulesDao.java b/src/main/java/com/datao/dao/PredWjrulesDao.java new file mode 100644 index 0000000..f2a6b58 --- /dev/null +++ b/src/main/java/com/datao/dao/PredWjrulesDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.PredWjrules; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PredWjrulesDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/dao/ScanDao.java b/src/main/java/com/datao/dao/ScanDao.java new file mode 100644 index 0000000..0ede571 --- /dev/null +++ b/src/main/java/com/datao/dao/ScanDao.java @@ -0,0 +1,31 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.datao.domain.Match; +import com.datao.domain.Scan; +import com.datao.vo.OUStatVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface ScanDao extends BaseMapper { + String AUTOSCAN_SQL = """ + SELECT A.id id, A.gid gid, A.subid subid, A.subgame subgame, A.season season, A.state state + FROM dg_scan A + JOIN ( + SELECT max(season) season, gid + FROM dg_scan + GROUP BY gid + ) C ON A.gid=C.gid AND C.season=A.season + WHERE LENGTH(IFNULL(subgame,''))=0 AND state=-1; + """; + + @Select(AUTOSCAN_SQL) + List listAutoScan(); +} + diff --git a/src/main/java/com/datao/dao/TeamDao.java b/src/main/java/com/datao/dao/TeamDao.java new file mode 100644 index 0000000..86de33a --- /dev/null +++ b/src/main/java/com/datao/dao/TeamDao.java @@ -0,0 +1,9 @@ +package com.datao.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.datao.domain.Team; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface TeamDao extends BaseMapper { +} diff --git a/src/main/java/com/datao/domain/BasePageQuery.java b/src/main/java/com/datao/domain/BasePageQuery.java new file mode 100644 index 0000000..63bcf18 --- /dev/null +++ b/src/main/java/com/datao/domain/BasePageQuery.java @@ -0,0 +1,17 @@ +package com.datao.domain; + + +import lombok.Data; + +/** + * 基础分页请求对象 + * + * @author haoxr + * @date 2021/2/28 + */ + +@Data +public class BasePageQuery { + private int pageNum = 0; + private int pageSize = 15; +} diff --git a/src/main/java/com/datao/domain/Detail.java b/src/main/java/com/datao/domain/Detail.java new file mode 100644 index 0000000..d69535e --- /dev/null +++ b/src/main/java/com/datao/domain/Detail.java @@ -0,0 +1,9 @@ +package com.datao.domain; + +public class Detail { + public String hand; + public int over; + public int under; + public String time; + public int state; +} diff --git a/src/main/java/com/datao/domain/Game.java b/src/main/java/com/datao/domain/Game.java new file mode 100644 index 0000000..311aacb --- /dev/null +++ b/src/main/java/com/datao/domain/Game.java @@ -0,0 +1,14 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class Game { + @TableId(type = IdType.AUTO) + Integer id; + Integer gid; + String name; + String abbr; +} diff --git a/src/main/java/com/datao/domain/Match.java b/src/main/java/com/datao/domain/Match.java new file mode 100644 index 0000000..5ccccd5 --- /dev/null +++ b/src/main/java/com/datao/domain/Match.java @@ -0,0 +1,20 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class Match { + @TableId(type = IdType.INPUT) + private Integer id; + private Integer gid; + private String season; + private String sub; + private Integer time; + private Integer hid; + private Integer aid; + private Integer hgoal; + private Integer agoal; + private Integer state; +} diff --git a/src/main/java/com/datao/domain/OUInfoQuery.java b/src/main/java/com/datao/domain/OUInfoQuery.java new file mode 100644 index 0000000..4ca4cd9 --- /dev/null +++ b/src/main/java/com/datao/domain/OUInfoQuery.java @@ -0,0 +1,11 @@ +package com.datao.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class OUInfoQuery extends OUStatQuery{ + private int pageNum; + private int pageSize; +} diff --git a/src/main/java/com/datao/domain/OUStatQuery.java b/src/main/java/com/datao/domain/OUStatQuery.java new file mode 100644 index 0000000..b3d1313 --- /dev/null +++ b/src/main/java/com/datao/domain/OUStatQuery.java @@ -0,0 +1,22 @@ +package com.datao.domain; + +import lombok.Data; + +@Data +public class OUStatQuery { + String hname; //主队名 + Integer dtstart;//开始时间 + Integer dtend; //截止时间 + String ihand; //初盘口 + Integer iorate; //初盘大赔 + Integer iurate; //初盘小赔 + String ehand; //早盘口 + Integer eorate; //早盘大赔 + Integer eurate; //早盘小赔 + Integer fluct; //赔率浮动范围 + Integer chgnum; //早动盘次数 + Integer goal; //总进球数 + Integer vhour; //有效时长 + Integer vhfluct;//有效时长浮动 + Integer gids[]; //赛事列表 +} diff --git a/src/main/java/com/datao/domain/Ourate.java b/src/main/java/com/datao/domain/Ourate.java new file mode 100644 index 0000000..6a15eb8 --- /dev/null +++ b/src/main/java/com/datao/domain/Ourate.java @@ -0,0 +1,13 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class Ourate { + @TableId(type = IdType.INPUT) + Integer id; + String rates; + Integer count; +} diff --git a/src/main/java/com/datao/domain/Oustat.java b/src/main/java/com/datao/domain/Oustat.java new file mode 100644 index 0000000..24479e9 --- /dev/null +++ b/src/main/java/com/datao/domain/Oustat.java @@ -0,0 +1,17 @@ +package com.datao.domain; + +import lombok.Data; + +@Data +public class Oustat { + Integer id; + String ihand; + Integer iorate; + Integer iurate; + String ehand; + Integer eorate; + Integer eurate; + Integer chgnum; + Integer vhour; + Integer state; +} diff --git a/src/main/java/com/datao/domain/PredLeague.java b/src/main/java/com/datao/domain/PredLeague.java new file mode 100644 index 0000000..b2dbd27 --- /dev/null +++ b/src/main/java/com/datao/domain/PredLeague.java @@ -0,0 +1,12 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class PredLeague { + @TableId(type = IdType.INPUT) + Integer lid; + String lname; +} diff --git a/src/main/java/com/datao/domain/PredMatch.java b/src/main/java/com/datao/domain/PredMatch.java new file mode 100644 index 0000000..25b67eb --- /dev/null +++ b/src/main/java/com/datao/domain/PredMatch.java @@ -0,0 +1,33 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.v3.oas.models.security.SecurityScheme; +import lombok.Data; + +@Data +public class PredMatch { + @TableId(type = IdType.INPUT) + Integer mid; + Integer lid; + String lname; + Integer htid; + String hname; + Integer gtid; + String gname; + Integer time; + Integer stage; + Integer state; + Integer pred; + Integer wjstate; + + @TableField(exist = false) + Integer hhgoals; //上半场主队进球数 + @TableField(exist = false) + Integer hggoals; //上半场客队进球数 + @TableField(exist = false) + Integer fhgoals; //全场主队进球数 + @TableField(exist = false) + Integer fggoals; //全场客队进球数 +} diff --git a/src/main/java/com/datao/domain/PredTeam.java b/src/main/java/com/datao/domain/PredTeam.java new file mode 100644 index 0000000..36c94d9 --- /dev/null +++ b/src/main/java/com/datao/domain/PredTeam.java @@ -0,0 +1,12 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class PredTeam { + @TableId(type = IdType.INPUT) + Integer tid; + String tname3; +} diff --git a/src/main/java/com/datao/domain/PredWjrules.java b/src/main/java/com/datao/domain/PredWjrules.java new file mode 100644 index 0000000..2ef9967 --- /dev/null +++ b/src/main/java/com/datao/domain/PredWjrules.java @@ -0,0 +1,17 @@ +package com.datao.domain; + +import lombok.Data; + +@Data +public class PredWjrules { + Integer id; + Integer handrq; + Integer handdx; + Integer stage; + Integer oddeven; + Integer pregame; + Integer histprop; + Integer statmatchs; + Integer stathits; + Integer statprop; +} diff --git a/src/main/java/com/datao/domain/Scan.java b/src/main/java/com/datao/domain/Scan.java new file mode 100644 index 0000000..b31f76f --- /dev/null +++ b/src/main/java/com/datao/domain/Scan.java @@ -0,0 +1,16 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class Scan { + @TableId(type = IdType.AUTO) + private Integer id; + private Integer gid; + private Integer subid; + private String subgame; + private String season; + private Integer state; +} diff --git a/src/main/java/com/datao/domain/Team.java b/src/main/java/com/datao/domain/Team.java new file mode 100644 index 0000000..b3081f8 --- /dev/null +++ b/src/main/java/com/datao/domain/Team.java @@ -0,0 +1,13 @@ +package com.datao.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class Team { + @TableId(type = IdType.INPUT) + private Integer id; + private String name; + private String abbr; +} diff --git a/src/main/java/com/datao/result/IResultCode.java b/src/main/java/com/datao/result/IResultCode.java new file mode 100644 index 0000000..9e57e8c --- /dev/null +++ b/src/main/java/com/datao/result/IResultCode.java @@ -0,0 +1,12 @@ +package com.datao.result; + +/** + * @author haoxr + **/ +public interface IResultCode { + + String getCode(); + + String getMsg(); + +} diff --git a/src/main/java/com/datao/result/PageResult.java b/src/main/java/com/datao/result/PageResult.java new file mode 100644 index 0000000..0dc3e2e --- /dev/null +++ b/src/main/java/com/datao/result/PageResult.java @@ -0,0 +1,39 @@ +package com.datao.result; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页响应结构体 + * + * @author haoxr + * @date 2022/2/18 23:29 + */ +@Data +public class PageResult implements Serializable { + private String code; + private ResData data; + private String msg; + + public static PageResult success(IPage page) { + PageResult result = new PageResult(); + result.setCode(ResultCode.SUCCESS.getCode()); + + ResData data = new ResData(); + data.setList(page.getRecords()); + data.setTotal(page.getTotal()); + + result.setData(data); + result.setMsg(ResultCode.SUCCESS.getMsg()); + return result; + } + + @Data + public static class ResData { + private List list; + private long total; + } +} diff --git a/src/main/java/com/datao/result/Result.java b/src/main/java/com/datao/result/Result.java new file mode 100644 index 0000000..b8dc2d9 --- /dev/null +++ b/src/main/java/com/datao/result/Result.java @@ -0,0 +1,73 @@ +package com.datao.result; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 统一响应结构体 + * + * @author haoxr + * @date 2022/1/30 + **/ +@Data +public class Result implements Serializable { + + private String code; + + private T data; + + private String msg; + + public static Result success() { + return success(null); + } + + public static Result success(T data) { + Result result = new Result<>(); + result.setCode(ResultCode.SUCCESS.getCode()); + result.setMsg(ResultCode.SUCCESS.getMsg()); + result.setData(data); + return result; + } + + public static Result failed() { + return result(ResultCode.SYSTEM_EXECUTION_ERROR.getCode(), ResultCode.SYSTEM_EXECUTION_ERROR.getMsg(), null); + } + + public static Result failed(String msg) { + return result(ResultCode.SYSTEM_EXECUTION_ERROR.getCode(), msg, null); + } + + public static Result judge(boolean status) { + if (status) { + return success(); + } else { + return failed(); + } + } + + public static Result failed(IResultCode resultCode) { + return result(resultCode.getCode(), resultCode.getMsg(), null); + } + + public static Result failed(IResultCode resultCode, String msg) { + return result(resultCode.getCode(), msg, null); + } + + private static Result result(IResultCode resultCode, T data) { + return result(resultCode.getCode(), resultCode.getMsg(), data); + } + + private static Result result(String code, String msg, T data) { + Result result = new Result<>(); + result.setCode(code); + result.setData(data); + result.setMsg(msg); + return result; + } + + public static boolean isSuccess(Result result) { + return result != null && ResultCode.SUCCESS.getCode().equals(result.getCode()); + } +} diff --git a/src/main/java/com/datao/result/ResultCode.java b/src/main/java/com/datao/result/ResultCode.java new file mode 100644 index 0000000..7ea6f2c --- /dev/null +++ b/src/main/java/com/datao/result/ResultCode.java @@ -0,0 +1,114 @@ +package com.datao.result; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 响应码枚举 + * + * @author haoxr + * @date 2020-06-23 + **/ +@AllArgsConstructor +@NoArgsConstructor +public enum ResultCode implements IResultCode, Serializable { + + SUCCESS("00000", "ok"), + +// USER_ERROR("A0001", "用户端错误"), +// REPEAT_SUBMIT_ERROR("A0002", "您的请求已提交,请不要重复提交或等待片刻再尝试。"), +// +// USER_LOGIN_ERROR("A0200", "用户登录异常"), +// +// USER_NOT_EXIST("A0201", "用户不存在"), +// USER_ACCOUNT_LOCKED("A0202", "用户账户被冻结"), +// USER_ACCOUNT_INVALID("A0203", "用户账户已作废"), +// +// USERNAME_OR_PASSWORD_ERROR("A0210", "用户名或密码错误"), +// PASSWORD_ENTER_EXCEED_LIMIT("A0211", "用户输入密码次数超限"), +// CLIENT_AUTHENTICATION_FAILED("A0212", "客户端认证失败"), +// +// VERIFY_CODE_TIMEOUT("A0213", "验证码已过期"), +// VERIFY_CODE_ERROR("A0214", "验证码错误"), +// +// TOKEN_INVALID("A0230", "token无效或已过期"), +// TOKEN_ACCESS_FORBIDDEN("A0231", "token已被禁止访问"), +// +// AUTHORIZED_ERROR("A0300", "访问权限异常"), +// ACCESS_UNAUTHORIZED("A0301", "访问未授权"), +// FORBIDDEN_OPERATION("A0302", "演示环境禁止新增、修改和删除数据,请本地部署后测试"), + + + PARAM_ERROR("A0400", "用户请求参数错误"), + RESOURCE_NOT_FOUND("A0401", "请求资源不存在"), + PARAM_IS_NULL("A0410", "请求必填参数为空"), + + USER_UPLOAD_FILE_ERROR("A0700", "用户上传文件异常"), + USER_UPLOAD_FILE_TYPE_NOT_MATCH("A0701", "用户上传文件类型不匹配"), + USER_UPLOAD_FILE_SIZE_EXCEEDS("A0702", "用户上传文件太大"), + USER_UPLOAD_IMAGE_SIZE_EXCEEDS("A0703", "用户上传图片太大"), + + SYSTEM_EXECUTION_ERROR("B0001", "系统执行出错"), + SYSTEM_EXECUTION_TIMEOUT("B0100", "系统执行超时"), + SYSTEM_ORDER_PROCESSING_TIMEOUT("B0100", "系统订单处理超时"), + + SYSTEM_DISASTER_RECOVERY_TRIGGER("B0200", "系统容灾功能被出发"), + FLOW_LIMITING("B0210", "系统限流"), + DEGRADATION("B0220", "系统功能降级"), + + SYSTEM_RESOURCE_ERROR("B0300", "系统资源异常"), + SYSTEM_RESOURCE_EXHAUSTION("B0310", "系统资源耗尽"), + SYSTEM_RESOURCE_ACCESS_ERROR("B0320", "系统资源访问异常"), + SYSTEM_READ_DISK_FILE_ERROR("B0321", "系统读取磁盘文件失败"), + + CALL_THIRD_PARTY_SERVICE_ERROR("C0001", "调用第三方服务出错"), + MIDDLEWARE_SERVICE_ERROR("C0100", "中间件服务出错"), + INTERFACE_NOT_EXIST("C0113", "接口不存在"), + + MESSAGE_SERVICE_ERROR("C0120", "消息服务出错"), + MESSAGE_DELIVERY_ERROR("C0121", "消息投递出错"), + MESSAGE_CONSUMPTION_ERROR("C0122", "消息消费出错"), + MESSAGE_SUBSCRIPTION_ERROR("C0123", "消息订阅出错"), + MESSAGE_GROUP_NOT_FOUND("C0124", "消息分组未查到"), + + DATABASE_ERROR("C0300", "数据库服务出错"), + DATABASE_TABLE_NOT_EXIST("C0311", "表不存在"), + DATABASE_COLUMN_NOT_EXIST("C0312", "列不存在"), + DATABASE_DUPLICATE_COLUMN_NAME("C0321", "多表关联中存在多个相同名称的列"), + DATABASE_DEADLOCK("C0331", "数据库死锁"), + DATABASE_PRIMARY_KEY_CONFLICT("C0341", "主键冲突"); + + @Override + public String getCode() { + return code; + } + + @Override + public String getMsg() { + return msg; + } + + private String code; + + private String msg; + + @Override + public String toString() { + return "{" + + "\"code\":\"" + code + '\"' + + ", \"msg\":\"" + msg + '\"' + + '}'; + } + + + public static ResultCode getValue(String code){ + for (ResultCode value : values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return SYSTEM_EXECUTION_ERROR; // 默认系统执行错误 + } +} diff --git a/src/main/java/com/datao/service/DataThreadService.java b/src/main/java/com/datao/service/DataThreadService.java new file mode 100644 index 0000000..3594824 --- /dev/null +++ b/src/main/java/com/datao/service/DataThreadService.java @@ -0,0 +1,482 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.datao.domain.*; +import io.swagger.v3.oas.models.security.SecurityScheme; +import lombok.Getter; +import org.jsoup.HttpStatusException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.client.RestClientException; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.text.ParseException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.*; + +public class DataThreadService extends Thread { + private final FetchService fetchService; + private final ScanService scanService; + private final MatchService matchService; + private final OurateService ourateService; + private final OustatService oustatService; +// private final PredMatchService predMatchService; +// private final PredWjrulesService predWjRulesService; + + @Getter + private static String lastScanTime = ""; + @Getter + private static String startServiceTime = ""; + @Getter + private static String stopServiceTime = ""; + + public DataThreadService(FetchService fetchService, + ScanService scanService, + MatchService matchService, + OurateService ourateService, + OustatService oustatService +// PredMatchService predMatchService, +// PredWjrulesService predWjRulesService + ){ + this.fetchService = fetchService; + this.scanService = scanService; + this.matchService = matchService; + this.ourateService = ourateService; + this.oustatService = oustatService; +// this.predMatchService = predMatchService; +// this.predWjRulesService = predWjRulesService; + + startServiceTime = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " " + + LocalTime.ofSecondOfDay(LocalTime.now().toSecondOfDay()).format(DateTimeFormatter.ISO_TIME); + lastScanTime = startServiceTime; + stopServiceTime = ""; + } + + private void pastDataProcess() throws Exception { + List scans = scanService.list(new LambdaQueryWrapper().ne(Scan::getState,-1) + .orderByDesc(Scan::getState)); + + System.out.println( "scan leagues size: " + scans.size() ); + int dtExpire = (int)(System.currentTimeMillis() / 1000L) - 864000; + + for(int i=0; i0) sleep(2500); //休息2秒,避免网站警告 + + Scan scan = scans.get(i); + List matches = fetchService.getMatches(scan); + + if (matches.isEmpty()) { //异常 + scan.setState(4); + scanService.updateById(scan); + continue; + } + else if(scan.getState()!=1){ + scan.setState(1); + scanService.updateById(scan); + } + + boolean bOver = true; + for(int j=0; j det = fetchService.getRatios(mid); + Ourate rate = ourateService.getById(mid); + + if (det==null || det.isEmpty()){ + if( match.getState() == -1 && match.getTime()>dtExpire){//比赛过后10天内重获数据 + match.setState(0); + } + } + else if(rate == null || rate.getCount() != det.size()) { + Oustat stat = oustatService.getById(mid); + boolean bSaveStat = stat == null; + boolean bStatis = stat==null || stat.getState()!=-1; + Detail d0 = det.get(0); + + if (stat == null) { + stat = new Oustat(); + stat.setId(mid); + } + else if(!Objects.equals(stat.getIhand(), d0.hand) + || stat.getIorate()!=d0.over + || stat.getIurate()!=d0.under){//设置或修改初盘,初盘数据有可能改变 + bStatis = true; + } + + boolean bSaveRate = false; + if (rate == null) { + rate = new Ourate(); + rate.setId(mid); + bSaveRate = true; + } + + int eMon=0, eDay=0, eHour=11, eMin=5, + oHour=0, oMin=0; + if(bStatis){ //计算早盘时间 + int oMon, oDay; + LocalDateTime dt = LocalDateTime.ofEpochSecond((long) match.getTime(), 0, ZoneOffset.ofHours(8)); + oMon = dt.getMonthValue(); + oDay = dt.getDayOfMonth(); + oHour = dt.getHour(); + oMin = dt.getMinute(); + + if(oHour>=11){ //11:05为最后的早盘数据 + eMon = oMon; + eDay = oDay; + } + else{ + LocalDateTime edt = dt.minusDays(1); + eMon = edt.getMonthValue(); + eDay = edt.getDayOfMonth(); + + oHour += 24; + } + } + + StringBuilder rates = new StringBuilder(); + int iED = 0, change = 0, valHour = -1; + boolean bChkValid = stat.getVhour()==null; //计算有效时长 + boolean bChkChange = true; + boolean bSpan = false; //是否跨年 + for (int k = 0; k < det.size() && !isInterrupted(); k++) { + Detail d = det.get(k); + if(bStatis ) { + String[] hdt = d.time.split(" "); + String[] hmd = hdt[0].split("-"); + String[] hhm = hdt[1].split(":"); + int hMon = Integer.parseInt(hmd[0]); + int hDay = Integer.parseInt(hmd[1]); + int hHour = Integer.parseInt(hhm[0]); + int hMin = Integer.parseInt(hhm[1]); + + if(bChkChange) { + if (k == 0) { + bSpan = hMon > eMon; //跨年 + } else if (bSpan && hMon <= eMon) { + bSpan = false; + } + + if (bSpan || hMon < eMon //跨年或跨月开盘 + || hMon == eMon && hDay < eDay //月份相同,日期小 + || (hDay == eDay && (hHour < eHour //日期相同,小时小 + || hHour == eHour && hMin <= eMin))) { //当日截止时间前 + iED = k; //最后的早盘数据 + + if (k > 0 && !det.get(k - 1).hand.equalsIgnoreCase(d.hand)) { //计算早变盘 + change++; + } + } else { //已过截止时间 + bChkChange = false; + } + } + + if(bChkValid && hMon==eMon && hDay==eDay) { + double sTime = oHour * 100 + oMin, + dTmp = (hHour * 100 + hMin - sTime) * 0.35 + sTime; + valHour = (int)(dTmp - hHour * 100 - hMin * 5.0 / 3 + 0.5); + + bChkValid = false; + } + } + + if (k > 0) { + rates.append(','); + } + rates.append(d.time).append('|') + .append(d.over).append('|') + .append(d.hand).append('|') + .append(d.under).append('|') + .append(d.state); + } + + if(bStatis){ + stat.setIhand(d0.hand); + stat.setIorate(d0.over); + stat.setIurate(d0.under); + + Detail de = det.get(iED); + stat.setEhand(de.hand); + stat.setEorate(de.over); + stat.setEurate(de.under); + stat.setChgnum(change); + + if(valHour!=-1){ + stat.setVhour(valHour); + } + + if(!bChkChange || match.getState()==-1){ + stat.setState(-1); + } + + if(bSaveStat){ + oustatService.save(stat); + } + else { + oustatService.updateById(stat); + } + } + + rate.setRates(rates.toString()); + rate.setCount(det.size()); + if (bSaveRate) { + ourateService.save(rate); + } else { + ourateService.updateById(rate); + } + } + } + + if (dbMatch == null) { + matchService.save(match); + } else { + matchService.updateById(match); + } + + if (match.getState() != -1 && match.getState() !=-10 && match.getState()!=-12) { //完场|取消|腰斩 + bOver = false; + } + } + + scan.setState(bOver ? -1 : 2); //完结或待处理 + scanService.updateById(scan); + } + } + +// private String getTeamName(Integer tid, List list){ +// Optional first = list.stream().filter(a-> Objects.equals(a.getTid(), tid)).findFirst(); +// return first.map(PredTeam::getTname3).orElse(null); +// } + +// public void predictDataProcess() throws IOException, ParseException, InterruptedException { +// //处理队名对照表 +// List tlist = fetchService.getHGTeams(); +// +// //无极预测比赛的规则 +// List wjRules = predWjRulesService.list(new QueryWrapper().orderByAsc("id")); +// +// //处理当日比赛表 +// List mlist = new ArrayList<>(); +// List todayMatches = fetchService.getTodayMatchs(mlist); +// System.out.println("today matches size: " + todayMatches.size()); +// +// //无极预测 +// List lstWj = fetchService.getWjMatches(mlist, wjRules); +// List wjMatches = (List) lstWj.get(0); //选中的比赛 +// List> ruleIds = (List>) lstWj.get(1); //选中比赛对应的规则 +// List wjRuleOut = (List) lstWj.get(2); //排除的比赛 +//// System.out.println("wuji matches size: " + wjMatches.size()); +// +// List updateRules = new ArrayList<>(); //修改的规则 +// +// for(int i=0; i=0) { +// String tname = match.getHname(); +// String tname3 = getTeamName(match.getHtid(), tlist); +// if (tname3 != null && !tname3.isEmpty() && !tname3.equals(tname)) { +// match.setHname(tname3); +// bUpdate = true; +// } +// +// tname = match.getGname(); +// tname3 = getTeamName(match.getGtid(), tlist); +// if (tname3 != null && !tname3.isEmpty() && !tname3.equals(tname)) { +// match.setGname(tname3); +// bUpdate = true; +// } +// +// if( state==0 ){ //未确定 +//// sleep(2500); //休息2.5秒,避免网站警告 +//// +//// Integer pred = fetchService.getOUPredict(mid); +//// if(pred!=null){ +////// System.out.println("[" + mid + "] pred: " + pred); +//// match.setPred( pred ); +//// match.setState(pred==0 ? 2 : 1); +//// +//// bUpdate = true; +//// } +// } +// } +// +// int index = wjMatches.indexOf(mid); +// int oldStage = match.getStage(); +// int oldWjState = match.getWjstate(); +// if(index!=-1){ +// int wjPred = 0; +// List rids = ruleIds.get(index); +// for(Integer id : rids){ +// PredWjrules rule = null; +// for(PredWjrules r : wjRules){ +// if(id.equals(r.getId())){ +// rule = r; +// break; +// } +// } +// +// if(rule!=null) { +// int hf = rule.getStage(); +// if (stage >= 0 && stage <= 3) { //未完场 +// if( (rule.getStatmatchs()<10 || rule.getHistprop() >= rule.getStatprop()) //及时占比小于等于历史占比 +// && (hf > 0 || stage < 2)) { //全场预测或上半场预测 +// int oe = rule.getOddeven(); +// int pg = rule.getPregame(); +// //1=半场双 2=半场单 4=全场双 8=全场单 10=半场双(赛前) 20=半场单(赛前) 40=全场双(赛前) 80=全场单(赛前) +// wjPred |= 1 << ((pg<<2) + (hf << 1) + oe); +// } +// +// if(hf==0 && (oldStage==0 || oldStage==1) && stage>=2 ){ //半场统计 +// int oe = rule.getOddeven(); +// if((m.getHhgoals()+m.getHggoals()) % 2 == oe){ +// rule.setStathits(rule.getStathits()+1); +// } +// +// rule.setStatmatchs(rule.getStatmatchs()+1); +// +// if(!updateRules.contains(rule)) { +// updateRules.add(rule); +// } +// } +// } +// else if(hf==1 && stage==-1 && oldStage>=2){ //全场结束更新统计 +// int oe = rule.getOddeven(); +// if((m.getFhgoals()+m.getFggoals()) % 2 == oe){ +// rule.setStathits(rule.getStathits()+1); +// } +// +// rule.setStatmatchs(rule.getStatmatchs()+1); +// +// if(!updateRules.contains(rule)) { +// updateRules.add(rule); +// } +// } +// } +// } +// +// if( wjPred>oldWjState ){ +// match.setWjstate(wjPred); +// bUpdate = true; +// +//// System.out.println("[" + mid + "] wjPred: " + wjPred); +// } +// } +// else if(wjRuleOut.contains(mid) && oldWjState==0){ +// match.setWjstate(-1); +// bUpdate = true; +// } +// +// if(oldStage!=stage){ +// match.setStage(stage); +// bUpdate = true; +// } +// +// if(bNew){ +// predMatchService.save(match); +// } +// else if(bUpdate){ +// predMatchService.updateById(match); +// } +// } +// +// if(!updateRules.isEmpty()){ +// for (PredWjrules rule : updateRules) { +// double dHits = rule.getStathits(); +// double dMatchs = rule.getStatmatchs(); +// rule.setStatprop((int) ((dHits/dMatchs+0.0005)*1000)); +// } +// +// predWjRulesService.updateBatchById(updateRules); +// System.out.println("update wj rules: " + updateRules.size()); +// } +// +// //清除已过期比赛 +// int dtExpire = (int)(System.currentTimeMillis() / 1000L) - 10800; //3小时过期 +// predMatchService.remove(new LambdaQueryWrapper() +// .lt(PredMatch::getStage,0) +// .or() +// .lt(PredMatch::getTime, dtExpire)); +// } + + @Override + public void run() { + while(!isInterrupted()){ + String tm = LocalTime.ofSecondOfDay(LocalTime.now().toSecondOfDay()).format(DateTimeFormatter.ISO_TIME); + System.out.println("[" + tm + "] " + getName() + " start"); + + lastScanTime = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " " + tm; + + int tmWait = 1800000; //30分钟 + + try { + pastDataProcess(); +// predictDataProcess(); + } catch (InterruptedException e) { + // System.out.println(getName() + " InterruptedException: " + e.getMessage()); + break; + } catch (SocketTimeoutException | ConnectException | ParseException | HttpStatusException e ){ +// tm = LocalTime.ofSecondOfDay(LocalTime.now().toSecondOfDay()).format(DateTimeFormatter.ISO_TIME); + System.out.println("Socket or Connect or Document exception: " + e.getMessage()); + tmWait = 600000; //10分钟后重试 + } catch (Exception e){ +// e.printStackTrace(); + System.out.println("OtherException: " + e.getMessage()); + tmWait = 300000; +// interrupt(); +// break; + } + + try{ + tm = LocalTime.ofSecondOfDay(LocalTime.now().toSecondOfDay()).format(DateTimeFormatter.ISO_TIME); + System.out.println("[" + tm + "] " + getName() + " sleep " + tmWait + "ms"); + Thread.sleep(tmWait); + } catch (InterruptedException e) { +// System.out.println(getName() + " InterruptedException: " + e.getMessage()); + break; + } + } + stopServiceTime = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " " + + LocalTime.ofSecondOfDay(LocalTime.now().toSecondOfDay()).format(DateTimeFormatter.ISO_TIME); + System.out.println(getName() + " exit"); + } +} diff --git a/src/main/java/com/datao/service/FetchService.java b/src/main/java/com/datao/service/FetchService.java new file mode 100644 index 0000000..871c5fa --- /dev/null +++ b/src/main/java/com/datao/service/FetchService.java @@ -0,0 +1,794 @@ +package com.datao.service; + +import com.alibaba.fastjson.JSONArray; +import com.datao.domain.*; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.*; + +import static java.lang.Math.abs; + +@Service +public class FetchService { + @Autowired + private TeamService teamService; + @Autowired + private ScanService scanService; + @Autowired + private PredLeagueService leagueService; + + static private final int[] cupGids = { //杯赛列表 + 67, //欧洲杯 + 75, //世界杯 + 93, //非洲杯 + 95, //亚洲杯 + 103, //欧冠杯 + 113, //欧罗巴杯 + 224, //美洲杯 + 304, //世俱杯 + 648, //亚洲预赛 + 649, //大洋洲预赛 + 650, //欧洲预赛 + 651, //非洲预赛 + 652, //南美洲预赛 + 653, //北美洲预赛 + 892, //世界杯附加赛 + 1864, //欧国联 + 2187, //欧协杯 + }; + +// static private final int[][] ftRules = { //全场无极预测规则 V1.0 +// {9,13,15}, //0 +// {}, //1 +// {6,8,10,11}, //2 +// {8,9,13,14,15}, //3 +// {10,9,11}, //4 +// {10,11,15}, //5 +// {10,14,15,16,17}, //6 +// {10,11,12,13,15,18}, //7 +// {11,12,14,17,18}, //8 +// {10,12,13,20}, //9 +// {12,15,17,18}, //10 +// {}, //11 +// {13,14,21}, //12 +// {18}, //13 +// {15}, //14 +// {17,18,21,22}, //15 +// {}, //16 +// {}, //17 +// {21}, //18 +// {23}, //19 +// {22}, //20 +// {23}, //21 +// {24,26}, //22 +// {25,27}, //23 +// {}, //24 +// {}, //25 +// {}, //26 +// {30}, //27 +// {}, //28 +// {}, //29 +// {32,34}, //30 +// }; + +// static private final int[][] htRules = { //半场无极预测规则 V1.0 +// {12,13,14,15,17}, //0 +// {14}, //1 +// {12,14,15,18}, //2 +// {14,16}, //3 +// {7,15,16}, //4 +// {7,12,15,16}, //5 +// {16,18}, //6 +// {9,10,15,17,18}, //7 +// {11,14,16,17,18}, //8 +// {10,11,12,13,18,20}, //9 +// {13,14,18}, //10 +// {14,15,16,17,18}, //11 +// {15,16,18,21}, //12 +// {17}, //13 +// {17,18,19}, //14 +// {17,18,20,21,22}, //15 +// {17,18,19,20}, //16 +// {21}, //17 +// {20,22}, //18 +// {21,22,24}, //19 +// {23}, //20 +// {22,23}, //21 +// {26}, //22 +// {24,27}, //23 +// {}, //24 +// {26,28}, //25 +// {}, //26 +// {30}, //27 +// {}, //28 +// {}, //29 +// {32}, //30 +// {}, //31 +// {}, //32 +// {35}, //33 +// }; +// static private final int[][] htORules = { //半场单无极预测规则 V2.0 +// {14,15,17}, //0 +// {15}, //1 +// {14,15,16}, //2 +// {14}, //3 +// {8,15,16}, //4 +// {7,16}, //5 +// {8,16,18}, //6 +// {10,15,16,17}, //7 +// {14,16,17,18}, //8 +// {10,11,12,18}, //9 +// {13,15,18}, //10 +// {13,15,17,18}, //11 +// {16,17,19,21}, //12 +// {17,18,19}, //13 +// {17,18,19}, //14 +// {17,20,21}, //15 +// {17,20}, //16 +// {}, //17 +// {20}, //18 +// {22,24}, //19 +// {22}, //20 +// {25}, //21 +// {26}, //22 +// {27}, //23 +// {25}, //24 +// {28}, //25 +// {}, //26 +// {}, //27 +// {}, //28 +// {}, //29 +// {}, //30 +// {}, //31 +// {}, //32 +// {35}, //33 +// }; +// static private final int[][] htOProps = { //半场单历史占比 V2.0 +// {667,500,1000}, //0 +// {571}, //1 +// {519,1000,1000}, //2 +// {552}, //3 +// {504,778,667}, //4 +// {1000,667}, //5 +// {500,1000,1000}, //6 +// {578,563,500,1000}, //7 +// {518,500,1000,1000}, //8 +// {1000,500,591,1000}, //9 +// {541,526,500}, //10 +// {571,579,625,667}, //11 +// {607,571,1000,1000}, //12 +// {700,500,1000}, //13 +// {545,750,667}, //14 +// {556,1000,1000}, //15 +// {1000,667}, //16 +// {}, //17 +// {750}, //18 +// {500,500}, //19 +// {500}, //20 +// {1000}, //21 +// {1000}, //22 +// {1000}, //23 +// {1000}, //24 +// {1000}, //25 +// {}, //26 +// {}, //27 +// {}, //28 +// {}, //29 +// {}, //30 +// {}, //31 +// {}, //32 +// {500}, //33 +// }; + +// static private final int[][] ftORules = { //全场单无极预测规则 V2.0 +// {13,14,15}, //0 +// {13,15}, //1 +// {11,12}, //2 +// {9,13,14,15}, //3 +// {11,14,15}, //4 +// {9,11,15}, //5 +// {9,10,11,14,15,16,17}, //6 +// {9,11,12,13,15,18}, //7 +// {11,12,14,16}, //8 +// {12,13,14}, //9 +// {13,15}, //10 +// {13,15}, //11 +// {13,14,15}, //12 +// {16,18,19}, //13 +// {15,16}, //14 +// {17,18}, //15 +// {19}, //16 +// {20,21}, //17 +// {21,22}, //18 +// {23,24}, //19 +// {22,23}, //20 +// {22,23}, //21 +// {}, //22 +// {25,27}, //23 +// {25}, //24 +// {26}, //25 +// {}, //26 +// {30}, //27 +// {}, //28 +// {}, //29 +// {34}, //30 +// }; +// static private final int[][] ftOProps = { //全场单单历史占比 +// {515,500,1000}, //0 +// {542,500}, //1 +// {492,491}, //2 +// {497,486,526,833}, //3 +// {484,500,667}, //4 +// {517,532,667}, //5 +// {559,534,512,564,647,1000,1000}, //6 +// {667,521,539,543,500,1000}, //7 +// {526,500,532,500}, //8 +// {568,551,500}, //9 +// {516,516}, //10 +// {600,556}, //11 +// {1000,667,533}, //12 +// {556,667,1000}, //13 +// {1000,500}, //14 +// {800,714}, //15 +// {500}, //16 +// {500,500}, //17 +// {667,500}, //18 +// {1000,1000}, //19 +// {750,500}, //20 +// {1000,500}, //21 +// {}, //22 +// {1000,1000}, //23 +// {1000}, //24 +// {1000}, //25 +// {}, //26 +// {1000}, //27 +// {}, //28 +// {}, //29 +// {1000}, //30 +// }; + + public String[] getScanData(Scan scan) throws IOException { + String season = scan.getSeason(); + String url = "http://zq.titan007.com/jsData/matchResult/"; + + Integer gid = scan.getGid(); + if(Arrays.stream(cupGids).anyMatch(gid::equals)) //是否杯赛 + url += season + "/c" + gid; + else + url += season + "/s" + gid; + + if(scan.getSubid() != null){ + url += "_" + scan.getSubid(); + } + LocalDateTime now = LocalDateTime.now(); + url += ".js?version=" + now.format(DateTimeFormatter.BASIC_ISO_DATE) + now.getHour() + now.getMinute(); + + Document doc = Jsoup.connect(url).timeout(15000).ignoreContentType(true).get(); + String str = doc.body().text(); + +// System.out.println(scan.getGid() + "_" + scan.getSubid() + "/" + season);// + " info:"); + + return str.split("; |;\n"); + } + + public void scanSubAvailable(Scan scan) { + String[] data; + try { + data = getScanData(scan); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + for(String variable : data) { + int subType = variable.contains("arrSubLeague") ? 1 +// : variable.contains("arrCupKind") ? 2 + : 0; + if( subType!=0 ){ + String season = scan.getSeason(); + + String[] parts = variable.split("="); + JSONArray ja = JSONArray.parseArray(parts[1]); + +// System.out.println(ja.size() + " subLeagues"); + + for (Object o : ja) { + JSONArray jaSub = (JSONArray) o; + Integer subid = jaSub.getIntValue(0); + + if (!subid.equals(scan.getSubid())) { + Scan subScan = new Scan(); + subScan.setGid(scan.getGid()); + subScan.setSubid(subid); + subScan.setSubgame(jaSub.getString(subType)); + subScan.setSeason(season); + subScan.setState(0); + scanService.save(subScan); + } + } + break; + } + } + } + + public boolean scanAvailable(Scan scan) throws IOException { + String[] data = getScanData(scan); + for(String variable : data) { + if (variable.contains("arrTeam") + || variable.contains("arrSubLeague") +// || variable.contains("arrCupKind") + || variable.contains("jh[")) { + return true; + } + } + + return false; + } + + public List getMatches(Scan scan) throws ParseException, IOException { + List mlist = new ArrayList<>(); + + String season = scan.getSeason(); + String subgame = scan.getSubgame(); + String[] data = getScanData(scan); + for(String variable : data) { + int varType = variable.contains("arrSubLeague") ? 1 +// : variable.contains("arrCupKind") ? 2 + : variable.contains("arrTeam") ? 3 + : variable.contains("jh[") ? 4 + : 0; + if (varType==3){ + String[] parts = variable.split("="); + JSONArray ja = JSONArray.parseArray(parts[1]); + + if(scan.getState()==0) { + System.out.println(ja.size() + " teams"); + } + + for (Object o : ja) { + JSONArray jaTeam = (JSONArray) o; + int id = jaTeam.getIntValue(0); + if(id>77000) + continue; + + Team team = teamService.getById(id); + if (team == null) { + team = new Team(); + team.setId(id); + team.setName(jaTeam.getString(1)); + team.setAbbr(jaTeam.getString(2)); +// System.out.println(team); + teamService.save(team); + } + } + } + else if(varType==4){ + String[] parts = variable.split("="); + JSONArray ja = JSONArray.parseArray(parts[1] + .replaceAll(",,,", ",9,") + .replaceAll(",,",",0,")); + getMatches(ja, mlist, subgame, season); + } + else if(varType!=0){ + String[] parts = variable.split("="); + JSONArray ja = JSONArray.parseArray(parts[1]); + +// System.out.println(ja.size() + " subLeagues"); + + for (Object o : ja) { + JSONArray jaSub = (JSONArray) o; + Integer subid = jaSub.getIntValue(0); + + if (!subid.equals(scan.getSubid())) { + Scan subScan = new Scan(); + subScan.setGid(scan.getGid()); + subScan.setSubid(subid); + subScan.setSubgame(jaSub.getString(varType)); + subScan.setSeason(season); + subScan.setState(0); + scanService.save(subScan); + } + } + } + } + + if(scan.getState()==0) { + System.out.println("total " + mlist.size() + " matches"); + } + + return mlist; + } + + public void getMatches(JSONArray ja, List mlist, String subgame, String season) throws ParseException { + boolean isMatch = ja.size()>=22 && ja.size()<=26; + for (Object o2 : ja) { + if (o2 instanceof JSONArray) { + getMatches((JSONArray) o2, mlist, subgame, season); + isMatch = false; + } + } + + if(isMatch) { + int hid = ja.getInteger(4), aid = ja.getInteger(5); + if(hid>77000 || aid>77000) //未确定球队 + return; + + Match match = new Match(); + match.setSub(subgame); + match.setSeason(season); + match.setId(ja.getInteger(0)); + match.setGid(ja.getInteger(1)); + match.setHid(hid); + match.setAid(aid); + + Integer state = ja.getInteger(2); + if(state==0 && (ja.getFloat(10)==9 || ja.getString(8).isEmpty() )) {//未开盘 + state = -2; + } + + match.setState(state); + + String sTmp = ja.getString(6); + if (!sTmp.isEmpty()) { + String[] aGoal = sTmp.split("-"); + if (aGoal.length == 2) { + match.setHgoal(Integer.parseInt(aGoal[0])); + match.setAgoal(Integer.parseInt(aGoal[1])); + match.setState(-1); + } + } + + sTmp = ja.getString(3); + if (!sTmp.isEmpty()) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + Date date = simpleDateFormat.parse(sTmp); + match.setTime((int) (date.getTime() / 1000L)); + } + +// System.out.println(match); + mlist.add(match); + } + } + + public List getRatios(int id) throws Exception { + List dlist = new ArrayList<>(); + + String url = "https://vip.titan007.com/changeDetail/overunder.aspx?id=" + id + "&companyID=3&l=0"; + + Document doc = Jsoup.connect(url).timeout(15000).ignoreContentType(true).get(); + + //判断是否有效 + if(doc.select("table").size()<2){ +// System.out.println(id + ": get ratios error"); + return null; + } + + Elements els = doc.select("tr[bgcolor='#ffffff']"); + +// System.out.println(id + ": " + els.size() + " ratios"); + + for(int i = els.size()-1; i >=0; i--){ + Element node = els.get(i); + Elements td = node.select("td"); + +// System.out.println(td.get(2).text() + " " + td.get(3).text() + " " + td.get(4).text() +// + " " + td.get(5).text() + " " + td.get(6).text()); + + Detail data = new Detail(); + data.over = (int)((Double.parseDouble(td.get(2).text()) * 100) + 0.5); + data.hand = td.get(3).text(); + data.under = (int)((Double.parseDouble(td.get(4).text()) * 100) + 0.5); + data.time = td.get(5).text(); + data.state = td.get(6).text().equalsIgnoreCase("早") ? 0 : 1; + dlist.add(data); + } + + return dlist; + } + + public List getHGTeams() throws IOException { + List tlist = new ArrayList<>(); + String url = "http://livestatic.titan007.com/vbsxml/alias3.txt?r=007" + System.currentTimeMillis(); + + Document doc = Jsoup.connect(url) + .header("Referer", "http://live.titan007.com/") + .timeout(15000).ignoreContentType(true).get(); + String str = doc.body().text(); + + String[] nameArr = str.split(","); + for (String s : nameArr){ + String[] data = s.split("\\^"); + int tid = Integer.parseInt( data[0] ); + String tname = data[2]; + + PredTeam team = new PredTeam(); + team.setTid( tid ); + team.setTname3( tname ); + + tlist.add( team ); + } + + return tlist; + } + + public List getTodayMatchs(List mids) throws IOException { + List mlist = new ArrayList<>(); + List llist = leagueService.listObjs(null, a -> Integer.valueOf(a.toString())); + + String url = "http://livestatic.titan007.com/vbsxml/bfdata_ut.js?r=007" + + (System.currentTimeMillis() / 1000L) + "000"; + + Document doc = Jsoup.connect(url) + .header("Referer", "http://live.titan007.com/") + .timeout(15000).ignoreContentType(true).get(); + String str = doc.body().text(); + + int pos = str.indexOf("A["); + while (pos>=0){ + if( (pos = str.indexOf("]=\"", pos+2)) >= 0 ){ + int end = str.indexOf("\".split(", pos+3); + if(end>=0){ + String sub = str.substring(pos+3, end); + String[] data = sub.split("\\^"); + int lid = Integer.parseInt( data[45] ); + if( llist.contains(lid) ) { + double hand = 0; + if( !data[46].isEmpty() ) { + hand = Double.parseDouble(data[46]); + } + + if( hand>0 ){ + String[] sTmp = data[11].split(":"); + int hour = Integer.parseInt(sTmp[0]); + int min = Integer.parseInt(sTmp[1]); + + sTmp = data[12].split(","); + int year = Integer.parseInt(sTmp[0]); + int mon = Integer.parseInt(sTmp[1]); + int day = Integer.parseInt(sTmp[2]); + long dt = LocalDateTime.of(year, mon + 1, day, hour, min, 0).toEpochSecond(ZoneOffset.ofHours(8)); + int mid = Integer.parseInt(data[0]); + int htid = Integer.parseInt(data[37]); + int gtid = Integer.parseInt(data[38]); + int stage = Integer.parseInt(data[13]); + int fhg = data[14].isEmpty() ? -1 : Integer.parseInt(data[14]); + int fgg = data[15].isEmpty() ? -1 : Integer.parseInt(data[15]); + int hhg = data[16].isEmpty() ? -1 : Integer.parseInt(data[16]); + int hgg = data[17].isEmpty() ? -1 : Integer.parseInt(data[17]); + + String lname = data[2]; + String hname = data[5]; + String gname = data[8]; + + PredMatch match = new PredMatch(); + match.setMid( mid ); + match.setLid( lid ); + match.setLname( lname ); + match.setHtid( htid ); + match.setHname( hname ); + match.setGname( gname ); + match.setGtid( gtid ); + match.setTime( (int)dt ); + match.setStage( stage ); + match.setHhgoals(hhg); + match.setHggoals(hgg); + match.setFhgoals(fhg); + match.setFggoals(fgg); + mlist.add(match); + mids.add(mid); + } + } + + pos = str.indexOf("A[", end+13); + } + else{ + break; + } + } + else { + break; + } + } + + return mlist; + } + + public List getWjMatches(List mids, List predWjRules) throws IOException { + List inIds = new ArrayList<>(); + List> ruleIds = new ArrayList<>(); + List outIds = new ArrayList<>(); + + String url = "http://livestatic.titan007.com/vbsxml/sbOddsData.js?r=007" + + (System.currentTimeMillis() / 1000L) + "000"; + + Document doc = Jsoup.connect(url) + .header("Referer", "http://live.titan007.com/") + .timeout(15000).ignoreContentType(true).get(); + String str = doc.body().text(); + + int pos1 = str.indexOf("sData["); + while (pos1>=0){ + pos1 += 6; + + int pos2 = str.indexOf("]=[", pos1); + if( pos2>pos1 ){ + String sub = str.substring(pos1, pos2); + Integer mid = Integer.parseInt(sub); + + pos2 += 4; + int pos3 = str.indexOf("]];", pos2); + if(pos3>pos2){ + if(mids.contains(mid)) { + sub = str.substring(pos2, pos3); + String[] data = sub.split("],\\["); + + if (data.length > 5) { + Integer rq = null, dx = null, hrq = null, hdx = null; + + String[] sTmp = data[0].split(",", 9); + String sHand = sTmp[1]; + if (!sHand.isEmpty()) { + rq = abs((int) (Double.parseDouble(sHand) * 4)); + } + + sTmp = data[2].split(",", 9); + sHand = sTmp[1]; + if (!sHand.isEmpty()) { + dx = (int) (Double.parseDouble(sHand) * 4); + } + + sTmp = data[3].split(",", 9); + sHand = sTmp[1]; + if (!sHand.isEmpty()) { + hrq = abs((int) (Double.parseDouble(sHand) * 4)); + } + + sTmp = data[4].split(",", 9); + sHand = sTmp[1]; + if (!sHand.isEmpty()) { + hdx = (int) (Double.parseDouble(sHand) * 4); + } + + List rids = new ArrayList<>(); + int maxrq = -1, maxdx = -1; + if( rq!=null ) + maxrq = rq; + if( hrq!=null && hrq>maxrq) + maxrq = hrq; + if( dx!=null ) + maxdx = dx; + if( hdx!=null && hdx>maxdx ) + maxdx = hdx; + if(maxrq!=-1 && maxdx!=-1) { + for (PredWjrules rules : predWjRules) { + int rStage = rules.getStage(); + int rhrq = rules.getHandrq(); + int rhdx = rules.getHanddx(); + + if(rStage==1 && rq!=null && dx!=null && rhrq==rq && rhdx==dx //全场 + || rStage==0 && hrq!=null && hdx!=null && rhrq==hrq && rhdx==hdx){ //半场 + rids.add(rules.getId()); + } + + if(rhrq>maxrq || rhrq==maxrq && rhdx>maxdx){ //比较完毕 + break; + } + } + } + + if (rids.isEmpty()) { + outIds.add(mid); + } + else{ + inIds.add( mid ); + ruleIds.add( rids ); + } + } + } + + pos1 = str.indexOf("sData[", pos3+3); + } + else{ + break; + } + } + else { + break; + } + } + + List mList = new ArrayList<>(); + mList.add(inIds); + mList.add(ruleIds); + mList.add(outIds); + return mList; + } + + public Integer getOUPredict(Integer mid) throws IOException { + String url = "https://vip.titan007.com/OverDown_n.aspx?id=" + mid; + Document doc = Jsoup.connect(url).timeout(15000).ignoreContentType(true).get(); + + //判断是否有效 + if(doc.select("table#odds").isEmpty() || doc.select("table#odds tr").size()<3){ + System.out.println(mid + ": OverDown error"); + return null; + } + + Elements trs4 = doc.select("tr:has(span[companyid='4'])"); //立博 + Elements trs9 = doc.select("tr:has(span[companyid='9'])"); //威廉希尔 +// Elements trs19 = doc.select("tr:has(span[companyid='19'])"); //Interwet ver1.1取消 + + if(trs4.isEmpty() || trs9.isEmpty()) { //首选2家 ver1.1 || trs1.isEmpty() || trs19.isEmpty()) { //有4个公司盘口 + return null; + } + +// Elements tds1 = trs1.get(0).select("td"); + Elements tds4 = trs4.get(0).select("td"); + Elements tds9 = trs9.get(0).select("td"); +// Elements tds19 = trs19.get(0).select("td"); + +// String hand1 = tds1.get(3).text(); +// String[] ah = hand1.split("/"); +// double fh1 = Double.parseDouble(ah[0]); +// if(ah.length>1){ +// fh1 = (fh1 + Double.parseDouble(ah[1]))/2; +// } + + String hand4 = tds4.get(3).text(); + String hand9 = tds9.get(3).text(); +// String hand19 = tds19.get(3).text(); + + if(!hand4.equals("2.5") || !hand9.equals("2.5")){ // ver1.1取消 || !hand19.equals("2.5")) { //后3个公司初盘都为2.5 + return 0; + } + +// double fo1 = Double.parseDouble( tds1.get(2).text() ); +// double fu1 = Double.parseDouble( tds1.get(4).text() ); + double fo4 = Double.parseDouble( tds4.get(2).text() ); + double fu4 = Double.parseDouble( tds4.get(4).text() ); + double fo9 = Double.parseDouble( tds9.get(2).text() ); + double fu9 = Double.parseDouble( tds9.get(4).text() ); +// double fo19 = Double.parseDouble( tds19.get(2).text() ); +// double fu19 = Double.parseDouble( tds19.get(4).text() ); + + if(fo4>=1.3 && fo9>=1.3) { // ver1.1取消 && abs(fu19-fu4)<=0.15 && abs(fu19-fu9)<=0.15 + // ver1.1取消 && (fh1<2.5 || fo1-fu1>0.15)) + return 2; //小球方向 + } + + if(fu4>=1.3 && fu9>=1.3) { // ver1.1取消 && abs(fo19-fo4)<=0.15 && abs(fo19-fo9)<=0.15 + // ver1.1取消 && (fh1>2.5 || fu1-fo1>0.15)) + Elements trs1 = doc.select("tr:has(span[companyid='1'])"); //ver1.1 澳门 + if(!trs1.isEmpty()){ + Elements tds1 = trs1.get(0).select("td"); + String hand1 = tds1.get(3).text(); + String[] ah = hand1.split("/"); + double fh1 = Double.parseDouble(ah[0]); + if(ah.length>1) { + fh1 = (fh1 + Double.parseDouble(ah[1])) / 2; + } + + if(fh1>=2.5){ + double fo1 = Double.parseDouble( tds1.get(2).text() ); + double fu1 = Double.parseDouble( tds1.get(4).text() ); + if(fo1 { + @Override + public boolean saveOrUpdate(Game entity) { + LambdaQueryWrapper wrap = new LambdaQueryWrapper() + .eq(Game::getGid, entity.getGid()); + + if(count(wrap) > 0) { + return false; + } + + return super.saveOrUpdate(entity); + } +} diff --git a/src/main/java/com/datao/service/HourThreadService.java b/src/main/java/com/datao/service/HourThreadService.java new file mode 100644 index 0000000..f229fe0 --- /dev/null +++ b/src/main/java/com/datao/service/HourThreadService.java @@ -0,0 +1,98 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.datao.domain.Detail; +import com.datao.domain.Match; +import com.datao.domain.Ourate; +import com.datao.domain.Oustat; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; + +@Service +public class HourThreadService extends Thread{ + private final MatchService matchService; + private final OurateService ourateService; + private final OustatService oustatService; + + public HourThreadService(MatchService matchService, OurateService ourateService, OustatService oustatService) { + this.matchService = matchService; + this.ourateService = ourateService; + this.oustatService = oustatService; + } + + @Override + public void run() { + int p = 1, total = 0, count = 0; + System.out.println("Valid hours counting started"); + + while (true) { + IPage page = oustatService.page(new Page<>(p++, 200)); + long num = page.getRecords().size(); + if (num == 0) + break; + + total += num; + + for(int i=0; i=11){ //11:05为最后的早盘数据 + eMon = oMon; + eDay = oDay; + } + else{ + LocalDateTime edt = dt.minusDays(1); + eMon = edt.getMonthValue(); + eDay = edt.getDayOfMonth(); + + oHour += 24; + } + + String[] aRates = rate.getRates().split(","); + + for (int j = 0; j < aRates.length; j++) { + String strTime = aRates[j].split("\\|")[0]; + String[] hdt = strTime.split(" "); + String[] hmd = hdt[0].split("-"); + String[] hhm = hdt[1].split(":"); + int hMon = Integer.parseInt(hmd[0]); + int hDay = Integer.parseInt(hmd[1]); + int hHour = Integer.parseInt(hhm[0]); + int hMin = Integer.parseInt(hhm[1]); + + if(hMon==eMon && hDay==eDay) { + double sTime = oHour * 100 + oMin, + dTmp = (hHour * 100 + hMin - sTime) * 0.35 + sTime; + int valHour = (int)(dTmp - hHour * 100 - hMin * 5.0 / 3 + 0.5); + + stat.setVhour(valHour); + oustatService.updateById(stat); + count++; + break; + } + } + } + } + + System.out.println("Valid hours counting finished.\nTotal: " + total + " Count: " + count); + } +} diff --git a/src/main/java/com/datao/service/MatchService.java b/src/main/java/com/datao/service/MatchService.java new file mode 100644 index 0000000..17ab9a7 --- /dev/null +++ b/src/main/java/com/datao/service/MatchService.java @@ -0,0 +1,26 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.MatchDao; +import com.datao.domain.Match; +import com.datao.vo.OUInfoVo; +import com.datao.vo.OUStatVo; +import jakarta.annotation.Resource; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Service; + +@Service +public class MatchService extends ServiceImpl { + @Resource + private MatchDao matchDao; + + public OUStatVo getOUStat(QueryWrapper wrapper){ return matchDao.selectGoals(wrapper);} + public IPage getOUInfo(Page page, QueryWrapper wrapper){ + return matchDao.selectOUInfo(page, wrapper); + }; + public Integer getMatchCount(){ return matchDao.selectMatchCount();} +} diff --git a/src/main/java/com/datao/service/OurateService.java b/src/main/java/com/datao/service/OurateService.java new file mode 100644 index 0000000..0129c62 --- /dev/null +++ b/src/main/java/com/datao/service/OurateService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.OurateDao; +import com.datao.domain.Ourate; +import org.springframework.stereotype.Service; + +@Service +public class OurateService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/service/OustatService.java b/src/main/java/com/datao/service/OustatService.java new file mode 100644 index 0000000..950ed0d --- /dev/null +++ b/src/main/java/com/datao/service/OustatService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.OustatDao; +import com.datao.domain.Oustat; +import org.springframework.stereotype.Service; + +@Service +public class OustatService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/service/PredLeagueService.java b/src/main/java/com/datao/service/PredLeagueService.java new file mode 100644 index 0000000..1389364 --- /dev/null +++ b/src/main/java/com/datao/service/PredLeagueService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.PredLeagueDao; +import com.datao.domain.PredLeague; +import org.springframework.stereotype.Service; + +@Service +public class PredLeagueService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/service/PredMatchService.java b/src/main/java/com/datao/service/PredMatchService.java new file mode 100644 index 0000000..be64a76 --- /dev/null +++ b/src/main/java/com/datao/service/PredMatchService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.PredMatchDao; +import com.datao.domain.PredMatch; +import org.springframework.stereotype.Service; + +@Service +public class PredMatchService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/service/PredTeamService.java b/src/main/java/com/datao/service/PredTeamService.java new file mode 100644 index 0000000..91f435c --- /dev/null +++ b/src/main/java/com/datao/service/PredTeamService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.PredTeamDao; +import com.datao.domain.PredTeam; +import org.springframework.stereotype.Service; + +@Service +public class PredTeamService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/service/PredWjrulesService.java b/src/main/java/com/datao/service/PredWjrulesService.java new file mode 100644 index 0000000..fde62a9 --- /dev/null +++ b/src/main/java/com/datao/service/PredWjrulesService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.PredWjrulesDao; +import com.datao.domain.PredWjrules; +import org.springframework.stereotype.Service; + +@Service +public class PredWjrulesService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/service/ScanService.java b/src/main/java/com/datao/service/ScanService.java new file mode 100644 index 0000000..46f3378 --- /dev/null +++ b/src/main/java/com/datao/service/ScanService.java @@ -0,0 +1,42 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.ScanDao; +import com.datao.domain.Scan; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ScanService extends ServiceImpl { + @Resource + private ScanDao scanDao; + + @Override + public boolean save(Scan entity) { + LambdaQueryWrapper wrap = new LambdaQueryWrapper() + .eq(Scan::getGid, entity.getGid()) + .eq(Scan::getSeason, entity.getSeason()); + + if (ObjectUtils.isNotEmpty(entity.getSubid())) { + wrap.eq(Scan::getSubid, entity.getSubid()); + } else { + wrap.isNull(Scan::getSubid); + } + + if(count(wrap) > 0) { + return false; + } + + return super.save(entity); + } + + public List listAutoScan() { + return scanDao.listAutoScan(); + } +} diff --git a/src/main/java/com/datao/service/TeamService.java b/src/main/java/com/datao/service/TeamService.java new file mode 100644 index 0000000..e220a24 --- /dev/null +++ b/src/main/java/com/datao/service/TeamService.java @@ -0,0 +1,10 @@ +package com.datao.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.datao.dao.TeamDao; +import com.datao.domain.Team; +import org.springframework.stereotype.Service; + +@Service +public class TeamService extends ServiceImpl { +} diff --git a/src/main/java/com/datao/vo/DBInfoVo.java b/src/main/java/com/datao/vo/DBInfoVo.java new file mode 100644 index 0000000..549bb35 --- /dev/null +++ b/src/main/java/com/datao/vo/DBInfoVo.java @@ -0,0 +1,12 @@ +package com.datao.vo; + +import lombok.Data; + +@Data +public class DBInfoVo { + Integer gameNum; + Integer yearStart; + Integer yearEnd; + Integer teamNum; + Integer matchNum; +} diff --git a/src/main/java/com/datao/vo/OUInfoVo.java b/src/main/java/com/datao/vo/OUInfoVo.java new file mode 100644 index 0000000..b9c5bbf --- /dev/null +++ b/src/main/java/com/datao/vo/OUInfoVo.java @@ -0,0 +1,25 @@ +package com.datao.vo; + +import lombok.Data; + +@Data +public class OUInfoVo { + Integer id; //比赛ID + String gname; //赛事名 + Integer time; //比赛时间 + String sub; //子赛事名 + String season; //赛季 + String hname; //主队名 + String aname; //客队名 + Integer hgoal; //主队进球 + Integer agoal; //客队进球 + String ihand; //初盘口 + Integer iorate; //初盘大赔 + Integer iurate; //初盘小赔 + String ehand; //早盘口 + Integer eorate; //早盘大赔 + Integer eurate; //早盘小赔 + Integer chgnum; //早动盘次数 + Integer vhour; //有效时长 + Integer state; //状态 +} diff --git a/src/main/java/com/datao/vo/OUStatVo.java b/src/main/java/com/datao/vo/OUStatVo.java new file mode 100644 index 0000000..07d680b --- /dev/null +++ b/src/main/java/com/datao/vo/OUStatVo.java @@ -0,0 +1,14 @@ +package com.datao.vo; + +import lombok.Data; + +@Data +public class OUStatVo { + Integer total; + Integer num0; + Integer num1; + Integer num2; + Integer num3; + Integer num4; + Integer num5; +} diff --git a/src/main/java/com/datao/vo/PredMatchVo.java b/src/main/java/com/datao/vo/PredMatchVo.java new file mode 100644 index 0000000..53b0c7d --- /dev/null +++ b/src/main/java/com/datao/vo/PredMatchVo.java @@ -0,0 +1,13 @@ +package com.datao.vo; + +import lombok.Data; + +@Data +public class PredMatchVo { + Integer mid; + String lname; + String hname; + String gname; + Integer time; + Integer pred; +} diff --git a/src/main/java/com/datao/vo/ServiceVo.java b/src/main/java/com/datao/vo/ServiceVo.java new file mode 100644 index 0000000..6b29a1d --- /dev/null +++ b/src/main/java/com/datao/vo/ServiceVo.java @@ -0,0 +1,19 @@ +package com.datao.vo; + +import com.datao.service.DataThreadService; +import lombok.Data; + +@Data +public class ServiceVo { + private Integer state; + private String startTime; + private String stopTime; + private String scanTime; + + public ServiceVo(Integer _state){ + state = _state; + startTime = DataThreadService.getStartServiceTime(); + stopTime = DataThreadService.getStopServiceTime(); + scanTime = DataThreadService.getLastScanTime(); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..8730160 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql:///datao_goal?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=UTF-8 + # url: jdbc:mysql:///software?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=UTF-8 + username: root + password: 168soft.xyz #123456 # + +mybatis-plus: + configuration: +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + map-underscore-to-camel-case: true + global-config: + banner: false + db-config: + logic-delete-field: deleted + logic-delete-value: 1 + logic-not-delete-value: 0 + table-prefix: dg_ + +server: + port: 10081 diff --git a/src/test/java/com/datao/DataoTest.java b/src/test/java/com/datao/DataoTest.java new file mode 100644 index 0000000..525da79 --- /dev/null +++ b/src/test/java/com/datao/DataoTest.java @@ -0,0 +1,91 @@ +package com.datao; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.datao.domain.Match; +import com.datao.domain.Scan; +import com.datao.service.*; +import com.datao.vo.OUInfoVo; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.io.IOException; +import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.*; + + +@SpringBootTest +public class DataoTest { + @Autowired + MatchService matchService; + @Autowired + OurateService ourateService; + @Autowired + OustatService oustatService; + @Autowired + FetchService fetchService; + @Autowired + PredMatchService predMatchService; + @Autowired + PredWjrulesService predWjRulesService; + + @Test + public void test(){ +// QueryWrapper wrapper = new QueryWrapper<>(); +// o.ihand='2.5' AND o.ehand='2.5' AND LENGTH(hgoal)>0 +// wrapper.eq("th.name","蔚山现代"); +// wrapper.eq("s.ihand", "2.5/3"); +// wrapper.eq("s.ehand", "2.5"); +// wrapper.le("s.iorate", 106); +// wrapper.ge("s.iorate", 104); +// IPage page = matchService.getOUInfo(new Page<>(0, 5), wrapper); +// System.out.println(page.getRecords()); + +// Map map = matchService.getMap(new QueryWrapper().select("min(time) as dtMin, max(time) as dtMax")); +// Calendar calendar = Calendar.getInstance(); +// calendar.setTimeInMillis((Integer)map.get("dtMin") * (long)1000); +// System.out.println(calendar); + +// LocalDateTime dt = LocalDateTime.ofEpochSecond((Integer) map.get("dtMin"), 0, ZoneOffset.ofHours(8)); +// System.out.println( dt ); +// dt = LocalDateTime.ofEpochSecond((Integer) map.get("dtMax"), 0, ZoneOffset.ofHours(8)); +// System.out.println( dt.getYear() ); + + try { +// fetchService.getHGTeams(); +// List mlist = new ArrayList<>(); +// fetchService.getTodayMatchs(mlist); +// DataThreadService threadService = new DataThreadService(fetchService,null,null, +// null,null,predMatchService, predWjRulesService); +// threadService.predictDataProcess(); +// Thread th = new HourThreadService(matchService,ourateService,oustatService); +// th.start(); + Scan scan = new Scan(); + scan.setGid(75); + scan.setSeason("2026"); + scan.setState(0); + List matches = fetchService.getMatches(scan); + + if (matches.isEmpty()) { //异常 + scan.setState(4); +// scanService.updateById(scan); +// continue; + } + else if(scan.getState()!=1){ + scan.setState(1); +// scanService.updateById(scan); + } + } catch (IOException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); +// } catch (InterruptedException e) { +// throw new RuntimeException(e); + } + + } +}