Compare commits

..

No commits in common. "master" and "v3.5.0" have entirely different histories.

356 changed files with 7259 additions and 9352 deletions

View File

@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.6</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.5.0</h1>
<h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4> <h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.6-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.5.0-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@ -17,9 +17,12 @@
* 后端采用Spring Boot、Spring Cloud & Alibaba。 * 后端采用Spring Boot、Spring Cloud & Alibaba。
* 注册中心、配置中心选型Nacos权限认证使用Redis。 * 注册中心、配置中心选型Nacos权限认证使用Redis。
* 流量控制框架选型Sentinel分布式事务选型Seata。 * 流量控制框架选型Sentinel分布式事务选型Seata。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Cloud-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Cloud-Vue3),保持同步更新。 * 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Cloud-Vue3](https://github.com/yangzongzhuan/RuoYi-Cloud-Vue3),保持同步更新。
* 如需不分离应用,请移步 [RuoYi](https://gitee.com/y_project/RuoYi),如需分离应用,请移步 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) * 如需不分离应用,请移步 [RuoYi](https://gitee.com/y_project/RuoYi),如需分离应用,请移步 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)
* 阿里云优惠券:[点我进入](http://aly.ruoyi.vip),腾讯云优惠券:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp; * 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
#### 友情链接 [若依/RuoYi-Cloud](https://gitee.com/zhangmrit/ruoyi-cloud) Ant Design版本。
## 系统模块 ## 系统模块
@ -36,9 +39,7 @@ com.ruoyi
│ └── ruoyi-common-datasource // 多数据源 │ └── ruoyi-common-datasource // 多数据源
│ └── ruoyi-common-log // 日志记录 │ └── ruoyi-common-log // 日志记录
│ └── ruoyi-common-redis // 缓存服务 │ └── ruoyi-common-redis // 缓存服务
│ └── ruoyi-common-seata // 分布式事务
│ └── ruoyi-common-security // 安全模块 │ └── ruoyi-common-security // 安全模块
│ └── ruoyi-common-sensitive // 数据脱敏
│ └── ruoyi-common-swagger // 系统接口 │ └── ruoyi-common-swagger // 系统接口
├── ruoyi-modules // 业务模块 ├── ruoyi-modules // 业务模块
│ └── ruoyi-system // 系统模块 [9201] │ └── ruoyi-system // 系统模块 [9201]
@ -126,4 +127,4 @@ com.ruoyi
## 若依微服务交流群 ## 若依微服务交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/已满-213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [![加入QQ群](https://img.shields.io/badge/已满-148794840-blue.svg)](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [![加入QQ群](https://img.shields.io/badge/已满-118752664-blue.svg)](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [![加入QQ群](https://img.shields.io/badge/已满-101038945-blue.svg)](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [![加入QQ群](https://img.shields.io/badge/已满-128355254-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) [![加入QQ群](https://img.shields.io/badge/已满-179219821-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=irnwcXhbLOQEv1g-TwGifjNTA_f4wZiA&authKey=4bpzEwhcUY%2FvsPDHvzYn6xfoS%2FtOArvZ%2BGXzfr7O0%2FEqLfkKA%2BuCDXlzHIFg8t93&noverify=0&group_code=179219821) [![加入QQ群](https://img.shields.io/badge/已满-158753145-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lx1uEdEDuxeM7rUvF3qmlFdqKqdJ5Z-R&authKey=rgyPW9yhhh4IIURKVFa6NgP3qiqH04WAzrJ0trsgkr3pjzm6sKIOGyA58oOjoj%2FJ&noverify=0&group_code=158753145) [![加入QQ群](https://img.shields.io/badge/112869560-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Kuaw0Xdlw2Nlgn6s8h9elzuquHGxGObD&authKey=cSrQcWQ%2BzQZAFFrwxaR%2BbzcumX4WRduZnd1O6JO1dlclQMiu%2BKwxAy8t2JfNp67V&noverify=0&group_code=112869560) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) 点击按钮入群。

View File

@ -9,8 +9,8 @@ usage() {
# copy sql # copy sql
echo "begin copy sql " echo "begin copy sql "
cp ../sql/ry_20250523.sql ./mysql/db cp ../sql/ry_20210908.sql ./mysql/db
cp ../sql/ry_config_20250224.sql ./mysql/db cp ../sql/ry_config_20220114.sql ./mysql/db
# copy html # copy html
echo "begin copy html " echo "begin copy html "

View File

@ -16,7 +16,7 @@ management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
server.tomcat.basedir=/home/ruoyi/nacos/tomcat/logs server.tomcat.basedir=
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/** nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**

View File

@ -28,14 +28,9 @@ http {
proxy_pass http://ruoyi-gateway:8080/; proxy_pass http://ruoyi-gateway:8080/;
} }
# 避免actuator暴露
if ($uri ~ "/actuator") {
return 403;
}
error_page 500 502 503 504 /50x.html; error_page 500 502 503 504 /50x.html;
location = /50x.html { location = /50x.html {
root html; root html;
} }
} }
} }# requirepass 123456

181
pom.xml
View File

@ -6,53 +6,45 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依微服务系统</description> <description>若依微服务系统</description>
<properties> <properties>
<ruoyi.version>3.6.6</ruoyi.version> <ruoyi.version>3.5.0</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-boot.version>2.7.18</spring-boot.version> <spring-boot.version>2.6.6</spring-boot.version>
<spring-cloud.version>2021.0.9</spring-cloud.version> <spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.6.1</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
<spring-boot-admin.version>2.7.16</spring-boot-admin.version> <alibaba.nacos.version>2.0.4</alibaba.nacos.version>
<spring-boot-admin.version>2.6.6</spring-boot-admin.version>
<spring-boot.mybatis>2.2.2</spring-boot.mybatis>
<swagger.fox.version>3.0.0</swagger.fox.version>
<swagger.core.version>1.6.2</swagger.core.version>
<tobato.version>1.27.2</tobato.version> <tobato.version>1.27.2</tobato.version>
<kaptcha.version>2.3.3</kaptcha.version> <kaptcha.version>2.3.2</kaptcha.version>
<pagehelper.boot.version>2.0.0</pagehelper.boot.version> <pagehelper.boot.version>1.4.1</pagehelper.boot.version>
<druid.version>1.2.23</druid.version> <druid.version>1.2.8</druid.version>
<dynamic-ds.version>4.3.1</dynamic-ds.version> <dynamic-ds.version>3.5.0</dynamic-ds.version>
<commons.io.version>2.19.0</commons.io.version> <commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<fastjson.version>2.0.57</fastjson.version> <fastjson.version>1.2.80</fastjson.version>
<jjwt.version>0.9.1</jjwt.version> <jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version> <minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<springdoc.version>1.6.9</springdoc.version> <commons-collections.version>3.2.2</commons-collections.version>
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version> <transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>
<!-- override dependency version -->
<tomcat.version>9.0.112</tomcat.version>
<logback.version>1.2.13</logback.version>
<spring-framework.version>5.3.39</spring-framework.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<!-- 覆盖SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud 微服务 --> <!-- SpringCloud 微服务 -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
@ -71,6 +63,13 @@
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<!-- Alibaba Nacos 配置 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${alibaba.nacos.version}</version>
</dependency>
<!-- SpringBoot 依赖配置 --> <!-- SpringBoot 依赖配置 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -80,36 +79,11 @@
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<!-- 覆盖logback的依赖配置--> <!-- SpringBoot 监控客户端 -->
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>de.codecentric</groupId>
<artifactId>logback-core</artifactId> <artifactId>spring-boot-admin-starter-client</artifactId>
<version>${logback.version}</version> <version>${spring-boot-admin.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 覆盖tomcat的依赖配置-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency> </dependency>
<!-- FastDFS 分布式文件系统 --> <!-- FastDFS 分布式文件系统 -->
@ -119,16 +93,28 @@
<version>${tobato.version}</version> <version>${tobato.version}</version>
</dependency> </dependency>
<!-- Springdoc webmvc 依赖配置 --> <!-- Mybatis 依赖配置 -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.mybatis.spring.boot</groupId>
<artifactId>springdoc-openapi-ui</artifactId> <artifactId>mybatis-spring-boot-starter</artifactId>
<version>${springdoc.version}</version> <version>${spring-boot.mybatis}</version>
</dependency>
<!-- Swagger 依赖配置 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger.core.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.core.version}</version>
</dependency> </dependency>
<!-- 验证码 --> <!-- 验证码 -->
<dependency> <dependency>
<groupId>pro.fessional</groupId> <groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version> <version>${kaptcha.version}</version>
</dependency> </dependency>
@ -154,6 +140,13 @@
<version>${poi.version}</version> <version>${poi.version}</version>
</dependency> </dependency>
<!-- 文件上传工具类 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<!-- 代码生成使用模板 --> <!-- 代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
@ -161,10 +154,17 @@
<version>${velocity.version}</version> <version>${velocity.version}</version>
</dependency> </dependency>
<!-- Collection 增强Java集合框架 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
</dependency>
<!-- JSON 解析器和生成器 --> <!-- JSON 解析器和生成器 -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson2</artifactId> <artifactId>fastjson</artifactId>
<version>${fastjson.version}</version> <version>${fastjson.version}</version>
</dependency> </dependency>
@ -203,13 +203,6 @@
<version>${ruoyi.version}</version> <version>${ruoyi.version}</version>
</dependency> </dependency>
<!-- 数据脱敏 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-sensitive</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 权限范围 --> <!-- 权限范围 -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
@ -224,13 +217,6 @@
<version>${ruoyi.version}</version> <version>${ruoyi.version}</version>
</dependency> </dependency>
<!-- 分布式事务 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-seata</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 日志记录 --> <!-- 日志记录 -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
@ -285,47 +271,6 @@
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build> </build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project> </project>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api</artifactId> <artifactId>ruoyi-api</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -2,9 +2,7 @@ package com.ruoyi.system.api;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.constant.ServiceNameConstants;
@ -28,13 +26,4 @@ public interface RemoteFileService
*/ */
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file); public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
/**
*
*
* @param fileUrl
* @return
*/
@DeleteMapping(value = "/delete", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public R<Boolean> delete(@RequestParam("fileUrl") String fileUrl);
} }

View File

@ -27,7 +27,7 @@ public interface RemoteLogService
* @return * @return
*/ */
@PostMapping("/operlog") @PostMapping("/operlog")
public R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source) throws Exception; public R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/** /**
* 访 * 访

View File

@ -4,7 +4,6 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.SecurityConstants;
@ -41,14 +40,4 @@ public interface RemoteUserService
*/ */
@PostMapping("/user/register") @PostMapping("/user/register")
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* IP
*
* @param sysUser
* @param source
* @return
*/
@PutMapping("/user/recordlogin")
public R<Boolean> recordUserLogin(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
} }

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.validation.constraints.Email; import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -32,7 +31,7 @@ public class SysDept extends BaseEntity
private String deptName; private String deptName;
/** 显示顺序 */ /** 显示顺序 */
private Integer orderNum; private String orderNum;
/** 负责人 */ /** 负责人 */
private String leader; private String leader;
@ -97,13 +96,13 @@ public class SysDept extends BaseEntity
this.deptName = deptName; this.deptName = deptName;
} }
@NotNull(message = "显示顺序不能为空") @NotBlank(message = "显示顺序不能为空")
public Integer getOrderNum() public String getOrderNum()
{ {
return orderNum; return orderNum;
} }
public void setOrderNum(Integer orderNum) public void setOrderNum(String orderNum)
{ {
this.orderNum = orderNum; this.orderNum = orderNum;
} }

View File

@ -131,7 +131,7 @@ public class SysDictData extends BaseEntity
public boolean getDefault() public boolean getDefault()
{ {
return UserConstants.YES.equals(this.isDefault); return UserConstants.YES.equals(this.isDefault) ? true : false;
} }
public String getIsDefault() public String getIsDefault()

View File

@ -1,7 +1,6 @@
package com.ruoyi.system.api.domain; package com.ruoyi.system.api.domain;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -58,7 +57,6 @@ public class SysDictType extends BaseEntity
@NotBlank(message = "字典类型不能为空") @NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType() public String getDictType()
{ {
return dictType; return dictType;

View File

@ -79,10 +79,6 @@ public class SysOperLog extends BaseEntity
@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operTime; private Date operTime;
/** 消耗时间 */
@Excel(name = "消耗时间", suffix = "毫秒")
private Long costTime;
public Long getOperId() public Long getOperId()
{ {
return operId; return operId;
@ -242,14 +238,4 @@ public class SysOperLog extends BaseEntity
{ {
this.operTime = operTime; this.operTime = operTime;
} }
public Long getCostTime()
{
return costTime;
}
public void setCostTime(Long costTime)
{
this.costTime = costTime;
}
} }

View File

@ -1,8 +1,6 @@
package com.ruoyi.system.api.domain; package com.ruoyi.system.api.domain;
import java.util.Set;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -33,7 +31,7 @@ public class SysRole extends BaseEntity
/** 角色排序 */ /** 角色排序 */
@Excel(name = "角色排序") @Excel(name = "角色排序")
private Integer roleSort; private String roleSort;
/** 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限 */ /** 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限 */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
@ -61,9 +59,6 @@ public class SysRole extends BaseEntity
/** 部门组(数据权限) */ /** 部门组(数据权限) */
private Long[] deptIds; private Long[] deptIds;
/** 角色菜单权限 */
private Set<String> permissions;
public SysRole() public SysRole()
{ {
@ -118,13 +113,13 @@ public class SysRole extends BaseEntity
this.roleKey = roleKey; this.roleKey = roleKey;
} }
@NotNull(message = "显示顺序不能为空") @NotBlank(message = "显示顺序不能为空")
public Integer getRoleSort() public String getRoleSort()
{ {
return roleSort; return roleSort;
} }
public void setRoleSort(Integer roleSort) public void setRoleSort(String roleSort)
{ {
this.roleSort = roleSort; this.roleSort = roleSort;
} }
@ -209,16 +204,6 @@ public class SysRole extends BaseEntity
this.deptIds = deptIds; this.deptIds = deptIds;
} }
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -10,7 +10,6 @@ import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.annotation.Excel.ColumnType; import com.ruoyi.common.core.annotation.Excel.ColumnType;
import com.ruoyi.common.core.annotation.Excel.Type; import com.ruoyi.common.core.annotation.Excel.Type;
import com.ruoyi.common.core.annotation.Excels; import com.ruoyi.common.core.annotation.Excels;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.web.domain.BaseEntity; import com.ruoyi.common.core.web.domain.BaseEntity;
import com.ruoyi.common.core.xss.Xss; import com.ruoyi.common.core.xss.Xss;
@ -24,7 +23,7 @@ public class SysUser extends BaseEntity
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 用户ID */ /** 用户ID */
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号") @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId; private Long userId;
/** 部门ID */ /** 部门ID */
@ -44,7 +43,7 @@ public class SysUser extends BaseEntity
private String email; private String email;
/** 手机号码 */ /** 手机号码 */
@Excel(name = "手机号码", cellType = ColumnType.TEXT) @Excel(name = "手机号码")
private String phonenumber; private String phonenumber;
/** 用户性别 */ /** 用户性别 */
@ -57,8 +56,8 @@ public class SysUser extends BaseEntity
/** 密码 */ /** 密码 */
private String password; private String password;
/** 号状态0正常 1停用 */ /** 号状态0正常 1停用 */
@Excel(name = "号状态", readConverterExp = "0=正常,1=停用") @Excel(name = "号状态", readConverterExp = "0=正常,1=停用")
private String status; private String status;
/** 删除标志0代表存在 2代表删除 */ /** 删除标志0代表存在 2代表删除 */
@ -72,9 +71,6 @@ public class SysUser extends BaseEntity
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate; private Date loginDate;
/** 密码最后更新时间 */
private Date pwdUpdateDate;
/** 部门对象 */ /** 部门对象 */
@Excels({ @Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@ -121,7 +117,7 @@ public class SysUser extends BaseEntity
public static boolean isAdmin(Long userId) public static boolean isAdmin(Long userId)
{ {
return UserConstants.isAdmin(userId); return userId != null && 1L == userId;
} }
public Long getDeptId() public Long getDeptId()
@ -202,7 +198,7 @@ public class SysUser extends BaseEntity
this.avatar = avatar; this.avatar = avatar;
} }
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @JsonProperty
public String getPassword() public String getPassword()
{ {
return password; return password;
@ -253,16 +249,6 @@ public class SysUser extends BaseEntity
this.loginDate = loginDate; this.loginDate = loginDate;
} }
public Date getPwdUpdateDate()
{
return pwdUpdateDate;
}
public void setPwdUpdateDate(Date pwdUpdateDate)
{
this.pwdUpdateDate = pwdUpdateDate;
}
public SysDept getDept() public SysDept getDept()
{ {
return dept; return dept;
@ -312,7 +298,6 @@ public class SysUser extends BaseEntity
{ {
this.roleId = roleId; this.roleId = roleId;
} }
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -329,7 +314,6 @@ public class SysUser extends BaseEntity
.append("delFlag", getDelFlag()) .append("delFlag", getDelFlag())
.append("loginIp", getLoginIp()) .append("loginIp", getLoginIp())
.append("loginDate", getLoginDate()) .append("loginDate", getLoginDate())
.append("pwdUpdateDate", getPwdUpdateDate())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())

View File

@ -30,12 +30,6 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
{ {
return R.fail("上传文件失败:" + throwable.getMessage()); return R.fail("上传文件失败:" + throwable.getMessage());
} }
@Override
public R<Boolean> delete(String fileUrl)
{
return R.fail("删除文件失败:" + throwable.getMessage());
}
}; };
} }
} }

View File

@ -28,13 +28,13 @@ public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogServic
@Override @Override
public R<Boolean> saveLog(SysOperLog sysOperLog, String source) public R<Boolean> saveLog(SysOperLog sysOperLog, String source)
{ {
return R.fail("保存操作日志失败:" + throwable.getMessage()); return null;
} }
@Override @Override
public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source) public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
{ {
return R.fail("保存登录日志失败:" + throwable.getMessage()); return null;
} }
}; };

View File

@ -36,12 +36,6 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
{ {
return R.fail("注册用户失败:" + throwable.getMessage()); return R.fail("注册用户失败:" + throwable.getMessage());
} }
@Override
public R<Boolean> recordUserLogin(SysUser sysUser, String source)
{
return R.fail("记录用户登录信息失败:" + throwable.getMessage());
}
}; };
} }
} }

View File

@ -0,0 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.system.api.factory.RemoteUserFallbackFactory,\
com.ruoyi.system.api.factory.RemoteLogFallbackFactory, \
com.ruoyi.system.api.factory.RemoteFileFallbackFactory

View File

@ -1,3 +0,0 @@
com.ruoyi.system.api.factory.RemoteUserFallbackFactory
com.ruoyi.system.api.factory.RemoteLogFallbackFactory
com.ruoyi.system.api.factory.RemoteFileFallbackFactory

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -2,20 +2,19 @@ package com.ruoyi.auth.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.enums.UserStatus; import com.ruoyi.common.core.enums.UserStatus;
import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ip.IpUtils; import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteLogService;
import com.ruoyi.system.api.RemoteUserService; import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysLogininfor;
import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser; import com.ruoyi.system.api.model.LoginUser;
@ -27,18 +26,12 @@ import com.ruoyi.system.api.model.LoginUser;
@Component @Component
public class SysLoginService public class SysLoginService
{ {
@Autowired
private RemoteLogService remoteLogService;
@Autowired @Autowired
private RemoteUserService remoteUserService; private RemoteUserService remoteUserService;
@Autowired
private SysPasswordService passwordService;
@Autowired
private SysRecordLogService recordLogService;
@Autowired
private RedisService redisService;
/** /**
* *
*/ */
@ -47,30 +40,23 @@ public class SysLoginService
// 用户名或密码为空 错误 // 用户名或密码为空 错误
if (StringUtils.isAnyBlank(username, password)) if (StringUtils.isAnyBlank(username, password))
{ {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写"); recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
throw new ServiceException("用户/密码必须填写"); throw new ServiceException("用户/密码必须填写");
} }
// 密码如果不在指定范围内 错误 // 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{ {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围"); recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
throw new ServiceException("用户密码不在指定范围"); throw new ServiceException("用户密码不在指定范围");
} }
// 用户名不在指定范围内 错误 // 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH) || username.length() > UserConstants.USERNAME_MAX_LENGTH)
{ {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
throw new ServiceException("用户名不在指定范围"); throw new ServiceException("用户名不在指定范围");
} }
// IP黑名单校验
String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾访问IP已被列入系统黑名单");
throw new ServiceException("很遗憾访问IP已被列入系统黑名单");
}
// 查询用户信息 // 查询用户信息
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
@ -79,43 +65,35 @@ public class SysLoginService
throw new ServiceException(userResult.getMsg()); throw new ServiceException(userResult.getMsg());
} }
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在");
}
LoginUser userInfo = userResult.getData(); LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser(); SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{ {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
} }
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{ {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + username + " 已停用"); throw new ServiceException("对不起,您的账号:" + username + " 已停用");
} }
passwordService.validate(user, password); if (!SecurityUtils.matchesPassword(password, user.getPassword()))
recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
recordLoginInfo(user.getUserId());
return userInfo;
}
/**
*
*
* @param userId ID
*/
public void recordLoginInfo(Long userId)
{ {
SysUser sysUser = new SysUser(); recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码错误");
sysUser.setUserId(userId); throw new ServiceException("用户不存在/密码错误");
// 更新用户登录IP }
sysUser.setLoginIp(IpUtils.getIpAddr()); recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
// 更新用户登录时间 return userInfo;
sysUser.setLoginDate(DateUtils.getNowDate());
remoteUserService.recordUserLogin(sysUser, SecurityConstants.INNER);
} }
public void logout(String loginName) public void logout(String loginName)
{ {
recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功"); recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
} }
/** /**
@ -143,7 +121,6 @@ public class SysLoginService
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
sysUser.setUserName(username); sysUser.setUserName(username);
sysUser.setNickName(username); sysUser.setNickName(username);
sysUser.setPwdUpdateDate(DateUtils.getNowDate());
sysUser.setPassword(SecurityUtils.encryptPassword(password)); sysUser.setPassword(SecurityUtils.encryptPassword(password));
R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
@ -151,6 +128,32 @@ public class SysLoginService
{ {
throw new ServiceException(registerResult.getMsg()); throw new ServiceException(registerResult.getMsg());
} }
recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功"); recordLogininfor(username, Constants.REGISTER, "注册成功");
}
/**
*
*
* @param username
* @param status
* @param message
* @return
*/
public void recordLogininfor(String username, String status, String message)
{
SysLogininfor logininfor = new SysLogininfor();
logininfor.setUserName(username);
logininfor.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
logininfor.setMsg(message);
// 日志状态
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
{
logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS);
}
else if (Constants.LOGIN_FAIL.equals(status))
{
logininfor.setStatus(Constants.LOGIN_FAIL_STATUS);
}
remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
} }
} }

View File

@ -1,85 +0,0 @@
package com.ruoyi.auth.service;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysUser;
/**
*
*
* @author ruoyi
*/
@Component
public class SysPasswordService
{
@Autowired
private RedisService redisService;
private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;
private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;
@Autowired
private SysRecordLogService recordLogService;
/**
*
*
* @param username
* @return key
*/
private String getCacheKey(String username)
{
return CacheConstants.PWD_ERR_CNT_KEY + username;
}
public void validate(SysUser user, String password)
{
String username = user.getUserName();
Integer retryCount = redisService.getCacheObject(getCacheKey(username));
if (retryCount == null)
{
retryCount = 0;
}
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{
String errMsg = String.format("密码输入错误%s次帐户锁定%s分钟", maxRetryCount, lockTime);
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL,errMsg);
throw new ServiceException(errMsg);
}
if (!matches(user, password))
{
retryCount = retryCount + 1;
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount));
redisService.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new ServiceException("用户不存在/密码错误");
}
else
{
clearLoginRecordCache(username);
}
}
public boolean matches(SysUser user, String rawPassword)
{
return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
}
public void clearLoginRecordCache(String loginName)
{
if (redisService.hasKey(getCacheKey(loginName)))
{
redisService.deleteObject(getCacheKey(loginName));
}
}
}

View File

@ -1,48 +0,0 @@
package com.ruoyi.auth.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.system.api.RemoteLogService;
import com.ruoyi.system.api.domain.SysLogininfor;
/**
*
*
* @author ruoyi
*/
@Component
public class SysRecordLogService
{
@Autowired
private RemoteLogService remoteLogService;
/**
*
*
* @param username
* @param status
* @param message
* @return
*/
public void recordLogininfor(String username, String status, String message)
{
SysLogininfor logininfor = new SysLogininfor();
logininfor.setUserName(username);
logininfor.setIpaddr(IpUtils.getIpAddr());
logininfor.setMsg(message);
// 日志状态
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
{
logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS);
}
else if (Constants.LOGIN_FAIL.equals(status))
{
logininfor.setStatus(Constants.LOGIN_FAIL_STATUS);
}
remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
}
}

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -12,10 +12,8 @@
<module>ruoyi-common-log</module> <module>ruoyi-common-log</module>
<module>ruoyi-common-core</module> <module>ruoyi-common-core</module>
<module>ruoyi-common-redis</module> <module>ruoyi-common-redis</module>
<module>ruoyi-common-seata</module>
<module>ruoyi-common-swagger</module> <module>ruoyi-common-swagger</module>
<module>ruoyi-common-security</module> <module>ruoyi-common-security</module>
<module>ruoyi-common-sensitive</module>
<module>ruoyi-common-datascope</module> <module>ruoyi-common-datascope</module>
<module>ruoyi-common-datasource</module> <module>ruoyi-common-datasource</module>
</modules> </modules>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -67,8 +67,8 @@
<!-- Alibaba Fastjson --> <!-- Alibaba Fastjson -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson2</artifactId> <artifactId>fastjson</artifactId>
</dependency> </dependency>
<!-- Jwt --> <!-- Jwt -->
@ -95,6 +95,12 @@
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
</dependency> </dependency>
<!-- Commons Fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<!-- excel工具 --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
@ -107,6 +113,12 @@
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
</dependency> </dependency>
<!-- Swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -5,8 +5,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter; import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter;
/** /**
@ -54,12 +52,17 @@ public @interface Excel
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/** /**
* excel * 0 1
*/
public ColumnType cellType() default ColumnType.STRING;
/**
* excel
*/ */
public double height() default 14; public double height() default 14;
/** /**
* excel * excel
*/ */
public double width() default 16; public double width() default 16;
@ -78,21 +81,11 @@ public @interface Excel
*/ */
public String prompt() default ""; public String prompt() default "";
/**
*
*/
public boolean wrapText() default false;
/** /**
* . * .
*/ */
public String[] combo() default {}; public String[] combo() default {};
/**
* ,:list)
*/
public boolean needMerge() default false;
/** /**
* ,:,. * ,:,.
*/ */
@ -109,34 +102,9 @@ public @interface Excel
public boolean isStatistics() default false; public boolean isStatistics() default false;
/** /**
* 0 1 * 0123
*/ */
public ColumnType cellType() default ColumnType.STRING; public Align align() default Align.AUTO;
/**
*
*/
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
/**
*
*/
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
*
*/
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
*
*/
public IndexedColors color() default IndexedColors.BLACK;
/**
*
*/
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
/** /**
* *
@ -148,6 +116,22 @@ public @interface Excel
*/ */
public String[] args() default {}; public String[] args() default {};
public enum Align
{
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
private final int value;
Align(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
/** /**
* 012 * 012
*/ */
@ -171,7 +155,7 @@ public @interface Excel
public enum ColumnType public enum ColumnType
{ {
NUMERIC(0), STRING(1), IMAGE(2), TEXT(3); NUMERIC(0), STRING(1), IMAGE(2);
private final int value; private final int value;
ColumnType(int value) ColumnType(int value)

View File

@ -1,7 +1,7 @@
package com.ruoyi.common.core.constant; package com.ruoyi.common.core.constant;
/** /**
* * key
* *
* @author ruoyi * @author ruoyi
*/ */
@ -17,43 +17,8 @@ public class CacheConstants
*/ */
public final static long REFRESH_TIME = 120; public final static long REFRESH_TIME = 120;
/**
*
*/
public final static int PASSWORD_MAX_RETRY_COUNT = 5;
/**
* 10
*/
public final static long PASSWORD_LOCK_TIME = 10;
/** /**
* *
*/ */
public final static String LOGIN_TOKEN_KEY = "login_tokens:"; public final static String LOGIN_TOKEN_KEY = "login_tokens:";
/**
* redis key
*/
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/**
* cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
/**
* redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
/**
* IP cache key
*/
public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList";
} }

View File

@ -17,11 +17,6 @@ public class Constants
*/ */
public static final String GBK = "GBK"; public static final String GBK = "GBK";
/**
* www
*/
public static final String WWW = "www.";
/** /**
* RMI * RMI
*/ */
@ -87,16 +82,6 @@ public class Constants
*/ */
public static final String LOGIN_FAIL = "Error"; public static final String LOGIN_FAIL = "Error";
/**
*
*/
public static final String ALL_PERMISSION = "*:*:*";
/**
*
*/
public static final String SUPER_ADMIN = "admin";
/** /**
* *
*/ */
@ -117,25 +102,36 @@ public class Constants
*/ */
public static final String IS_ASC = "isAsc"; public static final String IS_ASC = "isAsc";
/**
* redis key
*/
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/** /**
* *
*/ */
public static final long CAPTCHA_EXPIRATION = 2; public static final long CAPTCHA_EXPIRATION = 2;
/**
* cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
/** /**
* *
*/ */
public static final String RESOURCE_PREFIX = "/profile"; public static final String RESOURCE_PREFIX = "/profile";
/**
* json
*/
public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" };
/** /**
* 访 * 访
*/ */
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.job.task" }; public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
/** /**
* *

View File

@ -42,7 +42,7 @@ public class GenConstants
/** 数据库数字类型 */ /** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "double", "decimal" }; "bigint", "float", "double", "decimal" };
/** 页面不需要编辑字段 */ /** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };

View File

@ -86,9 +86,4 @@ public class HttpStatus
* *
*/ */
public static final int NOT_IMPLEMENTED = 501; public static final int NOT_IMPLEMENTED = 501;
/**
*
*/
public static final int WARN = 601;
} }

View File

@ -20,7 +20,7 @@ public class SecurityConstants
/** /**
* *
*/ */
public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String AUTHORIZATION_HEADER = "authorization";
/** /**
* *
@ -41,9 +41,4 @@ public class SecurityConstants
* *
*/ */
public static final String LOGIN_USER = "login_user"; public static final String LOGIN_USER = "login_user";
/**
*
*/
public static final String ROLE_PERMISSION = "role_permission";
} }

View File

@ -7,6 +7,11 @@ package com.ruoyi.common.core.constant;
*/ */
public class TokenConstants public class TokenConstants
{ {
/**
*
*/
public static final String AUTHENTICATION = "Authorization";
/** /**
* *
*/ */

View File

@ -21,9 +21,6 @@ public class UserConstants
/** 用户封禁状态 */ /** 用户封禁状态 */
public static final String USER_DISABLE = "1"; public static final String USER_DISABLE = "1";
/** 角色正常状态 */
public static final String ROLE_NORMAL = "0";
/** 角色封禁状态 */ /** 角色封禁状态 */
public static final String ROLE_DISABLE = "1"; public static final String ROLE_DISABLE = "1";
@ -63,9 +60,10 @@ public class UserConstants
/** InnerLink组件标识 */ /** InnerLink组件标识 */
public final static String INNER_LINK = "InnerLink"; public final static String INNER_LINK = "InnerLink";
/** 校验是否唯一的返回标识 */ /** 校验返回结果码 */
public final static boolean UNIQUE = true; public final static String UNIQUE = "0";
public final static boolean NOT_UNIQUE = false;
public final static String NOT_UNIQUE = "1";
/** /**
* *
@ -80,9 +78,4 @@ public class UserConstants
public static final int PASSWORD_MIN_LENGTH = 5; public static final int PASSWORD_MIN_LENGTH = 5;
public static final int PASSWORD_MAX_LENGTH = 20; public static final int PASSWORD_MAX_LENGTH = 20;
public static boolean isAdmin(Long userId)
{
return userId != null && 1L == userId;
}
} }

View File

@ -81,16 +81,6 @@ public class SecurityContextHolder
set(SecurityConstants.USER_KEY, userKey); set(SecurityConstants.USER_KEY, userKey);
} }
public static String getPermission()
{
return get(SecurityConstants.ROLE_PERMISSION);
}
public static void setPermission(String permissions)
{
set(SecurityConstants.ROLE_PERMISSION, permissions);
}
public static void remove() public static void remove()
{ {
THREAD_LOCAL.remove(); THREAD_LOCAL.remove();

View File

@ -102,14 +102,4 @@ public class R<T> implements Serializable
{ {
this.data = data; this.data = data;
} }
public static <T> Boolean isError(R<T> ret)
{
return !isSuccess(ret);
}
public static <T> Boolean isSuccess(R<T> ret)
{
return R.SUCCESS == ret.getCode();
}
} }

View File

@ -7,6 +7,7 @@ package com.ruoyi.common.core.exception;
*/ */
public class GlobalException extends RuntimeException public class GlobalException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
@ -44,7 +45,6 @@ public class GlobalException extends RuntimeException
return this; return this;
} }
@Override
public String getMessage() public String getMessage()
{ {
return message; return message;

View File

@ -49,7 +49,6 @@ public final class ServiceException extends RuntimeException
return detailMessage; return detailMessage;
} }
@Override
public String getMessage() public String getMessage()
{ {
return message; return message;

View File

@ -11,9 +11,9 @@ public class FileException extends BaseException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FileException(String code, Object[] args, String msg) public FileException(String code, Object[] args)
{ {
super("file", code, args, msg); super("file", code, args, null);
} }
} }

View File

@ -11,6 +11,6 @@ public class FileNameLengthLimitExceededException extends FileException
public FileNameLengthLimitExceededException(int defaultFileNameLength) public FileNameLengthLimitExceededException(int defaultFileNameLength)
{ {
super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }, "the filename is too long"); super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
} }
} }

View File

@ -11,6 +11,6 @@ public class FileSizeLimitExceededException extends FileException
public FileSizeLimitExceededException(long defaultMaxSize) public FileSizeLimitExceededException(long defaultMaxSize)
{ {
super("upload.exceed.maxSize", new Object[] { defaultMaxSize }, "the filesize is too large"); super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
} }
} }

View File

@ -1,61 +0,0 @@
package com.ruoyi.common.core.exception.file;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
*
*
* @author ruoyi
*/
public class FileUploadException extends Exception
{
private static final long serialVersionUID = 1L;
private final Throwable cause;
public FileUploadException()
{
this(null, null);
}
public FileUploadException(final String msg)
{
this(msg, null);
}
public FileUploadException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
@Override
public void printStackTrace(PrintStream stream)
{
super.printStackTrace(stream);
if (cause != null)
{
stream.println("Caused by:");
cause.printStackTrace(stream);
}
}
@Override
public void printStackTrace(PrintWriter writer)
{
super.printStackTrace(writer);
if (cause != null)
{
writer.println("Caused by:");
cause.printStackTrace(writer);
}
}
@Override
public Throwable getCause()
{
return cause;
}
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.common.core.exception.file; package com.ruoyi.common.core.exception.file;
import java.util.Arrays; import java.util.Arrays;
import org.apache.commons.fileupload.FileUploadException;
/** /**
* *

View File

@ -2,7 +2,6 @@ package com.ruoyi.common.core.text;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.text.NumberFormat; import java.text.NumberFormat;
@ -314,7 +313,7 @@ public class Convert
* Integer<br> * Integer<br>
* *
* @param split * @param split
* @param str * @param split
* @return * @return
*/ */
public static Integer[] toIntArray(String split, String str) public static Integer[] toIntArray(String split, String str)
@ -364,10 +363,6 @@ public class Convert
*/ */
public static String[] toStrArray(String str) public static String[] toStrArray(String str)
{ {
if (StringUtils.isEmpty(str))
{
return new String[] {};
}
return toStrArray(",", str); return toStrArray(",", str);
} }
@ -375,7 +370,7 @@ public class Convert
* String<br> * String<br>
* *
* @param split * @param split
* @param str * @param split
* @return * @return
*/ */
public static String[] toStrArray(String split, String str) public static String[] toStrArray(String split, String str)
@ -540,7 +535,7 @@ public class Convert
/** /**
* boolean<br> * boolean<br>
* Stringtruefalseyesokno10, <br> * Stringtruefalseyesokno1,0 <br>
* *
* *
* @param value * @param value
@ -566,15 +561,18 @@ public class Convert
switch (valueStr) switch (valueStr)
{ {
case "true": case "true":
case "yes":
case "ok":
case "1":
case "是":
return true; return true;
case "false": case "false":
return false;
case "yes":
return true;
case "ok":
return true;
case "no": case "no":
return false;
case "1":
return true;
case "0": case "0":
case "否":
return false; return false;
default: default:
return defaultValue; return defaultValue;
@ -719,7 +717,7 @@ public class Convert
} }
if (value instanceof Double) if (value instanceof Double)
{ {
return BigDecimal.valueOf((Double) value); return new BigDecimal((Double) value);
} }
if (value instanceof Integer) if (value instanceof Integer)
{ {
@ -909,7 +907,7 @@ public class Convert
*/ */
public static String toSBC(String input, Set<Character> notConvertSet) public static String toSBC(String input, Set<Character> notConvertSet)
{ {
char[] c = input.toCharArray(); char c[] = input.toCharArray();
for (int i = 0; i < c.length; i++) for (int i = 0; i < c.length; i++)
{ {
if (null != notConvertSet && notConvertSet.contains(c[i])) if (null != notConvertSet && notConvertSet.contains(c[i]))
@ -951,7 +949,7 @@ public class Convert
*/ */
public static String toDBC(String text, Set<Character> notConvertSet) public static String toDBC(String text, Set<Character> notConvertSet)
{ {
char[] c = text.toCharArray(); char c[] = text.toCharArray();
for (int i = 0; i < c.length; i++) for (int i = 0; i < c.length; i++)
{ {
if (null != notConvertSet && notConvertSet.contains(c[i])) if (null != notConvertSet && notConvertSet.contains(c[i]))
@ -969,7 +967,9 @@ public class Convert
c[i] = (char) (c[i] - 65248); c[i] = (char) (c[i] - 65248);
} }
} }
return new String(c); String returnString = new String(c);
return returnString;
} }
/** /**
@ -990,12 +990,7 @@ public class Convert
String s = ""; String s = "";
for (int i = 0; i < fraction.length; i++) for (int i = 0; i < fraction.length; i++)
{ {
// 优化double计算精度丢失问题 s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
BigDecimal nNum = new BigDecimal(n);
BigDecimal decimal = new BigDecimal(10);
BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
double d = scale.doubleValue();
s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
} }
if (s.length() < 1) if (s.length() < 1)
{ {

View File

@ -137,28 +137,16 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
} }
/** /**
* *
*/ */
public static int differentDaysByMillisecond(Date date1, Date date2) public static String getDatePoor(Date endDate, Date nowDate)
{
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
}
/**
*
*
* @param endDate
* @param startTime
* @return //
*/
public static String timeDistance(Date endDate, Date startTime)
{ {
long nd = 1000 * 24 * 60 * 60; long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60; long nh = 1000 * 60 * 60;
long nm = 1000 * 60; long nm = 1000 * 60;
// long ns = 1000; // long ns = 1000;
// 获得两个时间的毫秒时间差异 // 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - startTime.getTime(); long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天 // 计算差多少天
long day = diff / nd; long day = diff / nd;
// 计算差多少小时 // 计算差多少小时

View File

@ -20,10 +20,13 @@ public class PageUtils extends PageHelper
PageDomain pageDomain = TableSupport.buildPageRequest(); PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum(); Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize(); Integer pageSize = pageDomain.getPageSize();
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
{
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
Boolean reasonable = pageDomain.getReasonable(); Boolean reasonable = pageDomain.getReasonable();
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
} }
}
/** /**
* 线 * 线

View File

@ -0,0 +1,164 @@
package com.ruoyi.common.core.utils;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.StringUtils;
public class ReUtil
{
public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)");
/**
*
*/
public final static Set<Character> RE_KEYS = new HashSet<>(
Arrays.asList('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|'));;
/**
* <br>
* replacementTemplate$11
*
* <p>
* 12341234(1234)
*
* <pre>
* ReUtil.replaceAll("中文1234", "(\\d+)", "($1)"))
*
* (1234)
* </pre>
*
* @param content
* @param regex
* @param replacementTemplate 使$1
* @return
*/
public static String replaceAll(CharSequence content, String regex, String replacementTemplate)
{
final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
return replaceAll(content, pattern, replacementTemplate);
}
/**
* <br>
* replacementTemplate$11
*
* @param content
* @param pattern {@link Pattern}
* @param replacementTemplate 使$1
* @return
* @since 3.0.4
*/
public static String replaceAll(CharSequence content, Pattern pattern, String replacementTemplate)
{
if (StringUtils.isEmpty(content))
{
return StringUtils.EMPTY;
}
final Matcher matcher = pattern.matcher(content);
boolean result = matcher.find();
if (result)
{
final Set<String> varNums = findAll(GROUP_VAR, replacementTemplate, 1, new HashSet<>());
final StringBuffer sb = new StringBuffer();
do
{
String replacement = replacementTemplate;
for (String var : varNums)
{
int group = Integer.parseInt(var);
replacement = replacement.replace("$" + var, matcher.group(group));
}
matcher.appendReplacement(sb, escape(replacement));
result = matcher.find();
}
while (result);
matcher.appendTail(sb);
return sb.toString();
}
return Convert.toStr(content);
}
/**
*
*
* @param <T>
* @param pattern
* @param content
* @param group
* @param collection
* @return
*/
public static <T extends Collection<String>> T findAll(Pattern pattern, CharSequence content, int group,
T collection)
{
if (null == pattern || null == content)
{
return null;
}
if (null == collection)
{
throw new NullPointerException("Null collection param provided!");
}
final Matcher matcher = pattern.matcher(content);
while (matcher.find())
{
collection.add(matcher.group(group));
}
return collection;
}
/**
*
*
* @param c
* @return
*/
public static String escape(char c)
{
final StringBuilder builder = new StringBuilder();
if (RE_KEYS.contains(c))
{
builder.append('\\');
}
builder.append(c);
return builder.toString();
}
/**
*
*
* @param content
* @return
*/
public static String escape(CharSequence content)
{
if (StringUtils.isBlank(content))
{
return StringUtils.EMPTY;
}
final StringBuilder builder = new StringBuilder();
int len = content.length();
char current;
for (int i = 0; i < len; i++)
{
current = content.charAt(i);
if (RE_KEYS.contains(current))
{
builder.append('\\');
}
builder.append(current);
}
return builder.toString();
}
}

View File

@ -4,11 +4,9 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@ -17,11 +15,10 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
@ -82,34 +79,6 @@ public class ServletUtils
return Convert.toBool(getRequest().getParameter(name), defaultValue); return Convert.toBool(getRequest().getParameter(name), defaultValue);
} }
/**
*
*
* @param request {@link ServletRequest}
* @return Map
*/
public static Map<String, String[]> getParams(ServletRequest request)
{
final Map<String, String[]> map = request.getParameterMap();
return Collections.unmodifiableMap(map);
}
/**
*
*
* @param request {@link ServletRequest}
* @return Map
*/
public static Map<String, String> getParamMap(ServletRequest request)
{
Map<String, String> params = new HashMap<>();
for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
{
params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));
}
return params;
}
/** /**
* request * request
*/ */
@ -173,7 +142,7 @@ public class ServletUtils
public static Map<String, String> getHeaders(HttpServletRequest request) public static Map<String, String> getHeaders(HttpServletRequest request)
{ {
Map<String, String> map = new LinkedCaseInsensitiveMap<>(); Map<String, String> map = new LinkedHashMap<>();
Enumeration<String> enumeration = request.getHeaderNames(); Enumeration<String> enumeration = request.getHeaderNames();
if (enumeration != null) if (enumeration != null)
{ {
@ -327,7 +296,7 @@ public class ServletUtils
response.setStatusCode(status); response.setStatusCode(status);
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType); response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
R<?> result = R.fail(code, value.toString()); R<?> result = R.fail(code, value.toString());
DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes()); DataBuffer dataBuffer = response.bufferFactory().wrap(JSONObject.toJSONString(result).getBytes());
return response.writeWith(Mono.just(dataBuffer)); return response.writeWith(Mono.just(dataBuffer));
} }
} }

View File

@ -20,9 +20,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
/** 下划线 */ /** 下划线 */
private static final char SEPARATOR = '_'; private static final char SEPARATOR = '_';
/** 星号 */
private static final char ASTERISK = '*';
/** /**
* *
* *
@ -163,49 +160,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return (str == null ? "" : str.trim()); return (str == null ? "" : str.trim());
} }
/**
* "*"
*
* @param str
* @param startInclude
* @param endExclude
* @return
*/
public static String hide(CharSequence str, int startInclude, int endExclude)
{
if (isEmpty(str))
{
return NULLSTR;
}
final int strLength = str.length();
if (startInclude > strLength)
{
return NULLSTR;
}
if (endExclude > strLength)
{
endExclude = strLength;
}
if (startInclude > endExclude)
{
// 如果起始位置大于结束位置,不替换
return NULLSTR;
}
final char[] chars = new char[strLength];
for (int i = 0; i < strLength; i++)
{
if (i >= startInclude && i < endExclude)
{
chars[i] = ASTERISK;
}
else
{
chars[i] = str.charAt(i);
}
}
return new String(chars);
}
/** /**
* *
* *
@ -283,32 +237,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return str.substring(start, end); return str.substring(start, end);
} }
/**
* `open` `close`
*
* @param str
* @param open
* @param close
* @return
*/
public static String substringBetweenLast(final String str, final String open, final String close)
{
if (isEmpty(str) || isEmpty(open) || isEmpty(close))
{
return NULLSTR;
}
final int start = str.indexOf(open);
if (start != INDEX_NOT_FOUND)
{
final int end = str.lastIndexOf(close);
if (end != INDEX_NOT_FOUND)
{
return str.substring(start + open.length(), end);
}
}
return NULLSTR;
}
/** /**
* *
* *
@ -366,32 +294,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
} }
/**
* collectionarray arrayvalue
*
* @param collection
* @param array
* @return boolean
*/
public static boolean containsAny(Collection<String> collection, String... array)
{
if (isEmpty(collection) || isEmpty(array))
{
return false;
}
else
{
for (String str : array)
{
if (collection.contains(str))
{
return true;
}
}
return false;
}
}
/** /**
* 线 * 线
*/ */
@ -500,8 +402,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
} }
/** /**
* * user_name->userName
* user_name->userName
*/ */
public static String toCamelCase(String s) public static String toCamelCase(String s)
{ {
@ -509,10 +410,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
{ {
return null; return null;
} }
if (s.indexOf(SEPARATOR) == -1)
{
return s;
}
s = s.toLowerCase(); s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length()); StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false; boolean upperCase = false;

View File

@ -1,10 +1,7 @@
package com.ruoyi.common.core.utils.file; package com.ruoyi.common.core.utils.file;
import java.io.File; import java.io.File;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
/** /**
* *
@ -48,22 +45,6 @@ public class FileTypeUtils
return fileName.substring(separatorIndex + 1).toLowerCase(); return fileName.substring(separatorIndex + 1).toLowerCase();
} }
/**
*
*
* @param file
* @return
*/
public static final String getExtension(MultipartFile file)
{
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension))
{
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
}
return extension;
}
/** /**
* *
* *

View File

@ -97,7 +97,8 @@ public class FileUtils
// 路径为文件且不为空则进行删除 // 路径为文件且不为空则进行删除
if (file.isFile() && file.exists()) if (file.isFile() && file.exists())
{ {
flag = file.delete(); file.delete();
flag = true;
} }
return flag; return flag;
} }
@ -114,20 +115,27 @@ public class FileUtils
} }
/** /**
* *
* *
* @param fileUrl * @param resource
* @return true false * @return true false
*/ */
public static boolean validateFilePath(String fileUrl) public static boolean checkAllowDownload(String resource)
{ {
// 禁止目录上跳级别 // 禁止目录上跳级别
if (StringUtils.contains(fileUrl, "..")) if (StringUtils.contains(resource, ".."))
{ {
return false; return false;
} }
// 判断是否在允许下载的文件规则内
return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(fileUrl)); // 检查允许下载的文件规则
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
{
return true;
}
// 不在允许下载的文件规则
return false;
} }
/** /**

View File

@ -332,7 +332,7 @@ public final class HTMLFilter
final String name = m.group(1).toLowerCase(); final String name = m.group(1).toLowerCase();
if (allowed(name)) if (allowed(name))
{ {
if (!inArray(name, vSelfClosingTags)) if (false == inArray(name, vSelfClosingTags))
{ {
if (vTagCounts.containsKey(name)) if (vTagCounts.containsKey(name))
{ {
@ -387,7 +387,7 @@ public final class HTMLFilter
{ {
paramValue = processParamProtocol(paramValue); paramValue = processParamProtocol(paramValue);
} }
params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\""); params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\"");
} }
} }

View File

@ -3,7 +3,6 @@ package com.ruoyi.common.core.utils.ip;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
/** /**
@ -13,23 +12,6 @@ import com.ruoyi.common.core.utils.StringUtils;
*/ */
public class IpUtils public class IpUtils
{ {
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
// 匹配 ip
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
// 匹配网段
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
/**
* IP
*
* @return IP
*/
public static String getIpAddr()
{
return getIpAddr(ServletUtils.getRequest());
}
/** /**
* IP * IP
* *
@ -266,7 +248,7 @@ public class IpUtils
} }
} }
} }
return StringUtils.substring(ip, 0, 255); return ip;
} }
/** /**
@ -279,104 +261,4 @@ public class IpUtils
{ {
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
} }
/**
* IP
*/
public static boolean isIP(String ip)
{
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
}
/**
* IP *
*/
public static boolean isIpWildCard(String ip)
{
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
}
/**
* ip
*/
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
{
String[] s1 = ipWildCard.split("\\.");
String[] s2 = ip.split("\\.");
boolean isMatchedSeg = true;
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
{
if (!s1[i].equals(s2[i]))
{
isMatchedSeg = false;
break;
}
}
return isMatchedSeg;
}
/**
* :10.10.10.1-10.10.10.99ip
*/
public static boolean isIPSegment(String ipSeg)
{
return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
}
/**
* ip
*/
public static boolean ipIsInNetNoCheck(String iparea, String ip)
{
int idx = iparea.indexOf('-');
String[] sips = iparea.substring(0, idx).split("\\.");
String[] sipe = iparea.substring(idx + 1).split("\\.");
String[] sipt = ip.split("\\.");
long ips = 0L, ipe = 0L, ipt = 0L;
for (int i = 0; i < 4; ++i)
{
ips = ips << 8 | Integer.parseInt(sips[i]);
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
}
if (ips > ipe)
{
long t = ips;
ips = ipe;
ipe = t;
}
return ips <= ipt && ipt <= ipe;
}
/**
* ip
*
* @param filter IP,'*',:`10.10.10.1-10.10.10.99`
* @param ip IP
* @return boolean
*/
public static boolean isMatchedIp(String filter, String ip)
{
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
{
return false;
}
String[] ips = filter.split(";");
for (String iStr : ips)
{
if (isIP(iStr) && iStr.equals(ip))
{
return true;
}
else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
{
return true;
}
else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
{
return true;
}
}
return false;
}
} }

View File

@ -1,8 +1,5 @@
package com.ruoyi.common.core.utils.poi; package com.ruoyi.common.core.utils.poi;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
/** /**
* Excel * Excel
* *
@ -15,10 +12,8 @@ public interface ExcelHandlerAdapter
* *
* @param value * @param value
* @param args excelargs * @param args excelargs
* @param cell
* @param wb 簿
* *
* @return * @return
*/ */
Object format(Object value, String[] args, Cell cell, Workbook wb); Object format(Object value, String[] args);
} }

View File

@ -4,14 +4,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -20,15 +18,12 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint; import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper; import org.apache.poi.ss.usermodel.DataValidationHelper;
@ -38,7 +33,6 @@ import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.usermodel.VerticalAlignment;
@ -56,7 +50,6 @@ import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.annotation.Excel.ColumnType; import com.ruoyi.common.core.annotation.Excel.ColumnType;
import com.ruoyi.common.core.annotation.Excel.Type; import com.ruoyi.common.core.annotation.Excel.Type;
import com.ruoyi.common.core.annotation.Excels; import com.ruoyi.common.core.annotation.Excels;
import com.ruoyi.common.core.exception.UtilException;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
@ -73,8 +66,6 @@ public class ExcelUtil<T>
{ {
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
public static final String SEPARATOR = ",";
public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
@ -134,71 +125,26 @@ public class ExcelUtil<T>
*/ */
private short maxHeight; private short maxHeight;
/**
*
*/
private int subMergedLastRowNum = 0;
/**
*
*/
private int subMergedFirstRowNum = 1;
/**
*
*/
private Map<String, Method> subMethods;
/**
*
*/
private Map<String, List<Field>> subFieldsMap;
/** /**
* *
*/ */
private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
/**
*
*/
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
/** /**
* *
*/ */
public Class<T> clazz; public Class<T> clazz;
/**
*
*/
public String[] includeFields;
/**
*
*/
public String[] excludeFields;
public ExcelUtil(Class<T> clazz) public ExcelUtil(Class<T> clazz)
{ {
this.clazz = clazz; this.clazz = clazz;
} }
/**
* Excel
*
* @param fields ["name"/"id","name"]
*/
public void showColumn(String... fields)
{
this.includeFields = fields;
}
/**
* Excel
*
* @param fields ["name"/"id","name"]
*/
public void hideColumn(String... fields)
{
this.excludeFields = fields;
}
public void init(List<T> list, String sheetName, String title, Type type) public void init(List<T> list, String sheetName, String title, Type type)
{ {
if (list == null) if (list == null)
@ -212,7 +158,6 @@ public class ExcelUtil<T>
createExcelField(); createExcelField();
createWorkbook(); createWorkbook();
createTitle(); createTitle();
createSubHead();
} }
/** /**
@ -222,58 +167,13 @@ public class ExcelUtil<T>
{ {
if (StringUtils.isNotEmpty(title)) if (StringUtils.isNotEmpty(title))
{ {
int titleLastCol = this.fields.size() - 1;
if (isSubList())
{
for (List<Field> currentSubFields : subFieldsMap.values())
{
titleLastCol = titleLastCol + currentSubFields.size() - 1;
}
}
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
titleRow.setHeightInPoints(30); titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0); Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("title")); titleCell.setCellStyle(styles.get("title"));
titleCell.setCellValue(title); titleCell.setCellValue(title);
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), 0, titleLastCol)); sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(),
} this.fields.size() - 1));
}
/**
*
*/
public void createSubHead()
{
if (isSubList())
{
Row subRow = sheet.createRow(rownum);
int column = 0;
for (Object[] objects : fields)
{
Field field = (Field) objects[0];
Excel attr = (Excel) objects[1];
CellStyle cellStyle = styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()));
if (Collection.class.isAssignableFrom(field.getType()))
{
Cell cell = subRow.createCell(column);
cell.setCellValue(attr.name());
cell.setCellStyle(cellStyle);
int subFieldSize = subFieldsMap != null ? subFieldsMap.get(field.getName()).size() : 0;
if (subFieldSize > 1)
{
CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1);
sheet.addMergedRegion(cellAddress);
}
column += subFieldSize;
}
else
{
Cell cell = subRow.createCell(column++);
cell.setCellValue(attr.name());
cell.setCellStyle(cellStyle);
}
}
rownum++;
} }
} }
@ -283,7 +183,7 @@ public class ExcelUtil<T>
* @param is * @param is
* @return * @return
*/ */
public List<T> importExcel(InputStream is) public List<T> importExcel(InputStream is) throws Exception
{ {
return importExcel(is, 0); return importExcel(is, 0);
} }
@ -295,23 +195,9 @@ public class ExcelUtil<T>
* @param titleNum * @param titleNum
* @return * @return
*/ */
public List<T> importExcel(InputStream is, int titleNum) public List<T> importExcel(InputStream is, int titleNum) throws Exception
{ {
List<T> list = null; return importExcel(StringUtils.EMPTY, is, titleNum);
try
{
list = importExcel(StringUtils.EMPTY, is, titleNum);
}
catch (Exception e)
{
log.error("导入Excel异常{}", e.getMessage());
throw new UtilException(e.getMessage());
}
finally
{
IOUtils.closeQuietly(is);
}
return list;
} }
/** /**
@ -336,17 +222,14 @@ public class ExcelUtil<T>
// 获取最后一个非空行的行下标比如总行数为n则返回的为n-1 // 获取最后一个非空行的行下标比如总行数为n则返回的为n-1
int rows = sheet.getLastRowNum(); int rows = sheet.getLastRowNum();
if (rows > 0) if (rows > 0)
{ {
// 定义一个map用于存放excel列的序号和field. // 定义一个map用于存放excel列的序号和field.
Map<String, Integer> cellMap = new HashMap<String, Integer>(); Map<String, Integer> cellMap = new HashMap<String, Integer>();
// 获取表头 // 获取表头
Row heard = sheet.getRow(titleNum); Row heard = sheet.getRow(titleNum);
if (heard == null) for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
{
throw new UtilException("文件标题行为空请检查Excel文件格式");
}
for (int i = 0; i < heard.getLastCellNum(); i++)
{ {
Cell cell = heard.getCell(i); Cell cell = heard.getCell(i);
if (StringUtils.isNotNull(cell)) if (StringUtils.isNotNull(cell))
@ -354,6 +237,10 @@ public class ExcelUtil<T>
String value = this.getCellValue(heard, i).toString(); String value = this.getCellValue(heard, i).toString();
cellMap.put(value, i); cellMap.put(value, i);
} }
else
{
cellMap.put(null, i);
}
} }
// 有数据时才处理 得到类的所有field. // 有数据时才处理 得到类的所有field.
List<Object[]> fields = this.getFields(); List<Object[]> fields = this.getFields();
@ -391,7 +278,7 @@ public class ExcelUtil<T>
if (String.class == fieldType) if (String.class == fieldType)
{ {
String s = Convert.toStr(val); String s = Convert.toStr(val);
if (s.matches("^\\d+\\.0$")) if (StringUtils.endsWith(s, ".0"))
{ {
val = StringUtils.substringBefore(s, ".0"); val = StringUtils.substringBefore(s, ".0");
} }
@ -450,13 +337,13 @@ public class ExcelUtil<T>
{ {
propertyName = field.getName() + "." + attr.targetAttr(); propertyName = field.getName() + "." + attr.targetAttr();
} }
if (StringUtils.isNotEmpty(attr.readConverterExp())) else if (StringUtils.isNotEmpty(attr.readConverterExp()))
{ {
val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
} }
else if (!attr.handler().equals(ExcelHandlerAdapter.class)) else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{ {
val = dataFormatHandlerAdapter(val, attr, null); val = dataFormatHandlerAdapter(val, attr);
} }
ReflectUtils.invokeSetter(entity, propertyName, val); ReflectUtils.invokeSetter(entity, propertyName, val);
} }
@ -474,6 +361,7 @@ public class ExcelUtil<T>
* @param list * @param list
* @param sheetName * @param sheetName
* @return * @return
* @throws IOException
*/ */
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName) public void exportExcel(HttpServletResponse response, List<T> list, String sheetName)
{ {
@ -488,6 +376,7 @@ public class ExcelUtil<T>
* @param sheetName * @param sheetName
* @param title * @param title
* @return * @return
* @throws IOException
*/ */
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title) public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title)
{ {
@ -497,6 +386,12 @@ public class ExcelUtil<T>
exportExcel(response); exportExcel(response);
} }
/**
* listexcel
*
* @param sheetName
* @return
*/
/** /**
* listexcel * listexcel
* *
@ -562,25 +457,12 @@ public class ExcelUtil<T>
// 写入各个字段的列头名称 // 写入各个字段的列头名称
for (Object[] os : fields) for (Object[] os : fields)
{ {
Field field = (Field) os[0];
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
if (Collection.class.isAssignableFrom(field.getType())) this.createCell(excel, row, column++);
{
List<Field> currentSubFields = subFieldsMap.get(field.getName());
for (Field subField : currentSubFields)
{
Excel subExcel = subField.getAnnotation(Excel.class);
this.createHeadCell(subExcel, row, column++);
}
}
else
{
this.createHeadCell(excel, row, column++);
}
} }
if (Type.EXPORT.equals(type)) if (Type.EXPORT.equals(type))
{ {
fillExcelData(index); fillExcelData(index, row);
addStatisticsRow(); addStatisticsRow();
} }
} }
@ -590,98 +472,25 @@ public class ExcelUtil<T>
* excel * excel
* *
* @param index * @param index
* @param row
*/ */
@SuppressWarnings("unchecked") public void fillExcelData(int index, Row row)
public void fillExcelData(int index)
{ {
int startNo = index * sheetSize; int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size()); int endNo = Math.min(startNo + sheetSize, list.size());
int currentRowNum = rownum + 1; // 从标题行后开始
for (int i = startNo; i < endNo; i++) for (int i = startNo; i < endNo; i++)
{ {
Row row = sheet.createRow(currentRowNum); row = sheet.createRow(i + 1 + rownum - startNo);
// 得到导出对象.
T vo = (T) list.get(i); T vo = (T) list.get(i);
int column = 0; int column = 0;
int maxSubListSize = getCurrentMaxSubListSize(vo);
for (Object[] os : fields) for (Object[] os : fields)
{ {
Field field = (Field) os[0]; Field field = (Field) os[0];
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
if (Collection.class.isAssignableFrom(field.getType())) this.addCell(excel, row, vo, field, column++);
{
try
{
Collection<?> subList = (Collection<?>) getTargetValue(vo, field, excel);
List<Field> currentSubFields = subFieldsMap.get(field.getName());
if (subList != null && !subList.isEmpty())
{
int subIndex = 0;
for (Object subVo : subList)
{
Row subRow = sheet.getRow(currentRowNum + subIndex);
if (subRow == null)
{
subRow = sheet.createRow(currentRowNum + subIndex);
}
int subColumn = column;
for (Field subField : currentSubFields)
{
Excel subExcel = subField.getAnnotation(Excel.class);
addCell(subExcel, subRow, (T) subVo, subField, subColumn++);
}
subIndex++;
} }
} }
column += currentSubFields.size();
}
catch (Exception e)
{
log.error("填充集合数据失败", e);
}
}
else
{
// 创建单元格并设置值
addCell(excel, row, vo, field, column);
if (maxSubListSize > 1 && excel.needMerge())
{
sheet.addMergedRegion(new CellRangeAddress(currentRowNum, currentRowNum + maxSubListSize - 1, column, column));
}
column++;
}
}
currentRowNum += maxSubListSize;
}
}
/**
*
*/
private int getCurrentMaxSubListSize(T vo)
{
int maxSubListSize = 1;
for (Object[] os : fields)
{
Field field = (Field) os[0];
if (Collection.class.isAssignableFrom(field.getType()))
{
try
{
Collection<?> subList = (Collection<?>) getTargetValue(vo, field, (Excel) os[1]);
if (subList != null && !subList.isEmpty())
{
maxSubListSize = Math.max(maxSubListSize, subList.size());
}
}
catch (Exception e)
{
log.error("获取集合大小失败", e);
}
}
}
return maxSubListSize;
} }
/** /**
@ -702,8 +511,6 @@ public class ExcelUtil<T>
titleFont.setFontHeightInPoints((short) 16); titleFont.setFontHeightInPoints((short) 16);
titleFont.setBold(true); titleFont.setBold(true);
style.setFont(titleFont); style.setFont(titleFont);
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
styles.put("title", style); styles.put("title", style);
style = wb.createCellStyle(); style = wb.createCellStyle();
@ -723,151 +530,58 @@ public class ExcelUtil<T>
style.setFont(dataFont); style.setFont(dataFont);
styles.put("data", style); styles.put("data", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
Font headerFont = wb.createFont();
headerFont.setFontName("Arial");
headerFont.setFontHeightInPoints((short) 10);
headerFont.setBold(true);
headerFont.setColor(IndexedColors.WHITE.getIndex());
style.setFont(headerFont);
styles.put("header", style);
style = wb.createCellStyle(); style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER); style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setDataFormat(dataFormat.getFormat("######0.00"));
Font totalFont = wb.createFont(); Font totalFont = wb.createFont();
totalFont.setFontName("Arial"); totalFont.setFontName("Arial");
totalFont.setFontHeightInPoints((short) 10); totalFont.setFontHeightInPoints((short) 10);
style.setFont(totalFont); style.setFont(totalFont);
styles.put("total", style); styles.put("total", style);
styles.putAll(annotationHeaderStyles(wb, styles)); style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.LEFT);
styles.put("data1", style);
styles.putAll(annotationDataStyles(wb)); style = wb.createCellStyle();
return styles;
}
/**
* Excel
*
* @param wb
* @return
*/
private Map<String, CellStyle> annotationHeaderStyles(Workbook wb, Map<String, CellStyle> styles)
{
Map<String, CellStyle> headerStyles = new HashMap<String, CellStyle>();
for (Object[] os : fields)
{
Excel excel = (Excel) os[1];
String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor());
if (!headerStyles.containsKey(key))
{
CellStyle style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data")); style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.CENTER); style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER); styles.put("data2", style);
style.setFillForegroundColor(excel.headerBackgroundColor().index);
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style = wb.createCellStyle();
Font headerFont = wb.createFont(); style.cloneStyleFrom(styles.get("data"));
headerFont.setFontName("Arial"); style.setAlignment(HorizontalAlignment.RIGHT);
headerFont.setFontHeightInPoints((short) 10); styles.put("data3", style);
headerFont.setBold(true);
headerFont.setColor(excel.headerColor().index);
style.setFont(headerFont);
// 设置表格头单元格文本形式
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
headerStyles.put(key, style);
}
}
return headerStyles;
}
/**
* Excel
*
* @param wb
* @return
*/
private Map<String, CellStyle> annotationDataStyles(Workbook wb)
{
Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
for (Object[] os : fields)
{
Field field = (Field) os[0];
Excel excel = (Excel) os[1];
if (Collection.class.isAssignableFrom(field.getType()))
{
ParameterizedType pt = (ParameterizedType) field.getGenericType();
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
for (Field subField : subFields)
{
Excel subExcel = subField.getAnnotation(Excel.class);
annotationDataStyles(styles, subField, subExcel);
}
}
else
{
annotationDataStyles(styles, field, excel);
}
}
return styles; return styles;
} }
/**
* Excel
*
* @param styles
* @param field
* @param excel
*/
public void annotationDataStyles(Map<String, CellStyle> styles, Field field, Excel excel)
{
String key = StringUtils.format("data_{}_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType(), excel.wrapText());
if (!styles.containsKey(key))
{
CellStyle style = wb.createCellStyle();
style.setAlignment(excel.align());
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(excel.backgroundColor().getIndex());
style.setWrapText(excel.wrapText());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10);
dataFont.setColor(excel.color().index);
style.setFont(dataFont);
if (ColumnType.TEXT == excel.cellType())
{
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
}
styles.put(key, style);
}
}
/** /**
* *
*/ */
public Cell createHeadCell(Excel attr, Row row, int column) public Cell createCell(Excel attr, Row row, int column)
{ {
// 创建列 // 创建列
Cell cell = row.createCell(column); Cell cell = row.createCell(column);
// 写入列信息 // 写入列信息
cell.setCellValue(attr.name()); cell.setCellValue(attr.name());
setDataValidation(attr, row, column); setDataValidation(attr, row, column);
cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); cell.setCellStyle(styles.get("header"));
if (isSubList())
{
// 填充默认样式,防止合并单元格样式失效
sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType(), attr.wrapText())));
if (attr.needMerge())
{
sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
}
}
return cell; return cell;
} }
@ -880,7 +594,7 @@ public class ExcelUtil<T>
*/ */
public void setCellVo(Object value, Excel attr, Cell cell) public void setCellVo(Object value, Excel attr, Cell cell)
{ {
if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType()) if (ColumnType.STRING == attr.cellType())
{ {
String cellValue = Convert.toStr(value); String cellValue = Convert.toStr(value);
// 对于任何以表达式触发字符 =-+@开头的单元格直接使用tab字符作为前缀防止CSV注入。 // 对于任何以表达式触发字符 =-+@开头的单元格直接使用tab字符作为前缀防止CSV注入。
@ -888,10 +602,6 @@ public class ExcelUtil<T>
{ {
cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
} }
if (value instanceof Collection && StringUtils.equals("[]", cellValue))
{
cellValue = StringUtils.EMPTY;
}
cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
} }
else if (ColumnType.NUMERIC == attr.cellType()) else if (ColumnType.NUMERIC == attr.cellType())
@ -958,19 +668,11 @@ public class ExcelUtil<T>
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
} }
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
{
if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255)
{
// 如果下拉数大于15或字符串长度大于255则使用一个新sheet存储避免生成的模板下拉值获取不到
setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
}
else
{ {
// 提示信息或只能选择不能输入的列内容. // 提示信息或只能选择不能输入的列内容.
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
} }
} }
}
/** /**
* *
@ -987,14 +689,8 @@ public class ExcelUtil<T>
{ {
// 创建cell // 创建cell
cell = row.createCell(column); cell = row.createCell(column);
if (isSubListValue(vo) && getListCellValue(vo) > 1 && attr.needMerge()) int align = attr.align().value();
{ cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : "")));
if (subMergedLastRowNum >= subMergedFirstRowNum)
{
sheet.addMergedRegion(new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column));
}
}
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType(), attr.wrapText())));
// 用于读取对象中的属性 // 用于读取对象中的属性
Object value = getTargetValue(vo, field, attr); Object value = getTargetValue(vo, field, attr);
@ -1003,7 +699,6 @@ public class ExcelUtil<T>
String separator = attr.separator(); String separator = attr.separator();
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
{ {
cell.getCellStyle().setDataFormat(this.wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
cell.setCellValue(parseDateToStr(dateFormat, value)); cell.setCellValue(parseDateToStr(dateFormat, value));
} }
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
@ -1012,11 +707,11 @@ public class ExcelUtil<T>
} }
else if (value instanceof BigDecimal && -1 != attr.scale()) else if (value instanceof BigDecimal && -1 != attr.scale())
{ {
cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString());
} }
else if (!attr.handler().equals(ExcelHandlerAdapter.class)) else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{ {
cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); cell.setCellValue(dataFormatHandlerAdapter(value, attr));
} }
else else
{ {
@ -1070,76 +765,6 @@ public class ExcelUtil<T>
sheet.addValidationData(dataValidation); sheet.addValidationData(dataValidation);
} }
/**
* ,.
*
* @param sheet sheet.
* @param textlist
* @param promptContent
* @param firstRow
* @param endRow
* @param firstCol
* @param endCol
*/
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
{
String hideSheetName = "combo_" + firstCol + "_" + endCol;
Sheet hideSheet = null;
String hideSheetDataName = hideSheetName + "_data";
Name name = wb.getName(hideSheetDataName);
if (name != null)
{
// 名称已存在尝试从名称的引用中找到sheet名称
String refersToFormula = name.getRefersToFormula();
if (StringUtils.isNotEmpty(refersToFormula) && refersToFormula.contains("!"))
{
String sheetNameFromFormula = refersToFormula.substring(0, refersToFormula.indexOf("!"));
hideSheet = wb.getSheet(sheetNameFromFormula);
}
}
if (hideSheet == null)
{
hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
for (int i = 0; i < textlist.length; i++)
{
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
}
// 创建名称,可被其他单元格引用
name = wb.createName();
name.setNameName(hideSheetDataName);
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
}
DataValidationHelper helper = sheet.getDataValidationHelper();
// 加载下拉列表内容
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetDataName);
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
// 数据有效性对象
DataValidation dataValidation = helper.createValidation(constraint, regions);
if (StringUtils.isNotEmpty(promptContent))
{
// 如果设置了提示信息则鼠标放上去提示
dataValidation.createPromptBox("", promptContent);
dataValidation.setShowPromptBox(true);
}
// 处理Excel兼容性问题
if (dataValidation instanceof XSSFDataValidation)
{
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
}
else
{
dataValidation.setSuppressDropDownArrow(false);
}
sheet.addValidationData(dataValidation);
// 设置hiddenSheet隐藏
wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);
}
/** /**
* 0=,1=,2= * 0=,1=,2=
* *
@ -1151,11 +776,11 @@ public class ExcelUtil<T>
public static String convertByExp(String propertyValue, String converterExp, String separator) public static String convertByExp(String propertyValue, String converterExp, String separator)
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(SEPARATOR); String[] convertSource = converterExp.split(",");
for (String item : convertSource) for (String item : convertSource)
{ {
String[] itemArray = item.split("="); String[] itemArray = item.split("=");
if (StringUtils.containsAny(propertyValue, separator)) if (StringUtils.containsAny(separator, propertyValue))
{ {
for (String value : propertyValue.split(separator)) for (String value : propertyValue.split(separator))
{ {
@ -1188,11 +813,11 @@ public class ExcelUtil<T>
public static String reverseByExp(String propertyValue, String converterExp, String separator) public static String reverseByExp(String propertyValue, String converterExp, String separator)
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(SEPARATOR); String[] convertSource = converterExp.split(",");
for (String item : convertSource) for (String item : convertSource)
{ {
String[] itemArray = item.split("="); String[] itemArray = item.split("=");
if (StringUtils.containsAny(propertyValue, separator)) if (StringUtils.containsAny(separator, propertyValue))
{ {
for (String value : propertyValue.split(separator)) for (String value : propertyValue.split(separator))
{ {
@ -1221,13 +846,13 @@ public class ExcelUtil<T>
* @param excel * @param excel
* @return * @return
*/ */
public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell) public String dataFormatHandlerAdapter(Object value, Excel excel)
{ {
try try
{ {
Object instance = excel.handler().newInstance(); Object instance = excel.handler().newInstance();
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class });
value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); value = formatMethod.invoke(instance, value, excel.args());
} }
catch (Exception e) catch (Exception e)
{ {
@ -1276,7 +901,7 @@ public class ExcelUtil<T>
{ {
cell = row.createCell(key); cell = row.createCell(key);
cell.setCellStyle(styles.get("total")); cell.setCellStyle(styles.get("total"));
cell.setCellValue(statistics.get(key)); cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));
} }
statistics.clear(); statistics.clear();
} }
@ -1293,7 +918,6 @@ public class ExcelUtil<T>
*/ */
private Object getTargetValue(T vo, Field field, Excel excel) throws Exception private Object getTargetValue(T vo, Field field, Excel excel) throws Exception
{ {
field.setAccessible(true);
Object o = field.get(vo); Object o = field.get(vo);
if (StringUtils.isNotEmpty(excel.targetAttr())) if (StringUtils.isNotEmpty(excel.targetAttr()))
{ {
@ -1351,44 +975,9 @@ public class ExcelUtil<T>
{ {
List<Object[]> fields = new ArrayList<Object[]>(); List<Object[]> fields = new ArrayList<Object[]>();
List<Field> tempFields = new ArrayList<>(); List<Field> tempFields = new ArrayList<>();
subFieldsMap = new HashMap<>();
subMethods = new HashMap<>();
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
if (StringUtils.isNotEmpty(includeFields))
{
for (Field field : tempFields) for (Field field : tempFields)
{
if (ArrayUtils.contains(this.includeFields, field.getName()) || field.isAnnotationPresent(Excels.class))
{
addField(fields, field);
}
}
}
else if (StringUtils.isNotEmpty(excludeFields))
{
for (Field field : tempFields)
{
if (!ArrayUtils.contains(this.excludeFields, field.getName()))
{
addField(fields, field);
}
}
}
else
{
for (Field field : tempFields)
{
addField(fields, field);
}
}
return fields;
}
/**
*
*/
public void addField(List<Object[]> fields, Field field)
{ {
// 单注解 // 单注解
if (field.isAnnotationPresent(Excel.class)) if (field.isAnnotationPresent(Excel.class))
@ -1396,16 +985,9 @@ public class ExcelUtil<T>
Excel attr = field.getAnnotation(Excel.class); Excel attr = field.getAnnotation(Excel.class);
if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{ {
field.setAccessible(true);
fields.add(new Object[] { field, attr }); fields.add(new Object[] { field, attr });
} }
if (Collection.class.isAssignableFrom(field.getType()))
{
String fieldName = field.getName();
subMethods.put(fieldName, getSubMethod(fieldName, clazz));
ParameterizedType pt = (ParameterizedType) field.getGenericType();
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
subFieldsMap.put(fieldName, FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class));
}
} }
// 多注解 // 多注解
@ -1415,24 +997,15 @@ public class ExcelUtil<T>
Excel[] excels = attrs.value(); Excel[] excels = attrs.value();
for (Excel attr : excels) for (Excel attr : excels)
{ {
if (StringUtils.isNotEmpty(includeFields)) if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
if (ArrayUtils.contains(this.includeFields, field.getName() + "." + attr.targetAttr())
&& (attr != null && (attr.type() == Type.ALL || attr.type() == type)))
{
fields.add(new Object[] { field, attr });
}
}
else
{
if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr())
&& (attr != null && (attr.type() == Type.ALL || attr.type() == type)))
{ {
field.setAccessible(true);
fields.add(new Object[] { field, attr }); fields.add(new Object[] { field, attr });
} }
} }
} }
} }
return fields;
} }
/** /**
@ -1473,8 +1046,7 @@ public class ExcelUtil<T>
{ {
this.sheet = wb.createSheet(); this.sheet = wb.createSheet();
this.createTitle(); this.createTitle();
int actualIndex = wb.getSheetIndex(this.sheet); wb.setSheetName(index, sheetName + index);
wb.setSheetName(actualIndex, sheetName + index);
} }
} }
@ -1593,69 +1165,4 @@ public class ExcelUtil<T>
} }
return str; return str;
} }
/**
*
*/
public boolean isSubList()
{
return !StringUtils.isEmpty(subFieldsMap);
}
/**
*
*/
public boolean isSubListValue(T vo)
{
return !StringUtils.isEmpty(subFieldsMap) && getListCellValue(vo) > 0;
}
/**
*
*/
public int getListCellValue(Object obj)
{
Collection<?> value;
int max = 0;
try
{
for (String s : subMethods.keySet())
{
value = (Collection<?>) subMethods.get(s).invoke(obj);
if (value.size() > max)
{
max = value.size();
}
}
}
catch (Exception e)
{
return 0;
}
return max;
}
/**
*
*
* @param name
* @param pojoClass
* @return
*/
public Method getSubMethod(String name, Class<?> pojoClass)
{
StringBuffer getMethodName = new StringBuffer("get");
getMethodName.append(name.substring(0, 1).toUpperCase());
getMethodName.append(name.substring(1));
Method method = null;
try
{
method = pojoClass.getMethod(getMethodName.toString(), new Class[] {});
}
catch (Exception e)
{
log.error("获取对象异常{}", e.getMessage());
}
return method;
}
} }

View File

@ -13,18 +13,13 @@ public class SqlUtil
/** /**
* sql * sql
*/ */
public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()"; public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
/** /**
* 线 * 线
*/ */
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
/**
* orderBy
*/
private static final int ORDER_BY_MAX_LENGTH = 500;
/** /**
* *
*/ */
@ -34,10 +29,6 @@ public class SqlUtil
{ {
throw new UtilException("参数不符合规范,不能进行查询"); throw new UtilException("参数不符合规范,不能进行查询");
} }
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
{
throw new UtilException("参数已超过最大限制,不能进行查询");
}
return value; return value;
} }

View File

@ -22,7 +22,7 @@ public class Seq
private static AtomicInteger uploadSeq = new AtomicInteger(1); private static AtomicInteger uploadSeq = new AtomicInteger(1);
// 机器标识 // 机器标识
private static final String machineCode = "A"; private static String machineCode = "A";
/** /**
* *

View File

@ -66,7 +66,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
} }
/** /**
* 4UUID * 4UUID 使线 UUID
* *
* @return {@code UUID} * @return {@code UUID}
*/ */
@ -343,25 +343,25 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
// time_low // time_low
builder.append(digits(mostSigBits >> 32, 8)); builder.append(digits(mostSigBits >> 32, 8));
if (!isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// time_mid // time_mid
builder.append(digits(mostSigBits >> 16, 4)); builder.append(digits(mostSigBits >> 16, 4));
if (!isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// time_high_and_version // time_high_and_version
builder.append(digits(mostSigBits, 4)); builder.append(digits(mostSigBits, 4));
if (!isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// variant_and_sequence // variant_and_sequence
builder.append(digits(leastSigBits >> 48, 4)); builder.append(digits(leastSigBits >> 48, 4));
if (!isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }

View File

@ -7,17 +7,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.InitBinder;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.constant.HttpStatus; import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.PageUtils; import com.ruoyi.common.core.utils.PageUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.sql.SqlUtil;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageDomain;
import com.ruoyi.common.core.web.page.TableDataInfo; import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.core.web.page.TableSupport;
/** /**
* web * web
@ -53,19 +48,6 @@ public class BaseController
PageUtils.startPage(); PageUtils.startPage();
} }
/**
*
*/
protected void startOrderBy()
{
PageDomain pageDomain = TableSupport.buildPageRequest();
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
{
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.orderBy(orderBy);
}
}
/** /**
* 线 * 线
*/ */
@ -88,54 +70,6 @@ public class BaseController
return rspData; return rspData;
} }
/**
*
*/
public AjaxResult success()
{
return AjaxResult.success();
}
/**
*
*/
public AjaxResult success(String message)
{
return AjaxResult.success(message);
}
/**
*
*/
public AjaxResult success(Object data)
{
return AjaxResult.success(data);
}
/**
*
*/
public AjaxResult error()
{
return AjaxResult.error();
}
/**
*
*/
public AjaxResult error(String message)
{
return AjaxResult.error(message);
}
/**
*
*/
public AjaxResult warn(String message)
{
return AjaxResult.warn(message);
}
/** /**
* *
* *
@ -157,4 +91,36 @@ public class BaseController
{ {
return result ? success() : error(); return result ? success() : error();
} }
/**
*
*/
public AjaxResult success()
{
return AjaxResult.success();
}
/**
*
*/
public AjaxResult error()
{
return AjaxResult.error();
}
/**
*
*/
public AjaxResult success(String message)
{
return AjaxResult.success(message);
}
/**
*
*/
public AjaxResult error(String message)
{
return AjaxResult.error(message);
}
} }

View File

@ -1,7 +1,6 @@
package com.ruoyi.common.core.web.domain; package com.ruoyi.common.core.web.domain;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
import com.ruoyi.common.core.constant.HttpStatus; import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
@ -59,6 +58,20 @@ public class AjaxResult extends HashMap<String, Object>
} }
} }
/**
* 便
*
* @param key
* @param value
* @return
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
/** /**
* *
* *
@ -102,33 +115,10 @@ public class AjaxResult extends HashMap<String, Object>
return new AjaxResult(HttpStatus.SUCCESS, msg, data); return new AjaxResult(HttpStatus.SUCCESS, msg, data);
} }
/**
*
*
* @param msg
* @return
*/
public static AjaxResult warn(String msg)
{
return AjaxResult.warn(msg, null);
}
/**
*
*
* @param msg
* @param data
* @return
*/
public static AjaxResult warn(String msg, Object data)
{
return new AjaxResult(HttpStatus.WARN, msg, data);
}
/** /**
* *
* *
* @return * @return
*/ */
public static AjaxResult error() public static AjaxResult error()
{ {
@ -139,7 +129,7 @@ public class AjaxResult extends HashMap<String, Object>
* *
* *
* @param msg * @param msg
* @return * @return
*/ */
public static AjaxResult error(String msg) public static AjaxResult error(String msg)
{ {
@ -151,7 +141,7 @@ public class AjaxResult extends HashMap<String, Object>
* *
* @param msg * @param msg
* @param data * @param data
* @return * @return
*/ */
public static AjaxResult error(String msg, Object data) public static AjaxResult error(String msg, Object data)
{ {
@ -163,54 +153,10 @@ public class AjaxResult extends HashMap<String, Object>
* *
* @param code * @param code
* @param msg * @param msg
* @return * @return
*/ */
public static AjaxResult error(int code, String msg) public static AjaxResult error(int code, String msg)
{ {
return new AjaxResult(code, msg, null); return new AjaxResult(code, msg, null);
} }
/**
*
*
* @return
*/
public boolean isSuccess()
{
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
}
/**
*
*
* @return
*/
public boolean isWarn()
{
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
}
/**
*
*
* @return
*/
public boolean isError()
{
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
}
/**
* 便
*
* @param key
* @param value
* @return
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
} }

View File

@ -5,8 +5,6 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
/** /**
* Entity * Entity
@ -18,7 +16,6 @@ public class BaseEntity implements Serializable
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 搜索值 */ /** 搜索值 */
@JsonIgnore
private String searchValue; private String searchValue;
/** 创建者 */ /** 创建者 */
@ -39,7 +36,6 @@ public class BaseEntity implements Serializable
private String remark; private String remark;
/** 请求参数 */ /** 请求参数 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params; private Map<String, Object> params;
public String getSearchValue() public String getSearchValue()

View File

@ -37,7 +37,7 @@ public class TableDataInfo implements Serializable
* @param list * @param list
* @param total * @param total
*/ */
public TableDataInfo(List<?> list, long total) public TableDataInfo(List<?> list, int total)
{ {
this.rows = list; this.rows = list;
this.total = total; this.total = total;

View File

@ -1,6 +1,5 @@
package com.ruoyi.common.core.web.page; package com.ruoyi.common.core.web.page;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.ServletUtils;
/** /**
@ -41,8 +40,8 @@ public class TableSupport
public static PageDomain getPageDomain() public static PageDomain getPageDomain()
{ {
PageDomain pageDomain = new PageDomain(); PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); pageDomain.setPageNum(ServletUtils.getParameterToInt(PAGE_NUM));
pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); pageDomain.setPageSize(ServletUtils.getParameterToInt(PAGE_SIZE));
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));

View File

@ -27,13 +27,8 @@ public class XssValidator implements ConstraintValidator<Xss, String>
public static boolean containsHtml(String value) public static boolean containsHtml(String value)
{ {
StringBuilder sHtml = new StringBuilder();
Pattern pattern = Pattern.compile(HTML_PATTERN); Pattern pattern = Pattern.compile(HTML_PATTERN);
Matcher matcher = pattern.matcher(value); Matcher matcher = pattern.matcher(value);
while (matcher.find()) return matcher.matches();
{
sHtml.append(matcher.group());
}
return pattern.matcher(sHtml).matches();
} }
} }

View File

@ -0,0 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.core.utils.SpringUtils

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -25,9 +25,4 @@ public @interface DataScope
* *
*/ */
public String userAlias() default ""; public String userAlias() default "";
/**
* @RequiresPermissions
*/
public String permission() default "";
} }

View File

@ -1,14 +1,9 @@
package com.ruoyi.common.datascope.aspect; package com.ruoyi.common.datascope.aspect;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.BaseEntity; import com.ruoyi.common.core.web.domain.BaseEntity;
import com.ruoyi.common.datascope.annotation.DataScope; import com.ruoyi.common.datascope.annotation.DataScope;
@ -73,8 +68,8 @@ public class DataScopeAspect
// 如果是超级管理员,则不过滤数据 // 如果是超级管理员,则不过滤数据
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
{ {
String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), SecurityContextHolder.getPermission()); dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), controllerDataScope.userAlias(), permission); controllerDataScope.userAlias());
} }
} }
} }
@ -86,48 +81,24 @@ public class DataScopeAspect
* @param user * @param user
* @param deptAlias * @param deptAlias
* @param userAlias * @param userAlias
* @param permission
*/ */
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
{ {
StringBuilder sqlString = new StringBuilder(); StringBuilder sqlString = new StringBuilder();
List<String> conditions = new ArrayList<String>();
List<String> scopeCustomIds = new ArrayList<String>();
user.getRoles().forEach(role -> {
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && (StringUtils.isEmpty(permission) || StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))))
{
scopeCustomIds.add(Convert.toStr(role.getRoleId()));
}
});
for (SysRole role : user.getRoles()) for (SysRole role : user.getRoles())
{ {
String dataScope = role.getDataScope(); String dataScope = role.getDataScope();
if (conditions.contains(dataScope) || StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE))
{
continue;
}
if (StringUtils.isNotEmpty(permission) && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{
continue;
}
if (DATA_SCOPE_ALL.equals(dataScope)) if (DATA_SCOPE_ALL.equals(dataScope))
{ {
sqlString = new StringBuilder(); sqlString = new StringBuilder();
conditions.add(dataScope);
break; break;
} }
else if (DATA_SCOPE_CUSTOM.equals(dataScope)) else if (DATA_SCOPE_CUSTOM.equals(dataScope))
{ {
if (scopeCustomIds.size() > 1) sqlString.append(StringUtils.format(
{ " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
// 多个自定数据权限使用in查询避免多次拼接。 role.getRoleId()));
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds)));
}
else
{
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
}
} }
else if (DATA_SCOPE_DEPT.equals(dataScope)) else if (DATA_SCOPE_DEPT.equals(dataScope))
{ {
@ -135,7 +106,9 @@ public class DataScopeAspect
} }
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
{ {
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId())); sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
deptAlias, user.getDeptId(), user.getDeptId()));
} }
else if (DATA_SCOPE_SELF.equals(dataScope)) else if (DATA_SCOPE_SELF.equals(dataScope))
{ {
@ -146,16 +119,9 @@ public class DataScopeAspect
else else
{ {
// 数据权限为仅本人且没有userAlias别名不查询任何数据 // 数据权限为仅本人且没有userAlias别名不查询任何数据
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); sqlString.append(" OR 1=0 ");
} }
} }
conditions.add(dataScope);
}
// 角色都不包含传递过来的权限字符这个时候sqlString也会为空所以要限制一下,不查询任何数据
if (StringUtils.isEmpty(conditions))
{
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
} }
if (StringUtils.isNotBlank(sqlString.toString())) if (StringUtils.isNotBlank(sqlString.toString()))

View File

@ -0,0 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.datascope.aspect.DataScopeAspect

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -31,5 +31,11 @@
<version>${dynamic-ds.version}</version> <version>${dynamic-ds.version}</version>
</dependency> </dependency>
<!-- SpringBoot Seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,26 @@
package com.ruoyi.common.datasource.env;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* seata springboot 2.6.x
*
* @author ruoyi
*/
public class ApplicationSeataInitializer implements EnvironmentPostProcessor, Ordered
{
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application)
{
System.setProperty("spring.main.allow-circular-references", "true");
}
@Override
public int getOrder()
{
return Ordered.LOWEST_PRECEDENCE;
}
}

View File

@ -0,0 +1,2 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
com.ruoyi.common.datasource.env.ApplicationSeataInitializer

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -43,9 +43,4 @@ public @interface Log
* *
*/ */
public boolean isSaveResponseData() default true; public boolean isSaveResponseData() default true;
/**
*
*/
public String[] excludeParamNames() default {};
} }

View File

@ -4,29 +4,23 @@ import java.util.Collection;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.ExceptionUtil;
import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ip.IpUtils; import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessStatus; import com.ruoyi.common.log.enums.BusinessStatus;
import com.ruoyi.common.log.filter.PropertyPreExcludeFilter;
import com.ruoyi.common.log.service.AsyncLogService; import com.ruoyi.common.log.service.AsyncLogService;
import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysOperLog; import com.ruoyi.system.api.domain.SysOperLog;
@ -42,27 +36,9 @@ public class LogAspect
{ {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class); private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
/** 排除敏感属性字段 */
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
/** 计算操作消耗时间 */
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
/** 参数最大长度限制 */
private static final int PARAM_MAX_LENGTH = 2000;
@Autowired @Autowired
private AsyncLogService asyncLogService; private AsyncLogService asyncLogService;
/**
*
*/
@Before(value = "@annotation(controllerLog)")
public void doBefore(JoinPoint joinPoint, Log controllerLog)
{
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
/** /**
* *
* *
@ -94,9 +70,9 @@ public class LogAspect
SysOperLog operLog = new SysOperLog(); SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址 // 请求的地址
String ip = IpUtils.getIpAddr(); String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip); operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
String username = SecurityUtils.getUsername(); String username = SecurityUtils.getUsername();
if (StringUtils.isNotBlank(username)) if (StringUtils.isNotBlank(username))
{ {
@ -106,7 +82,7 @@ public class LogAspect
if (e != null) if (e != null)
{ {
operLog.setStatus(BusinessStatus.FAIL.ordinal()); operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(Convert.toStr(e.getMessage(), ExceptionUtil.getExceptionMessage(e)), 0, 2000)); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
} }
// 设置方法名称 // 设置方法名称
String className = joinPoint.getTarget().getClass().getName(); String className = joinPoint.getTarget().getClass().getName();
@ -116,21 +92,16 @@ public class LogAspect
operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数 // 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 设置消耗时间
operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
// 保存数据库 // 保存数据库
asyncLogService.saveSysLog(operLog); asyncLogService.saveSysLog(operLog);
} }
catch (Exception exp) catch (Exception exp)
{ {
// 记录本地异常日志 // 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage()); log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace(); exp.printStackTrace();
} }
finally
{
TIME_THREADLOCAL.remove();
}
} }
/** /**
@ -152,7 +123,7 @@ public class LogAspect
if (log.isSaveRequestData()) if (log.isSaveRequestData())
{ {
// 获取参数的信息,传入到数据库中。 // 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, operLog, log.excludeParamNames()); setRequestValue(joinPoint, operLog);
} }
// 是否需要保存response参数和值 // 是否需要保存response参数和值
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
@ -167,27 +138,22 @@ public class LogAspect
* @param operLog * @param operLog
* @throws Exception * @throws Exception
*/ */
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
{ {
String requestMethod = operLog.getRequestMethod(); String requestMethod = operLog.getRequestMethod();
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name()))
{ {
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(params); operLog.setOperParam(StringUtils.substring(params, 0, 2000));
}
else
{
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, PARAM_MAX_LENGTH));
} }
} }
/** /**
* *
*/ */
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) private String argsArrayToString(Object[] paramsArray)
{ {
StringBuilder params = new StringBuilder(); String params = "";
if (paramsArray != null && paramsArray.length > 0) if (paramsArray != null && paramsArray.length > 0)
{ {
for (Object o : paramsArray) for (Object o : paramsArray)
@ -196,29 +162,16 @@ public class LogAspect
{ {
try try
{ {
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); Object jsonObj = JSON.toJSON(o);
params.append(jsonObj).append(" "); params += jsonObj.toString() + " ";
if (params.length() >= PARAM_MAX_LENGTH)
{
return StringUtils.substring(params.toString(), 0, PARAM_MAX_LENGTH);
}
} }
catch (Exception e) catch (Exception e)
{ {
log.error("请求参数拼装异常 msg:{}, 参数:{}", e.getMessage(), paramsArray, e);
} }
} }
} }
} }
return params.toString(); return params.trim();
}
/**
*
*/
public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames)
{
return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
} }
/** /**

View File

@ -1,24 +0,0 @@
package com.ruoyi.common.log.filter;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
/**
* JSON
*
* @author ruoyi
*/
public class PropertyPreExcludeFilter extends SimplePropertyPreFilter
{
public PropertyPreExcludeFilter()
{
}
public PropertyPreExcludeFilter addExcludes(String... filters)
{
for (int i = 0; i < filters.length; i++)
{
this.getExcludes().add(filters[i]);
}
return this;
}
}

View File

@ -22,7 +22,7 @@ public class AsyncLogService
* *
*/ */
@Async @Async
public void saveSysLog(SysOperLog sysOperLog) throws Exception public void saveSysLog(SysOperLog sysOperLog)
{ {
remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER);
} }

View File

@ -0,0 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.log.service.AsyncLogService,\
com.ruoyi.common.log.aspect.LogAspect

View File

@ -1,2 +0,0 @@
com.ruoyi.common.log.service.AsyncLogService
com.ruoyi.common.log.aspect.LogAspect

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,13 +1,15 @@
package com.ruoyi.common.redis.configure; package com.ruoyi.common.redis.configure;
import java.nio.charset.Charset; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException; import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson2.JSONReader; import org.springframework.util.Assert;
import com.alibaba.fastjson2.JSONWriter; import java.nio.charset.Charset;
import com.alibaba.fastjson2.filter.Filter;
import com.ruoyi.common.core.constant.Constants;
/** /**
* Redis使FastJson * Redis使FastJson
@ -16,12 +18,18 @@ import com.ruoyi.common.core.constant.Constants;
*/ */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{ {
@SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);
private Class<T> clazz; private Class<T> clazz;
static
{
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
public FastJson2JsonRedisSerializer(Class<T> clazz) public FastJson2JsonRedisSerializer(Class<T> clazz)
{ {
super(); super();
@ -35,7 +43,7 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{ {
return new byte[0]; return new byte[0];
} }
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
} }
@Override @Override
@ -47,6 +55,17 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
} }
String str = new String(bytes, DEFAULT_CHARSET); String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER); return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper)
{
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class<?> clazz)
{
return TypeFactory.defaultInstance().constructType(clazz);
} }
} }

View File

@ -1,7 +1,5 @@
package com.ruoyi.common.redis.configure; package com.ruoyi.common.redis.configure;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -9,6 +7,11 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
/** /**
* redis * redis
@ -17,7 +20,6 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
*/ */
@Configuration @Configuration
@EnableCaching @EnableCaching
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport public class RedisConfig extends CachingConfigurerSupport
{ {
@Bean @Bean
@ -29,6 +31,11 @@ public class RedisConfig extends CachingConfigurerSupport
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
serializer.setObjectMapper(mapper);
// 使用StringRedisSerializer来序列化和反序列化redis的key值 // 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer()); template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer); template.setValueSerializer(serializer);

View File

@ -124,9 +124,9 @@ public class RedisService
* @param collection * @param collection
* @return * @return
*/ */
public boolean deleteObject(final Collection collection) public long deleteObject(final Collection collection)
{ {
return redisTemplate.delete(collection) > 0; return redisTemplate.delete(collection);
} }
/** /**
@ -243,18 +243,6 @@ public class RedisService
return redisTemplate.opsForHash().multiGet(key, hKeys); return redisTemplate.opsForHash().multiGet(key, hKeys);
} }
/**
* Hash
*
* @param key Redis
* @param hKey Hash
* @return
*/
public boolean deleteCacheMapValue(final String key, final String hKey)
{
return redisTemplate.opsForHash().delete(key, hKey) > 0;
}
/** /**
* *
* *

View File

@ -0,0 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.redis.configure.RedisConfig,\
com.ruoyi.common.redis.service.RedisService

View File

@ -1,2 +0,0 @@
com.ruoyi.common.redis.configure.RedisConfig
com.ruoyi.common.redis.service.RedisService

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-seata</artifactId>
<description>
ruoyi-common-seata分布式事务
</description>
<dependencies>
<!-- SpringBoot Seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.6</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -56,8 +56,16 @@ public class PreAuthorizeAspect
// 注解鉴权 // 注解鉴权
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); MethodSignature signature = (MethodSignature) joinPoint.getSignature();
checkMethodAnnotation(signature.getMethod()); checkMethodAnnotation(signature.getMethod());
try
{
// 执行原有逻辑 // 执行原有逻辑
return joinPoint.proceed(); Object obj = joinPoint.proceed();
return obj;
}
catch (Throwable e)
{
throw e;
}
} }
/** /**

View File

@ -4,7 +4,6 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.springframework.util.PatternMatchUtils; import org.springframework.util.PatternMatchUtils;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.exception.auth.NotLoginException; import com.ruoyi.common.core.exception.auth.NotLoginException;
import com.ruoyi.common.core.exception.auth.NotPermissionException; import com.ruoyi.common.core.exception.auth.NotPermissionException;
import com.ruoyi.common.core.exception.auth.NotRoleException; import com.ruoyi.common.core.exception.auth.NotRoleException;
@ -135,7 +134,6 @@ public class AuthLogic
*/ */
public void checkPermi(RequiresPermissions requiresPermissions) public void checkPermi(RequiresPermissions requiresPermissions)
{ {
SecurityContextHolder.setPermission(StringUtils.join(requiresPermissions.value(), ","));
if (requiresPermissions.logical() == Logical.AND) if (requiresPermissions.logical() == Logical.AND)
{ {
checkPermiAnd(requiresPermissions.value()); checkPermiAnd(requiresPermissions.value());
@ -355,7 +353,7 @@ public class AuthLogic
public boolean hasPermi(Collection<String> authorities, String permission) public boolean hasPermi(Collection<String> authorities, String permission)
{ {
return authorities.stream().filter(StringUtils::hasText) return authorities.stream().filter(StringUtils::hasText)
.anyMatch(x -> ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission)); .anyMatch(x -> ALL_PERMISSION.contains(x) || PatternMatchUtils.simpleMatch(x, permission));
} }
/** /**
@ -368,6 +366,6 @@ public class AuthLogic
public boolean hasRole(Collection<String> roles, String role) public boolean hasRole(Collection<String> roles, String role)
{ {
return roles.stream().filter(StringUtils::hasText) return roles.stream().filter(StringUtils::hasText)
.anyMatch(x -> SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role)); .anyMatch(x -> SUPER_ADMIN.contains(x) || PatternMatchUtils.simpleMatch(x, role));
} }
} }

View File

@ -27,7 +27,7 @@ public class AuthUtil
/** /**
* Token * Token
* *
* @param token token * @param tokenValue token
*/ */
public static void logoutByToken(String token) public static void logoutByToken(String token)
{ {
@ -44,9 +44,6 @@ public class AuthUtil
/** /**
* *
*
* @param token token
* @return
*/ */
public static LoginUser getLoginUser(String token) public static LoginUser getLoginUser(String token)
{ {
@ -55,8 +52,6 @@ public class AuthUtil
/** /**
* *
*
* @param loginUser
*/ */
public static void verifyLoginUserExpire(LoginUser loginUser) public static void verifyLoginUserExpire(LoginUser loginUser)
{ {

View File

@ -31,11 +31,6 @@ public class FeignRequestInterceptor implements RequestInterceptor
{ {
requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId); requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId);
} }
String userKey = headers.get(SecurityConstants.USER_KEY);
if (StringUtils.isNotEmpty(userKey))
{
requestTemplate.header(SecurityConstants.USER_KEY, userKey);
}
String userName = headers.get(SecurityConstants.DETAILS_USERNAME); String userName = headers.get(SecurityConstants.DETAILS_USERNAME);
if (StringUtils.isNotEmpty(userName)) if (StringUtils.isNotEmpty(userName))
{ {
@ -48,7 +43,7 @@ public class FeignRequestInterceptor implements RequestInterceptor
} }
// 配置客户端IP // 配置客户端IP
requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr()); requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr(ServletUtils.getRequest()));
} }
} }
} }

View File

@ -6,19 +6,15 @@ import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import com.ruoyi.common.core.constant.HttpStatus; import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.exception.DemoModeException; import com.ruoyi.common.core.exception.DemoModeException;
import com.ruoyi.common.core.exception.InnerAuthException; import com.ruoyi.common.core.exception.InnerAuthException;
import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.exception.auth.NotPermissionException; import com.ruoyi.common.core.exception.auth.NotPermissionException;
import com.ruoyi.common.core.exception.auth.NotRoleException; import com.ruoyi.common.core.exception.auth.NotRoleException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.html.EscapeUtil;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
/** /**
@ -57,7 +53,8 @@ public class GlobalExceptionHandler
* *
*/ */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
HttpServletRequest request)
{ {
String requestURI = request.getRequestURI(); String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
@ -75,33 +72,6 @@ public class GlobalExceptionHandler
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
} }
/**
*
*/
@ExceptionHandler(MissingPathVariableException.class)
public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
}
/**
*
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
String value = Convert.toStr(e.getValue());
if (StringUtils.isNotEmpty(value))
{
value = EscapeUtil.clean(value);
}
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));
}
/** /**
* *
*/ */

View File

@ -4,8 +4,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.CacheConstants;
@ -27,8 +25,6 @@ import com.ruoyi.system.api.model.LoginUser;
@Component @Component
public class TokenService public class TokenService
{ {
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
@Autowired @Autowired
private RedisService redisService; private RedisService redisService;
@ -36,11 +32,11 @@ public class TokenService
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private final static long TOKEN_EXPIRE_TIME = CacheConstants.EXPIRATION; private final static long expireTime = CacheConstants.EXPIRATION;
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY; private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
private final static Long TOKEN_REFRESH_THRESHOLD_MINUTES = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
/** /**
* *
@ -53,7 +49,7 @@ public class TokenService
loginUser.setToken(token); loginUser.setToken(token);
loginUser.setUserid(userId); loginUser.setUserid(userId);
loginUser.setUsername(userName); loginUser.setUsername(userName);
loginUser.setIpaddr(IpUtils.getIpAddr()); loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
refreshToken(loginUser); refreshToken(loginUser);
// Jwt存储信息 // Jwt存储信息
@ -65,7 +61,7 @@ public class TokenService
// 接口返回信息 // 接口返回信息
Map<String, Object> rspMap = new HashMap<String, Object>(); Map<String, Object> rspMap = new HashMap<String, Object>();
rspMap.put("access_token", JwtUtils.createToken(claimsMap)); rspMap.put("access_token", JwtUtils.createToken(claimsMap));
rspMap.put("expires_in", TOKEN_EXPIRE_TIME); rspMap.put("expires_in", expireTime);
return rspMap; return rspMap;
} }
@ -110,7 +106,6 @@ public class TokenService
} }
catch (Exception e) catch (Exception e)
{ {
log.error("获取用户信息异常'{}'", e.getMessage());
} }
return user; return user;
} }
@ -147,7 +142,7 @@ public class TokenService
{ {
long expireTime = loginUser.getExpireTime(); long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= TOKEN_REFRESH_THRESHOLD_MINUTES) if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
{ {
refreshToken(loginUser); refreshToken(loginUser);
} }
@ -161,10 +156,10 @@ public class TokenService
public void refreshToken(LoginUser loginUser) public void refreshToken(LoginUser loginUser)
{ {
loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + TOKEN_EXPIRE_TIME * MILLIS_MINUTE); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存 // 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken()); String userKey = getTokenKey(loginUser.getToken());
redisService.setCacheObject(userKey, loginUser, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES); redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
} }
private String getTokenKey(String token) private String getTokenKey(String token)

View File

@ -2,8 +2,7 @@ package com.ruoyi.common.security.utils;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import com.alibaba.fastjson2.JSONArray; import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.common.redis.service.RedisService;
@ -35,10 +34,10 @@ public class DictUtils
*/ */
public static List<SysDictData> getDictCache(String key) public static List<SysDictData> getDictCache(String key)
{ {
JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key)); Object cacheObj = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key));
if (StringUtils.isNotNull(arrayCache)) if (StringUtils.isNotNull(cacheObj))
{ {
return arrayCache.toList(SysDictData.class); return StringUtils.cast(cacheObj);
} }
return null; return null;
} }
@ -58,7 +57,7 @@ public class DictUtils
*/ */
public static void clearDictCache() public static void clearDictCache()
{ {
Collection<String> keys = SpringUtils.getBean(RedisService.class).keys(CacheConstants.SYS_DICT_KEY + "*"); Collection<String> keys = SpringUtils.getBean(RedisService.class).keys(Constants.SYS_DICT_KEY + "*");
SpringUtils.getBean(RedisService.class).deleteObject(keys); SpringUtils.getBean(RedisService.class).deleteObject(keys);
} }
@ -70,6 +69,6 @@ public class DictUtils
*/ */
public static String getCacheKey(String configKey) public static String getCacheKey(String configKey)
{ {
return CacheConstants.SYS_DICT_KEY + configKey; return Constants.SYS_DICT_KEY + configKey;
} }
} }

View File

@ -62,7 +62,7 @@ public class SecurityUtils
public static String getToken(HttpServletRequest request) public static String getToken(HttpServletRequest request)
{ {
// 从header获取token标识 // 从header获取token标识
String token = request.getHeader(SecurityConstants.AUTHORIZATION_HEADER); String token = request.getHeader(TokenConstants.AUTHENTICATION);
return replaceTokenPrefix(token); return replaceTokenPrefix(token);
} }

View File

@ -0,0 +1,6 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.security.config.WebMvcConfig,\
com.ruoyi.common.security.service.TokenService,\
com.ruoyi.common.security.aspect.PreAuthorizeAspect,\
com.ruoyi.common.security.aspect.InnerAuthAspect,\
com.ruoyi.common.security.handler.GlobalExceptionHandler

View File

@ -1,5 +0,0 @@
com.ruoyi.common.security.config.WebMvcConfig
com.ruoyi.common.security.service.TokenService
com.ruoyi.common.security.aspect.PreAuthorizeAspect
com.ruoyi.common.security.aspect.InnerAuthAspect
com.ruoyi.common.security.handler.GlobalExceptionHandler

Some files were not shown because too many files have changed in this diff Show More