This commit is contained in:
mmm8955405 2024-02-20 22:02:42 +08:00
commit a3a4e3f523
87 changed files with 8290 additions and 0 deletions

View File

@ -0,0 +1,75 @@
on:
#release:
#types: [published]
push:
branches:
- "master"
jobs:
build-image:
runs-on: ubuntu-act-latest
steps:
-
name: Check Out Repo
uses: https://github.com/actions/checkout@v4
#with:
#repository: jj/paolu-mybatis
#path: master
#token: ''
- name: Set Java Action
id: steps1
uses: https://github.com/actions/setup-java@v3
with:
distribution: temurin
java-version: 20
#cache: maven
#cache-dependency-path: .pom.xml
-
name: Set Maven Action
uses: https://github.com/stCarolas/setup-maven@v4.5
with:
maven-version: 3.9.5
-
name: Cache
uses: actions/cache@v3
id: cache1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
#- name: Set repo-java-maven Env
#uses: https://github.com/s4u/setup-maven-action@v1.11.0
#with:
#java-distribution: temurin
#java-version: 20
#maven-version: 3.9.5
- if: ${{ steps.cache1.outputs.cache-hit == 'true' }}
name: is hit cache
continue-on-error: true
run: echo " hit cache ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}"
-
name: Build With Maven
run: mvn -B package -Dmaven.test.skip
- name: Uzip
run: mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
#-
#name: set up qemu
#uses: https://github.com/docker/setup-qemu-action@v3
-
name: Set Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v3
-
name: Login To Zot
uses: https://github.com/docker/login-action@v3
with:
registry: zot.164500.xyz
username: test
password: test
-
name: Build And Push Image To Zot
uses: https://github.com/docker/build-push-action@v5
with:
context: .
push: true
tags: zot.164500.xyz/jj/finance:latest

30
.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.classpath
.project
.settings
target
/.factorypath

19
Dockerfile Normal file
View File

@ -0,0 +1,19 @@
#FROM maven:3.9.1-eclipse-temurin-20-alpine as build
#WORKDIR /workspace
#COPY pom.xml .
#COPY src src
#RUN --mount=type=cache,target=/root/.m2,id=m2,sharing=locked \
#mvn package -Dmaven.test.skip
#RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
#
FROM docker.io/eclipse-temurin:20-jre-alpine
WORKDIR /app
COPY target/dependency/BOOT-INF/lib /app/lib
COPY target/dependency/META-INF /app/META-INF
COPY target/dependency/BOOT-INF/classes /app
RUN ls
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone
ENTRYPOINT ["java","-cp","/app:/app/lib/*","jj.tech.finance.Application","--spring.profiles.active=prod"]

548
pom.xml Normal file
View File

@ -0,0 +1,548 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jj.tech.finance</groupId>
<artifactId>finance</artifactId>
<name>finance</name>
<packaging>jar</packaging>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<properties>
<java.version>20</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- <jooq.version>3.17.10</jooq.version> -->
<!-- <start-class>...</start-class>
<docker.image.prefix>springcloud</docker.image.prefix> -->
</properties>
<!--<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>-->
<dependencies>
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency> -->
<!-- 2020 bootstrap.yaml独立 -->
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.mybatis.dynamic-sql</groupId>
<artifactId>mybatis-dynamic-sql</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 使用slf4j+logbakc日志 淘汰log4j和commons-logging logback-classic包改善了log4j且实现了SLF4J API,maven自动引入slf4j-api、logback-core-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>com.github.loki4j</groupId>
<artifactId>loki-logback-appender</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-common</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.1</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.14</version>
</dependency>
<!--jwt token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- spring 引导 maven 插件提供了许多方便的功能:
1、它收集了类路径上的所有 jar, 并生成一个单一的可运行的 "超级jar", 这使得执行和传输服务更加方便。
2、它搜索公共静态 void main () 方法以将其标记为可运行类。
3、它提供了一个内置的依赖项冲突解决程序, 它将版本号设置为与 spring 启动依赖项匹配。
4、您可以重写任何您希望的版本, 但它将默认为启动所选的一组版本。 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 读取项目yaml文件编译打包的时候赋值给pom文件很久没有维护希望找到代替 -->
<plugin>
<groupId>it.ozimov</groupId>
<artifactId>yaml-properties-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>src/main/resources/application.yml</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<!-- <plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>9.20.1</version>
<configuration>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:./test;MODE=MySQL;AUTO_SERVER=TRUE</url>
<user>sa</user>
<password></password>
<locations>
<location>filesystem:src/main/resources/sql</location>
<location>classpath:src/main/resources/sql</location>
</locations>
<baselineOnMigrate>true</baselineOnMigrate>
<sqlMigrationSuffixes>
<sqlMigrationSuffix>.sql</sqlMigrationSuffix>
</sqlMigrationSuffixes>
</configuration>
<executions>
<execution>
<id>create-database-h2</id>
<phase>generate-sources</phase>
<goals>
<goal>migrate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>${mariadb.version}</version>
</dependency>
</dependencies>
</plugin> -->
<!--<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<skip>${maven.test.skip}</skip>
</configuration>
<executions>
<execution>
<id>create-database-h2</id>
<phase>generate-sources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:./finance;MODE=MariaDB;AUTO_SERVER=TRUE;DATABASE_TO_LOWER=TRUE</url>
<username>sa</username>
<password></password>
<driver>org.mariadb.jdbc.Driver</driver>
<url>jdbc:mariadb://173.249.203.214:3306/finance</url>
<username>root</username>
<password>open123</password>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>src/main/resources/sql/schema-h2.sql</srcFile>
<srcFile>src/main/resources/sql/data-h2.sql</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>${mariadb.version}</version>
</dependency>
</dependencies>
</plugin>-->
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<configuration>
<!--<generator>
<database>
<properties>
<property>
<key>scripts</key>
<value>src/main/resources/sql/schema-h2.sql</value>
</property>
</properties>
</database>
</generator>-->
<configurationFile>${basedir}/src/main/resources/generate/jooq/JooqConfig.xml</configurationFile>
</configuration>
<executions>
<execution>
<id>generate-jooq</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>${mariadb.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.2</version>
<configuration>
<overwrite>true</overwrite>
<configurationFile>${basedir}/src/main/resources/generate/mybatis/generatorConfig.xml</configurationFile>
<!--<sqlScript>${basedir}/src/main/resources/sql/schema-h2.sql</sqlScript>
<jdbcDriver>org.h2.Driver</jdbcDriver>
<jdbcURL>jdbc:h2:./finance;MODE=MySQL;AUTO_SERVER=TRUE;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE</jdbcURL>
<jdbcUserId>sa</jdbcUserId>
<jdbcPassword></jdbcPassword>-->
<!--<includeAllDependencies>true</includeAllDependencies>-->
</configuration>
<executions>
<execution>
<id>generate-myBatis</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>${mariadb.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<!--<repositories>
<repository>
<id>aliyun-public</id>
<name>aliyun-public</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>aliyun-central</id>
<name>aliyun-central</name>
<url>https://maven.aliyun.com/repository/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>aliyun-spring</id>
<url>https://maven.aliyun.com/repository/spring</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<name>aliyun-plugin</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>aliyun-plugin-central</id>
<name>aliyun-plugin-central</name>
<url>https://maven.aliyun.com/repository/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>-->
</project>

View File

@ -0,0 +1,91 @@
package jj.tech.finance;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @SpringBootApplication 是一个方便的注释, 它添加了以下所有内容:
*
@Configuration 将类标记为应用程序上下文的 bean 定义的源
@EnableAutoConfiguration 告诉 spring 引导开始根据类路径设置其他 bean 和各种属性设置添加 bean
通常你会为 spring mvc 应用程序添加 @EnableWebMvc, 但是 spring 引导在类路径上看到 spring WebMvc 时会自动添加它这将应用程序标记为 web 应用程序, 并激活诸如设置 DispatcherServlet 之类的关键行为
@ComponentScan 告诉 spring hello 包中查找其他组件配置和服务, 使其能够找到控制器
main () 方法使用 spring 引导的 SpringApplication. run () 方法来启动应用程序
没有单行 xml没有任何 web. xml 文件 web 应用程序是100% java, 您不必处理配置任何管道或基础结构
还有一个标记为 @Bean CommandLineRunner 方法, 并在启动时运行它检索所有的 bean, 由您的应用程序创建或自动添加感谢春季启动它的排序和打印出来
* @author Dou
*
*/
@SpringBootApplication
//@EnableDiscoveryClient
@EnableScheduling
public class Application {
//打成war包需要继承
// @SpringBootApplication
// public class Application extends SpringBootServletInitializer {
//
// @Override
// protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// return application.sources(Application.class);
// }
//
// public static void main(String[] args) {
// SpringApplication.run(Application.class, args);
// }
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.err.println(beanName);
}
};
}
// @StreamListener(IOrderProcessor.INPUT_ORDER)
// public void input(Message<A> message) {
// System.out.println("一般监听收到:" + message.getPayload());
// }
// public JdbcConnectionPool JdbcConnectionPool(){
// String url = "jdbc:h2:~/test";
// String user = "sa";
// String password = "";
// return JdbcConnectionPool.create(url, user, password);
// }
// @Bean
// @StreamMessageConverter
// public MessageConverter customMessageConverter() {
// return new MyCustomMessageConverter();
// }
}

View File

@ -0,0 +1,421 @@
package jj.tech.finance.biz.web.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.fluent.Request;
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.web.dao.ContractInfoSelectMapper;
import jj.tech.finance.biz.webadmin.dao.SelectMapper;
import jj.tech.finance.biz.webadmin.vo.ContractInfoStatu;
import jj.tech.finance.biz.webadmin.vo.ContractInfoStatuScribeStore;
import jj.tech.finance.biz.webadmin.vo.FuturesZhSpot;
import jj.tech.finance.biz.webadmin.vo.parm.Contract;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.biz.webadmin.vo.parm.P;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.ContractInfoStatusScribeMapper;
import jj.tech.finance.repository.mybatis.dao.ContractInfoUserMapper;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoStatusDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoStatusScribeDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoUserDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.repository.mybatis.entity.ContractInfoStatusScribe;
import jj.tech.finance.repository.mybatis.entity.ContractInfoUser;
import jj.tech.finance.repository.mybatis.entity.UserInfo;
import jj.tech.finance.utils.Page;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.WebUserUtil;
@RestController
@Tag(name = "contractInfo", description = "PC合约信息")
@RequestMapping(value = "/web/contract", name = "PC合约信息")
public class ContractInfoController {
@Autowired ObjectMapper objectMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired ContractInfoUserMapper contractInfoUserMapper;
@Autowired ContractInfoSelectMapper contractInfoSelectMapper;
@Autowired ContractInfoStatusScribeMapper contractInfoStatusScribeMapper;
@Autowired SelectMapper selectMapper;
@Operation(summary = "合约信息列表", description = " contract_status=1为禁用其他是启用,scribe_status=1为禁用其他是启用 store=null是未收藏有值为已收藏"
+ "exchange交易市场: cffex-中金所 dce-大商所 czce-郑商所 shfe-上期所 ine-上海国际能源交易中心 gfex-广州期货交易所。")
@PostMapping("/list")
public Object list(@RequestBody(required = true) Contract parm) {
Page p = new Page(parm.getPageNum(), parm.getPageSize());
UserInfo user = WebUserUtil.getUser();
if(user == null) {
return R.FALSE("not login");
}
var contractInfoUser = select(ContractInfoUserMapper.selectList)
.from(ContractInfoUserDynamicSqlSupport.contractInfoUser)
.where(ContractInfoUserDynamicSqlSupport.userid, isEqualTo(user.getId()))
;
BasicColumn[] allContractInfo = BasicColumn.columnList(ContractInfoDynamicSqlSupport.contractInfo.allColumns());
BasicColumn[] store = BasicColumn.columnList(
ContractInfoUserDynamicSqlSupport.id.qualifiedWith("contractInfoUser").as("store"),
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"),
ContractInfoStatusDynamicSqlSupport.scribe_status.qualifiedWith("contract_info_status"),
ContractInfoStatusDynamicSqlSupport.scribe_update_time.qualifiedWith("contract_info_status"),
ContractInfoStatusDynamicSqlSupport.scribe_number.qualifiedWith("contract_info_status")
);
BasicColumn[] basic = ArrayUtils.addAll(allContractInfo,store);
String isLikeTsCode = null;
String isLikeSymbol = null;
if(StringUtils.isNotBlank(parm.getTs_code())) {
isLikeTsCode = "%"+parm.getTs_code()+"%";
}
if(StringUtils.isNotBlank(parm.getSymbol())) {
isLikeSymbol = "%"+parm.getSymbol()+"%";
}
var from = select(basic)
.from(ContractInfoDynamicSqlSupport.contractInfo, "contractInfo")
.leftJoin(contractInfoUser,"contractInfoUser")
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoUserDynamicSqlSupport.ts_code.qualifiedWith("contractInfoUser")))
.leftJoin(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoStatusDynamicSqlSupport.ts_code.qualifiedWith("contract_info_status")))
;
var where = SqlBuilder.where();
where.and(
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isNull(),
or(ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isEqualTo(0)));
where.and(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isLikeWhenPresent(isLikeTsCode),
or(ContractInfoDynamicSqlSupport.contractInfo.symbol, isLikeWhenPresent(isLikeSymbol)));
where.and(ContractInfoDynamicSqlSupport.contractInfo.exchange, isEqualToWhenPresent(parm.getExchange()));
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = from
.applyWhere(applier)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
List<ContractInfoStatuScribeStore> list = contractInfoSelectMapper.selectStroeMany(provider);
var count = select(count())
.from(ContractInfoDynamicSqlSupport.contractInfo, "contractInfo")
.leftJoin(contractInfoUser,"contractInfoUser")
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoUserDynamicSqlSupport.ts_code.qualifiedWith("contractInfoUser")))
.leftJoin(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoStatusDynamicSqlSupport.ts_code.qualifiedWith("contract_info_status")))
.where(
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isNull(),
or(ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isEqualTo(0)))
.and(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isLikeWhenPresent(isLikeTsCode),
or(ContractInfoDynamicSqlSupport.contractInfo.symbol, isLikeWhenPresent(isLikeSymbol)))
.and(ContractInfoDynamicSqlSupport.contractInfo.exchange, isEqualToWhenPresent(parm.getExchange()))
.build()
.render(RenderingStrategies.MYBATIS3);
long total = selectMapper.count(count);
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
@Operation(summary = "收藏合约信息", description = "")
@PostMapping("/store")
public Object store(@Valid @RequestBody(required = true) Id id) {
int contractid = id.getId();
UserInfo user = WebUserUtil.getUser();
if(user == null) {
return R.FALSE("not login");
}
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
var contractInfoUser = select(ContractInfoUserMapper.selectList)
.from(ContractInfoUserDynamicSqlSupport.contractInfoUser)
.where(ContractInfoUserDynamicSqlSupport.userid, isEqualTo(user.getId()))
.and(ContractInfoUserDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.build()
.render(RenderingStrategies.MYBATIS3);
;
Optional<ContractInfoUser> opInfo = contractInfoUserMapper.selectOne(contractInfoUser);
if(opInfo.isPresent()) {
return R.SUCCESS("ok");
}
ContractInfoUser bean = new ContractInfoUser();
bean.setUserid(user.getId());
bean.setUsername(user.getUsername());
bean.setTs_code(contractInfo.getTs_code());
contractInfoUserMapper.insertSelective(bean);
return R.SUCCESS("ok");
}
@Operation(summary = "取消收藏合约信息", description = "")
@PostMapping("/cancel")
public Object cancel(@Valid @RequestBody(required = true) Id id) {
int contractid = id.getId();
UserInfo user = WebUserUtil.getUser();
if(user == null) {
return R.FALSE("not login");
}
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
DeleteStatementProvider deleteStatement = deleteFrom(ContractInfoUserDynamicSqlSupport.contractInfoUser)
.where(ContractInfoUserDynamicSqlSupport.userid, isEqualTo(user.getId()))
.and(ContractInfoUserDynamicSqlSupport.ts_code,isEqualTo(contractInfo.getTs_code()))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
contractInfoUserMapper.delete(deleteStatement);
return R.SUCCESS("delete:"+contractid);
}
@Operation(summary = "获取当前合约实时数据", description = "获取当前合约实时数据,第三方接口返回数据无法和传入合约数据对应。 只能按一条获取")
@PostMapping("/current")
public Object current(@Valid @RequestBody(required = true) Id id) {
try {
int contractid = id.getId();
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
String symbol = StringUtils.substringBefore(contractInfo.getTs_code(), ".");
String url =
"http://173.249.203.214:8080/api/public/futures_zh_spot?"
+ "symbol=" + symbol;
System.out.println(url);
InputStream stean = Request.Get(url)
.connectTimeout(2500)
.socketTimeout(2500)
.execute()
.returnContent()
.asStream();
//objectMapper.read
List<FuturesZhSpot> futuresZhSpots = objectMapper.readValue(stean, List.class);
if(!futuresZhSpots.isEmpty()) {
return R.SUCCESS(futuresZhSpots.get(0));
}
return R.SUCCESS("can not find current date");
} catch (Exception e) {
return R.SUCCESS("can not find current date");
}
}
@Operation(summary = "获取合约划线详情,按contractid获取", description = "")
@PostMapping("/get")
public Object get(@Valid @RequestBody(required = true) Id id) {
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(id.getId());
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+id.getId());
}
ContractInfo contractInfo = op.get();
var select = select(ContractInfoStatusScribeMapper.selectList)
.from(ContractInfoStatusScribeDynamicSqlSupport.contractInfoStatusScribe)
.where(ContractInfoStatusDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.build()
.render(RenderingStrategies.MYBATIS3);
List<ContractInfoStatusScribe> list = contractInfoStatusScribeMapper.selectMany(select);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("contractInfo", contractInfo);
map.put("scribeList", list);
return R.SUCCESS(map);
}
// public Object current(List<?> list) {
// try {
//
// String symbols = "";
// for(Object o: list) {
// ContractInfoStatu info = (ContractInfoStatu) o;
// String symbol = StringUtils.substringBefore(info.getTs_code(), ".");
// symbols = symbols+symbol+",";
// };
//
// String url =
// "http://173.249.203.214:8080/api/public/futures_zh_spot?"
// + "symbol=" + symbols;
// System.out.println(url);
// InputStream stean = Request.Get(url)
// .connectTimeout(2500)
// .socketTimeout(2500)
// .execute()
// .returnContent()
// .asStream();
// //objectMapper.read
// List<FuturesZhSpot> FuturesZhSpots = objectMapper.readValue(stean, List.class);
//
//
//
// for(Object o: list) {
// ContractInfoStatu info = (ContractInfoStatu) o;
// for(FuturesZhSpot i: FuturesZhSpots) {
// if(i.getSymbol() == info.getSymbol()) {
// info.setFuturesZhSpot(i);
// }
// }
//
// };
//
// return list;
// } catch (Exception e) {
// e.printStackTrace();
// return list;
// }
//
// }
@Operation(summary = "我收藏的合约信息列表", description = "")
@PostMapping("/mylist")
public Object mylist(@RequestBody(required = true) P parm) {
Page p = new Page(parm.getPageNum(), parm.getPageSize());
UserInfo user = WebUserUtil.getUser();
if(user == null) {
return R.FALSE("not login");
}
var contractInfoUser = select(ContractInfoUserMapper.selectList)
.from(ContractInfoUserDynamicSqlSupport.contractInfoUser)
.where(ContractInfoUserDynamicSqlSupport.userid, isEqualTo(user.getId()))
;
BasicColumn[] allContractInfo = BasicColumn.columnList(ContractInfoDynamicSqlSupport.contractInfo.allColumns());
BasicColumn[] store = BasicColumn.columnList(
ContractInfoUserDynamicSqlSupport.id.qualifiedWith("contractInfoUser").as("store"),
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"),
ContractInfoStatusDynamicSqlSupport.scribe_status.qualifiedWith("contract_info_status"),
ContractInfoStatusDynamicSqlSupport.scribe_update_time.qualifiedWith("contract_info_status"),
ContractInfoStatusDynamicSqlSupport.scribe_number.qualifiedWith("contract_info_status")
);
BasicColumn[] basic = ArrayUtils.addAll(allContractInfo,store);
var from = select(basic)
.from(ContractInfoDynamicSqlSupport.contractInfo, "contractInfo")
.leftJoin(contractInfoUser,"contractInfoUser")
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoUserDynamicSqlSupport.ts_code.qualifiedWith("contractInfoUser")))
.leftJoin(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoStatusDynamicSqlSupport.ts_code.qualifiedWith("contract_info_status")))
;
var where = SqlBuilder.where();
where.and(
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isNull(),
or(ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isEqualTo(0)));
where.and(ContractInfoUserDynamicSqlSupport.userid.qualifiedWith("contractInfoUser"), isEqualTo(user.getId()));
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = from
.applyWhere(applier)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = contractInfoSelectMapper.selectStroeMany(provider);
var count = select(count())
.from(ContractInfoDynamicSqlSupport.contractInfo, "contractInfo")
.leftJoin(contractInfoUser,"contractInfoUser")
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoUserDynamicSqlSupport.ts_code.qualifiedWith("contractInfoUser")))
.leftJoin(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("contractInfo"),
equalTo(ContractInfoStatusDynamicSqlSupport.ts_code.qualifiedWith("contract_info_status")))
.where(
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isNull(),
or(ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("contract_info_status"), isEqualTo(0)))
.and(ContractInfoUserDynamicSqlSupport.userid.qualifiedWith("contractInfoUser"), isEqualTo(user.getId()))
.build()
.render(RenderingStrategies.MYBATIS3);
long total = selectMapper.count(count);
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
}

View File

@ -0,0 +1,93 @@
package jj.tech.finance.biz.web.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualToWhenPresent;
import static org.mybatis.dynamic.sql.SqlBuilder.isGreaterThanOrEqualToWhenPresent;
import static org.mybatis.dynamic.sql.SqlBuilder.isLessThanOrEqualToWhenPresent;
import static org.mybatis.dynamic.sql.SqlBuilder.select;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jj.tech.finance.biz.webadmin.vo.parm.Daily;
import jj.tech.finance.repository.mybatis.dao.FutDailyMapper;
import jj.tech.finance.repository.mybatis.dao.support.FutDailyDynamicSqlSupport;
import jj.tech.finance.utils.Page;
import jj.tech.finance.utils.R;
@RestController
@Tag(name = "contractInfoDaily", description = "合约日线行情")
@RequestMapping(value = "/web/daily", name = "合约日线行情")
public class ContractInfoDaily {
@Autowired FutDailyMapper futDailyMapper;
@Operation(summary = "日线列表", description = "ts_code合约代码, trade_date交易日期 (yyyy-MM-dd格式下同)")
@PostMapping("/list")
public Object list(@RequestBody(required = true) Daily parm) {
Page p = new Page(parm.getPageNum(), parm.getPageSize());
var from = select(FutDailyMapper.selectList)
.from(FutDailyDynamicSqlSupport.futDaily);
if(StringUtils.isNoneBlank(parm.getTs_code())
|| parm.getTrade_date() !=null
|| parm.getStart_date() != null
|| parm.getEnd_date() != null
) {
var where = SqlBuilder.where();
where.and(FutDailyDynamicSqlSupport.ts_code, isEqualToWhenPresent(parm.getTs_code()));
where.and(FutDailyDynamicSqlSupport.trade_date, isEqualToWhenPresent(parm.getTrade_date()));
if(parm.getTrade_date() ==null) {
where.and(FutDailyDynamicSqlSupport.trade_date, isGreaterThanOrEqualToWhenPresent(parm.getStart_date()));
where.and(FutDailyDynamicSqlSupport.trade_date, isLessThanOrEqualToWhenPresent(parm.getEnd_date()));
}
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = from
.applyWhere(applier)
.orderBy(FutDailyDynamicSqlSupport.trade_date.descending())
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = futDailyMapper.selectMany(provider);
long total = futDailyMapper.count(c->c.applyWhere(applier));
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
SelectStatementProvider provider = from
.orderBy(FutDailyDynamicSqlSupport.trade_date.descending())
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = futDailyMapper.selectMany(provider);
long total = futDailyMapper.count(c->c);
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
}

View File

@ -0,0 +1,68 @@
package jj.tech.finance.biz.web.controller;
import java.io.InputStream;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.fluent.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jj.tech.finance.biz.webadmin.vo.parm.Minute;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.utils.R;
@RestController
@Tag(name = "contractInfoMinute", description = "合约分钟行情")
@RequestMapping(value = "/web/minute", name = "合约分钟行情")
public class ContractInfoMinute {
@Autowired ObjectMapper objectMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Operation(summary = "分钟列表", description = "id=合约ID; period= 1:1分钟,5:5分钟,15:15分钟,30:30分钟,60:60分钟")
@PostMapping("/list")
public Object list(@RequestBody(required = true) Minute parm) {
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(parm.getId());
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+parm.getId());
}
ContractInfo contractInfo = op.get();
String symbol = StringUtils.substringBefore(contractInfo.getTs_code(), ".");
if(parm.getPeriod() == null) {
parm.setPeriod(60);
}
try {
String url =
"http://173.249.203.214:8080/api/public/futures_zh_minute_sina?"
+ "symbol=" + symbol
+ "&period=" + parm.getPeriod();
System.out.println(url);
InputStream stean = Request.Get(url)
.connectTimeout(10000)
.socketTimeout(10000)
.execute()
.returnContent()
.asStream();
JsonNode root = objectMapper.readTree(stean);
return R.SUCCESS(root);
} catch (Exception e) {
e.printStackTrace();
}
return R.SUCCESS("get akshare date fail");
}
}

View File

@ -0,0 +1,81 @@
package jj.tech.finance.biz.web.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.webadmin.dao.SelectMapper;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.FutDailyMapper;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.utils.R;
@RestController
@Tag(name = "contractInfoMonth", description = "合约月行情")
@RequestMapping(value = "/web/month", name = "合约月行情")
public class ContractInfoMonth {
@Autowired FutDailyMapper futDailyMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired SelectMapper selectMapper;
@Operation(summary = "月线列表", description = "按contractid获取")
@PostMapping("/list")
public Object list(@Valid @RequestBody(required = true) Id id) {
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(id.getId());
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+id.getId());
}
ContractInfo contractInfo = op.get();
String select_sql =
"""
SELECT a.*, b.open, c.close FROM (
SELECT ts_code, MIN(low) AS low,
MAX(high) AS high, EXTRACT(YEAR_MONTH from trade_date) AS monthdate,
MIN(trade_date) AS mindate, MAX(trade_date) AS maxdate
FROM fut_daily
WHERE ts_code = #{parameters.ts_code}
GROUP BY EXTRACT(YEAR_MONTH from trade_date)
) AS a
LEFT JOIN
(
SELECT * FROM fut_daily WHERE ts_code = #{parameters.ts_code}
) AS b
ON (a.mindate = b.trade_date)
LEFT JOIN
(
SELECT * FROM fut_daily WHERE ts_code = #{parameters.ts_code}
) AS c
ON (a.maxdate = c.trade_date)
GROUP BY monthdate
ORDER BY monthdate
LIMIT 2000
""";
Map<String, Object> p = new HashMap<String, Object>();
p.put("ts_code", contractInfo.getTs_code());
SelectStatementProvider provider = DefaultSelectStatementProvider
.withSelectStatement(select_sql)
.withParameters(p)
.build();
var list = selectMapper.selectMany(provider);
return R.SUCCESS(list);
}
}

View File

@ -0,0 +1,88 @@
package jj.tech.finance.biz.web.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.webadmin.dao.SelectMapper;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.FutDailyMapper;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.utils.R;
@RestController
@Tag(name = "contractInfoWeek", description = "合约周行情")
@RequestMapping(value = "/web/week", name = "合约周行情")
public class ContractInfoWeek {
@Autowired FutDailyMapper futDailyMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired SelectMapper selectMapper;
@Operation(summary = "周线列表", description = "按contractid获取")
@PostMapping("/list")
public Object list(@Valid @RequestBody(required = true) Id id) {
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(id.getId());
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+id.getId());
}
ContractInfo contractInfo = op.get();
String select_sql =
"""
SELECT a.*, b.open, c.close FROM (
SELECT ts_code, MIN(low) AS low,
MAX(high) AS high, YEARWEEK(trade_date, 1) AS weekdate,
MIN(trade_date) AS mindate, MAX(trade_date) AS maxdate
FROM fut_daily
WHERE ts_code = #{parameters.ts_code}
GROUP BY YEARWEEK(trade_date, 1)
) AS a
LEFT JOIN
(
SELECT * FROM fut_daily WHERE ts_code = #{parameters.ts_code}
) AS b
ON (a.mindate = b.trade_date)
LEFT JOIN
(
SELECT * FROM fut_daily WHERE ts_code = #{parameters.ts_code}
) AS c
ON (a.maxdate = c.trade_date)
GROUP BY weekdate
ORDER BY weekdate
LIMIT 2000
""";
Map<String, Object> p = new HashMap<String, Object>();
p.put("ts_code", contractInfo.getTs_code());
SelectStatementProvider provider = DefaultSelectStatementProvider
.withSelectStatement(select_sql)
.withParameters(p)
.build();
var list = selectMapper.selectMany(provider);
return R.SUCCESS(list);
}
}

View File

@ -0,0 +1,88 @@
package jj.tech.finance.biz.web.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.select;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.biz.webadmin.vo.parm.Login;
import jj.tech.finance.repository.mybatis.dao.UserInfoMapper;
import jj.tech.finance.repository.mybatis.dao.support.UserInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.UserInfo;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.WebUserUtil;
@RestController
@Tag(name = "login", description = "用户前台登录")
@RequestMapping(value = "/web", name = "登录")
public class LoginController {
@Autowired UserInfoMapper userInfoMapper;
@Autowired ObjectMapper objectMapper;
@Operation(summary = "前台pc登录", description = "测试user 000000 或 user1 000000")
@PostMapping("/login")
public Object login(@Valid @RequestBody(required = true) Login parm) {
String passwordEncode = DigestUtils.sha3_256Hex(parm.getPassword());
var provider = select(UserInfoMapper.selectList)
.from(UserInfoDynamicSqlSupport.userInfo)
.where(UserInfoDynamicSqlSupport.username, isEqualTo(parm.username))
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<UserInfo> op = userInfoMapper.selectOne(provider);
if(!op.isPresent()) {
return R.FALSE("用户不存在");
}
UserInfo bean = op.get();
if(!passwordEncode.equals(bean.getPassword())) {
return R.FALSE("密码错误");
}
if(bean.getId()!=1 && bean.getIslock() == 1) {
return R.FALSE("用户已被禁用");
}
bean.setPassword(null);
Map<String, Object> h = objectMapper.convertValue(bean, Map.class);
h.put("logintime", System.currentTimeMillis());
String token = WebUserUtil.addToCookie(h);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("webtoken", token);
map.put("admin", bean);
return R.SUCCESS(map);
}
@Operation(summary = "登出", description = "")
@PostMapping("/logout")
public Object logout() {
WebUserUtil.deleteUser();
return R.SUCCESS("logout is ok");
}
}

View File

@ -0,0 +1,28 @@
package jj.tech.finance.biz.web.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.SelectProvider;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
import org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper;
import jj.tech.finance.biz.webadmin.vo.ContractInfoStatu;
import jj.tech.finance.biz.webadmin.vo.ContractInfoStatuScribe;
import jj.tech.finance.biz.webadmin.vo.ContractInfoStatuScribeStore;
@Mapper
public interface ContractInfoSelectMapper extends CommonCountMapper, CommonDeleteMapper, CommonUpdateMapper{
@SelectProvider(type=SqlProviderAdapter.class, method="select")
List<ContractInfoStatuScribeStore> selectStroeMany (SelectStatementProvider selectStatement);
@SelectProvider(type=SqlProviderAdapter.class, method="select")
List<ContractInfoStatuScribe> selectStatuMany (SelectStatementProvider selectStatement);
}

View File

@ -0,0 +1,267 @@
package jj.tech.finance.biz.webadmin.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
import org.mybatis.dynamic.sql.select.SelectModel;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.web.dao.ContractInfoSelectMapper;
import jj.tech.finance.biz.webadmin.dao.SelectMapper;
import jj.tech.finance.biz.webadmin.vo.parm.Contract;
import jj.tech.finance.biz.webadmin.vo.parm.Ids;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.ContractInfoStatusMapper;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoStatusDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.repository.mybatis.entity.ContractInfoStatus;
import jj.tech.finance.repository.mybatis.entity.SysAdmin;
import jj.tech.finance.utils.Page;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.WebAdminUtil;
@RestController
@Tag(name = "contractInfoManage", description = "合约管理-已对接")
@RequestMapping(value = "/op/contract", name = "合约管理-已对接")
public class ContractInfoManageController {
@Autowired ObjectMapper objectMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired ContractInfoStatusMapper contractInfoStatusMapper;
@Autowired ContractInfoSelectMapper contractInfoSelectMapper;
@Autowired SelectMapper selectMapper;
@Operation(summary = "合约信息列表", description = "ts_code合约代码, symbol交易代码,exchange交易所")
@PostMapping("/list")
public Object list(@RequestBody(required = true) Contract parm) {
// SysAdmin admin = WebAdminUtil.getUser();
// if(admin == null) {
// return R.FALSE("not login");
// }
Page p = new Page(parm.getPageNum(), parm.getPageSize());
BasicColumn[] info = BasicColumn.columnList(ContractInfoDynamicSqlSupport.contractInfo.allColumns());
BasicColumn[] statu = BasicColumn.columnList(
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("status"),
ContractInfoStatusDynamicSqlSupport.scribe_status.qualifiedWith("status"),
ContractInfoStatusDynamicSqlSupport.scribe_update_time.qualifiedWith("status"),
ContractInfoStatusDynamicSqlSupport.scribe_number.qualifiedWith("status")
);
BasicColumn[] basic = ArrayUtils.addAll(info,statu);
Function<QueryExpressionDSL.FromGatherer<SelectModel>, QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher> function =
s -> {
var from = s
.from(ContractInfoDynamicSqlSupport.contractInfo, "info")
.leftJoin(ContractInfoStatusDynamicSqlSupport.contractInfoStatus, "status")
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("info"),
equalTo(ContractInfoStatusDynamicSqlSupport.ts_code.qualifiedWith("status")))
;
return from;
};
if(StringUtils.isNoneBlank(parm.getTs_code())
|| StringUtils.isNoneBlank(parm.getSymbol())
|| StringUtils.isNoneBlank(parm.getExchange())) {
var where = SqlBuilder.where();
String likename = null;
if(StringUtils.isNotBlank(parm.getTs_code())) {
likename = "%"+parm.getTs_code()+"%";
}
where.and(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isLikeWhenPresent(likename),
or(ContractInfoDynamicSqlSupport.contractInfo.name, isLikeWhenPresent(likename)));
where.and(ContractInfoDynamicSqlSupport.contractInfo.symbol, isEqualToWhenPresent(parm.getSymbol()));
where.and(ContractInfoDynamicSqlSupport.contractInfo.exchange, isEqualToWhenPresent(parm.getExchange()));
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = function.apply(select(basic))
.applyWhere(applier)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
SelectStatementProvider count = function.apply(select(count()))
.applyWhere(applier)
.build().render(RenderingStrategies.MYBATIS3);
var list = contractInfoSelectMapper.selectStatuMany(provider);
List l =
list.stream().map(i->{
Map<String,Object> m = objectMapper.convertValue(i, Map.class);
m.put("idname", "ZGQH"+String.format("%04d", m.get("id")));
return m;
}).collect(Collectors.toList());
long total = contractInfoSelectMapper.count(count);
p.setList(l);
p.setTotal(total);
return R.SUCCESS(p);
}
SelectStatementProvider provider = function.apply(select(basic))
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
SelectStatementProvider count = function.apply(select(count()))
.build().render(RenderingStrategies.MYBATIS3);
var list = contractInfoSelectMapper.selectStatuMany(provider);
List l =
list.stream().map(i->{
Map<String,Object> m = objectMapper.convertValue(i, Map.class);
m.put("idname", "ZGQH"+String.format("%04d", m.get("id")));
return m;
}).collect(Collectors.toList());
long total = contractInfoSelectMapper.count(count);
p.setList(l);
p.setTotal(total);
return R.SUCCESS(p);
}
@Operation(summary = "启用合约信息", description = "传入contractid")
@PostMapping("/open")
public Object open(@Valid @RequestBody(required = true) Ids ids) {
if(ids.getIds().size()<1 || ids.getIds().size() >100) {
return R.FALSE("1 <= contractids <= 100");
}
SysAdmin admin = WebAdminUtil.getUser();
if(admin == null) {
return R.FALSE("not login");
}
for(Integer contractid : ids.getIds()){
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
var select = select(ContractInfoStatusMapper.selectList)
.from(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.where(ContractInfoStatusDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<ContractInfoStatus> opStatu = contractInfoStatusMapper.selectOne(select);
if(!opStatu.isPresent()) {
ContractInfoStatus bean = new ContractInfoStatus();
bean.setTs_code(contractInfo.getTs_code());
contractInfoStatusMapper.insertSelective(bean);
}
ContractInfoStatus info = opStatu.get();
info.setContract_status(0);
info.setScribe_status(null);
info.setScribe_status(null);
info.setScribe_update_time(null);
info.setScribe_number(null);
info.setTs_code(null);
contractInfoStatusMapper.updateByPrimaryKeySelective(info);
}
return R.SUCCESS("ok");
}
@Operation(summary = "关闭合约信息", description = "传入contractid")
@PostMapping("/close")
public Object close(@Valid @RequestBody(required = true) Ids ids) {
if(ids.getIds().size()<1 || ids.getIds().size() >100) {
return R.FALSE("1 <= contractids <= 100");
}
SysAdmin admin = WebAdminUtil.getUser();
if(admin == null) {
return R.FALSE("not login");
}
for(Integer contractid : ids.getIds()){
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
var select = select(ContractInfoStatusMapper.selectList)
.from(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.where(ContractInfoStatusDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<ContractInfoStatus> opStatu = contractInfoStatusMapper.selectOne(select);
if(!opStatu.isPresent()) {
ContractInfoStatus bean = new ContractInfoStatus();
bean.setTs_code(contractInfo.getTs_code());
bean.setContract_status(1);
contractInfoStatusMapper.insertSelective(bean);
}
ContractInfoStatus info = opStatu.get();
info.setContract_status(1);
info.setScribe_status(null);
info.setScribe_status(null);
info.setScribe_update_time(null);
info.setScribe_number(null);
info.setTs_code(null);
contractInfoStatusMapper.updateByPrimaryKeySelective(info);
}
return R.SUCCESS("ok");
}
}

View File

@ -0,0 +1,342 @@
package jj.tech.finance.biz.webadmin.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
import org.mybatis.dynamic.sql.select.SelectModel;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.web.dao.ContractInfoSelectMapper;
import jj.tech.finance.biz.webadmin.dao.SelectMapper;
import jj.tech.finance.biz.webadmin.vo.ScribeVo;
import jj.tech.finance.biz.webadmin.vo.parm.Contract;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.biz.webadmin.vo.parm.Ids;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.ContractInfoStatusMapper;
import jj.tech.finance.repository.mybatis.dao.ContractInfoStatusScribeMapper;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoStatusDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoStatusScribeDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.repository.mybatis.entity.ContractInfoStatus;
import jj.tech.finance.repository.mybatis.entity.ContractInfoStatusScribe;
import jj.tech.finance.repository.mybatis.entity.SysAdmin;
import jj.tech.finance.utils.Page;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.WebAdminUtil;
@RestController
@Tag(name = "contractInfoScribe", description = "划线管理")
@RequestMapping(value = "/op/scribe", name = "划线管理")
public class ContractInfoScribeController {
@Autowired ObjectMapper objectMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired ContractInfoStatusMapper contractInfoStatusMapper;
@Autowired ContractInfoStatusScribeMapper contractInfoStatusScribeMapper;
@Autowired ContractInfoSelectMapper contractInfoSelectMapper;
@Autowired SelectMapper selectMapper;
@Operation(summary = "合约信息列表", description = "ts_code合约代码, symbol交易代码,exchange交易所")
@PostMapping("/list")
public Object list(@RequestBody(required = true) Contract parm) {
// SysAdmin admin = WebAdminUtil.getUser();
// if(admin == null) {
// return R.FALSE("not login");
// }
Page p = new Page(parm.getPageNum(), parm.getPageSize());
BasicColumn[] info = BasicColumn.columnList(ContractInfoDynamicSqlSupport.contractInfo.allColumns());
BasicColumn[] statu = BasicColumn.columnList(
ContractInfoStatusDynamicSqlSupport.contract_status.qualifiedWith("status"),
ContractInfoStatusDynamicSqlSupport.scribe_status.qualifiedWith("status"),
ContractInfoStatusDynamicSqlSupport.scribe_update_time.qualifiedWith("status"),
ContractInfoStatusDynamicSqlSupport.scribe_number.qualifiedWith("status")
);
BasicColumn[] basic = ArrayUtils.addAll(info,statu);
Function<QueryExpressionDSL.FromGatherer<SelectModel>, QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher> function =
s -> {
var from = s
.from(ContractInfoDynamicSqlSupport.contractInfo, "info")
.leftJoin(ContractInfoStatusDynamicSqlSupport.contractInfoStatus, "status")
.on(ContractInfoDynamicSqlSupport.ts_code.qualifiedWith("info"),
equalTo(ContractInfoStatusDynamicSqlSupport.ts_code.qualifiedWith("status")))
;
return from;
};
var where = SqlBuilder.where();
where.and(ContractInfoStatusDynamicSqlSupport.contractInfoStatus.contract_status.as("status"), isEqualTo(0),
or(ContractInfoStatusDynamicSqlSupport.contractInfoStatus.contract_status.as("status"), isNull())
);
String likename = null;
if(StringUtils.isNotBlank(parm.getTs_code())) {
likename = "%"+parm.getTs_code()+"%";
}
where.and(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isLikeWhenPresent(likename),
or(ContractInfoDynamicSqlSupport.contractInfo.name, isLikeWhenPresent(likename)));
where.and(ContractInfoDynamicSqlSupport.contractInfo.symbol, isEqualToWhenPresent(parm.getSymbol()));
where.and(ContractInfoDynamicSqlSupport.contractInfo.exchange, isEqualToWhenPresent(parm.getExchange()));
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = function.apply(select(basic))
.applyWhere(applier)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
SelectStatementProvider count = function.apply(select(count()))
.applyWhere(applier)
.build().render(RenderingStrategies.MYBATIS3);
var list = contractInfoSelectMapper.selectStatuMany(provider);
long total = contractInfoSelectMapper.count(count);
var l =
list.stream().map(i->{
Map<String,Object> m = objectMapper.convertValue(i, Map.class);
m.put("idname", "ZGQH"+String.format("%04d", m.get("id")));
return m;
}).collect(Collectors.toList());
p.setList(l);
p.setTotal(total);
return R.SUCCESS(p);
}
@Operation(summary = "启用划线功能", description = "传入contractid")
@PostMapping("/open")
public Object open(@Valid @RequestBody(required = true) Ids ids) {
if(ids.getIds().size()<1 || ids.getIds().size() >100) {
return R.FALSE("1 <= contractids <= 100");
}
SysAdmin admin = WebAdminUtil.getUser();
if(admin == null) {
return R.FALSE("not login");
}
for(Integer contractid : ids.getIds()){
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
var select = select(ContractInfoStatusMapper.selectList)
.from(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.where(ContractInfoStatusDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<ContractInfoStatus> opStatu = contractInfoStatusMapper.selectOne(select);
if(!opStatu.isPresent()) {
ContractInfoStatus bean = new ContractInfoStatus();
bean.setTs_code(contractInfo.getTs_code());
bean.setContract_status(0);
bean.setScribe_status(0);
bean.setScribe_number(0);
bean.setScribe_update_time(LocalDateTime.now());
contractInfoStatusMapper.insertSelective(bean);
}
ContractInfoStatus bean = opStatu.get();
bean.setScribe_status(0);
bean.setScribe_update_time(LocalDateTime.now());
bean.setScribe_number(null);
bean.setContract_status(null);
bean.setTs_code(null);
contractInfoStatusMapper.updateByPrimaryKeySelective(bean);
}
return R.SUCCESS("ok");
}
@Operation(summary = "禁用划线功能", description = "传入contractid")
@PostMapping("/close")
public Object close(@Valid @RequestBody(required = true) Ids ids) {
if(ids.getIds().size()<1 || ids.getIds().size() >100) {
return R.FALSE("1 <= contractids <= 100");
}
SysAdmin admin = WebAdminUtil.getUser();
if(admin == null) {
return R.FALSE("not login");
}
for(Integer contractid : ids.getIds()){
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(contractid);
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+contractid);
}
ContractInfo contractInfo = op.get();
var select = select(ContractInfoStatusMapper.selectList)
.from(ContractInfoStatusDynamicSqlSupport.contractInfoStatus)
.where(ContractInfoStatusDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<ContractInfoStatus> opStatu = contractInfoStatusMapper.selectOne(select);
if(!opStatu.isPresent()) {
ContractInfoStatus bean = new ContractInfoStatus();
bean.setTs_code(contractInfo.getTs_code());
bean.setScribe_status(1);
bean.setScribe_update_time(LocalDateTime.now());
contractInfoStatusMapper.insertSelective(bean);
}
ContractInfoStatus bean = opStatu.get();
bean.setScribe_status(1);
bean.setScribe_update_time(LocalDateTime.now());
bean.setContract_status(null);
bean.setTs_code(null);
contractInfoStatusMapper.updateByPrimaryKeySelective(bean);
}
return R.SUCCESS("ok");
}
@Operation(summary = "添加或更新划线详情", description = "scribeids同一合约不能重复:1:普通/动态支撑,2:普通/动态压力,3:高级支撑,4:高级压力,5:高级重合位 6,7..... </br> scribe_value: 划线值</br> demo: </br>"
+ "{contractid\": 1,\r\n"
+ " \"list\": [\r\n"
+ " {\r\n"
+ " \"scribe_id\": 1,\r\n"
+ " \"scribe_value\": 100\r\n"
+ " }\r\n"
+ " ]\r\n"
+ "}")
@PostMapping("/add")
@Transactional
public Object add(@RequestBody(required = true) ScribeVo parm) {
if(parm.getContractid() == null) {
return R.FALSE("contractid must not null");
}
SysAdmin admin = WebAdminUtil.getUser();
if(admin == null) {
return R.FALSE("not login");
}
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(parm.getContractid());
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+parm.getContractid());
}
ContractInfo info = op.get();
Integer sum = 0;
for(ContractInfoStatusScribe i : parm.getList()) {
if(i.getScribe_id() >= 1 && i.getScribe_id() <= 9) {
ContractInfoStatusScribe entity = new ContractInfoStatusScribe();
entity.setScribe_id(i.getScribe_id());
entity.setScribe_value(i.getScribe_value());
entity.setColour(i.getColour());
entity.setTs_code(info.getTs_code());
int s=0;
if(i.getId()==null) {
s = contractInfoStatusScribeMapper.insertSelective(entity);
}else {
entity.setId(i.getId());
s = contractInfoStatusScribeMapper.updateByPrimaryKeySelective(entity);
}
sum=s+sum;
}
}
return R.SUCCESS("add:"+sum);
}
@Operation(summary = "获取合约划线详情,按contractid获取", description = "")
@PostMapping("/get")
public Object get(@Valid @RequestBody(required = true) Id id) {
Optional<ContractInfo> op = contractInfoMapper.selectByPrimaryKey(id.getId());
if(!op.isPresent()) {
return R.FALSE("cannot fine this contractid:"+id.getId());
}
ContractInfo contractInfo = op.get();
var select = select(ContractInfoStatusScribeMapper.selectList)
.from(ContractInfoStatusScribeDynamicSqlSupport.contractInfoStatusScribe)
.where(ContractInfoStatusDynamicSqlSupport.ts_code, isEqualTo(contractInfo.getTs_code()))
.build()
.render(RenderingStrategies.MYBATIS3);
List<ContractInfoStatusScribe> list = contractInfoStatusScribeMapper.selectMany(select);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("contractInfo", contractInfo);
map.put("scribeList", list);
return R.SUCCESS(map);
}
@Operation(summary = "删除划线详情,按划线详情的ID删除", description = "")
@PostMapping("/delete")
public Object delete(@Valid @RequestBody(required = true) Id id) {
// DeleteStatementProvider deleteStatement = deleteFrom(ContractInfoStatusScribeDynamicSqlSupport.contractInfoStatusScribe)
// .where(ContractInfoStatusScribeDynamicSqlSupport.ts_code, isEqualTo(info.getTs_code()))
// .limit(5)
// .build()
// .render(RenderingStrategies.MYBATIS3);
//
//contractInfoStatusScribeMapper.delete(deleteStatement);
int sum = contractInfoStatusScribeMapper.deleteByPrimaryKey(id.getId());
return R.SUCCESS("delete :" + sum);
}
}

View File

@ -0,0 +1,463 @@
package jj.tech.finance.biz.webadmin.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.io.InputStream;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jj.tech.finance.biz.webadmin.service.DailyService;
import jj.tech.finance.config.enums.Exchange;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.FutDailyMapper;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.FutDailyDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.repository.mybatis.entity.FutDaily;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.tushare.TushareConfig;
@RestController
@Tag(name = "futDaily", description = "获取日线信息")
public class GetFutDailyController {
private static Logger logger = LoggerFactory.getLogger(GetFutDailyController.class);
@Autowired ObjectMapper objectMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired FutDailyMapper futDailyMapper;
@Autowired DailyService dailyService;
// @Operation(summary = "获取日线信息", description = "")
// @GetMapping("/getDate")
// public Object getDate() {
//
// var ts_codes = select(FutDailyDynamicSqlSupport.ts_code)
// .from(FutDailyDynamicSqlSupport.futDaily)
// .groupBy(FutDailyDynamicSqlSupport.futDaily.ts_code);
//
// var from = select(ContractInfoMapper.selectList)
// .from(ContractInfoDynamicSqlSupport.contractInfo)
// .where(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isNotIn(ts_codes))
// //.groupBy(ContractInfoDynamicSqlSupport.contractInfo.ts_code)
// .build()
// .render(RenderingStrategies.MYBATIS3);
//
// List<ContractInfo> contractInfos = contractInfoMapper.selectMany(from);
//
// contractInfos.forEach(i->{
// try {
// HashMap<Object,Object> h = new HashMap<Object,Object>();
// h.put("api_name", "fut_daily");
// h.put("token", TushareConfig.TOKEN);
// HashMap<Object,Object> params = new HashMap<Object,Object>();
// params.put("ts_code", i.getTs_code());
// params.put("limit", 10000);
// h.put("params", params);
// logger.debug("tushare:" + objectMapper.writeValueAsString(h));
//
// InputStream stean =
// Request.Post(TushareConfig.URL)
// .connectTimeout(20000)
// .socketTimeout(20000)
// .bodyString(objectMapper.writeValueAsString(h), ContentType.APPLICATION_JSON)
// .execute()
// .returnContent()
// .asStream();
// JsonNode root = objectMapper.readTree(stean);
// JsonNode items = root.get("data").get("items");
//
// ArrayList<FutDaily> list = new ArrayList<FutDaily>();
//
// for(JsonNode jsonNode : items) {
// FutDaily bean = new FutDaily();
// bean.setTs_code(jsonNode.get(0).asText());
//
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
// LocalDate localDate = LocalDate.parse(jsonNode.get(1).asText(), formatter);
//
// bean.setTrade_date(localDate);
// bean.setPre_close(jsonNode.get(2).asDouble());
// bean.setPre_settle(jsonNode.get(3).asDouble());
// bean.setOpen(jsonNode.get(4).asDouble());
// bean.setHigh(jsonNode.get(5).asDouble());
//
// bean.setLow(jsonNode.get(6).asDouble());
// bean.setClose(jsonNode.get(7).asDouble());
// bean.setSettle(jsonNode.get(8).asDouble());
// bean.setChange1(jsonNode.get(9).asDouble());
// bean.setChange2(jsonNode.get(10).asDouble());
//
// bean.setVol(jsonNode.get(11).asDouble());
// bean.setAmount(jsonNode.get(12).asDouble());
// bean.setOi(jsonNode.get(13).asDouble());
// bean.setOi_chg(jsonNode.get(14).asDouble());
// list.add(bean);
// }
// if(!list.isEmpty()) {
// futDailyMapper.insertMultiple(list);
// }
//
// //Thread.sleep(200);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
//
//
//
// });
//
//
// return R.SUCCESS("getDate is ok");
// }
@Operation(summary = "获取最新日线信息", description = "")
@GetMapping("/getDateNow")
public Object getDateNow() {
LocalDate d = LocalDate.of(2024, 02, 20);
var from = select(ContractInfoMapper.selectList)
.from(ContractInfoDynamicSqlSupport.contractInfo)
.where(ContractInfoDynamicSqlSupport.contractInfo.delist_date, isGreaterThan(d))
//.and(ContractInfoDynamicSqlSupport.ts_code, )
.build()
.render(RenderingStrategies.MYBATIS3);
DeleteStatementProvider delete = deleteFrom(FutDailyDynamicSqlSupport.futDaily)
.where(FutDailyDynamicSqlSupport.ts_code, isIn(select(ContractInfoDynamicSqlSupport.ts_code)
.from(ContractInfoDynamicSqlSupport.contractInfo)
.where(ContractInfoDynamicSqlSupport.contractInfo.delist_date, isGreaterThan(d))))
.build()
.render(RenderingStrategies.MYBATIS3);
futDailyMapper.delete(delete);
List<ContractInfo> contractInfos = contractInfoMapper.selectMany(from);
contractInfos.forEach(i->{
try {
HashMap<Object,Object> h = new HashMap<Object,Object>();
h.put("api_name", "fut_daily");
h.put("token", TushareConfig.TOKEN);
HashMap<Object,Object> params = new HashMap<Object,Object>();
params.put("ts_code", i.getTs_code());
params.put("limit", 10000);
h.put("params", params);
logger.debug("tushare:" + objectMapper.writeValueAsString(h));
InputStream stean =
Request.Post(TushareConfig.URL)
.connectTimeout(15000)
.socketTimeout(15000)
.bodyString(objectMapper.writeValueAsString(h), ContentType.APPLICATION_JSON)
.execute()
.returnContent()
.asStream();
JsonNode root = objectMapper.readTree(stean);
JsonNode items = root.get("data").get("items");
ArrayList<FutDaily> list = new ArrayList<FutDaily>();
for(JsonNode jsonNode : items) {
FutDaily bean = new FutDaily();
bean.setTs_code(jsonNode.get(0).asText());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate localDate = LocalDate.parse(jsonNode.get(1).asText(), formatter);
bean.setTrade_date(localDate);
bean.setPre_close(jsonNode.get(2).asDouble());
bean.setPre_settle(jsonNode.get(3).asDouble());
bean.setOpen(jsonNode.get(4).asDouble());
bean.setHigh(jsonNode.get(5).asDouble());
bean.setLow(jsonNode.get(6).asDouble());
bean.setClose(jsonNode.get(7).asDouble());
bean.setSettle(jsonNode.get(8).asDouble());
bean.setChange1(jsonNode.get(9).asDouble());
bean.setChange2(jsonNode.get(10).asDouble());
bean.setVol(jsonNode.get(11).asDouble());
bean.setAmount(jsonNode.get(12).asDouble());
bean.setOi(jsonNode.get(13).asDouble());
bean.setOi_chg(jsonNode.get(14).asDouble());
list.add(bean);
}
if(!list.isEmpty()) {
dailyService.getCurr(i.getTs_code(), list);
}
//Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
});
return R.SUCCESS("getDate is ok");
}
@Operation(summary = "获取主力日线信息", description = "")
@GetMapping("/getDate")
public Object getDate() {
String select_sql =
"""
SELECT * FROM contract_info WHERE ts_code NOT REGEXP '[0-9]+'
""";
SelectStatementProvider provider = DefaultSelectStatementProvider
.withSelectStatement(select_sql)
.build();
List<ContractInfo> contractInfos = contractInfoMapper.selectMany(provider);
contractInfos.forEach(i->{
try {
HashMap<Object,Object> h = new HashMap<Object,Object>();
h.put("api_name", "fut_daily");
h.put("token", TushareConfig.TOKEN);
HashMap<Object,Object> params = new HashMap<Object,Object>();
params.put("ts_code", i.getTs_code());
params.put("limit", 10000);
h.put("params", params);
logger.debug("tushare:" + objectMapper.writeValueAsString(h));
InputStream stean =
Request.Post(TushareConfig.URL)
.connectTimeout(15000)
.socketTimeout(15000)
.bodyString(objectMapper.writeValueAsString(h), ContentType.APPLICATION_JSON)
.execute()
.returnContent()
.asStream();
JsonNode root = objectMapper.readTree(stean);
JsonNode items = root.get("data").get("items");
ArrayList<FutDaily> list = new ArrayList<FutDaily>();
for(JsonNode jsonNode : items) {
FutDaily bean = new FutDaily();
bean.setTs_code(jsonNode.get(0).asText());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate localDate = LocalDate.parse(jsonNode.get(1).asText(), formatter);
bean.setTrade_date(localDate);
bean.setPre_close(jsonNode.get(2).asDouble());
bean.setPre_settle(jsonNode.get(3).asDouble());
bean.setOpen(jsonNode.get(4).asDouble());
bean.setHigh(jsonNode.get(5).asDouble());
bean.setLow(jsonNode.get(6).asDouble());
bean.setClose(jsonNode.get(7).asDouble());
bean.setSettle(jsonNode.get(8).asDouble());
bean.setChange1(jsonNode.get(9).asDouble());
bean.setChange2(jsonNode.get(10).asDouble());
bean.setVol(jsonNode.get(11).asDouble());
bean.setAmount(jsonNode.get(12).asDouble());
bean.setOi(jsonNode.get(13).asDouble());
bean.setOi_chg(jsonNode.get(14).asDouble());
list.add(bean);
}
if(!list.isEmpty()) {
dailyService.getCurr(i.getTs_code(), list);
}
//Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
});
return R.SUCCESS("getDate is ok");
}
@Operation(summary = "合约信息", description = "")
@GetMapping("/init")
public Object init() throws Exception {
List<Exchange> exchanges = Arrays.asList(Exchange.values());
exchanges.forEach(i->{
HashMap<Object,Object> h = new HashMap<Object,Object>();
h.put("api_name", "fut_basic");
h.put("token", TushareConfig.TOKEN);
HashMap<Object,Object> params = new HashMap<Object,Object>();
params.put("exchange", i);
h.put("params", params);
try {
this.getExchangeDate(i, h);
} catch (Exception e) {
e.printStackTrace();
}
});
return R.SUCCESS("ok");
}
public void getExchangeDate(Exchange exchange, HashMap<Object,Object> parm) throws Exception{
logger.debug("tushare:" + objectMapper.writeValueAsString(parm));
InputStream stean =
Request.Post(TushareConfig.URL)
.connectTimeout(15000)
.socketTimeout(15000)
.bodyString(objectMapper.writeValueAsString(parm), ContentType.APPLICATION_JSON)
.execute()
.returnContent()
.asStream();
// .asString(StandardCharsets.UTF_8);
JsonNode root = objectMapper.readTree(stean);
JsonNode items = root.get("data").get("items");
ArrayList<ContractInfo> list = new ArrayList<ContractInfo>();
for(JsonNode jsonNode : items) {
ContractInfo bean = new ContractInfo();
bean.setTs_code(jsonNode.get(0).asText());
bean.setSymbol(jsonNode.get(1).asText());
bean.setExchange(jsonNode.get(2).asText());
bean.setName(jsonNode.get(3).asText());
bean.setFut_code(jsonNode.get(4).asText());
bean.setMultiplier(jsonNode.get(5).asDouble());
bean.setTrade_unit(jsonNode.get(6).asText());
bean.setPer_unit(jsonNode.get(7).asDouble());
bean.setQuote_unit(jsonNode.get(8).asText());
bean.setQuote_unit_desc(jsonNode.get(9).asText());
bean.setD_mode_desc(jsonNode.get(10).asText());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
String str11 = jsonNode.get(11).asText();
String str12 = jsonNode.get(12).asText();
String str14 = jsonNode.get(14).asText();
LocalDate list_date = null;
LocalDate delist_date = null;
LocalDate last_ddate = null;
if(StringUtils.isNoneBlank(str11) && !"null".equals(str11)) {
list_date = LocalDate.parse(str11, formatter);
}else {
list_date = LocalDate.ofInstant(Instant.ofEpochMilli(0), ZoneId.systemDefault());
}
if(StringUtils.isNoneBlank(str12) && !"null".equals(str12)) {
delist_date = LocalDate.parse(str12, formatter);
}else {
delist_date = LocalDate.ofInstant(Instant.ofEpochMilli(0), ZoneId.systemDefault());
}
if(StringUtils.isNoneBlank(str14) && !"null".equals(str14)) {
last_ddate = LocalDate.parse(str14, formatter);
}else {
last_ddate = LocalDate.ofInstant(Instant.ofEpochMilli(0), ZoneId.systemDefault());
}
bean.setList_date(list_date);
bean.setDelist_date(delist_date);
bean.setD_month(jsonNode.get(13).asText());
bean.setLast_ddate(last_ddate);
List<Exchange> exchanges = Arrays.asList(Exchange.values());
for(Exchange i : exchanges) {
if(bean.getExchange().equals(i.toString())){
bean.setExchange_name(i.getName());
break;
}
}
list.add(bean);
}
var from = select(ContractInfoMapper.selectList)
.from(ContractInfoDynamicSqlSupport.contractInfo)
.where(ContractInfoDynamicSqlSupport.exchange, isEqualTo(exchange.toString()))
.limit(8888)
.build()
.render(RenderingStrategies.MYBATIS3);
List<ContractInfo> contractInfos = contractInfoMapper.selectMany(from);
Map<String, Object> local =
contractInfos.stream().collect(
Collectors.toMap(ContractInfo::getTs_code, i->i)
);
//System.out.println(local);
List<ContractInfo> bath = new ArrayList<ContractInfo>();
list.forEach(i->{
if(local.get(i.getTs_code()) == null) {
bath.add(i);
}
});
if(!bath.isEmpty()) {
contractInfoMapper.insertMultiple(bath);
}
}
}

View File

@ -0,0 +1,172 @@
package jj.tech.finance.biz.webadmin.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isNotEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.select;
import java.util.Optional;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.biz.webadmin.vo.parm.UserName;
import jj.tech.finance.repository.mybatis.dao.SysAdminMapper;
import jj.tech.finance.repository.mybatis.dao.support.SysAdminDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.SysAdmin;
import jj.tech.finance.utils.Page;
import jj.tech.finance.utils.R;
@RestController
@RequestMapping(value = "/op/ad", name = "管理员列表")
@Tag(name = "sysAdmin", description = "管理员列表")
public class SysAdminController {
@Autowired SysAdminMapper sysAdminMapper;
@Operation(summary = "管理员列表,按内容搜索", description = "")
@PostMapping("/list")
public Object list(@RequestBody(required = true) UserName parm) {
Page p = new Page(parm.getPageNum(), parm.getPageSize());
BasicColumn[] selectList =
BasicColumn.columnList(SysAdminDynamicSqlSupport.id,
SysAdminDynamicSqlSupport.realname,
SysAdminDynamicSqlSupport.username,
SysAdminDynamicSqlSupport.islock);
var from = select(selectList)
.from(SysAdminDynamicSqlSupport.sysAdmin);
if(StringUtils.isNoneBlank(parm.getUsername()) || StringUtils.isNoneBlank(parm.getRealname()) ||
parm.getIslock()!=null) {
var where = SqlBuilder.where();
if(parm.getIslock()!=null) {
where.and(SysAdminDynamicSqlSupport.islock, isEqualTo(parm.getIslock()));
}
if(StringUtils.isNoneBlank(parm.getUsername())) {
where.and(SysAdminDynamicSqlSupport.username, isEqualTo(parm.getUsername()));
}
if(StringUtils.isNoneBlank(parm.getRealname())) {
where.and(SysAdminDynamicSqlSupport.realname, isEqualTo(parm.getRealname()));
}
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = from
.applyWhere(applier)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = sysAdminMapper.selectMany(provider);
long total = sysAdminMapper.count(c->c.applyWhere(applier));
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
//var where = SqlBuilder.where(SysAdminDynamicSqlSupport.id, isNotEqualTo(1)).toWhereApplier();
SelectStatementProvider provider = from
// .applyWhere(where)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = sysAdminMapper.selectMany(provider);
long total = sysAdminMapper.count(c->c);
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
@Operation(summary = "管理员更新和添加(ID不存在添加,否则更新)", description = "")
@PostMapping("/post")
public Object post(@RequestBody(required = true) SysAdmin parm) {
if(StringUtils.isEmpty(parm.getUsername())) {
return R.FALSE("用户名不能为空");
}
String password = parm.getPassword();
if(parm.getId() == null) {
if(StringUtils.isEmpty(password)) {
return R.FALSE("密码不能为空");
}
String passwordEncode = DigestUtils.sha3_256Hex(password);
parm.setPassword(passwordEncode);
sysAdminMapper.insertSelective(parm);
return R.SUCCESS(parm);
}
if(parm.getId() == 1) {
return R.FALSE("超级管理不能修改");
}
if(StringUtils.isEmpty(password)) {
parm.setPassword(null);
}else {
String passwordEncode = DigestUtils.sha3_256Hex(password);
parm.setPassword(passwordEncode);
}
sysAdminMapper.updateByPrimaryKeySelective(parm);
return R.SUCCESS("update:"+parm.getId());
}
@Operation(summary = "按管理员ID删除")
@PostMapping("/delete")
public Object delete(@Valid @RequestBody(required = true) Id id) {
if(id.getId()!=1) {
sysAdminMapper.deleteByPrimaryKey(id.getId());
}
if(id.getId()==1) {
return R.FALSE("超级管理员不能删除");
}
return R.SUCCESS("delete: "+id);
}
@Operation(summary = "按管理员ID获取", description = "")
@PostMapping("/get")
public Object get(@Valid @RequestBody(required = true) Id id) {
Optional<SysAdmin> op = sysAdminMapper.selectByPrimaryKey(id.getId());
if(op.isPresent()) {
SysAdmin u = op.get();
u.setPassword(null);
return R.SUCCESS(u);
}
return R.SUCCESS("can no find");
}
}

View File

@ -0,0 +1,90 @@
package jj.tech.finance.biz.webadmin.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.select;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.webadmin.vo.parm.Login;
import jj.tech.finance.repository.mybatis.dao.SysAdminMapper;
import jj.tech.finance.repository.mybatis.dao.support.SysAdminDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.SysAdmin;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.WebAdminUtil;
@RestController
@Tag(name = "login", description = "后端管理员登录")
@RequestMapping(value = "/op", name = "登录")
public class SysAdminLoginController {
@Autowired SysAdminMapper sysAdminMapper;
@Autowired ObjectMapper objectMapper;
@Operation(summary = "登录", description = "测试admin 000000")
@PostMapping("/login")
public Object login(@Valid @RequestBody(required = true) Login parm) {
String passwordEncode = DigestUtils.sha3_256Hex(parm.getPassword());
var provider = select(SysAdminMapper.selectList)
.from(SysAdminDynamicSqlSupport.sysAdmin)
.where(SysAdminDynamicSqlSupport.username, isEqualTo(parm.getUsername()))
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<SysAdmin> op = sysAdminMapper.selectOne(provider);
if(!op.isPresent()) {
return R.FALSE("管理员不存在");
}
SysAdmin bean = op.get();
if(!passwordEncode.equals(bean.getPassword())) {
return R.FALSE("密码错误");
}
if(bean.getId()!=1 && bean.getIslock() == 1) {
return R.FALSE("管理员已被禁用");
}
bean.setPassword(null);
// Map<String, String> h = BeanUtils.describe(bean);
// Map<Object, Object> h = new org.apache.commons.beanutils.BeanMap(bean);
Map<String, Object> h = objectMapper.convertValue(bean, Map.class);
h.put("logintime", System.currentTimeMillis());
String token = WebAdminUtil.addToCookie(h);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("token", token);
map.put("admin", bean);
return R.SUCCESS(map);
}
@Operation(summary = "登出", description = "")
@PostMapping("/logout")
public Object logout() {
WebAdminUtil.deleteUser();
return R.SUCCESS("logout is ok");
}
}

View File

@ -0,0 +1,168 @@
package jj.tech.finance.biz.webadmin.controller;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.util.Optional;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jj.tech.finance.biz.webadmin.vo.parm.Id;
import jj.tech.finance.biz.webadmin.vo.parm.UserName;
import jj.tech.finance.repository.mybatis.dao.UserInfoMapper;
import jj.tech.finance.repository.mybatis.dao.support.UserInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.UserInfo;
import jj.tech.finance.utils.Page;
import jj.tech.finance.utils.R;
@RestController
@RequestMapping(value = "/op/user", name = "用户管理")
@Tag(name = "userInfo", description = "用户管理")
public class UserInfoController {
@Autowired UserInfoMapper userInfoMapper;
@Operation(summary = "用户列表,按内容搜索", description = "")
@PostMapping("/list")
public Object list(@RequestBody(required = true) UserName parm) {
Page p = new Page(parm.getPageNum(), parm.getPageSize());
BasicColumn[] selectList =
BasicColumn.columnList(UserInfoDynamicSqlSupport.id,
UserInfoDynamicSqlSupport.realname,
UserInfoDynamicSqlSupport.username,
UserInfoDynamicSqlSupport.islock);
var from = select(selectList)
.from(UserInfoDynamicSqlSupport.userInfo);
if(StringUtils.isNoneBlank(parm.getUsername()) || StringUtils.isNoneBlank(parm.getRealname()) ||
parm.getIslock()!=null) {
var where = SqlBuilder.where();
if(parm.getIslock()!=null) {
where.and(UserInfoDynamicSqlSupport.islock, isEqualTo(parm.getIslock()));
}
if(StringUtils.isNoneBlank(parm.getUsername())) {
where.and(UserInfoDynamicSqlSupport.username, isEqualTo(parm.getUsername()));
}
if(StringUtils.isNoneBlank(parm.getRealname())) {
where.and(UserInfoDynamicSqlSupport.realname, isEqualTo(parm.getRealname()));
}
WhereApplier applier = where.toWhereApplier();
SelectStatementProvider provider = from
.applyWhere(applier)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = userInfoMapper.selectMany(provider);
long total = userInfoMapper.count(c->c.applyWhere(applier));
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
//var where = SqlBuilder.where(SysAdminDynamicSqlSupport.id, isNotEqualTo(1)).toWhereApplier();
SelectStatementProvider provider = from
// .applyWhere(where)
.limit(p.getPageSize())
.offset(p.limitStart())
.build()
.render(RenderingStrategies.MYBATIS3);
var list = userInfoMapper.selectMany(provider);
long total = userInfoMapper.count(c->c);
p.setList(list);
p.setTotal(total);
return R.SUCCESS(p);
}
@Operation(summary = "更新和添加(ID不存在添加,否则更新)", description = "")
@PostMapping("/post")
public Object post(@RequestBody(required = true) UserInfo parm) {
if(StringUtils.isEmpty(parm.getUsername())) {
return R.FALSE("用户名不能为空");
}
String password = parm.getPassword();
String username = parm.getUsername();
if(StringUtils.isNotBlank(password)) {
String passwordEncode = DigestUtils.sha3_256Hex(password);
parm.setPassword(passwordEncode);
}
if(parm.getId() == null) {
if(StringUtils.isBlank(password) || StringUtils.isBlank(username)) {
return R.FALSE("用户名/密码不能为空");
}
var from = select(UserInfoMapper.selectList)
.from(UserInfoDynamicSqlSupport.userInfo)
.where(UserInfoDynamicSqlSupport.username, isEqualTo(username))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
Optional<UserInfo> op = userInfoMapper.selectOne(from);
if(op.isPresent()) {
return R.FALSE("该用户已经存在");
}
userInfoMapper.insertSelective(parm);
return R.SUCCESS(parm);
}
userInfoMapper.updateByPrimaryKeySelective(parm);
return R.SUCCESS("update:"+parm.getId());
}
@Operation(summary = "按用户ID删除")
@PostMapping("/delete")
public Object delete(@Valid @RequestBody(required = true) Id id) {
if(id.getId()!=1) {
userInfoMapper.deleteByPrimaryKey(id.getId());
}
return R.SUCCESS("delete: "+id);
}
@Operation(summary = "按用户ID获取", description = "")
@PostMapping("/get")
public Object get(@Valid @RequestBody(required = true) Id id) {
Optional<UserInfo> op = userInfoMapper.selectByPrimaryKey(id.getId());
if(op.isPresent()) {
UserInfo u = op.get();
u.setPassword(null);
return R.SUCCESS(u);
}
return R.SUCCESS("can no find");
}
}

View File

@ -0,0 +1,34 @@
package jj.tech.finance.biz.webadmin.dao;
import java.util.List;
import org.apache.commons.collections4.map.CaseInsensitiveMap;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.SelectProvider;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
import org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper;
@Mapper
public interface SelectMapper extends CommonDeleteMapper, CommonUpdateMapper {
/**
* 没有映射直接返回表字段
* @param selectStatement
* @return
*/
@SelectProvider(type=SqlProviderAdapter.class, method="select")
List<CaseInsensitiveMap<Object,Object>> selectMany (SelectStatementProvider selectStatement);
// @SelectProvider(type=SqlProviderAdapter.class, method="select")
// List<HashMap<Object,Object>> selectMany (SelectStatementProvider selectStatement);
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
Long count(SelectStatementProvider selectStatement);
}

View File

@ -0,0 +1,139 @@
package jj.tech.finance.biz.webadmin.service;
import static org.mybatis.dynamic.sql.SqlBuilder.deleteFrom;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isGreaterThan;
import static org.mybatis.dynamic.sql.SqlBuilder.select;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
import jj.tech.finance.repository.mybatis.dao.FutDailyMapper;
import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.dao.support.FutDailyDynamicSqlSupport;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
import jj.tech.finance.repository.mybatis.entity.FutDaily;
import jj.tech.finance.utils.R;
import jj.tech.finance.utils.tushare.TushareConfig;
@Service
public class DailyService {
private static Logger logger = LoggerFactory.getLogger(DailyService.class);
@Autowired ObjectMapper objectMapper;
@Autowired ContractInfoMapper contractInfoMapper;
@Autowired FutDailyMapper futDailyMapper;
// public Object getDate() {
//
// var ts_codes = select(FutDailyDynamicSqlSupport.ts_code)
// .from(FutDailyDynamicSqlSupport.futDaily)
// .groupBy(FutDailyDynamicSqlSupport.futDaily.ts_code);
//
// var from = select(ContractInfoMapper.selectList)
// .from(ContractInfoDynamicSqlSupport.contractInfo)
// .where(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isNotIn(ts_codes))
// //.groupBy(ContractInfoDynamicSqlSupport.contractInfo.ts_code)
// .build()
// .render(RenderingStrategies.MYBATIS3);
//
// List<ContractInfo> contractInfos = contractInfoMapper.selectMany(from);
//
// contractInfos.forEach(i->{
// try {
// HashMap<Object,Object> h = new HashMap<Object,Object>();
// h.put("api_name", "fut_daily");
// h.put("token", TushareConfig.TOKEN);
// HashMap<Object,Object> params = new HashMap<Object,Object>();
// params.put("ts_code", i.getTs_code());
// h.put("params", params);
// logger.debug("tushare:" + objectMapper.writeValueAsString(h));
//
// InputStream stean =
// Request.Post(TushareConfig.URL)
// .connectTimeout(10000)
// .socketTimeout(10000)
// .bodyString(objectMapper.writeValueAsString(h), ContentType.APPLICATION_JSON)
// .execute()
// .returnContent()
// .asStream();
// JsonNode root = objectMapper.readTree(stean);
// JsonNode items = root.get("data").get("items");
//
// ArrayList<FutDaily> list = new ArrayList<FutDaily>();
//
// for(JsonNode jsonNode : items) {
// FutDaily bean = new FutDaily();
// bean.setTs_code(jsonNode.get(0).asText());
//
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
// LocalDate localDate = LocalDate.parse(jsonNode.get(1).asText(), formatter);
//
// bean.setTrade_date(localDate);
// bean.setPre_close(jsonNode.get(2).asDouble());
// bean.setPre_settle(jsonNode.get(3).asDouble());
// bean.setOpen(jsonNode.get(4).asDouble());
// bean.setHigh(jsonNode.get(5).asDouble());
//
// bean.setLow(jsonNode.get(6).asDouble());
// bean.setClose(jsonNode.get(7).asDouble());
// bean.setSettle(jsonNode.get(8).asDouble());
// bean.setChange1(jsonNode.get(9).asDouble());
// bean.setChange2(jsonNode.get(10).asDouble());
//
// bean.setVol(jsonNode.get(11).asDouble());
// bean.setAmount(jsonNode.get(12).asDouble());
// bean.setOi(jsonNode.get(13).asDouble());
// bean.setOi_chg(jsonNode.get(14).asDouble());
// list.add(bean);
// }
// if(!list.isEmpty()) {
// futDailyMapper.insertMultiple(list);
// }
//
// //Thread.sleep(200);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
//
//
//
// });
//
//
// return R.SUCCESS("getDate is ok");
// }
@Transactional
public void getCurr(String ts_code, ArrayList<FutDaily> list) {
DeleteStatementProvider delete = deleteFrom(FutDailyDynamicSqlSupport.futDaily)
.where(FutDailyDynamicSqlSupport.ts_code, isEqualTo(ts_code))
.build()
.render(RenderingStrategies.MYBATIS3);
futDailyMapper.delete(delete);
futDailyMapper.insertMultiple(list);
}
}

View File

@ -0,0 +1,137 @@
//package jj.tech.finance.biz.webadmin.task;
//
//import static org.mybatis.dynamic.sql.SqlBuilder.*;
//
//import java.io.InputStream;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//
//import org.apache.http.client.fluent.Request;
//import org.apache.http.entity.ContentType;
//import org.mybatis.dynamic.sql.render.RenderingStrategies;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//import org.springframework.web.service.annotation.GetExchange;
//
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.ObjectMapper;
//
//import jj.tech.finance.config.enums.Exchange;
//import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
//import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
//import jj.tech.finance.repository.mybatis.entity.ContractInfo;
//import jj.tech.finance.utils.tushare.TushareConfig;
//
//
//@Component
//public class ContractInfoTime {
// private static Logger logger = LoggerFactory.getLogger(ContractInfoTime.class);
//
// @Autowired ObjectMapper objectMapper;
// @Autowired ContractInfoMapper contractInfoMapper;
//
// /**
// * 同步tushare的合约信息
// */
//// @Scheduled(cron = "0 0 0/4 * * ?") //4小时一次
//// @Scheduled(cron = "0/50 * * * * ?") //50秒一次
// @Scheduled(cron = "0 0 8-17/4 * * ?") //8点到15点之间4小时一次
// public void checkUser() throws Exception {
//
// List<Exchange> exchanges = Arrays.asList(Exchange.values());
//
// exchanges.forEach(i->{
// HashMap<Object,Object> h = new HashMap<Object,Object>();
// h.put("api_name", "fut_basic");
// h.put("token", TushareConfig.TOKEN);
// HashMap<Object,Object> params = new HashMap<Object,Object>();
// params.put("exchange", i);
// h.put("params", params);
// try {
// this.getExchangeDate(i, h);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// });
//
// }
//
// public void getExchangeDate(Exchange exchange, HashMap<Object,Object> parm) throws Exception{
// logger.debug("tushare:" + objectMapper.writeValueAsString(parm));
//
// InputStream stean =
// Request.Post(TushareConfig.URL)
// .connectTimeout(3000)
// .socketTimeout(3000)
// .bodyString(objectMapper.writeValueAsString(parm), ContentType.APPLICATION_JSON)
// .execute()
// .returnContent()
// .asStream();
//// .asString(StandardCharsets.UTF_8);
//
// JsonNode root = objectMapper.readTree(stean);
// JsonNode items = root.get("data").get("items");
//
//
// ArrayList<ContractInfo> list = new ArrayList<ContractInfo>();
// for(JsonNode jsonNode : items) {
// ContractInfo bean = new ContractInfo();
// bean.setTs_code(jsonNode.get(0).asText());
// bean.setSymbol(jsonNode.get(1).asText());
// bean.setExchange(jsonNode.get(2).asText());
// bean.setName(jsonNode.get(3).asText());
// bean.setFut_code(jsonNode.get(4).asText());
// bean.setMultiplier(jsonNode.get(5).asDouble());
//
// bean.setTrade_unit(jsonNode.get(6).asText());
// bean.setPer_unit(jsonNode.get(7).asDouble());
// bean.setQuote_unit(jsonNode.get(8).asText());
// bean.setQuote_unit_desc(jsonNode.get(9).asText());
// bean.setD_mode_desc(jsonNode.get(10).asText());
//
// bean.setList_date(jsonNode.get(11).asText());
// bean.setDelist_date(jsonNode.get(12).asText());
// bean.setD_month(jsonNode.get(13).asText());
// bean.setLast_ddate(jsonNode.get(14).asText());
// list.add(bean);
// }
//
//
// var from = select(ContractInfoMapper.selectList)
// .from(ContractInfoDynamicSqlSupport.contractInfo)
// .where(ContractInfoDynamicSqlSupport.exchange, isEqualTo(exchange.toString()))
// .limit(8888)
// .build()
// .render(RenderingStrategies.MYBATIS3);
//
// List<ContractInfo> contractInfos = contractInfoMapper.selectMany(from);
// Map<String, Object> local =
// contractInfos.stream().collect(
// Collectors.toMap(ContractInfo::getTs_code, i->i)
// );
// //System.out.println(local);
//
//
// List<ContractInfo> bath = new ArrayList<ContractInfo>();
// list.forEach(i->{
// if(local.get(i.getTs_code()) == null) {
// bath.add(i);
// }
// });
// if(!bath.isEmpty()) {
// contractInfoMapper.insertMultiple(bath);
// }
//
//
// }
//
//
//}

View File

@ -0,0 +1,149 @@
//package jj.tech.finance.biz.webadmin.task;
//
//import static org.mybatis.dynamic.sql.SqlBuilder.*;
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//
//import org.apache.http.client.ClientProtocolException;
//import org.apache.http.client.fluent.Request;
//import org.apache.http.entity.ContentType;
//import org.mybatis.dynamic.sql.SqlBuilder;
//import org.mybatis.dynamic.sql.render.RenderingStrategies;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.ObjectMapper;
//
//import jj.tech.finance.config.enums.Exchange;
//import jj.tech.finance.repository.mybatis.dao.ContractInfoMapper;
//import jj.tech.finance.repository.mybatis.dao.FutDailyMapper;
//import jj.tech.finance.repository.mybatis.dao.support.ContractInfoDynamicSqlSupport;
//import jj.tech.finance.repository.mybatis.dao.support.FutDailyDynamicSqlSupport;
//import jj.tech.finance.repository.mybatis.entity.ContractInfo;
//import jj.tech.finance.utils.tushare.TushareConfig;
//
//@Component
//public class FutDailyTime {
// private static Logger logger = LoggerFactory.getLogger(FutDailyTime.class);
//
// @Autowired ObjectMapper objectMapper;
// @Autowired ContractInfoMapper contractInfoMapper;
// @Autowired FutDailyMapper futDailyMapper;
//
// //@Scheduled(cron = "0 0/5 * * * ?") //5分钟
// @Scheduled(cron = "0/50 * * * * ?")
// public void checkUser() throws Exception {
//
// List<Exchange> exchanges = Arrays.asList(Exchange.values());
//
// exchanges.forEach(i->{
// HashMap<Object,Object> h = new HashMap<Object,Object>();
// h.put("api_name", "fut_daily");
// h.put("token", TushareConfig.TOKEN);
// HashMap<Object,Object> params = new HashMap<Object,Object>();
// params.put("ts_code", "RU2310.SHF");
// h.put("params", params);
// try {
// this.getExchangeDate(i, h);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// });
//
// }
//
// public void getExchangeDate(Exchange exchange, HashMap<Object,Object> parm) throws Exception{
// logger.debug("tushare:" + objectMapper.writeValueAsString(parm));
//
//
//
//
//
//
//
//
//
// var ts_codes = select(FutDailyDynamicSqlSupport.ts_code)
// .from(FutDailyDynamicSqlSupport.futDaily)
// .groupBy(FutDailyDynamicSqlSupport.futDaily.ts_code);
//
// var from = select(ContractInfoMapper.selectList)
// .from(ContractInfoDynamicSqlSupport.contractInfo)
// .where(ContractInfoDynamicSqlSupport.contractInfo.ts_code, isNotIn(ts_codes))
// .groupBy(ContractInfoDynamicSqlSupport.contractInfo.ts_code)
// .build()
// .render(RenderingStrategies.MYBATIS3);
//
// List<ContractInfo> contractInfos = contractInfoMapper.selectMany(from);
//
// contractInfos.forEach(i->{
// try {
// HashMap<Object,Object> h = new HashMap<Object,Object>();
// h.put("api_name", "fut_daily");
// h.put("token", TushareConfig.TOKEN);
// HashMap<Object,Object> params = new HashMap<Object,Object>();
// params.put("ts_code", i.getTs_code());
// h.put("params", params);
// logger.debug("tushare:" + objectMapper.writeValueAsString(h));
//
// InputStream stean =
// Request.Post(TushareConfig.URL)
// .connectTimeout(3000)
// .socketTimeout(3000)
// .bodyString(objectMapper.writeValueAsString(h), ContentType.APPLICATION_JSON)
// .execute()
// .returnContent()
// .asStream();
// JsonNode root = objectMapper.readTree(stean);
// JsonNode items = root.get("data").get("items");
//
// ArrayList<ContractInfo> list = new ArrayList<ContractInfo>();
// for(JsonNode jsonNode : items) {
// ContractInfo bean = new ContractInfo();
// bean.setTs_code(jsonNode.get(0).asText());
// bean.setSymbol(jsonNode.get(1).asText());
// bean.setExchange(jsonNode.get(2).asText());
// bean.setName(jsonNode.get(3).asText());
// bean.setFut_code(jsonNode.get(4).asText());
// bean.setMultiplier(jsonNode.get(5).asDouble());
//
// bean.setTrade_unit(jsonNode.get(6).asText());
// bean.setPer_unit(jsonNode.get(7).asDouble());
// bean.setQuote_unit(jsonNode.get(8).asText());
// bean.setQuote_unit_desc(jsonNode.get(9).asText());
// bean.setD_mode_desc(jsonNode.get(10).asText());
//
// bean.setList_date(jsonNode.get(11).asText());
// bean.setDelist_date(jsonNode.get(12).asText());
// bean.setD_month(jsonNode.get(13).asText());
// bean.setLast_ddate(jsonNode.get(14).asText());
// list.add(bean);
// }
//
// Thread.sleep(300);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
//
//
//
// });
//
//
// }
//
//}

View File

@ -0,0 +1,29 @@
package jj.tech.finance.biz.webadmin.vo;
import jj.tech.finance.repository.mybatis.entity.ContractInfo;
public class ContractInfoStatu extends ContractInfo {
public Integer contract_status;
public FuturesZhSpot futuresZhSpot; //合约当前实时数据
public Integer getContract_status() {
return contract_status;
}
public void setContract_status(Integer contract_status) {
this.contract_status = contract_status;
}
public FuturesZhSpot getFuturesZhSpot() {
return futuresZhSpot;
}
public void setFuturesZhSpot(FuturesZhSpot futuresZhSpot) {
this.futuresZhSpot = futuresZhSpot;
}
}

View File

@ -0,0 +1,32 @@
package jj.tech.finance.biz.webadmin.vo;
import java.time.LocalDateTime;
public class ContractInfoStatuScribe extends ContractInfoStatu{
public Integer scribe_status;
public Integer scribe_number;
public LocalDateTime scribe_update_time;
public Integer getScribe_status() {
return scribe_status;
}
public void setScribe_status(Integer scribe_status) {
this.scribe_status = scribe_status;
}
public Integer getScribe_number() {
return scribe_number;
}
public void setScribe_number(Integer scribe_number) {
this.scribe_number = scribe_number;
}
public LocalDateTime getScribe_update_time() {
return scribe_update_time;
}
public void setScribe_update_time(LocalDateTime scribe_update_time) {
this.scribe_update_time = scribe_update_time;
}
}

View File

@ -0,0 +1,15 @@
package jj.tech.finance.biz.webadmin.vo;
public class ContractInfoStatuScribeStore extends ContractInfoStatuScribe {
public Integer store;
public Integer getStore() {
return store;
}
public void setStore(Integer store) {
this.store = store;
}
}

View File

@ -0,0 +1,119 @@
package jj.tech.finance.biz.webadmin.vo;
public class FuturesZhSpot {
public String symbol;
public String time;
public Double open;
public Double high;
public Double low;
public Double current_price;
public Double bid_price;
public Double ask_price;
public Double buy_vol;
public Double sell_vol;
public Double hold;
public Double volume;
public Double avg_price;
public Double last_close;
public Double last_settle_price;
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public Double getOpen() {
return open;
}
public void setOpen(Double open) {
this.open = open;
}
public Double getHigh() {
return high;
}
public void setHigh(Double high) {
this.high = high;
}
public Double getLow() {
return low;
}
public void setLow(Double low) {
this.low = low;
}
public Double getCurrent_price() {
return current_price;
}
public void setCurrent_price(Double current_price) {
this.current_price = current_price;
}
public Double getBid_price() {
return bid_price;
}
public void setBid_price(Double bid_price) {
this.bid_price = bid_price;
}
public Double getAsk_price() {
return ask_price;
}
public void setAsk_price(Double ask_price) {
this.ask_price = ask_price;
}
public Double getBuy_vol() {
return buy_vol;
}
public void setBuy_vol(Double buy_vol) {
this.buy_vol = buy_vol;
}
public Double getSell_vol() {
return sell_vol;
}
public void setSell_vol(Double sell_vol) {
this.sell_vol = sell_vol;
}
public Double getHold() {
return hold;
}
public void setHold(Double hold) {
this.hold = hold;
}
public Double getVolume() {
return volume;
}
public void setVolume(Double volume) {
this.volume = volume;
}
public Double getAvg_price() {
return avg_price;
}
public void setAvg_price(Double avg_price) {
this.avg_price = avg_price;
}
public Double getLast_close() {
return last_close;
}
public void setLast_close(Double last_close) {
this.last_close = last_close;
}
public Double getLast_settle_price() {
return last_settle_price;
}
public void setLast_settle_price(Double last_settle_price) {
this.last_settle_price = last_settle_price;
}
}

View File

@ -0,0 +1,54 @@
package jj.tech.finance.biz.webadmin.vo;
import java.util.List;
import jj.tech.finance.repository.mybatis.entity.ContractInfoStatusScribe;
public class ScribeVo {
public Integer contractid;
public List<ContractInfoStatusScribe> list;
public Integer getContractid() {
return contractid;
}
public void setContractid(Integer contractid) {
this.contractid = contractid;
}
public List<ContractInfoStatusScribe> getList() {
return list;
}
public void setList(List<ContractInfoStatusScribe> list) {
this.list = list;
}
}
class Scribe {
public Integer scribeid;
public Integer scribe_value;
public Integer getScribeid() {
return scribeid;
}
public void setScribeid(Integer scribeid) {
this.scribeid = scribeid;
}
public Integer getScribe_value() {
return scribe_value;
}
public void setScribe_value(Integer scribe_value) {
this.scribe_value = scribe_value;
}
};

View File

@ -0,0 +1,30 @@
package jj.tech.finance.biz.webadmin.vo.parm;
public class Contract extends P{
public String ts_code;
public String symbol;
public String exchange;
public String getTs_code() {
return ts_code;
}
public void setTs_code(String ts_code) {
this.ts_code = ts_code;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getExchange() {
return exchange;
}
public void setExchange(String exchange) {
this.exchange = exchange;
}
}

View File

@ -0,0 +1,51 @@
package jj.tech.finance.biz.webadmin.vo.parm;
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
public class Daily extends P{
public String ts_code;
@DateTimeFormat(pattern = "yyyy-MM-dd")
public LocalDate trade_date;
//public String exchange;
@DateTimeFormat(pattern = "yyyy-MM-dd")
public LocalDate start_date;
@DateTimeFormat(pattern = "yyyy-MM-dd")
public LocalDate end_date;
public String getTs_code() {
return ts_code;
}
public void setTs_code(String ts_code) {
this.ts_code = ts_code;
}
public LocalDate getTrade_date() {
return trade_date;
}
public void setTrade_date(LocalDate trade_date) {
this.trade_date = trade_date;
}
public LocalDate getStart_date() {
return start_date;
}
public void setStart_date(LocalDate start_date) {
this.start_date = start_date;
}
public LocalDate getEnd_date() {
return end_date;
}
public void setEnd_date(LocalDate end_date) {
this.end_date = end_date;
}
}

View File

@ -0,0 +1,18 @@
package jj.tech.finance.biz.webadmin.vo.parm;
import jakarta.validation.constraints.NotNull;
public class Id {
@NotNull
public Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

View File

@ -0,0 +1,20 @@
package jj.tech.finance.biz.webadmin.vo.parm;
import java.util.List;
import jakarta.validation.constraints.NotNull;
public class Ids {
@NotNull
public List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}

View File

@ -0,0 +1,28 @@
package jj.tech.finance.biz.webadmin.vo.parm;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
public class Login {
@NotEmpty
public String username;
@NotEmpty
public String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,25 @@
package jj.tech.finance.biz.webadmin.vo.parm;
public class Minute {
public Integer id; //合约id
public Integer period; //1:1分钟,5:5分钟,15:15分钟,30:30分钟,60:60分钟
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getPeriod() {
return period;
}
public void setPeriod(Integer period) {
this.period = period;
}
}

View File

@ -0,0 +1,21 @@
package jj.tech.finance.biz.webadmin.vo.parm;
public class P {
public Integer pageNum;
public Integer pageSize;
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
}

View File

@ -0,0 +1,30 @@
package jj.tech.finance.biz.webadmin.vo.parm;
public class UserName extends P{
public String username;
public String realname;
public Integer islock;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
public Integer getIslock() {
return islock;
}
public void setIslock(Integer islock) {
this.islock = islock;
}
}

View File

@ -0,0 +1,64 @@
package jj.tech.finance.config.datasource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.zaxxer.hikari.HikariDataSource;
/**
* 定义除spring提供的默认数据源以外的自定义数据源
* 参考 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-access.configure-two-datasources
* https://github.com/spring-projects/spring-boot/issues/20814
* https://github.com/spring-projects/spring-boot/issues/13325
* @author Dou
*/
@Configuration(proxyBeanMethods=false)
public class DataSourceConfig {
@Bean
@Primary
@ConditionalOnClass(HikariDataSource.class)
//@ConfigurationProperties("spring.datasource")
HikariDataSource dataSource(DataSourceProperties properties) {
return (HikariDataSource) properties.initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
// /**
// * 数据库名称url:需要改成jdbc-url其他名称值和spring默认的一样
// * 就可以自动注入
// */
// @Bean("dataSource2")
// @ConfigurationProperties("app.datasource")
// public HikariDataSource dataSource2() {
// return (HikariDataSource) DataSourceBuilder.create()
// .type(HikariDataSource.class).build();
// }
// /**
// * @p DataSourceProperties
// * @p 如果没有 显示的提供 url 用户名密码; 创建一个默认的嵌入式的数据库
// * @p 并提供url/jdbcUrl的转化
// * @p @EnableConfigurationProperties(DataSourceProperties.class)这个注解可以不用加因为
// * spring 在初始化 DataSourceAutoConfiguration的时候会初始化DataSourceProperties这个类到spring上下文
// */
// @Bean
// @Primary
// @ConfigurationProperties("spring.datasource")
// public DataSourceProperties dataSourceProperties() {
// return new DataSourceProperties();
// }
}

View File

@ -0,0 +1,15 @@
package jj.tech.finance.config.enums;
public enum Exchange {
CZCE("郑州商品交易所"), SHFE("上海期货交易所"), DCE("大连商品交易所"),
CFFEX("中国金融期货交易所"), INE("上海国际能源交易所"), GFEX("广州期货交易所");
public String name;
Exchange(String name) {
this.name=name;
}
public String getName() {
return this.name;
}
}

View File

@ -0,0 +1,11 @@
package jj.tech.finance.config.enums;
public class SysConfigGroup {
public static String grup_rulenotice = "rulenotice";
public static String key_rulenotice_due = "rulenotice_due";
}

View File

@ -0,0 +1,134 @@
package jj.tech.finance.config.jooq;
import javax.sql.DataSource;
import org.jooq.ConnectionProvider;
import org.jooq.DSLContext;
import org.jooq.ExecuteListenerProvider;
import org.jooq.impl.DataSourceConnectionProvider;
import org.jooq.impl.DefaultConfiguration;
import org.jooq.impl.DefaultDSLContext;
import org.jooq.impl.DefaultExecuteListenerProvider;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jooq.DefaultConfigurationCustomizer;
import org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator;
import org.springframework.boot.autoconfigure.jooq.JooqProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.transaction.PlatformTransactionManager;
/**
* jooq使用单个jdbc链接的时候自己不管理数据库链接开关也不管理事物的开关由外部管理
* jooq使用数据源的时候每次执行先获取一个链接执行完毕还给连接池
*
* @注意该类参考spring-boot-autoconfigure自动配置jooq包下的JooqAutoConfiguration
* 源码复制直接用 因为spring自动配置包下大多数类不是public类只能重写
*
* @在单数据源情况下不用配置任何东西spring boot 默认配置非常优秀
* 需要注意的是事务的传播特性spring boot jooq默认是嵌入事务
* https://blog.jooq.org/nested-transactions-in-jooq/
* @jooq代码中写sql
* https://blog.jooq.org/using-java-13-text-blocks-for-plain-sql-with-jooq/
*
* @关于嵌入事务: 错误只回滚自己其他成功的所有事务都成功
* https://stackoverflow.com/questions/6683929/propagation-nested-vs-propagation-required-in-spring
* @jooq与jpa按作者的表述他不愿意支持ORM
* https://github.com/jOOQ/jOOQ/issues/11685
* @jooq与r2dbc胶水写法脱裤子放屁
* https://github.com/jOOQ/jOOQ/issues/11700
* https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples
* https://blog.jooq.org/reactive-sql-with-jooq-3-15-and-r2dbc
* @examples
* https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples
*
* @Dou 2020/8/13
*/
@ConditionalOnClass(DSLContext.class)
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(JooqProperties.class)
@Configuration(proxyBeanMethods = false)
public class JooqConfig {
/**
* 创建使用默认数据源和spring默认嵌入式事务管理器的DSLContext
*/
@Bean
DefaultDSLContext dsl(org.jooq.Configuration configuration) {
return new DefaultDSLContext(configuration);
}
@Bean
DefaultConfiguration jooqConfiguration(
JooqProperties properties,
DataSource dataSource,
PlatformTransactionManager txManager){
DefaultConfiguration configuration = new DefaultConfiguration();
configuration.set(properties.determineSqlDialect(dataSource));
configuration.set(new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource)));
configuration.set(new JooqSpringTransactionProvider(txManager)); //spring提供的默认嵌入式事务PROPAGATION_NESTED
configuration.set(new DefaultExecuteListenerProvider(new JooqExceptionTranslator()));
return configuration;
}
//
// /**
// * @spring的事物管理器
// * 如果添加spring-boot-starter-jdbc 依赖框架会默认注入 DataSourceTransactionManager 实例
// * 如果你添加的是 spring-boot-starter-data-jpa 会注入 JpaTransactionManager
// *
// * @可以指定为DataSourceTransactionManagerspring boot的自动配置没有指定所以这里也不指定
// * 直接指定DataSourceTransactionManager可以参考 https://www.jooq.org/doc/3.18/manual/sql-execution/transaction-management/
//
// * @SpringTransactionProvider 已知bug,不适用于 jOOQ 的异步事务: https://github.com/jOOQ/jOOQ/issues/10850
// * 并且r2dbc有同样的问题 https://github.com/spring-projects/spring-framework/issues/28133
// * 可以取消SpringTransactionProvider事务管理并使用JOOP自己的事务管理解决
// * this.dslContext = dslContext.configuration().derive((TransactionProvider) null).dsl();
// */
// @Bean
// JooqSpringTransactionProvider jooqSpringTransactionProvider(
// PlatformTransactionManager txManager) {
// return new JooqSpringTransactionProvider(txManager);
// }
//
//
// /**
// * jooq提供对对外的使用外部的数据库链接DataSourceConnectionProvider代理类
// * 这里使用TransactionAwareDataSourceProxy 可以动态的发现spring 事物上下文transaction context
// */
// @Bean
// DataSourceConnectionProvider dataSourceConnectionProvider(
// @Qualifier("dataSource2") DataSource dataSource2) {
// return new DataSourceConnectionProvider(
// new TransactionAwareDataSourceProxy(dataSource2));
// }
//
// @Bean
// SQLDialect sQLDialect(
// JooqProperties properties,
// @Qualifier("dataSource2") DataSource dataSource2) {
// return properties.determineSqlDialect(dataSource2);
// }
//
// @Bean("dsl2")
// DSLContext dsl2(
// DataSourceConnectionProvider dataSourceConnectionProvider,
// SQLDialect sQLDialect,
// JooqSpringTransactionProvider jooqSpringTransactionProvider) {
//
// DefaultConfiguration config = new DefaultConfiguration();
// config.set(sQLDialect);
// config.set(dataSourceConnectionProvider);
// config.set(jooqSpringTransactionProvider); //spring提供的默认嵌入式事务PROPAGATION_NESTED
// config.set(new DefaultExecuteListenerProvider(new JooqExceptionTranslator()));
// return new DefaultDSLContext(config);
// }
}

View File

@ -0,0 +1,23 @@
package jj.tech.finance.config.jooq;
import org.jooq.Transaction;
import org.springframework.transaction.TransactionStatus;
/**
* @ 直接复制 org.springframework.boot.autoconfigure.jooq.SpringTransaction类
* 因为不是public只能自己写一个
* @author Dou
*/
public class JooqSpringTransaction implements Transaction{
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
private final TransactionStatus transactionStatus;
JooqSpringTransaction(TransactionStatus transactionStatus) {
this.transactionStatus = transactionStatus;
}
TransactionStatus getTxStatus() {
return this.transactionStatus;
}
}

View File

@ -0,0 +1,55 @@
package jj.tech.finance.config.jooq;
import org.jooq.TransactionContext;
import org.jooq.TransactionProvider;
import org.jooq.tools.JooqLogger;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* 修改默认事务传播行为成PROPAGATION_REQUIRED
* 参考 org.springframework.boot.autoconfigure.jooq.SpringTransactionProvider
* 修改TransactionDefinition.PROPAGATION_NESTED PROPAGATION_REQUIRED
* @author Dou
*
*/
public class JooqSpringTransactionProvider implements TransactionProvider{
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
private static final JooqLogger log = JooqLogger.getLogger(JooqSpringTransactionProvider.class);
private final PlatformTransactionManager transactionManager;
public JooqSpringTransactionProvider(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
@Override
public void begin(TransactionContext context) {
log.info("--> begin transaction --->");
TransactionDefinition definition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NESTED); //PROPAGATION_REQUIRED
TransactionStatus status = this.transactionManager.getTransaction(definition);
context.transaction(new JooqSpringTransaction(status));
}
@Override
public void commit(TransactionContext ctx) {
log.info("--> commit transaction --->");
this.transactionManager.commit(getTransactionStatus(ctx));
}
@Override
public void rollback(TransactionContext ctx) {
log.error("<-- rollback transaction <---");
this.transactionManager.rollback(getTransactionStatus(ctx));
}
private TransactionStatus getTransactionStatus(TransactionContext ctx) {
JooqSpringTransaction transaction = (JooqSpringTransaction) ctx.transaction();
return transaction.getTxStatus();
}
}

View File

@ -0,0 +1,51 @@
//package jj.tech.dcang.config.jpa;
//
//import javax.sql.DataSource;
//
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
//import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
//import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
//import org.springframework.orm.jpa.JpaTransactionManager;
//import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
//import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
//import org.springframework.transaction.PlatformTransactionManager;
///**
// * JPA多数据源配置,单一数据源由spring boot默认配置
// * https://github.com/spring-projects/spring-data-examples/blob/main/jpa/multiple-datasources/src/main/java/example/springdata/jpa/multipleds/customer/CustomerConfig.java
// * @author Dou
// *
// */
////@Configuration
////@EnableJpaRepositories(entityManagerFactoryRef = "customerEntityManagerFactory",
//// transactionManagerRef = "customerTransactionManager")
//public class JpaConfig {
//// @Bean
//// PlatformTransactionManager customerTransactionManager() {
//// return new JpaTransactionManager(customerEntityManagerFactory().getObject());
//// }
////
//// @Bean
//// LocalContainerEntityManagerFactoryBean customerEntityManagerFactory() {
////
//// var jpaVendorAdapter = new HibernateJpaVendorAdapter();
//// jpaVendorAdapter.setGenerateDdl(true);
////
//// var factoryBean = new LocalContainerEntityManagerFactoryBean();
////
//// factoryBean.setDataSource(customerDataSource());
//// factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
//// factoryBean.setPackagesToScan(JpaConfig.class.getPackage().getName());
////
//// return factoryBean;
//// }
////
//// @Bean
//// DataSource customerDataSource() {
//// return new EmbeddedDatabaseBuilder().//
//// setType(EmbeddedDatabaseType.HSQL).//
//// setName("customers").//
//// build();
//// }
//}

View File

@ -0,0 +1,46 @@
package jj.tech.finance.config.json;
import java.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
@Configuration
public class JacksonConfiguration {
@Value("${spring.jackson.date-format}")
public String DATETIME_FORMAT;
/**
* LoaclTime格式化字符串
*/
public String TIME_FORMAT = "HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
// formatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATETIME_FORMAT);
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_FORMAT);
// deserializers
builder.deserializers(new LocalDateTimeDeserializer(dateTimeFormatter));
builder.deserializers(new LocalTimeDeserializer(timeFormatter));
// serializers
builder.serializers(new LocalDateTimeSerializer(dateTimeFormatter));
builder.serializers(new LocalTimeSerializer(timeFormatter));
};
}
}

View File

@ -0,0 +1,37 @@
package jj.tech.finance.config.security;
import java.util.List;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class Cors {
@Bean
CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOriginPattern("*");
// corsConfiguration.addAllowedOrigin("file:///C:/Users/lenovo/Desktop/x.html");
// corsConfiguration.addAllowedOrigin("http://localhost:8080");
// corsConfiguration.addAllowedOrigin("http://localhost:80");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
@Bean
public FilterRegistrationBean<CorsFilter> filterRegistrationBean(CorsFilter corsFilter) {
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(corsFilter);
bean.setOrder(1);
return bean;
}
}

View File

@ -0,0 +1,103 @@
package jj.tech.finance.config.security;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jj.tech.finance.utils.CookieUtil;
import jj.tech.finance.utils.JsonUtil;
import jj.tech.finance.utils.JwtUtil;
import jj.tech.finance.utils.WebAdminUtil;
/**
* cors开头命名为了使该过滤器在CorsFilter之后执行
* @author admin
*
*/
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class SecurityAdminFilter extends OncePerRequestFilter {
AntPathMatcher matcher = new AntPathMatcher();
/**
* 不需要token就能访问的url
*/
List<String> allowUrls = Arrays.asList(
"/web/**",
"/ws**/**",
"/swagger-ui/index.html", "/swagger-ui/**", "/v3/**",
"/favicon.ico",
"/op/login","/op/logout",
"/h2-console**/**");
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 忽略的urls
if (this.isIgnoreUrl(request.getRequestURI())) {
// 向后执行
filterChain.doFilter(request, response);
return;
}
// 更新token的有效时间
Boolean verify = WebAdminUtil.verify(request, response);
if(verify == false) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
this.authError(request, response);
return;
}
filterChain.doFilter(request, response);
}
/**
* 判断当前 requestURI 是否需要token访问
*
* @param requestURI uri
* @return
*/
protected Boolean isIgnoreUrl(String requestURI) {
for (String i : allowUrls) {
if (matcher.match(i, requestURI)) {
return true;
}
}
return false;
}
/**
* 无token返回
*
* @param request
* @param response
*/
protected void authError(HttpServletRequest request, HttpServletResponse response) {
//request
response.setContentType("application/json;charset=UTF-8");
String msg = "请求访问:" + request.getRequestURI() + ",token验证失败无法访问资源";
HashMap<String, Object> map = new HashMap<>();
map.put("code", 401);
map.put("msg", msg);
try {
response.getWriter().write(JsonUtil.writeValueAsString(map));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,104 @@
package jj.tech.finance.config.security;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jj.tech.finance.utils.CookieUtil;
import jj.tech.finance.utils.JsonUtil;
import jj.tech.finance.utils.JwtUtil;
import jj.tech.finance.utils.WebAdminUtil;
import jj.tech.finance.utils.WebUserUtil;
/**
* cors开头命名为了使该过滤器在CorsFilter之后执行
* @author admin
*
*/
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class SecurityWebFilter extends OncePerRequestFilter {
AntPathMatcher matcher = new AntPathMatcher();
/**
* 不需要token就能访问的url
*/
List<String> allowUrls = Arrays.asList(
"/op/**",
"/ws**/**",
"/swagger-ui/index.html", "/swagger-ui/**", "/v3/**",
"/favicon.ico",
"/web/login","/web/logout",
"/h2-console**/**");
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 忽略的urls
if (this.isIgnoreUrl(request.getRequestURI())) {
// 向后执行
filterChain.doFilter(request, response);
return;
}
// 更新token的有效时间
Boolean verify = WebUserUtil.verify(request, response);
if(verify == false) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
this.authError(request, response);
return;
}
filterChain.doFilter(request, response);
}
/**
* 判断当前 requestURI 是否需要token访问
*
* @param requestURI uri
* @return
*/
protected Boolean isIgnoreUrl(String requestURI) {
for (String i : allowUrls) {
if (matcher.match(i, requestURI)) {
return true;
}
}
return false;
}
/**
* 无token返回
*
* @param request
* @param response
*/
protected void authError(HttpServletRequest request, HttpServletResponse response) {
//request
response.setContentType("application/json;charset=UTF-8");
String msg = "请求访问:" + request.getRequestURI() + ",token验证失败无法访问资源";
HashMap<String, Object> map = new HashMap<>();
map.put("code", 401);
map.put("msg", msg);
try {
response.getWriter().write(JsonUtil.writeValueAsString(map));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,144 @@
package jj.tech.finance.config.swagger;
import java.util.Collections;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
/**
* swagger配置
* 加入分组功能(默认注释掉)
*
* @author Dou
* @date 2022/6/30
**/
@Configuration
public class SwaggerConfig {
@Bean
OpenAPI springShopOpenAPI() {
SecurityScheme securityScheme = new SecurityScheme();
securityScheme.type(SecurityScheme.Type.HTTP)
.scheme("bearer").bearerFormat("JWT")
.in(SecurityScheme.In.HEADER)
.scheme("basic");
Components compoenents = new Components();
compoenents.addSecuritySchemes("bearer-key", securityScheme);
return new OpenAPI()
// .components(compoenents)
.info(new Info().title("JJ Finance 接口文档")
.description("Spring application")
.version("v1.0.0")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
// .security(Collections.singletonList(new SecurityRequirement().addList("bearer-key")))
;
}
// @Bean
// @Profile("prod")
// GroupedOpenApi prodApi(OpenAPI openAPI) {
// return GroupedOpenApi.builder()
// .group("user-test-api")
// .pathsToMatch("/null")
// .addOpenApiCustomizer(api -> {
// api = openAPI;
// })
// .pathsToExclude("/health/*")
// .build();
// }
// @Bean
// //@Profile("!prod")
// GroupedOpenApi loginApi(OpenAPI openAPI) {
// String paths[] = {"/op/login", "/op/logout"};
// return GroupedOpenApi.builder()
// .group("login")
//// .packagesToScan("tech.bcnew.modular.authaudit.controller")
// .pathsToMatch(paths)
// .addOpenApiCustomizer(api -> {
// api = openAPI;
// })
// .pathsToExclude("/health/*")
// .build();
// }
// @Bean
// @Profile("!prod")
// GroupedOpenApi jpaApi(OpenAPI openAPI) {
// String packagesToscan[] = {"jj.tech.dcang.repository"};
// return GroupedOpenApi.builder()
// .group("jpa")
// .packagesToScan(packagesToscan)
// .addOpenApiCustomizer(api -> {
// api = openAPI;
// })
// .pathsToExclude("/health/*")
// .build();
// }
// @Bean
// @Profile("!prod")
// GroupedOpenApi webApi(OpenAPI openAPI) {
// return GroupedOpenApi.builder()
// .group("web")
// .pathsToMatch("/web/**")
// //.packagesToScan("/jj/tech/paolu/biz/**")
// .addOpenApiCustomizer(api -> {
// api = openAPI;
// })
// .pathsToExclude("/health/*","/jpa*")
// .build();
// }
@Bean
//@Profile("!prod")
GroupedOpenApi webAdminApi(OpenAPI openAPI) {
return GroupedOpenApi.builder()
.group("op")
.pathsToMatch("/op/**")
//.pathsToExclude("/op/login", "/op/logout")
//.packagesToScan("/jj/tech/paolu/biz/**")
.addOpenApiCustomizer(api -> {
api = openAPI;
})
.pathsToExclude("/health/*","/jpa*")
.build();
}
@Bean
//@Profile("!prod")
GroupedOpenApi webApi(OpenAPI openAPI) {
return GroupedOpenApi.builder()
.group("web")
.pathsToMatch("/web/**")
//.packagesToScan("/jj/tech/paolu/biz/**")
.addOpenApiCustomizer(api -> {
api = openAPI;
})
.pathsToExclude("/health/*","/jpa*")
.build();
}
}

View File

@ -0,0 +1,40 @@
//package jj.tech.dcang.config.ws;
//
//import java.util.HashMap;
//import java.util.Map;
//
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.web.socket.CloseStatus;
//import org.springframework.web.socket.TextMessage;
//import org.springframework.web.socket.WebSocketSession;
//import org.springframework.web.socket.handler.TextWebSocketHandler;
//
//public class SocketHandler extends TextWebSocketHandler {
//
// public final Map<String, WebSocketSession> sessions = new HashMap<>();
//
// @Override
// public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// String path = StringUtils.substringAfterLast(session.getUri().getPath(), "/");
// System.out.println(path);
// sessions.put(path, session);
//
// super.afterConnectionEstablished(session);
// }
//
// @Override
// protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// String payload = message.getPayload();
// System.out.println(payload);
//// for (Map.Entry<String, WebSocketSession> otherSession : sessions.entrySet()) {
//// if (otherSession.getKey().equals(session.getId())) continue;
//// otherSession.getValue().sendMessage(new TextMessage("ssss"+payload));
//// }
// }
//
// @Override
// public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// sessions.remove(session.getId());
// super.afterConnectionClosed(session, status);
// }
//}

View File

@ -0,0 +1,30 @@
//package jj.tech.dcang.config.ws;
//
//
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.web.socket.WebSocketHandler;
//import org.springframework.web.socket.config.annotation.EnableWebSocket;
//import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
//import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
//
//@Configuration
//@EnableWebSocket
//public class WebSocketConfig implements WebSocketConfigurer {
//
//
// public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// registry.addHandler(myHandler(), "/ws/{id}", "/ws")
// .setAllowedOrigins("*")
//// .setAllowedOrigins("file:///E:/ss.html")
//// .setAllowedOriginPatterns("*")
// ;
//// .withSockJS();
// }
//
// @Bean
// public WebSocketHandler myHandler() {
// return new SocketHandler();
// }
//
//}

View File

@ -0,0 +1,102 @@
package jj.tech.finance.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
public class AES {
private Cipher CBC;
private Cipher ECB;
private IvParameterSpec ivParameterSpec;
private SecretKeySpec secretKeySpec;
public AES(){
this("ssdkF$HUy2A#D%kd","weJiSEvR5yAC5ftB");
}
public AES(String KEY, String IV){
try {
this.CBC = Cipher.getInstance("AES/CBC/PKCS5PADDING");
this.ECB = Cipher.getInstance("AES/ECB/PKCS5PADDING");
this.ivParameterSpec = new IvParameterSpec(IV.getBytes(Charset.defaultCharset()));
this.secretKeySpec = new SecretKeySpec(KEY.getBytes(Charset.defaultCharset()), "AES");
} catch (Exception e) {
e.printStackTrace();
}
}
public String encryptCBC(String toBeEncrypt){
try {
CBC.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = CBC.doFinal(toBeEncrypt.getBytes());
return Base64.encodeBase64URLSafeString(encrypted);
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
public String decryptCBC(String encrypted){
try {
CBC.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedBytes = CBC.doFinal(Base64.decodeBase64(encrypted));
return new String(decryptedBytes);
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
public String encrypt(String toBeEncrypt){
try {
ECB.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encrypted = ECB.doFinal(toBeEncrypt.getBytes());
return Base64.encodeBase64URLSafeString(encrypted);
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
public String decrypt(String encrypted){
try {
ECB.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedBytes = ECB.doFinal(Base64.decodeBase64(encrypted));
return new String(decryptedBytes);
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
AES a = new AES();
String s = a.encryptCBC("111");
String v = a.decryptCBC(s);
System.out.println(s);
System.out.println(v);
String bb = a.encrypt("222");
String cc = a.decrypt(bb);
System.out.println(bb);
System.out.println(cc);
String m = DigestUtils.sha3_256Hex("000000");
System.out.println("sha3256:"+m);
System.out.println(a.encrypt("555555555551"));
System.out.println(a.decrypt(a.encrypt("555555555551")));
}
}

View File

@ -0,0 +1,66 @@
package jj.tech.finance.utils;
import java.util.Arrays;
import org.apache.commons.lang3.StringUtils;
public class AlphaUtils {
public static String getNext(String charSeqStr) {
String nextCharSeqStr = null;
char[] charSeqArr = null;
boolean isResetAllChar = false;
boolean isResetAfterIndex = false;
Integer resetAfterIndex = 0;
if (StringUtils.isBlank(charSeqStr)) {
charSeqArr = new char[] { 'A' };
} else {
charSeqArr = charSeqStr.toCharArray();
Integer charSeqLen = charSeqArr.length;
for (int index = charSeqLen - 1; index >= 0; index--) {
char charAtIndex = charSeqArr[index];
if (Character.getNumericValue(charAtIndex) % 35 == 0) {
if (index == 0) {
charSeqArr = Arrays.copyOf(charSeqArr, charSeqLen + 1);
isResetAllChar = true;
} else {
continue;
}
} else {
char nextCharAtIndex = (char) (charAtIndex + 1);
charSeqArr[index] = nextCharAtIndex;
if (index + 1 < charSeqLen) {
isResetAfterIndex = true;
resetAfterIndex = index;
}
break;
}
}
charSeqLen = charSeqArr.length;
if (isResetAllChar) {
for (int index = 0; index < charSeqLen; index++) {
charSeqArr[index] = 'A';
}
} else if (isResetAfterIndex) {
for (int index = resetAfterIndex + 1; index < charSeqLen; index++) {
charSeqArr[index] = 'A';
}
}
}
nextCharSeqStr = String.valueOf(charSeqArr);
return nextCharSeqStr;
}
public static void main(String args[]) {
String nextAlphaSequence = null;
for (int index = 0; index < 55; index++) {
nextAlphaSequence = AlphaUtils.getNext(nextAlphaSequence);
System.out.println(nextAlphaSequence);
}
}
}

View File

@ -0,0 +1,112 @@
package jj.tech.finance.utils;
import java.io.UnsupportedEncodingException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class CookieUtil {
private static final String DEFAULT_PATH = "/";
private static final int DEFAULT_AGE = -1;
private static String path = DEFAULT_PATH;
private static int age = DEFAULT_AGE;
/**
* 添加cookie
* @param name
* @param value
* @param response
* @param maxAge
* @throws UnsupportedEncodingException
*/
public static void add(String name, String value,HttpServletResponse response){
try {
// Cookie cookie = new Cookie(name,URLEncoder.encode(value,"utf-8"));
// byte[] compressed =Snappy.compress(value.getBytes("UTF-8"));//压缩
Cookie cookie = new Cookie(name, value);
cookie.setMaxAge(age);
cookie.setPath(path);
// cookie.setDomain("localhost");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除cookie
* @param name
* @param response
*/
public static void delete(HttpServletResponse response,String name){
Cookie cookie = new Cookie(name,"");
cookie.setMaxAge(0);
cookie.setPath(path);
response.addCookie(cookie);
}
public static void deleteAll(HttpServletRequest request, HttpServletResponse response){
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
cookie.setMaxAge(0);
cookie.setPath(path);
response.addCookie(cookie);
}
}
}
/**
* 改变cookie的值
* @param cookie
* @param value
*/
public static void edit(Cookie cookie,String value){
if(cookie != null) cookie.setValue(value);
}
/**
* 更加cookie名称查找返回其值
* 找不到返回null
* @param request
* @param name
* @return
*/
public static String fine(HttpServletRequest request,String name){
try {
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(name.equals(cookie.getName()))
{
// byte[] cookitValue = Base64.decodeBase64(cookie.getValue());
// byte[] uncompressed = Snappy.uncompress(cookitValue);
// return URLDecoder.decode(cookie.getValue(), "utf-8");
// return new String (uncompressed,"UTF-8");
return cookie.getValue();
}
}
}
return null;
} catch (Exception e) {
return null;
}
}
public static Cookie get(HttpServletRequest request,String name){
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(name.equals(cookie.getName()))
return cookie;
}
}
return null;
}
}

View File

@ -0,0 +1,124 @@
package jj.tech.finance.utils;
import org.springframework.stereotype.Component;
import java.util.Random;
/**
* Twitter的SnowFlake算法
* 1111111111111111111111111100000000000000000000000 42位时间
* 1111111111111111111111111111111100000000000000000 5位数据中心ID
* 1111111111111111111111111111111111111000000000000 5位机器ID
* 0000000000000000000000000000000000000111111111111 12位sequenceBits
* 4个值或运算组成一个新的Long
* @DOU
*/
@Component
public class IDHelp {
// private static final Logger LOG = LoggerFactory.getLogger(IDHelp.class);
private static IDHelp instance;
private long workerId = 1; //只有五位,0<=workerId<32
private long datacenterId = 1; //只有5位, 0<=datacenterId<32
private long startTime = 1661370468606L; //42位bit,第1位固定正数0开始后最大能使用69年
private long workerIdBits = 5L; //5bit机器ID
private long datacenterIdBits = 5L; //5bit数据中心ID
private long sequenceBits = 12L; //12位bit,同毫秒内产生的不同id
private long workerIdLeft = sequenceBits; //左移量
private long datacenterIdLeft = sequenceBits + workerIdBits;
private long timestampLeft = sequenceBits + workerIdBits + datacenterIdBits; //22位64-22=42位
private long sequence = 0L; //每毫秒初始值
private long lastTimestamp = -1L; //上一次当前毫秒
private long sequenceMax = -1L ^ (-1L << sequenceBits); //sequenceMax 最大值 4095
private IDHelp() {
}
public synchronized Long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
// LOG.error(String.format("clock is moving backwards. Rejecting requests until %d.", lastTimestamp));
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMax;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// String.valueOf(((timestamp - startTime) << timestampLeft) | (datacenterId << datacenterIdLeft) | (workerId << workerIdLeft) | sequence)
return ((timestamp - startTime) << timestampLeft) | (datacenterId << datacenterIdLeft) | (workerId << workerIdLeft) | sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
* @param workerId 机器ID
* @param datacenterId 数据中心ID
* @return
*/
public static IDHelp getInstance(Integer workerId, Integer datacenterId) {
if(workerId<0 || datacenterId<0) {
throw new RuntimeException("workerId || datacenterId < 0");
}
if(workerId>31 || datacenterId>31) {
throw new RuntimeException("workerId || datacenterId > 31");
}
if(instance==null){
IDHelp bean= new IDHelp();
bean.workerId = workerId;
bean.datacenterId = datacenterId;
instance = bean;
}
return instance;
}
public static IDHelp getInstance() {
Random r = new Random();
r.nextInt(32);
return IDHelp.getInstance(r.nextInt(32), r.nextInt(32));
}
public static IDHelp getDefInstance() {
return IDHelp.getInstance(0, 0);
}
public static void main(String[] args) {
System.err.println(System.currentTimeMillis());
IDHelp id = IDHelp.getDefInstance();
for(int i=0; i<100000; i++) {
System.out.println(id.nextId());
}
}
}

View File

@ -0,0 +1,110 @@
package jj.tech.finance.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* json转换工具类
*/
public class JsonUtil {
private static Logger log = LoggerFactory.getLogger(JsonUtil.class);
private static ObjectMapper objectMapper = new ObjectMapper();
static {
// //将对象的所有字段全部列入
// objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);
//
// //取消默认转换timestamps形式,false使用日期格式转换true不使用日期转换结果是时间的数值157113793535
// objectMapper.configure(SerializationConfig.Feature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false); //默认值true
//
// //忽略空Bean转json的错误
// objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);
//
// //所有的日期格式统一样式 yyyy-MM-dd HH:mm:ss
// objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));
//
// //忽略 在json字符串中存在但是在对象中不存在对应属性的情况防止错误
// // 例如json数据中多出字段而对象中没有此字段如果设置true抛出异常因为字段不对应false则忽略多出的字段默认值为null将其他字段反序列化成功
// objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_NULL_FOR_PRIMITIVES,false);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false);
objectMapper.registerModule(javaTimeModule);
}
//将单个对象转换成json格式的字符串没有格式化后的json
public static <T> String writeValueAsString(T obj){
if (obj == null){
return null;
}
try {
return obj instanceof String ? (String) obj:objectMapper.writeValueAsString(obj);
} catch (IOException e) {
log.warn("Parse object to String error", e);
return null;
}
}
//将单个对象转换成json格式的字符串格式化后的json
public static <T> String writeValueAsStringPretty(T obj){
if (obj == null){
return null;
}
try {
return obj instanceof String ? (String) obj:objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (IOException e) {
log.warn("Parse object to String error", e);
return null;
}
}
//将json形式的字符串数据转换成单个对象
public static <T> T readValueToObj(String str, Class<T> clazz){
if (StringUtils.isEmpty(str) || clazz == null){
return null;
}
try {
return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str,clazz);
} catch (IOException e) {
log.warn("Parse object to Object error", e);
return null;
}
}
//将json形式的字符串数据转换成多个对象
// public static <T> T string2Obj(String str, TypeReference<T> typeReference){
// if (StringUtils.isEmpty(str) || typeReference == null){
// return null;
// }
// try {
// return typeReference.getType().equals(String.class) ? (T) str : (T) objectMapper.readValue(str, typeReference);
// } catch (IOException e) {
// log.warn("Parse object to Object error", e);
// return null;
// }
// }
//将json形式的字符串数据转换成多个对象
public static <T> T readValueToList(String str, Class<T> collectionClass, Class<?>... elementClasses){
try {
return objectMapper.readValue(str, objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses));
} catch (IOException e) {
log.warn("Parse object to Object error", e);
return null;
}
}
}

View File

@ -0,0 +1,149 @@
package jj.tech.finance.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.*;
import io.jsonwebtoken.jackson.io.JacksonDeserializer;
import io.jsonwebtoken.jackson.io.JacksonSerializer;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.time.Instant;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);
private static final String CLAIM_KEY_CREATED = "created";
public static final String HMACSHA256 = "HMACSHA256";
public static final String SECRET = "fn4hIX5+d29jYW8seWFtYWRpZSx3YW5kYW5sZX5+ISF+fg==";
public static final SecretKey DEFAULT_SECRET_KEY = new SecretKeySpec(Base64.getDecoder().decode(SECRET), HMACSHA256);
public static ObjectMapper objectMapper = new ObjectMapper();
private static long exp = 10 * 60 * 60 * 1000; //过期时间
/**
* 根据负责生成JWT的token
*/
public static String generateToken(Map<String, Object> claims) {
claims.put(CLAIM_KEY_CREATED, new Date());
JwtBuilder builder = Jwts.builder()
.setClaims(claims)
.compressWith(CompressionCodecs.GZIP)
.serializeToJsonWith(new JacksonSerializer(objectMapper))
.signWith(JwtUtil.DEFAULT_SECRET_KEY);
if (exp > 0) {
long nowMillis = System.currentTimeMillis();
builder.setExpiration(new Date(nowMillis + exp));
}
return builder.compact();
}
/**
* 当原来的token没过期时是可以刷新的
*
* @param oldToken 带tokenHead的token
*/
public static String refreshHeadToken(String oldToken) {
if(StringUtils.isEmpty(oldToken)){
return null;
}
//token校验不通过
Claims claims = getClaimsFromToken(oldToken);
if(claims==null){
return null;
}
//如果token已经过期不支持刷新
Date expiredDate = claims.getExpiration();
if(expiredDate.before(new Date())){
return null;
}
//如果token在30分钟之内刚刷新过返回原token
if(tokenRefreshJustBefore(oldToken,30*60)){
return oldToken;
}else{
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
}
/**
* 判断token在指定时间内是否刚刚刷新过
* @param token 原token
* @param time 指定时间
*/
public static boolean tokenRefreshJustBefore(String token, int time) {
Claims claims = getClaimsFromToken(token);
Date created = claims.get(CLAIM_KEY_CREATED, Date.class);
Date refreshDate = new Date();
//刷新时间在创建时间的指定时间内
if(refreshDate.after(created)&&refreshDate.before(DateUtils.addSeconds(created,time))){
return true;
}
return false;
}
/**
* 从token中获取JWT中的负载
*/
public static Claims getClaimsFromToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
logger.info("JWT格式验证失败:{}", token);
}
return claims;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public JwtBuilder jwtBuilder() {
return Jwts.builder()
.compressWith(CompressionCodecs.GZIP)
.serializeToJsonWith(new JacksonSerializer(objectMapper))
.signWith(JwtUtil.DEFAULT_SECRET_KEY);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public JwtParser jwtParser() {
return Jwts.parserBuilder()
.deserializeJsonWith(new JacksonDeserializer(objectMapper))
.setSigningKey(DEFAULT_SECRET_KEY)
.build();
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
JwtUtil jwtUtil = new JwtUtil();
//Create the TOKEN
HashMap<String,String> b = new HashMap<String,String>();
b.put("x", "11");
b.put("y", "22");
Claims claim = Jwts.claims();
claim.put("a", "aa");
claim.put("b", b);
claim.setExpiration(Date.from(Instant.now().plusSeconds(2L)));
var encoder = jwtUtil.jwtBuilder().setClaims(claim).compact();
System.out.println(encoder);
//Decode the TOKEN
var jwtParser = jwtUtil.jwtParser();
jwtParser.isSigned(encoder);
Jws<Claims> claims = (Jws<Claims>) jwtParser.parse(encoder);
System.out.println(claims.getBody());
}
}

View File

@ -0,0 +1,69 @@
package jj.tech.finance.utils;
import java.util.List;
public class Page {
private Integer pageSize=20; //页多少条
private Integer pageNum=1; //第几页
private Long total=0L; //一共多少条
private Long totalPage; //一共几页
private List<?> list;
public Page(){
}
public Page(Integer pageNum,Integer pageSize){
this.setPageNum(pageNum);
this.setPageSize(pageSize);
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
if(pageSize != null && pageSize >= 1 && pageSize<20000){
this.pageSize = pageSize;
}
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
if(pageNum != null && pageNum >= 1){
this.pageNum = pageNum;
}
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
if(total!=null) {
this.total = total;
}
}
public Long getTotalPage() {
Integer t = (int) Math.ceil((double) total / pageSize);
totalPage = t.longValue();
return totalPage;
}
public void setTotalPage(Long totalPage) {
this.totalPage = totalPage;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
public int limitStart(){
return (pageNum - 1) * pageSize;
}
}

View File

@ -0,0 +1,73 @@
package jj.tech.finance.utils;
public class R {
public Boolean isOk;
public String message;
public Object data;
public String code;
public R() {
}
public R(Boolean isOk, String message, Object data) {
this.isOk=isOk;
this.message=message;
this.data=data;
}
public static R SUCCESS(){
return new R(true,"", null);
}
public static R SUCCESS(String message){
return new R(true, message==null ? "" : message, null);
}
public static R SUCCESS(String message, Object data){
return new R(true, message==null ? "" : message, data);
}
public static R SUCCESS(Object data){
return new R(true, "" , data);
}
public static R FALSE(){
return new R(false,"", null);
}
public static R FALSE(String message){
return new R(false, message==null ? "" : message, null);
}
public static R FALSE(String message, Object data){
return new R(false, message==null ? "" : message, data);
}
public static R FALSE(Object data){
return new R(true, "" , data);
}
public Boolean getIsOk() {
return isOk;
}
public void setIsOk(Boolean isOk) {
this.isOk = isOk;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,109 @@
package jj.tech.finance.utils;
import java.time.LocalDateTime;
import java.util.HashMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jj.tech.finance.repository.mybatis.entity.SysAdmin;
public class WebAdminUtil {
private static Logger logger = LoggerFactory.getLogger(WebAdminUtil.class);
private static ObjectMapper objectMapper = new ObjectMapper();
public static String TOKEN = "token";
public static long exp = 5 * 60 * 60 * 1000; //过期时间5小时
static {
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@SuppressWarnings("unchecked")
public static Boolean verify(HttpServletRequest request, HttpServletResponse response) {
try {
String token = CookieUtil.fine(request, TOKEN);
if (StringUtils.isBlank(token)) {
return false;
}
AES aes = new AES();
String jsonUser = aes.decrypt(token);
HashMap<String,Object> map = objectMapper.readValue(jsonUser, HashMap.class);
Long logintime = (Long)map.get("logintime");
Long now = System.currentTimeMillis();
if(now-logintime > exp) {
return false;
}
//大于30分钟更新一下用户token
if(now-logintime > 30 * 60 * 1000) {
map.put("logintime", now);
WebAdminUtil.addToCookie(map);
}
SysAdmin bean = new SysAdmin();
BeanUtils.populate(bean, map);
request.setAttribute(TOKEN, bean);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static SysAdmin getUser() {
try {
ServletRequestAttributes servlet = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servlet.getRequest();
SysAdmin curr = (SysAdmin)request.getAttribute(TOKEN);
return curr;
}catch(Exception e) {
e.printStackTrace();
logger.info(e.getMessage());
return null;
}
}
public static String addToCookie(Object obj) {
try {
ServletRequestAttributes servlet = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servlet.getResponse();
String userJson = objectMapper.writeValueAsString(obj);
AES aes = new AES();
String token = aes.encrypt(userJson);
CookieUtil.add(TOKEN, token, response);
return token;
}catch(Exception e) {
logger.info(e.getMessage());
return null;
}
}
public static void deleteUser() {
try {
ServletRequestAttributes servlet = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servlet.getResponse();
CookieUtil.delete(response, TOKEN);
}catch(Exception e) {
logger.info(e.getMessage());
}
}
}

View File

@ -0,0 +1,105 @@
package jj.tech.finance.utils;
import java.util.HashMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jj.tech.finance.repository.mybatis.entity.UserInfo;
public class WebUserUtil {
private static Logger logger = LoggerFactory.getLogger(WebAdminUtil.class);
private static ObjectMapper objectMapper = new ObjectMapper();
public static String TOKEN = "webtoken";
public static long exp = 5 * 60 * 60 * 1000; //过期时间5小时
static {
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@SuppressWarnings("unchecked")
public static Boolean verify(HttpServletRequest request, HttpServletResponse response) {
try {
String token = CookieUtil.fine(request, TOKEN);
if (StringUtils.isBlank(token)) {
return false;
}
AES aes = new AES();
String jsonUser = aes.decrypt(token);
HashMap<String,Object> map = objectMapper.readValue(jsonUser, HashMap.class);
Long logintime = (Long)map.get("logintime");
Long now = System.currentTimeMillis();
if(now-logintime > exp) {
return false;
}
//大于30分钟更新一下用户token
if(now-logintime > 30 * 60 * 1000) {
map.put("logintime", now);
WebUserUtil.addToCookie(map);
}
UserInfo bean = new UserInfo();
BeanUtils.populate(bean, map);
request.setAttribute(TOKEN, bean);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static UserInfo getUser() {
try {
ServletRequestAttributes servlet = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servlet.getRequest();
UserInfo curr = (UserInfo)request.getAttribute(TOKEN);
return curr;
}catch(Exception e) {
e.printStackTrace();
logger.info(e.getMessage());
return null;
}
}
public static String addToCookie(Object obj) {
try {
ServletRequestAttributes servlet = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servlet.getResponse();
String userJson = objectMapper.writeValueAsString(obj);
AES aes = new AES();
String token = aes.encrypt(userJson);
CookieUtil.add(TOKEN, token, response);
return token;
}catch(Exception e) {
logger.info(e.getMessage());
return null;
}
}
public static void deleteUser() {
try {
ServletRequestAttributes servlet = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servlet.getResponse();
CookieUtil.delete(response, TOKEN);
}catch(Exception e) {
logger.info(e.getMessage());
}
}
}

View File

@ -0,0 +1,187 @@
package jj.tech.finance.utils.mybatis;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.mybatis.generator.internal.util.StringUtility;
import org.springframework.util.StringUtils;
/**
* 生成Controller
* @author Dou
*/
public class MybatisControllerPlugin extends PluginAdapter {
private String targetProject = null;
private String targetPackage = null;
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
targetProject = properties.getProperty("targetProject");
targetPackage = properties.getProperty("targetPackage");
}
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
if (Objects.nonNull(targetPackage) && Objects.nonNull(targetProject)) {
String daoMapperName = introspectedTable.getMyBatis3SqlMapNamespace();
String recordType = introspectedTable.getBaseRecordType();
String[] entityPackage = recordType.split("\\.");
String entityName = entityPackage[entityPackage.length - 1];
String first = String.valueOf(entityName.charAt(0));
String lowerEntityName = entityName.replaceFirst(first, first.toLowerCase());
String lowerEntityNameMapper = lowerEntityName + "Mapper";
TopLevelClass controllerClass = new TopLevelClass(targetPackage + "." + entityName + "Controller");
controllerClass.addImportedType("java.lang.Object");
controllerClass.addImportedType("org.springframework.web.bind.annotation.*");
controllerClass.addImportedType("org.springframework.stereotype.Controller");
controllerClass.addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));
controllerClass.addImportedType(daoMapperName);
controllerClass.addAnnotation("@Controller");
controllerClass.setVisibility(JavaVisibility.PUBLIC);
//controllerClass.addAnnotation("@RestController");
controllerClass.addAnnotation("@RequestMapping(\"" + lowerEntityName + "\")");
//daoMapper inject
FullyQualifiedJavaType daoMapper = new FullyQualifiedJavaType(daoMapperName);
Field serviceField = new Field(lowerEntityNameMapper , daoMapper);
serviceField.addJavaDocLine("");
serviceField.addAnnotation("@Autowired");
serviceField.setVisibility(JavaVisibility.PRIVATE);
controllerClass.addField(serviceField);
//Add Method
FullyQualifiedJavaType respondJavaType = new FullyQualifiedJavaType("Object");
controllerClass.addImportedType(respondJavaType);
controllerClass.addImportedType(new FullyQualifiedJavaType(recordType));
//primaryKeyType
Optional<FullyQualifiedJavaType> optional = PluginUtils.primaryKeyType(introspectedTable);
//primaryKeyTypeName
Optional<String> keyNameOptional = PluginUtils.primaryKeyName(introspectedTable);
if (optional.isPresent() && keyNameOptional.isPresent()) {
FullyQualifiedJavaType primaryKeyType = optional.get();
String primaryKeyName = keyNameOptional.get();
if (primaryKeyType.isExplicitlyImported()) {
controllerClass.addImportedType(primaryKeyType);
}
//findById
Method findByIdMethod = new Method("findById");
findByIdMethod.setReturnType(respondJavaType);
findByIdMethod.addAnnotation("@PostMapping(\"findById/{" + primaryKeyName + "}\")");
Parameter idParameter = new Parameter(primaryKeyType, primaryKeyName);
idParameter.addAnnotation("@PathVariable");
findByIdMethod.addParameter(idParameter);
findByIdMethod.addBodyLine("return " + lowerEntityNameMapper+".selectByPrimaryKey("+primaryKeyName+");");
controllerClass.addMethod(findByIdMethod);
//save
Method saveMethod = new Method("save");
saveMethod.setReturnType(respondJavaType);
saveMethod.addAnnotation("@PostMapping(\"save\")");
Parameter saveParameter = new Parameter(new FullyQualifiedJavaType(recordType), "record");
saveParameter.addAnnotation("@RequestBody");
saveMethod.addParameter(saveParameter);
saveMethod.addBodyLine("return " + lowerEntityNameMapper+".insertSelective(record);");
controllerClass.addMethod(saveMethod);
//update
Method updateMethod = new Method("update");
updateMethod.setReturnType(respondJavaType);
updateMethod.addAnnotation("@PutMapping(\"update\")");
Parameter updateParameter = new Parameter(new FullyQualifiedJavaType(recordType), "record");
updateParameter.addAnnotation("@RequestBody");
updateMethod.addParameter(saveParameter);
updateMethod.addBodyLine("return " + lowerEntityNameMapper+".updateByPrimaryKeySelective(record);");
controllerClass.addMethod(updateMethod);
//delete
Method deleteMethod = new Method("delete");
deleteMethod.setReturnType(respondJavaType);
deleteMethod.addAnnotation("@DeleteMapping(\"delete/{" + primaryKeyName + "}\")");
Parameter deleteIdParameter = new Parameter(primaryKeyType, primaryKeyName);
deleteIdParameter.addAnnotation("@PathVariable");
deleteMethod.addParameter(deleteIdParameter);
deleteMethod.addBodyLine("return " + lowerEntityNameMapper+".deleteByPrimaryKey(id);");
controllerClass.addMethod(deleteMethod);
//page
/*
* Method pageMethod = new Method("page");
* pageMethod.addAnnotation("@PostMapping(\"page\")");
* pageMethod.setReturnType(respondJavaType); Parameter pageNum = new
* Parameter(new FullyQualifiedJavaType("int"), "pageNum");
* pageNum.addAnnotation("@RequestParam(defaultValue = \"1\")");
* pageMethod.addParameter(pageNum); Parameter pageSize = new Parameter(new
* FullyQualifiedJavaType("int"), "pageSize");
* pageSize.addAnnotation("@RequestParam(defaultValue = \"15\")");
* pageMethod.addParameter(pageSize); pageMethod.addBodyLine("return null;");
* controllerClass.addMethod(pageMethod);
*/
}
GeneratedJavaFile javaFile = new GeneratedJavaFile(controllerClass, targetProject,
context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
context.getJavaFormatter());
List<GeneratedJavaFile> files = new ArrayList<>();
files.add(javaFile);
return files;
}
return Collections.emptyList();
}
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("src/main/resources/generate/mybatis/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}

View File

@ -0,0 +1,142 @@
package jj.tech.finance.utils.mybatis;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.InnerClass;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.config.GeneratedKey;
public class PluginUtils {
private PluginUtils() {
}
public static Optional<FullyQualifiedJavaType> primaryKeyType(IntrospectedTable introspectedTable) {
Optional<GeneratedKey> generatedKey = introspectedTable.getGeneratedKey();
if (generatedKey.isPresent()) {
String primaryKey = generatedKey.get().getColumn();
Optional<IntrospectedColumn> optional = introspectedTable.getColumn(primaryKey);
if (optional.isPresent()) {
IntrospectedColumn keyColumn = optional.get();
return Optional.ofNullable(keyColumn.getFullyQualifiedJavaType());
}
}
return Optional.empty();
}
public static Optional<String> primaryKeyName(IntrospectedTable introspectedTable) {
Optional<GeneratedKey> generatedKey = introspectedTable.getGeneratedKey();
if (generatedKey.isPresent()) {
String primaryKey = generatedKey.get().getColumn();
Optional<IntrospectedColumn> optional = introspectedTable.getColumn(primaryKey);
if (optional.isPresent()) {
IntrospectedColumn keyColumn = optional.get();
return Optional.ofNullable(keyColumn.getJavaProperty());
}
}
return Optional.empty();
}
public static void restfulMethod(Method method, boolean rest) {
if (!rest) {
method.addAnnotation("@ResponseBody");
}
method.setVisibility(JavaVisibility.PUBLIC);
}
public static void removeGeneratedAnnotation(Object object) {
if (Objects.nonNull(object)) {
if (object instanceof TopLevelClass) {
TopLevelClass topLevelClass = (TopLevelClass) object;
Set<FullyQualifiedJavaType> importedTypes = topLevelClass.getImportedTypes();
if (Objects.nonNull(importedTypes) && !importedTypes.isEmpty()) {
importedTypes.removeIf(importedType -> Objects.equals(importedType.getFullyQualifiedName(), "javax.annotation.Generated"));
}
List<Field> fields = topLevelClass.getFields();
if (Objects.nonNull(fields) && !fields.isEmpty()) {
fields.get(0).addJavaDocLine("");
actionRemoveGeneratedAnnotation(fields);
}
List<Method> methods = topLevelClass.getMethods();
if (Objects.nonNull(methods) && !methods.isEmpty()) {
actionRemoveGeneratedAnnotation(topLevelClass.getMethods());
}
List<InnerClass> innerClasses = topLevelClass.getInnerClasses();
if (Objects.nonNull(innerClasses) && !innerClasses.isEmpty()) {
actionRemoveGeneratedAnnotation(innerClasses);
}
} else if (object instanceof Interface) {
Interface anInterface = (Interface) object;
Set<FullyQualifiedJavaType> importedTypes = anInterface.getImportedTypes();
if (Objects.nonNull(importedTypes) && !importedTypes.isEmpty()) {
importedTypes.removeIf(importedType -> Objects.equals(importedType.getFullyQualifiedName(), "javax.annotation.Generated"));
}
List<Field> fields = anInterface.getFields();
if (Objects.nonNull(fields) && !fields.isEmpty()) {
fields.get(0).addJavaDocLine("");
actionRemoveGeneratedAnnotation(fields);
}
List<Method> methods = anInterface.getMethods();
if (Objects.nonNull(methods) && !methods.isEmpty()) {
actionRemoveGeneratedAnnotation(anInterface.getMethods());
}
List<InnerClass> innerClasses = anInterface.getInnerClasses();
if (Objects.nonNull(innerClasses) && !innerClasses.isEmpty()) {
actionRemoveGeneratedAnnotation(innerClasses);
}
}
}
}
private static void actionRemoveGeneratedAnnotation(List<?> objects) {
String delete = "@Generated(\"org.mybatis.generator.api.MyBatisGenerator\")";
if (Objects.nonNull(objects) && !objects.isEmpty()) {
for (Object object : objects) {
if (object instanceof Method) {
Method method = (Method) object;
List<String> annotations = method.getAnnotations();
if (Objects.nonNull(annotations) && !annotations.isEmpty()) {
for (int i = 0; i < annotations.size(); i++) {
if (Objects.equals(annotations.get(i), delete)) {
annotations.remove(i);
break;
}
}
}
} else if (object instanceof Field) {
Field field = (Field) object;
List<String> annotations = field.getAnnotations();
if (Objects.nonNull(annotations) && !annotations.isEmpty()) {
for (int i = 0; i < annotations.size(); i++) {
if (Objects.equals(annotations.get(i), delete)) {
annotations.remove(i);
break;
}
}
}
} else if (object instanceof InnerClass) {
InnerClass innerClass = (InnerClass) object;
List<String> annotations = innerClass.getAnnotations();
if (Objects.nonNull(annotations) && !annotations.isEmpty()) {
for (int i = 0; i < annotations.size(); i++) {
if (Objects.equals(annotations.get(i), delete)) {
annotations.remove(i);
break;
}
}
}
}
}
}
}}

View File

@ -0,0 +1,41 @@
package jj.tech.finance.utils.mybatis;
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.ColumnAndConditionCriterion;
import org.mybatis.dynamic.sql.SqlCriterion;
import org.mybatis.dynamic.sql.VisitableCondition;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;
import org.mybatis.dynamic.sql.where.render.CriterionRenderer;
public class Sum<T> extends AbstractUniTypeFunction<T, Sum<T>> {
private final VisitableCondition<T> condition;
private Sum(BindableColumn<T> column, VisitableCondition<T> condition) {
super(column);
this.condition = condition;
}
@Override
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
// ColumnAndConditionCriterion.withColumn(column).withCondition(condition).build().
ColumnAndConditionCriterion<T> criteion = ColumnAndConditionCriterion
.withColumn(column)
.withCondition(condition).build();
return "sum(" //$NON-NLS-1$
+ column.renderWithTableAlias(tableAliasCalculator)
// + s
+ ")"; //$NON-NLS-1$
}
@Override
protected Sum<T> copy() {
return new Sum<>(column, condition);
}
public static <T> Sum<T> of(BindableColumn<T> column, VisitableCondition<T> condition) {
return new Sum<>(column, condition);
}
}

View File

@ -0,0 +1,7 @@
package jj.tech.finance.utils.tushare;
public class TushareConfig {
public static String TOKEN = "843c785973fd04c932ac9612184e43f4d8f23eb2540d498e7b82154e";
public static String URL = "http://api.tushare.pro";
}

View File

@ -0,0 +1,68 @@
##约定大于配置,请勿重复造轮
server: #服务端口
port: 8083
forward-headers-strategy: framework
##spring----------
spring:
application:
name: zwyy
datasource:
type: com.zaxxer.hikari.HikariDataSource
#url: jdbc:h2:./test;AUTO_SERVER=TRUE #连接池Database 嵌入模式jdbc:h2:~/test-jooq FILE_LOCK=SOCKET MODE=MySQL;;AUTO_SERVER=TRUE
# url: jdbc:h2:./test;MODE=MySQL;AUTO_SERVER=TRUE
# username: sa
# password:
# hikari:
# driver-class-name: org.h2.Driver
url: jdbc:mariadb://mariadb:3306/finance
username: root
password: open123
hikari:
driver-class-name: org.mariadb.jdbc.Driver
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# serialization:
# fail-on-empty-beans: false
# deserialization:
# FAIL_ON_UNKNOWN_PROPERTIES: false
h2:
console:
enabled: true #开启h2数据库的浏览器管理界面
settings:
web-allow-others: true
trace: true #是否可以远程web
#path: /h2-console #h2浏览器管理访问路径默认/h2-console
# sql:
# init:
# mode: never ##加载脚本datasource.initialize已弃用,spring.sql.init.mode=never/always
# continue-on-error: true #初始化错误,继续执行
# encoding: utf-8 #加载sql文件的编码连接池ue #初始化错误,继续执行
# data-locations: classpath:/sql/data-h2.sql
# schema-locations: classpath:/sql/schema-h2.sql #spring boot 默认启动使用springJDBC初始化数据脚本, 加载类路径下的 schema-${platform}.sql \ data-${platform}.sql数据
# platform: h2
#elasticsearch:
#jest:
#uris: http://loalhost:9200
#read-timeout: 1000
# 多数据源
# app:
# datasource:
# type: com.zaxxer.hikari.HikariDataSource
# jdbcUrl: jdbc:h2:~/test-jooq;AUTO_SERVER=TRUE
# username: sa
# password:
# ##连接池
# hikari:
# driver-class-name: org.h2.Driver
logging:
level:
root: info
# org.jooq: debug
# org.springframework.amqp: debug
# org.mybatis: debug
# org.mybatis.dynamic.sql: debug
# jj.tech.dcang: debug

View File

@ -0,0 +1,70 @@
##约定大于配置,请勿重复造轮
server: #服务端口
port: 8083
forward-headers-strategy: framework
##spring----------
spring:
application:
name: zwyy
datasource:
type: com.zaxxer.hikari.HikariDataSource
#url: jdbc:h2:./test;AUTO_SERVER=TRUE #连接池Database 嵌入模式jdbc:h2:~/test-jooq FILE_LOCK=SOCKET MODE=MySQL;;AUTO_SERVER=TRUE
# url: jdbc:h2:./finance;MODE=MySQL;AUTO_SERVER=TRUE;DATABASE_TO_LOWER=TRUE
# username: sa
# password:
# hikari:
# driver-class-name: org.h2.Driver
url: jdbc:mariadb://106.53.186.11:3306/finance
username: root
password: open123
hikari:
driver-class-name: org.mariadb.jdbc.Driver
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: CST
# serialization:
# write-dates-as-timestamps: false
# fail-on-empty-beans: false
# deserialization:
# FAIL_ON_UNKNOWN_PROPERTIES: false
h2:
console:
enabled: true #开启h2数据库的浏览器管理界面
settings:
web-allow-others: true
trace: true #是否可以远程web
#path: /h2-console #h2浏览器管理访问路径默认/h2-console
sql:
init:
mode: never ##加载脚本datasource.initialize已弃用,spring.sql.init.mode=never/always
continue-on-error: true #初始化错误,继续执行
encoding: utf-8 #加载sql文件的编码连接池ue #初始化错误,继续执行
data-locations: classpath:/sql/data-h2.sql
schema-locations: classpath:/sql/schema-h2.sql #spring boot 默认启动使用springJDBC初始化数据脚本, 加载类路径下的 schema-${platform}.sql \ data-${platform}.sql数据
platform: h2
#elasticsearch:
#jest:
#uris: http://loalhost:9200
#read-timeout: 1000
# 多数据源
# app:
# datasource:
# type: com.zaxxer.hikari.HikariDataSource
# jdbcUrl: jdbc:h2:~/test-jooq;AUTO_SERVER=TRUE
# username: sa
# password:
# ##连接池
# hikari:
# driver-class-name: org.h2.Driver
logging:
level:
root: info
org.jooq: debug
org.springframework.amqp: debug
org.mybatis: debug
org.mybatis.dynamic.sql: debug
jj.tech.dcang: debug

View File

@ -0,0 +1,22 @@
#spring:
# cloud:
# consul:
# scheme: https
# host: consul.164500.xyz
# port: 443
# discovery:
# acl-token: b2gs44ddr3
## service-name: ${spring.application.name}
## https://github.com/spring-cloud/spring-cloud-consul/pull/590#issuecomment-1473038044
# heartbeat:
# enabled: true
# deregister: true
# health-check-critical-timeout: 30s
#
## config:
## acl-token: b1gs33cr3t
# #discovery:
# #register-health-check: true
## discovery:
## ip-address: 192.168.43.15
## #hostname: doudou

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<jdbc>
<driver>org.mariadb.jdbc.Driver</driver>
<url>jdbc:mariadb://106.53.186.11:3306/finance</url>
<user>root</user>
<password>open123</password>
<!--<driver>org.h2.Driver</driver>
<url>jdbc:h2:./finance;MODE=MariaDB;AUTO_SERVER=TRUE;DATABASE_TO_UPPER=FALSE;DATABASE_TO_LOWER=TRUE</url>
<user>sa</user>
<password></password>-->
</jdbc>
<generator>
<database>
<properties>
<property>
<key>scripts</key>
<value>src/main/resources/sql/schema-h2.sql</value>
</property>
</properties>
<!--数据库名称-->
<inputSchema>finance</inputSchema>
<!--include和exclude用于控制为数据库中哪些表生成代码-->
<includes>.*</includes>
<!--<excludes></excludes>-->
</database>
<generate>
<!--生成dao和pojo-->
<daos>true</daos>
<pojos>true</pojos>
<!--把数据库时间类型映射到java 8时间类型-->
<javaTimeTypes>true</javaTimeTypes>
<!--<interfaces>true</interfaces>-->
<!--不在生成的代码中添加spring注释比如@Repository-->
<springAnnotations>true</springAnnotations>
</generate>
<target>
<!--生成代码文件的包名及放置目录-->
<packageName>jj.tech.finance.repository.jooq</packageName>
<directory>target/generated-sources/repository</directory>
</target>
</generator>
</configuration>

View File

@ -0,0 +1,114 @@
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 驱动 -->
<!-- <classPathEntry location="C:\Users\lenovo\.m2\repository\com\h2database\h2\2.1.214\h2-2.1.214.jar"/> -->
<!--<classPathEntry location="C:\Users\lenovo\.m2\repository\com\mysql\mysql-connector-j\8.0.33\mysql-connector-j-8.0.33.jar"/>-->
<!--<classPathEntry location="C:\Users\lenovo\.m2\repository\org\mariadb\jdbc\mariadb-java-client\3.1.4\mariadb-java-client-3.1.4.jar"/>-->
<!-- <classPathEntry location="C:\Users\Administrator\.m2\repository\net\sourceforge\jtds\jtds\1.3.1\jtds-1.3.1.jar"/> -->
<!-- <classPathEntry location="C:\Users\Administrator\.m2\repository\com\oracle\ojdbc14\10.2.0.2.0\ojdbc14-10.2.0.2.0.jar"/> -->
<context id="mysqlTables" targetRuntime="MyBatis3DynamicSql"> <!-- MyBatis3DynamicSql MyBatis3-->
<!--<plugin type="jj.tech.dcang.utils.mybatis.MybatisControllerPlugin">
<property name="targetProject" value="target/generated-sources/repository"/>
<property name="targetPackage" value="jj.tech.dcang.repository.mybatis.controller"/>
<property name="respond" value="org.example.Respond"/>
</plugin>-->
<commentGenerator>
<!-- <property name="suppressDate" value="true"/> -->
<!-- 是否去除自动生成的注释 true false:否 -->
<!-- <property name="suppressAllComments" value="true" /> -->
<property name="addRemarkComments" value="true" />
</commentGenerator>
<!--<jdbcConnection driverClass="org.h2.Driver" connectionURL="jdbc:h2:./finance;MODE=MariaDB;AUTO_SERVER=TRUE;DATABASE_TO_LOWER=TRUE" userId="sa" password="">
</jdbcConnection>-->
<!-- nullCatalogMeansCurrent对mariadb 不起作用,会查出所有的非表对象 -->
<jdbcConnection driverClass="org.mariadb.jdbc.Driver" connectionURL="jdbc:mariadb://106.53.186.11:3306/finance" userId="root" password="open123">
<property name="nullCatalogMeansCurrent" value="true" />
</jdbcConnection>
<!-- 数据库驱动、连接URL、用户名、密码 -->
<!--<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://139.198.106.100:3306/archive?characterEncoding=utf-8" userId="root" password="test000000">
<property name="nullCatalogMeansCurrent" value="true" />
</jdbcConnection>-->
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@192.168.63.200:1521:orcl"
userId="new_hlpay" password="new_hlpay"> </jdbcConnection> -->
<!-- <jdbcConnection driverClass="net.sourceforge.jtds.jdbc.Driver" connectionURL="jdbc:jtds:sqlserver://192.168.63.190;DatabaseName=pay_2015-01-api"
userId="sa" password="111111"> </jdbcConnection> -->
<javaTypeResolver>
<!--<property name="forceBigDecimals" value="false" />-->
<property name="useJSR310Types" value="true" />
</javaTypeResolver>
<!-- 生成模型包名和位置 -->
<javaModelGenerator targetPackage="jj.tech.finance.repository.mybatis.entity"
targetProject="target/generated-sources/repository">
<!-- <property name="enableSubPackages" value="true" /> -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成xml文件的包名和位置 -->
<!-- <sqlMapGenerator targetPackage="jj.tech.dcang.repository.mybatis.dao"
targetProject="target/generated-sources/repository">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator> -->
<!-- 生成DAO的包名和位置 -->
<javaClientGenerator targetPackage="jj.tech.finance.repository.mybatis.dao"
targetProject="target/generated-sources/repository">
<!-- <property name="enableSubPackages" value="true" /> -->
<property name="dynamicSqlSupportPackage" value="jj.tech.finance.repository.mybatis.dao.support"/>
</javaClientGenerator>
<!-- 需要生成的表, mysql 不支持这种模式: catalog="TEST" schema="PUBLIC" -->
<!-- 参考https://mybatis.org/generator/usage/mysql.html -->
<!--<table schema="PUBLIC" tableName="%" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<generatedKey column="id" sqlStatement="MySql" identity="false" />
</table>-->
<!--<table catalog="finance" tableName="%" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<property name="ignoreQualifiersAtRuntime" value="true" />
设置ID自增策略generatedKey时, id不可以指定值, 无法生成批量插入方法insertMultiple
<generatedKey column="id" sqlStatement="JDBC" identity="true" />
不设置ID自增策略为generatedKey时, id可以指定值, 可以生成批量插入方法insertMultiple
<generatedKey column="id" sqlStatement="MySql" identity="true" />
</table>-->
<table catalog="finance" schema="finance" tableName="%" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<property name="useActualColumnNames" value="true" />
<property name="ignoreQualifiersAtRuntime" value="true" />
<!--设置ID自增策略generatedKey时, id不可以指定值, 无法生成批量插入方法insertMultiple-->
<!--<generatedKey column="id" sqlStatement="JDBC" identity="true" />-->
<!--不设置ID自增策略为generatedKey时, id可以指定值, 可以生成批量插入方法insertMultiple-->
<!--<generatedKey column="id" sqlStatement="MySql" identity="true" />-->
</table>
</context>
</generatorConfiguration>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>http://192.168.0.123:3100/loki/api/v1/push</url>
</http>
<format>
<label>
<pattern>app=zwyy,host=${HOSTNAME},level=%level</pattern>
</label>
<message>
<!-- <pattern>l=%level h=${HOSTNAME} c=%logger{20} t=%thread | %msg %ex</pattern> -->
<pattern>%d{yyyy-MM-dd HH-mm-ss.SSSXXX} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
</message>
<sortByTime>true</sortByTime>
</format>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{yyyy-MM-dd HH-mm-ss.SSSXXX} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<logger name="jj.tech.finance">
<level value="debug"/>
</logger>
<logger name="org.springframework.jdbc.core">
<level value="debug"/>
</logger>
<logger name="org.springframework.jdbc.support">
<level value="debug"/>
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,25 @@
insert into sys_admin values (1,'超级管理员','admin','fe9bdf42857f0fdfba26b120a42e04a0f331c711870656bea9d088bfcd1e8328',0);
insert into sys_admin values (2,'测试角色','admin1','fe9bdf42857f0fdfba26b120a42e04a0f331c711870656bea9d088bfcd1e8328',0);
insert into sys_role values (1,'超级管理员','技术部');
insert into sys_admin_role values (1,1,1);
insert into user_info values (1,'葫芦娃1', '大娃', 'user','fe9bdf42857f0fdfba26b120a42e04a0f331c711870656bea9d088bfcd1e8328',0, 3,'');
insert into sys_resource values (1,0,0,'菜单根目录','系统菜单','/url','',false,null);
insert into sys_resource values (2,1,1,'商品管理','系统菜单','/admin/goods','fa fa-sitemap fa-fw',false,null);
insert into sys_resource values (3,1,2,'订单管理','系统菜单','/admin/order','fa fa-edit fa-fw',false,null);
insert into sys_resource values (4,1,3,'用户管理','系统菜单','/admin/user','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (5,1,4,'营销管理','系统菜单','/admin/sales','fa fa-files-o fa-fw',false,null);
insert into sys_resource values (6,1,5,'统计','系统菜单','/admin/count','fa fa-bar-chart-o fa-fw',false,null);
insert into sys_resource values (7,1,6,'系统设置','系统菜单','/admin/system','fa fa-wrench fa-fw',true,null);
insert into sys_resource values (8,2,1,'品牌管理','系统菜单','/shop','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (9,2,2,'库存管理','系统菜单','/shop','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (10,2,3,'商品分类','系统菜单','/shop','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (11,2,4,'商品属性','系统菜单','/shop','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (12,7,1,'角色管理','系统菜单','/sys/role','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (13,7,2,'资源管理','系统菜单','/admin/system/resouce','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (14,7,3,'管理员','系统菜单','/admin/system/admin','fa fa-dashboard fa-fw',false,null);
insert into sys_resource values (15,7,2,'首页','系统菜单','/shop','fa fa-dashboard fa-fw',false,null);

View File

@ -0,0 +1,174 @@
-- drop all objects;
drop table if exists sys_admin;
create table sys_admin
(
id int not null auto_increment,
realname varchar(100) not null,
username varchar(100) not null,
password varchar(100) not null comment 'sha3_256hex',
islock int default 0 comment '0正常,1锁定',
primary key (id),
unique (username)
);
drop table if exists sys_role;
create table sys_role
(
id int not null auto_increment,
rolename varchar(50) not null,
department varchar(50) not null,
primary key (id)
);
drop table if exists sys_admin_role;
create table sys_admin_role (
id int not null auto_increment,
adminid int not null,
roleid int not null,
primary key (id)
);
drop table if exists sys_urls;
create table sys_urls (
id int not null auto_increment,
pid int comment '父类id',
types int default 1 comment '1:url,2:菜单',
level int default 0 comment '0:url,1:一级菜单, 2:二级菜单',
url varchar(300) default null,
name varchar(200) default null,
method varchar(200) default null,
primary key (id),
unique (url)
);
drop table if exists sys_role_url;
create table sys_role_url (
id int not null auto_increment,
roleid int not null,
url varchar(300) not null comment '对应sys_urls的url',
urltypes int not null comment '1:url,2:菜单',
primary key (id)
);
-- 系统配置表
drop table if exists sys_config;
create table sys_config
(
id int not null auto_increment,
subgroup varchar(500) not null comment '分组',
k varchar(1000) not null comment '',
val varchar(14000) comment '',
adminid int not null comment '管理员id',
adminname varchar(100) not null comment '管理员名称',
edittime datetime default current_timestamp on update current_timestamp comment '最后编辑时间',
primary key (id),
unique (k)
);
-- 用户信息
drop table if exists user_info;
create table user_info (
id int not null auto_increment,
realname varchar(200) comment '真实姓名',
nickname varchar(200) comment '昵称',
username varchar(200) not null comment '用户名',
password varchar(70) not null comment '密码',
islock int default 0 comment '0正常,1锁定',
source int default 0 comment '来源:0注册,1第三方,3管理员添加',
head_img varchar(1000),
primary key (id),
unique (username)
);
-- 合约信息
drop table if exists contract_info;
create table contract_info
(
id int not null auto_increment,
ts_code varchar(50) not null comment '合约代码',
symbol varchar(50) not null comment '交易代码',
exchange varchar(50) comment '交易市场: cffex-中金所 dce-大商所 czce-郑商所 shfe-上期所 ine-上海国际能源交易中心 gfex-广州期货交易所',
name varchar(50) not null comment '中文简称',
fut_code varchar(100) not null comment '合约产品代码',
multiplier double comment '合约乘数(只适用于国债期货、指数期货)',
trade_unit varchar(50) not null comment '交易计量单位',
per_unit double comment '交易单位(每手)',
quote_unit varchar(50) not null comment '报价单位',
quote_unit_desc varchar(50) not null comment '最小报价单位说明',
d_mode_desc varchar(200) not null comment '交割方式说明',
list_date date not null default '1970-01-01' comment '上市日期',
delist_date date not null default '1970-01-01' comment '最后交易日期',
d_month varchar(50) not null comment '交割月份',
last_ddate date not null default '1970-01-01' comment '最后交割日',
exchange_name varchar(50) comment '交易所名称',
primary key (id),
unique (ts_code)
);
-- 合约信息状态表
drop table if exists contract_info_status;
create table contract_info_status
(
id int not null auto_increment,
ts_code varchar(50) not null comment 'ts合约代码',
contract_status int default 0 comment '合约状态:0启用,1禁用',
scribe_status int default 0 comment '划线开关:0启用,1禁用',
scribe_update_time datetime default null comment '划线更新时间',
scribe_number int default 0 comment '划线数量',
primary key (id),
unique (ts_code)
);
-- 合约信息状态划线表
drop table if exists contract_info_status_scribe;
create table contract_info_status_scribe
(
id int not null auto_increment,
ts_code varchar(50) not null comment 'ts合约代码',
scribe_id int default 1 comment '1:普通/动态支撑,2:普通/动态压力,3:高级支撑,4:高级压力,5:高级重合位',
scribe_value int not null comment '划线值',
colour varchar(50) not null default '#FF00003' comment '划线颜色',
primary key (id)
);
-- 合约日线行情
drop table if exists fut_daily;
create table fut_daily
(
id int not null auto_increment,
ts_code varchar(50) not null comment 'ts合约代码',
trade_date date not null comment '交易日期',
pre_close double comment '昨收盘价',
pre_settle double not null comment '昨结算价',
open double not null comment '开盘价',
high double comment '最高价',
low double not null comment '最低价',
close double comment '收盘价',
settle double not null comment '结算价',
change1 double not null comment '涨跌1 收盘价-昨结算价',
change2 double not null comment '涨跌2 结算价-昨结算价',
vol double not null comment '成交量(手)',
amount double not null comment '成交金额(万元)',
oi double not null comment '持仓量(手)',
oi_chg double not null comment '持仓量变化',
primary key (id),
unique (ts_code,trade_date)
);
-- 管理员收藏合约信息表
drop table if exists contract_info_user;
create table contract_info_user
(
id int not null auto_increment,
userid int not null comment '用户ID',
username varchar(100) not null comment '用户名',
ts_code varchar(50) not null comment 'ts合约代码',
primary key (id),
unique (userid, ts_code)
);

View File

@ -0,0 +1,22 @@
package jj.tech.paolu.biz.webadmin.service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class RoomRuleImpTest {
public static void main(String[] args) {
String dateStr = "20210719"; // 输入日期字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); // 定义日期格式化模式
LocalDate localDate = LocalDate.parse(dateStr, formatter); // 将字符串按指定格式解析为LocalDate对象
System.out.println(localDate); // 打印结果
}
}

View File

@ -0,0 +1,295 @@
package test.nw;
import java.util.Stack;
public class BinaryTree {
private TreeNode root=null;
public BinaryTree(){
root=new TreeNode(1,"rootNode(A)");
}
/**
* 创建一棵二叉树
* <pre>
* A
* B C
* D E F
* </pre>
* @param root
* @author WWX
*/
public void createBinTree(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
TreeNode newNodeF = new TreeNode(6,"F");
root.leftChild=newNodeB;
root.rightChild=newNodeC;
root.leftChild.leftChild=newNodeD;
root.leftChild.rightChild=newNodeE;
root.rightChild.rightChild=newNodeF;
}
public boolean isEmpty(){
return root==null;
}
//树的高度
public int height(){
return height(root);
}
//节点个数
public int size(){
return size(root);
}
private int height(TreeNode subTree){
if(subTree==null)
return 0;//递归结束空树高度为0
else{
int i=height(subTree.leftChild);
int j=height(subTree.rightChild);
return (i<j)?(j+1):(i+1);
}
}
private int size(TreeNode subTree){
if(subTree==null){
return 0;
}else{
return 1+size(subTree.leftChild)
+size(subTree.rightChild);
}
}
//返回双亲结点
public TreeNode parent(TreeNode element){
return (root==null|| root==element)?null:parent(root, element);
}
public TreeNode parent(TreeNode subTree,TreeNode element){
if(subTree==null)
return null;
if(subTree.leftChild==element||subTree.rightChild==element)
//返回父结点地址
return subTree;
TreeNode p;
//现在左子树中找如果左子树中没有找到才到右子树去找
if((p=parent(subTree.leftChild, element))!=null)
//递归在左子树中搜索
return p;
else
//递归在右子树中搜索
return parent(subTree.rightChild, element);
}
public TreeNode getLeftChildNode(TreeNode element){
return (element!=null)?element.leftChild:null;
}
public TreeNode getRightChildNode(TreeNode element){
return (element!=null)?element.rightChild:null;
}
public TreeNode getRoot(){
return root;
}
//在释放某个结点时该结点的左右子树都已经释放
//所以应该采用后续遍历当访问某个结点时将该结点的存储空间释放
public void destroy(TreeNode subTree){
//删除根为subTree的子树
if(subTree!=null){
//删除左子树
destroy(subTree.leftChild);
//删除右子树
destroy(subTree.rightChild);
//删除根结点
subTree=null;
}
}
public void traverse(TreeNode subTree){
System.out.println("key:"+subTree.key+"--name:"+subTree.data);;
traverse(subTree.leftChild);
traverse(subTree.rightChild);
}
//前序遍历
public void preOrder(TreeNode subTree){
if(subTree!=null){
visted(subTree);
preOrder(subTree.leftChild);
preOrder(subTree.rightChild);
}
}
//中序遍历
public void inOrder(TreeNode subTree){
if(subTree!=null){
inOrder(subTree.leftChild);
visted(subTree);
inOrder(subTree.rightChild);
}
}
//后续遍历
public void postOrder(TreeNode subTree) {
if (subTree != null) {
postOrder(subTree.leftChild);
postOrder(subTree.rightChild);
visted(subTree);
}
}
//前序遍历的非递归实现
public void nonRecPreOrder(TreeNode p){
Stack<TreeNode> stack=new Stack<TreeNode>();
TreeNode node=p;
while(node!=null||stack.size()>0){
while(node!=null){
visted(node);
stack.push(node);
node=node.leftChild;
}
while(stack.size()>0){
node=stack.pop();
node=node.rightChild;
}
}
}
//中序遍历的非递归实现
public void nonRecInOrder(TreeNode p){
Stack<TreeNode> stack =new Stack<BinaryTree.TreeNode>();
TreeNode node =p;
while(node!=null||stack.size()>0){
//存在左子树
while(node!=null){
stack.push(node);
node=node.leftChild;
}
//栈非空
if(stack.size()>0){
node=stack.pop();
visted(node);
node=node.rightChild;
}
}
}
//后序遍历的非递归实现
public void noRecPostOrder(TreeNode p){
Stack<TreeNode> stack=new Stack<BinaryTree.TreeNode>();
TreeNode node =p;
while(p!=null){
//左子树入栈
for(;p.leftChild!=null;p=p.leftChild){
stack.push(p);
}
//当前结点无右子树或右子树已经输出
while(p!=null&&(p.rightChild==null||p.rightChild==node)){
visted(p);
//纪录上一个已输出结点
node =p;
if(stack.empty())
return;
p=stack.pop();
}
//处理右子树
stack.push(p);
p=p.rightChild;
}
}
public void visted(TreeNode subTree){
subTree.isVisted=true;
System.out.println("key:"+subTree.key+"--name:"+subTree.data);;
}
/**
* 二叉树的节点数据结构
* @author WWX
*/
private class TreeNode{
private int key=0;
private String data=null;
private boolean isVisted=false;
private TreeNode leftChild=null;
private TreeNode rightChild=null;
public TreeNode(){}
/**
* @param key 层序编码
* @param data 数据域
*/
public TreeNode(int key,String data){
this.key=key;
this.data=data;
this.leftChild=null;
this.rightChild=null;
}
}
//测试
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.createBinTree(bt.root);
// TreeNode newNodeB = new TreeNode(2,"B");
// TreeNode newNodeC = new TreeNode(3,"C");
// TreeNode newNodeD = new TreeNode(4,"D");
// TreeNode newNodeE = new TreeNode(5,"E");
// TreeNode newNodeF = new TreeNode(6,"F");
// bt.root.leftChild=newNodeB;
// bt.root.rightChild=newNodeC;
// bt.root.leftChild.leftChild=newNodeD;
// bt.root.leftChild.rightChild=newNodeE;
// bt.root.rightChild.rightChild=newNodeF;
System.out.println("the size of the tree is " + bt.size());
System.out.println("the height of the tree is " + bt.height());
System.out.println("*******(前序遍历)[ABDECF]遍历*****************");
bt.preOrder(bt.root);
System.out.println("*******(中序遍历)[DBEACF]遍历*****************");
bt.inOrder(bt.root);
System.out.println("*******(后序遍历)[DEBFCA]遍历*****************");
bt.postOrder(bt.root);
// System.out.println("***非递归实现****(前序遍历)[ABDECF]遍历*****************");
// bt.nonRecPreOrder(bt.root);
//
// System.out.println("***非递归实现****(中序遍历)[DBEACF]遍历*****************");
// bt.nonRecInOrder(bt.root);
//
// System.out.println("***非递归实现****(后序遍历)[DEBFCA]遍历*****************");
// bt.noRecPostOrder(bt.root);
}
}

View File

@ -0,0 +1,16 @@
package test.nw;
import java.lang.reflect.Type;
import java.util.List;
import org.springframework.core.ParameterizedTypeReference;
public class StreamTest {
public static void main(String[] args) {
ParameterizedTypeReference<List<Integer>> typeRef = new ParameterizedTypeReference<List<Integer>>() {};
Type type = typeRef.getType(); // 获取泛型类型
System.out.println("泛型类型为:" + type);
}
}

View File

@ -0,0 +1,32 @@
package test.nw;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import org.apache.commons.lang3.StringUtils;
public class TimeTest {
public static void main(String[] args) {
// LocalDateTime now = LocalDateTime.now();
// now = now.truncatedTo(ChronoUnit.SECONDS);
// System.out.println(now.plusMinutes(120));
// System.out.println(now.minusMinutes(61));
// FastDateFormat s = FastDateFormat.getInstance();
// LocalDateTime ordertime = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);
// System.out.println(ordertime.with(LocalTime.MAX));
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
// LocalDate d = LocalDate.parse("null", formatter);
// System.out.println(d);
// LocalDate l = LocalDate.ofInstant(Instant.ofEpochMilli(0), ZoneId.systemDefault());
// System.out.println(l);
//
System.out.println(String.format("%03d", 1));
}
}

View File

@ -0,0 +1,73 @@
//package test.nw;
//
//import java.nio.file.Paths;
//import java.util.List;
//
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.web.util.UriComponentsBuilder;
//
//import jj.tech.dcang.biz.demo.controller.TestController;
//
//public class UrlTest {
// public static void main(String[] args) {
// String uri = "/zz/v3/s/api-docs.yaml/{group}";
// uri="/t/s/bbb";
//
////
//// UriComponentsBuilder.fromUriString(uri).build().getPathSegments()
//// .stream().forEach(s->{
//// System.out.println(s);
//// });
//
//// PathContainer pathContainer = PathContainer.parsePath(uri);
////
//// System.out.println(pathContainer.subPath(0));
//// System.out.println(pathContainer.subPath(1));
//// System.out.println(pathContainer.subPath(2));
//// System.out.println(pathContainer.subPath(3));
//// System.out.println(pathContainer.subPath(4));
//// System.out.println(pathContainer.subPath(5));
//// System.out.println( Paths.get(UriComponentsBuilder.fromUriString("file://"+uri).build().toUri()).getParent());
//// System.out.println( Paths.get(UriComponentsBuilder.fromUriString("file://"+uri).build().toUri()).getParent().getParent());
//// System.out.println( Paths.get(UriComponentsBuilder.fromUriString("file://"+uri).build().toUri()).getParent().getParent().getParent());
//// System.out.println( Paths.get(UriComponentsBuilder.fromUriString("file://"+uri).build().toUri()).getParent().getParent().getParent().getParent());
//
//
//
//// URI uu = UriComponentsBuilder.fromUriString("file://"+uri).build().toUri();
////
////
//// List<String> list = UriComponentsBuilder.fromUriString("file://"+uri).build().getPathSegments();
//// List<Path> paths = new ArrayList<Path>();
//// Path path = Paths.get(uu);
//// paths.add(path);
////// list.stream().map(i->{
////// i="/"+i;
////// return i;
////// }).forEach(System.out::println);
//// for(int i=0;i<list.size()-1; i++) {
//// Path parent =paths.get(i).getParent();
//// paths.add(parent);
// TestController.getAllParents(uri);
// System.out.println(TestController.getAllParents(uri));
// List<String> parents = TestController.getAllParents("/a/b/c/d");
// System.out.println(parents);
//
// for(int i=parents.size()-1; i>=0; i--) {
//// if(i>0) {
// System.err.println(i+" "+parents.get(i));
//// }
// }
//
//
// System.err.println(StringUtils.startsWith("a/b/c", "/"));
//
//// DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" );
//// Instant.now().atZone(ZoneOffset.systemDefault()).format(formatter);
//// System.out.println();
//// System.out.println(DateUtils.truncate(new Date(), Calendar.SECOND));
//
//
// }
//}

View File

@ -0,0 +1,62 @@
##约定大于配置,请勿重复造轮
server: #服务端口
port: 8083
##spring----------
spring:
application:
name: zwyy
datasource:
type: com.zaxxer.hikari.HikariDataSource
#url: jdbc:h2:./test;AUTO_SERVER=TRUE #连接池Database 嵌入模式jdbc:h2:~/test-jooq FILE_LOCK=SOCKET MODE=MySQL;;AUTO_SERVER=TRUE
url: jdbc:h2:./test;MODE=MySQL;AUTO_SERVER=TRUE
username: sa
password:
hikari:
driver-class-name: org.h2.Driver
# url: jdbc:mariadb://173.249.203.214:3306/test
# username: root
# password: open123
# hikari:
# driver-class-name: org.mariadb.jdbc.Driver
jackson:
date-format: yyyy-MM-dd HH:mm:ss
h2:
console:
enabled: true #开启h2数据库的浏览器管理界面
settings:
web-allow-others: true
trace: true #是否可以远程web
#path: /h2-console #h2浏览器管理访问路径默认/h2-console
sql:
init:
mode: never ##加载脚本datasource.initialize已弃用,spring.sql.init.mode=never/always
continue-on-error: true #初始化错误,继续执行
encoding: utf-8 #加载sql文件的编码连接池ue #初始化错误,继续执行
data-locations: classpath:/sql/data-h2.sql
schema-locations: classpath:/sql/schema-h2.sql #spring boot 默认启动使用springJDBC初始化数据脚本, 加载类路径下的 schema-${platform}.sql \ data-${platform}.sql数据
platform: h2
#elasticsearch:
#jest:
#uris: http://loalhost:9200
#read-timeout: 1000
# 多数据源
# app:
# datasource:
# type: com.zaxxer.hikari.HikariDataSource
# jdbcUrl: jdbc:h2:~/test-jooq;AUTO_SERVER=TRUE
# username: sa
# password:
# ##连接池
# hikari:
# driver-class-name: org.h2.Driver
#logging:
# level:
# root: info
# org.jooq: debug
# org.springframework.amqp: debug
# org.mybatis: debug
# org.mybatis.dynamic.sql: debug
# jj.tech.paolu: debug

View File

@ -0,0 +1,17 @@
/ \
/X/ \X\
|XX\ _____ /XX|
|XXX\ _/ \_ /XXX|___________
\XXXXXXX XXXXXXX/ \\\
\XXXX / \ XXXXX/ \\\
| 0 0 | \
| | \
\ / |______//
\ / |
| O_O | \ |
\ _ / \________________ |
| | | | \ /
No Bullshit, / | / | \______/
Please... \ | \ | \ | \ |
__| |__| | __| |__| |
|___||___| |___||___|

View File

@ -0,0 +1,22 @@
spring:
cloud:
consul:
scheme: https
host: consul.164500.xyz
port: 443
discovery:
acl-token: b2gs44ddr3
# service-name: ${spring.application.name}
# https://github.com/spring-cloud/spring-cloud-consul/pull/590#issuecomment-1473038044
heartbeat:
enabled: true
deregister: true
health-check-critical-timeout: 30s
# config:
# acl-token: b1gs33cr3t
#discovery:
#register-health-check: true
# discovery:
# ip-address: 192.168.43.15
# #hostname: doudou

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<jdbc>
<!-- <driver>org.mariadb.jdbc.Driver</driver>
<url>jdbc:mariadb://192.168.0.123:3306</url>
<user>root</user>
<password>test000000</password> -->
<driver>org.h2.Driver</driver>
<url>jdbc:h2:~/test;MODE=MySQL;AUTO_SERVER=TRUE</url>
<user>sa</user>
<password></password>
</jdbc>
<generator>
<database>
<!--数据库名称-->
<inputSchema>PUBLIC</inputSchema>
<!--include和exclude用于控制为数据库中哪些表生成代码-->
<includes>.*</includes>
<!--<excludes></excludes>-->
</database>
<generate>
<!--生成dao和pojo-->
<daos>true</daos>
<pojos>true</pojos>
<!--把数据库时间类型映射到java 8时间类型-->
<javaTimeTypes>true</javaTimeTypes>
<!--<interfaces>true</interfaces>-->
<!--不在生成的代码中添加spring注释比如@Repository-->
<springAnnotations>true</springAnnotations>
</generate>
<target>
<!--生成代码文件的包名及放置目录-->
<packageName>jj.tech.dcang.repository.jooq</packageName>
<directory>target/generated-sources/repository</directory>
</target>
</generator>
</configuration>

View File

@ -0,0 +1,91 @@
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 驱动 -->
<!-- <classPathEntry location="C:\Users\lenovo\.m2\repository\com\h2database\h2\2.1.214\h2-2.1.214.jar"/> -->
<!--<classPathEntry location="C:\Users\lenovo\.m2\repository\com\mysql\mysql-connector-j\8.0.33\mysql-connector-j-8.0.33.jar"/>-->
<!--<classPathEntry location="C:\Users\lenovo\.m2\repository\org\mariadb\jdbc\mariadb-java-client\3.1.4\mariadb-java-client-3.1.4.jar"/>-->
<!-- <classPathEntry location="C:\Users\Administrator\.m2\repository\net\sourceforge\jtds\jtds\1.3.1\jtds-1.3.1.jar"/> -->
<!-- <classPathEntry location="C:\Users\Administrator\.m2\repository\com\oracle\ojdbc14\10.2.0.2.0\ojdbc14-10.2.0.2.0.jar"/> -->
<context id="mysqlTables" targetRuntime="MyBatis3DynamicSql"> <!-- MyBatis3DynamicSql MyBatis3-->
<commentGenerator>
<!-- <property name="suppressDate" value="true"/> -->
<!-- 是否去除自动生成的注释 true false:否 -->
<!-- <property name="suppressAllComments" value="true" /> -->
<property name="addRemarkComments" value="true" />
</commentGenerator>
<!--<jdbcConnection driverClass="org.h2.Driver" connectionURL="jdbc:h2:./test;MODE=MySQL;AUTO_SERVER=TRUE" userId="sa" password="">
</jdbcConnection>-->
<!-- nullCatalogMeansCurrent对mariadb 不起作用,会查出所有的非表对象 -->
<jdbcConnection driverClass="org.mariadb.jdbc.Driver" connectionURL="jdbc:mariadb://192.168.0.123:3306" userId="root" password="test000000">
<!--<property name="nullCatalogMeansCurrent" value="true" />-->
</jdbcConnection>
<!-- 数据库驱动、连接URL、用户名、密码 -->
<!--<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://139.198.106.100:3306/archive?characterEncoding=utf-8" userId="root" password="test000000">
<property name="nullCatalogMeansCurrent" value="true" />
</jdbcConnection>-->
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@192.168.63.200:1521:orcl"
userId="new_hlpay" password="new_hlpay"> </jdbcConnection> -->
<!-- <jdbcConnection driverClass="net.sourceforge.jtds.jdbc.Driver" connectionURL="jdbc:jtds:sqlserver://192.168.63.190;DatabaseName=pay_2015-01-api"
userId="sa" password="111111"> </jdbcConnection> -->
<javaTypeResolver>
<!--<property name="forceBigDecimals" value="false" />-->
<property name="useJSR310Types" value="true" />
</javaTypeResolver>
<!-- 生成模型包名和位置 -->
<javaModelGenerator targetPackage="jj.tech.dcang.repository.mybatis.entity"
targetProject="target/generated-sources/repository">
<!-- <property name="enableSubPackages" value="true" /> -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成xml文件的包名和位置 -->
<!-- <sqlMapGenerator targetPackage="jj.tech.dcang.repository.mybatis.dao"
targetProject="target/generated-sources/repository">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator> -->
<!-- 生成DAO的包名和位置 -->
<javaClientGenerator targetPackage="jj.tech.dcang.repository.mybatis.dao"
targetProject="target/generated-sources/repository">
<!-- <property name="enableSubPackages" value="true" /> -->
<property name="dynamicSqlSupportPackage" value="jj.tech.dcang.repository.mybatis.dao.support"/>
</javaClientGenerator>
<!-- 需要生成的表, mysql 不支持这种模式: catalog="TEST" schema="PUBLIC" -->
<!-- 参考https://mybatis.org/generator/usage/mysql.html -->
<!--<table schema="PUBLIC" tableName="%" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<generatedKey column="id" sqlStatement="MySql" identity="false" />
</table>-->
<table catalog="archive" tableName="%" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<property name="ignoreQualifiersAtRuntime" value="true" />
<!--设置ID自增策略为MySql时, id可以指定值, 无法生成批量插入方法insertMultiple-->
<generatedKey column="id" sqlStatement="MySql" identity="true" />
<!--设置ID自增策略为JDBC时, id不能指定值, 可以生成批量插入方法insertMultiple-->
<!--<generatedKey column="id" sqlStatement="JDBC" identity="true" />-->
</table>
</context>
</generatorConfiguration>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>http://192.168.0.123:3100/loki/api/v1/push</url>
</http>
<format>
<label>
<pattern>app=zwyy,host=${HOSTNAME},level=%level</pattern>
</label>
<message>
<!-- <pattern>l=%level h=${HOSTNAME} c=%logger{20} t=%thread | %msg %ex</pattern> -->
<pattern>%d{yyyy-MM-dd HH-mm-ss.SSSXXX} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
</message>
<sortByTime>true</sortByTime>
</format>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{yyyy-MM-dd HH-mm-ss.SSSXXX} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<logger name="jj.tech.paolu">
<level value="debug"/>
</logger>
<logger name="org.springframework.jdbc.core">
<level value="debug"/>
</logger>
<logger name="org.springframework.jdbc.support">
<level value="debug"/>
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,415 @@
DROP ALL OBJECTS;
DROP TABLE IF EXISTS sys_admin;
CREATE TABLE sys_admin
(
id INT NOT NULL auto_increment,
realname VARCHAR(50) NOT NULL,
username VARCHAR(50) NOT NULL,
password VARCHAR(70) NOT NULL COMMENT 'sha3_256Hex',
islock INT DEFAULT 0 COMMENT '0正常,1锁定',
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS sys_role;
CREATE TABLE sys_role
(
id INT NOT NULL auto_increment,
rolename VARCHAR(50) NOT NULL,
department VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS sys_admin_role;
CREATE TABLE sys_admin_role (
id INT NOT NULL auto_increment,
admin_id INT NOT NULL,
role_id INT NOT NULL,
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS `sys_resource`;
CREATE TABLE `sys_resource` (
id INT NOT NULL auto_increment,
parent_id INT DEFAULT NULL,
level smallint DEFAULT NULL COMMENT '菜单排列顺序',
name VARCHAR(50) DEFAULT NULL,
types VARCHAR(40) DEFAULT NULL COMMENT '资源类型',
url VARCHAR(200) DEFAULT NULL,
icon VARCHAR(100) DEFAULT NULL COMMENT '菜单图标',
ishide tinyint DEFAULT '0' COMMENT '是否折叠隐藏',
description VARCHAR(200) DEFAULT NULL,
PRIMARY KEY (`id`)
);
DROP TABLE IF EXISTS `sys_role_resource`;
CREATE TABLE `sys_role_resource` (
`role_id` INT NOT NULL,
`res_id` INT NOT NULL,
PRIMARY KEY (`role_id`,`res_id`)
);
DROP TABLE IF EXISTS SYS_URLS;
CREATE TABLE SYS_URLS (
id INT NOT NULL auto_increment,
pid INT COMMENT '父类ID',
types INT DEFAULT 1 COMMENT '1:url,2:菜单',
level INT DEFAULT 0 COMMENT '0:url,1:一级菜单, 2:二级菜单',
url VARCHAR(300) DEFAULT NULL,
name VARCHAR(200) DEFAULT NULL,
method VARCHAR(200) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE (url)
);
DROP TABLE IF EXISTS sys_role_url;
CREATE TABLE sys_role_url (
id INT NOT NULL auto_increment,
role_id INT NOT NULL,
url VARCHAR(300) NOT NULL COMMENT '对应SYS_URLS的url',
urltypes INT NOT NULL COMMENT '1:url,2:菜单',
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS SCHOOL;
CREATE TABLE SCHOOL
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) COMMENT '学校名称',
sort INT NOT NULL AUTO_INCREMENT COMMENT '学校排序',
inshow INT DEFAULT 1 COMMENT '是否显示0不显示1显示',
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS SCHOOL_DISTRICT;
CREATE TABLE SCHOOL_DISTRICT
(
id INT NOT NULL AUTO_INCREMENT,
schoolid INT NOT NULL COMMENT '所属学校ID',
district VARCHAR(200) COMMENT '校区名称',
sort INT NOT NULL AUTO_INCREMENT COMMENT '校区排序',
inshow INT DEFAULT 1 COMMENT '是否显示0不显示1显示',
edittime DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后编辑时间',
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS SCHOOL_DISTRICT_BUILDING;
CREATE TABLE SCHOOL_DISTRICT_BUILDING
(
id INT NOT NULL AUTO_INCREMENT,
districtid INT COMMENT '所属分校ID',
building VARCHAR(200) COMMENT '建筑名称',
sort INT NOT NULL AUTO_INCREMENT COMMENT '楼排序',
inshow int DEFAULT 1 COMMENT '是否显示0不显示1显示',
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS SCHOOL_DISTRICT_BUILDING_FLOOR;
CREATE TABLE SCHOOL_DISTRICT_BUILDING_FLOOR
(
id INT NOT NULL AUTO_INCREMENT,
buildingid INT COMMENT '所属建筑ID',
floor VARCHAR(200) COMMENT '楼层名称',
sort INT NOT NULL AUTO_INCREMENT COMMENT '楼层排序',
inshow int DEFAULT 1 COMMENT '是否显示0不显示1显示',
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS ROOM;
CREATE TABLE ROOM
(
id INT NOT NULL AUTO_INCREMENT,
districtid INT COMMENT '所属分校ID',
districtname VARCHAR(200) COMMENT '分校名称',
buildingid INT COMMENT '所属建筑ID',
buildingname VARCHAR(200) COMMENT '建筑名称',
floorid INT COMMENT '所属楼层ID',
floorname VARCHAR(200) COMMENT '楼层名称',
room VARCHAR(200) COMMENT '房间名称',
frontname VARCHAR(200) COMMENT '正前方名称',
sort INT NOT NULL AUTO_INCREMENT COMMENT '房间排序',
inshow INT DEFAULT 1 COMMENT '是否显示0不显示1显示',
rols INT DEFAULT 10 COMMENT '一共多少行',
cols INT DEFAULT 10 COMMENT '一共多少列',
seatscount INT DEFAULT 0 COMMENT '一共多少个座位',
edittime DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后编辑时间',
PRIMARY KEY (id)
);
-- 房间对应的座位
DROP TABLE IF EXISTS ROOM_SEATS;
CREATE TABLE ROOM_SEATS
(
id INT NOT NULL AUTO_INCREMENT,
seatname VARCHAR(200) COMMENT '座位名称',
seatvalue VARCHAR(200) COMMENT '座位选中后的值',
roomid INT NOT NULL COMMENT '房间ID',
roomname VARCHAR(200) COMMENT '房间名称',
typesid INT DEFAULT 0 COMMENT '关联SEATS_TYPE',
inshow INT DEFAULT 1 COMMENT '是否显示0禁用1可用',
rol INT COMMENT '',
col INT COMMENT '',
PRIMARY KEY (id)
);
-- 座位类型
DROP TABLE IF EXISTS SEATS_TYPE;
CREATE TABLE SEATS_TYPE
(
id INT NOT NULL AUTO_INCREMENT,
typename VARCHAR(50) COMMENT '名称: 普通,研究生,教师, 勤工助学区等',
typeval VARCHAR(50) COMMENT '值: 1身份, 2座位区域对应所有身份',
colour VARCHAR(50) COMMENT '座位颜色',
isapply INT DEFAULT 1 COMMENT '0不启用,1启用',
PRIMARY KEY (id),
UNIQUE (colour)
);
-- 座位相关设备
DROP TABLE IF EXISTS SEATS_DEVICE;
CREATE TABLE SEATS_DEVICE
(
id INT NOT NULL AUTO_INCREMENT,
seatsid INT NOT NULL COMMENT '座位ID',
deviceid INT NOT NULL COMMENT '设备ID',
devicename INT NOT NULL COMMENT '设备名称',
PRIMARY KEY (id)
);
-- 设备表
DROP TABLE IF EXISTS DEVICE;
CREATE TABLE DEVICE
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) COMMENT '名称: 0电源, 1网口, ...',
val INT DEFAULT 0 COMMENT '值: 0电源, 1网口, ...',
isapply INT DEFAULT 1 COMMENT '0不启用,1启用',
PRIMARY KEY (id)
);
-- 模板
DROP TABLE IF EXISTS TEMPLATE;
CREATE TABLE TEMPLATE
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) COMMENT '模板名称',
frontname VARCHAR(200) COMMENT '正前方名称',
rols INT COMMENT '一共多少行',
cols INT COMMENT '一共多少列',
seatscount INT DEFAULT 0 COMMENT '一共多少个座位',
PRIMARY KEY (id)
);
-- 模板的座位
DROP TABLE IF EXISTS TEMPLATE_SEATS;
CREATE TABLE TEMPLATE_SEATS
(
id INT NOT NULL AUTO_INCREMENT,
templateid INT NOT NULL COMMENT '模板ID',
seatname VARCHAR(200) COMMENT '座位名称',
seatvalue VARCHAR(200) COMMENT '座位选中后的值',
typesid INT DEFAULT 0 COMMENT '关联SEATS_TYPE',
inshow INT DEFAULT 1 COMMENT '是否显示0禁用1可用',
rol INT COMMENT '',
col INT COMMENT '',
PRIMARY KEY (id)
);
-- 用户信息
DROP TABLE IF EXISTS USER_INFO;
CREATE TABLE USER_INFO (
id INT NOT NULL AUTO_INCREMENT,
realname VARCHAR(200) NOT NULL,
nickname VARCHAR(200) NOT NULL,
username VARCHAR(200) NOT NULL,
password VARCHAR(70) NOT NULL,
usertypeid INT DEFAULT 0 COMMENT '0本科生,1研究生,2教师,3其他',
islock INT DEFAULT 0 COMMENT '0正常,1锁定',
source INT DEFAULT 0 COMMENT '0注册,1第三方,3管理员添加',
head_img VARCHAR(1000),
PRIMARY KEY (id),
UNIQUE (username)
);
-- 用户类型
DROP TABLE IF EXISTS USER_INFO_TYPE;
CREATE TABLE USER_INFO_TYPE (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) COMMENT '名称: 0本科生,1研究生,2教师,3其他',
val VARCHAR(50) COMMENT '值: 0本科生,1研究生,2教师,3其他',
isapply INT DEFAULT 1 COMMENT '0不启用,1启用',
PRIMARY KEY (id)
);
-- 用户座位预约
DROP TABLE IF EXISTS USER_SEATS;
CREATE TABLE USER_SEATS (
id INT NOT NULL AUTO_INCREMENT,
userid INT NOT NULL,
username VARCHAR(200) NOT NULL,
roomid INT NOT NULL COMMENT '所属房间ID',
room VARCHAR(200) COMMENT '房间名称',
seatid INT NOT NULL COMMENT '座位ID',
seatname VARCHAR(200) COMMENT '座位名称',
seatvalue VARCHAR(200) COMMENT '座位选中后的值',
duetime DATETIME COMMENT '预约下单时间',
duestartime DATETIME COMMENT '预约座位开始时间',
dueendtime DATETIME COMMENT '预约座位结束时间',
duestatu INT DEFAULT 1 COMMENT '预约状态:1预约成功,2签到成功,3结束',
PRIMARY KEY (id)
);
-- 用户投诉表
DROP TABLE IF EXISTS USER_COMPLAIN;
CREATE TABLE USER_COMPLAIN (
id INT NOT NULL AUTO_INCREMENT,
userid INT NOT NULL,
username VARCHAR(200) NOT NULL,
usertypeid INT DEFAULT 0 COMMENT '0本科生,1研究生,2教师,3职工',
complain VARCHAR(4000),
committime DATETIME COMMENT '提交时间',
isdelete INT DEFAULT 0 COMMENT '0未删除,1已删除',
PRIMARY KEY (id)
);
-- 用户座位维修表
DROP TABLE IF EXISTS USER_REPAIR;
CREATE TABLE USER_REPAIR (
id INT NOT NULL AUTO_INCREMENT,
userid INT NOT NULL,
username VARCHAR(200) NOT NULL,
usertypeid INT DEFAULT 0 COMMENT '0本科生,1研究生,2教师,3职工',
repair VARCHAR(4000),
committime DATETIME COMMENT '提交时间',
isdelete INT DEFAULT 0 COMMENT '0未删除,1已删除',
PRIMARY KEY (id)
);
-- 预约规则
DROP TABLE IF EXISTS RULE;
CREATE TABLE RULE (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
startime DATETIME COMMENT '规则开始时间',
endtime DATETIME COMMENT '规则结束时间',
circle INT DEFAULT 0 COMMENT '0单次,1每年循环',
types INT DEFAULT 0 COMMENT '0网络预约,1现场预约',
signedtimeout INT COMMENT '签到超时分钟',
stepawaytimeout INT COMMENT '可以暂时离开分钟',
bookdate INT COMMENT '可预约天数',
opentime DATETIME COMMENT '可预约放号时间',
renewaltime INT COMMENT '续座时间分钟',
canceltime INT DEFAULT 20 COMMENT '预约后可以取消的时间',
cancelnumber INT DEFAULT 5 COMMENT '预约后可以取消次数',
PRIMARY KEY (id)
);
-- 预约规则对应的用户类型
DROP TABLE IF EXISTS RULE_USERTYPE;
CREATE TABLE RULE_USERTYPE (
id INT NOT NULL AUTO_INCREMENT,
ruleid INT NOT NULL COMMENT '预约规则ID',
usertypeid INT NOT NULL COMMENT '用户类型ID',
PRIMARY KEY (id)
);
-- 预约规则违约对应的访问区域
DROP TABLE IF EXISTS RULE_REGION;
CREATE TABLE RULE_REGION (
id INT NOT NULL AUTO_INCREMENT,
ruleid INT NOT NULL COMMENT '预约规则ID',
roomid INT NOT NULL COMMENT '所属房间ID',
PRIMARY KEY (id)
);
-- 房间对应的预约规则
DROP TABLE IF EXISTS ROOM_RULE;
CREATE TABLE ROOM_RULE (
id INT NOT NULL AUTO_INCREMENT,
roomid INT NOT NULL COMMENT '房间ID',
ruleid INT NOT NULL COMMENT '预约规则ID',
PRIMARY KEY (id)
);
-- 违反预约规则记录
DROP TABLE IF EXISTS ILLEGA_RECORD;
CREATE TABLE ILLEGA_RECORD (
id INT NOT NULL AUTO_INCREMENT,
userid INT NOT NULL,
username VARCHAR(200) NOT NULL,
ruleid INT NOT NULL COMMENT '预约规则ID',
reason VARCHAR(200) COMMENT '违规原因',
illegatime DATETIME COMMENT '违规时间',
PRIMARY KEY (id)
);
-- 黑名单列表
DROP TABLE IF EXISTS USER_BLACKLIST;
CREATE TABLE USER_BLACKLIST (
id INT NOT NULL AUTO_INCREMENT,
userid INT NOT NULL,
username VARCHAR(200) NOT NULL,
types INT DEFAULT 0 COMMENT '0本科生,1研究生,2教师,3其他',
reason VARCHAR(500) COMMENT '拉黑原因',
committime DATETIME COMMENT '提交时间',
isrelease INT DEFAULT 0 COMMENT '是否释放:0否1释放',
PRIMARY KEY (id)
);
-- 用户消息
DROP TABLE IF EXISTS MESSAGE_USER;
CREATE TABLE MESSAGE_USER (
id INT NOT NULL AUTO_INCREMENT,
userid INT NOT NULL,
username VARCHAR(200) NOT NULL,
types INT DEFAULT 0 COMMENT '0本科生,1研究生,2教师,3职工',
messagetypes INT DEFAULT 0 COMMENT '0系统,1短信',
message VARCHAR(4000),
committime DATETIME COMMENT '提交时间',
isdelete INT DEFAULT 0 COMMENT '0未删除,1已删除',
PRIMARY KEY (id)
);
-- 管理员消息
DROP TABLE IF EXISTS MESSAGE_ADMIN;
CREATE TABLE MESSAGE_ADMIN (
id INT NOT NULL AUTO_INCREMENT,
adminid INT NOT NULL,
adminname VARCHAR(200) NOT NULL,
types INT DEFAULT 0 COMMENT '0本科生,1研究生,2教师,3职工',
messagetypes INT DEFAULT 0 COMMENT '0系统,1短信',
message VARCHAR(4000),
committime DATETIME COMMENT '提交时间',
isdelete INT DEFAULT 0 COMMENT '0未删除,1已删除',
PRIMARY KEY (id)
);
-- 门禁打卡记录
DROP TABLE IF EXISTS ACCESS_CONTROL_RECORD;
CREATE TABLE ACCESS_CONTROL_RECORD (
id INT NOT NULL AUTO_INCREMENT,
accesstime DATETIME COMMENT '刷卡时间',
PRIMARY KEY (id)
);

View File

@ -0,0 +1,218 @@
<#assign package = pojo.getPackageDeclaration()>
${package?substring(0,package?length-1)}.daos;
// Generated ${date} by Hibernate Tools ${version}
import ${pojo.getQualifiedDeclarationName()};
<#assign classbody>
<#assign declarationName = pojo.importType(pojo.getDeclarationName())>/**
* Home object for domain model class ${declarationName}.
* @see ${pojo.getQualifiedDeclarationName()}
* @author Hibernate Tools
*/
<#if ejb3>
@${pojo.importType("javax.ejb.Stateless")}
</#if>
<#if pojo.hasIdentifierProperty()>
${pojo.getJavaTypeName(clazz.identifierProperty, jdk5)}
</#if>
public class ${declarationName}Dao {
private static final ${pojo.importType("java.util.logging.Logger")} logger = ${pojo.importType("Logger")}.getLogger(${pojo.getDeclarationName()}Dao.class.getName());
<#if ejb3>
@${pojo.importType("jakarta.persistence.PersistenceContext")} private ${pojo.importType("jakarta.persistence.EntityManager")} entityManager;
public void persist(${declarationName} transientInstance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "persisting ${declarationName} instance");
try {
entityManager.persist(transientInstance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "persist successful");
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "persist failed", re);
throw re;
}
}
public void remove(${declarationName} persistentInstance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "removing ${declarationName} instance");
try {
entityManager.remove(persistentInstance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "remove successful");
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "remove failed", re);
throw re;
}
}
public ${declarationName} merge(${declarationName} detachedInstance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "merging ${declarationName} instance");
try {
${declarationName} result = entityManager.merge(detachedInstance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "merge successful");
return result;
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "merge failed", re);
throw re;
}
}
<#if clazz.identifierProperty?has_content>
public ${declarationName} findById( ${pojo.getJavaTypeName(clazz.identifierProperty, jdk5)} id) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "getting ${declarationName} instance with id: " + id);
try {
${declarationName} instance = entityManager.find(${pojo.getDeclarationName()}.class, id);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "get successful");
return instance;
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "get failed", re);
throw re;
}
}
</#if>
<#else>
private final ${pojo.importType("org.hibernate.SessionFactory")} sessionFactory = getSessionFactory();
protected ${pojo.importType("org.hibernate.SessionFactory")} getSessionFactory() {
try {
return (${pojo.importType("org.hibernate.SessionFactory")}) new ${pojo.importType("javax.naming.InitialContext")}().lookup("sessionFactoryName");
}
catch (Exception e) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "Could not locate SessionFactory in JNDI", e);
throw new IllegalStateException("Could not locate SessionFactory in JNDI");
}
}
public void persist(${declarationName} transientInstance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "persisting ${declarationName} instance");
try {
sessionFactory.getCurrentSession().persist(transientInstance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "persist successful");
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "persist failed", re);
throw re;
}
}
public void attachDirty(${declarationName} instance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "attaching dirty ${declarationName} instance");
try {
sessionFactory.getCurrentSession().saveOrUpdate(instance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "attach successful");
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "attach failed", re);
throw re;
}
}
public void attachClean(${declarationName} instance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "attaching clean ${declarationName} instance");
try {
sessionFactory.getCurrentSession().lock(instance, ${pojo.importType("org.hibernate.LockMode")}.NONE);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "attach successful");
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "attach failed", re);
throw re;
}
}
public void delete(${declarationName} persistentInstance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "deleting ${declarationName} instance");
try {
sessionFactory.getCurrentSession().delete(persistentInstance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "delete successful");
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "delete failed", re);
throw re;
}
}
public ${declarationName} merge(${declarationName} detachedInstance) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "merging ${declarationName} instance");
try {
${declarationName} result = (${declarationName}) sessionFactory.getCurrentSession()
.merge(detachedInstance);
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "merge successful");
return result;
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "merge failed", re);
throw re;
}
}
<#if clazz.identifierProperty?has_content>
public ${declarationName} findById( ${c2j.getJavaTypeName(clazz.identifierProperty, jdk5)} id) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "getting ${declarationName} instance with id: " + id);
try {
${declarationName} instance = (${declarationName}) sessionFactory.getCurrentSession()
.get("${clazz.entityName}", id);
if (instance==null) {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "get successful, no instance found");
}
else {
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "get successful, instance found");
}
return instance;
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "get failed", re);
throw re;
}
}
</#if>
</#if>
<#if false>
/**
TODO:
<#if jdk5>
public ${pojo.importType("java.util.List")}<${declarationName}> findByExample(${declarationName} instance) {
<#else>
public ${pojo.importType("java.util.List")} findByExample(${declarationName} instance) {
</#if>
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "finding ${declarationName} instance by example");
try {
<#if jdk5>
${pojo.importType("java.util.List")}<${declarationName}> results = (List<${declarationName}>) sessionFactory.getCurrentSession()
<#else>
${pojo.importType("java.util.List")} results = sessionFactory.getCurrentSession()
</#if>
.createCriteria("${clazz.entityName}")
<#if jdk5>
.add( ${pojo.staticImport("org.hibernate.criterion.Example", "create")}(instance) )
<#else>
.add(${pojo.importType("org.hibernate.criterion.Example")}.create(instance))
</#if>
.list();
logger.log(${pojo.importType("java.util.logging.Level")}.INFO, "find by example successful, result size: " + results.size());
return results;
}
catch (RuntimeException re) {
logger.log(${pojo.importType("java.util.logging.Level")}.SEVERE, "find by example failed", re);
throw re;
}
}
**/
</#if>
}
</#assign>
${pojo.generateImports()}
${classbody}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
org.mariadb.jdbc.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:mariadb://192.168.0.123:3306/book
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
test000000
</property>
<property name="hibernate.show_sql">true</property>
<!-- <property name="hbm2ddl.auto">update</property> -->
<!-- <mapping resource="mappings/hrdb.hbm.xml"></mapping> -->
</session-factory>
</hibernate-configuration>

View File

@ -0,0 +1,12 @@
#hibernate.dialect=org.hibernate.dialect.MySQLDialect
#hibernate.connection.driver_class=org.mariadb.jdbc.Driver
#hibernate.connection.url=jdbc:mariadb://192.168.0.123:3306/book
#hibernate.connection.username=root
#hibernate.connection.password=test000000
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:~/test-jooq;MODE=MySQL;AUTO_SERVER=TRUE
hibernate.connection.username=sa
hibernate.connection.password=
hibernate.user_sql_comments=true

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering SYSTEM "http://hibernate.org/dtd/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
<schema-selection match-catalog="TEST-JOOQ" match-schema="PUBLIC" match-table=".*"/>
<!-- <schema-selection match-catalog="book" match-schema="book" match-table=".*"/> -->
<!-- <table-filter match-schema="book" match-name=".*" exclude="true"/> -->
<!-- <type-mapping>
<sql-type jdbc-type="DATE" hibernate-type="java.time.LocalDate"/>
<sql-type jdbc-type="TIMESTAMP" hibernate-type="java.time.LocalDateTime"/>
</type-mapping> -->
</hibernate-reverse-engineering>