24 changed files with 1787 additions and 135 deletions
@ -0,0 +1,374 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||||
|
<version>3.3.2</version> |
||||||
|
<relativePath/> <!-- lookup parent from repository --> |
||||||
|
</parent> |
||||||
|
<groupId>com.biutag</groupId> |
||||||
|
<artifactId>supervision</artifactId> |
||||||
|
<version>0.0.1-SNAPSHOT</version> |
||||||
|
<name>supervision</name> |
||||||
|
<description>长沙公安数据督察</description> |
||||||
|
<url/> |
||||||
|
<licenses> |
||||||
|
<license/> |
||||||
|
</licenses> |
||||||
|
<developers> |
||||||
|
<developer/> |
||||||
|
</developers> |
||||||
|
<scm> |
||||||
|
<connection/> |
||||||
|
<developerConnection/> |
||||||
|
<tag/> |
||||||
|
<url/> |
||||||
|
</scm> |
||||||
|
<properties> |
||||||
|
<java.version>17</java.version> |
||||||
|
</properties> |
||||||
|
<dependencies> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.jfree</groupId> |
||||||
|
<artifactId>jfreechart</artifactId> |
||||||
|
<version>1.5.4</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.deepoove</groupId> |
||||||
|
<artifactId>poi-tl</artifactId> |
||||||
|
<version>1.12.2</version> |
||||||
|
<exclusions> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.apache.poi</groupId> |
||||||
|
<artifactId>poi</artifactId> |
||||||
|
</exclusion> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.apache.poi</groupId> |
||||||
|
<artifactId>poi-ooxml</artifactId> |
||||||
|
</exclusion> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.apache.poi</groupId> |
||||||
|
<artifactId>poi-ooxml-lite</artifactId> |
||||||
|
</exclusion> |
||||||
|
</exclusions> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<optional>true</optional> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- MapStruct 核心依赖 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.mapstruct</groupId> |
||||||
|
<artifactId>mapstruct</artifactId> |
||||||
|
<version>1.5.5.Final</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- MapStruct 编译期处理器 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.mapstruct</groupId> |
||||||
|
<artifactId>mapstruct-processor</artifactId> |
||||||
|
<version>1.5.5.Final</version> |
||||||
|
<scope>provided</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.google.guava</groupId> |
||||||
|
<artifactId>guava</artifactId> |
||||||
|
<version>32.1.2-jre</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-validation</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-data-redis-reactive</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- 达梦数据库驱动 --> |
||||||
|
<!-- 达梦数据库驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.dameng</groupId> |
||||||
|
<artifactId>DmJdbcDriver18</artifactId> |
||||||
|
<version>8.1.3.140</version> |
||||||
|
</dependency> |
||||||
|
<!-- <dependency>--> |
||||||
|
<!-- <groupId>org.springframework.boot</groupId>--> |
||||||
|
<!-- <artifactId>spring-boot-devtools</artifactId>--> |
||||||
|
<!-- <scope>runtime</scope>--> |
||||||
|
<!-- <optional>true</optional>--> |
||||||
|
<!-- </dependency>--> |
||||||
|
|
||||||
|
|
||||||
|
<!-- mysql JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.mysql</groupId> |
||||||
|
<artifactId>mysql-connector-j</artifactId> |
||||||
|
<scope>runtime</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- SQL Server JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.microsoft.sqlserver</groupId> |
||||||
|
<artifactId>mssql-jdbc</artifactId> |
||||||
|
<version>12.8.1.jre11</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>javax.xml.bind</groupId> |
||||||
|
<artifactId>jaxb-api</artifactId> |
||||||
|
<version>2.3.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.sun.xml.bind</groupId> |
||||||
|
<artifactId>jaxb-impl</artifactId> |
||||||
|
<version>2.3.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.sun.xml.bind</groupId> |
||||||
|
<artifactId>jaxb-core</artifactId> |
||||||
|
<version>2.3.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>javax.activation</groupId> |
||||||
|
<artifactId>activation</artifactId> |
||||||
|
<version>1.1.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- gbase数据库 JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.gbase</groupId> |
||||||
|
<artifactId>gbase-jdbc</artifactId> |
||||||
|
<scope>system</scope> |
||||||
|
<version>8.3.81.53-build55.2.1-bin</version> |
||||||
|
<systemPath>${project.basedir}/src/main/resources/lib/gbase-connector-java-8.3.81.53-build52.8-bin.jar</systemPath> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- dm数据库 JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.dameng</groupId> |
||||||
|
<artifactId>DmJdbcDriver18</artifactId> |
||||||
|
<version>8.1.3.140</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- postgresql JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.postgresql</groupId> |
||||||
|
<artifactId>postgresql</artifactId> |
||||||
|
<version>42.7.4</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>druid-spring-boot-starter</artifactId> |
||||||
|
<version>1.2.22</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<optional>true</optional> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.baomidou</groupId> |
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId> |
||||||
|
<version>3.5.7</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>easyexcel</artifactId> |
||||||
|
<version>4.0.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>commons-io</groupId> |
||||||
|
<artifactId>commons-io</artifactId> |
||||||
|
<version>2.17.0</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>cn.hutool</groupId> |
||||||
|
<artifactId>hutool-all</artifactId> |
||||||
|
<version>5.8.29</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>cn.hutool</groupId> |
||||||
|
<artifactId>hutool-core</artifactId> |
||||||
|
<version>5.8.29</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.hutool</groupId> |
||||||
|
<artifactId>hutool-http</artifactId> |
||||||
|
<version>5.8.29</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.baomidou</groupId> |
||||||
|
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId> |
||||||
|
<version>4.3.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.freemarker</groupId> |
||||||
|
<artifactId>freemarker</artifactId> |
||||||
|
<version>2.3.32</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-crypto</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.github.tobato</groupId> |
||||||
|
<artifactId>fastdfs-client</artifactId> |
||||||
|
<version>1.27.2</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!--knife4j--> |
||||||
|
<dependency> |
||||||
|
<groupId>com.github.xiaoymin</groupId> |
||||||
|
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> |
||||||
|
<version>4.1.0</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>fastjson</artifactId> |
||||||
|
<version>2.0.53</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>net.logstash.logback</groupId> |
||||||
|
<artifactId>logstash-logback-encoder</artifactId> |
||||||
|
<version>4.9</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- word转换 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.aspose</groupId> |
||||||
|
<artifactId>aspose-words</artifactId> |
||||||
|
<version>15.8.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- 数字证书 --> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.com.jit</groupId> |
||||||
|
<artifactId>authSDK</artifactId> |
||||||
|
<version>3.0.3</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>commons-httpclient</groupId> |
||||||
|
<artifactId>commons-httpclient</artifactId> |
||||||
|
<version>3.0.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.jsoup</groupId> |
||||||
|
<artifactId>jsoup</artifactId> |
||||||
|
<version>1.17.2</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
</dependencies> |
||||||
|
|
||||||
|
<build> |
||||||
|
<resources> |
||||||
|
<resource> |
||||||
|
<directory>src/main/resources</directory> |
||||||
|
<filtering>false</filtering> |
||||||
|
<!-- 本地跑时改成true,打包时改成false--> |
||||||
|
</resource> |
||||||
|
<resource> |
||||||
|
<directory>src/main/resources</directory> |
||||||
|
<includes> |
||||||
|
<include>application.yml</include> |
||||||
|
</includes> |
||||||
|
<filtering>true</filtering> |
||||||
|
</resource> |
||||||
|
</resources> |
||||||
|
|
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<!--打包跳过测试--> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-surefire-plugin</artifactId> |
||||||
|
<version>3.2.5</version> |
||||||
|
<configuration> |
||||||
|
<skipTests>false</skipTests> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||||
|
<configuration> |
||||||
|
<includeSystemScope>true</includeSystemScope> |
||||||
|
<excludes> |
||||||
|
<exclude> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
</exclude> |
||||||
|
</excludes> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
|
||||||
|
<finalName>supervision</finalName> |
||||||
|
</build> |
||||||
|
|
||||||
|
<profiles> |
||||||
|
<profile> |
||||||
|
<id>local</id> |
||||||
|
<properties> |
||||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||||
|
<profiles.active>local</profiles.active> |
||||||
|
</properties> |
||||||
|
|
||||||
|
<activation> |
||||||
|
<!-- 默认环境 --> |
||||||
|
<activeByDefault>true</activeByDefault> |
||||||
|
</activation> |
||||||
|
</profile> |
||||||
|
<profile> |
||||||
|
<id>dev</id> |
||||||
|
<properties> |
||||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||||
|
<profiles.active>dev</profiles.active> |
||||||
|
</properties> |
||||||
|
</profile> |
||||||
|
<profile> |
||||||
|
<id>prod</id> |
||||||
|
<properties> |
||||||
|
<profiles.active>prod</profiles.active> |
||||||
|
</properties> |
||||||
|
</profile> |
||||||
|
</profiles> |
||||||
|
|
||||||
|
</project> |
||||||
@ -0,0 +1,374 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||||
|
<version>3.3.2</version> |
||||||
|
<relativePath/> <!-- lookup parent from repository --> |
||||||
|
</parent> |
||||||
|
<groupId>com.biutag</groupId> |
||||||
|
<artifactId>supervision</artifactId> |
||||||
|
<version>0.0.1-SNAPSHOT</version> |
||||||
|
<name>supervision</name> |
||||||
|
<description>长沙公安数据督察</description> |
||||||
|
<url/> |
||||||
|
<licenses> |
||||||
|
<license/> |
||||||
|
</licenses> |
||||||
|
<developers> |
||||||
|
<developer/> |
||||||
|
</developers> |
||||||
|
<scm> |
||||||
|
<connection/> |
||||||
|
<developerConnection/> |
||||||
|
<tag/> |
||||||
|
<url/> |
||||||
|
</scm> |
||||||
|
<properties> |
||||||
|
<java.version>17</java.version> |
||||||
|
</properties> |
||||||
|
<dependencies> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.jfree</groupId> |
||||||
|
<artifactId>jfreechart</artifactId> |
||||||
|
<version>1.5.4</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.deepoove</groupId> |
||||||
|
<artifactId>poi-tl</artifactId> |
||||||
|
<version>1.12.2</version> |
||||||
|
<exclusions> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.apache.poi</groupId> |
||||||
|
<artifactId>poi</artifactId> |
||||||
|
</exclusion> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.apache.poi</groupId> |
||||||
|
<artifactId>poi-ooxml</artifactId> |
||||||
|
</exclusion> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.apache.poi</groupId> |
||||||
|
<artifactId>poi-ooxml-lite</artifactId> |
||||||
|
</exclusion> |
||||||
|
</exclusions> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<optional>true</optional> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- MapStruct 核心依赖 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.mapstruct</groupId> |
||||||
|
<artifactId>mapstruct</artifactId> |
||||||
|
<version>1.5.5.Final</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- MapStruct 编译期处理器 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.mapstruct</groupId> |
||||||
|
<artifactId>mapstruct-processor</artifactId> |
||||||
|
<version>1.5.5.Final</version> |
||||||
|
<scope>provided</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.google.guava</groupId> |
||||||
|
<artifactId>guava</artifactId> |
||||||
|
<version>32.1.2-jre</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-validation</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-data-redis-reactive</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- 达梦数据库驱动 --> |
||||||
|
<!-- 达梦数据库驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.dameng</groupId> |
||||||
|
<artifactId>DmJdbcDriver18</artifactId> |
||||||
|
<version>8.1.3.140</version> |
||||||
|
</dependency> |
||||||
|
<!-- <dependency>--> |
||||||
|
<!-- <groupId>org.springframework.boot</groupId>--> |
||||||
|
<!-- <artifactId>spring-boot-devtools</artifactId>--> |
||||||
|
<!-- <scope>runtime</scope>--> |
||||||
|
<!-- <optional>true</optional>--> |
||||||
|
<!-- </dependency>--> |
||||||
|
|
||||||
|
|
||||||
|
<!-- mysql JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.mysql</groupId> |
||||||
|
<artifactId>mysql-connector-j</artifactId> |
||||||
|
<scope>runtime</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- SQL Server JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.microsoft.sqlserver</groupId> |
||||||
|
<artifactId>mssql-jdbc</artifactId> |
||||||
|
<version>12.8.1.jre11</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>javax.xml.bind</groupId> |
||||||
|
<artifactId>jaxb-api</artifactId> |
||||||
|
<version>2.3.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.sun.xml.bind</groupId> |
||||||
|
<artifactId>jaxb-impl</artifactId> |
||||||
|
<version>2.3.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.sun.xml.bind</groupId> |
||||||
|
<artifactId>jaxb-core</artifactId> |
||||||
|
<version>2.3.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>javax.activation</groupId> |
||||||
|
<artifactId>activation</artifactId> |
||||||
|
<version>1.1.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- gbase数据库 JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.gbase</groupId> |
||||||
|
<artifactId>gbase-jdbc</artifactId> |
||||||
|
<scope>system</scope> |
||||||
|
<version>8.3.81.53-build55.2.1-bin</version> |
||||||
|
<systemPath>${project.basedir}/src/main/resources/lib/gbase-connector-java-8.3.81.53-build52.8-bin.jar</systemPath> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- dm数据库 JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.dameng</groupId> |
||||||
|
<artifactId>DmJdbcDriver18</artifactId> |
||||||
|
<version>8.1.3.140</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- postgresql JDBC驱动 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.postgresql</groupId> |
||||||
|
<artifactId>postgresql</artifactId> |
||||||
|
<version>42.7.4</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>druid-spring-boot-starter</artifactId> |
||||||
|
<version>1.2.22</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<optional>true</optional> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.baomidou</groupId> |
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId> |
||||||
|
<version>3.5.7</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>easyexcel</artifactId> |
||||||
|
<version>4.0.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>commons-io</groupId> |
||||||
|
<artifactId>commons-io</artifactId> |
||||||
|
<version>2.17.0</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>cn.hutool</groupId> |
||||||
|
<artifactId>hutool-all</artifactId> |
||||||
|
<version>5.8.29</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>cn.hutool</groupId> |
||||||
|
<artifactId>hutool-core</artifactId> |
||||||
|
<version>5.8.29</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.hutool</groupId> |
||||||
|
<artifactId>hutool-http</artifactId> |
||||||
|
<version>5.8.29</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.baomidou</groupId> |
||||||
|
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId> |
||||||
|
<version>4.3.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.freemarker</groupId> |
||||||
|
<artifactId>freemarker</artifactId> |
||||||
|
<version>2.3.32</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-crypto</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.github.tobato</groupId> |
||||||
|
<artifactId>fastdfs-client</artifactId> |
||||||
|
<version>1.27.2</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!--knife4j--> |
||||||
|
<dependency> |
||||||
|
<groupId>com.github.xiaoymin</groupId> |
||||||
|
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> |
||||||
|
<version>4.1.0</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>fastjson</artifactId> |
||||||
|
<version>2.0.53</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>net.logstash.logback</groupId> |
||||||
|
<artifactId>logstash-logback-encoder</artifactId> |
||||||
|
<version>4.9</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- word转换 --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.aspose</groupId> |
||||||
|
<artifactId>aspose-words</artifactId> |
||||||
|
<version>15.8.0</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- 数字证书 --> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.com.jit</groupId> |
||||||
|
<artifactId>authSDK</artifactId> |
||||||
|
<version>3.0.3</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>commons-httpclient</groupId> |
||||||
|
<artifactId>commons-httpclient</artifactId> |
||||||
|
<version>3.0.1</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.jsoup</groupId> |
||||||
|
<artifactId>jsoup</artifactId> |
||||||
|
<version>1.17.2</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
</dependencies> |
||||||
|
|
||||||
|
<build> |
||||||
|
<resources> |
||||||
|
<resource> |
||||||
|
<directory>src/main/resources</directory> |
||||||
|
<filtering>false</filtering> |
||||||
|
<!-- 本地跑时改成true,打包时改成false--> |
||||||
|
</resource> |
||||||
|
<resource> |
||||||
|
<directory>src/main/resources</directory> |
||||||
|
<includes> |
||||||
|
<include>application.yml</include> |
||||||
|
</includes> |
||||||
|
<filtering>true</filtering> |
||||||
|
</resource> |
||||||
|
</resources> |
||||||
|
|
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<!--打包跳过测试--> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-surefire-plugin</artifactId> |
||||||
|
<version>3.2.5</version> |
||||||
|
<configuration> |
||||||
|
<skipTests>false</skipTests> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||||
|
<configuration> |
||||||
|
<includeSystemScope>true</includeSystemScope> |
||||||
|
<excludes> |
||||||
|
<exclude> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
</exclude> |
||||||
|
</excludes> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
|
||||||
|
<finalName>supervision</finalName> |
||||||
|
</build> |
||||||
|
|
||||||
|
<profiles> |
||||||
|
<profile> |
||||||
|
<id>local</id> |
||||||
|
<properties> |
||||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||||
|
<profiles.active>local</profiles.active> |
||||||
|
</properties> |
||||||
|
|
||||||
|
<activation> |
||||||
|
<!-- 默认环境 --> |
||||||
|
<activeByDefault>true</activeByDefault> |
||||||
|
</activation> |
||||||
|
</profile> |
||||||
|
<profile> |
||||||
|
<id>dev</id> |
||||||
|
<properties> |
||||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||||
|
<profiles.active>dev</profiles.active> |
||||||
|
</properties> |
||||||
|
</profile> |
||||||
|
<profile> |
||||||
|
<id>prod</id> |
||||||
|
<properties> |
||||||
|
<profiles.active>prod</profiles.active> |
||||||
|
</properties> |
||||||
|
</profile> |
||||||
|
</profiles> |
||||||
|
|
||||||
|
</project> |
||||||
@ -0,0 +1,267 @@ |
|||||||
|
-- MySQL 5.7.21:只读诊断脚本,请先选中生产业务库。 |
||||||
|
-- 下面默认查询全部时间、全部单位,与列表初次打开一致。 |
||||||
|
-- 请先返回本文件的版本、行数估计、索引、8 份 EXPLAIN 结果;不要先执行建索引脚本。 |
||||||
|
-- EXPLAIN 不返回业务明细,不代表真实耗时;验证耗时需另行运行实际 SQL。 |
||||||
|
SELECT VERSION(), DATABASE(); |
||||||
|
SELECT TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES |
||||||
|
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME IN ('negative','negative_blame','sup_police','sup_depart','sup_depart_police_size'); |
||||||
|
SHOW INDEX FROM negative; |
||||||
|
SHOW INDEX FROM negative_blame; |
||||||
|
SHOW INDEX FROM sup_police; |
||||||
|
SHOW INDEX FROM sup_depart; |
||||||
|
SHOW INDEX FROM sup_depart_police_size; |
||||||
|
|
||||||
|
SET @beginTime = '1949-01-01 00:00:00'; |
||||||
|
SET @endTime = NOW(); |
||||||
|
|
||||||
|
-- 单位问题库:优化前列表查询(第一页 10 条) |
||||||
|
EXPLAIN |
||||||
|
SELECT |
||||||
|
d.id depart_id, |
||||||
|
d1.short_name parent_depart_name, |
||||||
|
d.short_name depart_name, |
||||||
|
p.police_size, |
||||||
|
p.aux_size, |
||||||
|
count(DISTINCT nb.blameIdCode) verify_police_size, |
||||||
|
count(DISTINCT n.id) verify_size |
||||||
|
FROM sup_depart d |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id |
||||||
|
LEFT JOIN sup_depart_police_size p ON p.depart_id = d.id |
||||||
|
INNER JOIN negative n ON d.id = n.involveDepartId |
||||||
|
LEFT JOIN negative_blame nb ON n.id = nb.negativeId |
||||||
|
WHERE d.level = 3 |
||||||
|
AND n.crtTime BETWEEN @beginTime AND @endTime |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GROUP BY d.id, d1.short_name, d.short_name, p.police_size, p.aux_size |
||||||
|
ORDER BY |
||||||
|
verify_size |
||||||
|
DESC , d.id ASC |
||||||
|
LIMIT 0, 10; |
||||||
|
|
||||||
|
-- 单位问题库:优化前分页总数 |
||||||
|
EXPLAIN |
||||||
|
SELECT count(*) FROM ( |
||||||
|
SELECT |
||||||
|
d.id depart_id, |
||||||
|
d1.short_name parent_depart_name, |
||||||
|
d.short_name depart_name, |
||||||
|
p.police_size, |
||||||
|
p.aux_size, |
||||||
|
count(DISTINCT nb.blameIdCode) verify_police_size, |
||||||
|
count(DISTINCT n.id) verify_size |
||||||
|
FROM sup_depart d |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id |
||||||
|
LEFT JOIN sup_depart_police_size p ON p.depart_id = d.id |
||||||
|
INNER JOIN negative n ON d.id = n.involveDepartId |
||||||
|
LEFT JOIN negative_blame nb ON n.id = nb.negativeId |
||||||
|
WHERE d.level = 3 |
||||||
|
AND n.crtTime BETWEEN @beginTime AND @endTime |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GROUP BY d.id, d1.short_name, d.short_name, p.police_size, p.aux_size |
||||||
|
) counted; |
||||||
|
|
||||||
|
-- 单位问题库:优化后列表查询(第一页 10 条) |
||||||
|
EXPLAIN |
||||||
|
SELECT DISTINCT |
||||||
|
d.id depart_id, |
||||||
|
d1.short_name parent_depart_name, |
||||||
|
d.short_name depart_name, |
||||||
|
p.police_size, |
||||||
|
p.aux_size, |
||||||
|
stats.verify_police_size, |
||||||
|
stats.verify_size |
||||||
|
FROM ( |
||||||
|
SELECT d.id depart_id, |
||||||
|
count(DISTINCT nb.blameIdCode) verify_police_size, |
||||||
|
count(DISTINCT n.id) verify_size |
||||||
|
FROM sup_depart d |
||||||
|
INNER JOIN negative n ON d.id = n.involveDepartId |
||||||
|
LEFT JOIN negative_blame nb ON n.id = nb.negativeId |
||||||
|
WHERE |
||||||
|
d.level = 3 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AND n.crtTime BETWEEN @beginTime AND @endTime |
||||||
|
GROUP BY d.id |
||||||
|
) stats |
||||||
|
INNER JOIN sup_depart d ON d.id = stats.depart_id |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id |
||||||
|
LEFT JOIN sup_depart_police_size p ON p.depart_id = d.id |
||||||
|
ORDER BY |
||||||
|
verify_size |
||||||
|
DESC , d.id ASC |
||||||
|
LIMIT 0, 10; |
||||||
|
|
||||||
|
-- 单位问题库:优化后分页总数 |
||||||
|
EXPLAIN |
||||||
|
SELECT count(*) FROM ( |
||||||
|
SELECT DISTINCT d.id, p.police_size, p.aux_size |
||||||
|
FROM sup_depart d |
||||||
|
LEFT JOIN sup_depart_police_size p ON p.depart_id = d.id |
||||||
|
WHERE |
||||||
|
d.level = 3 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AND EXISTS ( |
||||||
|
SELECT 1 FROM negative n |
||||||
|
WHERE n.involveDepartId = d.id |
||||||
|
AND n.crtTime BETWEEN @beginTime AND @endTime |
||||||
|
) |
||||||
|
) counted; |
||||||
|
|
||||||
|
-- 个人问题库:优化前列表查询(第一页 10 条) |
||||||
|
EXPLAIN |
||||||
|
SELECT |
||||||
|
p.id_code, |
||||||
|
p.NAME, |
||||||
|
p.emp_no, |
||||||
|
p.position, |
||||||
|
p.employment_date, |
||||||
|
p.person_type, |
||||||
|
d.short_name depart_name, |
||||||
|
d.id depart_id, |
||||||
|
d1.short_name parent_depart_name, |
||||||
|
count(DISTINCT n.id) verify_size |
||||||
|
FROM |
||||||
|
sup_police p |
||||||
|
LEFT JOIN sup_depart d ON p.org_id = d.id |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id and d1.level >= 2 |
||||||
|
INNER JOIN negative_blame nb ON p.id_code = nb.blameIdCode AND nb.type = 'personal' |
||||||
|
INNER JOIN negative n ON nb.negativeId = n.id |
||||||
|
WHERE |
||||||
|
p.del = 0 |
||||||
|
AND n.checkStatus IN ('1', '2') |
||||||
|
AND n.processing_status = 'completed' |
||||||
|
AND n.discoveryTime BETWEEN @beginTime AND @endTime |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GROUP BY |
||||||
|
p.id_code, |
||||||
|
p.NAME, |
||||||
|
p.emp_no, |
||||||
|
p.employment_date, |
||||||
|
p.position, |
||||||
|
p.person_type, |
||||||
|
d.short_name, |
||||||
|
d.id, |
||||||
|
d1.short_name |
||||||
|
ORDER BY |
||||||
|
verify_size |
||||||
|
DESC , p.id_code ASC |
||||||
|
LIMIT 0, 10; |
||||||
|
|
||||||
|
-- 个人问题库:优化前分页总数 |
||||||
|
EXPLAIN |
||||||
|
SELECT count(*) FROM ( |
||||||
|
SELECT |
||||||
|
p.id_code, |
||||||
|
p.NAME, |
||||||
|
p.emp_no, |
||||||
|
p.position, |
||||||
|
p.employment_date, |
||||||
|
p.person_type, |
||||||
|
d.short_name depart_name, |
||||||
|
d.id depart_id, |
||||||
|
d1.short_name parent_depart_name, |
||||||
|
count(DISTINCT n.id) verify_size |
||||||
|
FROM |
||||||
|
sup_police p |
||||||
|
LEFT JOIN sup_depart d ON p.org_id = d.id |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id and d1.level >= 2 |
||||||
|
INNER JOIN negative_blame nb ON p.id_code = nb.blameIdCode AND nb.type = 'personal' |
||||||
|
INNER JOIN negative n ON nb.negativeId = n.id |
||||||
|
WHERE |
||||||
|
p.del = 0 |
||||||
|
AND n.checkStatus IN ('1', '2') |
||||||
|
AND n.processing_status = 'completed' |
||||||
|
AND n.discoveryTime BETWEEN @beginTime AND @endTime |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GROUP BY |
||||||
|
p.id_code, |
||||||
|
p.NAME, |
||||||
|
p.emp_no, |
||||||
|
p.employment_date, |
||||||
|
p.position, |
||||||
|
p.person_type, |
||||||
|
d.short_name, |
||||||
|
d.id, |
||||||
|
d1.short_name |
||||||
|
) counted; |
||||||
|
|
||||||
|
-- 个人问题库:优化后列表查询(第一页 10 条) |
||||||
|
EXPLAIN |
||||||
|
SELECT DISTINCT |
||||||
|
p.id_code, p.name, p.emp_no, p.position, p.employment_date, p.person_type, |
||||||
|
d.short_name depart_name, d.id depart_id, d1.short_name parent_depart_name |
||||||
|
, stats.verify_size |
||||||
|
FROM ( |
||||||
|
SELECT nb.blameIdCode, count(DISTINCT n.id) verify_size |
||||||
|
FROM negative n |
||||||
|
INNER JOIN negative_blame nb ON nb.negativeId = n.id |
||||||
|
WHERE |
||||||
|
nb.type = 'personal' |
||||||
|
AND n.checkStatus IN ('1', '2') |
||||||
|
AND n.processing_status = 'completed' |
||||||
|
AND n.discoveryTime BETWEEN @beginTime AND @endTime |
||||||
|
|
||||||
|
GROUP BY nb.blameIdCode |
||||||
|
) stats |
||||||
|
INNER JOIN sup_police p ON p.id_code = stats.blameIdCode |
||||||
|
LEFT JOIN sup_depart d ON p.org_id = d.id |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id AND d1.level >= 2 |
||||||
|
WHERE |
||||||
|
p.del = 0 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ORDER BY verify_size |
||||||
|
DESC , p.id_code ASC |
||||||
|
LIMIT 0, 10; |
||||||
|
|
||||||
|
-- 个人问题库:优化后分页总数 |
||||||
|
EXPLAIN |
||||||
|
SELECT count(*) FROM ( |
||||||
|
SELECT DISTINCT |
||||||
|
p.id_code, p.name, p.emp_no, p.position, p.employment_date, p.person_type, |
||||||
|
d.short_name depart_name, d.id depart_id, d1.short_name parent_depart_name |
||||||
|
|
||||||
|
FROM sup_police p |
||||||
|
LEFT JOIN sup_depart d ON p.org_id = d.id |
||||||
|
LEFT JOIN sup_depart d1 ON d.pid = d1.id AND d1.level >= 2 |
||||||
|
WHERE |
||||||
|
p.del = 0 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AND EXISTS ( |
||||||
|
SELECT 1 FROM negative_blame nb |
||||||
|
INNER JOIN negative n ON nb.negativeId = n.id |
||||||
|
WHERE nb.blameIdCode = p.id_code |
||||||
|
AND |
||||||
|
nb.type = 'personal' |
||||||
|
AND n.checkStatus IN ('1', '2') |
||||||
|
AND n.processing_status = 'completed' |
||||||
|
AND n.discoveryTime BETWEEN @beginTime AND @endTime |
||||||
|
|
||||||
|
) |
||||||
|
) counted; |
||||||
|
|
||||||
@ -0,0 +1,95 @@ |
|||||||
|
-- 单位/个人问题库查询索引,MySQL InnoDB。 |
||||||
|
-- 在目标业务库执行;先核对字段类型、索引长度和剩余磁盘空间。 |
||||||
|
-- 按完整左前缀识别已有等价索引;LOCK=NONE 不支持时会报错,不自动降级为锁表。 |
||||||
|
-- 在低峰期逐条执行,建索引会消耗 I/O;无需删除任何现有索引或业务数据。 |
||||||
|
|
||||||
|
SET @profile_index_sql = IF( |
||||||
|
EXISTS ( |
||||||
|
SELECT 1 FROM ( |
||||||
|
SELECT GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX SEPARATOR ',') AS columns_in_index, |
||||||
|
SUM(SUB_PART IS NOT NULL) AS prefix_parts |
||||||
|
FROM information_schema.STATISTICS |
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'negative' AND INDEX_TYPE = 'BTREE' |
||||||
|
GROUP BY INDEX_NAME |
||||||
|
) existing_indexes |
||||||
|
WHERE prefix_parts = 0 AND (columns_in_index = 'involveDepartId,crtTime' OR columns_in_index LIKE 'involveDepartId,crtTime,%') |
||||||
|
), |
||||||
|
'SELECT ''idx_profile_depart_time: existing equivalent index, skipped'' AS result', |
||||||
|
'ALTER TABLE `negative` ADD INDEX `idx_profile_depart_time` (`involveDepartId`, `crtTime`), ALGORITHM=INPLACE, LOCK=NONE' |
||||||
|
); |
||||||
|
PREPARE profile_index_stmt FROM @profile_index_sql; |
||||||
|
EXECUTE profile_index_stmt; |
||||||
|
DEALLOCATE PREPARE profile_index_stmt; |
||||||
|
|
||||||
|
SET @profile_index_sql = IF( |
||||||
|
EXISTS ( |
||||||
|
SELECT 1 FROM ( |
||||||
|
SELECT GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX SEPARATOR ',') AS columns_in_index, |
||||||
|
SUM(SUB_PART IS NOT NULL) AS prefix_parts |
||||||
|
FROM information_schema.STATISTICS |
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'negative' AND INDEX_TYPE = 'BTREE' |
||||||
|
GROUP BY INDEX_NAME |
||||||
|
) existing_indexes |
||||||
|
WHERE prefix_parts = 0 AND (columns_in_index = 'processing_status,checkStatus,discoveryTime' OR columns_in_index LIKE 'processing_status,checkStatus,discoveryTime,%') |
||||||
|
), |
||||||
|
'SELECT ''idx_profile_verified_time: existing equivalent index, skipped'' AS result', |
||||||
|
'ALTER TABLE `negative` ADD INDEX `idx_profile_verified_time` (`processing_status`, `checkStatus`, `discoveryTime`), ALGORITHM=INPLACE, LOCK=NONE' |
||||||
|
); |
||||||
|
PREPARE profile_index_stmt FROM @profile_index_sql; |
||||||
|
EXECUTE profile_index_stmt; |
||||||
|
DEALLOCATE PREPARE profile_index_stmt; |
||||||
|
|
||||||
|
SET @profile_index_sql = IF( |
||||||
|
EXISTS ( |
||||||
|
SELECT 1 FROM ( |
||||||
|
SELECT GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX SEPARATOR ',') AS columns_in_index, |
||||||
|
SUM(SUB_PART IS NOT NULL) AS prefix_parts |
||||||
|
FROM information_schema.STATISTICS |
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'negative_blame' AND INDEX_TYPE = 'BTREE' |
||||||
|
GROUP BY INDEX_NAME |
||||||
|
) existing_indexes |
||||||
|
WHERE prefix_parts = 0 AND (columns_in_index = 'negativeId,type,blameIdCode' OR columns_in_index LIKE 'negativeId,type,blameIdCode,%') |
||||||
|
), |
||||||
|
'SELECT ''idx_profile_problem_person: existing equivalent index, skipped'' AS result', |
||||||
|
'ALTER TABLE `negative_blame` ADD INDEX `idx_profile_problem_person` (`negativeId`, `type`, `blameIdCode`), ALGORITHM=INPLACE, LOCK=NONE' |
||||||
|
); |
||||||
|
PREPARE profile_index_stmt FROM @profile_index_sql; |
||||||
|
EXECUTE profile_index_stmt; |
||||||
|
DEALLOCATE PREPARE profile_index_stmt; |
||||||
|
|
||||||
|
SET @profile_index_sql = IF( |
||||||
|
EXISTS ( |
||||||
|
SELECT 1 FROM ( |
||||||
|
SELECT GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX SEPARATOR ',') AS columns_in_index, |
||||||
|
SUM(SUB_PART IS NOT NULL) AS prefix_parts |
||||||
|
FROM information_schema.STATISTICS |
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'negative_blame' AND INDEX_TYPE = 'BTREE' |
||||||
|
GROUP BY INDEX_NAME |
||||||
|
) existing_indexes |
||||||
|
WHERE prefix_parts = 0 AND (columns_in_index = 'blameIdCode,type,negativeId' OR columns_in_index LIKE 'blameIdCode,type,negativeId,%') |
||||||
|
), |
||||||
|
'SELECT ''idx_profile_person_problem: existing equivalent index, skipped'' AS result', |
||||||
|
'ALTER TABLE `negative_blame` ADD INDEX `idx_profile_person_problem` (`blameIdCode`, `type`, `negativeId`), ALGORITHM=INPLACE, LOCK=NONE' |
||||||
|
); |
||||||
|
PREPARE profile_index_stmt FROM @profile_index_sql; |
||||||
|
EXECUTE profile_index_stmt; |
||||||
|
DEALLOCATE PREPARE profile_index_stmt; |
||||||
|
|
||||||
|
SET @profile_index_sql = IF( |
||||||
|
EXISTS ( |
||||||
|
SELECT 1 FROM ( |
||||||
|
SELECT GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX SEPARATOR ',') AS columns_in_index, |
||||||
|
SUM(SUB_PART IS NOT NULL) AS prefix_parts |
||||||
|
FROM information_schema.STATISTICS |
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sup_police' AND INDEX_TYPE = 'BTREE' |
||||||
|
GROUP BY INDEX_NAME |
||||||
|
) existing_indexes |
||||||
|
WHERE prefix_parts = 0 AND (columns_in_index = 'id_code,del' OR columns_in_index LIKE 'id_code,del,%') |
||||||
|
), |
||||||
|
'SELECT ''idx_profile_police_identity: existing equivalent index, skipped'' AS result', |
||||||
|
'ALTER TABLE `sup_police` ADD INDEX `idx_profile_police_identity` (`id_code`, `del`), ALGORITHM=INPLACE, LOCK=NONE' |
||||||
|
); |
||||||
|
PREPARE profile_index_stmt FROM @profile_index_sql; |
||||||
|
EXECUTE profile_index_stmt; |
||||||
|
DEALLOCATE PREPARE profile_index_stmt; |
||||||
|
|
||||||
@ -0,0 +1,23 @@ |
|||||||
|
# 单位 / 个人问题库查询优化(MySQL 5.7.21) |
||||||
|
|
||||||
|
## 本次改动 |
||||||
|
|
||||||
|
- 先按单位 ID / 身份证号聚合明细,再连接名称、职务等展示字段,避免在多字段的明细结果上分组。 |
||||||
|
- 分页使用自定义 count SQL,使用 EXISTS 判断是否有符合条件的问题,不再重复统计每个单位的涉及人数或每个人的问题数。 |
||||||
|
- 保留 DISTINCT 去重语义、筛选条件、全量排序后分页及总数。不新增缓存,不降低数据实时性。 |
||||||
|
- 单位仍按问题创建时间统计;个人仍按发现时间、已办结、属实/部分属实及个人责任记录统计,不调整业务口径。 |
||||||
|
|
||||||
|
## 生产核查步骤 |
||||||
|
|
||||||
|
1. 在业务库执行 `20261027_profile_query_explain.sql`,收集版本、表规模估计、索引及优化前后 8 份 EXPLAIN。默认不限时间、不选单位;如果慢请求带筛选条件,应按实际请求补上同样条件。 |
||||||
|
2. 检查 `negative_blame` 是否按 `negativeId` / `blameIdCode` 走索引、`negative` 是否使用对应时间和状态索引,以及连接字段的数据类型和字符集是否一致。小的聚合结果出现临时表或排序不等于优化失败。 |
||||||
|
3. 对照现有索引评估 `20261027_profile_query_indexes.sql`。脚本按完整左前缀跳过已有等价索引,不删除旧索引。先确认 InnoDB、字段长度、磁盘空间和同名索引冲突;低峰期执行。在线建索引仍消耗 I/O 并可能等待元数据锁,LOCK=NONE 不支持时会停止,不降级为锁表。 |
||||||
|
4. 索引准备后部署后端改动,再执行优化后 EXPLAIN 和实际请求。MySQL 5.7 不支持 EXPLAIN ANALYZE;EXPLAIN 的 rows 是估计值,不能用来证明 3 秒达标。 |
||||||
|
5. 性能验收同时计入总数 SQL、列表 SQL、接口开销和网络耗时。分别验证首次请求与重复请求、不限时间与短时间范围、单位/姓名筛选、升降序、后续分页,以及实际并发下的耗时。避免把查询缓存命中误判为 SQL 本身已优化。 |
||||||
|
|
||||||
|
## 验证状态 |
||||||
|
|
||||||
|
- 后端编译、SQL 映射与排序/筛选回归测试已通过。 |
||||||
|
- 本地模拟使用 SQLite 内存数据库及 12 万条问题,属于结果一致性和优化方向验证,不是生产 MySQL 5.7 性能验收。 |
||||||
|
- 开发数据库连接失败;生产索引、执行计划和端到端耗时尚未取得,不能承诺已达到 3 秒。 |
||||||
|
- 索引脚本尚未对任何数据库执行;本次未改前端或运行前端构建。 |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.biutag.supervision.pojo.param; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
@Setter |
||||||
|
public class PoliceProfileQuery { |
||||||
|
private String groupId; |
||||||
|
private String category; |
||||||
|
private String rankName; |
||||||
|
private String rankEmpNo; |
||||||
|
} |
||||||
@ -0,0 +1,97 @@ |
|||||||
|
package com.biutag.supervision.controller; |
||||||
|
|
||||||
|
import com.biutag.supervision.controller.sensitiveperception.ProfileDepartController; |
||||||
|
import com.biutag.supervision.mapper.ProfileDepartMapper; |
||||||
|
import com.biutag.supervision.pojo.entity.Negative; |
||||||
|
import com.biutag.supervision.pojo.entity.NegativeBlame; |
||||||
|
import com.biutag.supervision.pojo.entity.NegativeProblemRelation; |
||||||
|
import com.baomidou.mybatisplus.core.conditions.Wrapper; |
||||||
|
import com.biutag.supervision.service.*; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.junit.jupiter.api.extension.ExtendWith; |
||||||
|
import org.mockito.InjectMocks; |
||||||
|
import org.mockito.Mock; |
||||||
|
import org.mockito.junit.jupiter.MockitoExtension; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||||
|
import static org.mockito.Mockito.*; |
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class) |
||||||
|
class ProfileDepartControllerTest { |
||||||
|
@Mock ProfileDepartMapper mapper; |
||||||
|
@Mock SupDepartService departService; |
||||||
|
@Mock SupPoliceService policeService; |
||||||
|
@Mock NegativeService negativeService; |
||||||
|
@Mock BusinessDepartService businessDepartService; |
||||||
|
@Mock NegativeScoreDepartService scoreService; |
||||||
|
@Mock NegativeProblemRelationService relationService; |
||||||
|
@Mock SupDepartPoliceSizeService sizeService; |
||||||
|
@Mock NegativeBlameService blameService; |
||||||
|
@InjectMocks ProfileDepartController controller; |
||||||
|
|
||||||
|
@Test |
||||||
|
void unscoredProblemsStillCountAndAppearInDetail() { |
||||||
|
Date begin = new Date(0); |
||||||
|
Date end = new Date(); |
||||||
|
Negative first = new Negative(); |
||||||
|
first.setId("first"); |
||||||
|
Negative second = new Negative(); |
||||||
|
second.setId("second"); |
||||||
|
when(mapper.selectDepartProblems("station", begin, end)).thenReturn(List.of(first, second)); |
||||||
|
|
||||||
|
var profile = controller.profile("station", begin, end).getData(); |
||||||
|
|
||||||
|
assertEquals(2, profile.getNegativeInfo().getSize()); |
||||||
|
assertEquals(2, profile.getNegatives().size()); |
||||||
|
assertTrue(profile.getNegatives().stream().allMatch(item -> item.getScore() == null)); |
||||||
|
assertEquals(1, profile.getProblemSourcesList().size()); |
||||||
|
verify(mapper).selectDepartProblems("station", begin, end); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void noProblemsReturnsZeroAndEmptyDetail() { |
||||||
|
var profile = controller.profile("station", new Date(0), new Date()).getData(); |
||||||
|
assertEquals(0, profile.getNegativeInfo().getSize()); |
||||||
|
assertTrue(profile.getNegatives().isEmpty()); |
||||||
|
verifyNoInteractions(scoreService); |
||||||
|
} |
||||||
|
@Test |
||||||
|
void missingGroupingFieldsDoNotBreakDetailOrCreateEmptyRankings() { |
||||||
|
Negative missing = new Negative(); |
||||||
|
missing.setId("missing"); |
||||||
|
Negative blank = new Negative(); |
||||||
|
blank.setId("blank"); |
||||||
|
blank.setProblemSourcesCode(" "); |
||||||
|
blank.setBusinessTypeCode(""); |
||||||
|
when(mapper.selectDepartProblems(eq("station"), any(), any())).thenReturn(List.of(missing, blank)); |
||||||
|
NegativeProblemRelation missingType = new NegativeProblemRelation(); |
||||||
|
missingType.setNegativeId("missing"); |
||||||
|
NegativeProblemRelation blankType = new NegativeProblemRelation(); |
||||||
|
blankType.setNegativeId("blank"); |
||||||
|
blankType.setOneLevelContent(" "); |
||||||
|
when(relationService.list(any(Wrapper.class))).thenReturn(List.of(missingType, blankType)); |
||||||
|
when(blameService.list(any(Wrapper.class))).thenReturn(List.of( |
||||||
|
new NegativeBlame(), |
||||||
|
new NegativeBlame().setBlameEmpNo(" "), |
||||||
|
new NegativeBlame().setBlameEmpNo("001").setBlameName("甲"), |
||||||
|
new NegativeBlame().setBlameEmpNo("002").setBlameName("乙").setLeadEmpNo(" "), |
||||||
|
new NegativeBlame().setBlameEmpNo("003").setBlameName("丙").setLeadEmpNo("100").setLeadName("领导"))); |
||||||
|
|
||||||
|
var profile = assertDoesNotThrow(() -> controller.profile("station", new Date(0), new Date())).getData(); |
||||||
|
|
||||||
|
assertEquals(2, profile.getNegativeInfo().getSize()); |
||||||
|
assertEquals(2, profile.getNegatives().size()); |
||||||
|
for (var items : List.of(profile.getProblemSourcesList(), profile.getBusinessTypeList(), profile.getProblemTypeList())) { |
||||||
|
assertEquals(1, items.size()); |
||||||
|
assertEquals("未分类", items.get(0).getName()); |
||||||
|
assertEquals(2, items.get(0).getValue()); |
||||||
|
} |
||||||
|
assertEquals(3, profile.getPoliceBarList().size()); |
||||||
|
assertEquals(1, profile.getPoliceLeadBarList().size()); |
||||||
|
assertEquals("领导", profile.getPoliceLeadBarList().get(0).getLabel()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
package com.biutag.supervision.controller; |
||||||
|
|
||||||
|
import com.biutag.supervision.controller.sensitiveperception.ProfilePoliceController; |
||||||
|
import com.biutag.supervision.mapper.ProfilePoliceMapper; |
||||||
|
import com.biutag.supervision.pojo.entity.*; |
||||||
|
import com.biutag.supervision.pojo.param.PoliceProfileQuery; |
||||||
|
import com.biutag.supervision.service.*; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.junit.jupiter.api.extension.ExtendWith; |
||||||
|
import org.mockito.InjectMocks; |
||||||
|
import org.mockito.Mock; |
||||||
|
import org.mockito.junit.jupiter.MockitoExtension; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||||
|
import static org.mockito.Mockito.*; |
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class) |
||||||
|
class ProfilePoliceDetailTest { |
||||||
|
@Mock ProfilePoliceMapper mapper; |
||||||
|
@Mock SupPoliceService policeService; |
||||||
|
@Mock BusinessPoliceService businessService; |
||||||
|
@Mock NegativeBlameService blameService; |
||||||
|
@Mock NegativeService negativeService; |
||||||
|
@Mock NegativeScorePoliceService scoreService; |
||||||
|
@Mock NegativeProblemRelationService relationService; |
||||||
|
@InjectMocks ProfilePoliceController controller; |
||||||
|
|
||||||
|
@Test |
||||||
|
void countsUnscoredProblemsAndUsesSameRecordsForDetail() { |
||||||
|
var scope = new PoliceProfileQuery(); |
||||||
|
scope.setCategory("aux"); |
||||||
|
scope.setGroupId("10"); |
||||||
|
when(policeService.getByIdCode("person")).thenReturn(new SupPolice()); |
||||||
|
Negative first = new Negative(); |
||||||
|
first.setId("a"); |
||||||
|
Negative second = new Negative(); |
||||||
|
second.setId("b"); |
||||||
|
second.setProblemSourcesCode(" "); |
||||||
|
when(mapper.selectPoliceProblems(eq("person"), any(), any(), same(scope))) |
||||||
|
.thenReturn(List.of(first, second)); |
||||||
|
var profile = controller.profile("person", new Date(0), new Date(), scope).getData(); |
||||||
|
assertEquals(2, profile.getNegativeInfo().getSize()); |
||||||
|
assertEquals(2, profile.getNegatives().size()); |
||||||
|
assertTrue(profile.getNegatives().stream().allMatch(item -> item.getScore() == null)); |
||||||
|
assertEquals("未分类", profile.getProblemSourcesList().get(0).getName()); |
||||||
|
assertEquals(2, profile.getProblemSourcesList().get(0).getValue()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void emptyProblemsDoNotReadScores() { |
||||||
|
when(policeService.getByIdCode("person")).thenReturn(new SupPolice()); |
||||||
|
var profile = controller.profile("person", new Date(0), new Date(), new PoliceProfileQuery()).getData(); |
||||||
|
assertEquals(0, profile.getNegativeInfo().getSize()); |
||||||
|
assertTrue(profile.getNegatives().isEmpty()); |
||||||
|
verifyNoInteractions(scoreService); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void monthlyTrendUsesCreationTimeAndSameScope() { |
||||||
|
var scope = new PoliceProfileQuery(); |
||||||
|
scope.setCategory("police"); |
||||||
|
scope.setGroupId("11"); |
||||||
|
Negative problem = new Negative(); |
||||||
|
problem.setCrtTime(LocalDateTime.now()); |
||||||
|
problem.setDiscoveryTime(LocalDateTime.now().minusYears(1)); |
||||||
|
when(mapper.selectPoliceProblems(eq("person"), any(), any(), same(scope))).thenReturn(List.of(problem)); |
||||||
|
var result = controller.listByMonth("person", scope).getData(); |
||||||
|
assertEquals(1L, ((List<?>) result.get("values")).get(11)); |
||||||
|
verifyNoInteractions(scoreService, negativeService); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
package com.biutag.supervision.controller; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||||
|
import com.biutag.supervision.controller.sensitiveperception.ProfileDepartController; |
||||||
|
import com.biutag.supervision.controller.sensitiveperception.ProfilePoliceController; |
||||||
|
import com.biutag.supervision.mapper.ProfileDepartMapper; |
||||||
|
import com.biutag.supervision.mapper.ProfilePoliceMapper; |
||||||
|
import com.biutag.supervision.pojo.param.DepartNegativeQueryParam; |
||||||
|
import com.biutag.supervision.pojo.param.DepartPoliceQueryParam; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.junit.jupiter.api.extension.ExtendWith; |
||||||
|
import org.mockito.ArgumentCaptor; |
||||||
|
import org.mockito.InjectMocks; |
||||||
|
import org.mockito.Mock; |
||||||
|
import org.mockito.junit.jupiter.MockitoExtension; |
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||||
|
import static org.mockito.ArgumentMatchers.*; |
||||||
|
import static org.mockito.Mockito.verify; |
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class) |
||||||
|
class ProfileQueryPaginationTest { |
||||||
|
@Mock ProfileDepartMapper departMapper; |
||||||
|
@Mock ProfilePoliceMapper policeMapper; |
||||||
|
@InjectMocks ProfileDepartController departController; |
||||||
|
@InjectMocks ProfilePoliceController policeController; |
||||||
|
|
||||||
|
@Test |
||||||
|
void bothListsUseCustomCountAndKeepPageNumberAndSize() { |
||||||
|
DepartNegativeQueryParam depart = new DepartNegativeQueryParam(); |
||||||
|
depart.setCurrent(2); |
||||||
|
depart.setSize(18); |
||||||
|
departController.list(depart); |
||||||
|
ArgumentCaptor<Page> departPage = ArgumentCaptor.forClass(Page.class); |
||||||
|
verify(departMapper).queryDepartNegative(departPage.capture(), any(), any(), isNull(), isNull(), isNull(), isNull(), isNull()); |
||||||
|
assertEquals("com.biutag.supervision.mapper.ProfileDepartMapper.countDepartNegative", departPage.getValue().countId()); |
||||||
|
assertEquals(2, departPage.getValue().getCurrent()); |
||||||
|
assertEquals(18, departPage.getValue().getSize()); |
||||||
|
|
||||||
|
DepartPoliceQueryParam police = new DepartPoliceQueryParam(); |
||||||
|
police.setCurrent(3); |
||||||
|
police.setSize(9); |
||||||
|
policeController.list(police); |
||||||
|
ArgumentCaptor<Page> policePage = ArgumentCaptor.forClass(Page.class); |
||||||
|
verify(policeMapper).queryPoliceNegative(policePage.capture(), any(), any(), isNull(), isNull(), isNull(), isNull(), isNull()); |
||||||
|
assertEquals("com.biutag.supervision.mapper.ProfilePoliceMapper.countPoliceNegative", policePage.getValue().countId()); |
||||||
|
assertEquals(3, policePage.getValue().getCurrent()); |
||||||
|
assertEquals(9, policePage.getValue().getSize()); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,94 @@ |
|||||||
|
package com.biutag.supervision.mapper; |
||||||
|
|
||||||
|
import org.apache.ibatis.builder.xml.XMLMapperBuilder; |
||||||
|
import org.apache.ibatis.session.Configuration; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||||
|
|
||||||
|
class ProfileDepartMapperTest { |
||||||
|
@Test |
||||||
|
void screenListAndDetailUseSameProblemScope() throws Exception { |
||||||
|
Configuration configuration = new Configuration(); |
||||||
|
for (String resource : new String[]{"mapper/ProfileDepartMapper.xml", "mapper/StatisticsGroupMapper.xml"}) { |
||||||
|
try (var input = getClass().getClassLoader().getResourceAsStream(resource)) { |
||||||
|
new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); |
||||||
|
} |
||||||
|
} |
||||||
|
for (String id : new String[]{"ProfileDepartMapper.queryDepartNegative", |
||||||
|
"ProfileDepartMapper.selectDepartProblems", "StatisticsGroupMapper.selectNegativeStatisticsByThree"}) { |
||||||
|
String sql = configuration.getMappedStatement("com.biutag.supervision.mapper." + id) |
||||||
|
.getBoundSql(new HashMap<>()).getSql().replaceAll("\\s+", " "); |
||||||
|
assertTrue(sql.contains("involveDepartId"), id); |
||||||
|
assertTrue(sql.contains("level = 3"), id); |
||||||
|
assertTrue(sql.contains("crtTime BETWEEN ? AND ?"), id); |
||||||
|
assertFalse(sql.contains("checkStatus"), id); |
||||||
|
assertFalse(sql.contains("discoveryTime"), id); |
||||||
|
assertFalse(sql.contains("three_involve_depart_id"), id); |
||||||
|
assertFalse(sql.contains("negative_score_depart"), id); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void listSortsBeforePaginationAndBindsFilters() throws Exception { |
||||||
|
Configuration configuration = new Configuration(); |
||||||
|
String resource = "mapper/ProfileDepartMapper.xml"; |
||||||
|
try (var input = getClass().getClassLoader().getResourceAsStream(resource)) { |
||||||
|
new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); |
||||||
|
} |
||||||
|
var statement = configuration.getMappedStatement( |
||||||
|
"com.biutag.supervision.mapper.ProfileDepartMapper.queryDepartNegative"); |
||||||
|
Map<String, Object> params = new HashMap<>(); |
||||||
|
params.put("departId", "county-id"); |
||||||
|
params.put("departName", "分局"); |
||||||
|
params.put("departGroupId", "10"); |
||||||
|
for (var field : Map.of("policeSize", "police_size", "verifyPoliceSize", "verify_police_size", |
||||||
|
"verifySize", "verify_size").entrySet()) { |
||||||
|
for (String order : new String[]{"ascending", "descending"}) { |
||||||
|
params.put("sortField", field.getKey()); |
||||||
|
params.put("sortOrder", order); |
||||||
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ").replace(" ,", ","); |
||||||
|
assertTrue(sql.contains("ORDER BY " + field.getValue() |
||||||
|
+ (order.equals("ascending") ? " ASC" : " DESC") + ", d.id ASC")); |
||||||
|
assertTrue(sql.contains("(d.id = ? OR d.pid = ?)")); |
||||||
|
assertTrue(sql.contains("count(DISTINCT n.id)")); |
||||||
|
assertFalse(sql.contains("negative_score_depart")); |
||||||
|
assertFalse(sql.contains("county-id")); |
||||||
|
} |
||||||
|
} |
||||||
|
params.put("sortField", "police_size; DROP TABLE negative"); |
||||||
|
params.put("sortOrder", "ASC; DROP TABLE negative"); |
||||||
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ").replace(" ,", ","); |
||||||
|
assertTrue(sql.contains("ORDER BY verify_size DESC, d.id ASC")); |
||||||
|
assertFalse(sql.contains("DROP")); |
||||||
|
params.clear(); |
||||||
|
sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ").replace(" ,", ","); |
||||||
|
assertTrue(sql.contains("ORDER BY verify_size DESC, d.id ASC")); |
||||||
|
assertFalse(sql.contains("d.pid = ?")); |
||||||
|
} |
||||||
|
@Test |
||||||
|
void paginationCountUsesExistenceWithoutProblemAggregation() throws Exception { |
||||||
|
Configuration configuration = new Configuration(); |
||||||
|
String resource = "mapper/ProfileDepartMapper.xml"; |
||||||
|
try (var input = getClass().getClassLoader().getResourceAsStream(resource)) { |
||||||
|
new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); |
||||||
|
} |
||||||
|
Map<String, Object> params = new HashMap<>(); |
||||||
|
params.put("departId", "department-id"); |
||||||
|
params.put("departGroupId", "10"); |
||||||
|
params.put("departName", "单位"); |
||||||
|
params.put("name", "姓名"); |
||||||
|
params.put("empNo", "123"); |
||||||
|
String sql = configuration.getMappedStatement("com.biutag.supervision.mapper.ProfileDepartMapper.countDepartNegative") |
||||||
|
.getBoundSql(params).getSql().replaceAll("\\s+", " "); |
||||||
|
assertTrue(sql.contains("EXISTS (")); |
||||||
|
assertFalse(sql.contains("GROUP BY")); |
||||||
|
assertFalse(sql.contains("verify_size")); |
||||||
|
assertFalse(sql.contains("department-id")); |
||||||
|
assertTrue(sql.contains("d.statistics_group_id = ?")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,103 @@ |
|||||||
|
package com.biutag.supervision.mapper; |
||||||
|
|
||||||
|
import org.apache.ibatis.builder.xml.XMLMapperBuilder; |
||||||
|
import org.apache.ibatis.session.Configuration; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||||
|
|
||||||
|
class ProfilePoliceMapperTest { |
||||||
|
@Test |
||||||
|
void detailKeepsScreenScopeAndDeduplicatesProblems() throws Exception { |
||||||
|
Configuration configuration = new Configuration(); |
||||||
|
String resource = "mapper/ProfilePoliceMapper.xml"; |
||||||
|
try (var input = getClass().getClassLoader().getResourceAsStream(resource)) { |
||||||
|
new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); |
||||||
|
} |
||||||
|
var statement = configuration.getMappedStatement("com.biutag.supervision.mapper.ProfilePoliceMapper.selectPoliceProblems"); |
||||||
|
var scope = new com.biutag.supervision.pojo.param.PoliceProfileQuery(); |
||||||
|
scope.setGroupId("10"); |
||||||
|
Map<String, Object> params = new HashMap<>(); |
||||||
|
params.put("scope", scope); |
||||||
|
for (String category : new String[]{"police", "aux", "lead"}) { |
||||||
|
scope.setCategory(category); |
||||||
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " "); |
||||||
|
assertTrue(sql.contains("SELECT DISTINCT n.*")); |
||||||
|
assertTrue(sql.contains("n.crtTime BETWEEN ? AND ?")); |
||||||
|
assertTrue(sql.contains("b.blameEmpNo <=> ?")); |
||||||
|
assertTrue(sql.contains("b.blameName <=> ?")); |
||||||
|
assertTrue(sql.contains("n.handle_three_depart_id = d.id")); |
||||||
|
assertTrue(sql.contains("d.statistics_group_id = ?")); |
||||||
|
assertTrue(sql.contains(category.equals("lead") ? "b.type = 'department'" : "b.type = 'personal'")); |
||||||
|
assertTrue(sql.contains(category.equals("aux") ? "IN ('2', '3', '4', '5')" : "b.ivPersonTypeCode = '1'")); |
||||||
|
assertFalse(sql.contains("checkStatus")); |
||||||
|
assertFalse(sql.contains("negative_score_police")); |
||||||
|
assertFalse(sql.contains("b.blameIdCode = ?")); |
||||||
|
} |
||||||
|
scope.setCategory(null); |
||||||
|
String sql = statement.getBoundSql(params).getSql(); |
||||||
|
assertTrue(sql.contains("b.blameIdCode = ?")); |
||||||
|
assertTrue(sql.contains("b.type = 'personal'")); |
||||||
|
assertFalse(sql.contains("d.statistics_group_id = ?")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void listUsesVerifiedPersonalProblemsAndSafeSortDirection() throws Exception { |
||||||
|
Configuration configuration = new Configuration(); |
||||||
|
String resource = "mapper/ProfilePoliceMapper.xml"; |
||||||
|
try (var input = getClass().getClassLoader().getResourceAsStream(resource)) { |
||||||
|
new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); |
||||||
|
} |
||||||
|
var statement = configuration.getMappedStatement( |
||||||
|
"com.biutag.supervision.mapper.ProfilePoliceMapper.queryPoliceNegative"); |
||||||
|
Map<String, Object> params = new HashMap<>(); |
||||||
|
params.put("departId", "department-id"); |
||||||
|
params.put("departGroupId", "10"); |
||||||
|
params.put("name", "姓名"); |
||||||
|
params.put("empNo", "123"); |
||||||
|
for (String order : new String[]{"ascending", "descending", "", "ASC; DROP TABLE negative"}) { |
||||||
|
params.put("sortOrder", order); |
||||||
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ").replace(" ,", ","); |
||||||
|
assertTrue(sql.contains("ORDER BY verify_size " |
||||||
|
+ (order.equals("ascending") ? "ASC" : "DESC") + ", p.id_code ASC"), sql); |
||||||
|
assertTrue(sql.contains("count(DISTINCT n.id)")); |
||||||
|
assertTrue(sql.contains("nb.type = 'personal'")); |
||||||
|
assertTrue(sql.contains("n.checkStatus IN ('1', '2')")); |
||||||
|
assertTrue(sql.contains("n.processing_status = 'completed'")); |
||||||
|
assertTrue(sql.contains("n.discoveryTime BETWEEN ? AND ?")); |
||||||
|
assertTrue(sql.contains("p.org_id = ?")); |
||||||
|
assertFalse(sql.contains("negative_score_police")); |
||||||
|
assertFalse(sql.contains("department-id")); |
||||||
|
assertFalse(sql.contains("DROP")); |
||||||
|
} |
||||||
|
params.clear(); |
||||||
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ").replace(" ,", ","); |
||||||
|
assertTrue(sql.contains("ORDER BY verify_size DESC, p.id_code ASC")); |
||||||
|
assertFalse(sql.contains("p.org_id = ?")); |
||||||
|
} |
||||||
|
@Test |
||||||
|
void paginationCountUsesExistenceWithoutProblemAggregation() throws Exception { |
||||||
|
Configuration configuration = new Configuration(); |
||||||
|
String resource = "mapper/ProfilePoliceMapper.xml"; |
||||||
|
try (var input = getClass().getClassLoader().getResourceAsStream(resource)) { |
||||||
|
new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); |
||||||
|
} |
||||||
|
Map<String, Object> params = new HashMap<>(); |
||||||
|
params.put("departId", "department-id"); |
||||||
|
params.put("departGroupId", "10"); |
||||||
|
params.put("departName", "单位"); |
||||||
|
params.put("name", "姓名"); |
||||||
|
params.put("empNo", "123"); |
||||||
|
String sql = configuration.getMappedStatement("com.biutag.supervision.mapper.ProfilePoliceMapper.countPoliceNegative") |
||||||
|
.getBoundSql(params).getSql().replaceAll("\\s+", " "); |
||||||
|
assertTrue(sql.contains("EXISTS (")); |
||||||
|
assertFalse(sql.contains("GROUP BY")); |
||||||
|
assertFalse(sql.contains("verify_size")); |
||||||
|
assertFalse(sql.contains("department-id")); |
||||||
|
assertTrue(sql.contains("d.statistics_group_id = ?")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue