forked from gitee/vben-java
Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# 项目排除路径
|
||||
/vboot-application/target/
|
||||
/vboot-core/target/
|
||||
/vboot-extend-bi/target/
|
||||
/vboot-extend-wf/target/
|
||||
@@ -0,0 +1,3 @@
|
||||
- **初始化项目 V0.1**
|
||||
|
||||
- [更新] README.md、项目介绍
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 vboot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,81 @@
|
||||
<div align="center"><h1 align="center">vboot-net</h1></div>
|
||||
<div align="center"><h3 align="center">一个开箱即用的快速开发平台.JAVA版</h3></div>
|
||||
|
||||
### 🍟 概述
|
||||
|
||||
* 基于JAVA实现的快速开发平台。模块化插件式开发,前后端分离,开箱即用。
|
||||
* 后台基于SpringBoot框架,数据库访问使用Jpa,自动生成数据库表结构。
|
||||
* 前端基于Vben-Admin vxe-table框架。
|
||||
* 核心模块包括:部门、用户、岗位、群组、角色、菜单、字典、日志、文件管理、定时任务等功能。
|
||||
* QQ交流群:[795417789] 暂时就几个人哦,哈哈
|
||||
* .NET6实现的同功能项目地址[https://gitee.com/zsvg/vboot-net](https://gitee.com/zsvg/vboot-net) 两个项目会同步开发
|
||||
```
|
||||
如果对您有帮助,点击右上角⭐Star⭐关注 ,感谢支持开源!
|
||||
```
|
||||
|
||||
### 🎁 前后端一体化
|
||||
|
||||
将后台提供的Swagger接口直接生成对应前端的API文件,前端再也不需要手撸一个个的对应后后的API定义了。后台接口更新后,只需要重新生成一遍覆盖即可。
|
||||
|
||||
### 🥞 更新日志
|
||||
|
||||
更新日志 [点击查看](https://gitee.com/zsvg/vboot-java/CHANGELOG.md)
|
||||
|
||||
### 🍄 快速启动
|
||||
* 准备工作:1.配置一个名为vboot-java的mysql数据库,默认账号root,密码123456(可改) 2.开启redis 可不设置密码
|
||||
* 启动后台:打开项目,找到application启动类启动运行
|
||||
* 启动前端方式1:前端vbenAdmin已将Build后的代码放在JAVA项目里,会随着后台启动而启动,可直接访问 `http://localhost:5000/vben.html` 预览
|
||||
* 启动前端方式2:下载配套的前端UI[https://gitee.com/zsvg/vboot-vben](https://gitee.com/zsvg/vboot-vben)使用yarn构建,访问 `http://localhost:3100` 预览
|
||||
|
||||
### 🏀 分层说明
|
||||
```
|
||||
├─vboot-application ->业务应用层,在此写您具体业务代码
|
||||
├─vboot-core ->框架核心层
|
||||
├─vboot-extend-bi ->BI(报表与数据抽取),近期在开发中,以单独一个模块方式维护
|
||||
├─vboot-extend-wf ->WF(工作流),近期在开发中,以单独一个模块方式维护
|
||||
注:源码直接开发建议自己的业务代码直接写在【vboot-application】层里面,可随框架升级减少冲突。
|
||||
```
|
||||
|
||||
### 📖 帮助文档
|
||||
|
||||
👉后台文档:
|
||||
* SpringBoot后台框架文档 [https://spring.io/projects/spring-boot](https://spring.io/projects/spring-boot)
|
||||
|
||||
👉前端文档:
|
||||
* VbenAdmin前端业务文档 [https://vvbin.cn/next/](https://vvbin.cn/next/)
|
||||
|
||||
|
||||
### 🍖 详细功能
|
||||
|
||||
1. 主控面板、控制台页面,可进行工作台,分析页,统计等功能的展示。
|
||||
2. 部门管理、部门维护,支持多层级结构的树形结构。
|
||||
3. 用户管理、用户维护,可设置用户部门,岗位,群组,职务,角色,数据权限等。
|
||||
4. 岗位管理、岗位维护,岗位可作为用户的一个标签,岗位也可与权限等其他功能挂钩。
|
||||
5. 群组管理、群组维护,群组可设置部门,用户,岗位,用于更广泛的权限设置。
|
||||
6. 菜单管理、菜单目录,菜单,和按钮的维护是权限控制的基本单位。
|
||||
7. 角色管理、角色绑定菜单后,可限制相关角色的人员登录系统的功能范围。
|
||||
8. 字典管理、系统内各种枚举类型的维护。
|
||||
9. 访问日志、用户的登录和退出日志的查看和管理。
|
||||
10. 操作日志、用户的操作业务的日志的查看和管理。
|
||||
11. 定时任务、定时任务的维护,通过cron表达式控制任务的执行频率。
|
||||
|
||||
### ⚡ 近期计划
|
||||
|
||||
- [ ] 文档编写
|
||||
- [ ] 在线用户
|
||||
- [ ] 文件存储 minio
|
||||
- [ ] 集成工作流
|
||||
|
||||
|
||||
### 🍻 贡献代码
|
||||
|
||||
`vboot-java` 遵循 `MIT` 开源协议,欢迎大家提交 `PR` 或 `Issue`。
|
||||
|
||||
|
||||
### 💐 特别鸣谢
|
||||
- 👉 eladmin:[https://gitee.com/elunez/eladmin](https://gitee.com/elunez/eladmin)
|
||||
- 👉 ruoyi:[https://gitee.com/y_project/RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)
|
||||
- 👉 vben-admin:[https://vvbin.cn/doc-next/](https://vvbin.cn/doc-next/)
|
||||
- 👉 vxe-table:[https://gitee.com/xuliangzhan_admin/vxe-table](https://gitee.com/xuliangzhan_admin/vxe-table)
|
||||
|
||||
如果对您有帮助,您可以点右上角 💘Star💘支持一下,这样我们才有持续下去的动力,谢谢!!!
|
||||
@@ -0,0 +1,84 @@
|
||||
<?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.zsvg</groupId>
|
||||
<artifactId>vboot</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>0.1</version>
|
||||
<modules>
|
||||
<module>vboot-core</module>
|
||||
<module>vboot-application</module>
|
||||
<module>vboot-extend-bi</module>
|
||||
<module>vboot-extend-wf</module>
|
||||
</modules>
|
||||
|
||||
<!--定义属性值-->
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<vboot.version>0.1</vboot.version>
|
||||
<spring.boot.version>2.2.13.RELEASE</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringBoot的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<!--编译管理 jdk版本和字符集编码-->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!--Maven远程仓库设置 非必要,可以删除-->
|
||||
<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>
|
||||
</repositories>
|
||||
|
||||
<!--Maven远程插件库设置 非必要,可以删除-->
|
||||
<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,61 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<artifactId>vboot</artifactId>
|
||||
<groupId>com.zsvg</groupId>
|
||||
<version>0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>vboot-application</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.zsvg</groupId>
|
||||
<artifactId>vboot-extend-bi</artifactId>
|
||||
<version>${vboot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zsvg</groupId>
|
||||
<artifactId>vboot-extend-wf</artifactId>
|
||||
<version>${vboot.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.zsvg</groupId>
|
||||
<artifactId>vboot-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- 打包 -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.abc;
|
||||
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import com.zsvg.vboot.common.util.web.XspringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@EnableCaching
|
||||
@SpringBootApplication
|
||||
@EntityScan({"com.zsvg","com.abc"})
|
||||
@ComponentScan({"com.zsvg","com.abc"})
|
||||
@EnableJpaRepositories({"com.zsvg","com.abc"})
|
||||
@Slf4j
|
||||
//@EnableSwagger2
|
||||
//@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60)
|
||||
public class Application {// extends SpringBootServletInitializer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ApplicationContext app = SpringApplication.run(Application.class, args);
|
||||
String[] beanDefinitionNames = app.getBeanDefinitionNames();
|
||||
for (int i = 0; i < beanDefinitionNames.length; i++) {
|
||||
// System.out.println(beanDefinitionNames[i]);
|
||||
}
|
||||
XspringUtil.setApplicationContext(app);
|
||||
Environment env = app.getEnvironment();
|
||||
String ip = null;
|
||||
try {
|
||||
ip = InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String port = env.getProperty("server.port");
|
||||
String path = env.getProperty("server.servlet.context-path");
|
||||
if (XstringUtil.isBlank(path)) {
|
||||
path = "";
|
||||
}
|
||||
log.info("\n----------------------------------------------------------\n\t" +
|
||||
"Application is running! Access URLs:\n\t" +
|
||||
"Local访问网址: \t\thttp://localhost:" + port + path +"/vben.html"+ "\n\t" +
|
||||
"External访问网址: \thttp://" + ip + ":" + port + path +"/vben.html"+ "\n\t");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.abc.demo;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.api.RestResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("demo")
|
||||
public class DemoApi {
|
||||
|
||||
@GetMapping
|
||||
public RestResult get() {
|
||||
return RestResult.ok("这里可写实际业务模块");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
ldap.url=
|
||||
ldap.base=
|
||||
ldap.userDn=
|
||||
ldap.userPwd=
|
||||
ldap.referral=
|
||||
ldap.domainName=
|
||||
|
||||
#web\u914D\u7F6E
|
||||
server.port=5000
|
||||
spring.servlet.multipart.max-file-size=1024
|
||||
spring.servlet.multipart.max-request-size=1024
|
||||
server.compression.enabled=true
|
||||
server.compression.mime-types=application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css
|
||||
server.compression.min-response-size=4096
|
||||
|
||||
|
||||
app.db.type=MYSQL
|
||||
app.att.path=D:/zsvg/att
|
||||
#1代表session,2待办jwt token,4待办蓝凌token
|
||||
app.authc.type=7
|
||||
|
||||
|
||||
#\u6700\u5927\u8FDE\u63A5\u6570
|
||||
http.maxTotal: 100
|
||||
http.defaultMaxPerRoute: 20
|
||||
http.connectTimeout: 1000
|
||||
http.connectionRequestTimeout: 500
|
||||
http.socketTimeout: 10000
|
||||
http.staleConnectionCheckEnabled: true
|
||||
http.validateAfterInactivity: 3000000
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
druid:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: 1
|
||||
login-password: 1
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 5000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
# driver-class-name: com.mysql.jdbc.Driver
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/vboot-java?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&nullCatalogMeansCurrent=true
|
||||
username: root
|
||||
password: 123456
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
open-in-view: true
|
||||
banner:
|
||||
location: classpath:config/banner.txt
|
||||
jackson:
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
time-zone: GMT+8
|
||||
|
||||
ldap:
|
||||
url:
|
||||
base:
|
||||
userDn:
|
||||
userPwd:
|
||||
referral:
|
||||
domainName:
|
||||
|
||||
|
||||
logging.config: classpath:config/logback.xml
|
||||
|
||||
|
||||
zsvg:
|
||||
jwt:
|
||||
header: Authorization
|
||||
prefix: "Bearer "
|
||||
#生成accessToken用的key
|
||||
akey: 6EtRVaDRFyIe5pBlBh1p6dRD+fLA5phPMyEeVkaNcEMUcpvQwZtGNby24TzuTZ4OBuXTYUaWgZqsRwROg1XWFA==
|
||||
#生成refreshToken用的key
|
||||
rkey: W3UZyVu0VQCGMRPvU11CqDovDUku3XASJlXLu0zFZdvUyAvXoEVrumKnz1DSBJ4O5l49Mi2Hesx7Kct4UPTL9g==
|
||||
#accessToken过期时间 此处单位秒 ,默认8小时 28800
|
||||
atime: 28800
|
||||
#accessToken过期时间 此处单位秒 ,默认30天 3456000
|
||||
rtime: 3456000
|
||||
# # 在线用户key
|
||||
# online-key: online-token-
|
||||
# # 验证码
|
||||
# code-key: code-key-
|
||||
# # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
# detect: 1800000
|
||||
# # 续期时间范围,默认1小时,单位毫秒
|
||||
# renew: 3600000
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
${AnsiColor.GREEN}
|
||||
|
||||
vboot V0.1 一个开箱即用的快速开发平台.JAVA版
|
||||
|
||||
${AnsiColor.GREEN}
|
||||
${spring-boot.version}
|
||||
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
|
||||
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
|
||||
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
|
||||
当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
|
||||
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
|
||||
<configuration scan="true" scanPeriod="10 seconds">
|
||||
<contextName>logback</contextName>
|
||||
|
||||
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 -->
|
||||
<property name="log.path" value="D:/zsvg/logs" />
|
||||
|
||||
<!--0. 日志格式和颜色渲染 -->
|
||||
<!-- 彩色日志依赖的渲染类 -->
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
||||
<!-- 彩色日志格式 -->
|
||||
<!--<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>-->
|
||||
|
||||
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
|
||||
|
||||
<!--1. 输出到控制台-->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>debug</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
|
||||
<!-- 设置字符集 -->
|
||||
<!--<charset>UTF-8</charset>-->
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--2. 输出到文档-->
|
||||
<!-- 2.1 level为 DEBUG 日志,时间滚动输出 -->
|
||||
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文档的路径及文档名 -->
|
||||
<file>${log.path}/web_debug.log</file>
|
||||
<!--日志文档输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>UTF-8</charset> <!-- 设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志归档 -->
|
||||
<fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文档保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文档只记录debug级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>debug</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 2.2 level为 INFO 日志,时间滚动输出 -->
|
||||
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文档的路径及文档名 -->
|
||||
<file>${log.path}/web_info.log</file>
|
||||
<!--日志文档输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 每天日志归档路径以及格式 -->
|
||||
<fileNamePattern>${log.path}/web-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文档保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文档只记录info级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>info</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 2.3 level为 WARN 日志,时间滚动输出 -->
|
||||
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文档的路径及文档名 -->
|
||||
<file>${log.path}/web_warn.log</file>
|
||||
<!--日志文档输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/web-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文档保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文档只记录warn级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>warn</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 2.4 level为 ERROR 日志,时间滚动输出 -->
|
||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文档的路径及文档名 -->
|
||||
<file>${log.path}/web_error.log</file>
|
||||
<!--日志文档输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文档保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文档只记录ERROR级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!--
|
||||
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
|
||||
以及指定<appender>。<logger>仅有一个name属性,
|
||||
一个可选的level和一个可选的addtivity属性。
|
||||
name:用来指定受此logger约束的某一个包或者具体的某一个类。
|
||||
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
|
||||
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
|
||||
如果未设置此属性,那么当前logger将会继承上级的级别。
|
||||
addtivity:是否向上级logger传递打印信息。默认是true。
|
||||
<logger name="org.springframework.web" level="info"/>
|
||||
<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
|
||||
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
|
||||
第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
|
||||
【logging.level.org.mybatis=debug logging.level.dao=debug】
|
||||
-->
|
||||
|
||||
<!--
|
||||
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
|
||||
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
|
||||
不能设置为INHERITED或者同义词NULL。默认是DEBUG
|
||||
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
|
||||
-->
|
||||
<!--<springProfile name="dev">-->
|
||||
<!--<logger name="logging.level.org.hibernate" level="error"/>-->
|
||||
<!--</springProfile>-->
|
||||
|
||||
<!-- 4. 最终的策略 -->
|
||||
<!-- 4.1 开发环境:打印控制台-->
|
||||
<logger name="com.abc" level="debug" additivity="false">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
<appender-ref ref="INFO_FILE"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.zsvg" level="debug" additivity="false">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
<appender-ref ref="INFO_FILE"/>
|
||||
</logger>
|
||||
|
||||
<root level="warn">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
<appender-ref ref="DEBUG_FILE" />
|
||||
<appender-ref ref="INFO_FILE" />
|
||||
<appender-ref ref="WARN_FILE" />
|
||||
<appender-ref ref="ERROR_FILE" />
|
||||
</root>
|
||||
|
||||
<!--4.2 生产环境:输出到文档-->
|
||||
<!--<logger name="com.abc" level="info" additivity="true">-->
|
||||
<!--<appender-ref ref="CONSOLE"/>-->
|
||||
<!--<appender-ref ref="INFO_FILE"/>-->
|
||||
<!--</logger>-->
|
||||
|
||||
<!--<root level="warn">-->
|
||||
<!--<appender-ref ref="WARN_FILE" />-->
|
||||
<!--<appender-ref ref="ERROR_FILE" />-->
|
||||
<!--</root>-->
|
||||
|
||||
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,16 @@
|
||||
#sap\u6D4B\u8BD5\u673A
|
||||
jco.client.client=800
|
||||
jco.client.user=xxxx
|
||||
jco.client.passwd=xxxxx
|
||||
jco.client.lang=zh
|
||||
jco.client.ashost=10.10.10.10
|
||||
jco.client.sysnr=00
|
||||
|
||||
|
||||
#jco.client.pool_capacity=30
|
||||
#jco.client.peak_limit=150
|
||||
|
||||
|
||||
|
||||
#jco.client.pool_capacity=30
|
||||
#jco.client.peak_limit=150
|
||||
@@ -0,0 +1,278 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<artifactId>vboot</artifactId>
|
||||
<groupId>com.zsvg</groupId>
|
||||
<version>0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>vboot-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.2.8</version>
|
||||
</dependency>
|
||||
|
||||
<!--测试相关开始-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.databene</groupId>
|
||||
<artifactId>contiperf</artifactId>
|
||||
<version>2.3.4</version>
|
||||
<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-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--数据库相关开始-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-ldap</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.26</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--数据库相关结束-->
|
||||
|
||||
<!--可用DATA注解自动生成get set toString等,idea需要插件支持-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--图片压缩-->
|
||||
<dependency>
|
||||
<groupId>net.coobird</groupId>
|
||||
<artifactId>thumbnailator</artifactId>
|
||||
<version>0.4.8</version>
|
||||
</dependency>
|
||||
|
||||
<!--自动生成API文档开始-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<!--自动生成API文档结束-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--AUTH权限相关开始-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!--AUTH权限相关结束-->
|
||||
|
||||
<!--定时调度开始-->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<!--定时调度结束-->
|
||||
|
||||
|
||||
<!--消息机制开始-->
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<!--消息机制结束-->
|
||||
|
||||
<!--word,excel处理开始-->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<!--word,excel处理结束-->
|
||||
|
||||
<!--浏览器客户端识别开始-->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
<!--浏览器客户端识别结束-->
|
||||
|
||||
<!--服务器监控开始-->
|
||||
<dependency>
|
||||
<groupId>ch.ethz.ganymed</groupId>
|
||||
<artifactId>ganymed-ssh2</artifactId>
|
||||
<version>262</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.snmp4j</groupId>
|
||||
<artifactId>snmp4j</artifactId>
|
||||
<version>2.6.2</version>
|
||||
</dependency>
|
||||
<!--服务器监控结束-->
|
||||
|
||||
<!--json包开始-->
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.2.3</version>
|
||||
<classifier>jdk15</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.58</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.6</version>
|
||||
</dependency>
|
||||
<!--json包结束-->
|
||||
|
||||
<!--二维码-->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--pdf水印-->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itextpdf</artifactId>
|
||||
<version>5.5.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itext-asian</artifactId>
|
||||
<version>5.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--webservice-->
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
|
||||
<version>3.2.7</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>0.11.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>0.11.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>0.11.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
<version>1.7.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 解析客户端操作系统、浏览器信息 -->
|
||||
<dependency>
|
||||
<groupId>nl.basjes.parse.useragent</groupId>
|
||||
<artifactId>yauaa</artifactId>
|
||||
<version>5.23</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.zsvg.vboot.common.mvc.api;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PageData {
|
||||
|
||||
private Integer total;
|
||||
|
||||
private Object items;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.zsvg.vboot.common.mvc.api;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class RestResult extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String CODE_TAG = "code";
|
||||
|
||||
public static final String MSG_TAG = "message";
|
||||
|
||||
public static final String DATA_TAG = "result";
|
||||
|
||||
public RestResult() {
|
||||
|
||||
}
|
||||
|
||||
public RestResult(int code, String msg) {
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
}
|
||||
|
||||
public RestResult(int code, String msg, Object data) {
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
super.put(DATA_TAG, data);
|
||||
}
|
||||
|
||||
public static RestResult ok() {
|
||||
return RestResult.ok("操作成功");
|
||||
}
|
||||
|
||||
public static RestResult ok(Object data) {
|
||||
return RestResult.ok("操作成功", data);
|
||||
}
|
||||
|
||||
public static RestResult ok(String msg, Object data) {
|
||||
return new RestResult(0, msg, data);
|
||||
}
|
||||
|
||||
public static RestResult error(Object data) {
|
||||
return RestResult.error("操作失败", data);
|
||||
}
|
||||
|
||||
public static RestResult error(String msg, Object data) {
|
||||
return new RestResult(500, msg, data);
|
||||
}
|
||||
|
||||
public static RestResult build(int code, String msg) {
|
||||
return new RestResult(code, msg, null);
|
||||
}
|
||||
|
||||
public static RestResult build(int code, String msg, Object data) {
|
||||
return new RestResult(code, msg, data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public abstract class BaseSqler {
|
||||
|
||||
public abstract String getSql() throws SQLException;
|
||||
|
||||
|
||||
public abstract Object[] getParams();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class CacheDao<T> {
|
||||
|
||||
private RedisTemplate<String, T> redisTemplate;
|
||||
|
||||
@Autowired
|
||||
public CacheDao(RedisTemplate<String, T> redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
|
||||
//============================String=============================
|
||||
|
||||
/**
|
||||
* 普通缓存获取
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public T getCache(String key) {
|
||||
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean setCache(String key, T value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean setCache(String key, T value, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
setCache(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HashGet
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return 值
|
||||
*/
|
||||
public Object getHashCache(String key, String item) {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取hashKey对应的所有键值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 对应的多个键值
|
||||
*/
|
||||
public Map<Object, Object> getHashCache(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @return true 成功 false 失败
|
||||
*/
|
||||
public boolean setHashCache(String key, Map<String, T> map) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * HashSet 并设置时间
|
||||
// *
|
||||
// * @param key 键
|
||||
// * @param map 对应多个键值
|
||||
// * @param time 时间(秒)
|
||||
// * @return true成功 false失败
|
||||
// */
|
||||
// public boolean setHashCache(String key, Map<String, T> map, long time) {
|
||||
// try {
|
||||
// redisTemplate.opsForHash().putAll(key, map);
|
||||
// if (time > 0) {
|
||||
// setExpireTime(key, time);
|
||||
// }
|
||||
// return true;
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean setHashCache(String key, String item, T value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 向一张hash表中放入数据,如果不存在将创建
|
||||
// *
|
||||
// * @param key 键
|
||||
// * @param hashKey 项
|
||||
// * @param value 值
|
||||
// * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||
// * @return true 成功 false失败
|
||||
// */
|
||||
// public boolean setHashCache(String key, String hashKey, T value, long time) {
|
||||
// try {
|
||||
// redisTemplate.opsForHash().put(key, hashKey, value);
|
||||
// if (time > 0) {
|
||||
// setExpireTime(key, time);
|
||||
// }
|
||||
// return true;
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Dsqler extends BaseSqler{
|
||||
private String deleteClause = "";
|
||||
private String whereClause = "";
|
||||
private List<Object> whereParameters = new ArrayList<Object>();
|
||||
|
||||
|
||||
public Dsqler(String table)
|
||||
{
|
||||
this.deleteClause = "DELETE FROM " + table + " ";
|
||||
}
|
||||
|
||||
|
||||
public Dsqler addWhere(String condition, Object... params)
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + condition;
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + condition;
|
||||
}
|
||||
if (params != null && params.length > 0)
|
||||
{
|
||||
for (Object obj : params)
|
||||
{
|
||||
whereParameters.add(obj);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSql() throws SQLException {
|
||||
if("".equals(whereClause)){
|
||||
throw new SQLException("为防止误删,delete 语句必须要有where条件");
|
||||
}
|
||||
return deleteClause + whereClause;
|
||||
}
|
||||
|
||||
public Object[] getParams()
|
||||
{
|
||||
return whereParameters.toArray();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Isqler extends BaseSqler
|
||||
{
|
||||
private String insertClause = "";
|
||||
private String keyClause = "";
|
||||
private String valueClause = "";
|
||||
private List<Object> parameters = new ArrayList<Object>();
|
||||
|
||||
public Isqler(String table)
|
||||
{
|
||||
this.insertClause = "INSERT INTO " + table;
|
||||
}
|
||||
|
||||
public Isqler add(String key, Object value)
|
||||
{
|
||||
if ("true".equals(value))
|
||||
{
|
||||
keyClause += key + ",";
|
||||
valueClause += "?,";
|
||||
parameters.add(true);
|
||||
} else if ("false".equals(value))
|
||||
{
|
||||
keyClause += key + ",";
|
||||
valueClause += "?,";
|
||||
parameters.add(false);
|
||||
} else
|
||||
{
|
||||
keyClause += key + ",";
|
||||
valueClause += "?,";
|
||||
parameters.add(value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSql()
|
||||
{
|
||||
return insertClause + "(" + keyClause.substring(0, keyClause.length() - 1) + ")" + " VALUES(" + valueClause.substring(0, valueClause.length() - 1) + ")";
|
||||
}
|
||||
|
||||
public Object[] getParams()
|
||||
{
|
||||
return parameters.toArray();
|
||||
}
|
||||
|
||||
public void testParams()
|
||||
{
|
||||
for (int i = 0; i < parameters.size(); i++)
|
||||
{
|
||||
if (i == parameters.size() - 1)
|
||||
{
|
||||
System.out.println(parameters.get(i) + ";");
|
||||
} else
|
||||
{
|
||||
System.out.print(parameters.get(i) + ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
import com.zsvg.vboot.module.sys.org.root.SysOrg;
|
||||
import com.zsvg.vboot.common.mvc.api.PageData;
|
||||
import com.zsvg.vboot.common.mvc.pojo.ZidName;
|
||||
import com.zsvg.vboot.common.mvc.pojo.Zinp;
|
||||
import com.zsvg.vboot.common.mvc.pojo.Ztree;
|
||||
import com.zsvg.vboot.common.util.lang.XjsonUtil;
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import com.zsvg.vboot.common.util.web.XreqUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class JdbcDao {
|
||||
|
||||
@Value("${app.db.type}")
|
||||
private String DB_TYPE;
|
||||
|
||||
public PageData findPageData(Sqler sqler) {
|
||||
XreqUtil.setPageParam(sqler);
|
||||
Integer count = jdbcTemplate.queryForObject(sqler.getSizeSql(), sqler.getParams(), Integer.class);
|
||||
if (count == null || count == 0) {
|
||||
return new PageData(0, new ArrayList<>());
|
||||
}
|
||||
List<Map<String, Object>> list;
|
||||
if ("MYSQL".equals(DB_TYPE)) {
|
||||
list = jdbcTemplate.queryForList(sqler.getMysqlPagingSql(), sqler.getParams());
|
||||
} else {
|
||||
list = jdbcTemplate.queryForList(sqler.getOraclePagingSql(), sqler.getParams());
|
||||
}
|
||||
return new PageData(count, list);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
public List<Ztree> findTreeList(Sqler sqler) {
|
||||
List<Ztree> list = jdbcTemplate.query(sqler.getSql(), sqler.getParams(), (rs, rowNum) -> {
|
||||
Ztree ztree = new Ztree();
|
||||
ztree.setId(rs.getString("id"));
|
||||
ztree.setName(rs.getString("name"));
|
||||
ztree.setPid(rs.getString("pid"));
|
||||
return ztree;
|
||||
});
|
||||
return XjsonUtil.buildByRecursive(list);
|
||||
}
|
||||
|
||||
|
||||
public List<ZidName> findIdNameList(String sql, Object... args) {
|
||||
return jdbcTemplate.query(sql, args, (rs, rowNum) -> {
|
||||
ZidName ztwo = new ZidName();
|
||||
ztwo.setId(rs.getString("id"));
|
||||
ztwo.setName(rs.getString("name"));
|
||||
return ztwo;
|
||||
});
|
||||
}
|
||||
|
||||
public List<ZidName> getIdNameListByTable(String table, String name) {
|
||||
String sql = "select id,name from " + table + " where avtag = 1";
|
||||
if (XstringUtil.isBlank(name)) {
|
||||
return findIdNameList(sql);
|
||||
} else {
|
||||
return jdbcTemplate.query(sql + " and name like ?", new Object[]{"%" + name + "%"}, (rs, rowNum) -> {
|
||||
ZidName ztwo = new ZidName();
|
||||
ztwo.setId(rs.getString("id"));
|
||||
ztwo.setName(rs.getString("name"));
|
||||
return ztwo;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<ZidName> findIdNameList(Sqler sqlHelper) {
|
||||
return findIdNameList((sqlHelper.getSql()), sqlHelper.getParams());
|
||||
}
|
||||
|
||||
|
||||
public List<SysOrg> findOrgList(String sql, Object... args) {
|
||||
return jdbcTemplate.query(sql, args, (rs, rowNum) -> {
|
||||
SysOrg sysOrg = new SysOrg();
|
||||
sysOrg.setId(rs.getString("id"));
|
||||
sysOrg.setName(rs.getString("name"));
|
||||
return sysOrg;
|
||||
});
|
||||
}
|
||||
|
||||
public List<Zinp> findInpList(String sql, Object... args) {
|
||||
return jdbcTemplate.query(sql, args, (rs, rowNum) -> {
|
||||
Zinp zinp = new Zinp();
|
||||
zinp.setId(rs.getString("id"));
|
||||
zinp.setName(rs.getString("name"));
|
||||
zinp.setPid(rs.getString("pid"));
|
||||
return zinp;
|
||||
});
|
||||
}
|
||||
|
||||
public List<Zinp> findInpList(Sqler sqlHelper) {
|
||||
return findInpList(sqlHelper.getSql(), sqlHelper.getParams());
|
||||
}
|
||||
|
||||
public List<Zinp> findInpListByTable(String table) {
|
||||
String sql = "select id,name,pid from " + table + " where avtag = 1";
|
||||
return findInpList(sql);
|
||||
}
|
||||
|
||||
public List<Zinp> findInpListByTable(String table, String name) {
|
||||
String sql = "select id,name,pid from " + table + " where avtag = 1";
|
||||
if (XstringUtil.isBlank(name)) {
|
||||
return findInpList(sql);
|
||||
} else {
|
||||
return jdbcTemplate.query(sql + " and name like ?", new Object[]{"%" + name + "%"}, (rs, rowNum) -> new Zinp(rs.getString("id"), rs.getString("name"), rs.getString("pid")));
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> findStringList(String sql, Object... args) {
|
||||
return jdbcTemplate.query(sql, args, (rs, rowNum) -> rs.getString("id"));
|
||||
}
|
||||
|
||||
public List<String> findStringList(Sqler sqler) {
|
||||
return jdbcTemplate.query(sqler.getSql(), sqler.getParams(), (rs, rowNum) -> rs.getString("id"));
|
||||
}
|
||||
|
||||
public Integer findSize(Sqler sqler) {
|
||||
return jdbcTemplate.queryForObject(sqler.getSizeSql(), sqler.getParams(), Integer.class);
|
||||
}
|
||||
|
||||
public String findOneString(String sql, Object... args) {
|
||||
String str = null;
|
||||
try {
|
||||
str = jdbcTemplate.queryForObject(sql, args, String.class);
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public String findOneString(Sqler sqler) {
|
||||
return findOneString(sqler.getSql(), sqler.getParams());
|
||||
}
|
||||
|
||||
public Map<String, Object> findMap(Sqler sqler) {
|
||||
List<Map<String, Object>> list = jdbcTemplate.queryForList(sqler.getSql(), sqler.getParams());
|
||||
if (list.size() > 0) {
|
||||
return list.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
// return jdbcTemplate.queryForMap(sqler.getSql(), sqler.getParams());
|
||||
}
|
||||
|
||||
public Map<String, Object> findMap(String sql, Object... args) {
|
||||
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, args);
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> findMapList(Sqler sqler) {
|
||||
return jdbcTemplate.queryForList(sqler.getSql(), sqler.getParams());
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> findMapList(String sql, Object... args) {
|
||||
return jdbcTemplate.queryForList(sql, args);
|
||||
}
|
||||
|
||||
|
||||
public String findOneName(String table, String id) {
|
||||
if (XstringUtil.isBlank(id)) {
|
||||
return null;
|
||||
} else {
|
||||
return jdbcTemplate.queryForObject("select name from " + table + " where id = ?", new Object[]{id}, String.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//queryForObject 如果返回没结果会报错
|
||||
|
||||
|
||||
//增删改----------------------------------------------------------------------------------
|
||||
public int update(String sql, Object... args) {
|
||||
return jdbcTemplate.update(sql, args);
|
||||
}
|
||||
|
||||
public int update(BaseSqler sqler) throws SQLException {
|
||||
return jdbcTemplate.update(sqler.getSql(), sqler.getParams());
|
||||
}
|
||||
|
||||
public int[] batch(String sql, List<java.lang.Object[]> list) {
|
||||
return jdbcTemplate.batchUpdate(sql, list);
|
||||
}
|
||||
|
||||
public String getDbType() {
|
||||
return DB_TYPE;
|
||||
}
|
||||
|
||||
public JdbcTemplate getTp() {
|
||||
// jdbcDao.getTp().query(sql, new Object[]{}, new BeanPropertyRowMapper<>(Qmarg.class));
|
||||
return jdbcTemplate;
|
||||
}
|
||||
|
||||
@Resource
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import com.zsvg.vboot.config.security.pojo.Zuser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Sqler
|
||||
{
|
||||
private String fromClause = "";
|
||||
private String whereClause = "";
|
||||
private String orderClause = "";
|
||||
private String selectClause = "";
|
||||
private String groupClause = "";
|
||||
private Integer panum = 1;
|
||||
private Integer pasiz = 10;
|
||||
private int autoType=1;
|
||||
private List<Object> parameters = new ArrayList<Object>(); // 参数清单
|
||||
|
||||
public Sqler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Sqler(String table, Integer panum, Integer pasiz)
|
||||
{
|
||||
this.selectClause = "SELECT t.id,t.name";
|
||||
this.fromClause = " FROM " + table+" t";
|
||||
if (panum != null)
|
||||
{
|
||||
this.panum = panum;
|
||||
}
|
||||
if (pasiz != null)
|
||||
{
|
||||
this.pasiz = pasiz;
|
||||
}
|
||||
}
|
||||
|
||||
public Sqler(String fields, String table, Integer panum, Integer pasiz)
|
||||
{
|
||||
this.selectClause = "SELECT " + fields;
|
||||
this.fromClause = " FROM " + table+" t";
|
||||
if (panum != null)
|
||||
{
|
||||
this.panum = panum;
|
||||
}
|
||||
if (pasiz != null)
|
||||
{
|
||||
this.pasiz = pasiz;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Sqler(String table)
|
||||
{
|
||||
this.selectClause = "SELECT t.id,t.name";
|
||||
this.fromClause = " FROM " + table+" t";
|
||||
}
|
||||
|
||||
public Sqler(String fields, String table)
|
||||
{
|
||||
this.selectClause = "SELECT " + fields;
|
||||
this.fromClause = " FROM " + table+" t";
|
||||
}
|
||||
|
||||
public void addSelect(String fields)
|
||||
{
|
||||
selectClause += "," + fields;
|
||||
}
|
||||
|
||||
public Sqler addInnerJoin(String fields, String table, String condition)
|
||||
{
|
||||
if (!fields.equals(""))
|
||||
{
|
||||
selectClause += "," + fields;
|
||||
}
|
||||
fromClause += " INNER JOIN " + table + " ON " + condition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addLeftJoin(String fields, String table, String condition)
|
||||
{
|
||||
if (!fields.equals(""))
|
||||
{
|
||||
selectClause += "," + fields;
|
||||
}
|
||||
fromClause += " Left JOIN " + table + " ON " + condition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addWhere(String condition, Object... params)
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + condition;
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + condition;
|
||||
}
|
||||
if (params != null && params.length > 0)
|
||||
{
|
||||
for (Object obj : params)
|
||||
{
|
||||
parameters.add(obj);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addWhere(boolean append, String condition, Object... params)
|
||||
{
|
||||
if (append)
|
||||
{
|
||||
addWhere(condition, params);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addEqual(String name, Object value)
|
||||
{
|
||||
if (XstringUtil.isNotBlank(value + ""))
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + name + " = ?";
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + name + " = ?";
|
||||
}
|
||||
parameters.add(value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addLike(String name, Object value)
|
||||
{
|
||||
if (XstringUtil.isNotBlank(value + ""))
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + name + " like ?";
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + name + " like ?";
|
||||
}
|
||||
parameters.add("%"+(""+value).trim()+"%");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addGtStringDate(String name, Object value)
|
||||
{
|
||||
if (XstringUtil.isNotBlank(value + ""))
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + name + ">=?";
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + name + ">=?";
|
||||
}
|
||||
parameters.add(value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addGtDate(String name, Object value, String dbType)
|
||||
{
|
||||
if("ORACLE".equals(dbType)){
|
||||
if (XstringUtil.isNotBlank(value + ""))
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + name + ">=to_date(?,'yyyy-MM-dd')";
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + name + ">=to_date(?,'yyyy-MM-dd')";
|
||||
}
|
||||
parameters.add(value);
|
||||
}
|
||||
}else if("MYSQL".equals(dbType)){
|
||||
if (XstringUtil.isNotBlank(value + ""))
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE unix_timestamp(" + name + ") >=unix_timestamp(?)";
|
||||
} else
|
||||
{
|
||||
whereClause += " AND unix_timestamp(" + name + ") >=unix_timestamp(?)";
|
||||
}
|
||||
parameters.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addLtDate(String name, Object value, String dbType)
|
||||
{
|
||||
if("ORACLE".equals(dbType)) {
|
||||
if (XstringUtil.isNotBlank(value + "")) {
|
||||
if (whereClause.length() == 0) {
|
||||
whereClause = " WHERE " + name + "<to_date(?,'yyyy-MM-dd')+1";
|
||||
} else {
|
||||
whereClause += " AND " + name + "<to_date(?,'yyyy-MM-dd')+1";
|
||||
}
|
||||
parameters.add(value);
|
||||
}
|
||||
}else{
|
||||
if (XstringUtil.isNotBlank(value + "")) {
|
||||
if (whereClause.length() == 0) {
|
||||
whereClause = " WHERE unix_timestamp(" + name + ") <=unix_timestamp(?)";
|
||||
} else {
|
||||
whereClause += " AND unix_timestamp(" + name + ") <=unix_timestamp(?)";
|
||||
}
|
||||
parameters.add(value+" 23:59:59");
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addLtStringDate(String name, Object value)
|
||||
{
|
||||
if (XstringUtil.isNotBlank(value + ""))
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + name + "<=?";
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + name + "<=?";
|
||||
}
|
||||
parameters.add(value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addOrder(String propertyName)
|
||||
{
|
||||
if (orderClause.length() == 0)
|
||||
{
|
||||
orderClause = " ORDER BY " + propertyName;
|
||||
} else
|
||||
{
|
||||
orderClause += ", " + propertyName;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addDescOrder(String propertyName)
|
||||
{
|
||||
if (orderClause.length() == 0)
|
||||
{
|
||||
orderClause = " ORDER BY " + propertyName + " DESC";
|
||||
} else
|
||||
{
|
||||
orderClause += ", " + propertyName + " DESC";
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addGroup(String gclause)
|
||||
{
|
||||
groupClause=" GROUP BY "+gclause;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addJoin(String joinClause)
|
||||
{
|
||||
this.fromClause += " " + joinClause;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler addAuth(Zuser zuser, String table)
|
||||
{
|
||||
addJoin(" left join "+table+"_viewer vvv on vvv.id=t.id");
|
||||
addJoin(" left join "+table+"_editor eee on eee.id=t.id");
|
||||
if (!zuser.isAdmin())
|
||||
{
|
||||
addWhere("(t.crman=? or vvv.org in (" + zuser.getConds() + ") or eee.org in (" + zuser.getConds() + "))", zuser.getId());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sqler selectCinfo(){
|
||||
addLeftJoin("oo1.name as crman,t.crtim", "sys_org oo1", "oo1.id=t.crman");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Sqler selectCUinfo(){
|
||||
addLeftJoin("oo1.name as crman,t.crtim", "sys_org oo1", "oo1.id=t.crman");
|
||||
addLeftJoin("oo2.name as upman,t.uptim", "sys_org oo2", "oo2.id=t.upman");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//get and set-------------------------------------------
|
||||
|
||||
public String getSql()
|
||||
{
|
||||
return selectClause + fromClause + whereClause +groupClause+ orderClause;
|
||||
}
|
||||
|
||||
public String getLowerCaseSql()
|
||||
{
|
||||
//字段转成小写
|
||||
StringBuilder changeSelectClause= new StringBuilder();
|
||||
String[] strArr= selectClause.split(",");
|
||||
lowerCaseSelect(changeSelectClause, strArr);
|
||||
changeSelectClause.deleteCharAt(changeSelectClause.length()-1);
|
||||
return changeSelectClause.toString() + fromClause + whereClause+groupClause + orderClause;
|
||||
}
|
||||
|
||||
public Sqler getNewGroupSqler(String groupClause){
|
||||
Sqler sqler = new Sqler("");
|
||||
sqler.fromClause=this.fromClause;
|
||||
sqler.whereClause=this.whereClause;
|
||||
sqler.groupClause=" group by "+groupClause;
|
||||
return sqler;
|
||||
}
|
||||
|
||||
|
||||
public String getSizeSql()
|
||||
{
|
||||
if("".equals(groupClause)){
|
||||
return "SELECT count(1)" + fromClause + whereClause;
|
||||
}
|
||||
else {
|
||||
return "SELECT count(1) FROM (SELECT 1 " + fromClause + whereClause+groupClause+") SSZZ";
|
||||
}
|
||||
}
|
||||
|
||||
public String getMysqlPagingSql()
|
||||
{
|
||||
int fromIndex = pasiz * (panum - 1);
|
||||
return selectClause + fromClause + whereClause+groupClause + orderClause + " limit " + fromIndex + "," + pasiz;
|
||||
}
|
||||
|
||||
public String getOraclePagingSql()
|
||||
{
|
||||
int rownum = panum * pasiz;
|
||||
int rn = (panum - 1) * pasiz;
|
||||
return " SELECT * FROM (SELECT PPGG.*, ROWNUM RN FROM (" + selectClause + fromClause + whereClause+groupClause + orderClause + ") PPGG WHERE ROWNUM <= " + rownum + ") WHERE RN > " + rn;
|
||||
// return " SELECT * FROM (SELECT PPGG.*, ROWNUM RN FROM (" + changeSelectClause.toString() + fromClause + whereClause+groupClause + orderClause + ") PPGG WHERE ROWNUM <= " + rownum + ") WHERE RN > " + rn;
|
||||
}
|
||||
|
||||
public String getOraclePagingLowerCaseSql()
|
||||
{
|
||||
//字段转成小写
|
||||
StringBuilder changeSelectClause= new StringBuilder();
|
||||
String[] strArr= selectClause.split(",");
|
||||
lowerCaseSelect(changeSelectClause, strArr);
|
||||
changeSelectClause.deleteCharAt(changeSelectClause.length()-1);
|
||||
//分页
|
||||
int rownum = panum * pasiz;
|
||||
int rn = (panum - 1) * pasiz;
|
||||
return " SELECT * FROM (SELECT PPGG.*, ROWNUM RN FROM (" + changeSelectClause.toString() + fromClause + whereClause+groupClause + orderClause + ") PPGG WHERE ROWNUM <= " + rownum + ") WHERE RN > " + rn;
|
||||
}
|
||||
|
||||
private void lowerCaseSelect(StringBuilder changeSelectClause, String[] strArr) {
|
||||
for (String aStrArr : strArr) {
|
||||
if(aStrArr.contains("(")&&!aStrArr.contains(")")){
|
||||
changeSelectClause.append(" ").append(aStrArr);
|
||||
}else{
|
||||
String[] strArr2 = aStrArr.split(" ");
|
||||
strArr2[strArr2.length - 1] = "\"" + strArr2[strArr2.length - 1] + "\"";
|
||||
for (String aStrArr2 : strArr2) {
|
||||
changeSelectClause.append(" ").append(aStrArr2);
|
||||
}
|
||||
}
|
||||
changeSelectClause.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
public Object[] getParams()
|
||||
{
|
||||
return parameters.toArray();
|
||||
}
|
||||
|
||||
public void testParams()
|
||||
{
|
||||
for (int i = 0; i < parameters.size(); i++)
|
||||
{
|
||||
if (i == parameters.size() - 1)
|
||||
{
|
||||
System.out.println(parameters.get(i) + ";");
|
||||
} else
|
||||
{
|
||||
System.out.print(parameters.get(i) + ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
//get and set-----------------------------------------------
|
||||
|
||||
|
||||
public Integer getPanum() {
|
||||
return panum;
|
||||
}
|
||||
|
||||
public Integer getPasiz() {
|
||||
return pasiz;
|
||||
}
|
||||
|
||||
public int getAutoType() {
|
||||
return autoType;
|
||||
}
|
||||
|
||||
public void setAutoType(int autoType) {
|
||||
this.autoType = autoType;
|
||||
}
|
||||
|
||||
public void setPanum(Integer panum) {
|
||||
this.panum = panum;
|
||||
}
|
||||
|
||||
public void setPasiz(Integer pasiz) {
|
||||
this.pasiz = pasiz;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.zsvg.vboot.common.mvc.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Usqler extends BaseSqler
|
||||
{
|
||||
private String updateClause = "";
|
||||
private String keyClause = "";
|
||||
private String whereClause = "";
|
||||
private List<Object> parameters = new ArrayList<Object>(); //参数列表
|
||||
private List<Object> whereParameters = new ArrayList<Object>();
|
||||
|
||||
|
||||
public Usqler(String table)
|
||||
{
|
||||
this.updateClause = "UPDATE " + table + " SET ";
|
||||
}
|
||||
|
||||
public Usqler add(String key, Object value)
|
||||
{
|
||||
if ("true".equals(value))
|
||||
{
|
||||
keyClause += key + "=?,";
|
||||
parameters.add(true);
|
||||
} else if ("false".equals(value))
|
||||
{
|
||||
keyClause += key + "=?,";
|
||||
parameters.add(false);
|
||||
} else
|
||||
{
|
||||
keyClause += key + "=?,";
|
||||
parameters.add(value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Usqler addWhere(String condition, Object... params)
|
||||
{
|
||||
if (whereClause.length() == 0)
|
||||
{
|
||||
whereClause = " WHERE " + condition;
|
||||
} else
|
||||
{
|
||||
whereClause += " AND " + condition;
|
||||
}
|
||||
if (params != null && params.length > 0)
|
||||
{
|
||||
for (Object obj : params)
|
||||
{
|
||||
whereParameters.add(obj);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSql() throws SQLException {
|
||||
if("".equals(whereClause)){
|
||||
throw new SQLException("为防止误更新,update 语句必须要有where条件");
|
||||
}
|
||||
return updateClause + keyClause.substring(0, keyClause.length() - 1) + whereClause;
|
||||
}
|
||||
|
||||
public Object[] getParams()
|
||||
{
|
||||
parameters.addAll(whereParameters);
|
||||
return parameters.toArray();
|
||||
}
|
||||
|
||||
public void testParams()
|
||||
{
|
||||
for (int i = 0; i < parameters.size(); i++)
|
||||
{
|
||||
if (i == parameters.size() - 1)
|
||||
{
|
||||
System.out.println(parameters.get(i) + ";");
|
||||
} else
|
||||
{
|
||||
System.out.print(parameters.get(i) + ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.zsvg.vboot.common.mvc.entity;
|
||||
|
||||
import com.zsvg.vboot.module.sys.org.root.SysOrg;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Date;
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
public class BaseCateEntity {
|
||||
//----------------------id属性-----------------------
|
||||
@Id
|
||||
@Column(length = 32)
|
||||
protected String id;
|
||||
//----------------------权限属性-----------------------
|
||||
// @ManyToMany
|
||||
// @JoinTable(name = "xxx_viewer", joinColumns = {@JoinColumn(name = "id")},
|
||||
// inverseJoinColumns = {@JoinColumn(name = "org")})
|
||||
// private List<SysOrg> viewers;//分类可查看使用者,拥有此权限者可以创建此分类下主数据信息
|
||||
//
|
||||
// @ManyToMany
|
||||
// @JoinTable(name = "xxx_editor", joinColumns = {@JoinColumn(name = "id")},
|
||||
// inverseJoinColumns = {@JoinColumn(name = "org")})
|
||||
// private List<SysOrg> editors;//分类可编辑维护者,拥有此权限者可以查看此分类下所有主数据信息
|
||||
|
||||
//----------------------层级属性参考-----------------------
|
||||
@Column(length = 1000)
|
||||
protected String tier;//层级信息
|
||||
|
||||
@Transient
|
||||
private String pid;
|
||||
|
||||
@Transient
|
||||
protected BaseCateEntity parent;//父类别
|
||||
//----------------------norm标准属性-----------------------
|
||||
@Column(length = 100)
|
||||
protected String name;//名称
|
||||
|
||||
@Column(length = 64)
|
||||
protected String label;//标签
|
||||
|
||||
@Column(length = 500)
|
||||
protected String notes;//备注
|
||||
|
||||
protected Boolean avtag;//可用标记 1启用,0禁用
|
||||
|
||||
protected Integer ornum;//排序号
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "crman", updatable = false)
|
||||
protected SysOrg crman;//创建人
|
||||
|
||||
@Column(updatable = false)
|
||||
protected Date crtim = new Date();//创建时间
|
||||
|
||||
protected Date uptim;//更新时间
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "upman")
|
||||
protected SysOrg upman;//更新人
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.zsvg.vboot.common.mvc.entity;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
public class BaseEntity {
|
||||
|
||||
|
||||
@Id
|
||||
@Column(length = 32)
|
||||
protected String id;
|
||||
|
||||
@Column(length = 126)
|
||||
protected String name;//名称
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.zsvg.vboot.common.mvc.entity;
|
||||
|
||||
import com.zsvg.vboot.module.sys.org.root.SysOrg;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Date;
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
public class BaseMainEntity {
|
||||
//----------------------id属性-----------------------
|
||||
@Id
|
||||
@Column(length = 32)
|
||||
protected String id;
|
||||
|
||||
//----------------------权限属性-----------------------
|
||||
// @ManyToMany
|
||||
// @JoinTable(name = "xxx_viewer", joinColumns = {@JoinColumn(name = "id")},
|
||||
// inverseJoinColumns = {@JoinColumn(name = "org")})
|
||||
// private List<SysOrg> viewers;//记录可查看者
|
||||
//
|
||||
// @ManyToMany
|
||||
// @JoinTable(name = "xxx_editor", joinColumns = {@JoinColumn(name = "id")},
|
||||
// inverseJoinColumns = {@JoinColumn(name = "org")})
|
||||
// private List<SysOrg> editors;//记录可编辑者
|
||||
|
||||
|
||||
//----------------------norm标准属性-----------------------
|
||||
@Column(length = 126)
|
||||
protected String name;//名称
|
||||
|
||||
protected Boolean avtag=true;//可用标记 1启用,0禁用
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "crman", updatable = false)
|
||||
protected SysOrg crman;//创建人
|
||||
|
||||
@Column(updatable = false)
|
||||
protected Date crtim = new Date();//创建时间
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "upman")
|
||||
protected SysOrg upman;//更新人
|
||||
|
||||
protected Date uptim;//更新时间
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.zsvg.vboot.common.mvc.exception;
|
||||
|
||||
public class BadConfigurationException extends RuntimeException {
|
||||
/**
|
||||
* Constructs a new runtime exception with {@code null} as its
|
||||
* detail message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public BadConfigurationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified detail message.
|
||||
* The cause is not initialized, and may subsequently be initialized by a
|
||||
* call to {@link #initCause}.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for
|
||||
* later retrieval by the {@link #getMessage()} method.
|
||||
*/
|
||||
public BadConfigurationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified detail message and
|
||||
* cause. <p>Note that the detail message associated with
|
||||
* {@code cause} is <i>not</i> automatically incorporated in
|
||||
* this runtime exception's detail message.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval
|
||||
* by the {@link #getMessage()} method).
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public BadConfigurationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified cause and a
|
||||
* detail message of {@code (cause==null ? null : cause.toString())}
|
||||
* (which typically contains the class and detail message of
|
||||
* {@code cause}). This constructor is useful for runtime exceptions
|
||||
* that are little more than wrappers for other throwables.
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public BadConfigurationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified detail
|
||||
* message, cause, suppression enabled or disabled, and writable
|
||||
* stack trace enabled or disabled.
|
||||
*
|
||||
* @param message the detail message.
|
||||
* @param cause the cause. (A {@code null} value is permitted,
|
||||
* and indicates that the cause is nonexistent or unknown.)
|
||||
* @param enableSuppression whether or not suppression is enabled
|
||||
* or disabled
|
||||
* @param writableStackTrace whether or not the stack trace should
|
||||
* be writable
|
||||
* @since 1.7
|
||||
*/
|
||||
protected BadConfigurationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.zsvg.vboot.common.mvc.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||
|
||||
@Getter
|
||||
public class BadRequestException extends RuntimeException{
|
||||
|
||||
private Integer status = BAD_REQUEST.value();
|
||||
|
||||
public BadRequestException(String msg){
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public BadRequestException(HttpStatus status, String msg){
|
||||
super(msg);
|
||||
this.status = status.value();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.zsvg.vboot.common.mvc.exception;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class EntityExistException extends RuntimeException {
|
||||
|
||||
public EntityExistException(Class clazz, String field, String val) {
|
||||
super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val));
|
||||
}
|
||||
|
||||
private static String generateMessage(String entity, String field, String val) {
|
||||
return StringUtils.capitalize(entity)
|
||||
+ " with " + field + " "+ val + " existed";
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.zsvg.vboot.common.mvc.exception;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class EntityNotFoundException extends RuntimeException {
|
||||
|
||||
public EntityNotFoundException(Class clazz, String field, String val) {
|
||||
super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val));
|
||||
}
|
||||
|
||||
private static String generateMessage(String entity, String field, String val) {
|
||||
return StringUtils.capitalize(entity)
|
||||
+ " with " + field + " "+ val + " does not exist";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.zsvg.vboot.common.mvc.exception.handler;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
class ApiError {
|
||||
|
||||
private Integer status = 500;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime timestamp;
|
||||
private String message;
|
||||
|
||||
private ApiError() {
|
||||
timestamp = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public static ApiError error(String message){
|
||||
ApiError apiError = new ApiError();
|
||||
apiError.setMessage(message);
|
||||
return apiError;
|
||||
}
|
||||
|
||||
public static ApiError error(Integer status, String message){
|
||||
ApiError apiError = new ApiError();
|
||||
apiError.setStatus(status);
|
||||
apiError.setMessage(message);
|
||||
return apiError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.zsvg.vboot.common.mvc.exception.handler;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.exception.BadRequestException;
|
||||
import com.zsvg.vboot.common.mvc.exception.EntityExistException;
|
||||
import com.zsvg.vboot.common.mvc.exception.EntityNotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理所有不可知的异常
|
||||
*/
|
||||
@ExceptionHandler(Throwable.class)
|
||||
public ResponseEntity<ApiError> handleException(Throwable e){
|
||||
// 打印堆栈信息
|
||||
log.error(ThrowableUtil.getStackTrace(e));
|
||||
return buildResponseEntity(ApiError.error(e.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* BadCredentialsException
|
||||
*/
|
||||
@ExceptionHandler(BadCredentialsException.class)
|
||||
public ResponseEntity<ApiError> badCredentialsException(BadCredentialsException e){
|
||||
// 打印堆栈信息
|
||||
String message = "坏的凭证".equals(e.getMessage()) ? "用户名或密码不正确" : e.getMessage();
|
||||
log.error(message);
|
||||
return buildResponseEntity(ApiError.error(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(value = BadRequestException.class)
|
||||
public ResponseEntity<ApiError> badRequestException(BadRequestException e) {
|
||||
// 打印堆栈信息
|
||||
log.error(ThrowableUtil.getStackTrace(e));
|
||||
return buildResponseEntity(ApiError.error(e.getStatus(),e.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 EntityExist
|
||||
*/
|
||||
@ExceptionHandler(value = EntityExistException.class)
|
||||
public ResponseEntity<ApiError> entityExistException(EntityExistException e) {
|
||||
// 打印堆栈信息
|
||||
log.error(ThrowableUtil.getStackTrace(e));
|
||||
return buildResponseEntity(ApiError.error(e.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 EntityNotFound
|
||||
*/
|
||||
@ExceptionHandler(value = EntityNotFoundException.class)
|
||||
public ResponseEntity<ApiError> entityNotFoundException(EntityNotFoundException e) {
|
||||
// 打印堆栈信息
|
||||
log.error(ThrowableUtil.getStackTrace(e));
|
||||
return buildResponseEntity(ApiError.error(NOT_FOUND.value(),e.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理所有接口数据验证异常
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<ApiError> handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
|
||||
// 打印堆栈信息
|
||||
log.error(ThrowableUtil.getStackTrace(e));
|
||||
String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\.");
|
||||
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
|
||||
String msg = "不能为空";
|
||||
if(msg.equals(message)){
|
||||
message = str[1] + ":" + message;
|
||||
}
|
||||
return buildResponseEntity(ApiError.error(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一返回
|
||||
*/
|
||||
private ResponseEntity<ApiError> buildResponseEntity(ApiError apiError) {
|
||||
return new ResponseEntity<>(apiError, HttpStatus.valueOf(apiError.getStatus()));
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.zsvg.vboot.common.mvc.exception.handler;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
public class ThrowableUtil {
|
||||
|
||||
/**
|
||||
* 获取堆栈信息
|
||||
*/
|
||||
public static String getStackTrace(Throwable throwable){
|
||||
StringWriter sw = new StringWriter();
|
||||
try (PrintWriter pw = new PrintWriter(sw)) {
|
||||
throwable.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.zsvg.vboot.common.mvc.others;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MapHelper {
|
||||
private Map<String,String> map;
|
||||
|
||||
public MapHelper(){
|
||||
map = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public MapHelper(String field,String title){
|
||||
map = new LinkedHashMap<>();
|
||||
map.put("field", field);
|
||||
map.put("title", title);
|
||||
}
|
||||
|
||||
public MapHelper put(String key,String value){
|
||||
map.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String,String> get(){
|
||||
return map;
|
||||
}
|
||||
|
||||
public MapHelper addTo(List list){
|
||||
list.add(map);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.zsvg.vboot.common.mvc.pojo;
|
||||
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Zconn {
|
||||
private String type;
|
||||
|
||||
private String url;
|
||||
|
||||
private String username;
|
||||
|
||||
private String passcode;
|
||||
|
||||
|
||||
|
||||
public String getSid()
|
||||
{
|
||||
if(isMysql())
|
||||
{
|
||||
return url.substring(url.lastIndexOf("/")+1).replaceAll("/","");
|
||||
}
|
||||
else if (isOracle())
|
||||
{
|
||||
return url.substring(url.lastIndexOf(":")+1);
|
||||
}
|
||||
else if (isDB2())
|
||||
{
|
||||
return url.substring(url.lastIndexOf("/")+1);
|
||||
}
|
||||
else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getDriver(){
|
||||
if(isOracle()){
|
||||
return "oracle.jdbc.driver.OracleDriver";
|
||||
}else if(isMysql()){
|
||||
return "com.mysql.jdbc.Driver";
|
||||
}else if(isMysql8()){
|
||||
return "com.mysql.cj.jdbc.Driver";
|
||||
}else if(isDB2()){
|
||||
return "com.ibm.db2.jcc.DB2Driver";
|
||||
}else{
|
||||
return "暂不支持";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOracle()
|
||||
{
|
||||
return "ORACLE".equals(type);
|
||||
}
|
||||
public boolean isMysql()
|
||||
{
|
||||
return "MYSQL".equals(type);
|
||||
}
|
||||
public boolean isMysql8()
|
||||
{
|
||||
return "MYSQL8".equals(type);
|
||||
}
|
||||
public boolean isDB2()
|
||||
{
|
||||
return "DB2".equals(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.zsvg.vboot.common.mvc.pojo;
|
||||
|
||||
|
||||
public class ZidName
|
||||
{
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ZidName{" +
|
||||
"id='" + id + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public ZidName(String id, String name)
|
||||
{
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ZidName()
|
||||
{
|
||||
}
|
||||
|
||||
//get and set-------
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.zsvg.vboot.common.mvc.pojo;
|
||||
|
||||
public class Zinp {
|
||||
private String id;
|
||||
private String name;
|
||||
private String pid;
|
||||
|
||||
public Zinp() {
|
||||
}
|
||||
|
||||
public Zinp(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Zinp(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Zinp(String id, String name, String pid) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.pid = pid;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
public void setPid(String pid) {
|
||||
this.pid = pid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.zsvg.vboot.common.mvc.pojo;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class Ztree {
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
@JsonIgnore
|
||||
private String pid;
|
||||
|
||||
private List<Ztree> children;
|
||||
|
||||
private Map<String, Object> data;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package com.zsvg.vboot.common.mvc.service;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.api.RestResult;
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import com.zsvg.vboot.common.mvc.dao.Sqler;
|
||||
import com.zsvg.vboot.common.mvc.pojo.ZidName;
|
||||
import com.zsvg.vboot.common.mvc.pojo.Ztree;
|
||||
import com.zsvg.vboot.common.mvc.entity.BaseCateEntity;
|
||||
import com.zsvg.vboot.common.mvc.api.PageData;
|
||||
import com.zsvg.vboot.common.mvc.pojo.Zinp;
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import com.zsvg.vboot.common.util.web.XuserUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public abstract class BaseCateService<T extends BaseCateEntity> {
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PageData findPageData(Sqler sqler) {
|
||||
sqler.selectCUinfo().addSelect("t.label");
|
||||
sqler.addOrder("t.ornum");
|
||||
return jdbcDao.findPageData(sqler);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<ZidName> findIdNameRes(Sqler sqler) {
|
||||
return jdbcDao.findIdNameList(sqler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//用户编辑时选择父类别,不能选择自己及孩子节点,否则会造成无线循环
|
||||
@Transactional(readOnly = true)
|
||||
public List<Zinp> inpChoose(String table, String id, String name){
|
||||
Sqler sqler = new Sqler(table);
|
||||
sqler.addSelect("pid");
|
||||
sqler.addWhere("t.avtag = 1");
|
||||
if (XstringUtil.isNotBlank(id)) {
|
||||
sqler.addWhere("t.tier not like ?", "%;" + id + ";%");
|
||||
sqler.addWhere("t.id <> ?", id);
|
||||
}
|
||||
if(XstringUtil.isNotBlank(name)){
|
||||
sqler.addLike("t.name", name);
|
||||
}
|
||||
sqler.addOrder("t.ornum");
|
||||
return jdbcDao.findInpList(sqler);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Ztree> tier2Choose(String table, String id, String name){
|
||||
Sqler sqler = new Sqler(table);
|
||||
sqler.addSelect("pid");
|
||||
sqler.addWhere("t.avtag = 1");
|
||||
if (XstringUtil.isNotBlank(id)) {
|
||||
sqler.addWhere("t.tier not like ?", "%;" + id + ";%");
|
||||
sqler.addWhere("t.id <> ?", id);
|
||||
}
|
||||
if(XstringUtil.isNotBlank(name)){
|
||||
sqler.addLike("t.name", name);
|
||||
}
|
||||
sqler.addOrder("t.ornum");
|
||||
return jdbcDao.findTreeList(sqler);
|
||||
}
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public RestResult inpFind(String table){
|
||||
Sqler sqlHelper = new Sqler(table);
|
||||
sqlHelper.addSelect("pid");
|
||||
sqlHelper.addWhere("t.avtag = 1");
|
||||
sqlHelper.addOrder("t.ornum");
|
||||
return RestResult.ok(jdbcDao.findInpList(sqlHelper));
|
||||
}
|
||||
|
||||
public RestResult inpDele(String table, String id){
|
||||
String sql = "select id from " + table + " where tier like ? order by tier";
|
||||
List<String> stringList = jdbcDao.findStringList(sql, "%;" + id + ";%");
|
||||
for (String sid : stringList) {
|
||||
repo.deleteById(sid);
|
||||
}
|
||||
repo.deleteById(id);
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
public String insert(T cate) {
|
||||
if(cate.getId()==null||"".equals(cate.getId())){
|
||||
cate.setId(XstringUtil.getUUID());
|
||||
}
|
||||
if(cate.getCrman()==null){
|
||||
cate.setCrman(XuserUtil.getUser());
|
||||
}
|
||||
if (cate.getParent() != null) {
|
||||
T parent = repo.findById(cate.getParent().getId()).get();
|
||||
cate.setTier(parent.getTier()+parent.getId()+ ";");
|
||||
} else {
|
||||
cate.setTier("null;");
|
||||
}
|
||||
repo.save(cate);
|
||||
return cate.getId();
|
||||
}
|
||||
|
||||
public String update(T cate){
|
||||
cate.setUptim(new Date());
|
||||
if(cate.getUpman()==null){
|
||||
cate.setUpman(XuserUtil.getUser());
|
||||
}
|
||||
repo.save(cate);
|
||||
return cate.getId();
|
||||
}
|
||||
|
||||
|
||||
public String update(T cate,String table){
|
||||
cate.setUptim(new Date());
|
||||
if(cate.getUpman()==null){
|
||||
cate.setUpman(XuserUtil.getUser());
|
||||
}
|
||||
String newPid = "";
|
||||
if(cate.getParent()!=null){
|
||||
newPid=cate.getParent().getId();
|
||||
}
|
||||
T oldCate=repo.findById(cate.getId()).get();
|
||||
String oldPid="";
|
||||
if(oldCate.getParent()!=null){
|
||||
oldPid =oldCate.getParent().getId();
|
||||
}
|
||||
String oldTier=oldCate.getTier();
|
||||
if(oldPid.equals(newPid)){//如果父节点没有变,则只更新自己
|
||||
// System.out.println("父节点没有变");
|
||||
cate.setTier(oldTier);
|
||||
repo.save(cate);
|
||||
}else{//如果父节点变了,则另外需要更新自己孩子节点的tier层级
|
||||
String newTier = "null;";
|
||||
if(cate.getParent()!=null){
|
||||
// System.out.println("父节点变成其他点了");
|
||||
T newParentCate=repo.findById(cate.getParent().getId()).get();
|
||||
newTier =newParentCate.getTier()+newParentCate.getId()+";";
|
||||
}else{
|
||||
// System.out.println("父节点变成更节点了");
|
||||
}
|
||||
cate.setTier(newTier);
|
||||
repo.save(cate);
|
||||
//更新子节点
|
||||
String sql = "select id,tier as name from " + table + " where tier like ? and id<>?";
|
||||
// System.out.println(sql);
|
||||
List<ZidName> list = jdbcDao.findIdNameList(sql, oldTier+oldCate.getId()+";%",cate.getId());
|
||||
|
||||
String updateSql = "update " + table + " set tier=? where id=?";
|
||||
List<Object[]> updateList = new ArrayList<Object[]>();
|
||||
for (ZidName ztwo : list) {
|
||||
Object[] arr = new Object[2];
|
||||
arr[0] = ztwo.getName().replace(oldTier,newTier);
|
||||
arr[1] = ztwo.getId();
|
||||
updateList.add(arr);
|
||||
}
|
||||
jdbcDao.batch(updateSql, updateList);
|
||||
}
|
||||
return cate.getId();
|
||||
|
||||
}
|
||||
|
||||
@Autowired
|
||||
protected JdbcDao jdbcDao;
|
||||
|
||||
protected JpaRepository<T,String> repo;
|
||||
|
||||
public void setRepo(JpaRepository<T,String> repo) {
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
// public T save(T t) {
|
||||
// return repo.save(t);
|
||||
// }
|
||||
//
|
||||
// public T update(T t) {
|
||||
// return repo.saveAndFlush(t);
|
||||
// }
|
||||
//
|
||||
@Transactional(readOnly = true)
|
||||
public T findOne(String id) {
|
||||
return repo.findById(id).get();
|
||||
}
|
||||
|
||||
public int delete(String[] ids) {
|
||||
for (String id : ids) {
|
||||
repo.deleteById(id);
|
||||
}
|
||||
return ids.length;
|
||||
}
|
||||
//
|
||||
// public void deleteOne(T t) {
|
||||
// repo.delete(t);
|
||||
// }
|
||||
//
|
||||
//// public boolean exists(String id) {
|
||||
//// return baseDao.exists(id);
|
||||
//// }
|
||||
//
|
||||
// public long count() {
|
||||
// return baseDao.count();
|
||||
// }
|
||||
//
|
||||
// public List<T> findAll() {
|
||||
// return baseDao.findAll();
|
||||
// }
|
||||
//
|
||||
// public List<T> findAll(Sort sort) {
|
||||
// return baseDao.findAll(sort);
|
||||
// }
|
||||
//
|
||||
// public List<T> findAll(Specification<T> specification) {
|
||||
// // TODO Auto-generated method stub
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// public Page<T> findAll(Pageable pageable) {
|
||||
// return baseDao.findAll(pageable);
|
||||
// }
|
||||
//
|
||||
// public Page<T> findAll(Specification<T> specification, Pageable pageable) {
|
||||
// // TODO Auto-generated method stub
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.zsvg.vboot.common.mvc.service;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import com.zsvg.vboot.common.mvc.dao.Sqler;
|
||||
import com.zsvg.vboot.common.mvc.entity.BaseMainEntity;
|
||||
import com.zsvg.vboot.common.mvc.api.PageData;
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import com.zsvg.vboot.common.util.web.XuserUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public abstract class BaseMainService<T extends BaseMainEntity> {
|
||||
|
||||
//---------------------------------------查询-------------------------------------
|
||||
@Transactional(readOnly = true)
|
||||
public PageData findPageData(Sqler sqler) {
|
||||
if (sqler.getAutoType() == 1) {
|
||||
sqler.selectCUinfo();
|
||||
sqler.addOrder("t.crtim desc");
|
||||
}
|
||||
return jdbcDao.findPageData(sqler);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Map<String, Object>> findMapList(Sqler sqler) {
|
||||
return jdbcDao.findMapList(sqler);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Map<String, Object>> findMapList(String sql, Object... args) {
|
||||
return jdbcDao.findMapList(sql, args);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public boolean existsById(String id) {
|
||||
return repo.existsById(id);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public T findOne(String id) {
|
||||
return repo.findById(id).get();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> findAll() {
|
||||
return repo.findAll();
|
||||
}
|
||||
|
||||
//---------------------------------------增删改-------------------------------------
|
||||
public T insert(T main) {
|
||||
if (main.getId() == null || "".equals(main.getId())) {
|
||||
main.setId(XstringUtil.getUUID());
|
||||
}
|
||||
main.setCrtim(new Date());
|
||||
if (main.getCrman() == null) {
|
||||
main.setCrman(XuserUtil.getUser());
|
||||
}
|
||||
return repo.save(main);
|
||||
}
|
||||
|
||||
public int delete(String[] ids) {
|
||||
for (String id : ids) {
|
||||
repo.deleteById(id);
|
||||
}
|
||||
return ids.length;
|
||||
}
|
||||
|
||||
public T update(T main) {
|
||||
main.setUptim(new Date());
|
||||
if (main.getUpman() == null) {
|
||||
main.setUpman(XuserUtil.getUser());
|
||||
}
|
||||
return repo.save(main);
|
||||
}
|
||||
|
||||
public T save(T t) {
|
||||
return repo.save(t);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------bean注入-------------------------------------
|
||||
@Autowired
|
||||
protected JdbcDao jdbcDao;
|
||||
|
||||
protected JpaRepository<T, String> repo;
|
||||
|
||||
public void setRepo(JpaRepository<T, String> repo) {
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.zsvg.vboot.common.mvc.service;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import com.zsvg.vboot.common.mvc.dao.Sqler;
|
||||
import com.zsvg.vboot.common.mvc.api.PageData;
|
||||
import com.zsvg.vboot.common.mvc.entity.BaseEntity;
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public abstract class BaseService<T extends BaseEntity> {
|
||||
|
||||
//---------------------------------------查询-------------------------------------
|
||||
@Transactional(readOnly = true)
|
||||
public PageData findPageData(Sqler sqler) {
|
||||
return jdbcDao.findPageData(sqler);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Map<String, Object>> findMapList(Sqler sqler) {
|
||||
return jdbcDao.findMapList(sqler);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Map<String, Object>> findMapList(String sql,Object... args) {
|
||||
return jdbcDao.findMapList(sql,args);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public boolean existsById(String id) {
|
||||
return repo.existsById(id);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public T findOne(String id) {
|
||||
return repo.findById(id).get();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> findAll() {
|
||||
return repo.findAll();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------增删改-------------------------------------
|
||||
public T insert(T main) {
|
||||
if (main.getId() == null||"".equals(main.getId())) {
|
||||
main.setId(XstringUtil.getUUID());
|
||||
}
|
||||
return repo.save(main);
|
||||
}
|
||||
|
||||
public int delete(String[] ids) {
|
||||
for (String id : ids) {
|
||||
repo.deleteById(id);
|
||||
}
|
||||
return ids.length;
|
||||
}
|
||||
|
||||
public T update(T main) {
|
||||
return repo.save(main);
|
||||
}
|
||||
|
||||
public T save(T t) {
|
||||
return repo.save(t);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------bean注入-------------------------------------
|
||||
@Autowired
|
||||
protected JdbcDao jdbcDao;
|
||||
|
||||
protected JpaRepository<T, String> repo;
|
||||
|
||||
public void setRepo(JpaRepository<T, String> repo) {
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.zsvg.vboot.common.util.file;
|
||||
|
||||
import com.zsvg.vboot.common.util.lang.XdateUtil;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class XexcelUtil
|
||||
{
|
||||
//转换列数字序号列字母序号
|
||||
public static String excelColIndexToStr(int columnIndex)
|
||||
{
|
||||
if (columnIndex <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String columnStr = "";
|
||||
columnIndex--;
|
||||
do
|
||||
{
|
||||
if (columnStr.length() > 0)
|
||||
{
|
||||
columnIndex--;
|
||||
}
|
||||
columnStr = ((char) (columnIndex % 26 + (int) 'A')) + columnStr;
|
||||
columnIndex = ((columnIndex - columnIndex % 26) / 26);
|
||||
} while (columnIndex > 0);
|
||||
return columnStr;
|
||||
}
|
||||
|
||||
|
||||
//---------------------以下为EXCEL复制功能-----------------
|
||||
|
||||
|
||||
//行复制功能
|
||||
public static void copyRow(Row fromRow, Row toRow, boolean copyValueFlag) {
|
||||
toRow.setHeight(fromRow.getHeight());
|
||||
for(Iterator cellIt = fromRow.cellIterator(); cellIt.hasNext(); ) {
|
||||
Cell tmpCell = (Cell) cellIt.next();
|
||||
Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
|
||||
copyCell(tmpCell, newCell, copyValueFlag);
|
||||
}
|
||||
Sheet worksheet = fromRow.getSheet();
|
||||
for(int i = 0; i < worksheet.getNumMergedRegions(); i++) {
|
||||
CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
|
||||
if(cellRangeAddress.getFirstRow() == fromRow.getRowNum()) {
|
||||
CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +
|
||||
(cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress
|
||||
.getFirstColumn(), cellRangeAddress.getLastColumn());
|
||||
worksheet.addMergedRegionUnsafe(newCellRangeAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//复制单元格 true则连同cell的内容一起复制
|
||||
public static void copyCell(Cell srcCell, Cell distCell, boolean copyValueFlag) {
|
||||
//样式
|
||||
distCell.setCellStyle(srcCell.getCellStyle());
|
||||
//评论
|
||||
if(srcCell.getCellComment() != null) {
|
||||
distCell.setCellComment(srcCell.getCellComment());
|
||||
}
|
||||
// 不同数据类型处理
|
||||
CellType srcCellType = srcCell.getCellTypeEnum();
|
||||
distCell.setCellType(srcCellType);
|
||||
if(copyValueFlag) {
|
||||
if(srcCellType == CellType.NUMERIC) {
|
||||
if(DateUtil.isCellDateFormatted(srcCell)) {
|
||||
distCell.setCellValue(srcCell.getDateCellValue());
|
||||
} else {
|
||||
distCell.setCellValue(srcCell.getNumericCellValue());
|
||||
}
|
||||
} else if(srcCellType == CellType.STRING) {
|
||||
distCell.setCellValue(srcCell.getRichStringCellValue());
|
||||
} else if(srcCellType == CellType.BLANK) {
|
||||
|
||||
} else if(srcCellType == CellType.BOOLEAN) {
|
||||
distCell.setCellValue(srcCell.getBooleanCellValue());
|
||||
} else if(srcCellType == CellType.ERROR) {
|
||||
distCell.setCellErrorValue(srcCell.getErrorCellValue());
|
||||
} else if(srcCellType == CellType.FORMULA) {
|
||||
distCell.setCellFormula(srcCell.getCellFormula());
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//复制单元格 true则连同cell的内容一起复制
|
||||
public static HSSFCellStyle createCellStyle(HSSFWorkbook workbook,short index)
|
||||
{
|
||||
HSSFCellStyle style = workbook.createCellStyle();
|
||||
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
style.setFillForegroundColor(index);
|
||||
style.setBorderBottom(BorderStyle.HAIR);
|
||||
style.setBorderTop(BorderStyle.HAIR);
|
||||
style.setBorderLeft(BorderStyle.HAIR);
|
||||
style.setBorderRight(BorderStyle.HAIR);
|
||||
return style;
|
||||
}
|
||||
|
||||
public static Object getCellValue(Cell cell)
|
||||
{
|
||||
Object back = null;
|
||||
if (null != cell)
|
||||
{
|
||||
switch (cell.getCellType())
|
||||
{
|
||||
case Cell.CELL_TYPE_BLANK:
|
||||
back = null;
|
||||
break;
|
||||
case Cell.CELL_TYPE_BOOLEAN:
|
||||
back = Boolean.toString(cell.getBooleanCellValue());
|
||||
break;
|
||||
//数值
|
||||
case Cell.CELL_TYPE_NUMERIC:
|
||||
if (DateUtil.isCellDateFormatted(cell))
|
||||
{
|
||||
back = XdateUtil.getDate(cell.getDateCellValue());
|
||||
} else
|
||||
{
|
||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
||||
String temp = cell.getStringCellValue();
|
||||
//判断是否包含小数点,如果不含小数点,则以字符串读取,如果含小数点,则转换为Double类型的字符串
|
||||
if (temp.indexOf(".") > -1)
|
||||
{
|
||||
back = String.valueOf(new Double(temp)).trim();
|
||||
} else
|
||||
{
|
||||
back = temp.trim();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Cell.CELL_TYPE_STRING:
|
||||
back = cell.getStringCellValue().trim();
|
||||
if ("".equals(back))
|
||||
{
|
||||
back = null;
|
||||
}
|
||||
break;
|
||||
case Cell.CELL_TYPE_ERROR:
|
||||
back = null;
|
||||
break;
|
||||
case Cell.CELL_TYPE_FORMULA:
|
||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
||||
back = cell.getStringCellValue();
|
||||
break;
|
||||
default:
|
||||
back = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.zsvg.vboot.common.util.file;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class XfileUtil
|
||||
{
|
||||
public static String getFileSize(long fileS)
|
||||
{
|
||||
String size = "";
|
||||
DecimalFormat df = new DecimalFormat("#.00");
|
||||
if (fileS < 1024)
|
||||
{
|
||||
size = df.format((double) fileS) + "B";
|
||||
} else if (fileS < 1048576)
|
||||
{
|
||||
size = df.format((double) fileS / 1024) + "KB";
|
||||
} else if (fileS < 1073741824)
|
||||
{
|
||||
size = df.format((double) fileS / 1048576) + "MB";
|
||||
} else
|
||||
{
|
||||
size = df.format((double) fileS / 1073741824) + "GB";
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public static void unZipFiles(File zipFile,String descDir)throws IOException
|
||||
{
|
||||
File pathFile = new File(descDir);
|
||||
if(!pathFile.exists())
|
||||
{
|
||||
pathFile.mkdirs();
|
||||
}
|
||||
//解决zip文件中有中文目录或者中文文件
|
||||
ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
|
||||
for(Enumeration entries = zip.entries(); entries.hasMoreElements();)
|
||||
{
|
||||
ZipEntry entry = (ZipEntry)entries.nextElement();
|
||||
String zipEntryName = entry.getName();
|
||||
int len2=zipEntryName.split("/")[0].length();
|
||||
zipEntryName = zipEntryName.substring(len2, zipEntryName.length());
|
||||
System.out.println(zipEntryName);
|
||||
InputStream in = zip.getInputStream(entry);
|
||||
String outPath = (descDir+zipEntryName).replaceAll("\\*", "/");;
|
||||
//判断路径是否存在,不存在则创建文件路径
|
||||
File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
|
||||
if(!file.exists())
|
||||
{
|
||||
file.mkdirs();
|
||||
}
|
||||
//判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
|
||||
if(new File(outPath).isDirectory())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
//输出文件路径信息
|
||||
// System.out.println(outPath);
|
||||
OutputStream out = new FileOutputStream(outPath);
|
||||
byte[] buf1 = new byte[1024];
|
||||
int len;
|
||||
while((len=in.read(buf1))>0)
|
||||
{
|
||||
out.write(buf1,0,len);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
// System.out.println("******************解压完毕********************");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.zsvg.vboot.common.util.file;
|
||||
|
||||
import com.itextpdf.text.BaseColor;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.Element;
|
||||
import com.itextpdf.text.pdf.BaseFont;
|
||||
import com.itextpdf.text.pdf.PdfContentByte;
|
||||
import com.itextpdf.text.pdf.PdfGState;
|
||||
import com.itextpdf.text.pdf.PdfReader;
|
||||
import com.itextpdf.text.pdf.PdfStamper;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class XpdfUtil {
|
||||
// public static void main(String[] args) throws IOException {
|
||||
// setWatermark(new BufferedOutputStream(new FileOutputStream(new File("D:\\bb.pdf"))),
|
||||
// new FileInputStream("D:\\aa.pdf"), "借阅借阅水印借阅水印借阅水印水印", 1);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 中间或者两边水印
|
||||
* @param bos 添加完水印的输出
|
||||
* @param input 原PDF文件输入
|
||||
* @param word 水印内容
|
||||
* @param model 水印添加位置1中间,2两边
|
||||
*/
|
||||
public static void setWatermark(BufferedOutputStream bos, InputStream input, String word, int model) {
|
||||
PdfReader reader = null;
|
||||
try {
|
||||
reader = new PdfReader(input);
|
||||
PdfStamper stamper = new PdfStamper(reader, bos);
|
||||
PdfContentByte content;
|
||||
// 创建字体,第一个参数是字体路径,itext有一些默认的字体比如说:
|
||||
// BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
|
||||
//2 BaseFont base = BaseFont.createFont("/msyh.ttf", BaseFont.IDENTITY_H,
|
||||
// BaseFont.EMBEDDED);
|
||||
//这个是为了解决linux服务器,水印乱码问题,如果是windows服务器,用第一个就可以。
|
||||
// 需要指定的字体,用第2,3个写法,在resources文件夹下放置对应字体就行。
|
||||
|
||||
// BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
|
||||
BaseFont base = BaseFont.createFont("C:/WINDOWS/Fonts/simhei.ttf", BaseFont.IDENTITY_H,BaseFont.EMBEDDED);
|
||||
// BaseFont base = BaseFont.createFont();
|
||||
|
||||
PdfGState gs = new PdfGState();
|
||||
// 获取PDF页数
|
||||
int total = reader.getNumberOfPages();
|
||||
// 遍历每一页
|
||||
for (int i = 0; i < total; i++) {
|
||||
// 页宽度
|
||||
float width = reader.getPageSize(i + 1).getWidth();
|
||||
// 页高度
|
||||
float height = reader.getPageSize(i + 1).getHeight();
|
||||
// 内容
|
||||
content = stamper.getOverContent(i + 1);
|
||||
//开始写入文本
|
||||
content.beginText();
|
||||
//水印透明度
|
||||
gs.setFillOpacity(0.2f);
|
||||
content.setGState(gs);
|
||||
content.setColorFill(BaseColor.LIGHT_GRAY);
|
||||
//设置字体的输出位置
|
||||
content.setTextMatrix(70, 200);
|
||||
|
||||
if (model == 1) {
|
||||
//平行居中的3条水印
|
||||
//字体大小
|
||||
content.setFontAndSize(base, 50);
|
||||
//showTextAligned 方法的参数分别是(文字对齐方式,位置内容,输出水印X轴位置,Y轴位置,旋转角度)
|
||||
content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 650, 30);
|
||||
content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 400, 30);
|
||||
content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 150, 30);
|
||||
} else {
|
||||
// 左右两边个从上到下4条水印
|
||||
// 水印旋转度数
|
||||
float rotation = 30;
|
||||
content.setFontAndSize(base, 20);
|
||||
content.showTextAligned(Element.ALIGN_LEFT, word, 20, height - 50, rotation);
|
||||
content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 4 * 3 - 50, rotation);
|
||||
content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 2 - 50, rotation);
|
||||
content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 4 - 50, rotation);
|
||||
|
||||
content.setFontAndSize(base, 22);
|
||||
content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height - 50, rotation);
|
||||
content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 4 * 3 - 50, rotation);
|
||||
content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 2 - 50, rotation);
|
||||
content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 4 - 50, rotation);
|
||||
}
|
||||
//结束写入文本
|
||||
content.endText();
|
||||
//要打图片水印的话
|
||||
//Image image = Image.getInstance("c:/1.jpg");
|
||||
//content.addImage(image);
|
||||
}
|
||||
stamper.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.zsvg.vboot.common.util.file;
|
||||
|
||||
import com.google.zxing.*;
|
||||
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.google.zxing.qrcode.QRCodeReader;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class XqcodeUtil {
|
||||
/**
|
||||
* 生成包含字符串信息的二维码图片
|
||||
* @param outputStream 文件输出流路径
|
||||
* @param content 二维码携带信息
|
||||
* @param qrCodeSize 二维码图片大小
|
||||
* @param imageFormat 二维码的格式
|
||||
* @throws WriterException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean createQrCode(OutputStream outputStream, String content, int qrCodeSize, String imageFormat) throws WriterException, IOException{
|
||||
//设置二维码纠错级别MAP
|
||||
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
|
||||
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 矫错级别
|
||||
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||
//创建比特矩阵(位矩阵)的QR码编码的字符串
|
||||
BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
|
||||
// 使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点)
|
||||
int matrixWidth = byteMatrix.getWidth();
|
||||
BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
|
||||
image.createGraphics();
|
||||
Graphics2D graphics = (Graphics2D) image.getGraphics();
|
||||
graphics.setColor(Color.WHITE);
|
||||
graphics.fillRect(0, 0, matrixWidth, matrixWidth);
|
||||
// 使用比特矩阵画并保存图像
|
||||
graphics.setColor(Color.BLACK);
|
||||
for (int i = 0; i < matrixWidth; i++){
|
||||
for (int j = 0; j < matrixWidth; j++){
|
||||
if (byteMatrix.get(i, j)){
|
||||
graphics.fillRect(i-100, j-100, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ImageIO.write(image, imageFormat, outputStream);
|
||||
}
|
||||
|
||||
|
||||
public static InputStream createQrCode(String content, int qrCodeSize, String imageFormat) throws WriterException, IOException{
|
||||
//设置二维码纠错级别MAP
|
||||
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
|
||||
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 矫错级别
|
||||
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||
//创建比特矩阵(位矩阵)的QR码编码的字符串
|
||||
BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
|
||||
// 使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点)
|
||||
int matrixWidth = byteMatrix.getWidth();
|
||||
BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
|
||||
image.createGraphics();
|
||||
Graphics2D graphics = (Graphics2D) image.getGraphics();
|
||||
graphics.setColor(Color.WHITE);
|
||||
graphics.fillRect(0, 0, matrixWidth, matrixWidth);
|
||||
// 使用比特矩阵画并保存图像
|
||||
graphics.setColor(Color.BLACK);
|
||||
for (int i = 0; i < matrixWidth; i++){
|
||||
for (int j = 0; j < matrixWidth; j++){
|
||||
if (byteMatrix.get(i, j)){
|
||||
graphics.fillRect(i-100, j-100, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, imageFormat, os);
|
||||
return new ByteArrayInputStream(os.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读二维码并输出携带的信息
|
||||
*/
|
||||
public static void readQrCode(InputStream inputStream) throws IOException{
|
||||
//从输入流中获取字符串信息
|
||||
BufferedImage image = ImageIO.read(inputStream);
|
||||
//将图像转换为二进制位图源
|
||||
LuminanceSource source = new BufferedImageLuminanceSource(image);
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
QRCodeReader reader = new QRCodeReader();
|
||||
Result result = null ;
|
||||
try {
|
||||
result = reader.decode(bitmap);
|
||||
} catch (ReaderException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// System.out.println(result.getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试代码
|
||||
* @throws WriterException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException, WriterException {
|
||||
createQrCode(new FileOutputStream(new File("d:\\qrcode.jpg")),"WE1231238239128sASDASDSADSDWEWWREWRERWSDFDFSDSDF123123123123213123",900,"JPEG");
|
||||
readQrCode(new FileInputStream(new File("d:\\qrcode.jpg")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import javax.xml.datatype.DatatypeConfigurationException;
|
||||
import javax.xml.datatype.DatatypeFactory;
|
||||
import javax.xml.datatype.XMLGregorianCalendar;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class XdateUtil {
|
||||
|
||||
public static XMLGregorianCalendar dateToXmlDate(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
DatatypeFactory dtf = null;
|
||||
try {
|
||||
dtf = DatatypeFactory.newInstance();
|
||||
} catch (DatatypeConfigurationException e) {
|
||||
}
|
||||
XMLGregorianCalendar dateType = dtf.newXMLGregorianCalendar();
|
||||
dateType.setYear(cal.get(Calendar.YEAR));
|
||||
//由于Calendar.MONTH取值范围为0~11,需要加1
|
||||
dateType.setMonth(cal.get(Calendar.MONTH) + 1);
|
||||
dateType.setDay(cal.get(Calendar.DAY_OF_MONTH));
|
||||
dateType.setHour(cal.get(Calendar.HOUR_OF_DAY));
|
||||
dateType.setMinute(cal.get(Calendar.MINUTE));
|
||||
dateType.setSecond(cal.get(Calendar.SECOND));
|
||||
return dateType;
|
||||
}
|
||||
|
||||
public static Date xmlDate2Date(XMLGregorianCalendar cal) {
|
||||
return cal.toGregorianCalendar().getTime();
|
||||
}
|
||||
|
||||
public static String getYYYY() {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static String getYYYYMM() {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static String getMM() {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("MM");
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static String getDD() {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("dd");
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static Date strToDate(String strDate) {
|
||||
if (XstringUtil.isBlank(strDate)) {
|
||||
return null;
|
||||
}
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||
ParsePosition pos = new ParsePosition(0);
|
||||
Date strtodate = formatter.parse(strDate, pos);
|
||||
return strtodate;
|
||||
}
|
||||
|
||||
public static Date strToDateBySap(String strDate) {
|
||||
if (XstringUtil.isBlank(strDate)) {
|
||||
return null;
|
||||
}
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
|
||||
ParsePosition pos = new ParsePosition(0);
|
||||
Date strtodate = formatter.parse(strDate, pos);
|
||||
return strtodate;
|
||||
}
|
||||
|
||||
public static String getDate() {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static String getDate(int i) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
int day = c.get(Calendar.DATE);
|
||||
c.set(Calendar.DATE, day + i);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return dateFormat.format(c.getTime());
|
||||
}
|
||||
|
||||
public static String getSapDate(int i) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
int day = c.get(Calendar.DATE);
|
||||
c.set(Calendar.DATE, day + i);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
|
||||
return dateFormat.format(c.getTime());
|
||||
}
|
||||
|
||||
public static String getDate(String geshi) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(geshi);
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static String getDate(Date date) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
|
||||
public static int getDifferDays(Date data1, Date date2) {
|
||||
if (null == data1 || null == date2) {
|
||||
return -1;
|
||||
|
||||
}
|
||||
long intervalMilli = data1.getTime() - date2.getTime();
|
||||
return (int) (intervalMilli / (24 * 60 * 60 * 1000));
|
||||
}
|
||||
|
||||
public static int getDifferDays(String strDate1, String strDate2) {
|
||||
Date date1 = strToDate(strDate1);
|
||||
Date date2 = strToDate(strDate2);
|
||||
if (null == date1 || null == date2) {
|
||||
return -1;
|
||||
}
|
||||
long intervalMilli = date1.getTime() - date2.getTime();
|
||||
return (int) (intervalMilli / (24 * 60 * 60 * 1000));
|
||||
}
|
||||
|
||||
public static int getDifferDaysBySap(String strDate1, String strDate2) {
|
||||
Date date1 = strToDateBySap(strDate1);
|
||||
Date date2 = strToDateBySap(strDate2);
|
||||
if (null == date1 || null == date2) {
|
||||
return -1;
|
||||
}
|
||||
long intervalMilli = date1.getTime() - date2.getTime();
|
||||
return (int) (intervalMilli / (24 * 60 * 60 * 1000));
|
||||
}
|
||||
|
||||
public static String getStringDateAfterTian(String strDate, int i) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(strToDateBySap(strDate));
|
||||
int day = c.get(Calendar.DATE);
|
||||
c.set(Calendar.DATE, day + i);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
|
||||
return dateFormat.format(c.getTime());
|
||||
}
|
||||
|
||||
public static String getMonthFirstDay() {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.add(Calendar.MONTH, 0);
|
||||
c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
|
||||
return format.format(c.getTime());
|
||||
}
|
||||
|
||||
public static String getMonthLastDay() {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
|
||||
Calendar ca = Calendar.getInstance();
|
||||
ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
|
||||
return format.format(ca.getTime());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.pojo.Zinp;
|
||||
import com.zsvg.vboot.common.mvc.pojo.Ztree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class XjsonUtil {
|
||||
|
||||
|
||||
//使用递归方法建树
|
||||
public static List<Ztree> buildByRecursive(List<Ztree> treeNodes) {
|
||||
List<Ztree> trees = new ArrayList<>();
|
||||
for (Ztree treeNode : treeNodes) {
|
||||
if (treeNode.getPid()==null) {
|
||||
trees.add(findChildrenByTier(treeNode,treeNodes));
|
||||
}
|
||||
}
|
||||
return trees;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//递归查找子节点
|
||||
public static Ztree findChildrenByTier(Ztree treeNode, List<Ztree> treeNodes) {
|
||||
// treeNode.setChildren(new ArrayList<>());
|
||||
for (Ztree it : treeNodes) {
|
||||
if(treeNode.getId().equals(it.getPid())) {
|
||||
if (treeNode.getChildren() == null) {
|
||||
treeNode.setChildren(new ArrayList<>());
|
||||
}
|
||||
treeNode.getChildren().add(findChildrenByTier(it,treeNodes));
|
||||
}
|
||||
}
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
public static List<Ztree> inpToTree(List<Zinp> inpList) {
|
||||
List<Ztree> trees = new ArrayList<>();
|
||||
for (Zinp zinp : inpList) {
|
||||
if (zinp.getPid()==null) {
|
||||
trees.add(findChildrenByTree(zinp,inpList));
|
||||
}
|
||||
}
|
||||
return trees;
|
||||
}
|
||||
|
||||
|
||||
public static Ztree findChildrenByTree(Zinp zinp, List<Zinp> zinpList) {
|
||||
// treeNode.setChildren(new ArrayList<>());
|
||||
Ztree ztree =new Ztree();
|
||||
ztree.setId(zinp.getId());
|
||||
ztree.setName(zinp.getName());
|
||||
for (Zinp it : zinpList) {
|
||||
if(zinp.getId().equals(it.getPid())) {
|
||||
if (ztree.getChildren() == null) {
|
||||
ztree.setChildren(new ArrayList<>());
|
||||
}
|
||||
ztree.getChildren().add(findChildrenByTree(it,zinpList));
|
||||
}
|
||||
}
|
||||
return ztree;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
public class XmapUtil
|
||||
{
|
||||
public static String getName(String id)
|
||||
{
|
||||
String[] arr = id.split("/");
|
||||
String back = "";
|
||||
for (int i = 0; i < arr.length; i++)
|
||||
{
|
||||
if (!"".equals(arr[i]))
|
||||
{
|
||||
String mapValue = map.get(arr[i]);
|
||||
if (mapValue != null)
|
||||
{
|
||||
back += map.get(arr[i]) + "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
back += arr[i] + "-";
|
||||
}
|
||||
}
|
||||
}
|
||||
return back.substring(0, back.length() - 1);
|
||||
}
|
||||
|
||||
public static Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
static
|
||||
{
|
||||
//a
|
||||
map.put("admin", "管理员");
|
||||
map.put("address", "地址");
|
||||
map.put("att", "附件");
|
||||
map.put("auth", "认证");
|
||||
map.put("actual", "实际");
|
||||
//b
|
||||
map.put("bar", "块");
|
||||
//c
|
||||
map.put("choose", "选择");
|
||||
map.put("customer", "客户");
|
||||
map.put("config", "配置");
|
||||
map.put("choose_data", "选择数据");
|
||||
//d
|
||||
map.put("demo", "样例");
|
||||
//e
|
||||
map.put("edit", "编辑");
|
||||
map.put("edit_save", "编辑保存");
|
||||
|
||||
//f
|
||||
map.put("file", "文件");
|
||||
map.put("flow", "流程");
|
||||
|
||||
//g
|
||||
map.put("group", "组");
|
||||
|
||||
//l
|
||||
map.put("log", "日志");
|
||||
map.put("login", "登入");
|
||||
|
||||
//i
|
||||
map.put("index", "主页");
|
||||
map.put("info", "信息");
|
||||
//t
|
||||
map.put("task", "任务");
|
||||
map.put("type", "分类");
|
||||
|
||||
//m
|
||||
map.put("mail", "邮箱");
|
||||
map.put("main", "主信息");
|
||||
map.put("move", "移动");
|
||||
map.put("mobile", "移动端");
|
||||
//n
|
||||
map.put("node", "节点");
|
||||
|
||||
//o
|
||||
map.put("org", "组织架构");
|
||||
//p
|
||||
map.put("password", "密码");
|
||||
map.put("product", "产品");
|
||||
map.put("project", "项目");
|
||||
map.put("pp", "生产");
|
||||
//q
|
||||
map.put("quote", "报价");
|
||||
|
||||
//k
|
||||
|
||||
//l
|
||||
map.put("line", "线");
|
||||
map.put("list", "列表");
|
||||
map.put("list_data", "列表数据");
|
||||
map.put("list_dele", "列表删除");
|
||||
map.put("layout", "扶梯排布");
|
||||
|
||||
//r
|
||||
map.put("register", "注册");
|
||||
map.put("report", "报表");
|
||||
map.put("perm", "权限");
|
||||
map.put("role", "角色");
|
||||
map.put("scheme", "方案");
|
||||
|
||||
//s
|
||||
map.put("save", "保存");
|
||||
map.put("sd", "销售");
|
||||
map.put("send", "发送");
|
||||
map.put("set", "设置");
|
||||
map.put("show", "展示");
|
||||
map.put("stock", "股票");
|
||||
|
||||
//t
|
||||
map.put("task", "任务");
|
||||
map.put("template", "模块");
|
||||
map.put("test", "测试");
|
||||
map.put("tool", "工具");
|
||||
map.put("tree", "树");
|
||||
map.put("turn", "转换");
|
||||
map.put("tree_data", "树数据");
|
||||
map.put("tree_move", "树移动");
|
||||
map.put("tree_remove", "树删除");
|
||||
|
||||
//v
|
||||
map.put("view", "查看");
|
||||
|
||||
//w
|
||||
map.put("warn", "警告");
|
||||
map.put("weather", "天气");
|
||||
map.put("write", "撰写");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class XnumberUtil {
|
||||
public static double tsize = 1024L * 1024;
|
||||
|
||||
public static double gsize = 1024L;
|
||||
|
||||
|
||||
public static String tranWellSize(Long space) {
|
||||
|
||||
if (space > tsize) {
|
||||
return String.format("%.2f", space / tsize) + "T";
|
||||
} else if (space > gsize) {
|
||||
return String.format("%.2f", space / gsize) + "G";
|
||||
} else if(space>0){
|
||||
return space + "M";
|
||||
}else{
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
public static int getRandom6(){
|
||||
int radom = new Random().nextInt(999999);
|
||||
if (radom < 100000) {
|
||||
radom += 100000;
|
||||
}
|
||||
return radom;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import com.zsvg.vboot.common.util.obj.AlterPropertyInfo;
|
||||
import com.zsvg.vboot.common.util.obj.PropertyModelInfo;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
public class XreflectUtil {
|
||||
|
||||
public static void print(Object obj){
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
System.out.println("---------------------------------");
|
||||
for (Field field:fields) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
System.out.println(field.getName()+":"+field.get(obj));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较两个对象属性值是否相同
|
||||
* 如果不同返回修改过的属性信息
|
||||
* @param oldObj
|
||||
* @param newObj
|
||||
* @param ignoreProperties
|
||||
* @param <T>
|
||||
* @return 修改过的属性字段
|
||||
*/
|
||||
public static <T> List<AlterPropertyInfo> getDifferentProperty(T oldObj , T newObj , String... ignoreProperties){
|
||||
if (oldObj != null && newObj != null) {
|
||||
// 比较全部字段
|
||||
if (ignoreProperties == null || ignoreProperties.length > 0) {
|
||||
if (oldObj.equals(newObj)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
List<PropertyModelInfo> oldObjectPropertyValue = getObjectPropertyValue(oldObj, ignoreProperties);
|
||||
if (!CollectionUtils.isEmpty(oldObjectPropertyValue)) {
|
||||
List<AlterPropertyInfo> modifiedPropertyInfos = new ArrayList<>(oldObjectPropertyValue.size());
|
||||
|
||||
List<PropertyModelInfo> newObjectPropertyValue = getObjectPropertyValue(newObj, ignoreProperties);
|
||||
Map<String , Object> objectMap = new HashMap<>(newObjectPropertyValue.size());
|
||||
// 获取新对象所有属性值
|
||||
for (PropertyModelInfo propertyModelInfo : newObjectPropertyValue) {
|
||||
String prnam = propertyModelInfo.getPrnam();
|
||||
Object value = propertyModelInfo.getValue();
|
||||
objectMap.put(prnam , value);
|
||||
}
|
||||
|
||||
for (PropertyModelInfo propertyModelInfo : oldObjectPropertyValue) {
|
||||
String prnam = propertyModelInfo.getPrnam();
|
||||
Object value = propertyModelInfo.getValue();
|
||||
if (objectMap.containsKey(prnam)) {
|
||||
Object newValue = objectMap.get(prnam);
|
||||
AlterPropertyInfo modifiedPropertyInfo = new AlterPropertyInfo();
|
||||
// System.out.println("----------------------");
|
||||
// System.out.println(propertyName);
|
||||
// System.out.println(value);
|
||||
// System.out.println(newValue);
|
||||
if (value != null && newValue != null) {
|
||||
if(value instanceof BigDecimal){
|
||||
if ((new BigDecimal(value.toString())).compareTo(new BigDecimal(newValue.toString()))!=0) {
|
||||
modifiedPropertyInfo.setPrnam(prnam);
|
||||
modifiedPropertyInfo.setOlval(value);
|
||||
modifiedPropertyInfo.setNeval(newValue);
|
||||
modifiedPropertyInfos.add(modifiedPropertyInfo);
|
||||
}
|
||||
}else{
|
||||
if (!(value.toString()).equals(newValue.toString())) {
|
||||
modifiedPropertyInfo.setPrnam(prnam);
|
||||
modifiedPropertyInfo.setOlval(value);
|
||||
modifiedPropertyInfo.setNeval(newValue);
|
||||
modifiedPropertyInfos.add(modifiedPropertyInfo);
|
||||
}
|
||||
}
|
||||
}else if ((XstringUtil.isNotBlank(""+value)&& newValue == null) ||(value== null && XstringUtil.isNotBlank(""+newValue))){
|
||||
modifiedPropertyInfo.setPrnam(prnam);
|
||||
modifiedPropertyInfo.setOlval(value);
|
||||
modifiedPropertyInfo.setNeval(newValue);
|
||||
modifiedPropertyInfos.add(modifiedPropertyInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return modifiedPropertyInfos;
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过反射获取对象的属性名称、getter返回值类型、属性值等信息
|
||||
* @param obj
|
||||
* @param ignoreProperties
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<PropertyModelInfo> getObjectPropertyValue(T obj , String... ignoreProperties){
|
||||
if (obj != null) {
|
||||
|
||||
Class<?> objClass = obj.getClass();
|
||||
PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(objClass);
|
||||
List<PropertyModelInfo> modelInfos = new ArrayList<>(propertyDescriptors.length);
|
||||
|
||||
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
|
||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
|
||||
Method readMethod = propertyDescriptor.getReadMethod();
|
||||
String name = propertyDescriptor.getName();
|
||||
if (readMethod != null && (ignoreList == null || !ignoreList.contains(name))) {
|
||||
Object invoke = null;
|
||||
Class<?> returnType = readMethod.getReturnType();
|
||||
try {
|
||||
invoke = readMethod.invoke(obj);
|
||||
PropertyModelInfo propertyModelInfo = new PropertyModelInfo();
|
||||
propertyModelInfo.setPrnam(name);
|
||||
propertyModelInfo.setValue(invoke);
|
||||
propertyModelInfo.setRetyp(returnType);
|
||||
modelInfos.add(propertyModelInfo);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
System.out.println("反射获取类【"+objClass.getName()+"】方法异常,");
|
||||
}
|
||||
}
|
||||
}
|
||||
return modelInfos;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class XregUtil {
|
||||
public static boolean match(String reg, String str) {
|
||||
return Pattern.matches(reg, str);
|
||||
}
|
||||
|
||||
public static List<String> find(String reg, String str) {
|
||||
Matcher matcher = Pattern.compile(reg).matcher(str);
|
||||
List<String> list = new ArrayList<String>();
|
||||
while (matcher.find()) {
|
||||
list.add(matcher.group());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static String find(String reg, String str, int index) {
|
||||
Matcher matcher = Pattern.compile(reg).matcher(str);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String findString(String reg, String str) {
|
||||
String returnStr = null;
|
||||
List<String> list = find(reg, str);
|
||||
if (list.size() != 0)
|
||||
returnStr = list.get(0);
|
||||
return returnStr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public class XscanUtil
|
||||
{
|
||||
//从包package中获取所有的Class
|
||||
public static Set<Class<?>> getClasses(String pack) {
|
||||
|
||||
// 第一个class类的集合
|
||||
Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
|
||||
// 是否循环迭代
|
||||
boolean recursive = true;
|
||||
// 获取包的名字 并进行替换
|
||||
String packageName = pack;
|
||||
String packageDirName = packageName.replace('.', '/');
|
||||
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
|
||||
Enumeration<URL> dirs;
|
||||
try {
|
||||
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
||||
// 循环迭代下去
|
||||
while (dirs.hasMoreElements()) {
|
||||
// 获取下一个元素
|
||||
URL url = dirs.nextElement();
|
||||
// 得到协议的名称
|
||||
String protocol = url.getProtocol();
|
||||
// 如果是以文件的形式保存在服务器上
|
||||
if ("file".equals(protocol)) {
|
||||
// System.err.println("file类型的扫描");
|
||||
// 获取包的物理路径
|
||||
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
|
||||
// 以文件的方式扫描整个包下的文件 并添加到集合中
|
||||
findAndAddClassesInPackageByFile(packageName, filePath,recursive, classes);
|
||||
} else if ("jar".equals(protocol)) {
|
||||
// 如果是jar包文件
|
||||
// 定义一个JarFile
|
||||
// System.err.println("jar类型的扫描");
|
||||
JarFile jar;
|
||||
try {
|
||||
// 获取jar
|
||||
jar = ((JarURLConnection) url.openConnection())
|
||||
.getJarFile();
|
||||
// 从此jar包 得到一个枚举类
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
// 同样的进行循环迭代
|
||||
while (entries.hasMoreElements()) {
|
||||
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
|
||||
JarEntry entry = entries.nextElement();
|
||||
String name = entry.getName();
|
||||
// 如果是以/开头的
|
||||
if (name.charAt(0) == '/') {
|
||||
// 获取后面的字符串
|
||||
name = name.substring(1);
|
||||
}
|
||||
// 如果前半部分和定义的包名相同
|
||||
if (name.startsWith(packageDirName)) {
|
||||
int idx = name.lastIndexOf('/');
|
||||
// 如果以"/"结尾 是一个包
|
||||
if (idx != -1) {
|
||||
// 获取包名 把"/"替换成"."
|
||||
packageName = name.substring(0, idx)
|
||||
.replace('/', '.');
|
||||
}
|
||||
// 如果可以迭代下去 并且是一个包
|
||||
if ((idx != -1) || recursive) {
|
||||
// 如果是一个.class文件 而且不是目录
|
||||
if (name.endsWith(".class")
|
||||
&& !entry.isDirectory()) {
|
||||
// 去掉后面的".class" 获取真正的类名
|
||||
String className = name.substring(
|
||||
packageName.length() + 1, name
|
||||
.length() - 6);
|
||||
try {
|
||||
// 添加到classes
|
||||
classes.add(Class
|
||||
.forName(packageName + '.'
|
||||
+ className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
// log
|
||||
// .error("添加用户自定义视图类错误 找不到此类的.class文件");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// log.error("在扫描用户定义视图时从jar包获取文件出错");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
//以文件的形式来获取包下的所有Class
|
||||
public static void findAndAddClassesInPackageByFile(String packageName,
|
||||
String packagePath, final boolean recursive, Set<Class<?>> classes) {
|
||||
// 获取此包的目录 建立一个File
|
||||
File dir = new File(packagePath);
|
||||
// 如果不存在或者 也不是目录就直接返回
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
|
||||
return;
|
||||
}
|
||||
// 如果存在 就获取包下的所有文件 包括目录
|
||||
File[] dirfiles = dir.listFiles(new FileFilter() {
|
||||
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
|
||||
public boolean accept(File file) {
|
||||
return (recursive && file.isDirectory())
|
||||
|| (file.getName().endsWith(".class"));
|
||||
}
|
||||
});
|
||||
// 循环所有文件
|
||||
for (File file : dirfiles) {
|
||||
// 如果是目录 则继续扫描
|
||||
if (file.isDirectory()) {
|
||||
findAndAddClassesInPackageByFile(packageName + "."
|
||||
+ file.getName(), file.getAbsolutePath(), recursive,
|
||||
classes);
|
||||
} else {
|
||||
// 如果是java类文件 去掉后面的.class 只留下类名
|
||||
String className = file.getName().substring(0,
|
||||
file.getName().length() - 6);
|
||||
try {
|
||||
// 添加到集合中去
|
||||
//classes.add(Class.forName(packageName + '.' + className));
|
||||
//经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
|
||||
classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
// log.error("添加用户自定义视图类错误 找不到此类的.class文件");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class XstringUtil {
|
||||
|
||||
public static boolean containChinese(String str) {
|
||||
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
|
||||
Matcher m = p.matcher(str);
|
||||
if (m.find()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// public static boolean isEmpty(String str) {
|
||||
// return str == null || str.length() == 0|| "null".equals(str);
|
||||
// }
|
||||
//
|
||||
// public static boolean isNotEmpty(String str) {
|
||||
// return !XstringUtil.isEmpty(str);
|
||||
// }
|
||||
|
||||
public static boolean isBlank(String str) {
|
||||
int strLen;
|
||||
if (str == null || (strLen = str.length()) == 0|| "null".equals(str)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < strLen; i++) {
|
||||
if ((!Character.isWhitespace(str.charAt(i)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isAllBlank(String str1,String str2) {
|
||||
return XstringUtil.isBlank(str1)&&XstringUtil.isBlank(str2);
|
||||
}
|
||||
|
||||
public static boolean isAllBlank(String str1,String str2,String str3) {
|
||||
return XstringUtil.isBlank(str1)&&XstringUtil.isBlank(str2)&&XstringUtil.isBlank(str3);
|
||||
}
|
||||
|
||||
public static boolean isNotBlank(String str) {
|
||||
return !XstringUtil.isBlank(str);
|
||||
}
|
||||
|
||||
public static String addWhereInCondition(String field,List<String> list){
|
||||
if(list==null||list.size()==0){
|
||||
return " 1=0 ";
|
||||
}
|
||||
StringBuilder sb=new StringBuilder(field).append(" in (");
|
||||
for (String str : list) {
|
||||
sb.append("'").append(str).append("',");
|
||||
}
|
||||
sb.setCharAt(sb.length()-1,')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String getUUID()
|
||||
{
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
//生成随机字母和数字,
|
||||
public static String getRSID(int length) {
|
||||
String val = "";
|
||||
Random random = new Random();
|
||||
//参数length,表示生成几位随机数
|
||||
for(int i = 0; i < length; i++) {
|
||||
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
|
||||
//输出字母还是数字
|
||||
if( "char".equalsIgnoreCase(charOrNum) ) {
|
||||
//输出是大写字母还是小写字母
|
||||
// int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
|
||||
val += (char)(random.nextInt(26) + 97);
|
||||
} else if( "num".equalsIgnoreCase(charOrNum) ) {
|
||||
val += String.valueOf(random.nextInt(10));
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public static String getRSID4() {
|
||||
return getRSID(4);
|
||||
}
|
||||
|
||||
public static String getRSID8() {
|
||||
return getRSID(8);
|
||||
}
|
||||
|
||||
//首字母转小写
|
||||
public static String toLowerfirst(String s)
|
||||
{
|
||||
if (Character.isLowerCase(s.charAt(0)))
|
||||
{
|
||||
return s;
|
||||
} else
|
||||
{
|
||||
return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
|
||||
}
|
||||
}
|
||||
|
||||
//首字母转大写
|
||||
public static String toUpperfirst(String s)
|
||||
{
|
||||
if (Character.isUpperCase(s.charAt(0)))
|
||||
{
|
||||
return s;
|
||||
} else
|
||||
{
|
||||
return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String DelZeroBefore(String str){
|
||||
return str.replaceAll("^(0+)", "");
|
||||
}
|
||||
|
||||
public static String addZeroBefore(String str, int strLength) {
|
||||
int strLen = str.length();
|
||||
if (strLen < strLength) {
|
||||
while (strLen < strLength) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("0").append(str);// 左补0
|
||||
// sb.append(str).append("0");//右补0
|
||||
str = sb.toString();
|
||||
strLen = str.length();
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.zsvg.vboot.common.util.lang;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class XtimeUtil
|
||||
{
|
||||
private static long lastTime;
|
||||
private static long startTime;
|
||||
|
||||
public static String getTime()
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return sdf.format(new Date());
|
||||
}
|
||||
|
||||
public static void calStart()
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
|
||||
startTime=System.currentTimeMillis();
|
||||
lastTime=startTime;
|
||||
System.err.println("----"+sdf.format(new Date())+" 计时开始▼ ");
|
||||
}
|
||||
|
||||
public static void calMid()
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
|
||||
long curTime=System.currentTimeMillis();
|
||||
long time = curTime - lastTime;
|
||||
System.err.println("----"+sdf.format(new Date())+" 中间用时■ "+time + "毫秒");
|
||||
lastTime=curTime;
|
||||
}
|
||||
|
||||
public static void calEnd()
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
|
||||
long curTime=System.currentTimeMillis();
|
||||
long time = curTime - lastTime;
|
||||
long time2 = curTime - startTime;
|
||||
System.err.println("----"+sdf.format(new Date())+" 计时结束▲ "+time + "毫秒,合计:" + time2+ "毫秒");
|
||||
|
||||
}
|
||||
|
||||
public static String getTimeByDate(Date date)
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static Boolean compare(String s1, String s2)
|
||||
{
|
||||
if(s1==null){
|
||||
return false;
|
||||
}else if(s2==null){
|
||||
return true;
|
||||
}
|
||||
int i = s1.compareTo(s2);
|
||||
if (i >= 0)
|
||||
{
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static long getTimeGap(long beforeTimeMillis)
|
||||
{
|
||||
return (System.currentTimeMillis() - beforeTimeMillis) / 1000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.zsvg.vboot.common.util.obj;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class AlterPropertyInfo implements Serializable {
|
||||
|
||||
// 对应的属性名
|
||||
private String prnam;
|
||||
|
||||
// 未修改之前的值
|
||||
private Object olval;
|
||||
|
||||
// 修改后的值
|
||||
private Object neval;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.zsvg.vboot.common.util.obj;
|
||||
|
||||
import net.sf.json.JsonConfig;
|
||||
import net.sf.json.processors.JsonValueProcessor;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
public class JsonDateValueProcessor implements JsonValueProcessor {
|
||||
@Override
|
||||
public Object processArrayValue(Object obj, JsonConfig jsonconfig) {
|
||||
return process(obj);
|
||||
}
|
||||
@Override
|
||||
public Object processObjectValue(String s, Object obj, JsonConfig jsonconfig) {
|
||||
return process(obj);
|
||||
}
|
||||
private Object process(Object obj) {
|
||||
if (obj == null) {// 如果时间为null,则返回空字串
|
||||
return "";
|
||||
}
|
||||
if (obj instanceof Date) {
|
||||
obj = new java.util.Date(((Date) obj).getTime());
|
||||
}
|
||||
if (obj instanceof java.util.Date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
|
||||
Locale.CHINA);// 格式化时间为yyyy-MM-dd类型
|
||||
return sdf.format(obj);
|
||||
} else {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.zsvg.vboot.common.util.obj;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PropertyModelInfo {
|
||||
//属性名
|
||||
private String prnam;
|
||||
// 属性值
|
||||
private Object value;
|
||||
// 返回值类型
|
||||
private Class<?> retyp;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.zsvg.vboot.common.util.web;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
public class XhttpUtil {
|
||||
|
||||
public static String httpGetConnect(String httpUrl, String key) {
|
||||
String back = "error";
|
||||
if (StringUtils.isBlank(httpUrl)) {
|
||||
return back;
|
||||
}
|
||||
HttpURLConnection connection = null;
|
||||
InputStream is = null;
|
||||
BufferedReader br = null;
|
||||
String result = "";
|
||||
try {
|
||||
URL url = new URL(httpUrl);
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setRequestProperty("Content-Type", "text/html");
|
||||
connection.setRequestProperty("Cache-Control", "no-cache");
|
||||
connection.setRequestProperty("Charsert", "UTF-8");
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setReadTimeout(60000);
|
||||
connection.connect();
|
||||
if (connection.getResponseCode() == 200) {
|
||||
is = connection.getInputStream();
|
||||
// 封装输入流is,并指定字符集
|
||||
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
||||
// 存放数据
|
||||
StringBuffer sbf = new StringBuffer();
|
||||
String temp = null;
|
||||
while ((temp = br.readLine()) != null) {
|
||||
sbf.append(temp);
|
||||
//sbf.append("\r\n");
|
||||
}
|
||||
result = sbf.toString();
|
||||
back = result;
|
||||
} else {
|
||||
System.out.println("http链接错误!" + key);
|
||||
back = "error";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
back = "error";
|
||||
} finally {
|
||||
// 关闭资源
|
||||
if (null != br) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (null != is) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
connection.disconnect();// 关闭远程连接
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
public static String httpPostConnect(String httpUrl, String param, String key) {
|
||||
String back = "";
|
||||
if (StringUtils.isBlank(httpUrl)) {
|
||||
return back;
|
||||
}
|
||||
HttpURLConnection connection = null;
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
URL url = new URL(httpUrl);
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setReadTimeout(60000);
|
||||
/** 设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个 */
|
||||
// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
|
||||
connection.setDoOutput(true);
|
||||
// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
|
||||
connection.setDoInput(true);
|
||||
// 设置是否使用缓存
|
||||
connection.setUseCaches(false);
|
||||
/** 设置通用的请求属性 */
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
// 设置传入参数的格式
|
||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //name1=value1&name2=value2 的形式
|
||||
//connection.setRequestProperty("Content-Type", "application/json;charset=utf-8"); //json格式
|
||||
//connection.connect();
|
||||
|
||||
os = connection.getOutputStream();
|
||||
if (StringUtils.isNotBlank(param)) {
|
||||
os.write(param.getBytes());
|
||||
}
|
||||
|
||||
if (connection.getResponseCode() == 200) {
|
||||
is = connection.getInputStream();
|
||||
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
||||
StringBuffer sbf = new StringBuffer();
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
sbf.append(line);
|
||||
//sbf.append("\r\n");
|
||||
}
|
||||
back = sbf.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
back = "error";
|
||||
} finally {
|
||||
// 关闭资源
|
||||
try {
|
||||
if (null != br) {
|
||||
br.close();
|
||||
}
|
||||
if (null != is) {
|
||||
is.close();
|
||||
}
|
||||
if (null != os) {
|
||||
os.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
connection.disconnect();// 关闭远程连接
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.zsvg.vboot.common.util.web;
|
||||
|
||||
public class XpageUtil {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package com.zsvg.vboot.common.util.web;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.zsvg.vboot.common.mvc.dao.Sqler;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class XreqUtil {
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
public static final String PAGE_NUM = "page";
|
||||
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static final String PAGE_SIZE = "pageSize";
|
||||
|
||||
|
||||
public static void testParams(HttpServletRequest request) {
|
||||
Enumeration pNames = request.getParameterNames();
|
||||
while (pNames.hasMoreElements()) {
|
||||
String pName = (String) pNames.nextElement();
|
||||
Object pValue = request.getParameter(pName);
|
||||
System.out.println(pName + ":" + pValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getIpAddress(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
public static void setPageParam(Sqler sqler) {
|
||||
HttpServletRequest request = getRequest();
|
||||
Integer pageNum = Convert.toInt(request.getParameter(PAGE_NUM));
|
||||
Integer pageSize = Convert.toInt(request.getParameter(PAGE_SIZE));
|
||||
if(pageNum!=null){
|
||||
sqler.setPanum(pageNum);
|
||||
}
|
||||
if(pageSize!=null){
|
||||
sqler.setPasiz(pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取String参数
|
||||
*/
|
||||
public static String getParameter(String name)
|
||||
{
|
||||
return getRequest().getParameter(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取String参数
|
||||
*/
|
||||
public static String getParameter(String name, String defaultValue)
|
||||
{
|
||||
return Convert.toStr(getRequest().getParameter(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Integer参数
|
||||
*/
|
||||
public static Integer getParameterToInt(String name)
|
||||
{
|
||||
return Convert.toInt(getRequest().getParameter(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Integer参数
|
||||
*/
|
||||
public static Integer getParameterToInt(String name, Integer defaultValue)
|
||||
{
|
||||
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Boolean参数
|
||||
*/
|
||||
public static Boolean getParameterToBool(String name)
|
||||
{
|
||||
return Convert.toBool(getRequest().getParameter(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Boolean参数
|
||||
*/
|
||||
public static Boolean getParameterToBool(String name, Boolean defaultValue)
|
||||
{
|
||||
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取request
|
||||
*/
|
||||
public static HttpServletRequest getRequest()
|
||||
{
|
||||
return getRequestAttributes().getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取response
|
||||
*/
|
||||
public static HttpServletResponse getResponse()
|
||||
{
|
||||
return getRequestAttributes().getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取session
|
||||
*/
|
||||
public static HttpSession getSession()
|
||||
{
|
||||
return getRequest().getSession();
|
||||
}
|
||||
|
||||
public static ServletRequestAttributes getRequestAttributes()
|
||||
{
|
||||
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
|
||||
return (ServletRequestAttributes) attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串渲染到客户端
|
||||
*
|
||||
* @param response 渲染对象
|
||||
* @param string 待渲染的字符串
|
||||
* @return null
|
||||
*/
|
||||
public static String renderString(HttpServletResponse response, String string)
|
||||
{
|
||||
try
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.getWriter().print(string);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Ajax异步请求
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
// public static boolean isAjaxRequest(HttpServletRequest request)
|
||||
// {
|
||||
// String accept = request.getHeader("accept");
|
||||
// if (accept != null && accept.indexOf("application/json") != -1)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// String xRequestedWith = request.getHeader("X-Requested-With");
|
||||
// if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// String uri = request.getRequestURI();
|
||||
// if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// String ajax = request.getParameter("__ajax");
|
||||
// if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.zsvg.vboot.common.util.web;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class XresUtil {
|
||||
|
||||
|
||||
public static void downloadExcelXls(HttpServletResponse response, HSSFWorkbook workbook, String name) throws IOException
|
||||
{
|
||||
String fileName = URLEncoder.encode(name, "UTF-8");
|
||||
response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xls");
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
OutputStream out = response.getOutputStream();
|
||||
workbook.write(out);
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
public static void downloadExcelXlsx(HttpServletResponse response, XSSFWorkbook workbook, String name) throws IOException
|
||||
{
|
||||
String fileName = URLEncoder.encode(name, "UTF-8");
|
||||
response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
OutputStream out = response.getOutputStream();
|
||||
workbook.write(out);
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.zsvg.vboot.common.util.web;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
public class XspringUtil {
|
||||
|
||||
private static ApplicationContext applicationContext = null;
|
||||
|
||||
public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if(XspringUtil.applicationContext == null){
|
||||
XspringUtil.applicationContext = applicationContext;
|
||||
}
|
||||
}
|
||||
|
||||
public static ApplicationContext getApp() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
public static Object getBean(String name){
|
||||
return getApp().getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> clazz){
|
||||
return getApp().getBean(clazz);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name,Class<T> clazz){
|
||||
return getApp().getBean(name, clazz);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.zsvg.vboot.common.util.web;
|
||||
|
||||
import com.zsvg.vboot.module.sys.org.root.SysOrg;
|
||||
import com.zsvg.vboot.config.security.pojo.Zuser;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
public class XuserUtil {
|
||||
|
||||
public static String[] admins;
|
||||
|
||||
public static boolean isAdmin(String usnam) {
|
||||
if ("sa".equals(usnam)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < XuserUtil.admins.length; i++) {
|
||||
if (XuserUtil.admins[i].equals(usnam)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static SysOrg getUser() {
|
||||
String userId = null;
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
userId = calcUserId(userId, authentication);
|
||||
return new SysOrg(userId, "");
|
||||
}
|
||||
|
||||
public static String getUserId() {
|
||||
String userId = null;
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
userId = calcUserId(userId, authentication);
|
||||
return userId;
|
||||
}
|
||||
|
||||
private static String calcUserId(String userId, Authentication authentication) {
|
||||
if (authentication.getPrincipal() instanceof String) {
|
||||
userId = (String) authentication.getPrincipal();
|
||||
} else if (authentication.getPrincipal() instanceof Zuser) {
|
||||
Zuser zuser = (Zuser) authentication.getPrincipal();
|
||||
userId = zuser.getId();
|
||||
}
|
||||
return userId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.zsvg.vboot.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@Validated
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "zsvg")
|
||||
public class AppConfig {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Valid
|
||||
private Jwt jwt = new Jwt();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Jwt {
|
||||
private String header = "Authorization"; //HTTP 报头的认证字段的 key
|
||||
private String prefix = "Bearer "; //HTTP 报头的认证字段的值的前缀
|
||||
|
||||
private long atime = 28800L; //accessToken过期时间 此处单位秒 ,默认8小时 28800
|
||||
|
||||
private long rtime = 3456000L; //accessToken过期时间 此处单位秒 ,默认30天 3456000
|
||||
|
||||
private String akey;//生成accessToken用的key
|
||||
|
||||
private String rkey;//生成refreshToken用的key
|
||||
|
||||
|
||||
//以下赞未用到
|
||||
// //在线用户 key,根据 key 查询 redis 中在线用户的数据
|
||||
// private String onlineKey;
|
||||
//
|
||||
// //验证码 key
|
||||
// private String codeKey;
|
||||
//
|
||||
// //token 续期检查
|
||||
// private Long detect;
|
||||
//
|
||||
// //续期时间
|
||||
// private Long renew;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.zsvg.vboot.config.db.init;
|
||||
|
||||
import com.zsvg.vboot.module.sys.org.user.SysOrgUserRepo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class DbInitListener implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
|
||||
/**
|
||||
* 首次数据库生成后,初始化组织架构,菜单,权限角色等信息
|
||||
* 增加sa,admin管理员账号及相关测试账号
|
||||
* 判断依据是sys_org_user是否含有id为sa的账号
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
try {
|
||||
if (!userDao.existsById("sa")) {
|
||||
System.out.println("首次启动系统,正在进行数据库初始化,请耐心等待。");
|
||||
sysOrgInit.initCorp();
|
||||
System.out.println("1.1 初始化部门完毕");
|
||||
sysOrgInit.initUser();
|
||||
sysOrgInit.initZsf();
|
||||
sysOrgInit.initSa();
|
||||
System.out.println("1.2 初始化用户完毕");
|
||||
// sysOrgInit.initPost();
|
||||
// sysOrgInit.initGroup();
|
||||
|
||||
sysAuthInit.initMenu();
|
||||
System.out.println("2.1 初始化菜单完毕");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("初始化出错");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private SysOrgUserRepo userDao;
|
||||
|
||||
|
||||
@Autowired
|
||||
private SysOrgInit sysOrgInit;
|
||||
|
||||
@Autowired
|
||||
private SysAuthInit sysAuthInit;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.zsvg.vboot.config.db.init;
|
||||
|
||||
import com.zsvg.vboot.module.sys.auth.menu.SysAuthMenu;
|
||||
import com.zsvg.vboot.module.sys.auth.menu.SysAuthMenuService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SysAuthInit {
|
||||
|
||||
protected void initMenu() {
|
||||
SysAuthMenu menu1 = new SysAuthMenu();
|
||||
menu1.setId("Sys");
|
||||
menu1.setName("系统管理");
|
||||
menu1.setCode("Sys");
|
||||
menu1.setComp("LAYOUT");
|
||||
menu1.setPath("/sys");
|
||||
menu1.setRedirect("/sys/org/user");
|
||||
menu1.setOrnum(1);
|
||||
menu1.setIcon("ant-design:setting-outlined");
|
||||
menu1.setAvtag(true);
|
||||
menu1.setShtag(true);
|
||||
menu1.setType("D");
|
||||
menuService.insert(menu1);
|
||||
|
||||
SysAuthMenu menu11 = new SysAuthMenu();
|
||||
menu11.setId("SysOrg");
|
||||
menu11.setName("组织架构");
|
||||
menu11.setCode("SysOrg");
|
||||
menu11.setComp("LAYOUT");
|
||||
menu11.setPath("/sys/org");
|
||||
menu11.setRedirect("/sys/org/user");
|
||||
menu11.setOrnum(1);
|
||||
menu11.setIcon("ant-design:partition-outlined");
|
||||
menu11.setPid("Sys");
|
||||
menu11.setAvtag(true);
|
||||
menu11.setShtag(true);
|
||||
menu11.setType("D");
|
||||
menuService.insert(menu11);
|
||||
|
||||
SysAuthMenu menu111 = new SysAuthMenu();
|
||||
menu111.setId("SysOrgDept");
|
||||
menu111.setName("部门管理");
|
||||
menu111.setCode("SysOrgDept");
|
||||
menu111.setPath("/sys/org/dept");
|
||||
menu111.setComp("/sys/org/dept/index.vue");
|
||||
menu111.setOrnum(1);
|
||||
menu111.setPid("SysOrg");
|
||||
menu111.setCatag(false);
|
||||
menu111.setAvtag(true);
|
||||
menu111.setShtag(true);
|
||||
menu111.setType("M");
|
||||
menuService.insert(menu111);
|
||||
|
||||
SysAuthMenu menu112 = new SysAuthMenu();
|
||||
menu112.setId("SysOrgUser");
|
||||
menu112.setName("用户管理");
|
||||
menu112.setCode("SysOrgUser");
|
||||
menu112.setPath("/sys/org/user");
|
||||
menu112.setComp("/sys/org/user/index.vue");
|
||||
menu112.setOrnum(2);
|
||||
menu112.setPid("SysOrg");
|
||||
menu112.setCatag(false);
|
||||
menu112.setAvtag(true);
|
||||
menu112.setShtag(true);
|
||||
menu112.setType("M");
|
||||
menuService.insert(menu112);
|
||||
|
||||
SysAuthMenu menu113 = new SysAuthMenu();
|
||||
menu113.setId("SysOrgPost");
|
||||
menu113.setName("岗位管理");
|
||||
menu113.setCode("SysOrgPost");
|
||||
menu113.setPath("/sys/org/post");
|
||||
menu113.setComp("/sys/org/post/index.vue");
|
||||
menu113.setOrnum(3);
|
||||
menu113.setPid("SysOrg");
|
||||
menu113.setCatag(false);
|
||||
menu113.setAvtag(true);
|
||||
menu113.setShtag(true);
|
||||
menu113.setType("M");
|
||||
menuService.insert(menu113);
|
||||
|
||||
SysAuthMenu menu114 = new SysAuthMenu();
|
||||
menu114.setId("SysOrgGroup");
|
||||
menu114.setName("群组管理");
|
||||
menu114.setCode("SysOrgGroup");
|
||||
menu114.setPath("/sys/org/group");
|
||||
menu114.setComp("/sys/org/group/index.vue");
|
||||
menu114.setOrnum(4);
|
||||
menu114.setPid("SysOrg");
|
||||
menu114.setCatag(false);
|
||||
menu114.setAvtag(true);
|
||||
menu114.setShtag(true);
|
||||
menu114.setType("M");
|
||||
menuService.insert(menu114);
|
||||
|
||||
SysAuthMenu menu12 = new SysAuthMenu();
|
||||
menu12.setId("SysAuth");
|
||||
menu12.setName("权限管理");
|
||||
menu12.setCode("SysAuth");
|
||||
menu12.setComp("LAYOUT");
|
||||
menu12.setPath("/sys/auth");
|
||||
menu12.setRedirect("/sys/auth/menu");
|
||||
menu12.setOrnum(2);
|
||||
menu12.setIcon("ant-design:safety-certificate-outlined");
|
||||
menu12.setPid("Sys");
|
||||
menu12.setAvtag(true);
|
||||
menu12.setShtag(true);
|
||||
menu12.setType("D");
|
||||
menuService.insert(menu12);
|
||||
|
||||
SysAuthMenu menu121 = new SysAuthMenu();
|
||||
menu121.setId("SysAuthMenu");
|
||||
menu121.setName("菜单管理");
|
||||
menu121.setCode("SysAuthMenu");
|
||||
menu121.setPath("/sys/auth/menu");
|
||||
menu121.setComp("/sys/auth/menu/index.vue");
|
||||
menu121.setOrnum(1);
|
||||
menu121.setPid("SysAuth");
|
||||
menu121.setCatag(false);
|
||||
menu121.setAvtag(true);
|
||||
menu121.setShtag(true);
|
||||
menu121.setType("M");
|
||||
menuService.insert(menu121);
|
||||
|
||||
SysAuthMenu menu122 = new SysAuthMenu();
|
||||
menu122.setId("SysAuthRole");
|
||||
menu122.setName("角色管理");
|
||||
menu122.setCode("SysAuthRole");
|
||||
menu122.setPath("/sys/auth/role");
|
||||
menu122.setComp("/sys/auth/role/index.vue");
|
||||
menu122.setOrnum(1);
|
||||
menu122.setPid("SysAuth");
|
||||
menu122.setCatag(false);
|
||||
menu122.setAvtag(true);
|
||||
menu122.setShtag(true);
|
||||
menu122.setType("M");
|
||||
menuService.insert(menu122);
|
||||
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private SysAuthMenuService menuService;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
package com.zsvg.vboot.config.db.init;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import com.zsvg.vboot.module.sys.org.dept.SysOrgDeptService;
|
||||
import com.zsvg.vboot.module.sys.org.root.SysOrg;
|
||||
import com.zsvg.vboot.module.sys.org.user.SysOrgUser;
|
||||
import com.zsvg.vboot.module.sys.org.user.SysOrgUserService;
|
||||
import com.zsvg.vboot.module.sys.org.dept.SysOrgDept;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class SysOrgInit {
|
||||
|
||||
|
||||
//公司及子公司初始化
|
||||
protected void initCorp() throws Exception {
|
||||
List<SysOrgDept> deptList = new ArrayList<>();
|
||||
initDept(deptList,"刘", "LIU",1);
|
||||
initDept(deptList,"陈", "CHEN",2);
|
||||
initDept(deptList,"张", "ZHANG",3);
|
||||
initDept(deptList,"李", "LI",4);
|
||||
initDept(deptList,"王", "WANG",5);
|
||||
initDept(deptList,"赵", "ZHAO",6);
|
||||
initDept(deptList,"孙", "SUN",7);
|
||||
initDept(deptList,"周", "ZHOU",8);
|
||||
initDept(deptList,"吴", "WU",9);
|
||||
initDept(deptList,"郑", "ZHENG",10);
|
||||
deptService.insertAll(deptList);
|
||||
}
|
||||
|
||||
//部门初始化
|
||||
private void initDept(List<SysOrgDept> deptList,String name, String id,Integer ornum) throws Exception {
|
||||
SysOrgDept corp = new SysOrgDept();
|
||||
corp.setType(1);
|
||||
corp.setId(id);
|
||||
corp.setName(name + "家科技");
|
||||
corp.setLabel(id);
|
||||
corp.setOrnum(ornum);
|
||||
corp.setAvtag(true);
|
||||
corp.setTier("x"+id+"x");
|
||||
deptList.add(corp);
|
||||
|
||||
SysOrgDept dept1 = new SysOrgDept();
|
||||
dept1.setType(2);
|
||||
dept1.setId(id + "-1");
|
||||
dept1.setName(name + "一总金办");
|
||||
dept1.setLabel(id);
|
||||
dept1.setParent(new SysOrg(id));
|
||||
dept1.setOrnum(1);
|
||||
dept1.setAvtag(true);
|
||||
dept1.setTier("x"+id+"x"+id + "-1"+"x");
|
||||
deptList.add(dept1);
|
||||
|
||||
SysOrgDept dept2 = new SysOrgDept();
|
||||
dept2.setType(2);
|
||||
dept2.setId(id + "-2");
|
||||
dept2.setName(name + "二人事部");
|
||||
dept2.setLabel(id);
|
||||
dept2.setParent(new SysOrg(id));
|
||||
dept2.setOrnum(2);
|
||||
dept2.setAvtag(true);
|
||||
dept2.setTier("x"+id+"x"+id + "-2"+"x");
|
||||
deptList.add(dept2);
|
||||
|
||||
SysOrgDept dept3 = new SysOrgDept();
|
||||
dept3.setType(2);
|
||||
dept3.setId(id + "-3");
|
||||
dept3.setName(name + "三销售部");
|
||||
dept3.setLabel(id);
|
||||
dept3.setParent(new SysOrg(id));
|
||||
dept3.setOrnum(3);
|
||||
dept3.setAvtag(true);
|
||||
dept3.setTier("x"+id+"x"+id + "-3"+"x");
|
||||
deptList.add(dept3);
|
||||
|
||||
SysOrgDept dept4 = new SysOrgDept();
|
||||
dept4.setType(2);
|
||||
dept4.setId(id + "-4");
|
||||
dept4.setName(name + "四财务部");
|
||||
dept4.setLabel(id);
|
||||
dept4.setParent(new SysOrg(id));
|
||||
dept4.setOrnum(4);
|
||||
dept4.setAvtag(true);
|
||||
dept4.setTier("x"+id+"x"+id + "-4"+"x");
|
||||
deptList.add(dept4);
|
||||
|
||||
SysOrgDept dept5 = new SysOrgDept();
|
||||
dept5.setType(2);
|
||||
dept5.setId(id + "-5");
|
||||
dept5.setName(name + "五采购部");
|
||||
dept5.setLabel(id);
|
||||
dept5.setParent(new SysOrg(id));
|
||||
dept5.setOrnum(5);
|
||||
dept5.setAvtag(true);
|
||||
dept5.setTier("x"+id+"x"+id + "-5"+"x");
|
||||
deptList.add(dept5);
|
||||
|
||||
SysOrgDept dept6 = new SysOrgDept();
|
||||
dept6.setType(2);
|
||||
dept6.setId(id + "-6");
|
||||
dept6.setName(name + "六技术部");
|
||||
dept6.setLabel(id);
|
||||
dept6.setParent(new SysOrg(id));
|
||||
dept6.setOrnum(6);
|
||||
dept6.setAvtag(true);
|
||||
dept6.setTier("x"+id+"x"+id + "-6"+"x");
|
||||
deptList.add(dept6);
|
||||
|
||||
SysOrgDept dept7 = new SysOrgDept();
|
||||
dept7.setType(2);
|
||||
dept7.setId(id + "-7");
|
||||
dept7.setName(name + "七制造部");
|
||||
dept7.setLabel(id);
|
||||
dept7.setParent(new SysOrg(id));
|
||||
dept7.setOrnum(7);
|
||||
dept7.setAvtag(true);
|
||||
dept7.setTier("x"+id+"x"+id + "-7"+"x");
|
||||
deptList.add(dept7);
|
||||
|
||||
SysOrgDept dept8 = new SysOrgDept();
|
||||
dept8.setType(2);
|
||||
dept8.setId(id + "-8");
|
||||
dept8.setName(name + "八法务部");
|
||||
dept8.setLabel(id);
|
||||
dept8.setParent(new SysOrg(id));
|
||||
dept8.setOrnum(8);
|
||||
dept8.setAvtag(true);
|
||||
dept8.setTier("x"+id+"x"+id + "-8"+"x");
|
||||
deptList.add(dept8);
|
||||
|
||||
SysOrgDept dept9 = new SysOrgDept();
|
||||
dept9.setType(2);
|
||||
dept9.setId(id + "-9");
|
||||
dept9.setName(name + "九信息部");
|
||||
dept9.setLabel(id);
|
||||
dept9.setParent(new SysOrg(id));
|
||||
dept9.setOrnum(9);
|
||||
dept9.setAvtag(true);
|
||||
dept9.setTier("x"+id+"x"+id + "-9"+"x");
|
||||
deptList.add(dept9);
|
||||
|
||||
for (int i = 1; i <= 50; i++) {
|
||||
String RSID8= XstringUtil.getRSID8();
|
||||
SysOrgDept xdept = new SysOrgDept();
|
||||
xdept.setType(2);
|
||||
xdept.setId(id + "--"+i);
|
||||
xdept.setName(RSID8);
|
||||
xdept.setLabel(id);
|
||||
xdept.setParent(new SysOrg(id+"-"+(i%10==0?1:i%10)));
|
||||
xdept.setAvtag(true);
|
||||
xdept.setTier("x"+id+"x"+id+"-"+(i%10==0?1:i%10)+"x"+id + "--"+i+"x");
|
||||
deptList.add(xdept);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void initUser() {
|
||||
List<SysOrgUser> userList = new ArrayList<>();
|
||||
initUser(userList,"刘", "liu", "LIU");
|
||||
initUser(userList,"陈", "c", "CHEN");
|
||||
initUser(userList,"张", "z", "ZHANG");
|
||||
initUser(userList,"李", "l", "LI");
|
||||
initUser(userList,"王", "w", "WANG");
|
||||
initUser(userList,"赵", "zhao", "ZHAO");
|
||||
initUser(userList,"孙", "s", "SUN");
|
||||
initUser(userList,"周", "zhou", "ZHOU");
|
||||
initUser(userList,"吴", "wu", "WU");
|
||||
initUser(userList,"郑", "zheng", "ZHENG");
|
||||
userService.insertAll(userList);
|
||||
}
|
||||
|
||||
private void initUser(List<SysOrgUser> userList,String name, String id, String pid) {
|
||||
SysOrgUser user0 = new SysOrgUser();
|
||||
user0.setId(id+"lao");
|
||||
user0.setUsnam(id);
|
||||
user0.setName(name + "老");
|
||||
user0.setDept(new SysOrg(pid));
|
||||
user0.setPacod("1");//1
|
||||
user0.setAvtag(true);
|
||||
user0.setTier("x"+pid+"x"+id+"lao");
|
||||
userList.add(user0);
|
||||
|
||||
for (int i = 1; i <= 9; i++) {
|
||||
SysOrgUser userx = new SysOrgUser();
|
||||
userx.setId(id + i);
|
||||
userx.setUsnam(id + i);
|
||||
userx.setName(name + numChange("" + i));
|
||||
userx.setDept(new SysOrg(pid + "-" + i));
|
||||
userx.setOrnum(i);
|
||||
userx.setPacod("1");//1
|
||||
userx.setAvtag(true);
|
||||
userx.setTier("x"+pid+"x"+pid + "-" + i+"x"+id + i+"x");
|
||||
userList.add(userx);
|
||||
|
||||
for (int j = 1; j <= 9; j++) {
|
||||
SysOrgUser usery = new SysOrgUser();
|
||||
usery.setId(id + i + j);
|
||||
usery.setUsnam(id + i + j);
|
||||
usery.setName(name + numChange("" + i) + numChange("" + j));
|
||||
usery.setDept(new SysOrg(pid + "-" + i));
|
||||
usery.setOrnum(j);
|
||||
usery.setPacod("1");//1
|
||||
usery.setAvtag(true);
|
||||
usery.setTier("x"+pid+"x"+pid + "-" + i+"x"+id + i + j+"x");
|
||||
userList.add(usery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void initZsf() {
|
||||
|
||||
SysOrgDept dept1 = new SysOrgDept();
|
||||
dept1.setType(2);
|
||||
dept1.setId("ZHANG-3-1");
|
||||
dept1.setName("张三销售一室");
|
||||
dept1.setLabel("ZHANG");
|
||||
dept1.setParent(new SysOrg("ZHANG-3"));
|
||||
dept1.setOrnum(1);
|
||||
dept1.setAvtag(true);
|
||||
dept1.setTier("xZHANGxZHANG-3xZHANG-3-1x");
|
||||
deptService.insert(dept1);
|
||||
|
||||
SysOrgDept dept2 = new SysOrgDept();
|
||||
dept2.setType(2);
|
||||
dept2.setId("ZHANG-3-2");
|
||||
dept2.setName("张三销售二室");
|
||||
dept2.setLabel("ZHANG");
|
||||
dept2.setParent(new SysOrg("ZHANG-3"));
|
||||
dept2.setOrnum(1);
|
||||
dept2.setAvtag(true);
|
||||
dept2.setTier("xZHANGxZHANG-3xZHANG-3-2x");
|
||||
deptService.insert(dept2);
|
||||
|
||||
SysOrgUser user4 = new SysOrgUser();
|
||||
user4.setId("zsf");
|
||||
user4.setUsnam("zsf");
|
||||
user4.setName("张三丰");
|
||||
user4.setDept(new SysOrg("ZHANG-3-2"));
|
||||
user4.setOrnum(1);
|
||||
user4.setPacod("1");
|
||||
user4.setAvtag(true);
|
||||
user4.setTier("xZHANGxZHANG-3xZHANG-3-2xzsfx");
|
||||
userService.insert(user4);
|
||||
}
|
||||
|
||||
protected void initSa() {
|
||||
SysOrgUser user = new SysOrgUser();
|
||||
user.setId("sa");
|
||||
user.setUsnam("sa");
|
||||
user.setName("管理员");
|
||||
user.setPacod("1");
|
||||
user.setAvtag(true);
|
||||
user.setTier("xsax");
|
||||
userService.insert(user);
|
||||
|
||||
SysOrgUser user2 = new SysOrgUser();
|
||||
user2.setId("vben");
|
||||
user2.setUsnam("vben");
|
||||
user2.setName("小维");
|
||||
user2.setPacod("123456");
|
||||
user2.setAvtag(true);
|
||||
user2.setTier("xvbenx");
|
||||
userService.insert(user2);
|
||||
}
|
||||
|
||||
private String numChange(String num) {
|
||||
switch (num) {
|
||||
case "1":
|
||||
return "一";
|
||||
case "2":
|
||||
return "二";
|
||||
case "3":
|
||||
return "三";
|
||||
case "4":
|
||||
return "四";
|
||||
case "5":
|
||||
return "五";
|
||||
case "6":
|
||||
return "六";
|
||||
case "7":
|
||||
return "七";
|
||||
case "8":
|
||||
return "八";
|
||||
case "9":
|
||||
return "九";
|
||||
case "10":
|
||||
return "十";
|
||||
}
|
||||
return "零";
|
||||
}
|
||||
|
||||
//
|
||||
// //岗位初始化
|
||||
// private void initPost() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// //组织架构组初始化
|
||||
// private void initGroup() {
|
||||
//
|
||||
// }
|
||||
|
||||
@Autowired
|
||||
private JdbcDao jdbcDao;
|
||||
|
||||
@Autowired
|
||||
private SysOrgDeptService deptService;
|
||||
|
||||
@Autowired
|
||||
private SysOrgUserService userService;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.zsvg.vboot.config.dbx.ldap;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.ldap.core.support.LdapContextSource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
public class LdapConfig {
|
||||
|
||||
@Value("${ldap.url}")
|
||||
private String ldapUrl;
|
||||
|
||||
@Value("${ldap.base}")
|
||||
private String ldapBase;
|
||||
|
||||
@Value("${ldap.userDn}")
|
||||
private String ldapUserDn;
|
||||
|
||||
@Value("${ldap.userPwd}")
|
||||
private String ldapUserPwd;
|
||||
|
||||
@Value("${ldap.referral}")
|
||||
private String ldapReferral;
|
||||
|
||||
@Bean
|
||||
public LdapTemplate ldapTemplate() {
|
||||
return new LdapTemplate(contextSourceTarget());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LdapContextSource contextSourceTarget() {
|
||||
LdapContextSource ldapContextSource = new LdapContextSource();
|
||||
ldapContextSource.setUrl(ldapUrl);
|
||||
ldapContextSource.setBase(ldapBase);
|
||||
ldapContextSource.setUserDn(ldapUserDn);
|
||||
ldapContextSource.setPassword(ldapUserPwd);
|
||||
ldapContextSource.setReferral(ldapReferral);
|
||||
Map<String, Object> config = new HashMap();
|
||||
config.put("java.naming.ldap.attributes.binary", "objectGUID");
|
||||
// config.put("com.sun.jndi.ldap.read.timeout","3000");
|
||||
ldapContextSource.setPooled(false);
|
||||
ldapContextSource.setBaseEnvironmentProperties(config);
|
||||
return ldapContextSource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.zsvg.vboot.config.dbx.redis;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.zsvg.vboot.common.util.lang.XstringUtil;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
@ConditionalOnClass(RedisOperations.class)
|
||||
@EnableConfigurationProperties(RedisProperties.class)
|
||||
public class RedisConfig extends CachingConfigurerSupport {
|
||||
|
||||
/**
|
||||
* 设置 redis 数据默认过期时间,默认2小时
|
||||
* 设置@cacheable 序列化方式
|
||||
*/
|
||||
@Bean
|
||||
public RedisCacheConfiguration redisCacheConfiguration() {
|
||||
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
|
||||
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
|
||||
configuration = configuration.serializeValuesWith(RedisSerializationContext.
|
||||
SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(6));
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Bean(name = "redisTemplate")
|
||||
@ConditionalOnMissingBean(name = "redisTemplate")
|
||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<Object, Object> template = new RedisTemplate<>();
|
||||
//序列化
|
||||
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
|
||||
// value值的序列化采用fastJsonRedisSerializer
|
||||
template.setValueSerializer(fastJsonRedisSerializer);
|
||||
template.setHashValueSerializer(fastJsonRedisSerializer);
|
||||
// 全局开启AutoType,这里方便开发,使用全局的方式
|
||||
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
|
||||
// 建议使用这种方式,小范围指定白名单
|
||||
// ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain");
|
||||
// key的序列化采用StringRedisSerializer
|
||||
template.setKeySerializer(new StringRedisSerializer());
|
||||
template.setHashKeySerializer(new StringRedisSerializer());
|
||||
template.setConnectionFactory(redisConnectionFactory);
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义缓存key生成策略,默认将使用该策略
|
||||
*/
|
||||
@Bean
|
||||
@Override
|
||||
public KeyGenerator keyGenerator() {
|
||||
return (target, method, params) -> {
|
||||
Map<String, Object> container = new HashMap<>(3);
|
||||
Class<?> targetClassClass = target.getClass();
|
||||
// 类地址
|
||||
container.put("class", targetClassClass.toGenericString());
|
||||
// 方法名称
|
||||
container.put("methodName", method.getName());
|
||||
// 包名称
|
||||
container.put("package", targetClassClass.getPackage());
|
||||
// 参数列表
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
container.put(String.valueOf(i), params[i]);
|
||||
}
|
||||
// 转为JSON字符串
|
||||
String jsonString = JSON.toJSONString(container);
|
||||
// 做SHA256 Hash计算,得到一个SHA256摘要作为Key
|
||||
return DigestUtils.sha256Hex(jsonString);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public CacheErrorHandler errorHandler() {
|
||||
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
|
||||
log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
|
||||
return new CacheErrorHandler() {
|
||||
@Override
|
||||
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
|
||||
log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
|
||||
log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
|
||||
log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCacheClearError(RuntimeException e, Cache cache) {
|
||||
log.error("Redis occur handleCacheClearError:", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Value 序列化
|
||||
*
|
||||
* @param <T>
|
||||
* @author /
|
||||
*/
|
||||
class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
|
||||
|
||||
private final Class<T> clazz;
|
||||
|
||||
FastJsonRedisSerializer(Class<T> clazz) {
|
||||
super();
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(T t) {
|
||||
if (t == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deserialize(byte[] bytes) {
|
||||
if (bytes == null || bytes.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
String str = new String(bytes, StandardCharsets.UTF_8);
|
||||
return JSON.parseObject(str, clazz);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写序列化器
|
||||
*
|
||||
* @author /
|
||||
*/
|
||||
class StringRedisSerializer implements RedisSerializer<Object> {
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
StringRedisSerializer() {
|
||||
this(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private StringRedisSerializer(Charset charset) {
|
||||
Assert.notNull(charset, "Charset must not be null!");
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deserialize(byte[] bytes) {
|
||||
return (bytes == null ? null : new String(bytes, charset));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(Object object) {
|
||||
String string = JSON.toJSONString(object);
|
||||
if (XstringUtil.isBlank(string)) {
|
||||
return null;
|
||||
}
|
||||
string = string.replace("\"", "");
|
||||
return string.getBytes(charset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,693 @@
|
||||
package com.zsvg.vboot.config.dbx.redis;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisConnectionUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@SuppressWarnings({"unchecked", "all"})
|
||||
public class RedisHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(RedisHandler.class);
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
// @Value("${jwt.online-key}")
|
||||
private String onlineKey="online-key";
|
||||
|
||||
public RedisHandler(RedisTemplate<Object, Object> redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
*/
|
||||
public boolean expire(String key, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @param timeUnit 单位
|
||||
*/
|
||||
public boolean expire(String key, long time, TimeUnit timeUnit) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, timeUnit);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 key 获取过期时间
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @return 时间(秒) 返回0代表为永久有效
|
||||
*/
|
||||
public long getExpire(Object key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找匹配key
|
||||
*
|
||||
* @param pattern key
|
||||
* @return /
|
||||
*/
|
||||
public List<String> scan(String pattern) {
|
||||
ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
|
||||
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
|
||||
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
|
||||
Cursor<byte[]> cursor = rc.scan(options);
|
||||
List<String> result = new ArrayList<>();
|
||||
while (cursor.hasNext()) {
|
||||
result.add(new String(cursor.next()));
|
||||
}
|
||||
try {
|
||||
RedisConnectionUtils.releaseConnection(rc, factory);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询 key
|
||||
*
|
||||
* @param patternKey key
|
||||
* @param page 页码
|
||||
* @param size 每页数目
|
||||
* @return /
|
||||
*/
|
||||
public List<String> findKeysForPage(String patternKey, int page, int size) {
|
||||
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
|
||||
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
|
||||
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
|
||||
Cursor<byte[]> cursor = rc.scan(options);
|
||||
List<String> result = new ArrayList<>(size);
|
||||
int tmpIndex = 0;
|
||||
int fromIndex = page * size;
|
||||
int toIndex = page * size + size;
|
||||
while (cursor.hasNext()) {
|
||||
if (tmpIndex >= fromIndex && tmpIndex < toIndex) {
|
||||
result.add(new String(cursor.next()));
|
||||
tmpIndex++;
|
||||
continue;
|
||||
}
|
||||
// 获取到满足条件的数据后,就可以退出了
|
||||
if (tmpIndex >= toIndex) {
|
||||
break;
|
||||
}
|
||||
tmpIndex++;
|
||||
cursor.next();
|
||||
}
|
||||
try {
|
||||
RedisConnectionUtils.releaseConnection(rc, factory);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param key 可以传一个值 或多个
|
||||
*/
|
||||
public void del(String... keys) {
|
||||
if (keys != null && keys.length > 0) {
|
||||
if (keys.length == 1) {
|
||||
boolean result = redisTemplate.delete(keys[0]);
|
||||
log.debug("--------------------------------------------");
|
||||
log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString());
|
||||
log.debug("--------------------------------------------");
|
||||
} else {
|
||||
Set<Object> keySet = new HashSet<>();
|
||||
for (String key : keys) {
|
||||
keySet.addAll(redisTemplate.keys(key));
|
||||
}
|
||||
long count = redisTemplate.delete(keySet);
|
||||
log.debug("--------------------------------------------");
|
||||
log.debug("成功删除缓存:" + keySet.toString());
|
||||
log.debug("缓存删除数量:" + count + "个");
|
||||
log.debug("--------------------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================String=============================
|
||||
|
||||
/**
|
||||
* 普通缓存获取
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object get(String key) {
|
||||
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量获取
|
||||
*
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
public List<Object> multiGet(List<String> keys) {
|
||||
List list = redisTemplate.opsForValue().multiGet(Sets.newHashSet(keys));
|
||||
List resultList = Lists.newArrayList();
|
||||
Optional.ofNullable(list).ifPresent(e -> list.forEach(ele -> Optional.ofNullable(ele).ifPresent(resultList::add)));
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean set(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
set(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间
|
||||
* @param timeUnit 类型
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time, TimeUnit timeUnit) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, timeUnit);
|
||||
} else {
|
||||
set(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ================================Map=================================
|
||||
|
||||
/**
|
||||
* HashGet
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return 值
|
||||
*/
|
||||
public Object hget(String key, String item) {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取hashKey对应的所有键值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 对应的多个键值
|
||||
*/
|
||||
public Map<Object, Object> hmget(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @return true 成功 false 失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet 并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @param time 时间(秒)
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除hash表中的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 可以使多个 不能为null
|
||||
*/
|
||||
public void hdel(String key, Object... item) {
|
||||
redisTemplate.opsForHash().delete(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断hash表中是否有该项的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hHasKey(String key, String item) {
|
||||
return redisTemplate.opsForHash().hasKey(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public double hincr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, by);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要减少记(小于0)
|
||||
* @return
|
||||
*/
|
||||
public double hdecr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, -by);
|
||||
}
|
||||
|
||||
// ============================set=============================
|
||||
|
||||
/**
|
||||
* 根据key获取Set中的所有值
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public Set<Object> sGet(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据value从一个set中查询,是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean sHasKey(String key, Object value) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据放入set缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSet(String key, Object... values) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将set数据放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSetAndTime(String key, long time, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取set缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long sGetSetSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除值为value的
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long setRemove(String key, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().remove(key, values);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================list=================================
|
||||
|
||||
/**
|
||||
* 获取list缓存的内容
|
||||
*
|
||||
* @param key 键
|
||||
* @param start 开始
|
||||
* @param end 结束 0 到 -1代表所有值
|
||||
* @return
|
||||
*/
|
||||
public List<Object> lGet(String key, long start, long end) {
|
||||
try {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取list缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long lGetListSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过索引 获取list中的值
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
|
||||
* @return
|
||||
*/
|
||||
public Object lGetIndex(String key, long index) {
|
||||
try {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引修改list中的某条数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引
|
||||
* @param value 值
|
||||
* @return /
|
||||
*/
|
||||
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().set(key, index, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除N个值为value
|
||||
*
|
||||
* @param key 键
|
||||
* @param count 移除多少个
|
||||
* @param value 值
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long lRemove(String key, long count, Object value) {
|
||||
try {
|
||||
return redisTemplate.opsForList().remove(key, count, value);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prefix 前缀
|
||||
* @param ids id
|
||||
*/
|
||||
public void delByKeys(String prefix, Set<Long> ids) {
|
||||
Set<Object> keys = new HashSet<>();
|
||||
for (Long id : ids) {
|
||||
keys.addAll(redisTemplate.keys(new StringBuffer(prefix).append(id).toString()));
|
||||
}
|
||||
long count = redisTemplate.delete(keys);
|
||||
// 此处提示可自行删除
|
||||
log.debug("--------------------------------------------");
|
||||
log.debug("成功删除缓存:" + keys.toString());
|
||||
log.debug("缓存删除数量:" + count + "个");
|
||||
log.debug("--------------------------------------------");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.zsvg.vboot.config.security;
|
||||
|
||||
import com.zsvg.vboot.config.dbx.redis.RedisHandler;
|
||||
import com.zsvg.vboot.config.security.authn.AuthnFailedHandler;
|
||||
import com.zsvg.vboot.config.security.authz.AuthzDeniedHandler;
|
||||
import com.zsvg.vboot.config.security.jwt.JwtFilterAdapter;
|
||||
import com.zsvg.vboot.config.security.jwt.JwtHandler;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
//1.禁用JWT登录无关的相关功能
|
||||
http.headers().frameOptions().disable().and()
|
||||
.formLogin(AbstractHttpConfigurer::disable)
|
||||
.httpBasic(AbstractHttpConfigurer::disable)
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.logout(AbstractHttpConfigurer::disable)
|
||||
.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
|
||||
|
||||
//2.跨域处理
|
||||
http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
|
||||
|
||||
//3.启用JWT过滤器
|
||||
http.apply(securityConfigurerAdapter());
|
||||
|
||||
//4.过滤器异常与授权失败处理
|
||||
http.exceptionHandling()
|
||||
.authenticationEntryPoint(authnFailedHandler)
|
||||
.accessDeniedHandler(authzDeniedHandler);
|
||||
|
||||
//5.授权配置
|
||||
http.authorizeRequests(authorizeRequests -> authorizeRequests
|
||||
.antMatchers("/gen/**").permitAll()//gen通用的请求直接放行
|
||||
// .antMatchers("/sys/**").hasRole("ADMIN")//sys开头的需要管理员权限
|
||||
// .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()//放行OPTIONS请求
|
||||
.antMatchers("/**").access("@authzHandler.hasPermission(request, authentication)")//其他请求统一认证
|
||||
// .antMatchers("/getUserInfo").hasRole("xxx")
|
||||
.anyRequest().authenticated());
|
||||
|
||||
}
|
||||
|
||||
//<<-------------------------------2.跨域处理-------------------------------
|
||||
@Bean
|
||||
CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
// if (environment.acceptsProfiles(Profiles.of("dev"))) {
|
||||
// configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3100"));
|
||||
// } else {
|
||||
// configuration.setAllowedOrigins(Collections.singletonList("https://uaa.imooc.com"));
|
||||
// }
|
||||
// configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3100"));
|
||||
configuration.setAllowedOrigins(Collections.singletonList("*"));
|
||||
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||
configuration.setAllowedHeaders(Collections.singletonList("*"));
|
||||
configuration.addExposedHeader("X-Authenticate");
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
return source;
|
||||
}
|
||||
//>>
|
||||
|
||||
//<<-------------------------------3.启用JWT过滤器-------------------------------
|
||||
private final JwtHandler jwtHandler;
|
||||
|
||||
private final RedisHandler redisHandler;
|
||||
|
||||
//JwtFilter 如果通过@Component 注解注入,则web.ignoring().antMatchers 不起作用,还是会被拦截过滤
|
||||
private JwtFilterAdapter securityConfigurerAdapter() {
|
||||
return new JwtFilterAdapter(jwtHandler, redisHandler);
|
||||
}
|
||||
//>>
|
||||
|
||||
//<<-------------------------------4.过滤器异常与授权失败处理-------------------------------
|
||||
private final AuthzDeniedHandler authzDeniedHandler;//解决认证过的用户访问无权限资源时的异常
|
||||
|
||||
private final AuthnFailedHandler authnFailedHandler;//解决匿名用户访问无权限资源时的异常
|
||||
//>>
|
||||
|
||||
//<<-------------------------------X.其他配置-------------------------------
|
||||
//配置security忽略的请求与资源
|
||||
@Override
|
||||
public void configure(WebSecurity web) {
|
||||
web.ignoring().antMatchers("/**","/assets/**","/druid/**","/login", "/pub/**","/index.html","/vben.html","/favicon.ico","/resource/**","/_app.config.js");
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
// auth.authenticationProvider(ssLoginProvider);
|
||||
//// auth.userDetailsService(ssUserDetailsService).passwordEncoder( passwordEncoder());
|
||||
// }
|
||||
|
||||
// @Bean
|
||||
// public PasswordEncoder passwordEncoder() {
|
||||
// return new BCryptPasswordEncoder();
|
||||
// }
|
||||
//authn是认证相关的类,authz是授权相关的类
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.zsvg.vboot.config.security.authn;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.zsvg.vboot.common.mvc.api.RestResult;
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import com.zsvg.vboot.config.AppConfig;
|
||||
import com.zsvg.vboot.module.sys.org.user.SysOrgUserService;
|
||||
import com.zsvg.vboot.config.dbx.redis.RedisHandler;
|
||||
import com.zsvg.vboot.config.security.jwt.JwtHandler;
|
||||
import com.zsvg.vboot.config.security.pojo.Duser;
|
||||
import com.zsvg.vboot.config.security.pojo.Zmenu;
|
||||
import com.zsvg.vboot.config.security.pojo.Zmeta;
|
||||
import com.zsvg.vboot.config.security.pojo.Zuser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@RestController
|
||||
public class AuthnController {
|
||||
|
||||
@PostMapping("/login")
|
||||
public RestResult login(@Valid @RequestBody LoginDto loginDTO) throws IOException, ClassNotFoundException {
|
||||
System.out.println("开始登录");
|
||||
|
||||
//1.登录验证
|
||||
Duser duser = null;
|
||||
try {
|
||||
duser = jdbcDao.getTp().queryForObject("select id,name,pacod,retag from sys_org_user where usnam=? and avtag=1",
|
||||
new Object[]{loginDTO.getUsername()}, new BeanPropertyRowMapper<>(Duser.class));
|
||||
} catch (DataAccessException ignored) {
|
||||
|
||||
}
|
||||
|
||||
boolean passFlag = false;
|
||||
if (duser != null) {
|
||||
String encodePassword = DigestUtils.md5DigestAsHex(("abc" + loginDTO.getPassword() + "xyz").getBytes());//数据库密码验证
|
||||
if (encodePassword.equals(duser.getPacod())) {
|
||||
passFlag = true;
|
||||
} else {
|
||||
passFlag = ldapService.authenticate(loginDTO.getUsername(), loginDTO.getPassword());//AD域密码验证
|
||||
}
|
||||
}
|
||||
if (!passFlag) {
|
||||
return RestResult.build(402, "账号不存在或密码错误");
|
||||
}
|
||||
|
||||
//2.初始化用户信息,获取菜单与权限
|
||||
String atokenUUID = IdUtil.simpleUUID();
|
||||
String atoken = jwtHandler.createTokenByUuid(atokenUUID);
|
||||
String rtoken = jwtHandler.createTokenByUuid(loginDTO.getUsername());//需要加密下
|
||||
|
||||
Map<String, Object> backMap = new HashMap<>();
|
||||
backMap.put("token", atoken);
|
||||
backMap.put("rtoken", rtoken);
|
||||
|
||||
Zuser zuser = new Zuser(duser.getId(), duser.getName(), loginDTO.getUsername());
|
||||
authnService.initZuser(zuser, duser, backMap);//初始化用户
|
||||
|
||||
redisHandler.set(atokenUUID, zuser, appConfig.getJwt().getAtime());//默认8小时过期
|
||||
|
||||
//3.登录日志记录
|
||||
return RestResult.ok(backMap);
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/rtoken")
|
||||
public RestResult rtoken(@PathParam("token2") String token2) {
|
||||
System.out.println("token2=" + token2);
|
||||
String username = jwtHandler.getClaims(token2).getId();
|
||||
System.out.println("username=" + username);
|
||||
String uuid = IdUtil.simpleUUID();
|
||||
String token = jwtHandler.createTokenByUuid(uuid);
|
||||
Zuser zuser = authnService.getUser(username);
|
||||
redisHandler.set(uuid, zuser, 10000 / 1000);
|
||||
Map<String, Object> backMap = new HashMap<>();
|
||||
backMap.put("token", token);
|
||||
return RestResult.ok(backMap);
|
||||
}
|
||||
|
||||
@GetMapping("/getMenuList")
|
||||
public RestResult getMenuList(Authentication auth) {
|
||||
List<Zmenu> zmenuList = new ArrayList<>();
|
||||
Zmenu zmenu = new Zmenu();
|
||||
zmenu.setPath("/sys/org");
|
||||
zmenu.setName("SysOrg");
|
||||
zmenu.setComponent("LAYOUT");
|
||||
zmenu.setRedirect("/sys/org/user");
|
||||
Zmeta zmeta = new Zmeta();
|
||||
zmeta.setOrderNo(1);
|
||||
zmeta.setIcon("ant-design:apartment-outlined");
|
||||
zmeta.setTitle("组织架构");
|
||||
zmenu.setMeta(zmeta);
|
||||
zmenuList.add(zmenu);
|
||||
|
||||
Zmenu zmenu2 = new Zmenu();
|
||||
zmenu2.setPath("dept");
|
||||
zmenu2.setName("SysOrgDept");
|
||||
zmenu2.setComponent("/sys/org/dept/index.vue");
|
||||
Zmeta zmeta2 = new Zmeta();
|
||||
zmeta2.setOrderNo(1);
|
||||
zmeta2.setIcon("ant-design:apartment-outlined");
|
||||
zmeta2.setTitle("部门管理");
|
||||
zmeta2.setIgnoreKeepAlive(false);
|
||||
zmenu2.setMeta(zmeta2);
|
||||
|
||||
zmenu.setChildren(new ArrayList<>());
|
||||
zmenu.getChildren().add(zmenu2);
|
||||
|
||||
|
||||
// return RestResult.ok(authnService.findMenuList(auth));
|
||||
return RestResult.ok(zmenuList);
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private AuthnService authnService;
|
||||
|
||||
@Autowired
|
||||
private AppConfig appConfig;
|
||||
|
||||
@Autowired
|
||||
private RedisHandler redisHandler;
|
||||
|
||||
@Autowired
|
||||
private JwtHandler jwtHandler;
|
||||
|
||||
@Autowired
|
||||
private LdapService ldapService;
|
||||
|
||||
@Autowired
|
||||
private JdbcDao jdbcDao;
|
||||
|
||||
@Autowired
|
||||
private SysOrgUserService userService;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.zsvg.vboot.config.security.authn;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class AuthnFailedHandler implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
|
||||
if (!response.isCommitted()) {
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
response.setStatus(200);
|
||||
response.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
try (ServletOutputStream ous = response.getOutputStream()) {
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
map.put("code", HttpStatus.SC_UNAUTHORIZED);
|
||||
// map.put("code", HttpStatus.SC_OK);
|
||||
map.put("success", false);
|
||||
System.out.println(e.getMessage());
|
||||
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage());
|
||||
|
||||
map.put("message", Optional.ofNullable(request.getAttribute("errorMessage")).orElse("认证失败").toString());
|
||||
ous.write(JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
package com.zsvg.vboot.config.security.authn;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import com.zsvg.vboot.config.security.pojo.Duser;
|
||||
import com.zsvg.vboot.config.security.pojo.Zmenu;
|
||||
import com.zsvg.vboot.config.security.pojo.Zmeta;
|
||||
import com.zsvg.vboot.config.security.pojo.Zuser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class AuthnService {
|
||||
|
||||
public void initZuser(Zuser zuser, Duser duser, Map<String, Object> backMap) {
|
||||
if (!duser.getRetag()) {
|
||||
//1.获取用户所有的组织架构集:conds
|
||||
String conds = findConds(duser);
|
||||
zuser.setConds(conds);
|
||||
|
||||
//2.根据组织架构集conds查询前台菜单集:menus
|
||||
List<Zmenu> menuList = findMenuList(zuser.getConds());
|
||||
|
||||
//3.根据组织架构集conds查询前台按钮集:btns
|
||||
List<String> btnList = findBtnList(zuser.getConds());
|
||||
|
||||
//4.计算后台缓存的url权限集
|
||||
List<String> permList = new ArrayList<>();
|
||||
for (Zmenu menu : menuList) {
|
||||
if (StrUtil.isNotBlank(menu.getPerm())) {
|
||||
permList.add(menu.getPerm());
|
||||
}
|
||||
}
|
||||
permList.addAll(btnList);
|
||||
zuser.setPermList(permList);
|
||||
|
||||
//5.设置前台返回数据
|
||||
menuList = buildTree(menuList);
|
||||
backMap.put("menus", menuList);
|
||||
backMap.put("btns", btnList);
|
||||
backMap.put("zuser", zuser);
|
||||
|
||||
//6.更新用户,序列化保存数据,使下次这些数据可直接从数据库取
|
||||
updateUser(zuser, menuList, btnList);
|
||||
System.out.println("通过数据库");
|
||||
|
||||
} else {
|
||||
String sql = "select conds,menus,btns,perms from sys_org_user where id=?";
|
||||
Map<String, Object> map = jdbcDao.findMap(sql, zuser.getId());
|
||||
|
||||
zuser.setConds((String) map.get("conds"));
|
||||
|
||||
List<Zmenu> menuList = JSON.parseArray((String) map.get("menus"), Zmenu.class);
|
||||
|
||||
String[] btnArr = null;
|
||||
String btns = (String) map.get("btns");
|
||||
if (btns != null) {
|
||||
btnArr = btns.split(";");
|
||||
}
|
||||
|
||||
String[] permArr = null;
|
||||
String perms = (String) map.get("perms");
|
||||
if (perms != null) {
|
||||
permArr = perms.split(";");
|
||||
}
|
||||
List<String> permList = new ArrayList<>();
|
||||
if (permArr != null) {
|
||||
permList = Arrays.asList(permArr);
|
||||
}
|
||||
|
||||
zuser.setPermList(permList);
|
||||
backMap.put("menus", menuList);
|
||||
backMap.put("btns", btnArr);
|
||||
backMap.put("zuser", zuser);
|
||||
System.out.println("通过缓存");
|
||||
}
|
||||
|
||||
// //初始化数据库user
|
||||
// String perms = "";
|
||||
// for (int i = 0; i < permSum.length; i++) {
|
||||
// perms += permSum[i] + ";";
|
||||
// }
|
||||
// if (!perms.equals("")) {
|
||||
// perms = perms.substring(0, perms.length() - 1);
|
||||
// } else {
|
||||
// perms = "0";
|
||||
// }
|
||||
// updatePerson(perms, conds, id);
|
||||
// zuser = new Zuser(id, "" + orgInfo.get("name"), sysOrgUser.getUsnam(), permSum, conds);
|
||||
// zuser.setAdmin(XuserUtil.isAdmin(sysOrgUser.getUsnam()));
|
||||
// zuser.setWatag(sysOrgUser.getWatag());
|
||||
// } else {
|
||||
// String[] permArr = sysOrgUser.getPerms().split(";");
|
||||
// long[] permSum = new long[permArr.length];
|
||||
// for (int i = 0; i < permArr.length; i++) {
|
||||
// permSum[i] = Long.parseLong(permArr[i]);
|
||||
// }
|
||||
// zuser = new Zuser(id, "" + orgInfo.get("name"), "" + sysOrgUser.getUsnam(), permSum, sysOrgUser.getConds());
|
||||
// zuser.setAdmin(XuserUtil.isAdmin(sysOrgUser.getUsnam()));
|
||||
// zuser.setWatag(sysOrgUser.getWatag());
|
||||
// }
|
||||
// return zuser;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// private void calcPerms(Zuser zuser,){
|
||||
// //查询权限集合
|
||||
// Integer posSum = SysAuthPermService.AUTHPOS + 1;//取出最大权限位
|
||||
// long[] permSum = new long[posSum];
|
||||
////
|
||||
// List<Zperm> zpermList = getPermList(conds);
|
||||
// for (Zperm zperm : zpermList) {
|
||||
// for (int i = 0; i < posSum; i++) {
|
||||
// if (i == zperm.getPos()) {
|
||||
// permSum[i] = permSum[i] + zperm.getCode();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
private String findConds(Duser duser) {
|
||||
StringBuilder conds = new StringBuilder();
|
||||
//1. conds拼接父级id
|
||||
if (StrUtil.isNotBlank(duser.getTier())) {
|
||||
String[] pidArr = duser.getTier().split("x");
|
||||
for (int i = pidArr.length - 1; i >= 0; i--) {
|
||||
if (!"".equals(pidArr[i])) {
|
||||
conds.append("'").append(pidArr[i]).append("',");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
conds = new StringBuilder("'" + duser.getId() + "',");
|
||||
}
|
||||
//2. conds拼接岗位id
|
||||
List<String> postList = findPostList(duser.getId());
|
||||
for (String str : postList) {
|
||||
conds.append("'").append(str).append("',");
|
||||
}
|
||||
conds = new StringBuilder(conds.substring(0, conds.length() - 1));//优化
|
||||
//3. conds拼接群组id
|
||||
List<String> groupList = findGroupList(conds.toString());
|
||||
for (String str : groupList) {
|
||||
conds.append(",'").append(str).append("'");
|
||||
}
|
||||
return conds.toString();
|
||||
}
|
||||
|
||||
|
||||
private List<String> findPostList(String uid) {
|
||||
String sql = "select pid as id from sys_org_post_user where uid=?";
|
||||
return jdbcDao.findStringList(sql, uid);
|
||||
}
|
||||
|
||||
private List<String> findGroupList(String conds) {
|
||||
String sql = "select DISTINCT gid as id from sys_org_group_org where oid in (" + conds + ")";
|
||||
return jdbcDao.findStringList(sql);
|
||||
}
|
||||
|
||||
|
||||
private List<Zmenu> findMenuList(String conds) {
|
||||
String sql = "select distinct m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm from sys_auth_menu m inner join sys_auth_role_menu rm on rm.mid=m.id inner join sys_auth_role_org ru on ru.rid=rm.rid where m.type in ('D','M') and m.avtag=1 and ru.oid in (" + conds + ") order by m.ornum";
|
||||
if(conds.contains("'sa'")||conds.contains("'vben'")){
|
||||
sql = "select m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm from sys_auth_menu m where m.type in ('D','M') and m.avtag=1 order by m.ornum";
|
||||
}
|
||||
|
||||
List<Zmenu> list = jdbcDao.getTp().query(sql, (rs, rowNum) -> {
|
||||
Zmenu zmenu = new Zmenu();
|
||||
zmenu.setId(rs.getString("id"));
|
||||
zmenu.setPid(rs.getString("pid"));
|
||||
zmenu.setPerm(rs.getString("perm"));
|
||||
zmenu.setName(rs.getString("code"));
|
||||
zmenu.setPath(rs.getString("path"));
|
||||
zmenu.setComponent(rs.getString("comp"));
|
||||
Zmeta zmeta = new Zmeta();
|
||||
zmeta.setTitle(rs.getString("name"));
|
||||
zmeta.setOrderNo(rs.getInt("ornum"));
|
||||
zmeta.setIcon(rs.getString("icon"));
|
||||
zmenu.setMeta(zmeta);
|
||||
return zmenu;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
//使用递归方法建树
|
||||
private List<Zmenu> buildTree(List<Zmenu> treeNodes) {
|
||||
List<Zmenu> trees = new ArrayList<>();
|
||||
for (Zmenu treeNode : treeNodes) {
|
||||
if (treeNode.getPid() == null) {
|
||||
trees.add(recTree(treeNode, treeNodes));
|
||||
}
|
||||
}
|
||||
return trees;
|
||||
}
|
||||
|
||||
|
||||
//递归查找子节点
|
||||
private Zmenu recTree(Zmenu treeNode, List<Zmenu> treeNodes) {
|
||||
for (Zmenu it : treeNodes) {
|
||||
if (treeNode.getId().equals(it.getPid())) {
|
||||
if (treeNode.getChildren() == null) {
|
||||
treeNode.setChildren(new ArrayList<>());
|
||||
}
|
||||
treeNode.getChildren().add(recTree(it, treeNodes));
|
||||
}
|
||||
}
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
|
||||
private List<String> findBtnList(String conds) {
|
||||
String sql = "select distinct m.perm id from sys_auth_menu m inner join sys_auth_role_menu rm on rm.mid=m.id inner join sys_auth_role_org ru on ru.rid=rm.rid where m.type = 'B' and m.avtag=1 and ru.oid in (" + conds + ") order by m.ornum";
|
||||
if(conds.contains("'sa'")||conds.contains("'vben'")){
|
||||
sql = "select m.perm id from sys_auth_menu m where m.type = 'B' and m.avtag=1 order by m.ornum";
|
||||
}
|
||||
return jdbcDao.findStringList(sql);
|
||||
}
|
||||
|
||||
|
||||
private void updateUser(Zuser zuser, List<Zmenu> menuList, List<String> btnList) {
|
||||
|
||||
String menus = JSON.toJSONString(menuList);
|
||||
StringBuilder btns = new StringBuilder();
|
||||
for (String str : btnList) {
|
||||
btns.append(str).append(";");
|
||||
}
|
||||
|
||||
StringBuilder perms = new StringBuilder();
|
||||
for (String str : zuser.getPermList()) {
|
||||
perms.append(str).append(";");
|
||||
}
|
||||
|
||||
String sql = "update sys_org_user set conds=?,menus=?,btns=?,perms=?,retag=1 where id=?";
|
||||
jdbcDao.update(sql, zuser.getConds(), menus, btns.toString(), perms.toString(), zuser.getId());
|
||||
}
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Zuser getUser(String username) {
|
||||
Map<String, Object> map = jdbcDao.getTp().queryForMap("select u.id,u.name from sys_org_user u where u.usnam=? and u.avtag=1", username);
|
||||
Zuser user = new Zuser();
|
||||
user.setId((String) map.get("id"));
|
||||
user.setName((String) map.get("name"));
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private JdbcDao jdbcDao;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.zsvg.vboot.config.security.authn;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
@Service
|
||||
public class LdapService {
|
||||
|
||||
@Autowired
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
@Value("${ldap.domainName}")
|
||||
private String ldapDomainName;
|
||||
|
||||
@Value("${ldap.base}")
|
||||
private String ldapBaseDn;
|
||||
|
||||
public boolean authenticate(String userName, String password) {
|
||||
//String userDomainName = getDnForUser(userName);
|
||||
String userDomainName = String.format(ldapDomainName, userName);
|
||||
DirContext ctx = null;
|
||||
try {
|
||||
ctx = ldapTemplate.getContextSource().getContext(userDomainName, password);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
} finally {
|
||||
LdapUtils.closeContext(ctx);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.zsvg.vboot.config.security.authn;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LoginDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@NotNull
|
||||
private String username;
|
||||
|
||||
@NotNull
|
||||
private String password;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.zsvg.vboot.config.security.authz;
|
||||
|
||||
|
||||
import com.zsvg.vboot.common.mvc.api.RestResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class AuthzController {
|
||||
|
||||
|
||||
@GetMapping("/getUserInfo")
|
||||
public RestResult getUserInfo(Authentication auth) {
|
||||
|
||||
return RestResult.ok("test");
|
||||
}
|
||||
|
||||
@GetMapping("/getPermCode")
|
||||
public RestResult getPermCode(Authentication auth) {
|
||||
|
||||
return RestResult.ok("test");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@GetMapping("/com/getZuser")
|
||||
public RestResult getZuser(Authentication auth) {
|
||||
return RestResult.ok("test");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Autowired
|
||||
private AuthzService authzService;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.zsvg.vboot.config.security.authz;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class AuthzDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
|
||||
response.setStatus(403);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
response.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
|
||||
try (ServletOutputStream ous = response.getOutputStream()) {
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
map.put("code", HttpStatus.SC_FORBIDDEN);
|
||||
map.put("success", false);
|
||||
map.put("message", Optional.ofNullable(request.getAttribute("errorMessage")).orElse("授权失败").toString());
|
||||
ous.write(JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.zsvg.vboot.config.security.authz;
|
||||
|
||||
import com.zsvg.vboot.config.security.pojo.Zuser;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Component
|
||||
public class AuthzHandler {
|
||||
|
||||
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
|
||||
String uri=request.getRequestURI();
|
||||
Zuser zuser = (Zuser) authentication.getPrincipal();
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.zsvg.vboot.config.security.authz;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.dao.JdbcDao;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class AuthzService {
|
||||
|
||||
|
||||
// public List<Zmenu> findMenuList(Authentication auth) {
|
||||
// String sql = "select name,code,path,icon,comp,ornum,id,pid from sys_auth_menu where type in ('D','M') and avtag=1 order by ornum";
|
||||
// List<Zmenu> list=jdbcDao.getTp().query(sql, (rs, rowNum) -> {
|
||||
// Zmenu zmenu = new Zmenu();
|
||||
// zmenu.setId(rs.getString("id"));
|
||||
// zmenu.setPid(rs.getString("pid"));
|
||||
// zmenu.setName(rs.getString("code"));
|
||||
// zmenu.setPath(rs.getString("path"));
|
||||
// zmenu.setComponent(rs.getString("comp"));
|
||||
// Zmeta zmeta = new Zmeta();
|
||||
// zmeta.setTitle(rs.getString("name"));
|
||||
// zmeta.setOrderNo(rs.getInt("ornum"));
|
||||
// zmeta.setIcon(rs.getString("icon"));
|
||||
// zmenu.setMeta(zmeta);
|
||||
// return zmenu;
|
||||
// });
|
||||
// return buildByRecursive(list);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// //使用递归方法建树
|
||||
// public List<Zmenu> buildByRecursive(List<Zmenu> treeNodes) {
|
||||
// List<Zmenu> trees = new ArrayList<>();
|
||||
// for (Zmenu treeNode : treeNodes) {
|
||||
// if (treeNode.getPid()==null) {
|
||||
// trees.add(findChildrenByTier(treeNode,treeNodes));
|
||||
// }
|
||||
// }
|
||||
// return trees;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// //递归查找子节点
|
||||
// public Zmenu findChildrenByTier(Zmenu treeNode, List<Zmenu> treeNodes) {
|
||||
//// treeNode.setChildren(new ArrayList<>());
|
||||
// for (Zmenu it : treeNodes) {
|
||||
// if(treeNode.getId().equals(it.getPid())) {
|
||||
// if (treeNode.getChildren() == null) {
|
||||
// treeNode.setChildren(new ArrayList<>());
|
||||
// }
|
||||
// treeNode.getChildren().add(findChildrenByTier(it,treeNodes));
|
||||
// }
|
||||
// }
|
||||
// return treeNode;
|
||||
// }
|
||||
|
||||
|
||||
@Autowired
|
||||
private JdbcDao jdbcDao;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.zsvg.vboot.config.security.jwt;
|
||||
|
||||
import com.zsvg.vboot.config.dbx.redis.RedisHandler;
|
||||
import com.zsvg.vboot.config.security.pojo.Zuser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
public class JwtFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtHandler jwtHandler;
|
||||
|
||||
private final RedisHandler redisHandler;
|
||||
|
||||
|
||||
public JwtFilter(JwtHandler jwtHandler, RedisHandler redisHandler) {
|
||||
this.jwtHandler = jwtHandler;
|
||||
this.redisHandler = redisHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
|
||||
// System.out.println("拦截的URL:" + request.getRequestURI());
|
||||
String token = jwtHandler.getToken(request);
|
||||
if (token != null) {
|
||||
String uuid = jwtHandler.getClaims(token).getId();
|
||||
// System.out.println("过滤器:uuid:" + uuid);
|
||||
Zuser zuser = (Zuser) redisHandler.get(uuid);
|
||||
if (zuser != null) {
|
||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(zuser, null, zuser.getAuthorities());
|
||||
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||
} else {
|
||||
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "当前登录状态过期");
|
||||
throw new BadCredentialsException("当前登录状态过期");
|
||||
}
|
||||
}
|
||||
|
||||
//测试用时
|
||||
String uri = request.getRequestURI();
|
||||
String ip = request.getRemoteAddr();
|
||||
long start = System.currentTimeMillis();
|
||||
log.debug(ip + "--" + uri + "--开始▼...");
|
||||
chain.doFilter(request, response);
|
||||
long time = (System.currentTimeMillis() - start);
|
||||
if (time > 3000) {
|
||||
log.warn(ip + "--" +uri + "--结束▲...用时:" + time / 1000 + "秒");
|
||||
} else {
|
||||
log.debug(ip + "--"+uri + "--结束▲...用时:" + time + "毫秒");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.zsvg.vboot.config.security.jwt;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.zsvg.vboot.config.dbx.redis.RedisHandler;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class JwtFilterAdapter extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||
|
||||
private final JwtHandler jwtHandler;
|
||||
private final RedisHandler redisHandler;
|
||||
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
JwtFilter jwtFilter = new JwtFilter(jwtHandler, redisHandler);
|
||||
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.zsvg.vboot.config.security.jwt;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.zsvg.vboot.config.AppConfig;
|
||||
import com.zsvg.vboot.config.dbx.redis.RedisHandler;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.security.Key;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Component
|
||||
public class JwtHandler implements InitializingBean {
|
||||
|
||||
private final Key key; // 用于签名 Access Token
|
||||
private final Key refreshKey; // 用于签名 Refresh Token
|
||||
private final AppConfig appConfig;
|
||||
private JwtParser jwtParser;
|
||||
private JwtBuilder jwtBuilder;
|
||||
private final RedisHandler redisHandler;
|
||||
|
||||
public JwtHandler(AppConfig appConfig, RedisHandler redisHandler) {
|
||||
this.appConfig = appConfig;
|
||||
this.redisHandler = redisHandler;
|
||||
key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(appConfig.getJwt().getAkey()));
|
||||
refreshKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(appConfig.getJwt().getRkey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
jwtParser = Jwts.parserBuilder().setSigningKey(key).build();
|
||||
jwtBuilder = Jwts.builder().signWith(key, SignatureAlgorithm.HS512);
|
||||
}
|
||||
|
||||
//创建Token 设置永不过期,Token 的时间有效性转到Redis 维护
|
||||
public String createToken(Authentication authentication) {
|
||||
return jwtBuilder
|
||||
// 加入ID确保生成的 Token 都不一致
|
||||
.setId(IdUtil.simpleUUID())
|
||||
.claim("user", authentication.getName())
|
||||
.setSubject(authentication.getName())
|
||||
.compact();
|
||||
}
|
||||
|
||||
public String createTokenByUuid(String uuid) {
|
||||
// System.out.println("uuidz:" + uuid);
|
||||
return jwtBuilder
|
||||
.setId(uuid)
|
||||
.claim("username", uuid)
|
||||
.setSubject(uuid)
|
||||
.compact();
|
||||
}
|
||||
|
||||
|
||||
//依据Token 获取鉴权信息
|
||||
Authentication getAuthentication(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
|
||||
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
|
||||
}
|
||||
|
||||
public Claims getClaims(String token) {
|
||||
return jwtParser
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
//需要检查的token
|
||||
// public void checkRenewal(String token) {
|
||||
// // 判断是否续期token,计算token的过期时间
|
||||
// long time = redisHandler.getExpire("online" + token) * 1000;
|
||||
// Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
|
||||
// // 判断当前时间与过期时间的时间差
|
||||
// long differ = expireDate.getTime() - System.currentTimeMillis();
|
||||
// // 如果在续期检查的范围内,则续期
|
||||
// if (differ <= appConfig.getJwt().getDetect()) {
|
||||
// long renew = time + appConfig.getJwt().getRenew();
|
||||
// redisHandler.expire(appConfig.getJwt().getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
|
||||
// }
|
||||
// }
|
||||
|
||||
public String getToken(HttpServletRequest request) {
|
||||
final String requestHeader = request.getHeader(appConfig.getJwt().getHeader());
|
||||
if (requestHeader != null && requestHeader.startsWith(appConfig.getJwt().getPrefix())) {
|
||||
return requestHeader.substring(7);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.zsvg.vboot.config.security.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Duser {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String pacod;
|
||||
|
||||
private Boolean retag;
|
||||
|
||||
private String tier;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.zsvg.vboot.config.security.pojo;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class Zmenu implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@JsonIgnore
|
||||
@JSONField(serialize = false)
|
||||
private String id;
|
||||
|
||||
@JsonIgnore
|
||||
@JSONField(serialize = false)
|
||||
private String pid;
|
||||
|
||||
@JsonIgnore
|
||||
@JSONField(serialize = false)
|
||||
private String perm;
|
||||
|
||||
private String path;
|
||||
|
||||
private String name;
|
||||
|
||||
private String component;
|
||||
|
||||
private Zmeta meta;
|
||||
|
||||
private String redirect;
|
||||
|
||||
private List<Zmenu> children;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.zsvg.vboot.config.security.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class Zmeta implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String title;
|
||||
|
||||
private String affix;
|
||||
|
||||
private String icon;
|
||||
|
||||
private Integer orderNo;
|
||||
|
||||
private Boolean ignoreKeepAlive;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.zsvg.vboot.config.security.pojo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class Zuser implements UserDetails, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2487878824333265058L;
|
||||
|
||||
private String id;//用户ID
|
||||
|
||||
private String name;//用户名称
|
||||
|
||||
private Boolean watag;
|
||||
|
||||
private String usnam;//用户名
|
||||
|
||||
@JsonIgnore//前端不需要
|
||||
private long[] permArr;//权限集,用于验证URL权限 比较下哪个方式快1
|
||||
|
||||
@JsonIgnore
|
||||
private List<String> permList;//权限集,用于验证URL权限 比较下哪个方式快2
|
||||
|
||||
@JsonIgnore//前端不需要
|
||||
private String conds;//组织架构集,用户ID,所有上级部门ID,岗位ID,群组ID
|
||||
|
||||
public Zuser(String id, String name, String usnam, long[] perms, String conds) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.usnam = usnam;
|
||||
this.conds = conds;
|
||||
this.permArr = perms;
|
||||
}
|
||||
|
||||
|
||||
public Zuser() {
|
||||
|
||||
}
|
||||
|
||||
public Zuser(String id, String name, String usnam) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.usnam = usnam;
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
private boolean isAdmin;
|
||||
|
||||
public boolean isAdmin() {
|
||||
return isAdmin;
|
||||
}
|
||||
|
||||
public void setAdmin(boolean admin) {
|
||||
isAdmin = admin;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasPerm(int pos, long code) {
|
||||
if (isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
if (permArr.length <= pos) {
|
||||
return false;
|
||||
}
|
||||
long ret = permArr[pos] & code;
|
||||
return !(ret == 0);
|
||||
}
|
||||
|
||||
//----------------------------UserDetails------------------------------------------------
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.getUsnam();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//@JSONField(serialize = false)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.zsvg.vboot.config.web;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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 {
|
||||
@Bean
|
||||
public WebMvcConfigurer corsConfigurer() {
|
||||
return new WebMvcConfigurer() {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
// .allowedHeaders("Authorization")
|
||||
.allowedOrigins("*")
|
||||
.allowCredentials(true)
|
||||
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
|
||||
.maxAge(3600);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.zsvg.vboot.config.web;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
@Value("${http.maxTotal}")
|
||||
private Integer maxTotal;
|
||||
|
||||
@Value("${http.defaultMaxPerRoute}")
|
||||
private Integer defaultMaxPerRoute;
|
||||
|
||||
@Value("${http.connectTimeout}")
|
||||
private Integer connectTimeout;
|
||||
|
||||
@Value("${http.connectionRequestTimeout}")
|
||||
private Integer connectionRequestTimeout;
|
||||
|
||||
@Value("${http.socketTimeout}")
|
||||
private Integer socketTimeout;
|
||||
|
||||
@Value("${http.staleConnectionCheckEnabled}")
|
||||
private boolean staleConnectionCheckEnabled;
|
||||
|
||||
@Value("${http.validateAfterInactivity}")
|
||||
private Integer validateAfterInactivity;
|
||||
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate(httpRequestFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ClientHttpRequestFactory httpRequestFactory() {
|
||||
return new HttpComponentsClientHttpRequestFactory(httpClient());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpClient httpClient() {
|
||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
||||
.build();
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
|
||||
connectionManager.setMaxTotal(maxTotal); // 最大连接数
|
||||
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); //单个路由最大连接数
|
||||
connectionManager.setValidateAfterInactivity(validateAfterInactivity); // 最大空间时间
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setSocketTimeout(socketTimeout) //服务器返回数据(response)的时间,超过抛出read timeout
|
||||
.setConnectTimeout(connectTimeout) //连接上服务器(握手成功)的时间,超出抛出connect timeout
|
||||
.setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // 提交前检测是否可用
|
||||
.setConnectionRequestTimeout(connectionRequestTimeout)//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
|
||||
.build();
|
||||
return HttpClientBuilder.create()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setConnectionManager(connectionManager)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.zsvg.vboot.config.web;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class WebSocketConfig {
|
||||
/**
|
||||
* ServerEndpointExporter 作用
|
||||
*
|
||||
* 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
//影响单元测试所以先注释了
|
||||
// @Bean
|
||||
// public ServerEndpointExporter serverEndpointExporter() {
|
||||
// return new ServerEndpointExporter();
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.zsvg.vboot.config.web;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.websocket.*;
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
//影响单元测试所以先注释了
|
||||
//@ServerEndpoint("/webSocket/{sid}")
|
||||
@Component
|
||||
public class WebSocketServer {
|
||||
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
|
||||
private static AtomicInteger onlineNum = new AtomicInteger();
|
||||
|
||||
//concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
|
||||
private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
|
||||
|
||||
//发送消息
|
||||
public void sendMessage(Session session, String message) throws IOException {
|
||||
if(session != null){
|
||||
synchronized (session) {
|
||||
// System.out.println("发送数据:" + message);
|
||||
session.getBasicRemote().sendText(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
//给指定用户发送信息
|
||||
public void sendInfo(String userName, String message){
|
||||
Session session = sessionPools.get(userName);
|
||||
try {
|
||||
sendMessage(session, message);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//建立连接成功调用
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam(value = "sid") String userName){
|
||||
sessionPools.put(userName, session);
|
||||
addOnlineCount();
|
||||
System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
|
||||
try {
|
||||
sendMessage(session, "欢迎" + userName + "加入连接!");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//关闭连接时调用
|
||||
@OnClose
|
||||
public void onClose(@PathParam(value = "sid") String userName){
|
||||
sessionPools.remove(userName);
|
||||
subOnlineCount();
|
||||
System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);
|
||||
}
|
||||
|
||||
//收到客户端信息
|
||||
@OnMessage
|
||||
public void onMessage(String message) throws IOException{
|
||||
message = "客户端:" + message + ",已收到";
|
||||
System.out.println(message);
|
||||
for (Session session: sessionPools.values()) {
|
||||
try {
|
||||
sendMessage(session, message);
|
||||
} catch(Exception e){
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//错误时调用
|
||||
@OnError
|
||||
public void onError(Session session, Throwable throwable){
|
||||
System.out.println("发生错误");
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
public static void addOnlineCount(){
|
||||
onlineNum.incrementAndGet();
|
||||
}
|
||||
|
||||
public static void subOnlineCount() {
|
||||
onlineNum.decrementAndGet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.zsvg.vboot.module.ass.dict.cate;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import com.zsvg.vboot.common.mvc.entity.BaseCateEntity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
public class AssDictCate extends BaseCateEntity {
|
||||
|
||||
private String notes;//备注
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.zsvg.vboot.module.ass.dict.cate;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.api.RestResult;
|
||||
import com.zsvg.vboot.common.mvc.dao.Sqler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("ass/dict/cate")
|
||||
public class AssDictCateApi {
|
||||
|
||||
private String table = "ass_dict_cate";
|
||||
|
||||
@GetMapping
|
||||
public RestResult get(String name) {
|
||||
Sqler sqler = new Sqler(table);
|
||||
sqler.addLike("t.name", name);
|
||||
sqler.addSelect("t.notes,t.ornum");
|
||||
return RestResult.ok(service.findPageData(sqler));
|
||||
}
|
||||
|
||||
@GetMapping("one/{id}")
|
||||
public RestResult getOne(@PathVariable String id) {
|
||||
AssDictCate cate = service.findOne(id);
|
||||
return RestResult.ok(cate);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public RestResult post(@RequestBody AssDictCate main) {
|
||||
return RestResult.ok(service.insert(main));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public RestResult put(@RequestBody AssDictCate main) {
|
||||
return RestResult.ok(service.update(main));
|
||||
}
|
||||
|
||||
@DeleteMapping("{ids}")
|
||||
public RestResult delete(@PathVariable String[] ids) {
|
||||
return RestResult.ok(service.delete(ids));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private AssDictCateService service;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.zsvg.vboot.module.ass.dict.cate;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface AssDictCateRepo extends JpaRepository<AssDictCate,String> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.zsvg.vboot.module.ass.dict.cate;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.service.BaseCateService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@Service
|
||||
public class AssDictCateService extends BaseCateService<AssDictCate> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//----------bean注入------------
|
||||
@Autowired
|
||||
private AssDictCateRepo repo;
|
||||
|
||||
@PostConstruct
|
||||
public void initDao() {
|
||||
super.setRepo(repo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.zsvg.vboot.module.ass.dict.data;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import com.zsvg.vboot.common.mvc.entity.BaseEntity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
public class AssDictData extends BaseEntity {
|
||||
|
||||
private String notes;//备注
|
||||
|
||||
@Column(length = 32)
|
||||
private String code;//编码
|
||||
|
||||
private Integer ornum;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.zsvg.vboot.module.ass.dict.data;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.api.RestResult;
|
||||
import com.zsvg.vboot.common.mvc.dao.Sqler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("ass/dict/data")
|
||||
public class AssDictDataApi {
|
||||
|
||||
private String table = "ass_dict_data";
|
||||
|
||||
@GetMapping
|
||||
public RestResult get(String name) {
|
||||
Sqler sqler = new Sqler(table);
|
||||
sqler.addLike("t.name", name);
|
||||
sqler.addSelect("t.notes,t.ornum,t.code");
|
||||
return RestResult.ok(service.findPageData(sqler));
|
||||
}
|
||||
|
||||
@GetMapping("one/{id}")
|
||||
public RestResult getOne(@PathVariable String id) {
|
||||
AssDictData main = service.findOne(id);
|
||||
return RestResult.ok(main);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public RestResult post(@RequestBody AssDictData main) {
|
||||
return RestResult.ok(service.insert(main));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public RestResult put(@RequestBody AssDictData main) {
|
||||
return RestResult.ok(service.update(main));
|
||||
}
|
||||
|
||||
@DeleteMapping("{ids}")
|
||||
public RestResult delete(@PathVariable String[] ids) {
|
||||
return RestResult.ok(service.delete(ids));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private AssDictDataService service;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.zsvg.vboot.module.ass.dict.data;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
|
||||
public interface AssDictDataRepo extends JpaRepository<AssDictData,String> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.zsvg.vboot.module.ass.dict.data;
|
||||
|
||||
import com.zsvg.vboot.common.mvc.service.BaseService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
|
||||
@Service
|
||||
public class AssDictDataService extends BaseService<AssDictData> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//----------bean注入------------
|
||||
@Autowired
|
||||
private AssDictDataRepo repo;
|
||||
|
||||
@PostConstruct
|
||||
public void initDao() {
|
||||
super.setRepo(repo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.zsvg.vboot.module.ass.dict.main;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import com.zsvg.vboot.common.mvc.entity.BaseMainEntity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
public class AssDictMain extends BaseMainEntity {
|
||||
|
||||
private String notes;
|
||||
|
||||
@Column(length = 32)
|
||||
private String code;//编码
|
||||
|
||||
private Integer ornum;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user