first commit
This commit is contained in:
commit
03cd33b658
|
|
@ -0,0 +1,39 @@
|
|||
**项目说明**
|
||||
- sqx-fast是一个轻量级的,前后端分离的Java快速开发平台,能快速开发项目并交付
|
||||
- 支持MySQL、PostgreSQL等主流数据库
|
||||
<br>
|
||||
|
||||
|
||||
**具有如下特点**
|
||||
- 友好的代码结构及注释,便于阅读及二次开发
|
||||
- 实现前后端分离,通过token进行数据交互,前端再也不用关注后端技术
|
||||
- 灵活的权限控制,可控制到页面或按钮,满足绝大部分的权限需求
|
||||
- 页面交互使用Vue2.x,极大的提高了开发效率
|
||||
- 引入API模板,根据token作为登录令牌,极大的方便了APP接口开发
|
||||
- 引入swagger文档支持,方便编写API接口文档
|
||||
<br>
|
||||
|
||||
|
||||
**技术选型:**
|
||||
- 核心框架:Spring Boot 2.6
|
||||
- 安全框架:Apache Shiro 1.4
|
||||
- 视图框架:Spring MVC 5.0
|
||||
- 持久层框架:MyBatis 3.3
|
||||
- 数据库连接池:Druid 1.0
|
||||
- 日志管理:SLF4J 1.7、Log4j
|
||||
- 页面交互:Vue2.x
|
||||
<br>
|
||||
|
||||
|
||||
**后端部署**
|
||||
- 通过git下载源码
|
||||
- idea、eclipse需安装lombok插件,不然会提示找不到entity的get set方法
|
||||
- 创建数据库sqx_fast,数据库编码为UTF-8
|
||||
- 执行db/mysql.sql文件,初始化数据
|
||||
- 修改application-dev.yml,更新MySQL账号和密码
|
||||
- Eclipse、IDEA运行sqxApplication.java,则可启动项目
|
||||
- Swagger文档路径:http://localhost:8080/sqx_fast/swagger/index.html
|
||||
- Swagger注解路径:http://localhost:8080/sqx_fast/swagger-ui.html
|
||||
|
||||
|
||||
<br>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,526 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.sqx</groupId>
|
||||
<artifactId>duanju</artifactId>
|
||||
<version>7.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
<description>duanju</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.11</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<mybatisplus.version>3.2.0</mybatisplus.version>
|
||||
<mysql.version>8.0.17</mysql.version>
|
||||
<mssql.version>4.0</mssql.version>
|
||||
<oracle.version>11.2.0.3</oracle.version>
|
||||
<druid.version>1.1.13</druid.version>
|
||||
<quartz.version>2.3.0</quartz.version>
|
||||
<commons.lang.version>2.6</commons.lang.version>
|
||||
<commons.fileupload.version>1.2.2</commons.fileupload.version>
|
||||
<commons.io.version>2.5</commons.io.version>
|
||||
<commons.codec.version>1.10</commons.codec.version>
|
||||
<commons.configuration.version>1.10</commons.configuration.version>
|
||||
<shiro.version>1.6.0</shiro.version>
|
||||
<jwt.version>0.7.0</jwt.version>
|
||||
<kaptcha.version>0.0.9</kaptcha.version>
|
||||
<qiniu.version>7.2.23</qiniu.version>
|
||||
<aliyun.oss.version>3.4.0</aliyun.oss.version>
|
||||
<qcloud.cos.version>4.4</qcloud.cos.version>
|
||||
<swagger.version>2.7.0</swagger.version>
|
||||
<joda.time.version>2.9.9</joda.time.version>
|
||||
<gson.version>2.8.5</gson.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<hutool.version>4.6.10</hutool.version>
|
||||
<lombok.version>1.18.4</lombok.version>
|
||||
|
||||
<!--wagon plugin 配置-->
|
||||
<!--<service-path>/work/sz</service-path>
|
||||
<pack-name>${project.artifactId}-${project.version}.jar</pack-name>
|
||||
<remote-addr>192.168.1.10:22</remote-addr>
|
||||
<remote-username>root</remote-username>
|
||||
<remote-passwd>123456</remote-passwd>-->
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.volcengine</groupId>
|
||||
<artifactId>ve-tos-java-sdk</artifactId>
|
||||
<version>2.6.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk</artifactId>
|
||||
<version>1.11.274</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.afterturn</groupId>
|
||||
<artifactId>easypoi-spring-boot-starter</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.qcloudsms</groupId>
|
||||
<artifactId>qcloudsms</artifactId>
|
||||
<version>1.0.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.qcloud</groupId>
|
||||
<artifactId>cos_api</artifactId>
|
||||
<version>5.5.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--云购os支付-->
|
||||
<dependency>
|
||||
<groupId>com.yungouos.pay</groupId>
|
||||
<artifactId>yungouos-pay-sdk</artifactId>
|
||||
<version>2.0.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.2.3.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<!-- go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version. -->
|
||||
<!-- 请到https://search.maven.org/search?q=tencentcloud-sdk-java查询所有版本,最新版本如下 -->
|
||||
<version>3.1.792</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>5.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-platform</artifactId>
|
||||
<version>5.5.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.10</version>
|
||||
</dependency>
|
||||
<!-- 苹果工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>3.8.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>jwks-rsa</artifactId>
|
||||
<version>0.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.4</version>
|
||||
<classifier>jdk15</classifier>
|
||||
</dependency>
|
||||
<!-- excel工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>4.0.1</version>
|
||||
</dependency>
|
||||
<!-- excel工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>4.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.qcloudsms</groupId>
|
||||
<artifactId>qcloudsms</artifactId>
|
||||
<version>1.0.6</version>
|
||||
</dependency>
|
||||
<!--阿里云短信-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
<version>4.5.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
<!-- 集成支付宝sdk -->
|
||||
<dependency>
|
||||
<groupId>com.alipay.sdk</groupId>
|
||||
<artifactId>alipay-sdk-java</artifactId>
|
||||
<version>4.10.29.ALL</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.wxpay</groupId>
|
||||
<artifactId>wxpay-sdk</artifactId>
|
||||
<version>0.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.liyiorg</groupId>
|
||||
<artifactId>weixin-popular</artifactId>
|
||||
<version>2.8.25</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-devtools</artifactId>-->
|
||||
<!--<optional>true</optional>-->
|
||||
<!--</dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatisplus.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
<!--oracle驱动-->
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>${oracle.version}</version>
|
||||
</dependency>
|
||||
<!--mssql驱动-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>sqljdbc4</artifactId>
|
||||
<version>${mssql.version}</version>
|
||||
</dependency>
|
||||
<!--postgresql驱动-->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>${quartz.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commons.lang.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>${commons.fileupload.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons.codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>${commons.configuration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.axet</groupId>
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<version>${kaptcha.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
<artifactId>qiniu-java-sdk</artifactId>
|
||||
<version>${qiniu.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${joda.time.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--二维码生成架包引用-->
|
||||
<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.3.3</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.3.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<version>3.6.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-pay</artifactId>
|
||||
<version>3.6.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.2.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mybatis-spring</artifactId>
|
||||
<groupId>org.mybatis</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<groupId>org.mybatis</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.dozermapper</groupId>
|
||||
<artifactId>dozer-core</artifactId>
|
||||
<version>6.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.getui.push</groupId>
|
||||
<artifactId>restful-sdk</artifactId>
|
||||
<version>1.0.0.1</version>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>com.baidu.aip</groupId>-->
|
||||
<!-- <artifactId>java-sdk</artifactId>-->
|
||||
<!-- <version>4.11.3</version>-->
|
||||
<!--</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-ssh</artifactId>
|
||||
<version>2.8</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 跳过单元测试 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>wagon-maven-plugin</artifactId>
|
||||
<version>1.0</version>
|
||||
<!--<configuration>
|
||||
<fromFile>target/${pack-name}</fromFile>
|
||||
<url><![CDATA[scp://${remote-username}:${remote-passwd}@${remote-addr}${service-path}]]></url>
|
||||
<commands>
|
||||
<!– Kill Old Process –>
|
||||
<command>kill -9 `ps -ef |grep ${project.artifactId}.jar|grep -v "grep" |awk '{print $2}'`</command>
|
||||
<command><![CDATA[nohup java -jar ${service-path}/${pack-name} --spring.profiles.active=test > ${service-path}/sz.log 2>&1 & ]]></command>
|
||||
<command><![CDATA[netstat -nptl]]></command>
|
||||
<command><![CDATA[ps -ef | grep java | grep -v grep]]></command>
|
||||
</commands>
|
||||
<!– 运行命令 mvn clean package wagon:upload-single wagon:sshexec–>
|
||||
<displayCommandOutputs>true</displayCommandOutputs>
|
||||
</configuration>-->
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>0.4.14</version>
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<phase>package</phase>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>build</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<configuration>
|
||||
<imageName>sqx/fast</imageName>
|
||||
<dockerDirectory>${project.basedir}</dockerDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>/</targetPath>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<include>${project.build.finalName}.jar</include>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
<!-- 运行命令 mvn clean package docker:build 打包并生成docker镜像 -->
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>douyincloud</id>
|
||||
<name>douyincloud</name>
|
||||
<url>https://artifacts-cn-beijing.volces.com/repository/douyincloud/</url>
|
||||
</repository>
|
||||
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sqx;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
public class SqxApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SqxApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 短剧系统启动成功 ლ(´ڡ`ლ)゙ \n"+
|
||||
" _ \n" +
|
||||
" | | \n" +
|
||||
" ___ | | __\n" +
|
||||
" / _ \\| |/ /\n" +
|
||||
"| (_) | < \n" +
|
||||
" \\___/|_|\\_\\");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.sqx.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 系统日志注解
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SysLog {
|
||||
|
||||
String value() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.sqx.common.aspect;
|
||||
|
||||
import com.sqx.common.exception.SqxException;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Redis切面处理类
|
||||
*
|
||||
*/
|
||||
@Aspect
|
||||
@Configuration
|
||||
public class RedisAspect {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
//是否开启redis缓存 true开启 false关闭
|
||||
@Value("${spring.redis.open: false}")
|
||||
private boolean open;
|
||||
|
||||
@Around("execution(* com.sqx.common.utils.RedisUtils.*(..))")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
Object result = null;
|
||||
if(open){
|
||||
try{
|
||||
result = point.proceed();
|
||||
}catch (Exception e){
|
||||
logger.error("redis error", e);
|
||||
throw new SqxException("Redis服务异常");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package com.sqx.common.aspect;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.sqx.common.utils.HttpContextUtils;
|
||||
import com.sqx.common.utils.IPUtils;
|
||||
import com.sqx.common.annotation.SysLog;
|
||||
import com.sqx.modules.sys.entity.SysLogEntity;
|
||||
import com.sqx.modules.sys.entity.SysUserEntity;
|
||||
import com.sqx.modules.sys.service.SysLogService;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 系统日志,切面处理类
|
||||
*
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class SysLogAspect {
|
||||
@Autowired
|
||||
private SysLogService sysLogService;
|
||||
|
||||
@Pointcut("@annotation(com.sqx.common.annotation.SysLog)")
|
||||
public void logPointCut() {
|
||||
|
||||
}
|
||||
|
||||
@Around("logPointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
//执行方法
|
||||
Object result = point.proceed();
|
||||
//执行时长(毫秒)
|
||||
long time = System.currentTimeMillis() - beginTime;
|
||||
|
||||
//保存日志
|
||||
saveSysLog(point, time);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
SysLogEntity sysLog = new SysLogEntity();
|
||||
SysLog syslog = method.getAnnotation(SysLog.class);
|
||||
if(syslog != null){
|
||||
//注解上的描述
|
||||
sysLog.setOperation(syslog.value());
|
||||
}
|
||||
|
||||
//请求的方法名
|
||||
String className = joinPoint.getTarget().getClass().getName();
|
||||
String methodName = signature.getName();
|
||||
sysLog.setMethod(className + "." + methodName + "()");
|
||||
|
||||
//请求的参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
try{
|
||||
String params = new Gson().toJson(args);
|
||||
sysLog.setParams(params);
|
||||
}catch (Exception e){
|
||||
|
||||
}
|
||||
|
||||
//获取request
|
||||
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
||||
//设置IP地址
|
||||
sysLog.setIp(IPUtils.getIpAddr(request));
|
||||
|
||||
//用户名
|
||||
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
|
||||
sysLog.setUsername(username);
|
||||
|
||||
sysLog.setTime(time);
|
||||
sysLog.setCreateDate(new Date());
|
||||
//保存系统日志
|
||||
sysLogService.save(sysLog);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.sqx.common.exception;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
*/
|
||||
public class SqxException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code = 500;
|
||||
|
||||
public SqxException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public SqxException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public SqxException(String msg, int code) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public SqxException(String msg, int code, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package com.sqx.common.exception;
|
||||
|
||||
import com.sqx.common.utils.Result;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class SqxExceptionHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(SqxException.class)
|
||||
public Result handleException(SqxException e){
|
||||
Result r = new Result();
|
||||
r.put("code", e.getCode());
|
||||
r.put("msg", e.getMessage());
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
public Result handlerNoFoundException(Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return Result.error(404, "路径不存在,请检查路径是否正确");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public Result handleDuplicateKeyException(DuplicateKeyException e){
|
||||
logger.error(e.getMessage(), e);
|
||||
return Result.error("数据库中已存在该记录");
|
||||
}
|
||||
|
||||
@ExceptionHandler(AuthorizationException.class)
|
||||
public Result handleAuthorizationException(AuthorizationException e){
|
||||
logger.error(e.getMessage(), e);
|
||||
return Result.error("没有权限,请联系管理员授权");
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result handleException(Exception e){
|
||||
logger.error(e.getMessage(), e);
|
||||
return Result.error();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
/**
|
||||
* 系统参数相关Key
|
||||
*
|
||||
*/
|
||||
public class ConfigConstant {
|
||||
/**
|
||||
* 云存储配置KEY
|
||||
*/
|
||||
public final static String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY";
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
/**
|
||||
* 常量
|
||||
*
|
||||
*/
|
||||
public class Constant {
|
||||
/** 超级管理员ID */
|
||||
public static final int SUPER_ADMIN = 1;
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
public static final String PAGE = "page";
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static final String LIMIT = "limit";
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
public static final String ORDER_FIELD = "sidx";
|
||||
/**
|
||||
* 排序方式
|
||||
*/
|
||||
public static final String ORDER = "order";
|
||||
/**
|
||||
* 升序
|
||||
*/
|
||||
public static final String ASC = "asc";
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
public enum MenuType {
|
||||
/**
|
||||
* 目录
|
||||
*/
|
||||
CATALOG(0),
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
MENU(1),
|
||||
/**
|
||||
* 按钮
|
||||
*/
|
||||
BUTTON(2);
|
||||
|
||||
private int value;
|
||||
|
||||
MenuType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务状态
|
||||
*/
|
||||
public enum ScheduleStatus {
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL(0),
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
PAUSE(1);
|
||||
|
||||
private int value;
|
||||
|
||||
ScheduleStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 云服务商
|
||||
*/
|
||||
public enum CloudService {
|
||||
/**
|
||||
* 七牛云
|
||||
*/
|
||||
QINIU(1),
|
||||
/**
|
||||
* 阿里云
|
||||
*/
|
||||
ALIYUN(2),
|
||||
/**
|
||||
* 腾讯云
|
||||
*/
|
||||
QCLOUD(3);
|
||||
|
||||
private int value;
|
||||
|
||||
CloudService(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期处理
|
||||
*
|
||||
*/
|
||||
public class DateUtils {
|
||||
/** 时间格式(yyyy-MM-dd) */
|
||||
public final static String DATE_PATTERN = "yyyy-MM-dd";
|
||||
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
|
||||
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 日期格式化 日期格式为:yyyy-MM-dd
|
||||
* @param date 日期
|
||||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date, DATE_TIME_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化 日期格式为:yyyy-MM-dd
|
||||
* @param date 日期
|
||||
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
|
||||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date, String pattern) {
|
||||
if(date != null){
|
||||
SimpleDateFormat df = new SimpleDateFormat(pattern);
|
||||
return df.format(date);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转换成日期
|
||||
* @param strDate 日期字符串
|
||||
* @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN
|
||||
*/
|
||||
public static Date stringToDate(String strDate, String pattern) {
|
||||
if (StringUtils.isBlank(strDate)){
|
||||
return null;
|
||||
}
|
||||
|
||||
DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
|
||||
return fmt.parseLocalDateTime(strDate).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据周数,获取开始日期、结束日期
|
||||
* @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周
|
||||
* @return 返回date[0]开始日期、date[1]结束日期
|
||||
*/
|
||||
public static Date[] getWeekStartAndEnd(int week) {
|
||||
DateTime dateTime = new DateTime();
|
||||
LocalDate date = new LocalDate(dateTime.plusWeeks(week));
|
||||
|
||||
date = date.dayOfWeek().withMinimumValue();
|
||||
Date beginDate = date.toDate();
|
||||
Date endDate = date.plusDays(6).toDate();
|
||||
return new Date[]{beginDate, endDate};
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【秒】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param seconds 秒数,负数为减
|
||||
* @return 加/减几秒后的日期
|
||||
*/
|
||||
public static Date addDateSeconds(Date date, int seconds) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusSeconds(seconds).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【分钟】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param minutes 分钟数,负数为减
|
||||
* @return 加/减几分钟后的日期
|
||||
*/
|
||||
public static Date addDateMinutes(Date date, int minutes) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusMinutes(minutes).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【小时】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param hours 小时数,负数为减
|
||||
* @return 加/减几小时后的日期
|
||||
*/
|
||||
public static Date addDateHours(Date date, int hours) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusHours(hours).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【天】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param days 天数,负数为减
|
||||
* @return 加/减几天后的日期
|
||||
*/
|
||||
public static Date addDateDays(Date date, int days) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusDays(days).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【周】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param weeks 周数,负数为减
|
||||
* @return 加/减几周后的日期
|
||||
*/
|
||||
public static Date addDateWeeks(Date date, int weeks) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusWeeks(weeks).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【月】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param months 月数,负数为减
|
||||
* @return 加/减几月后的日期
|
||||
*/
|
||||
public static Date addDateMonths(Date date, int months) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusMonths(months).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【年】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param years 年数,负数为减
|
||||
* @return 加/减几年后的日期
|
||||
*/
|
||||
public static Date addDateYears(Date date, int years) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusYears(years).toDate();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class HttpContextUtils {
|
||||
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}
|
||||
|
||||
public static String getDomain(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
StringBuffer url = request.getRequestURL();
|
||||
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
|
||||
}
|
||||
|
||||
public static String getOrigin(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
return request.getHeader("Origin");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*
|
||||
*/
|
||||
public class IPUtils {
|
||||
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
|
||||
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ip = null;
|
||||
try {
|
||||
ip = request.getHeader("x-forwarded-for");
|
||||
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("IPUtils ERROR ", e);
|
||||
}
|
||||
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* Map工具类
|
||||
*
|
||||
*/
|
||||
public class MapUtils extends HashMap<String, Object> {
|
||||
|
||||
@Override
|
||||
public MapUtils put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页工具类
|
||||
*
|
||||
*/
|
||||
public class PageUtils implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 总记录数
|
||||
*/
|
||||
private int totalCount;
|
||||
/**
|
||||
* 每页记录数
|
||||
*/
|
||||
private int pageSize;
|
||||
/**
|
||||
* 总页数
|
||||
*/
|
||||
private int totalPage;
|
||||
/**
|
||||
* 当前页数
|
||||
*/
|
||||
private int currPage;
|
||||
/**
|
||||
* 列表数据
|
||||
*/
|
||||
private List<?> list;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
* @param list 列表数据
|
||||
* @param totalCount 总记录数
|
||||
* @param pageSize 每页记录数
|
||||
* @param currPage 当前页数
|
||||
*/
|
||||
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
|
||||
this.list = list;
|
||||
this.totalCount = totalCount;
|
||||
this.pageSize = pageSize;
|
||||
this.currPage = currPage;
|
||||
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
public PageUtils(IPage<?> page) {
|
||||
this.list = page.getRecords();
|
||||
this.totalCount = (int)page.getTotal();
|
||||
this.pageSize = (int)page.getSize();
|
||||
this.currPage = (int)page.getCurrent();
|
||||
this.totalPage = (int)page.getPages();
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
public void setTotalCount(int totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public int getTotalPage() {
|
||||
return totalPage;
|
||||
}
|
||||
|
||||
public void setTotalPage(int totalPage) {
|
||||
this.totalPage = totalPage;
|
||||
}
|
||||
|
||||
public int getCurrPage() {
|
||||
return currPage;
|
||||
}
|
||||
|
||||
public void setCurrPage(int currPage) {
|
||||
this.currPage = currPage;
|
||||
}
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import cn.hutool.extra.qrcode.BufferedImageLuminanceSource;
|
||||
import com.google.zxing.*;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* 二维码生成解析工具类
|
||||
|
||||
* @date 2020/02/12 09:37
|
||||
*/
|
||||
public class QRCodeUtil {
|
||||
|
||||
//编码格式,采用utf-8
|
||||
private static final String UNICODE = "utf-8";
|
||||
//图片格式
|
||||
private static final String FORMAT = "JPG";
|
||||
//二维码宽度,单位:像素pixels
|
||||
private static final int QRCODE_WIDTH = 300;
|
||||
//二维码高度,单位:像素pixels
|
||||
private static final int QRCODE_HEIGHT = 300;
|
||||
//LOGO宽度,单位:像素pixels
|
||||
private static final int LOGO_WIDTH = 100;
|
||||
//LOGO高度,单位:像素pixels
|
||||
private static final int LOGO_HEIGHT = 100;
|
||||
|
||||
/**
|
||||
* 生成二维码图片
|
||||
* @param content 二维码内容
|
||||
* @param logoPath 图片地址
|
||||
* @param needCompress 是否压缩
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
|
||||
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||
hints.put(EncodeHintType.CHARACTER_SET, UNICODE);
|
||||
hints.put(EncodeHintType.MARGIN, 1);
|
||||
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_WIDTH, QRCODE_HEIGHT,
|
||||
hints);
|
||||
int width = bitMatrix.getWidth();
|
||||
int height = bitMatrix.getHeight();
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
if (logoPath == null || "".equals(logoPath)) {
|
||||
return image;
|
||||
}
|
||||
// 插入图片
|
||||
QRCodeUtil.insertImage(image, logoPath, needCompress);
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入LOGO
|
||||
* @param source 二维码图片
|
||||
* @param logoPath LOGO图片地址
|
||||
* @param needCompress 是否压缩
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void insertImage(BufferedImage source, String logoPath, boolean needCompress) throws Exception {
|
||||
File file = new File(logoPath);
|
||||
if (!file.exists()) {
|
||||
throw new Exception("logo file not found.");
|
||||
}
|
||||
Image src = ImageIO.read(new File(logoPath));
|
||||
int width = src.getWidth(null);
|
||||
int height = src.getHeight(null);
|
||||
if (needCompress) { // 压缩LOGO
|
||||
if (width > LOGO_WIDTH) {
|
||||
width = LOGO_WIDTH;
|
||||
}
|
||||
if (height > LOGO_HEIGHT) {
|
||||
height = LOGO_HEIGHT;
|
||||
}
|
||||
Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
|
||||
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = tag.getGraphics();
|
||||
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
|
||||
g.dispose();
|
||||
src = image;
|
||||
}
|
||||
// 插入LOGO
|
||||
Graphics2D graph = source.createGraphics();
|
||||
int x = (QRCODE_WIDTH - width) / 2;
|
||||
int y = (QRCODE_HEIGHT - height) / 2;
|
||||
graph.drawImage(src, x, y, width, height, null);
|
||||
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
|
||||
graph.setStroke(new BasicStroke(3f));
|
||||
graph.draw(shape);
|
||||
graph.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码(内嵌LOGO)
|
||||
* 调用者指定二维码文件名
|
||||
* @param content 二维码的内容
|
||||
* @param logoPath 中间图片地址
|
||||
* @param destPath 存储路径
|
||||
* @param fileName 文件名称
|
||||
* @param needCompress 是否压缩
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encode(String content, String logoPath, String destPath, String fileName, boolean needCompress) throws Exception {
|
||||
BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
|
||||
mkdirs(destPath);
|
||||
//文件名称通过传递
|
||||
fileName = fileName.substring(0, fileName.indexOf(".")>0?fileName.indexOf("."):fileName.length())
|
||||
+ "." + FORMAT.toLowerCase();
|
||||
ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件夹, mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
|
||||
* @param destPath
|
||||
*/
|
||||
public static void mkdirs(String destPath) {
|
||||
File file = new File(destPath);
|
||||
if (!file.exists() && !file.isDirectory()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析二维码
|
||||
* @param path 二维码图片路径
|
||||
* @return String 二维码内容
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String decode(String path) throws Exception {
|
||||
File file = new File(path);
|
||||
BufferedImage image = ImageIO.read(file);
|
||||
if (image == null) {
|
||||
return null;
|
||||
}
|
||||
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
Result result;
|
||||
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
|
||||
hints.put(DecodeHintType.CHARACTER_SET, UNICODE);
|
||||
result = new MultiFormatReader().decode(bitmap, hints);
|
||||
return result.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
String text = "http://47.105.101.72:8088";
|
||||
//不含Logo
|
||||
// QRCodeUtil.encode(text, null, "/Users/kyson/Downloads", "qrcode", true);
|
||||
//含Logo,指定二维码图片名
|
||||
QRCodeUtil.encode(text, "/Users/kyson/Downloads/宋康.jpg", "/Users/kyson/Downloads", "qrcode1", true);
|
||||
// System.out.println(QRCodeUtil.decode("d:\\cc\\qrcode1.jpg"));
|
||||
// System.out.println(QRCodeUtil.encode(text, null, "/Users/kyson/Downloads", "qrcode", true));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.sqx.common.xss.SQLFilter;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 查询参数
|
||||
*
|
||||
*/
|
||||
public class Query<T> {
|
||||
|
||||
public IPage<T> getPage(Map<String, Object> params) {
|
||||
return this.getPage(params, null, false);
|
||||
}
|
||||
|
||||
public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
|
||||
//分页参数
|
||||
long curPage = 1;
|
||||
long limit = 10;
|
||||
|
||||
if(params.get(Constant.PAGE) != null){
|
||||
curPage = Long.parseLong(String.valueOf(params.get(Constant.PAGE)));
|
||||
}
|
||||
if(params.get(Constant.LIMIT) != null){
|
||||
limit = Long.parseLong(String.valueOf(params.get(Constant.LIMIT)));
|
||||
}
|
||||
|
||||
//分页对象
|
||||
Page<T> page = new Page<>(curPage, limit);
|
||||
|
||||
//分页参数
|
||||
params.put(Constant.PAGE, page);
|
||||
|
||||
//排序字段
|
||||
//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
|
||||
String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
|
||||
String order = (String)params.get(Constant.ORDER);
|
||||
|
||||
|
||||
//前端字段排序
|
||||
if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
|
||||
if(Constant.ASC.equalsIgnoreCase(order)) {
|
||||
return page.addOrder(OrderItem.asc(orderField));
|
||||
}else {
|
||||
return page.addOrder(OrderItem.desc(orderField));
|
||||
}
|
||||
}
|
||||
|
||||
//没有排序字段,则不排序
|
||||
if(StringUtils.isBlank(defaultOrderField)){
|
||||
return page;
|
||||
}
|
||||
|
||||
//默认排序
|
||||
if(isAsc) {
|
||||
page.addOrder(OrderItem.asc(defaultOrderField));
|
||||
}else {
|
||||
page.addOrder(OrderItem.desc(defaultOrderField));
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
/**
|
||||
* Redis所有Keys
|
||||
*
|
||||
*/
|
||||
public class RedisKeys {
|
||||
|
||||
public static String getSysConfigKey(String key){
|
||||
return "sys:config:" + key;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Redis工具类
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class RedisUtils {
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Autowired
|
||||
private ValueOperations<String, String> valueOperations;
|
||||
@Autowired
|
||||
private HashOperations<String, String, Object> hashOperations;
|
||||
@Autowired
|
||||
private ListOperations<String, Object> listOperations;
|
||||
@Autowired
|
||||
private SetOperations<String, Object> setOperations;
|
||||
@Autowired
|
||||
private ZSetOperations<String, Object> zSetOperations;
|
||||
/** 默认过期时长,单位:秒 */
|
||||
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
|
||||
/** 不设置过期时长 */
|
||||
public final static long NOT_EXPIRE = -1;
|
||||
private final static Gson Gson = new Gson();
|
||||
|
||||
public void set(String key, Object value, long expire){
|
||||
valueOperations.set(key, toJson(value));
|
||||
if(expire != NOT_EXPIRE){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String key, Object value){
|
||||
set(key, value, DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
public <T> T get(String key, Class<T> clazz, long expire) {
|
||||
String value = valueOperations.get(key);
|
||||
if(expire != NOT_EXPIRE){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
return value == null ? null : fromJson(value, clazz);
|
||||
}
|
||||
|
||||
public <T> T get(String key, Class<T> clazz) {
|
||||
return get(key, clazz, NOT_EXPIRE);
|
||||
}
|
||||
|
||||
public String get(String key, long expire) {
|
||||
String value = valueOperations.get(key);
|
||||
if(expire != NOT_EXPIRE){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
return get(key, NOT_EXPIRE);
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Object转成JSON数据
|
||||
*/
|
||||
private String toJson(Object object){
|
||||
if(object instanceof Integer || object instanceof Long || object instanceof Float ||
|
||||
object instanceof Double || object instanceof Boolean || object instanceof String){
|
||||
return String.valueOf(object);
|
||||
}
|
||||
return Gson.toJson(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON数据,转成Object
|
||||
*/
|
||||
private <T> T fromJson(String json, Class<T> clazz){
|
||||
return Gson.fromJson(json, clazz);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 返回数据
|
||||
*
|
||||
*/
|
||||
public class Result extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Result () {
|
||||
put("code", 0);
|
||||
put("msg", "success");
|
||||
}
|
||||
|
||||
public static Result error() {
|
||||
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
|
||||
}
|
||||
|
||||
public static Result error(String msg) {
|
||||
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
|
||||
}
|
||||
|
||||
public static Result error(int code, String msg) {
|
||||
Result r = new Result();
|
||||
r.put("code", code);
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result success(String msg) {
|
||||
Result r = new Result();
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result success(Map<String, Object> map) {
|
||||
Result r = new Result();
|
||||
r.putAll(map);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result success() {
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import com.sqx.common.exception.SqxException;
|
||||
import com.sqx.modules.sys.entity.SysUserEntity;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
/**
|
||||
* Shiro工具类
|
||||
*
|
||||
*/
|
||||
public class ShiroUtils {
|
||||
|
||||
public static Session getSession() {
|
||||
return SecurityUtils.getSubject().getSession();
|
||||
}
|
||||
|
||||
public static Subject getSubject() {
|
||||
return SecurityUtils.getSubject();
|
||||
}
|
||||
|
||||
public static SysUserEntity getUserEntity() {
|
||||
return (SysUserEntity)SecurityUtils.getSubject().getPrincipal();
|
||||
}
|
||||
|
||||
public static Long getUserId() {
|
||||
return getUserEntity().getUserId();
|
||||
}
|
||||
|
||||
public static void setSessionAttribute(Object key, Object value) {
|
||||
getSession().setAttribute(key, value);
|
||||
}
|
||||
|
||||
public static Object getSessionAttribute(Object key) {
|
||||
return getSession().getAttribute(key);
|
||||
}
|
||||
|
||||
public static boolean isLogin() {
|
||||
return SecurityUtils.getSubject().getPrincipal() != null;
|
||||
}
|
||||
|
||||
public static String getKaptcha(String key) {
|
||||
Object kaptcha = getSessionAttribute(key);
|
||||
if(kaptcha == null){
|
||||
throw new SqxException("验证码已失效");
|
||||
}
|
||||
getSession().removeAttribute(key);
|
||||
return kaptcha.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.sqx.common.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Spring Context 工具类
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class SpringContextUtils implements ApplicationContextAware {
|
||||
public static ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
SpringContextUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public static Object getBean(String name) {
|
||||
return applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> requiredType) {
|
||||
return applicationContext.getBean(name, requiredType);
|
||||
}
|
||||
|
||||
public static boolean containsBean(String name) {
|
||||
return applicationContext.containsBean(name);
|
||||
}
|
||||
|
||||
public static boolean isSingleton(String name) {
|
||||
return applicationContext.isSingleton(name);
|
||||
}
|
||||
|
||||
public static Class<? extends Object> getType(String name) {
|
||||
return applicationContext.getType(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sqx.common.validator;
|
||||
|
||||
import com.sqx.common.exception.SqxException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* 数据校验
|
||||
*
|
||||
*/
|
||||
public class Assert {
|
||||
|
||||
public static void isBlank(String str, String message) {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
throw new SqxException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void isNull(Object object, String message) {
|
||||
if (object == null) {
|
||||
throw new SqxException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.sqx.common.validator;
|
||||
|
||||
import com.sqx.common.exception.SqxException;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* hibernate-validator校验工具类
|
||||
*
|
||||
* 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
|
||||
*
|
||||
*/
|
||||
public class ValidatorUtils {
|
||||
private static Validator validator;
|
||||
|
||||
static {
|
||||
validator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验对象
|
||||
* @param object 待校验对象
|
||||
* @param groups 待校验的组
|
||||
* @throws SqxException 校验不通过,则报SqxException异常
|
||||
*/
|
||||
public static void validateEntity(Object object, Class<?>... groups)
|
||||
throws SqxException {
|
||||
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
|
||||
if (!constraintViolations.isEmpty()) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
for(ConstraintViolation<Object> constraint: constraintViolations){
|
||||
msg.append(constraint.getMessage()).append("<br>");
|
||||
}
|
||||
throw new SqxException(msg.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.sqx.common.validator.group;
|
||||
|
||||
/**
|
||||
* 新增数据 Group
|
||||
*
|
||||
*/
|
||||
public interface AddGroup {
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.sqx.common.validator.group;
|
||||
|
||||
/**
|
||||
* 阿里云
|
||||
*
|
||||
*/
|
||||
public interface AliyunGroup {
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.sqx.common.validator.group;
|
||||
|
||||
import javax.validation.GroupSequence;
|
||||
|
||||
/**
|
||||
* 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验
|
||||
*
|
||||
*/
|
||||
@GroupSequence({AddGroup.class, UpdateGroup.class})
|
||||
public interface Group {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.sqx.common.validator.group;
|
||||
|
||||
/**
|
||||
* 腾讯云
|
||||
*
|
||||
*/
|
||||
public interface QcloudGroup {
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.sqx.common.validator.group;
|
||||
|
||||
/**
|
||||
* 七牛
|
||||
*
|
||||
*/
|
||||
public interface QiniuGroup {
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.sqx.common.validator.group;
|
||||
|
||||
/**
|
||||
* 更新数据 Group
|
||||
*
|
||||
*/
|
||||
|
||||
public interface UpdateGroup {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,526 @@
|
|||
package com.sqx.common.xss;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* HTML filtering utility for protecting against XSS (Cross Site Scripting).
|
||||
*
|
||||
* This code is licensed LGPLv3
|
||||
*
|
||||
* This code is a Java port of the original work in PHP by Cal Hendersen.
|
||||
* http://code.iamcal.com/php/lib_filter/
|
||||
*
|
||||
* The trickiest part of the translation was handling the differences in regex handling
|
||||
* between PHP and Java. These resources were helpful in the process:
|
||||
*
|
||||
* http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html
|
||||
* http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php
|
||||
* http://www.regular-expressions.info/modifiers.html
|
||||
*
|
||||
* A note on naming conventions: instance variables are prefixed with a "v"; global
|
||||
* constants are in all caps.
|
||||
*
|
||||
* Sample use:
|
||||
* String input = ...
|
||||
* String clean = new HTMLFilter().filter( input );
|
||||
*
|
||||
* The class is not thread safe. Create a new instance if in doubt.
|
||||
*
|
||||
* If you find bugs or have suggestions on improvement (especially regarding
|
||||
* performance), please contact us. The latest version of this
|
||||
* source, and our contact details, can be found at http://xss-html-filter.sf.net
|
||||
*
|
||||
* @author Joseph O'Connell
|
||||
* @author Cal Hendersen
|
||||
* @author Michael Semb Wever
|
||||
*/
|
||||
public final class HTMLFilter {
|
||||
|
||||
/** regex flag union representing /si modifiers in php **/
|
||||
private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
|
||||
private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);
|
||||
private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);
|
||||
private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");
|
||||
private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");
|
||||
private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");
|
||||
private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");
|
||||
private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);
|
||||
private static final Pattern P_END_ARROW = Pattern.compile("^>");
|
||||
private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");
|
||||
private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");
|
||||
private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");
|
||||
private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");
|
||||
private static final Pattern P_AMP = Pattern.compile("&");
|
||||
private static final Pattern P_QUOTE = Pattern.compile("<");
|
||||
private static final Pattern P_LEFT_ARROW = Pattern.compile("<");
|
||||
private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");
|
||||
private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
|
||||
|
||||
// @xxx could grow large... maybe use sesat's ReferenceMap
|
||||
private static final ConcurrentMap<String,Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<String, Pattern>();
|
||||
private static final ConcurrentMap<String,Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<String, Pattern>();
|
||||
|
||||
/** set of allowed html elements, along with allowed attributes for each element **/
|
||||
private final Map<String, List<String>> vAllowed;
|
||||
/** counts of open tags for each (allowable) html element **/
|
||||
private final Map<String, Integer> vTagCounts = new HashMap<String, Integer>();
|
||||
|
||||
/** html elements which must always be self-closing (e.g. "<img />") **/
|
||||
private final String[] vSelfClosingTags;
|
||||
/** html elements which must always have separate opening and closing tags (e.g. "<b></b>") **/
|
||||
private final String[] vNeedClosingTags;
|
||||
/** set of disallowed html elements **/
|
||||
private final String[] vDisallowed;
|
||||
/** attributes which should be checked for valid protocols **/
|
||||
private final String[] vProtocolAtts;
|
||||
/** allowed protocols **/
|
||||
private final String[] vAllowedProtocols;
|
||||
/** tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") **/
|
||||
private final String[] vRemoveBlanks;
|
||||
/** entities allowed within html markup **/
|
||||
private final String[] vAllowedEntities;
|
||||
/** flag determining whether comments are allowed in input String. */
|
||||
private final boolean stripComment;
|
||||
private final boolean encodeQuotes;
|
||||
private boolean vDebug = false;
|
||||
/**
|
||||
* flag determining whether to try to make tags when presented with "unbalanced"
|
||||
* angle brackets (e.g. "<b text </b>" becomes "<b> text </b>"). If set to false,
|
||||
* unbalanced angle brackets will be html escaped.
|
||||
*/
|
||||
private final boolean alwaysMakeTags;
|
||||
|
||||
/** Default constructor.
|
||||
*
|
||||
*/
|
||||
public HTMLFilter() {
|
||||
vAllowed = new HashMap<>();
|
||||
|
||||
final ArrayList<String> a_atts = new ArrayList<String>();
|
||||
a_atts.add("href");
|
||||
a_atts.add("target");
|
||||
vAllowed.put("a", a_atts);
|
||||
|
||||
final ArrayList<String> img_atts = new ArrayList<String>();
|
||||
img_atts.add("src");
|
||||
img_atts.add("width");
|
||||
img_atts.add("height");
|
||||
img_atts.add("alt");
|
||||
vAllowed.put("img", img_atts);
|
||||
|
||||
final ArrayList<String> no_atts = new ArrayList<String>();
|
||||
vAllowed.put("b", no_atts);
|
||||
vAllowed.put("strong", no_atts);
|
||||
vAllowed.put("i", no_atts);
|
||||
vAllowed.put("em", no_atts);
|
||||
|
||||
vSelfClosingTags = new String[]{"img"};
|
||||
vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};
|
||||
vDisallowed = new String[]{};
|
||||
vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.
|
||||
vProtocolAtts = new String[]{"src", "href"};
|
||||
vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};
|
||||
vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};
|
||||
stripComment = true;
|
||||
encodeQuotes = true;
|
||||
alwaysMakeTags = true;
|
||||
}
|
||||
|
||||
/** Set debug flag to true. Otherwise use default settings. See the default constructor.
|
||||
*
|
||||
* @param debug turn debug on with a true argument
|
||||
*/
|
||||
public HTMLFilter(final boolean debug) {
|
||||
this();
|
||||
vDebug = debug;
|
||||
|
||||
}
|
||||
|
||||
/** Map-parameter configurable constructor.
|
||||
*
|
||||
* @param conf map containing configuration. keys match field names.
|
||||
*/
|
||||
public HTMLFilter(final Map<String,Object> conf) {
|
||||
|
||||
assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
|
||||
assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
|
||||
assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";
|
||||
assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";
|
||||
assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";
|
||||
assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";
|
||||
assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";
|
||||
assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";
|
||||
|
||||
vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));
|
||||
vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");
|
||||
vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");
|
||||
vDisallowed = (String[]) conf.get("vDisallowed");
|
||||
vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");
|
||||
vProtocolAtts = (String[]) conf.get("vProtocolAtts");
|
||||
vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");
|
||||
vAllowedEntities = (String[]) conf.get("vAllowedEntities");
|
||||
stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;
|
||||
encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;
|
||||
alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
vTagCounts.clear();
|
||||
}
|
||||
|
||||
private void debug(final String msg) {
|
||||
if (vDebug) {
|
||||
Logger.getAnonymousLogger().info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// my versions of some PHP library functions
|
||||
public static String chr(final int decimal) {
|
||||
return String.valueOf((char) decimal);
|
||||
}
|
||||
|
||||
public static String htmlSpecialChars(final String s) {
|
||||
String result = s;
|
||||
result = regexReplace(P_AMP, "&", result);
|
||||
result = regexReplace(P_QUOTE, """, result);
|
||||
result = regexReplace(P_LEFT_ARROW, "<", result);
|
||||
result = regexReplace(P_RIGHT_ARROW, ">", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/**
|
||||
* given a user submitted input String, filter out any invalid or restricted
|
||||
* html.
|
||||
*
|
||||
* @param input text (i.e. submitted by a user) than may contain html
|
||||
* @return "clean" version of input, with only valid, whitelisted html elements allowed
|
||||
*/
|
||||
public String filter(final String input) {
|
||||
reset();
|
||||
String s = input;
|
||||
|
||||
debug("************************************************");
|
||||
debug(" INPUT: " + input);
|
||||
|
||||
s = escapeComments(s);
|
||||
debug(" escapeComments: " + s);
|
||||
|
||||
s = balanceHTML(s);
|
||||
debug(" balanceHTML: " + s);
|
||||
|
||||
s = checkTags(s);
|
||||
debug(" checkTags: " + s);
|
||||
|
||||
s = processRemoveBlanks(s);
|
||||
debug("processRemoveBlanks: " + s);
|
||||
|
||||
s = validateEntities(s);
|
||||
debug(" validateEntites: " + s);
|
||||
|
||||
debug("************************************************\n\n");
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean isAlwaysMakeTags(){
|
||||
return alwaysMakeTags;
|
||||
}
|
||||
|
||||
public boolean isStripComments(){
|
||||
return stripComment;
|
||||
}
|
||||
|
||||
private String escapeComments(final String s) {
|
||||
final Matcher m = P_COMMENTS.matcher(s);
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
if (m.find()) {
|
||||
final String match = m.group(1); //(.*?)
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String balanceHTML(String s) {
|
||||
if (alwaysMakeTags) {
|
||||
//
|
||||
// try and form html
|
||||
//
|
||||
s = regexReplace(P_END_ARROW, "", s);
|
||||
s = regexReplace(P_BODY_TO_END, "<$1>", s);
|
||||
s = regexReplace(P_XML_CONTENT, "$1<$2", s);
|
||||
|
||||
} else {
|
||||
//
|
||||
// escape stray brackets
|
||||
//
|
||||
s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s);
|
||||
s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s);
|
||||
|
||||
//
|
||||
// the last regexp causes '<>' entities to appear
|
||||
// (we need to do a lookahead assertion so that the last bracket can
|
||||
// be used in the next pass of the regexp)
|
||||
//
|
||||
s = regexReplace(P_BOTH_ARROWS, "", s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String checkTags(String s) {
|
||||
Matcher m = P_TAGS.matcher(s);
|
||||
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
while (m.find()) {
|
||||
String replaceStr = m.group(1);
|
||||
replaceStr = processTag(replaceStr);
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
s = buf.toString();
|
||||
|
||||
// these get tallied in processTag
|
||||
// (remember to reset before subsequent calls to filter method)
|
||||
for (String key : vTagCounts.keySet()) {
|
||||
for (int ii = 0; ii < vTagCounts.get(key); ii++) {
|
||||
s += "</" + key + ">";
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String processRemoveBlanks(final String s) {
|
||||
String result = s;
|
||||
for (String tag : vRemoveBlanks) {
|
||||
if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){
|
||||
P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));
|
||||
}
|
||||
result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
|
||||
if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){
|
||||
P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
|
||||
}
|
||||
result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) {
|
||||
Matcher m = regex_pattern.matcher(s);
|
||||
return m.replaceAll(replacement);
|
||||
}
|
||||
|
||||
private String processTag(final String s) {
|
||||
// ending tags
|
||||
Matcher m = P_END_TAG.matcher(s);
|
||||
if (m.find()) {
|
||||
final String name = m.group(1).toLowerCase();
|
||||
if (allowed(name)) {
|
||||
if (!inArray(name, vSelfClosingTags)) {
|
||||
if (vTagCounts.containsKey(name)) {
|
||||
vTagCounts.put(name, vTagCounts.get(name) - 1);
|
||||
return "</" + name + ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// starting tags
|
||||
m = P_START_TAG.matcher(s);
|
||||
if (m.find()) {
|
||||
final String name = m.group(1).toLowerCase();
|
||||
final String body = m.group(2);
|
||||
String ending = m.group(3);
|
||||
|
||||
//debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
|
||||
if (allowed(name)) {
|
||||
String params = "";
|
||||
|
||||
final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
|
||||
final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
|
||||
final List<String> paramNames = new ArrayList<String>();
|
||||
final List<String> paramValues = new ArrayList<String>();
|
||||
while (m2.find()) {
|
||||
paramNames.add(m2.group(1)); //([a-z0-9]+)
|
||||
paramValues.add(m2.group(3)); //(.*?)
|
||||
}
|
||||
while (m3.find()) {
|
||||
paramNames.add(m3.group(1)); //([a-z0-9]+)
|
||||
paramValues.add(m3.group(3)); //([^\"\\s']+)
|
||||
}
|
||||
|
||||
String paramName, paramValue;
|
||||
for (int ii = 0; ii < paramNames.size(); ii++) {
|
||||
paramName = paramNames.get(ii).toLowerCase();
|
||||
paramValue = paramValues.get(ii);
|
||||
|
||||
if (allowedAttribute(name, paramName)) {
|
||||
if (inArray(paramName, vProtocolAtts)) {
|
||||
paramValue = processParamProtocol(paramValue);
|
||||
}
|
||||
params += " " + paramName + "=\"" + paramValue + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
if (inArray(name, vSelfClosingTags)) {
|
||||
ending = " /";
|
||||
}
|
||||
|
||||
if (inArray(name, vNeedClosingTags)) {
|
||||
ending = "";
|
||||
}
|
||||
|
||||
if (ending == null || ending.length() < 1) {
|
||||
if (vTagCounts.containsKey(name)) {
|
||||
vTagCounts.put(name, vTagCounts.get(name) + 1);
|
||||
} else {
|
||||
vTagCounts.put(name, 1);
|
||||
}
|
||||
} else {
|
||||
ending = " /";
|
||||
}
|
||||
return "<" + name + params + ending + ">";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// comments
|
||||
m = P_COMMENT.matcher(s);
|
||||
if (!stripComment && m.find()) {
|
||||
return "<" + m.group() + ">";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private String processParamProtocol(String s) {
|
||||
s = decodeEntities(s);
|
||||
final Matcher m = P_PROTOCOL.matcher(s);
|
||||
if (m.find()) {
|
||||
final String protocol = m.group(1);
|
||||
if (!inArray(protocol, vAllowedProtocols)) {
|
||||
// bad protocol, turn into local anchor link instead
|
||||
s = "#" + s.substring(protocol.length() + 1, s.length());
|
||||
if (s.startsWith("#//")) {
|
||||
s = "#" + s.substring(3, s.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String decodeEntities(String s) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
Matcher m = P_ENTITY.matcher(s);
|
||||
while (m.find()) {
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.decode(match).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
buf = new StringBuffer();
|
||||
m = P_ENTITY_UNICODE.matcher(s);
|
||||
while (m.find()) {
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.valueOf(match, 16).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
buf = new StringBuffer();
|
||||
m = P_ENCODE.matcher(s);
|
||||
while (m.find()) {
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.valueOf(match, 16).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
s = validateEntities(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private String validateEntities(final String s) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
// validate entities throughout the string
|
||||
Matcher m = P_VALID_ENTITIES.matcher(s);
|
||||
while (m.find()) {
|
||||
final String one = m.group(1); //([^&;]*)
|
||||
final String two = m.group(2); //(?=(;|&|$))
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
return encodeQuotes(buf.toString());
|
||||
}
|
||||
|
||||
private String encodeQuotes(final String s){
|
||||
if(encodeQuotes){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Matcher m = P_VALID_QUOTES.matcher(s);
|
||||
while (m.find()) {
|
||||
final String one = m.group(1); //(>|^)
|
||||
final String two = m.group(2); //([^<]+?)
|
||||
final String three = m.group(3); //(<|$)
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
return buf.toString();
|
||||
}else{
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private String checkEntity(final String preamble, final String term) {
|
||||
|
||||
return ";".equals(term) && isValidEntity(preamble)
|
||||
? '&' + preamble
|
||||
: "&" + preamble;
|
||||
}
|
||||
|
||||
private boolean isValidEntity(final String entity) {
|
||||
return inArray(entity, vAllowedEntities);
|
||||
}
|
||||
|
||||
private static boolean inArray(final String s, final String[] array) {
|
||||
for (String item : array) {
|
||||
if (item != null && item.equals(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allowed(final String name) {
|
||||
return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
|
||||
}
|
||||
|
||||
private boolean allowedAttribute(final String name, final String paramName) {
|
||||
return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.sqx.common.xss;
|
||||
|
||||
import com.sqx.common.exception.SqxException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* SQL过滤
|
||||
*
|
||||
*/
|
||||
public class SQLFilter {
|
||||
|
||||
/**
|
||||
* SQL注入过滤
|
||||
* @param str 待验证的字符串
|
||||
*/
|
||||
public static String sqlInject(String str){
|
||||
if(StringUtils.isBlank(str)){
|
||||
return null;
|
||||
}
|
||||
//去掉'|"|;|\字符
|
||||
str = StringUtils.replace(str, "'", "");
|
||||
str = StringUtils.replace(str, "\"", "");
|
||||
str = StringUtils.replace(str, ";", "");
|
||||
str = StringUtils.replace(str, "\\", "");
|
||||
|
||||
//转换成小写
|
||||
str = str.toLowerCase();
|
||||
|
||||
//非法字符
|
||||
String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"};
|
||||
|
||||
//判断是否包含非法字符
|
||||
for(String keyword : keywords){
|
||||
if(str.indexOf(keyword) != -1){
|
||||
throw new SqxException("包含非法字符");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.sqx.common.xss;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* XSS过滤
|
||||
*
|
||||
*/
|
||||
public class XssFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest hreq = (HttpServletRequest) request;
|
||||
HttpServletResponse hresp = (HttpServletResponse) response;
|
||||
|
||||
//跨域
|
||||
hresp.setHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
|
||||
//跨域 Header
|
||||
|
||||
hresp.setHeader("Access-Control-Allow-Methods", "*");
|
||||
|
||||
hresp.setHeader("Access-Control-Allow-Headers", "*");
|
||||
|
||||
// Filter 只是链式处理,请求依然转发到目的地址。
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.sqx.common.xss;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* XSS过滤处理
|
||||
*
|
||||
*/
|
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
//没被包装过的HttpServletRequest(特殊场景,需要自己过滤)
|
||||
HttpServletRequest orgRequest;
|
||||
//html过滤
|
||||
private final static HTMLFilter HtmlFilter = new HTMLFilter();
|
||||
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
orgRequest = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
//非json类型,直接返回
|
||||
if(!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
//为空,直接返回
|
||||
String json = IOUtils.toString(super.getInputStream(), "utf-8");
|
||||
if (StringUtils.isBlank(json)) {
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
//xss过滤
|
||||
json = xssEncode(json);
|
||||
final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));
|
||||
return new ServletInputStream() {
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return bis.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String value = super.getParameter(xssEncode(name));
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
value = xssEncode(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] parameters = super.getParameterValues(name);
|
||||
if (parameters == null || parameters.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parameters[i] = xssEncode(parameters[i]);
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String,String[]> getParameterMap() {
|
||||
Map<String,String[]> map = new LinkedHashMap<>();
|
||||
Map<String,String[]> parameters = super.getParameterMap();
|
||||
for (String key : parameters.keySet()) {
|
||||
String[] values = parameters.get(key);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = xssEncode(values[i]);
|
||||
}
|
||||
map.put(key, values);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
String value = super.getHeader(xssEncode(name));
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
value = xssEncode(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String xssEncode(String input) {
|
||||
return HtmlFilter.filter(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*/
|
||||
public HttpServletRequest getOrgRequest() {
|
||||
return orgRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*/
|
||||
public static HttpServletRequest getOrgRequest(HttpServletRequest request) {
|
||||
if (request instanceof XssHttpServletRequestWrapper) {
|
||||
return ((XssHttpServletRequestWrapper) request).getOrgRequest();
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
|
||||
/**
|
||||
* 跨域设置
|
||||
*/
|
||||
@Configuration
|
||||
public class CorsConfig implements WebMvcConfigurer {
|
||||
|
||||
/*private CorsConfiguration buildConfig() {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
// 1允许任何域名使用
|
||||
corsConfiguration.addAllowedOrigin("*");
|
||||
// 2允许任何头
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
// 3允许任何方法(post、get等)
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
return corsConfiguration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsFilter corsFilter() {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", buildConfig());
|
||||
return new CorsFilter(source);
|
||||
}*/
|
||||
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("*")
|
||||
.allowCredentials(true)
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.maxAge(3600);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import com.sqx.common.xss.XssFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
/**
|
||||
* Filter配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean shiroFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
|
||||
//该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
|
||||
registration.addInitParameter("targetFilterLifecycle", "true");
|
||||
registration.setEnabled(true);
|
||||
registration.setOrder(Integer.MAX_VALUE - 1);
|
||||
registration.addUrlPatterns("/*");
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean xssFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
registration.setFilter(new XssFilter());
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("xssFilter");
|
||||
registration.setOrder(Integer.MAX_VALUE);
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
/**
|
||||
* 生成验证码配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class KaptchaConfig {
|
||||
|
||||
@Bean
|
||||
public DefaultKaptcha producer() {
|
||||
Properties properties = new Properties();
|
||||
properties.put("kaptcha.border", "no");
|
||||
properties.put("kaptcha.textproducer.font.color", "black");
|
||||
properties.put("kaptcha.textproducer.char.space", "5");
|
||||
properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
|
||||
Config config = new Config(properties);
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* mybatis-plus配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
/**
|
||||
* 分页插件
|
||||
*/
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor() {
|
||||
return new PaginationInterceptor();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Redis配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
@Autowired
|
||||
private RedisConnectionFactory factory;
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate() {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(new StringRedisSerializer());
|
||||
redisTemplate.setConnectionFactory(factory);
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForHash();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
|
||||
return redisTemplate.opsForValue();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForList();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForSet();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForZSet();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import com.sqx.modules.sys.oauth2.OAuth2Filter;
|
||||
import com.sqx.modules.sys.oauth2.OAuth2Realm;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Shiro配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class ShiroConfig {
|
||||
|
||||
@Bean("securityManager")
|
||||
public SecurityManager securityManager(OAuth2Realm oAuth2Realm) {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
securityManager.setRealm(oAuth2Realm);
|
||||
securityManager.setRememberMeManager(null);
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
@Bean("shiroFilter")
|
||||
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
|
||||
shiroFilter.setSecurityManager(securityManager);
|
||||
|
||||
//oauth过滤
|
||||
Map<String, Filter> filters = new HashMap<>();
|
||||
filters.put("oauth2", new OAuth2Filter());
|
||||
shiroFilter.setFilters(filters);
|
||||
|
||||
Map<String, String> filterMap = new LinkedHashMap<>();
|
||||
filterMap.put("/course/synCourse", "anon");
|
||||
filterMap.put("/webjars/**", "anon");
|
||||
filterMap.put("/druid/**", "anon");
|
||||
filterMap.put("/app/**", "anon");
|
||||
filterMap.put("/activity/**", "anon");
|
||||
filterMap.put("/banner/**", "anon");
|
||||
filterMap.put("/courseClassification/selectCourseClassification", "anon");
|
||||
filterMap.put("/sys/login", "anon");
|
||||
filterMap.put("/swagger/**", "anon");
|
||||
filterMap.put("/alioss/**", "anon");
|
||||
filterMap.put("/v2/api-docs", "anon");
|
||||
filterMap.put("/swagger-ui.html", "anon");
|
||||
filterMap.put("/swagger-resources/**", "anon");
|
||||
filterMap.put("/captcha.jpg", "anon");
|
||||
filterMap.put("/aaa.txt", "anon");
|
||||
filterMap.put("/search/**", "anon");
|
||||
filterMap.put("/**", "oauth2");
|
||||
|
||||
shiroFilter.setFilterChainDefinitionMap(filterMap);
|
||||
|
||||
return shiroFilter;
|
||||
}
|
||||
|
||||
@Bean("lifecycleBeanPostProcessor")
|
||||
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||
advisor.setSecurityManager(securityManager);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.sqx.config;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.ApiKey;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
//加了ApiOperation注解的类,才生成接口文档
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
//包下的类,才生成接口文档
|
||||
//.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.securitySchemes(security());
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("")
|
||||
.description("sqx-fast文档")
|
||||
.termsOfServiceUrl("")
|
||||
.version("3.0.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<ApiKey> security() {
|
||||
return newArrayList(
|
||||
new ApiKey("token", "token", "header")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.sqx.datasource.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 多数据源注解
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface DataSource {
|
||||
String value() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.sqx.datasource.aspect;
|
||||
|
||||
|
||||
import com.sqx.datasource.annotation.DataSource;
|
||||
import com.sqx.datasource.config.DynamicContextHolder;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 多数据源,切面处理类
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class DataSourceAspect {
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Pointcut("@annotation(com.sqx.datasource.annotation.DataSource) " +
|
||||
"|| @within(com.sqx.datasource.annotation.DataSource)")
|
||||
public void dataSourcePointCut() {
|
||||
|
||||
}
|
||||
|
||||
@Around("dataSourcePointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
Class targetClass = point.getTarget().getClass();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
|
||||
DataSource methodDataSource = method.getAnnotation(DataSource.class);
|
||||
if(targetDataSource != null || methodDataSource != null){
|
||||
String value;
|
||||
if(methodDataSource != null){
|
||||
value = methodDataSource.value();
|
||||
}else {
|
||||
value = targetDataSource.value();
|
||||
}
|
||||
|
||||
DynamicContextHolder.push(value);
|
||||
logger.debug("set datasource is {}", value);
|
||||
}
|
||||
|
||||
try {
|
||||
return point.proceed();
|
||||
} finally {
|
||||
DynamicContextHolder.poll();
|
||||
logger.debug("clean datasource");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.sqx.datasource.config;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* 多数据源上下文
|
||||
*/
|
||||
public class DynamicContextHolder {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final ThreadLocal<Deque<String>> CONTEXT_HOLDER = new ThreadLocal() {
|
||||
@Override
|
||||
protected Object initialValue() {
|
||||
return new ArrayDeque();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获得当前线程数据源
|
||||
*
|
||||
* @return 数据源名称
|
||||
*/
|
||||
public static String peek() {
|
||||
return CONTEXT_HOLDER.get().peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前线程数据源
|
||||
*
|
||||
* @param dataSource 数据源名称
|
||||
*/
|
||||
public static void push(String dataSource) {
|
||||
CONTEXT_HOLDER.get().push(dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空当前线程数据源
|
||||
*/
|
||||
public static void poll() {
|
||||
Deque<String> deque = CONTEXT_HOLDER.get();
|
||||
deque.poll();
|
||||
if (deque.isEmpty()) {
|
||||
CONTEXT_HOLDER.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.sqx.datasource.config;
|
||||
|
||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||
|
||||
/**
|
||||
* 多数据源
|
||||
*/
|
||||
public class DynamicDataSource extends AbstractRoutingDataSource {
|
||||
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey() {
|
||||
return DynamicContextHolder.peek();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.sqx.datasource.config;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.sqx.datasource.properties.DataSourceProperties;
|
||||
import com.sqx.datasource.properties.DynamicDataSourceProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 配置多数据源
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
|
||||
public class DynamicDataSourceConfig {
|
||||
@Autowired
|
||||
private DynamicDataSourceProperties properties;
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid")
|
||||
public DataSourceProperties dataSourceProperties() {
|
||||
return new DataSourceProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
dynamicDataSource.setTargetDataSources(getDynamicDataSource());
|
||||
|
||||
//默认数据源
|
||||
DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
|
||||
dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
|
||||
|
||||
return dynamicDataSource;
|
||||
}
|
||||
|
||||
private Map<Object, Object> getDynamicDataSource(){
|
||||
Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
|
||||
Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
|
||||
dataSourcePropertiesMap.forEach((k, v) -> {
|
||||
DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
|
||||
targetDataSources.put(k, druidDataSource);
|
||||
});
|
||||
|
||||
return targetDataSources;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.sqx.datasource.config;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.sqx.datasource.properties.DataSourceProperties;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* DruidDataSource
|
||||
*
|
||||
*/
|
||||
public class DynamicDataSourceFactory {
|
||||
|
||||
public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) {
|
||||
DruidDataSource druidDataSource = new DruidDataSource();
|
||||
druidDataSource.setDriverClassName(properties.getDriverClassName());
|
||||
druidDataSource.setUrl(properties.getUrl());
|
||||
druidDataSource.setUsername(properties.getUsername());
|
||||
druidDataSource.setPassword(properties.getPassword());
|
||||
|
||||
druidDataSource.setInitialSize(properties.getInitialSize());
|
||||
druidDataSource.setMaxActive(properties.getMaxActive());
|
||||
druidDataSource.setMinIdle(properties.getMinIdle());
|
||||
druidDataSource.setMaxWait(properties.getMaxWait());
|
||||
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
|
||||
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
|
||||
druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
|
||||
druidDataSource.setValidationQuery(properties.getValidationQuery());
|
||||
druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());
|
||||
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
|
||||
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
|
||||
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
|
||||
druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
|
||||
druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements());
|
||||
|
||||
try {
|
||||
druidDataSource.setFilters(properties.getFilters());
|
||||
druidDataSource.init();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return druidDataSource;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package com.sqx.datasource.properties;
|
||||
|
||||
/**
|
||||
* 多数据源属性
|
||||
*
|
||||
*/
|
||||
public class DataSourceProperties {
|
||||
private String driverClassName;
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Druid默认参数
|
||||
*/
|
||||
private int initialSize = 2;
|
||||
private int maxActive = 10;
|
||||
private int minIdle = -1;
|
||||
private long maxWait = 60 * 1000L;
|
||||
private long timeBetweenEvictionRunsMillis = 60 * 1000L;
|
||||
private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
|
||||
private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
|
||||
private String validationQuery = "select 1";
|
||||
private int validationQueryTimeout = -1;
|
||||
private boolean testOnBorrow = false;
|
||||
private boolean testOnReturn = false;
|
||||
private boolean testWhileIdle = true;
|
||||
private boolean poolPreparedStatements = false;
|
||||
private int maxOpenPreparedStatements = -1;
|
||||
private boolean sharePreparedStatements = false;
|
||||
private String filters = "stat,wall";
|
||||
|
||||
public String getDriverClassName() {
|
||||
return driverClassName;
|
||||
}
|
||||
|
||||
public void setDriverClassName(String driverClassName) {
|
||||
this.driverClassName = driverClassName;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public int getInitialSize() {
|
||||
return initialSize;
|
||||
}
|
||||
|
||||
public void setInitialSize(int initialSize) {
|
||||
this.initialSize = initialSize;
|
||||
}
|
||||
|
||||
public int getMaxActive() {
|
||||
return maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.maxActive = maxActive;
|
||||
}
|
||||
|
||||
public int getMinIdle() {
|
||||
return minIdle;
|
||||
}
|
||||
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
public long getMaxWait() {
|
||||
return maxWait;
|
||||
}
|
||||
|
||||
public void setMaxWait(long maxWait) {
|
||||
this.maxWait = maxWait;
|
||||
}
|
||||
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
|
||||
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
|
||||
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public long getMaxEvictableIdleTimeMillis() {
|
||||
return maxEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
|
||||
this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public String getValidationQuery() {
|
||||
return validationQuery;
|
||||
}
|
||||
|
||||
public void setValidationQuery(String validationQuery) {
|
||||
this.validationQuery = validationQuery;
|
||||
}
|
||||
|
||||
public int getValidationQueryTimeout() {
|
||||
return validationQueryTimeout;
|
||||
}
|
||||
|
||||
public void setValidationQueryTimeout(int validationQueryTimeout) {
|
||||
this.validationQueryTimeout = validationQueryTimeout;
|
||||
}
|
||||
|
||||
public boolean isTestOnBorrow() {
|
||||
return testOnBorrow;
|
||||
}
|
||||
|
||||
public void setTestOnBorrow(boolean testOnBorrow) {
|
||||
this.testOnBorrow = testOnBorrow;
|
||||
}
|
||||
|
||||
public boolean isTestOnReturn() {
|
||||
return testOnReturn;
|
||||
}
|
||||
|
||||
public void setTestOnReturn(boolean testOnReturn) {
|
||||
this.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
public boolean isTestWhileIdle() {
|
||||
return testWhileIdle;
|
||||
}
|
||||
|
||||
public void setTestWhileIdle(boolean testWhileIdle) {
|
||||
this.testWhileIdle = testWhileIdle;
|
||||
}
|
||||
|
||||
public boolean isPoolPreparedStatements() {
|
||||
return poolPreparedStatements;
|
||||
}
|
||||
|
||||
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
|
||||
this.poolPreparedStatements = poolPreparedStatements;
|
||||
}
|
||||
|
||||
public int getMaxOpenPreparedStatements() {
|
||||
return maxOpenPreparedStatements;
|
||||
}
|
||||
|
||||
public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
|
||||
this.maxOpenPreparedStatements = maxOpenPreparedStatements;
|
||||
}
|
||||
|
||||
public boolean isSharePreparedStatements() {
|
||||
return sharePreparedStatements;
|
||||
}
|
||||
|
||||
public void setSharePreparedStatements(boolean sharePreparedStatements) {
|
||||
this.sharePreparedStatements = sharePreparedStatements;
|
||||
}
|
||||
|
||||
public String getFilters() {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public void setFilters(String filters) {
|
||||
this.filters = filters;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.sqx.datasource.properties;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 多数据源属性
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "dynamic")
|
||||
public class DynamicDataSourceProperties {
|
||||
private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
|
||||
|
||||
public Map<String, DataSourceProperties> getDatasource() {
|
||||
return datasource;
|
||||
}
|
||||
|
||||
public void setDatasource(Map<String, DataSourceProperties> datasource) {
|
||||
this.datasource = datasource;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.sqx.modules.app.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* app登录效验
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Login {
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.sqx.modules.app.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 登录用户信息
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LoginUser {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.sqx.modules.app.config;
|
||||
|
||||
import com.sqx.modules.app.interceptor.AuthorizationInterceptor;
|
||||
import com.sqx.modules.app.resolver.LoginUserHandlerMethodArgumentResolver;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MVC配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Autowired
|
||||
private AuthorizationInterceptor authorizationInterceptor;
|
||||
@Autowired
|
||||
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/app/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package com.sqx.modules.app.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.App;
|
||||
import com.sqx.modules.app.service.AppService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* APP登录授权
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/appinfo")
|
||||
@Api(value = "APP升级管理", tags = {"APP升级管理"})
|
||||
public class AppUpgradeController {
|
||||
|
||||
@Autowired
|
||||
private AppService iAppService;
|
||||
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
@ApiOperation("管理平台升级详情")
|
||||
@ResponseBody
|
||||
public Result list(Integer page,Integer limit) {
|
||||
IPage<App> pages =new Page<>(page,limit);
|
||||
return Result.success().put("data",iAppService.page(pages));
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||
@ApiOperation("管理平台升级详情")
|
||||
@ResponseBody
|
||||
public Result getBanner(@PathVariable Long id) {
|
||||
return Result.success().put("data",iAppService.selectAppById(id));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/save", method = RequestMethod.POST)
|
||||
@ApiOperation("管理平台添加升级信息")
|
||||
@ResponseBody
|
||||
public Result addBanner(@RequestBody App app) {
|
||||
if(app.getId()!=null){
|
||||
iAppService.updateAppById(app);
|
||||
}else{
|
||||
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
app.setCreateAt(sdf.format(new Date()));
|
||||
iAppService.insertApp(app);
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
|
||||
@ApiOperation("管理平台删除升级信息")
|
||||
public Result deleteBanner(@PathVariable Long id) {
|
||||
iAppService.deleteAppById(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,414 @@
|
|||
package com.sqx.modules.app.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.sqx.common.utils.PageUtils;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import com.sqx.modules.app.entity.UserMoneyDetails;
|
||||
import com.sqx.modules.app.entity.UserVip;
|
||||
import com.sqx.modules.app.response.HomeMessageResponse;
|
||||
import com.sqx.modules.app.service.UserMoneyDetailsService;
|
||||
import com.sqx.modules.app.service.UserMoneyService;
|
||||
import com.sqx.modules.app.service.UserService;
|
||||
import com.sqx.modules.app.service.UserVipService;
|
||||
import com.sqx.modules.invite.dao.InviteMoneyDao;
|
||||
import com.sqx.modules.invite.entity.InviteMoney;
|
||||
import com.sqx.modules.invite.service.InviteMoneyService;
|
||||
import com.sqx.modules.pay.dao.CashOutDao;
|
||||
import com.sqx.modules.pay.dao.PayDetailsDao;
|
||||
import com.sqx.modules.pay.entity.PayDetails;
|
||||
import com.sqx.modules.pay.service.PayDetailsService;
|
||||
import com.sqx.modules.sys.entity.SysUserEntity;
|
||||
import com.sqx.modules.sys.service.SysUserService;
|
||||
import com.sqx.modules.utils.EasyPoi.ExcelUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author fang
|
||||
* @date 2020/7/30
|
||||
*/
|
||||
@RestController
|
||||
@Api(value = "用户管理", tags = {"用户管理"})
|
||||
@RequestMapping(value = "/user")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private CashOutDao cashOutDao;
|
||||
@Autowired
|
||||
private PayDetailsService payDetailsService;
|
||||
@Autowired
|
||||
private UserMoneyDetailsService userMoneyDetailsService;
|
||||
@Autowired
|
||||
private UserMoneyService userMoneyService;
|
||||
@Autowired
|
||||
private InviteMoneyService inviteMoneyService;
|
||||
@Autowired
|
||||
private InviteMoneyDao inviteMoneyDao;
|
||||
@Autowired
|
||||
private UserVipService userVipService;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private PayDetailsDao payDetailsDao;
|
||||
|
||||
@RequestMapping(value = "/selectUserByInvitationCode", method = RequestMethod.GET)
|
||||
@ApiOperation("获取用户详细信息")
|
||||
@ResponseBody
|
||||
public Result selectUserByInvitationCode(String invitationCode) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
UserEntity userEntity = userService.queryByInvitationCode(invitationCode);
|
||||
Long userId=userEntity.getUserId();
|
||||
//查询用户钱包
|
||||
// Double money = cashOutDao.selectMayMoney(userId);
|
||||
InviteMoney inviteMoney = inviteMoneyService.selectInviteMoneyByUserId(userId);
|
||||
Double money = inviteMoney.getMoney();
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String date = simpleDateFormat.format(new Date());
|
||||
//查询本月充值
|
||||
Double consume = payDetailsService.instantselectSumPay(date, userId);
|
||||
//查询本月提现
|
||||
Double income = userMoneyDetailsService.monthIncome(date, userId);
|
||||
//查询邀请人数
|
||||
int count = userService.queryInviterCount(userEntity.getInvitationCode());
|
||||
UserVip userVip = userVipService.selectUserVipByUserId(userId);
|
||||
if(userVip!=null){
|
||||
userEntity.setMember(userVip.getIsVip());
|
||||
userEntity.setEndTime(userVip.getEndTime());
|
||||
userEntity.setVipType(userVip.getVipType());
|
||||
}
|
||||
map.put("userEntity", userEntity);
|
||||
map.put("money", money);
|
||||
map.put("consume", consume);
|
||||
map.put("income", income);
|
||||
map.put("count", count);
|
||||
return Result.success().put("data", map);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
|
||||
@ApiOperation("获取用户详细信息")
|
||||
@ResponseBody
|
||||
public Result selectUserById(@ApiParam("用户id") @PathVariable Long userId) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
UserEntity userEntity = userService.queryByUserId(userId);
|
||||
//查询用户钱包
|
||||
// Double money = cashOutDao.selectMayMoney(userId);
|
||||
InviteMoney inviteMoney = inviteMoneyService.selectInviteMoneyByUserId(userId);
|
||||
Double money = inviteMoney.getMoney();
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String date = simpleDateFormat.format(new Date());
|
||||
//查询本月充值
|
||||
Double consume = payDetailsService.instantselectSumPay(date, userId);
|
||||
//查询本月提现
|
||||
Double income = userMoneyDetailsService.monthIncome(date, userId);
|
||||
//查询邀请人数
|
||||
int count = userService.queryInviterCount(userEntity.getInvitationCode());
|
||||
UserVip userVip = userVipService.selectUserVipByUserId(userId);
|
||||
if(userVip!=null){
|
||||
userEntity.setMember(userVip.getIsVip());
|
||||
userEntity.setEndTime(userVip.getEndTime());
|
||||
userEntity.setVipType(userVip.getVipType());
|
||||
}
|
||||
map.put("userEntity", userEntity);
|
||||
map.put("money", money);
|
||||
map.put("consume", consume);
|
||||
map.put("income", income);
|
||||
map.put("count", count);
|
||||
return Result.success().put("data", map);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/selectUserList", method = RequestMethod.GET)
|
||||
@ApiOperation("查询所有用户列表")
|
||||
@ResponseBody
|
||||
public Result selectUserList(Integer page, Integer limit,String phone,Integer sex,String platform,
|
||||
String sysPhone,Integer status, Integer member, String inviterCode,
|
||||
String userName, String invitationCode, String startTime, String endTime,
|
||||
String qdCode,String sysUserName,Integer vipType) {
|
||||
return Result.success().put("data", userService.selectUserPage(page, limit, phone, sex, platform, sysPhone, status, member,
|
||||
inviterCode, userName, invitationCode, startTime, endTime,qdCode,sysUserName,vipType));
|
||||
}
|
||||
|
||||
@GetMapping("/userListExcel")
|
||||
public void userListExcel(UserEntity userEntity, String startTime, String endTime, HttpServletResponse response) throws IOException {
|
||||
List<UserEntity> list = userService.userListExcel(startTime, endTime, userEntity);
|
||||
ExcelUtils.exportExcel(list, "用户表", "用户Sheet", UserEntity.class, "用户表", response);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/deleteUserByUserId/{userId}", method = RequestMethod.POST)
|
||||
@ApiOperation("删除用户")
|
||||
@ResponseBody
|
||||
public Result deleteUserByUserId(@PathVariable("userId") Long userId) {
|
||||
userService.removeById(userId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/updateUserByUserId", method = RequestMethod.POST)
|
||||
@ApiOperation("修改用户")
|
||||
@ResponseBody
|
||||
public Result updateUserByUserId(@RequestBody UserEntity userEntity) {
|
||||
if(StringUtils.isNotEmpty(userEntity.getPhone())){
|
||||
UserEntity phoneUser = userService.queryByPhone(userEntity.getPhone());
|
||||
if(phoneUser!=null && !phoneUser.getUserId().equals(userEntity.getUserId())){
|
||||
return Result.error("手机号已被其他用户绑定!");
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(userEntity.getQdCode())){
|
||||
SysUserEntity sysUserEntity = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("qd_code", userEntity.getQdCode()));
|
||||
if(sysUserEntity==null){
|
||||
return Result.error("渠道码不正确!");
|
||||
}
|
||||
}
|
||||
userService.updateById(userEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/updateUserStatusByUserId", method = RequestMethod.GET)
|
||||
@ApiOperation("禁用或启用用户")
|
||||
@ResponseBody
|
||||
public Result updateUserByUserId(Long userId) {
|
||||
UserEntity byId = userService.getById(userId);
|
||||
if (byId.getStatus().equals(1)) {
|
||||
byId.setStatus(2);
|
||||
} else {
|
||||
byId.setStatus(1);
|
||||
}
|
||||
userService.updateById(byId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation("修改用户密码")
|
||||
@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public Result forgetPwd(String pwd, Long userId) {
|
||||
UserEntity userEntity = userService.selectUserById(userId);
|
||||
userEntity.setPassword(DigestUtils.sha256Hex(pwd));
|
||||
userService.updateById(userEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取openid
|
||||
*
|
||||
* @param code 微信code
|
||||
* @return openid
|
||||
*/
|
||||
@GetMapping("/openId/{code:.+}/{userId}")
|
||||
@ApiOperation("根据code获取openid")
|
||||
public Result getOpenid(@PathVariable("code") String code, @PathVariable("userId") Long userId) {
|
||||
return userService.getOpenId(code, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 信息分析
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/homeMessage")
|
||||
@ApiOperation("信息分析")
|
||||
public Result homeMessage(Long sysUserId) {
|
||||
String qdCode=null;
|
||||
if(sysUserId!=null){
|
||||
qdCode=sysUserService.getById(sysUserId).getQdCode();
|
||||
}
|
||||
HomeMessageResponse homeMessageResponse = new HomeMessageResponse();
|
||||
// 0查总 1查天 2查月 3查年
|
||||
//设置总用户人数
|
||||
homeMessageResponse.setTotalUsers(userService.queryUserCount(0, null,null,qdCode));
|
||||
//设置今日新增
|
||||
homeMessageResponse.setNewToday(userService.queryUserCount(1, null,null,qdCode));
|
||||
//设置本月新增
|
||||
homeMessageResponse.setNewMonth(userService.queryUserCount(2, null,null,qdCode));
|
||||
//设置本年新增
|
||||
homeMessageResponse.setNewYear(userService.queryUserCount(3, null,null,qdCode));
|
||||
//设置总收入
|
||||
homeMessageResponse.setTotalRevenue(userService.queryPayMoney(0,qdCode));
|
||||
//设置今日收入
|
||||
homeMessageResponse.setTodayRevenue(userService.queryPayMoney(1,qdCode));
|
||||
//设置本月收入
|
||||
homeMessageResponse.setMonthRevenue(userService.queryPayMoney(2,qdCode));
|
||||
//设置本年收入
|
||||
homeMessageResponse.setYearRevenue(userService.queryPayMoney(3,qdCode));
|
||||
//查询指定日期下的短剧购买的 量
|
||||
return Result.success().put("data", homeMessageResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 短剧分析
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/courseMessage")
|
||||
@ApiOperation("短剧分析")
|
||||
public Result courseMessage(Long page, Long limit, String date, int type,Long sysUserId) {
|
||||
Page<Map<String, Object>> iPage = new Page<>(page, limit);
|
||||
IPage<Map<String, Object>> mapIPage = userService.queryCourseOrder(iPage, type, date,sysUserId);
|
||||
return Result.success().put("data", new PageUtils(mapIPage));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户分析
|
||||
*/
|
||||
@GetMapping("/userMessage")
|
||||
@ApiOperation("用户分析")
|
||||
public Result userMessage(String date, int type,Long sysUserId) {
|
||||
String qdCode=null;
|
||||
if(sysUserId!=null){
|
||||
qdCode=sysUserService.getById(sysUserId).getQdCode();
|
||||
}
|
||||
int sumUserCount = userService.queryUserCount(type, date,null,qdCode);
|
||||
int h5Count = userService.queryUserCount(type, date,"h5",qdCode);
|
||||
int appCount = userService.queryUserCount(type, date,"app",qdCode);
|
||||
int wxCount = userService.queryUserCount(type, date,"小程序",qdCode);
|
||||
int dyCount = userService.queryUserCount(type, date,"抖音",qdCode);
|
||||
int giveMemberCount = userService.userMessage(date, type,qdCode,1);
|
||||
int moneyMemberCount = userService.userMessage(date, type,qdCode,2);
|
||||
int memberCount = userService.userMessage(date, type,qdCode,null);
|
||||
int userCount = sumUserCount-memberCount;
|
||||
Map<String,Integer> result=new HashMap<>();
|
||||
result.put("sumUserCount",sumUserCount);
|
||||
result.put("h5Count",h5Count);
|
||||
result.put("appCount",appCount);
|
||||
result.put("wxCount",wxCount);
|
||||
result.put("dyCount",dyCount);
|
||||
result.put("memberCount",memberCount);
|
||||
result.put("giveMemberCount",giveMemberCount);
|
||||
result.put("moneyMemberCount",moneyMemberCount);
|
||||
result.put("userCount",userCount);
|
||||
return Result.success().put("data", result);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("addCannotMoney/{userId}/{money}")
|
||||
@ApiOperation("添加金豆")
|
||||
public Result addCannotMoney(@PathVariable("userId") Long userId, @PathVariable("money") Double money) {
|
||||
userMoneyService.updateMoney(1, userId, money);
|
||||
//inviteMoneyDao.updateInviteMoneySum(money,userId);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
|
||||
userMoneyDetails.setUserId(userId);
|
||||
userMoneyDetails.setTitle("[增加金豆]平台增加金豆:" + money);
|
||||
userMoneyDetails.setContent("[增加金豆]平台增加金豆:" + money);
|
||||
userMoneyDetails.setType(1);
|
||||
userMoneyDetails.setClassify(1);
|
||||
userMoneyDetails.setMoney(new BigDecimal(money));
|
||||
userMoneyDetails.setCreateTime(sdf.format(new Date()));
|
||||
userMoneyDetailsService.save(userMoneyDetails);
|
||||
PayDetails payDetails=new PayDetails();
|
||||
payDetails.setState(1);
|
||||
payDetails.setCreateTime(sdf.format(new Date()));
|
||||
payDetails.setUserId(userId);
|
||||
payDetails.setMoney(money);
|
||||
payDetails.setClassify(9);
|
||||
payDetails.setType(1);
|
||||
payDetails.setPayTime(sdf.format(new Date()));
|
||||
payDetailsDao.insert(payDetails);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("subCannotMoney/{userId}/{money}")
|
||||
@ApiOperation("减少金豆")
|
||||
public Result subCannotMoney(@PathVariable("userId") Long userId, @PathVariable("money") Double money) {
|
||||
userMoneyService.updateMoney(2, userId, money);
|
||||
//inviteMoneyDao.updateInviteMoneySumSub(money,userId);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
|
||||
userMoneyDetails.setUserId(userId);
|
||||
userMoneyDetails.setTitle("[减少金豆]平台减少金豆:" + money);
|
||||
userMoneyDetails.setContent("平台减少金豆:" + money);
|
||||
userMoneyDetails.setType(1);
|
||||
userMoneyDetails.setClassify(1);
|
||||
userMoneyDetails.setMoney(new BigDecimal(money));
|
||||
userMoneyDetails.setCreateTime(sdf.format(new Date()));
|
||||
userMoneyDetailsService.save(userMoneyDetails);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/updateSysUserMoney")
|
||||
@ApiOperation("修改金豆")
|
||||
public Result updateSysUserMoney(Long userId, Double money,Integer type) {
|
||||
userMoneyService.updateSysMoney(type, userId, money);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
|
||||
userMoneyDetails.setSysUserId(userId);
|
||||
if(type==1){
|
||||
userMoneyDetails.setTitle("[增加金豆]平台增加金豆:" + money);
|
||||
userMoneyDetails.setContent("[增加金豆]平台增加金豆:" + money);
|
||||
}else{
|
||||
userMoneyDetails.setTitle("[减少金豆]平台减少金豆:" + money);
|
||||
userMoneyDetails.setContent("[减少金豆]平台减少金豆:" + money);
|
||||
}
|
||||
userMoneyDetails.setType(type);
|
||||
userMoneyDetails.setClassify(1);
|
||||
userMoneyDetails.setMoney(new BigDecimal(money));
|
||||
userMoneyDetails.setCreateTime(sdf.format(new Date()));
|
||||
userMoneyDetailsService.save(userMoneyDetails);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@GetMapping("/selectInviteUserList")
|
||||
@ApiOperation("邀请用户排行榜")
|
||||
public Result selectInviteUserList(Integer page,Integer limit,String phone,String userName){
|
||||
return userService.selectInviteUserList(page, limit, userName, phone);
|
||||
}
|
||||
|
||||
@GetMapping("/selectUserOnLineCount")
|
||||
@ApiOperation("统计当前在线人数")
|
||||
public Result selectUserCount(Long sysUserId){
|
||||
String qdCode=null;
|
||||
if(sysUserId!=null){
|
||||
qdCode=sysUserService.getById(sysUserId).getQdCode();
|
||||
}
|
||||
return userService.selectUserOnLineCount(qdCode);
|
||||
}
|
||||
|
||||
@GetMapping("/selectUserCountStatisticsByTime")
|
||||
@ApiOperation("用户统计")
|
||||
public Result selectUserCountStatisticsByTime(String startTime,String endTime){
|
||||
List<Integer> userCountList=new ArrayList<>();
|
||||
List<String> year=new ArrayList<>();
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Calendar calendar=Calendar.getInstance();
|
||||
Date parse = null;
|
||||
try {
|
||||
parse = simpleDateFormat.parse(startTime);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
calendar.setTime(parse);
|
||||
while (true){
|
||||
String dateTime = simpleDateFormat.format(calendar.getTime());
|
||||
int i = userService.queryUserCount(1, dateTime,null,null);
|
||||
userCountList.add(i);
|
||||
year.add(dateTime);
|
||||
if(dateTime.equals(endTime)){
|
||||
break;
|
||||
}
|
||||
calendar.add(Calendar.DATE,1);
|
||||
}
|
||||
Map<String,Object> result=new HashMap<>();
|
||||
result.put("userCountList",userCountList);
|
||||
result.put("year",year);
|
||||
return Result.success().put("data",result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.sqx.modules.app.controller;
|
||||
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.service.UserMoneyDetailsService;
|
||||
import com.sqx.modules.app.service.UserMoneyService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/moneyDetails")
|
||||
@AllArgsConstructor
|
||||
@Api("钱包明细")
|
||||
public class UserMoneyDetailsController {
|
||||
private UserMoneyDetailsService userMoneyDetailsService;
|
||||
private UserMoneyService userMoneyService;
|
||||
|
||||
|
||||
@ApiOperation("钱包明细")
|
||||
@GetMapping("/queryUserMoneyDetails")
|
||||
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId, Long userId,Integer classify,Integer type) {
|
||||
return userMoneyDetailsService.queryUserMoneyDetails(page, limit, sysUserId, userId,classify,type);
|
||||
}
|
||||
|
||||
@GetMapping("/selectUserMoney")
|
||||
@ApiOperation("我的钱包")
|
||||
public Result selectUserMoney(Long userId){
|
||||
return Result.success().put("data",userMoneyService.selectUserMoneyByUserId(userId));
|
||||
}
|
||||
|
||||
@GetMapping("/selectSysUserMoney")
|
||||
@ApiOperation("代理钱包")
|
||||
public Result selectSysUserMoney(Long userId){
|
||||
return Result.success().put("data",userMoneyService.selectSysUserMoneyByUserId(userId));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package com.sqx.modules.app.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.sqx.common.utils.DateUtils;
|
||||
import com.sqx.common.utils.PageUtils;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.UserVip;
|
||||
import com.sqx.modules.app.entity.VipDetails;
|
||||
import com.sqx.modules.app.service.UserVipService;
|
||||
import com.sqx.modules.app.service.VipDetailsService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
@RestController
|
||||
@Api(value = "会员管理", tags = {"会员管理"})
|
||||
@RequestMapping(value = "/vipDetails")
|
||||
public class VipDetailsController {
|
||||
|
||||
@Autowired
|
||||
private VipDetailsService vipDetailsService;
|
||||
@Autowired
|
||||
private UserVipService userVipService;
|
||||
|
||||
@PostMapping("/sendVip")
|
||||
@ApiOperation("赠送会员")
|
||||
public Result sendVip(Long userId,Integer num){
|
||||
UserVip userVip = userVipService.selectUserVipByUserId(userId);
|
||||
Calendar calendar=Calendar.getInstance();
|
||||
if(userVip!=null){
|
||||
if(userVip.getIsVip()==2){
|
||||
Date date = DateUtils.stringToDate(userVip.getEndTime(), "yyyy-MM-dd HH:mm:ss");
|
||||
calendar.setTime(date);
|
||||
}
|
||||
}else{
|
||||
userVip=new UserVip();
|
||||
userVip.setUserId(userId);
|
||||
userVip.setCreateTime(DateUtils.format(new Date()));
|
||||
}
|
||||
userVip.setVipType(1);
|
||||
userVip.setIsVip(2);
|
||||
calendar.add(Calendar.DAY_OF_MONTH,num);
|
||||
userVip.setEndTime(DateUtils.format(calendar.getTime()));
|
||||
if(userVip.getVipId()!=null){
|
||||
userVipService.updateById(userVip);
|
||||
}else{
|
||||
userVipService.save(userVip);
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/deleteVip")
|
||||
@ApiOperation("取消会员")
|
||||
public Result deleteVip(Long userId){
|
||||
UserVip userVip = userVipService.selectUserVipByUserId(userId);
|
||||
if(userVip!=null){
|
||||
userVipService.removeById(userVip.getVipId());
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@ApiParam("添加会员的详情信息")
|
||||
@PostMapping("/insertVipDetails")
|
||||
public Result insertVipDetails(@RequestBody VipDetails vipDetails) {
|
||||
return vipDetailsService.insertVipDetails(vipDetails);
|
||||
}
|
||||
|
||||
|
||||
@ApiParam("修改会员的详情信息")
|
||||
@PostMapping("/updateVipDetails")
|
||||
public Result updateVipDetails(@RequestBody VipDetails vipDetails) {
|
||||
vipDetailsService.updateById(vipDetails);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiParam("删除的详情信息")
|
||||
@PostMapping("/deleteVipDetails")
|
||||
public Result deleteVipDetails(Long id) {
|
||||
vipDetailsService.removeById(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiParam("查询会员列表")
|
||||
@GetMapping("/selectVipDetailsList")
|
||||
public Result selectVipDetailsList(Integer page,Integer limit) {
|
||||
return Result.success().put("data",new PageUtils(vipDetailsService.page(new Page<>(page,limit))));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
package com.sqx.modules.app.controller.app;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.annotation.Login;
|
||||
import com.sqx.modules.app.annotation.LoginUser;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import com.sqx.modules.app.service.AppService;
|
||||
import com.sqx.modules.app.service.UserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* APP登录授权
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/app/user")
|
||||
@Api(value = "APP管理", tags = {"APP管理"})
|
||||
public class AppController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private AppService appService;
|
||||
|
||||
@PostMapping("/authenticationRegister")
|
||||
@ApiOperation("认证创建账号")
|
||||
public Result authenticationRegister(@RequestBody JSONObject jsonObject, HttpServletRequest request){
|
||||
return userService.authenticationRegister(jsonObject,request);
|
||||
}
|
||||
|
||||
@Login
|
||||
@PostMapping("/getNewUserRed")
|
||||
@ApiOperation("领取新用户红包")
|
||||
public Result getNewUserRed(@RequestAttribute Long userId){
|
||||
return userService.getNewUserRed(userId);
|
||||
}
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
@ApiOperation("用户端修改密码")
|
||||
public Result updatePwd(@LoginUser UserEntity user,String pwd,String oldPwd) {
|
||||
if(!user.getPassword().equals(DigestUtils.sha256Hex(oldPwd))){
|
||||
return Result.error("原始密码不正确!");
|
||||
}
|
||||
if(pwd.equals(oldPwd)){
|
||||
return Result.error("新密码不能与旧密码相同!");
|
||||
}
|
||||
user.setPassword(DigestUtils.sha256Hex(pwd));
|
||||
userService.updateById(user);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/updatePhone", method = RequestMethod.POST)
|
||||
@ApiOperation("用户端换绑手机号")
|
||||
@ResponseBody
|
||||
public Result updatePhone(@RequestAttribute("userId") Long userId,@RequestParam String phone, @RequestParam String msg) {
|
||||
return userService.updatePhone(phone, msg,userId);
|
||||
}
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
|
||||
@ApiOperation("用户修改个人信息")
|
||||
@ResponseBody
|
||||
public Result updateUserImageUrl(@RequestAttribute("userId") Long userId,String zhiFuBao,String zhiFuBaoName) {
|
||||
UserEntity userEntity=new UserEntity();
|
||||
userEntity.setZhiFuBao(zhiFuBao);
|
||||
userEntity.setZhiFuBaoName(zhiFuBaoName);
|
||||
userEntity.setUserId(userId);
|
||||
userService.updateById(userEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/updateUsers", method = RequestMethod.POST)
|
||||
@ApiOperation("用户修改个人信息")
|
||||
@ResponseBody
|
||||
public Result updateUsers(@RequestAttribute("userId") Long userId,@RequestBody UserEntity userEntity) {
|
||||
userEntity.setUserId(userId);
|
||||
userService.updateById(userEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
/*@Login
|
||||
@RequestMapping(value = "/updateUsers", method = RequestMethod.POST)
|
||||
@ApiOperation("用户修改个人信息")
|
||||
@ResponseBody
|
||||
public Result updateUsers(@RequestAttribute("userId") Long userId,String userName,String avatar,String phone) {
|
||||
UserEntity userEntity=new UserEntity();
|
||||
userEntity.setUserId(userId);
|
||||
userEntity.setUserName(userName);
|
||||
userEntity.setAvatar(avatar);
|
||||
userEntity.setPhone(phone);
|
||||
userService.updateById(userEntity);
|
||||
return Result.success();
|
||||
}*/
|
||||
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/updateUserImageUrl", method = RequestMethod.POST)
|
||||
@ApiOperation("用户修改头像")
|
||||
@ResponseBody
|
||||
public Result updateUserImageUrl(@LoginUser UserEntity user,String avatar) {
|
||||
user.setAvatar(avatar);
|
||||
userService.updateById(user);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/updateUserName", method = RequestMethod.POST)
|
||||
@ApiOperation("用户修改昵称")
|
||||
@ResponseBody
|
||||
public Result updateUserName(@LoginUser UserEntity user,String userName) {
|
||||
user.setUserName(userName);
|
||||
userService.updateById(user);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Login
|
||||
@RequestMapping(value = "/selectUserById", method = RequestMethod.GET)
|
||||
@ApiOperation("获取用户详细信息")
|
||||
@ResponseBody
|
||||
public Result selectUserById(@LoginUser UserEntity user) {
|
||||
return Result.success().put("data",user);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/selectNewApp", method = RequestMethod.GET)
|
||||
@ApiOperation("升级检测")
|
||||
@ResponseBody
|
||||
public Result selectNewApp() {
|
||||
return Result.success().put("data",appService.selectNewApp());
|
||||
}
|
||||
|
||||
@GetMapping("/openId/{code:.+}/{userId}")
|
||||
@ApiOperation("根据code获取openid")
|
||||
public Result getOpenid(@PathVariable("code") String code,@PathVariable("userId")Long userId) {
|
||||
return userService.getOpenId(code,userId);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/updateClientId", method = RequestMethod.GET)
|
||||
@ApiOperation("绑定ClientId")
|
||||
@ResponseBody
|
||||
public Result updateClientId(String clientId,Long userId,Integer sysPhone ) {
|
||||
userService.updateUserClientIdIsNull(clientId);
|
||||
UserEntity userEntity=new UserEntity();
|
||||
userEntity.setSysPhone(sysPhone);
|
||||
userEntity.setUserId(userId);
|
||||
userEntity.setClientid(clientId);
|
||||
userService.updateById(userEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
package com.sqx.modules.app.controller.app;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import com.sqx.modules.app.service.IAppleService;
|
||||
import com.sqx.modules.app.service.UserService;
|
||||
import com.sqx.modules.app.utils.UserConstantInterface;
|
||||
import com.sqx.modules.app.utils.WxPhone;
|
||||
import com.sqx.modules.common.entity.CommonInfo;
|
||||
import com.sqx.modules.common.service.CommonInfoService;
|
||||
import com.sqx.modules.utils.HttpClientUtil;
|
||||
import com.sqx.modules.utils.SenInfoCheckUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import weixin.popular.api.SnsAPI;
|
||||
import weixin.popular.bean.sns.SnsToken;
|
||||
|
||||
/**
|
||||
* APP登录授权
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/app/Login")
|
||||
@Api("APP登录接口")
|
||||
@Slf4j
|
||||
public class AppLoginController {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private IAppleService appleService;
|
||||
@Autowired
|
||||
private CommonInfoService commonInfoService;
|
||||
|
||||
@ApiOperation("微信小程序登陆")
|
||||
@RequestMapping(value = "/wxLogin", method = RequestMethod.GET)
|
||||
public Result wxLogin(@ApiParam("小程序code码") String code){
|
||||
return userService.wxLogin(code);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("小程序登录新增或修改个人信息")
|
||||
@RequestMapping(value = "/insertWxUser", method = RequestMethod.POST)
|
||||
public Result insertWxUser(@RequestBody UserEntity userInfo){
|
||||
return userService.wxRegister(userInfo);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/dyLogin", method = RequestMethod.POST)
|
||||
@ApiOperation("抖音登录")
|
||||
@ResponseBody
|
||||
public Result dyLogin(String code,String anonymous_code) {
|
||||
return userService.dyLogin(code,anonymous_code);
|
||||
}
|
||||
|
||||
@ApiOperation("抖音登录新增或修改个人信息")
|
||||
@RequestMapping(value = "/dyRegister", method = RequestMethod.POST)
|
||||
public Result dyRegister(@RequestBody UserEntity userInfo){
|
||||
return userService.dyRegister(userInfo);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/ksLogin", method = RequestMethod.POST)
|
||||
@ApiOperation("快手登录")
|
||||
@ResponseBody
|
||||
public Result ksLogin(String code) {
|
||||
return userService.ksLogin(code);
|
||||
}
|
||||
|
||||
@ApiOperation("快手登录新增或修改个人信息")
|
||||
@RequestMapping(value = "/ksRegister", method = RequestMethod.POST)
|
||||
public Result ksRegister(@RequestBody UserEntity userInfo){
|
||||
return userService.ksRegister(userInfo);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/appleLogin", method = RequestMethod.GET)
|
||||
@ApiOperation("苹果登陆获取appleUserId")
|
||||
public Result loginVerify(@RequestParam("identityToken") String identityToken) {
|
||||
try {
|
||||
log.info("苹果token:{}", identityToken);
|
||||
JSONObject jsonObject = JSON.parseObject(identityToken);
|
||||
JSONObject userInfo = jsonObject.getJSONObject("userInfo");
|
||||
String identityTokens = userInfo.getString("identityToken");
|
||||
return appleService.getAppleUserInfo(identityTokens);
|
||||
} catch (Exception e) {
|
||||
log.error("苹果token校验失败:{}", identityToken, e);
|
||||
return Result.error("苹果账号验证失败,请退出重试!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("苹果登录")
|
||||
@RequestMapping(value = "/insertAppleUser", method = RequestMethod.GET)
|
||||
public Result insertAppleUser(@RequestParam String appleId){
|
||||
return userService.iosRegister(appleId);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/iosBindMobile", method = RequestMethod.POST)
|
||||
@ApiOperation("苹果登录绑定手机号")
|
||||
@ResponseBody
|
||||
public Result iosBindMobile(@RequestParam String phone,@RequestParam String code,@RequestParam String appleId,
|
||||
@RequestParam String platform,@RequestParam Integer sysPhone,String inviterCode,String qdCode) {
|
||||
return userService.iosBindMobile(phone, code, appleId, platform, sysPhone,inviterCode,qdCode);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/wxAppLogin", method = RequestMethod.POST)
|
||||
@ApiOperation("微信APP登录")
|
||||
@ResponseBody
|
||||
public Result wxAppLogin(@RequestParam String wxOpenId,@RequestParam String token) {
|
||||
return userService.wxAppLogin(wxOpenId,token);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/wxBindMobile", method = RequestMethod.POST)
|
||||
@ApiOperation("微信登录绑定手机号")
|
||||
@ResponseBody
|
||||
public Result wxBindMobile(@RequestParam String phone,@RequestParam String code,@RequestParam String wxOpenId,@RequestParam String token,
|
||||
@RequestParam String platform,@RequestParam Integer sysPhone,String inviterCode,String qdCode) {
|
||||
return userService.wxBindMobile(phone, code, wxOpenId, token, platform, sysPhone,inviterCode,qdCode);
|
||||
}
|
||||
|
||||
@PostMapping("/phoneLogin")
|
||||
@ApiOperation("手机号一键登录")
|
||||
@ResponseBody
|
||||
public Result phoneLogin(String phone){
|
||||
return userService.phoneLogin(phone);
|
||||
}
|
||||
|
||||
@PostMapping("/bindMobile")
|
||||
@ApiOperation("手机号一键登录")
|
||||
@ResponseBody
|
||||
public Result bindMobile(String phone,String platform, Integer sysPhone,String inviterCode,String qdCode){
|
||||
return userService.bindMobile(phone, platform, sysPhone, inviterCode, qdCode);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/registerCode", method = RequestMethod.POST)
|
||||
@ApiOperation("app或h5注册或登录")
|
||||
@ResponseBody
|
||||
public Result registerCode(@RequestParam String phone,String msg,String platform,Integer sysPhone,
|
||||
String password,String inviterCode,String wxId,String qdCode) {
|
||||
return userService.registerCode(phone,msg,platform,sysPhone,password,inviterCode,wxId,qdCode);
|
||||
}
|
||||
|
||||
@PostMapping("/bindWxOpenPhone")
|
||||
@ApiOperation("微信公众号绑定手机号")
|
||||
public Result bindWxOpenPhone(Long userId,String phone,String msg){
|
||||
return userService.bindWxOpenPhone(userId, phone, msg);
|
||||
}
|
||||
|
||||
@ApiOperation("用户端发送验证码")
|
||||
@RequestMapping(value = "/sendMsg/{phone}/{state}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Result sendMsg(@PathVariable String phone, @PathVariable String state) {
|
||||
return userService.sendMsg(phone, state,null);
|
||||
}
|
||||
|
||||
@ApiOperation("解密手机号")
|
||||
@RequestMapping(value = "/selectPhone",method = RequestMethod.POST)
|
||||
public Result getPhoneNumberBeanS5(@RequestBody WxPhone wxPhone) {
|
||||
return UserConstantInterface.decryptS5(wxPhone.getDecryptData(), wxPhone.getKey(), wxPhone.getIv());
|
||||
}
|
||||
|
||||
@ApiOperation("微信小程序解密手机号")
|
||||
@RequestMapping(value = "/wxPhone",method = RequestMethod.POST)
|
||||
public Result wxPhone(String code) {
|
||||
String url="https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+SenInfoCheckUtil.getMpToken();
|
||||
JSONObject param=new JSONObject();
|
||||
param.put("code",code);
|
||||
String result = HttpClientUtil.doPostJson(url, param.toJSONString());
|
||||
return Result.success().put("data",JSONObject.parseObject(result));
|
||||
}
|
||||
|
||||
@ApiOperation("用户端忘记密码")
|
||||
@RequestMapping(value = "/forgetPwd", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public Result forgetPwd(String pwd, String phone, String msg) {
|
||||
return userService.forgetPwd(pwd, phone, msg);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getOpenId")
|
||||
@ApiOperation("公众号根据code换取openId")
|
||||
public Result getOpenId(String code,Long userId) {
|
||||
try {
|
||||
//微信appid
|
||||
CommonInfo one = commonInfoService.findOne(5);
|
||||
//微信秘钥
|
||||
CommonInfo two = commonInfoService.findOne(21);
|
||||
SnsToken snsToken = SnsAPI.oauth2AccessToken(one.getValue(), two.getValue(), code);
|
||||
String openid = snsToken.getOpenid();
|
||||
return Result.success().put("data",openid);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("GET_OPENID_FAIL");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ApiOperation("用户端openid登录呢")
|
||||
@RequestMapping(value = "/openid/login", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Result loginByOpenId(@RequestParam String openId) {
|
||||
return userService.loginByOpenId(openId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.sqx.modules.app.controller.app;
|
||||
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.annotation.Login;
|
||||
import com.sqx.modules.app.service.UserMoneyDetailsService;
|
||||
import com.sqx.modules.app.service.UserMoneyService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/app/moneyDetails")
|
||||
@AllArgsConstructor
|
||||
@Api("钱包明细")
|
||||
public class AppUserMoneyDetailsController {
|
||||
|
||||
private UserMoneyDetailsService userMoneyDetailsService;
|
||||
private UserMoneyService userMoneyService;
|
||||
|
||||
|
||||
@Login
|
||||
@ApiOperation("钱包明细")
|
||||
@GetMapping("/queryUserMoneyDetails")
|
||||
public Result queryUserMoneyDetails(Integer page, Integer limit, @RequestAttribute Long userId,Integer classify,Integer type) {
|
||||
return userMoneyDetailsService.queryUserMoneyDetails(page, limit,null, userId,1,type);
|
||||
}
|
||||
|
||||
@Login
|
||||
@GetMapping("/selectUserMoney")
|
||||
@ApiOperation("我的钱包")
|
||||
public Result selectUserMoney(@RequestAttribute Long userId){
|
||||
return Result.success().put("data",userMoneyService.selectUserMoneyByUserId(userId));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.sqx.modules.app.controller.app;
|
||||
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.annotation.Login;
|
||||
import com.sqx.modules.app.service.UserVipService;
|
||||
import com.sqx.modules.sys.controller.AbstractController;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@Api(value = "用户会员信息", tags = {"用户会员信息"})
|
||||
@RequestMapping(value = "/app/UserVip")
|
||||
public class AppUserVipController extends AbstractController {
|
||||
@Autowired
|
||||
private UserVipService userVipService;
|
||||
@Login
|
||||
@GetMapping("/selectUserVip")
|
||||
@ApiOperation("查询用户会员信息")
|
||||
public Result selectUserVip(@RequestAttribute Long userId){
|
||||
return Result.success().put("data",userVipService.selectUserVipByUserId(userId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.sqx.modules.app.controller.app;
|
||||
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.annotation.Login;
|
||||
import com.sqx.modules.app.entity.VipDetails;
|
||||
import com.sqx.modules.app.service.VipDetailsService;
|
||||
import com.sqx.modules.orders.service.OrdersService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/app/VipDetails")
|
||||
@AllArgsConstructor
|
||||
@Api("会员详情信息")
|
||||
public class AppVipDetailsController {
|
||||
private VipDetailsService appVipDetailsService;
|
||||
private OrdersService ordersService;
|
||||
|
||||
/**
|
||||
* 查询会员的详情信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Login
|
||||
@ApiParam("查询会员的详情信息")
|
||||
@GetMapping("/selectVipDetails")
|
||||
public Result selectVipDetails() {
|
||||
return appVipDetailsService.selectVipDetails();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加会员的详情信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Login
|
||||
@ApiParam("添加会员的详情信息")
|
||||
@GetMapping("/insertVipDetails")
|
||||
public Result insertVipDetails(VipDetails vipDetails) {
|
||||
return appVipDetailsService.insertVipDetails(vipDetails);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sqx.modules.app.entity.App;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户升级
|
||||
*
|
||||
*/
|
||||
@Mapper
|
||||
public interface AppDao extends BaseMapper<App> {
|
||||
|
||||
List<App> selectNewApp();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sqx.modules.app.entity.Msg;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
*/
|
||||
@Mapper
|
||||
public interface MsgDao extends BaseMapper<Msg> {
|
||||
|
||||
Msg findByPhone(String phone);
|
||||
|
||||
Msg findByPhoneAndCode(String phone, String msg);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserDao extends BaseMapper<UserEntity> {
|
||||
|
||||
|
||||
IPage<UserEntity> selectUserPage(@Param("page") Page<UserEntity> page, @Param("search") String search, @Param("sex") Integer sex, @Param("platform") String platform,
|
||||
@Param("sysPhone") String sysPhone, @Param("status") Integer status, @Param("member") Integer member,
|
||||
@Param("inviterCode") String inviterCode, @Param("userName") String userName,
|
||||
@Param("invitationCode") String invitationCode, @Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime,@Param("qdCode") String qdCode,@Param("sysUserName") String sysUserName,Integer vipType);
|
||||
|
||||
List<UserEntity> userListExcel(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("userEntity") UserEntity userEntity);
|
||||
|
||||
int queryInviterCount(@Param("inviterCode") String inviterCode);
|
||||
|
||||
int queryUserCount(@Param("type") int type, @Param("date") String date,String platform,String qdCode);
|
||||
|
||||
Double queryPayMoney(@Param("type") int type, @Param("date") String date,String qdCode);
|
||||
|
||||
IPage<Map<String, Object>> queryCourseOrder(Page iPage,@Param("type") int type, @Param("date") String date,Long sysUserId);
|
||||
|
||||
int userMessage( String date, int type,String qdCode,Integer vipType);
|
||||
|
||||
int insertUser(UserEntity userEntity);
|
||||
|
||||
IPage<UserEntity> selectInviteUserList(Page<UserEntity> page,String userName,String phone);
|
||||
|
||||
int selectUserOnLineCount(String qdCode);
|
||||
|
||||
int updateUserClientIdIsNull(String clientid);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sqx.modules.app.entity.UserMoney;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface UserMoneyDao extends BaseMapper<UserMoney> {
|
||||
|
||||
void updateMayMoney(@Param("type") Integer type, @Param("userId")Long userId, @Param("money") Double money);
|
||||
|
||||
void updateSysMoney(@Param("type") Integer type, @Param("sysUserId")Long sysUserId, @Param("money") Double money);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sqx.modules.app.entity.UserMoneyDetails;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface UserMoneyDetailsDao extends BaseMapper<UserMoneyDetails> {
|
||||
|
||||
|
||||
Double monthIncome(@Param("date") String date,@Param("userId") Long userId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sqx.modules.app.entity.UserVip;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface UserVipDao extends BaseMapper<UserVip> {
|
||||
|
||||
int updateUserVipByEndTime();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.sqx.modules.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sqx.modules.app.entity.VipDetails;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface VipDetailsDao extends BaseMapper<VipDetails> {
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 广告位
|
||||
*/
|
||||
@Data
|
||||
@TableName("app")
|
||||
public class App implements Serializable {
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private String createAt;
|
||||
|
||||
private String androidWgtUrl;
|
||||
|
||||
private String iosWgtUrl;
|
||||
|
||||
private String wgtUrl;
|
||||
|
||||
private String version;
|
||||
|
||||
private String iosVersion;
|
||||
|
||||
private String method;
|
||||
|
||||
private String des;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class AppUserInfo {
|
||||
|
||||
|
||||
|
||||
private String openid;
|
||||
private String nickname;
|
||||
private int sex;
|
||||
private String province;
|
||||
private String city;
|
||||
private String country;
|
||||
private String headimgurl;
|
||||
private String unionid;
|
||||
private List<String> privilege;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author fang
|
||||
* @date 2020/7/10
|
||||
*/
|
||||
@Data
|
||||
@TableName("msg")
|
||||
public class Msg implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private String code;
|
||||
|
||||
private String phone;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class UserDetails {
|
||||
/**
|
||||
* 本月订单数量
|
||||
*/
|
||||
private int monthlyOrderNum;
|
||||
/**
|
||||
* 本月充值金豆
|
||||
*/
|
||||
private BigDecimal monthlyRechargeMoney;
|
||||
/**
|
||||
*本月提现数量
|
||||
*/
|
||||
private int monthWithdrawalNum;
|
||||
/**
|
||||
* 本月提现金豆
|
||||
*/
|
||||
private BigDecimal monthlyWithdrawalMoney;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("用户")
|
||||
@TableName("tb_user")
|
||||
public class UserEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@Excel(name = "用户id", orderNum = "1")
|
||||
@ApiModelProperty("用户id")
|
||||
@TableId(type = IdType.AUTO, value = "user_id")
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Excel(name = "用户昵称", orderNum = "2")
|
||||
@ApiModelProperty("用户名")
|
||||
@TableField("user_name")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Excel(name = "手机号", orderNum = "4")
|
||||
@ApiModelProperty("手机号")
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
@Excel(name = "头像", orderNum = "3")
|
||||
@ApiModelProperty("头像")
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 性别 1男 2女
|
||||
*/
|
||||
@ApiModelProperty("性别 1男 2女")
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 微信小程序openid
|
||||
*/
|
||||
@ApiModelProperty("微信小程序openid")
|
||||
@TableField("open_id")
|
||||
private String openId;
|
||||
|
||||
/**
|
||||
* 微信小程序openid
|
||||
*/
|
||||
@ApiModelProperty("微信公众号openid")
|
||||
@TableField("wx_id")
|
||||
private String wxId;
|
||||
|
||||
/**
|
||||
* 微信app openid
|
||||
*/
|
||||
@ApiModelProperty("微信app openid")
|
||||
@TableField("wx_open_id")
|
||||
private String wxOpenId;
|
||||
|
||||
/**
|
||||
* 抖音小程序openId
|
||||
*/
|
||||
private String dyOpenId;
|
||||
|
||||
/**
|
||||
* 快手小程序openId
|
||||
*/
|
||||
private String ksOpenId;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Excel(name = "创建时间", orderNum = "13", width = 18)
|
||||
@TableField("create_time")
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private String updateTime;
|
||||
|
||||
/**
|
||||
* 苹果id
|
||||
*/
|
||||
@TableField("apple_id")
|
||||
private String appleId;
|
||||
|
||||
/**
|
||||
* 手机类型 1安卓 2ios
|
||||
*/
|
||||
@TableField("sys_phone")
|
||||
private Integer sysPhone;
|
||||
|
||||
/**
|
||||
* 状态 1正常 2禁用
|
||||
*/
|
||||
@Excel(name = "状态", orderNum = "13", replace = {"正常_1", "禁用_1"})
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 来源 app 小程序 公众号
|
||||
*/
|
||||
@Excel(name = "渠道来源", orderNum = "9")
|
||||
private String platform;
|
||||
|
||||
/**
|
||||
* 积分
|
||||
*/
|
||||
private Integer jifen;
|
||||
|
||||
/**
|
||||
* 邀请码
|
||||
*/
|
||||
@Excel(name = "邀请码", orderNum = "5")
|
||||
@TableField("invitation_code")
|
||||
private String invitationCode;
|
||||
|
||||
/**
|
||||
* 邀请人邀请码
|
||||
*/
|
||||
@Excel(name = "邀请人邀请码", orderNum = "6",width = 15)
|
||||
@TableField("inviter_code")
|
||||
private String inviterCode;
|
||||
|
||||
private String clientid;
|
||||
|
||||
@Excel(name = "支付宝账号", orderNum = "8", width = 18)
|
||||
private String zhiFuBao;
|
||||
|
||||
@Excel(name = "支付宝名称", orderNum = "8", width = 18)
|
||||
private String zhiFuBaoName;
|
||||
|
||||
@Excel(name = "一级推广收益比例", orderNum = "8", width = 18)
|
||||
private BigDecimal rate;
|
||||
|
||||
@Excel(name = "二级推广收益比例", orderNum = "8", width = 18)
|
||||
private BigDecimal twoRate;
|
||||
|
||||
/**
|
||||
* 最后一次在线时间
|
||||
*/
|
||||
private String onLineTime;
|
||||
|
||||
/**
|
||||
* 渠道码
|
||||
*/
|
||||
private String qdCode;
|
||||
|
||||
/**
|
||||
* 是否是新用户 1否
|
||||
*/
|
||||
private Integer isNewUser;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String sysUserName;
|
||||
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer member;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer counts;
|
||||
|
||||
@TableField(exist = false)
|
||||
private BigDecimal money;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String endTime;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer vipType;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("user_money")
|
||||
@ApiModel("用户钱包")
|
||||
public class UserMoney implements Serializable {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
@ApiModelProperty("主键id")
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 钱包金豆
|
||||
*/
|
||||
@ApiModelProperty("钱包金豆")
|
||||
private BigDecimal money;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ApiModelProperty("用户id")
|
||||
@TableField("user_id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 渠道用户id
|
||||
*/
|
||||
@ApiModelProperty("渠道用户id")
|
||||
@TableField("sys_user_id")
|
||||
private Long sysUserId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("user_money_details")
|
||||
@ApiModel("钱包详情")
|
||||
public class UserMoneyDetails implements Serializable {
|
||||
/**
|
||||
* 钱包详情id
|
||||
*/
|
||||
@ApiModelProperty("钱包详情id")
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@TableField("user_id")
|
||||
@ApiModelProperty("用户id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 渠道用户id
|
||||
*/
|
||||
@ApiModelProperty("渠道用户id")
|
||||
@TableField("sys_user_id")
|
||||
private Long sysUserId;
|
||||
|
||||
/**
|
||||
* 对应用户id
|
||||
*/
|
||||
@TableField("by_user_id")
|
||||
@ApiModelProperty("对应用户id")
|
||||
private Long byUserId;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
@ApiModelProperty("标题")
|
||||
private String title;
|
||||
/**
|
||||
* 1注册 2首次购买 3购买 4提现
|
||||
*/
|
||||
@ApiModelProperty("1充值钱包明细 2提现钱包明细")
|
||||
private Integer classify;
|
||||
/**
|
||||
* 类别(1充值2支出)
|
||||
*/
|
||||
@ApiModelProperty("类别(1充值2支出)")
|
||||
private Integer type;
|
||||
/**
|
||||
* 状态 1待支付 2已到账 3取消
|
||||
*/
|
||||
@ApiModelProperty("状态 1待支付 2已到账 3取消")
|
||||
private Integer state;
|
||||
/**
|
||||
* 金豆
|
||||
*/
|
||||
@ApiModelProperty("金豆")
|
||||
private BigDecimal money;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
@ApiModelProperty("内容")
|
||||
private String content;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
@ApiModelProperty("创建时间")
|
||||
private String createTime;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
@Data
|
||||
@TableName("user_vip")
|
||||
public class UserVip implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 用户会员ID
|
||||
*/
|
||||
@TableId
|
||||
private Long vipId;
|
||||
/**
|
||||
* 会员类型
|
||||
*/
|
||||
private Integer vipNameType;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 会员是否到期
|
||||
*/
|
||||
private Integer isVip;
|
||||
|
||||
|
||||
/**
|
||||
* 购买时间
|
||||
*/
|
||||
private String createTime;
|
||||
/**
|
||||
* 到期时间
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 会员类型 1活动赠送 2充值开通
|
||||
*/
|
||||
private Integer vipType;
|
||||
|
||||
public UserVip() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.sqx.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("vip_details")
|
||||
@ApiModel("会员详情")
|
||||
public class VipDetails implements Serializable {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("会员类型")
|
||||
@TableField("vip_name_type")
|
||||
private Integer vipNameType;
|
||||
|
||||
@ApiModelProperty("会员价格")
|
||||
private BigDecimal money;
|
||||
|
||||
/**
|
||||
* 支付钻石
|
||||
*/
|
||||
private BigDecimal payDiamond;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.sqx.modules.app.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 登录表单
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "登录表单")
|
||||
public class LoginForm {
|
||||
@ApiModelProperty(value = "手机号")
|
||||
@NotBlank(message="手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "密码")
|
||||
@NotBlank(message="密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.sqx.modules.app.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 注册表单
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "注册表单")
|
||||
public class RegisterForm {
|
||||
@ApiModelProperty(value = "手机号")
|
||||
@NotBlank(message="手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "密码")
|
||||
@NotBlank(message="密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.sqx.modules.app.interceptor;
|
||||
|
||||
|
||||
import com.sqx.common.exception.SqxException;
|
||||
import com.sqx.common.utils.DateUtils;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import com.sqx.modules.app.service.UserService;
|
||||
import com.sqx.modules.app.utils.JwtUtils;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import com.sqx.modules.app.annotation.Login;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 权限(Token)验证
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
|
||||
@Autowired
|
||||
private JwtUtils jwtUtils;
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
public static final String USER_KEY = "userId";
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
Login annotation;
|
||||
if(handler instanceof HandlerMethod) {
|
||||
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(annotation == null){
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取用户凭证
|
||||
String token = request.getHeader(jwtUtils.getHeader());
|
||||
if(StringUtils.isBlank(token)){
|
||||
token = request.getParameter(jwtUtils.getHeader());
|
||||
}
|
||||
|
||||
//凭证为空
|
||||
if(StringUtils.isBlank(token)){
|
||||
throw new SqxException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
|
||||
Claims claims = jwtUtils.getClaimByToken(token);
|
||||
if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
|
||||
throw new SqxException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
|
||||
//设置userId到request里,后续根据userId,获取用户信息
|
||||
long userId = Long.parseLong(claims.getSubject());
|
||||
request.setAttribute(USER_KEY, userId);
|
||||
//记录用户最后一次调用接口的时间
|
||||
UserEntity userEntity=new UserEntity();
|
||||
userEntity.setUserId(userId);
|
||||
userEntity.setOnLineTime(DateUtils.format(new Date()));
|
||||
userService.updateById(userEntity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.sqx.modules.app.resolver;
|
||||
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import com.sqx.modules.app.interceptor.AuthorizationInterceptor;
|
||||
import com.sqx.modules.app.service.UserService;
|
||||
import com.sqx.modules.app.annotation.LoginUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* 有@LoginUser注解的方法参数,注入当前登录用户
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
|
||||
NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
|
||||
//获取用户ID
|
||||
Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
|
||||
if(object == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
UserEntity user = userService.getById((Long)object);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.sqx.modules.app.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class CourseOrderResponse implements Serializable {
|
||||
/**
|
||||
* 短剧名称
|
||||
*/
|
||||
private String coursename;
|
||||
/**
|
||||
* 售卖笔数
|
||||
*/
|
||||
private int coursenum;
|
||||
/**
|
||||
* 售卖金豆
|
||||
*/
|
||||
private Double coursemoney;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.sqx.modules.app.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 首页信息返回实体
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class HomeMessageResponse implements Serializable {
|
||||
/**
|
||||
* 总用户数
|
||||
*/
|
||||
private int totalUsers;
|
||||
/**
|
||||
*今日新增
|
||||
*/
|
||||
private int newToday;
|
||||
/**
|
||||
*本月新增
|
||||
*/
|
||||
private int newMonth;
|
||||
/**
|
||||
* 本年新增
|
||||
*/
|
||||
private int newYear;
|
||||
/**
|
||||
* 总收入
|
||||
*/
|
||||
private Double totalRevenue;
|
||||
/**
|
||||
* 今日收入
|
||||
*/
|
||||
private Double todayRevenue;
|
||||
/**
|
||||
* 本月收入
|
||||
*/
|
||||
private Double monthRevenue;
|
||||
/**
|
||||
* 本年收入
|
||||
*/
|
||||
private Double yearRevenue;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.sqx.modules.app.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserMessageResponse implements Serializable {
|
||||
/**
|
||||
* 总人数
|
||||
*/
|
||||
private int totalNumber;
|
||||
/**
|
||||
* 普通用户人数
|
||||
*/
|
||||
private int userNumber;
|
||||
/**
|
||||
* 会员人数
|
||||
*/
|
||||
private int vipUserNumber;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.modules.app.entity.App;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 升级
|
||||
*
|
||||
*/
|
||||
public interface AppService extends IService<App> {
|
||||
|
||||
App selectAppById(Long id);
|
||||
|
||||
int insertApp(App app);
|
||||
|
||||
int updateAppById(App app);
|
||||
|
||||
int deleteAppById(Long id);
|
||||
|
||||
List<App> selectNewApp();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
|
||||
import com.sqx.common.utils.Result;
|
||||
|
||||
public interface IAppleService {
|
||||
|
||||
Result getAppleUserInfo(String identityToken) throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.modules.app.entity.Msg;
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*
|
||||
*/
|
||||
public interface MsgService extends IService<Msg> {
|
||||
|
||||
Msg findByPhone(String phone);
|
||||
|
||||
Msg findByPhoneAndCode(String phone, String msg);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.UserMoneyDetails;
|
||||
|
||||
public interface UserMoneyDetailsService extends IService<UserMoneyDetails> {
|
||||
Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId,Long userId,Integer classify,Integer type);
|
||||
Double monthIncome(String date,Long userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.modules.app.entity.UserMoney;
|
||||
|
||||
public interface UserMoneyService extends IService<UserMoney> {
|
||||
|
||||
UserMoney selectUserMoneyByUserId(Long userId);
|
||||
|
||||
UserMoney selectSysUserMoneyByUserId(Long userId);
|
||||
|
||||
void updateMoney(int i, Long userId, double money);
|
||||
|
||||
void updateSysMoney(int i, Long userId, double money);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.common.utils.PageUtils;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
* @author fang
|
||||
* @date 2021/2/27
|
||||
*/
|
||||
public interface UserService extends IService<UserEntity> {
|
||||
|
||||
|
||||
Result authenticationRegister(JSONObject jsonObject, HttpServletRequest request);
|
||||
|
||||
|
||||
Result getNewUserRed(Long userId);
|
||||
|
||||
/**
|
||||
* 根据手机号查询用户
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return
|
||||
*/
|
||||
UserEntity queryByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 根据小程序微信openId查询用户
|
||||
*
|
||||
* @param openId 微信小程序openId
|
||||
* @return
|
||||
*/
|
||||
UserEntity queryByOpenId(String openId);
|
||||
|
||||
UserEntity queryByWxId(String wxId);
|
||||
|
||||
UserEntity queryByDyOpenId(String dyOpenId);
|
||||
|
||||
UserEntity queryByKsOpenId(String ksOpenId);
|
||||
|
||||
/**
|
||||
* 根据微信APP openId查询用户
|
||||
*
|
||||
* @param openId 微信APP openId
|
||||
* @return
|
||||
*/
|
||||
UserEntity queryByWxOpenId(String openId);
|
||||
|
||||
/**
|
||||
* 根据userId查询用户
|
||||
*
|
||||
* @param userId userId
|
||||
* @return
|
||||
*/
|
||||
UserEntity queryByUserId(Long userId);
|
||||
|
||||
UserEntity queryByInvitationCode(String invitationCode);
|
||||
|
||||
/**
|
||||
* 根据用户appleId查询用户
|
||||
* @param appleId
|
||||
* @return
|
||||
*/
|
||||
UserEntity queryByAppleId(String appleId);
|
||||
|
||||
|
||||
Result wxLogin(String code);
|
||||
|
||||
/**
|
||||
* 注册或更新用户信息
|
||||
*
|
||||
* @param userInfo1 用户信息
|
||||
* @return 用户信息
|
||||
*/
|
||||
Result wxRegister(UserEntity userInfo1);
|
||||
|
||||
Result dyLogin(String code,String anonymous_code);
|
||||
|
||||
Result dyRegister(UserEntity userInfo1);
|
||||
|
||||
Result ksLogin(String code);
|
||||
|
||||
Result ksRegister(UserEntity userInfo1);
|
||||
|
||||
/**
|
||||
* 注册或更新用户信息
|
||||
*
|
||||
* @param appleId 苹果账号id
|
||||
* @return 用户信息
|
||||
*/
|
||||
Result iosRegister(String appleId);
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @param state 验证码类型
|
||||
* @return
|
||||
*/
|
||||
Result sendMsg(String phone, String state,String pwd);
|
||||
|
||||
Result forgetPwd(String pwd, String phone, String msg);
|
||||
|
||||
/**
|
||||
* 绑定手机号
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @param code 验证码
|
||||
* @return
|
||||
*/
|
||||
Result wxBindMobile(String phone, String code, String wxOpenId, String token, String platform, Integer sysPhone,String inviterCode,String qdCode);
|
||||
|
||||
/**
|
||||
* @param phone
|
||||
* @param code
|
||||
* @param appleId
|
||||
* @param platform
|
||||
* @param sysPhone
|
||||
* @return
|
||||
*/
|
||||
Result iosBindMobile(String phone, String code, String appleId, String platform, Integer sysPhone,String inviterCode,String qdCode);
|
||||
|
||||
Result phoneLogin(String phone);
|
||||
|
||||
Result bindMobile(String phone,String platform, Integer sysPhone,String inviterCode,String qdCode);
|
||||
|
||||
|
||||
/**
|
||||
* 换绑手机号
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @param msg 验证码
|
||||
* @param userId 用户id
|
||||
* @return
|
||||
*/
|
||||
Result updatePhone(String phone, String msg, Long userId);
|
||||
|
||||
/**
|
||||
* 登录token
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return
|
||||
*/
|
||||
Result getResult(UserEntity user);
|
||||
|
||||
/**
|
||||
* app注册或h5注册
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @param msg 验证按
|
||||
* @param pwd 密码
|
||||
* @param platform 来源 app h5
|
||||
* @return
|
||||
*/
|
||||
Result registerCode(String phone, String msg, String platform, Integer sysPhone,String password,
|
||||
String inviterCode,String wxId,String qdCode);
|
||||
|
||||
Result bindWxOpenPhone(Long userId, String phone, String msg);
|
||||
|
||||
|
||||
Result wxAppLogin(String wxOpenId, String token);
|
||||
|
||||
|
||||
/**
|
||||
* app或h5登录
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @param pwd 密码
|
||||
* @return
|
||||
*/
|
||||
Result login(String phone, String pwd);
|
||||
|
||||
|
||||
/**
|
||||
* 根据 code 获取openId
|
||||
*
|
||||
* @param code
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Result getOpenId(String code, Long userId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return
|
||||
*/
|
||||
UserEntity selectUserById(Long userId);
|
||||
|
||||
void pushToSingle(String title, String content, String clientId);
|
||||
|
||||
PageUtils selectUserPage(Integer page, Integer limit,String phone,Integer sex,String platform,String sysPhone,Integer status,
|
||||
Integer member, String inviterCode, String userName, String invitationCode, String startTime,
|
||||
String endTime,String qdCode,String sysUserName,Integer vipType);
|
||||
|
||||
List<UserEntity> userListExcel(String startTime, String endTime, UserEntity userEntity);
|
||||
|
||||
int queryInviterCount(String inviterCode);
|
||||
|
||||
int queryUserCount(int type,String date,String platform,String qdCode);
|
||||
|
||||
Double queryPayMoney(int type,String qdCode);
|
||||
|
||||
IPage<Map<String, Object>> queryCourseOrder(Page<Map<String, Object>> iPage, int type, String date,Long sysUserId);
|
||||
|
||||
int userMessage( String date, int type,String qdCode,Integer vipType);
|
||||
|
||||
|
||||
Result selectInviteUserList(Integer page,Integer limit,String userName,String phone);
|
||||
|
||||
Result loginByOpenId(String openId);
|
||||
|
||||
Result selectUserOnLineCount(String qdCode);
|
||||
|
||||
int updateUserClientIdIsNull(String clientid);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.modules.app.entity.UserVip;
|
||||
|
||||
public interface UserVipService extends IService<UserVip> {
|
||||
|
||||
UserVip selectUserVipByUserId(Long userId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sqx.modules.app.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.entity.VipDetails;
|
||||
|
||||
public interface VipDetailsService extends IService<VipDetails> {
|
||||
/**
|
||||
* 查询会员的详情信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Result selectVipDetails();
|
||||
|
||||
/**
|
||||
* 添加会员的详情信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Result insertVipDetails(VipDetails vipDetails);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.sqx.modules.app.service.impl;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sqx.modules.app.dao.AppDao;
|
||||
import com.sqx.modules.app.entity.App;
|
||||
import com.sqx.modules.app.service.AppService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Service("AppService")
|
||||
public class AppServiceImpl extends ServiceImpl<AppDao, App> implements AppService {
|
||||
|
||||
@Autowired
|
||||
private AppDao appDao;
|
||||
|
||||
|
||||
@Override
|
||||
public App selectAppById(Long id) {
|
||||
return appDao.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertApp(App app) {
|
||||
return appDao.insert(app);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateAppById(App app) {
|
||||
return appDao.updateById(app);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteAppById(Long id) {
|
||||
return appDao.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<App> selectNewApp() {
|
||||
return appDao.selectNewApp();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package com.sqx.modules.app.service.impl;
|
||||
|
||||
|
||||
import com.auth0.jwk.Jwk;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.service.IAppleService;
|
||||
import io.jsonwebtoken.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.json.JSONArray;
|
||||
import net.sf.json.JSONObject;
|
||||
import org.apache.tomcat.util.codec.binary.Base64;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* @Description 苹果登录service
|
||||
* @author fang
|
||||
* @date 2020/11/4
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AppleServiceImpl implements IAppleService {
|
||||
|
||||
@Override
|
||||
public Result getAppleUserInfo(String identityToken) throws Exception {
|
||||
//验证identityToken
|
||||
if (!verify(identityToken)) {
|
||||
log.error("苹果解析失败!");
|
||||
return Result.error("苹果账号验证失败,请退出重试!");
|
||||
}
|
||||
//对identityToken解码
|
||||
JSONObject json = parserIdentityToken(identityToken);
|
||||
if (json == null) {
|
||||
return Result.error("苹果账号验证失败,请退出重试!");
|
||||
}
|
||||
String appleUserId = String.valueOf(json.get("sub"));
|
||||
log.error("苹果账号解析成功:"+appleUserId);
|
||||
System.err.println(appleUserId);
|
||||
return Result.success().put("data",appleUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对前端传来的JWT字符串identityToken的第二部分进行解码
|
||||
* 主要获取其中的aud和sub,aud大概对应ios前端的包名,sub大概对应当前用户的授权的openID
|
||||
*
|
||||
* @param identityToken 身份token
|
||||
* @return {"aud":"com.xkj.****","sub":"000***.8da764d3f9e34d2183e8da08a1057***.0***","c_hash":"UsKAuEoI-****","email_verified":"true","auth_time":1574673481,"iss":"https://appleid.apple.com","exp":1574674081,"iat":1574673481,"email":"****@qq.com"}
|
||||
*/
|
||||
private JSONObject parserIdentityToken(String identityToken) {
|
||||
String[] arr = identityToken.split("\\.");
|
||||
String decode = new String(Base64.decodeBase64(arr[1]));
|
||||
String substring = decode.substring(0, decode.indexOf("}") + 1);
|
||||
return JSONObject.fromObject(substring);
|
||||
}
|
||||
|
||||
|
||||
public Boolean verify(String jwt) throws Exception {
|
||||
JSONArray arr = getAuthKeys();
|
||||
if (arr == null) {
|
||||
log.error("获取不到苹果的验证秘钥!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
JSONObject authKey = null;
|
||||
//先取苹果第一个key进行校验
|
||||
if(arr.size()==2){
|
||||
authKey = JSONObject.fromObject(arr.getString(0));
|
||||
if (verifyExc(jwt, authKey)) {
|
||||
log.error("苹果解析成功!1");
|
||||
return true;
|
||||
} else {
|
||||
//再取第二个key校验
|
||||
authKey = JSONObject.fromObject(arr.getString(1));
|
||||
return verifyExc(jwt, authKey);
|
||||
}
|
||||
}else{
|
||||
authKey = JSONObject.fromObject(arr.getString(0));
|
||||
if (verifyExc(jwt, authKey)) {
|
||||
log.error("苹果解析成功!1");
|
||||
return true;
|
||||
}
|
||||
//再取第二个key校验
|
||||
authKey = JSONObject.fromObject(arr.getString(1));
|
||||
if(verifyExc(jwt, authKey)){
|
||||
log.error("苹果解析成功!2");
|
||||
return true;
|
||||
}else{
|
||||
authKey = JSONObject.fromObject(arr.getString(2));
|
||||
return verifyExc(jwt, authKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对前端传来的identityToken进行验证
|
||||
*
|
||||
* @param jwt 对应前端传来的 identityToken
|
||||
* @param authKey 苹果的公钥 authKey
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Boolean verifyExc(String jwt, JSONObject authKey) throws Exception {
|
||||
|
||||
Jwk jwa = Jwk.fromValues(authKey);
|
||||
PublicKey publicKey = jwa.getPublicKey();
|
||||
|
||||
String aud = "";
|
||||
String sub = "";
|
||||
if (jwt.split("\\.").length > 1) {
|
||||
String claim = new String(Base64.decodeBase64(jwt.split("\\.")[1]));
|
||||
aud = JSONObject.fromObject(claim).get("aud").toString();
|
||||
sub = JSONObject.fromObject(claim).get("sub").toString();
|
||||
}
|
||||
JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
|
||||
jwtParser.requireIssuer("https://appleid.apple.com");
|
||||
jwtParser.requireAudience(aud);
|
||||
jwtParser.requireSubject(sub);
|
||||
|
||||
try {
|
||||
Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
|
||||
if (claim != null && claim.getBody().containsKey("auth_time")) {
|
||||
System.out.println(claim);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (ExpiredJwtException e) {
|
||||
log.error("[AppleServiceImpl.verifyExc] [error] [apple identityToken expired]", e);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("[AppleServiceImpl.verifyExc] [error] [apple identityToken illegal]", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取苹果的公钥
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static JSONArray getAuthKeys() {
|
||||
String url = "https://appleid.apple.com/auth/keys";
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
JSONObject json = restTemplate.getForObject(url, JSONObject.class);
|
||||
if (json != null) {
|
||||
return json.getJSONArray("keys");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.sqx.modules.app.service.impl;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sqx.modules.app.dao.MsgDao;
|
||||
import com.sqx.modules.app.entity.Msg;
|
||||
import com.sqx.modules.app.service.MsgService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service("MsgService")
|
||||
public class MsgServiceImpl extends ServiceImpl<MsgDao, Msg> implements MsgService {
|
||||
|
||||
@Autowired
|
||||
private MsgDao msgDao;
|
||||
|
||||
@Override
|
||||
public Msg findByPhone(String phone){
|
||||
return msgDao.findByPhone(phone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Msg findByPhoneAndCode(String phone, String msg){
|
||||
return msgDao.findByPhoneAndCode(phone,msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.sqx.modules.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sqx.common.utils.Result;
|
||||
import com.sqx.modules.app.dao.UserMoneyDetailsDao;
|
||||
import com.sqx.modules.app.entity.UserMoneyDetails;
|
||||
import com.sqx.modules.app.service.UserMoneyDetailsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserMoneyDetailsServiceImpl extends ServiceImpl<UserMoneyDetailsDao, UserMoneyDetails> implements UserMoneyDetailsService {
|
||||
|
||||
@Override
|
||||
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId,Long userId,Integer classify,Integer type) {
|
||||
IPage<UserMoneyDetails> page1 = new Page(page, limit);
|
||||
QueryWrapper<UserMoneyDetails> queryWrapper = new QueryWrapper();
|
||||
if(sysUserId!=null){
|
||||
queryWrapper.eq("sys_user_id", sysUserId);
|
||||
}
|
||||
if(userId!=null){
|
||||
queryWrapper.eq("user_id", userId);
|
||||
}
|
||||
if(classify!=null){
|
||||
queryWrapper.eq("classify", classify);
|
||||
}
|
||||
if(type!=null){
|
||||
queryWrapper.eq("type", type);
|
||||
}
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
return Result.success().put("data", baseMapper.selectPage(page1, queryWrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double monthIncome(String date, Long userId) {
|
||||
return baseMapper.monthIncome(date,userId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.sqx.modules.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sqx.modules.app.dao.UserMoneyDao;
|
||||
import com.sqx.modules.app.entity.UserMoney;
|
||||
import com.sqx.modules.app.service.UserMoneyService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class UserMoneyServiceImpl extends ServiceImpl<UserMoneyDao, UserMoney> implements UserMoneyService {
|
||||
|
||||
@Override
|
||||
public void updateMoney(int i, Long userId, double money){
|
||||
selectUserMoneyByUserId(userId);
|
||||
baseMapper.updateMayMoney(i,userId,money);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSysMoney(int i, Long userId, double money){
|
||||
selectSysUserMoneyByUserId(userId);
|
||||
baseMapper.updateSysMoney(i,userId,money);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserMoney selectUserMoneyByUserId(Long userId){
|
||||
UserMoney userMoney = baseMapper.selectOne(new QueryWrapper<UserMoney>().eq("user_id", userId));
|
||||
if(userMoney==null){
|
||||
userMoney=new UserMoney();
|
||||
userMoney.setUserId(userId);
|
||||
userMoney.setMoney(new BigDecimal("0.00"));
|
||||
baseMapper.insert(userMoney);
|
||||
}
|
||||
return userMoney;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserMoney selectSysUserMoneyByUserId(Long userId){
|
||||
UserMoney userMoney = baseMapper.selectOne(new QueryWrapper<UserMoney>().eq("sys_user_id", userId));
|
||||
if(userMoney==null){
|
||||
userMoney=new UserMoney();
|
||||
userMoney.setSysUserId(userId);
|
||||
userMoney.setMoney(new BigDecimal("0.00"));
|
||||
baseMapper.insert(userMoney);
|
||||
}
|
||||
return userMoney;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,25 @@
|
|||
package com.sqx.modules.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sqx.modules.app.dao.UserVipDao;
|
||||
import com.sqx.modules.app.entity.UserVip;
|
||||
import com.sqx.modules.app.service.UserVipService;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> implements UserVipService {
|
||||
|
||||
@Override
|
||||
public UserVip selectUserVipByUserId(Long userId) {
|
||||
QueryWrapper<UserVip> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("user_id",userId);
|
||||
return baseMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Scheduled(cron="0 */1 * * * ?")
|
||||
public void getEndVip() {
|
||||
baseMapper.updateUserVipByEndTime();
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue