commit
ce5ed356ee
1180 changed files with 134496 additions and 0 deletions
@ -0,0 +1,18 @@
|
||||
# http://editorconfig.org |
||||
root = true |
||||
|
||||
# 空格替代Tab缩进在各种编辑工具下效果一致 |
||||
[*] |
||||
indent_style = space |
||||
indent_size = 4 |
||||
charset = utf-8 |
||||
end_of_line = lf |
||||
trim_trailing_whitespace = true |
||||
insert_final_newline = true |
||||
|
||||
[*.{json,yml,yaml}] |
||||
indent_size = 2 |
||||
|
||||
[*.md] |
||||
insert_final_newline = false |
||||
trim_trailing_whitespace = false |
@ -0,0 +1,46 @@
|
||||
###################################################################### |
||||
# Build Tools |
||||
|
||||
.gradle |
||||
/build/ |
||||
!gradle/wrapper/gradle-wrapper.jar |
||||
|
||||
target/ |
||||
!.mvn/wrapper/maven-wrapper.jar |
||||
|
||||
###################################################################### |
||||
# IDE |
||||
|
||||
### STS ### |
||||
.apt_generated |
||||
.classpath |
||||
.factorypath |
||||
.project |
||||
.settings |
||||
.springBeans |
||||
|
||||
### IntelliJ IDEA ### |
||||
.idea |
||||
*.iws |
||||
*.iml |
||||
*.ipr |
||||
|
||||
### JRebel ### |
||||
rebel.xml |
||||
|
||||
### NetBeans ### |
||||
nbproject/private/ |
||||
build/* |
||||
nbbuild/ |
||||
nbdist/ |
||||
.nb-gradle/ |
||||
|
||||
###################################################################### |
||||
# Others |
||||
*.log |
||||
*.xml.versionsBackup |
||||
*.swp |
||||
|
||||
!*/build/*.java |
||||
!*/build/*.html |
||||
!*/build/*.xml |
@ -0,0 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager"> |
||||
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
||||
<deployment type="dockerfile"> |
||||
<settings> |
||||
<option name="imageTag" value="ruoyi/ruoyi-server:0.8.3" /> |
||||
<option name="buildOnly" value="true" /> |
||||
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> |
||||
</settings> |
||||
</deployment> |
||||
<method v="2" /> |
||||
</configuration> |
||||
</component> |
@ -0,0 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager"> |
||||
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
||||
<deployment type="dockerfile"> |
||||
<settings> |
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:0.8.3" /> |
||||
<option name="buildOnly" value="true" /> |
||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" /> |
||||
</settings> |
||||
</deployment> |
||||
<method v="2" /> |
||||
</configuration> |
||||
</component> |
@ -0,0 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager"> |
||||
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
||||
<deployment type="dockerfile"> |
||||
<settings> |
||||
<option name="imageTag" value="ruoyi/ruoyi-server:0.8.3" /> |
||||
<option name="buildOnly" value="true" /> |
||||
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> |
||||
</settings> |
||||
</deployment> |
||||
<method v="2" /> |
||||
</configuration> |
||||
</component> |
@ -0,0 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager"> |
||||
<configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
||||
<deployment type="dockerfile"> |
||||
<settings> |
||||
<option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:0.8.3" /> |
||||
<option name="buildOnly" value="true" /> |
||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" /> |
||||
</settings> |
||||
</deployment> |
||||
<method v="2" /> |
||||
</configuration> |
||||
</component> |
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 2021 RuoYi-Flowable-Plus |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||
this software and associated documentation files (the "Software"), to deal in |
||||
the Software without restriction, including without limitation the rights to |
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
||||
the Software, and to permit persons to whom the Software is furnished to do so, |
||||
subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,461 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-flowable-plus</artifactId> |
||||
<version>0.8.3</version> |
||||
|
||||
<name>RuoYi-Flowable-Plus</name> |
||||
<url>https://gitee.com/KonBAI-Q/ruoyi-flowable-plus</url> |
||||
<description>RuoYi-Flowable-Plus后台管理系统</description> |
||||
|
||||
<properties> |
||||
<ruoyi-flowable-plus.version>0.8.3</ruoyi-flowable-plus.version> |
||||
<spring-boot.version>2.7.11</spring-boot.version> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> |
||||
<java.version>1.8</java.version> |
||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version> |
||||
<spring-boot.mybatis>2.2.2</spring-boot.mybatis> |
||||
<springdoc.version>1.6.15</springdoc.version> |
||||
<poi.version>5.2.3</poi.version> |
||||
<easyexcel.version>3.2.1</easyexcel.version> |
||||
<velocity.version>2.3</velocity.version> |
||||
<satoken.version>1.34.0</satoken.version> |
||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version> |
||||
<p6spy.version>3.9.1</p6spy.version> |
||||
<hutool.version>5.8.18</hutool.version> |
||||
<okhttp.version>4.10.0</okhttp.version> |
||||
<spring-boot-admin.version>2.7.10</spring-boot-admin.version> |
||||
<redisson.version>3.20.1</redisson.version> |
||||
<lock4j.version>2.2.3</lock4j.version> |
||||
<dynamic-ds.version>3.5.2</dynamic-ds.version> |
||||
<alibaba-ttl.version>2.14.2</alibaba-ttl.version> |
||||
<xxl-job.version>2.4.0</xxl-job.version> |
||||
<lombok.version>1.18.26</lombok.version> |
||||
<bouncycastle.version>1.72</bouncycastle.version> |
||||
<flowable.version>6.8.0</flowable.version> |
||||
<!-- 离线IP地址定位库 --> |
||||
<ip2region.version>2.7.0</ip2region.version> |
||||
|
||||
<!-- 临时修复 snakeyaml 漏洞 --> |
||||
<snakeyaml.version>1.33</snakeyaml.version> |
||||
|
||||
<!-- OSS 配置 --> |
||||
<aws-java-sdk-s3.version>1.12.400</aws-java-sdk-s3.version> |
||||
<!-- SMS 配置 --> |
||||
<aliyun.sms.version>2.0.23</aliyun.sms.version> |
||||
<tencent.sms.version>3.1.687</tencent.sms.version> |
||||
</properties> |
||||
|
||||
<profiles> |
||||
<profile> |
||||
<id>local</id> |
||||
<properties> |
||||
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||
<profiles.active>local</profiles.active> |
||||
<logging.level>debug</logging.level> |
||||
</properties> |
||||
</profile> |
||||
<profile> |
||||
<id>dev</id> |
||||
<properties> |
||||
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||
<profiles.active>dev</profiles.active> |
||||
<logging.level>debug</logging.level> |
||||
</properties> |
||||
<activation> |
||||
<!-- 默认环境 --> |
||||
<activeByDefault>true</activeByDefault> |
||||
</activation> |
||||
</profile> |
||||
<profile> |
||||
<id>prod</id> |
||||
<properties> |
||||
<profiles.active>prod</profiles.active> |
||||
<logging.level>warn</logging.level> |
||||
</properties> |
||||
</profile> |
||||
</profiles> |
||||
|
||||
<!-- 依赖声明 --> |
||||
<dependencyManagement> |
||||
<dependencies> |
||||
|
||||
<!-- SpringBoot的依赖配置--> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-dependencies</artifactId> |
||||
<version>${spring-boot.version}</version> |
||||
<type>pom</type> |
||||
<scope>import</scope> |
||||
</dependency> |
||||
|
||||
<!-- hutool 的依赖配置--> |
||||
<dependency> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-bom</artifactId> |
||||
<version>${hutool.version}</version> |
||||
<type>pom</type> |
||||
<scope>import</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springdoc</groupId> |
||||
<artifactId>springdoc-openapi-webmvc-core</artifactId> |
||||
<version>${springdoc.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springdoc</groupId> |
||||
<artifactId>springdoc-openapi-javadoc</artifactId> |
||||
<version>${springdoc.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.projectlombok</groupId> |
||||
<artifactId>lombok</artifactId> |
||||
<version>${lombok.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.poi</groupId> |
||||
<artifactId>poi</artifactId> |
||||
<version>${poi.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.poi</groupId> |
||||
<artifactId>poi-ooxml</artifactId> |
||||
<version>${poi.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>easyexcel</artifactId> |
||||
<version>${easyexcel.version}</version> |
||||
<exclusions> |
||||
<exclusion> |
||||
<groupId>org.apache.poi</groupId> |
||||
<artifactId>poi-ooxml-schemas</artifactId> |
||||
</exclusion> |
||||
</exclusions> |
||||
</dependency> |
||||
|
||||
<!-- velocity代码生成使用模板 --> |
||||
<dependency> |
||||
<groupId>org.apache.velocity</groupId> |
||||
<artifactId>velocity-engine-core</artifactId> |
||||
<version>${velocity.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ --> |
||||
<dependency> |
||||
<groupId>cn.dev33</groupId> |
||||
<artifactId>sa-token-spring-boot-starter</artifactId> |
||||
<version>${satoken.version}</version> |
||||
</dependency> |
||||
<!-- Sa-Token 整合 jwt --> |
||||
<dependency> |
||||
<groupId>cn.dev33</groupId> |
||||
<artifactId>sa-token-jwt</artifactId> |
||||
<version>${satoken.version}</version> |
||||
<exclusions> |
||||
<exclusion> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-all</artifactId> |
||||
</exclusion> |
||||
</exclusions> |
||||
</dependency> |
||||
|
||||
<!-- dynamic-datasource 多数据源--> |
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId> |
||||
<version>${dynamic-ds.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
<version>${mybatis-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- sql性能分析插件 --> |
||||
<dependency> |
||||
<groupId>p6spy</groupId> |
||||
<artifactId>p6spy</artifactId> |
||||
<version>${p6spy.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.squareup.okhttp3</groupId> |
||||
<artifactId>okhttp</artifactId> |
||||
<version>${okhttp.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.amazonaws</groupId> |
||||
<artifactId>aws-java-sdk-s3</artifactId> |
||||
<version>${aws-java-sdk-s3.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.aliyun</groupId> |
||||
<artifactId>dysmsapi20170525</artifactId> |
||||
<version>${aliyun.sms.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.tencentcloudapi</groupId> |
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId> |
||||
<version>${tencent.sms.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>de.codecentric</groupId> |
||||
<artifactId>spring-boot-admin-starter-server</artifactId> |
||||
<version>${spring-boot-admin.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>de.codecentric</groupId> |
||||
<artifactId>spring-boot-admin-starter-client</artifactId> |
||||
<version>${spring-boot-admin.version}</version> |
||||
</dependency> |
||||
|
||||
<!--redisson--> |
||||
<dependency> |
||||
<groupId>org.redisson</groupId> |
||||
<artifactId>redisson-spring-boot-starter</artifactId> |
||||
<version>${redisson.version}</version> |
||||
<exclusions> |
||||
<exclusion> |
||||
<groupId>org.redisson</groupId> |
||||
<artifactId>redisson-spring-data-30</artifactId> |
||||
</exclusion> |
||||
</exclusions> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.redisson</groupId> |
||||
<artifactId>redisson-spring-data-27</artifactId> |
||||
<version>${redisson.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId> |
||||
<version>${lock4j.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- xxl-job-core --> |
||||
<dependency> |
||||
<groupId>com.xuxueli</groupId> |
||||
<artifactId>xxl-job-core</artifactId> |
||||
<version>${xxl-job.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>transmittable-thread-local</artifactId> |
||||
<version>${alibaba-ttl.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 离线IP地址定位库 ip2region --> |
||||
<dependency> |
||||
<groupId>org.lionsoul</groupId> |
||||
<artifactId>ip2region</artifactId> |
||||
<version>${ip2region.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 临时修复 snakeyaml 漏洞 --> |
||||
<dependency> |
||||
<groupId>org.yaml</groupId> |
||||
<artifactId>snakeyaml</artifactId> |
||||
<version>${snakeyaml.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 加密包引入 --> |
||||
<dependency> |
||||
<groupId>org.bouncycastle</groupId> |
||||
<artifactId>bcprov-jdk15to18</artifactId> |
||||
<version>${bouncycastle.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- flowable --> |
||||
<dependency> |
||||
<groupId>org.flowable</groupId> |
||||
<artifactId>flowable-spring-boot-starter-process</artifactId> |
||||
<version>${flowable.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 定时任务 --> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-job</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 代码生成--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-generator</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 核心模块--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-framework</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 系统模块--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-system</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 通用工具--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-common</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- 工作流模块 --> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-flowable</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- OSS对象存储模块 --> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-oss</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- SMS短信模块 --> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-sms</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
<!-- demo模块 --> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-demo</artifactId> |
||||
<version>${ruoyi-flowable-plus.version}</version> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
</dependencyManagement> |
||||
|
||||
<modules> |
||||
<module>ruoyi-admin</module> |
||||
<module>ruoyi-common</module> |
||||
<module>ruoyi-demo</module> |
||||
<module>ruoyi-extend</module> |
||||
<module>ruoyi-flowable</module> |
||||
<module>ruoyi-framework</module> |
||||
<module>ruoyi-generator</module> |
||||
<module>ruoyi-job</module> |
||||
<module>ruoyi-oss</module> |
||||
<module>ruoyi-sms</module> |
||||
<module>ruoyi-system</module> |
||||
</modules> |
||||
<packaging>pom</packaging> |
||||
|
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-compiler-plugin</artifactId> |
||||
<version>3.9.0</version> |
||||
<configuration> |
||||
<source>${java.version}</source> |
||||
<target>${java.version}</target> |
||||
<encoding>${project.build.sourceEncoding}</encoding> |
||||
<annotationProcessorPaths> |
||||
<path> |
||||
<groupId>com.github.therapi</groupId> |
||||
<artifactId>therapi-runtime-javadoc-scribe</artifactId> |
||||
<version>0.15.0</version> |
||||
</path> |
||||
<path> |
||||
<groupId>org.projectlombok</groupId> |
||||
<artifactId>lombok</artifactId> |
||||
<version>${lombok.version}</version> |
||||
</path> |
||||
<path> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-configuration-processor</artifactId> |
||||
<version>${spring-boot.version}</version> |
||||
</path> |
||||
</annotationProcessorPaths> |
||||
</configuration> |
||||
</plugin> |
||||
<!-- 单元测试使用 --> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-surefire-plugin</artifactId> |
||||
<version>2.22.2</version> |
||||
<configuration> |
||||
<argLine>-Dfile.encoding=UTF-8</argLine> |
||||
<!-- 根据打包环境执行对应的@Tag测试方法 --> |
||||
<groups>${profiles.active}</groups> |
||||
<!-- 排除标签 --> |
||||
<excludedGroups>exclude</excludedGroups> |
||||
</configuration> |
||||
</plugin> |
||||
</plugins> |
||||
<resources> |
||||
<resource> |
||||
<directory>src/main/resources</directory> |
||||
<!-- 关闭过滤 --> |
||||
<filtering>false</filtering> |
||||
</resource> |
||||
<resource> |
||||
<directory>src/main/resources</directory> |
||||
<!-- 引入所有 匹配文件进行过滤 --> |
||||
<includes> |
||||
<include>application*</include> |
||||
<include>bootstrap*</include> |
||||
<include>banner*</include> |
||||
</includes> |
||||
<!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 --> |
||||
<filtering>true</filtering> |
||||
</resource> |
||||
</resources> |
||||
</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> |
@ -0,0 +1,23 @@
|
||||
FROM anapsix/alpine-java:8_server-jre_unlimited |
||||
|
||||
MAINTAINER Lion Li |
||||
|
||||
RUN mkdir -p /ruoyi/server/logs \ |
||||
/ruoyi/server/temp \ |
||||
/ruoyi/skywalking/agent |
||||
|
||||
WORKDIR /ruoyi/server |
||||
|
||||
ENV SERVER_PORT=8080 |
||||
|
||||
EXPOSE ${SERVER_PORT} |
||||
|
||||
ADD ./target/ruoyi-admin.jar ./app.jar |
||||
|
||||
ENTRYPOINT ["java", \ |
||||
"-Djava.security.egd=file:/dev/./urandom", \ |
||||
"-Dserver.port=${SERVER_PORT}", \ |
||||
# 应用名称 如果想区分集群节点监控 改成不同的名称即可 |
||||
# "-Dskywalking.agent.service_name=ruoyi-server", \ |
||||
# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ |
||||
"-jar", "app.jar"] |
@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<parent> |
||||
<artifactId>ruoyi-flowable-plus</artifactId> |
||||
<groupId>com.ruoyi</groupId> |
||||
<version>0.8.3</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<packaging>jar</packaging> |
||||
<artifactId>ruoyi-admin</artifactId> |
||||
|
||||
<description> |
||||
web服务入口 |
||||
</description> |
||||
|
||||
<dependencies> |
||||
|
||||
<!-- spring-boot-devtools --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-devtools</artifactId> |
||||
<optional>true</optional> <!-- 表示依赖不会传递 --> |
||||
</dependency> |
||||
|
||||
<!-- Mysql驱动包 --> |
||||
<dependency> |
||||
<groupId>com.mysql</groupId> |
||||
<artifactId>mysql-connector-j</artifactId> |
||||
</dependency> |
||||
<!-- Oracle --> |
||||
<dependency> |
||||
<groupId>com.oracle.database.jdbc</groupId> |
||||
<artifactId>ojdbc8</artifactId> |
||||
</dependency> |
||||
<!-- PostgreSql --> |
||||
<dependency> |
||||
<groupId>org.postgresql</groupId> |
||||
<artifactId>postgresql</artifactId> |
||||
</dependency> |
||||
<!-- SqlServer --> |
||||
<dependency> |
||||
<groupId>com.microsoft.sqlserver</groupId> |
||||
<artifactId>mssql-jdbc</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- 核心模块--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-framework</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-system</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-job</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-oss</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- 代码生成--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-generator</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- demo模块 --> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-demo</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- flowable模块--> |
||||
<dependency> |
||||
<groupId>com.ruoyi</groupId> |
||||
<artifactId>ruoyi-flowable</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-test</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<!-- skywalking 整合 logback --> |
||||
<!-- <dependency>--> |
||||
<!-- <groupId>org.apache.skywalking</groupId>--> |
||||
<!-- <artifactId>apm-toolkit-logback-1.x</artifactId>--> |
||||
<!-- <version>${与你的agent探针版本保持一致}</version>--> |
||||
<!-- </dependency>--> |
||||
<!-- <dependency>--> |
||||
<!-- <groupId>org.apache.skywalking</groupId>--> |
||||
<!-- <artifactId>apm-toolkit-trace</artifactId>--> |
||||
<!-- <version>${与你的agent探针版本保持一致}</version>--> |
||||
<!-- </dependency>--> |
||||
|
||||
</dependencies> |
||||
|
||||
<build> |
||||
<finalName>${project.artifactId}</finalName> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-maven-plugin</artifactId> |
||||
<version>${spring-boot.version}</version> |
||||
<configuration> |
||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> |
||||
</configuration> |
||||
<executions> |
||||
<execution> |
||||
<goals> |
||||
<goal>repackage</goal> |
||||
</goals> |
||||
</execution> |
||||
</executions> |
||||
</plugin> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-war-plugin</artifactId> |
||||
<version>3.2.2</version> |
||||
<configuration> |
||||
<failOnMissingWebXml>false</failOnMissingWebXml> |
||||
<warName>${project.artifactId}</warName> |
||||
</configuration> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
|
||||
</project> |
@ -0,0 +1,24 @@
|
||||
package com.ruoyi; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; |
||||
|
||||
/** |
||||
* 启动程序 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
|
||||
@SpringBootApplication |
||||
public class RuoYiApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
System.setProperty("spring.devtools.restart.enabled", "false"); |
||||
SpringApplication application = new SpringApplication(RuoYiApplication.class); |
||||
application.setApplicationStartup(new BufferingApplicationStartup(2048)); |
||||
application.run(args); |
||||
System.out.println("(♥◠‿◠)ノ゙ RuoYi-Flowable-Plus启动成功 ლ(´ڡ`ლ)゙"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,18 @@
|
||||
package com.ruoyi; |
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
||||
|
||||
/** |
||||
* web容器中进行部署 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
public class RuoYiServletInitializer extends SpringBootServletInitializer { |
||||
|
||||
@Override |
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { |
||||
return application.sources(RuoYiApplication.class); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.ruoyi.config; |
||||
|
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry; |
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||
|
||||
import javax.servlet.*; |
||||
import javax.servlet.annotation.WebFilter; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project ruoyi-flowable-plus |
||||
* @description 跨域处理 |
||||
* @date 2024-04-24 17:56:58 |
||||
*/ |
||||
@Configuration |
||||
public class CorsConfig implements WebMvcConfigurer { |
||||
|
||||
@Override |
||||
public void addCorsMappings(CorsRegistry registry) { |
||||
registry.addMapping("/**") |
||||
.allowedOrigins("*") // 替换为前端应用的实际域名
|
||||
.allowedMethods("*") |
||||
.allowedHeaders("*"); |
||||
} |
||||
} |
@ -0,0 +1,138 @@
|
||||
package com.ruoyi.web.controller.common; |
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore; |
||||
import cn.hutool.captcha.AbstractCaptcha; |
||||
import cn.hutool.captcha.generator.CodeGenerator; |
||||
import cn.hutool.core.util.IdUtil; |
||||
import cn.hutool.core.util.RandomUtil; |
||||
import com.ruoyi.common.constant.CacheConstants; |
||||
import com.ruoyi.common.constant.Constants; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.enums.CaptchaType; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.email.MailUtils; |
||||
import com.ruoyi.common.utils.redis.RedisUtils; |
||||
import com.ruoyi.common.utils.reflect.ReflectUtils; |
||||
import com.ruoyi.common.utils.spring.SpringUtils; |
||||
import com.ruoyi.framework.config.properties.CaptchaProperties; |
||||
import com.ruoyi.framework.config.properties.MailProperties; |
||||
import com.ruoyi.sms.config.properties.SmsProperties; |
||||
import com.ruoyi.sms.core.SmsTemplate; |
||||
import com.ruoyi.sms.entity.SmsResult; |
||||
import com.ruoyi.system.service.ISysConfigService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.expression.Expression; |
||||
import org.springframework.expression.ExpressionParser; |
||||
import org.springframework.expression.spel.standard.SpelExpressionParser; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.CrossOrigin; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
import java.time.Duration; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 验证码操作处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@SaIgnore |
||||
@Slf4j |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@CrossOrigin |
||||
public class CaptchaController { |
||||
|
||||
private final CaptchaProperties captchaProperties; |
||||
private final SmsProperties smsProperties; |
||||
private final ISysConfigService configService; |
||||
private final MailProperties mailProperties; |
||||
|
||||
/** |
||||
* 短信验证码 |
||||
* |
||||
* @param phonenumber 用户手机号 |
||||
*/ |
||||
@GetMapping("/captchaSms") |
||||
public R<Void> smsCaptcha(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) { |
||||
if (!smsProperties.getEnabled()) { |
||||
return R.fail("当前系统没有开启短信功能!"); |
||||
} |
||||
String key = CacheConstants.CAPTCHA_CODE_KEY + phonenumber; |
||||
String code = RandomUtil.randomNumbers(4); |
||||
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); |
||||
// 验证码模板id 自行处理 (查数据库或写死均可)
|
||||
String templateId = ""; |
||||
Map<String, String> map = new HashMap<>(1); |
||||
map.put("code", code); |
||||
SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); |
||||
SmsResult result = smsTemplate.send(phonenumber, templateId, map); |
||||
if (!result.isSuccess()) { |
||||
log.error("验证码短信发送异常 => {}", result); |
||||
return R.fail(result.getMessage()); |
||||
} |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 邮箱验证码 |
||||
* |
||||
* @param email 邮箱 |
||||
*/ |
||||
@GetMapping("/captchaEmail") |
||||
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) { |
||||
if (!mailProperties.getEnabled()) { |
||||
return R.fail("当前系统没有开启邮箱功能!"); |
||||
} |
||||
String key = CacheConstants.CAPTCHA_CODE_KEY + email; |
||||
String code = RandomUtil.randomNumbers(4); |
||||
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); |
||||
try { |
||||
MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。"); |
||||
} catch (Exception e) { |
||||
log.error("验证码短信发送异常 => {}", e.getMessage()); |
||||
return R.fail(e.getMessage()); |
||||
} |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 生成验证码 |
||||
*/ |
||||
@GetMapping("/captchaImage") |
||||
public R<Map<String, Object>> getCode() { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
boolean captchaEnabled = configService.selectCaptchaEnabled(); |
||||
ajax.put("captchaEnabled", captchaEnabled); |
||||
if (!captchaEnabled) { |
||||
return R.ok(ajax); |
||||
} |
||||
// 保存验证码信息
|
||||
String uuid = IdUtil.simpleUUID(); |
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; |
||||
// 生成验证码
|
||||
CaptchaType captchaType = captchaProperties.getType(); |
||||
boolean isMath = CaptchaType.MATH == captchaType; |
||||
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength(); |
||||
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length); |
||||
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz()); |
||||
captcha.setGenerator(codeGenerator); |
||||
captcha.createCode(); |
||||
String code = captcha.getCode(); |
||||
if (isMath) { |
||||
ExpressionParser parser = new SpelExpressionParser(); |
||||
Expression exp = parser.parseExpression(StringUtils.remove(code, "=")); |
||||
code = exp.getValue(String.class); |
||||
} |
||||
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); |
||||
ajax.put("uuid", uuid); |
||||
ajax.put("img", captcha.getImageBase64()); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,168 @@
|
||||
package com.ruoyi.web.controller.monitor; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import com.ruoyi.common.constant.CacheConstants; |
||||
import com.ruoyi.common.constant.CacheNames; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.utils.JsonUtils; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.redis.CacheUtils; |
||||
import com.ruoyi.common.utils.redis.RedisUtils; |
||||
import com.ruoyi.system.domain.SysCache; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.redisson.spring.data.connection.RedissonConnectionFactory; |
||||
import org.springframework.data.redis.connection.RedisConnection; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 缓存监控 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/monitor/cache") |
||||
public class CacheController { |
||||
|
||||
private final RedissonConnectionFactory connectionFactory; |
||||
|
||||
private final static List<SysCache> CACHES = new ArrayList<>(); |
||||
|
||||
static { |
||||
CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "在线用户")); |
||||
CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息")); |
||||
CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典")); |
||||
CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); |
||||
CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); |
||||
CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); |
||||
CACHES.add(new SysCache(CacheNames.SYS_OSS_CONFIG, "OSS配置")); |
||||
CACHES.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); |
||||
} |
||||
|
||||
/** |
||||
* 获取缓存监控列表 |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@GetMapping() |
||||
public R<Map<String, Object>> getInfo() throws Exception { |
||||
RedisConnection connection = connectionFactory.getConnection(); |
||||
Properties info = connection.info(); |
||||
Properties commandStats = connection.info("commandstats"); |
||||
Long dbSize = connection.dbSize(); |
||||
|
||||
Map<String, Object> result = new HashMap<>(3); |
||||
result.put("info", info); |
||||
result.put("dbSize", dbSize); |
||||
|
||||
List<Map<String, String>> pieList = new ArrayList<>(); |
||||
if (commandStats != null) { |
||||
commandStats.stringPropertyNames().forEach(key -> { |
||||
Map<String, String> data = new HashMap<>(2); |
||||
String property = commandStats.getProperty(key); |
||||
data.put("name", StringUtils.removeStart(key, "cmdstat_")); |
||||
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); |
||||
pieList.add(data); |
||||
}); |
||||
} |
||||
result.put("commandStats", pieList); |
||||
return R.ok(result); |
||||
} |
||||
|
||||
/** |
||||
* 获取缓存监控缓存名列表 |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@GetMapping("/getNames") |
||||
public R<List<SysCache>> cache() { |
||||
return R.ok(CACHES); |
||||
} |
||||
|
||||
/** |
||||
* 获取缓存监控Key列表 |
||||
* |
||||
* @param cacheName 缓存名 |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@GetMapping("/getKeys/{cacheName}") |
||||
public R<Collection<String>> getCacheKeys(@PathVariable String cacheName) { |
||||
Collection<String> cacheKeys = new HashSet<>(0); |
||||
if (isCacheNames(cacheName)) { |
||||
Set<Object> keys = CacheUtils.keys(cacheName); |
||||
if (CollUtil.isNotEmpty(keys)) { |
||||
cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList()); |
||||
} |
||||
} else { |
||||
cacheKeys = RedisUtils.keys(cacheName + "*"); |
||||
} |
||||
return R.ok(cacheKeys); |
||||
} |
||||
|
||||
/** |
||||
* 获取缓存监控缓存值详情 |
||||
* |
||||
* @param cacheName 缓存名 |
||||
* @param cacheKey 缓存key |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@GetMapping("/getValue/{cacheName}/{cacheKey}") |
||||
public R<SysCache> getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) { |
||||
Object cacheValue; |
||||
if (isCacheNames(cacheName)) { |
||||
cacheValue = CacheUtils.get(cacheName, cacheKey); |
||||
} else { |
||||
cacheValue = RedisUtils.getCacheObject(cacheKey); |
||||
} |
||||
SysCache sysCache = new SysCache(cacheName, cacheKey, JsonUtils.toJsonString(cacheValue)); |
||||
return R.ok(sysCache); |
||||
} |
||||
|
||||
/** |
||||
* 清理缓存监控缓存名 |
||||
* |
||||
* @param cacheName 缓存名 |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@DeleteMapping("/clearCacheName/{cacheName}") |
||||
public R<Void> clearCacheName(@PathVariable String cacheName) { |
||||
if (isCacheNames(cacheName)) { |
||||
CacheUtils.clear(cacheName); |
||||
} else { |
||||
RedisUtils.deleteKeys(cacheName + "*"); |
||||
} |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 清理缓存监控Key |
||||
* |
||||
* @param cacheKey key名 |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@DeleteMapping("/clearCacheKey/{cacheName}/{cacheKey}") |
||||
public R<Void> clearCacheKey(@PathVariable String cacheName, @PathVariable String cacheKey) { |
||||
if (isCacheNames(cacheName)) { |
||||
CacheUtils.evict(cacheName, cacheKey); |
||||
} else { |
||||
RedisUtils.deleteObject(cacheKey); |
||||
} |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 清理全部缓存监控 |
||||
*/ |
||||
@SaCheckPermission("monitor:cache:list") |
||||
@DeleteMapping("/clearCacheAll") |
||||
public R<Void> clearCacheAll() { |
||||
RedisUtils.deleteKeys("*"); |
||||
return R.ok(); |
||||
} |
||||
|
||||
private boolean isCacheNames(String cacheName) { |
||||
return !StringUtils.contains(cacheName, ":"); |
||||
} |
||||
} |
@ -0,0 +1,88 @@
|
||||
package com.ruoyi.web.controller.monitor; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.CacheConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.common.utils.redis.RedisUtils; |
||||
import com.ruoyi.system.domain.SysLogininfor; |
||||
import com.ruoyi.system.service.ISysLogininforService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 系统访问记录 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/monitor/logininfor") |
||||
public class SysLogininforController extends BaseController { |
||||
|
||||
private final ISysLogininforService logininforService; |
||||
|
||||
/** |
||||
* 获取系统访问记录列表 |
||||
*/ |
||||
@SaCheckPermission("monitor:logininfor:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysLogininfor> list(SysLogininfor logininfor, PageQuery pageQuery) { |
||||
return logininforService.selectPageLogininforList(logininfor, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出系统访问记录列表 |
||||
*/ |
||||
@Log(title = "登录日志", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("monitor:logininfor:export") |
||||
@PostMapping("/export") |
||||
public void export(SysLogininfor logininfor, HttpServletResponse response) { |
||||
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); |
||||
ExcelUtil.exportExcel(list, "登录日志", SysLogininfor.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 批量删除登录日志 |
||||
* @param infoIds 日志ids |
||||
*/ |
||||
@SaCheckPermission("monitor:logininfor:remove") |
||||
@Log(title = "登录日志", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{infoIds}") |
||||
public R<Void> remove(@PathVariable Long[] infoIds) { |
||||
return toAjax(logininforService.deleteLogininforByIds(infoIds)); |
||||
} |
||||
|
||||
/** |
||||
* 清理系统访问记录 |
||||
*/ |
||||
@SaCheckPermission("monitor:logininfor:remove") |
||||
@Log(title = "登录日志", businessType = BusinessType.CLEAN) |
||||
@DeleteMapping("/clean") |
||||
public R<Void> clean() { |
||||
logininforService.cleanLogininfor(); |
||||
return R.ok(); |
||||
} |
||||
|
||||
@SaCheckPermission("monitor:logininfor:unlock") |
||||
@Log(title = "账户解锁", businessType = BusinessType.OTHER) |
||||
@GetMapping("/unlock/{userName}") |
||||
public R<Void> unlock(@PathVariable("userName") String userName) { |
||||
String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; |
||||
if (RedisUtils.hasKey(loginName)) { |
||||
RedisUtils.deleteObject(loginName); |
||||
} |
||||
return R.ok(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,74 @@
|
||||
package com.ruoyi.web.controller.monitor; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.domain.SysOperLog; |
||||
import com.ruoyi.system.service.ISysOperLogService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 操作日志记录 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/monitor/operlog") |
||||
public class SysOperlogController extends BaseController { |
||||
|
||||
private final ISysOperLogService operLogService; |
||||
|
||||
/** |
||||
* 获取操作日志记录列表 |
||||
*/ |
||||
@SaCheckPermission("monitor:operlog:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysOperLog> list(SysOperLog operLog, PageQuery pageQuery) { |
||||
return operLogService.selectPageOperLogList(operLog, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出操作日志记录列表 |
||||
*/ |
||||
@Log(title = "操作日志", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("monitor:operlog:export") |
||||
@PostMapping("/export") |
||||
public void export(SysOperLog operLog, HttpServletResponse response) { |
||||
List<SysOperLog> list = operLogService.selectOperLogList(operLog); |
||||
ExcelUtil.exportExcel(list, "操作日志", SysOperLog.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 批量删除操作日志记录 |
||||
* @param operIds 日志ids |
||||
*/ |
||||
@Log(title = "操作日志", businessType = BusinessType.DELETE) |
||||
@SaCheckPermission("monitor:operlog:remove") |
||||
@DeleteMapping("/{operIds}") |
||||
public R<Void> remove(@PathVariable Long[] operIds) { |
||||
return toAjax(operLogService.deleteOperLogByIds(operIds)); |
||||
} |
||||
|
||||
/** |
||||
* 清理操作日志记录 |
||||
*/ |
||||
@Log(title = "操作日志", businessType = BusinessType.CLEAN) |
||||
@SaCheckPermission("monitor:operlog:remove") |
||||
@DeleteMapping("/clean") |
||||
public R<Void> clean() { |
||||
operLogService.cleanOperLog(); |
||||
return R.ok(); |
||||
} |
||||
} |
@ -0,0 +1,90 @@
|
||||
package com.ruoyi.web.controller.monitor; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.dev33.satoken.exception.NotLoginException; |
||||
import cn.dev33.satoken.stp.StpUtil; |
||||
import cn.hutool.core.bean.BeanUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.CacheConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.dto.UserOnlineDTO; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.StreamUtils; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.redis.RedisUtils; |
||||
import com.ruoyi.system.domain.SysUserOnline; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 在线用户监控 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/monitor/online") |
||||
public class SysUserOnlineController extends BaseController { |
||||
|
||||
/** |
||||
* 获取在线用户监控列表 |
||||
* |
||||
* @param ipaddr IP地址 |
||||
* @param userName 用户名 |
||||
*/ |
||||
@SaCheckPermission("monitor:online:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) { |
||||
// 获取所有未过期的 token
|
||||
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false); |
||||
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>(); |
||||
for (String key : keys) { |
||||
String token = StringUtils.substringAfterLast(key, ":"); |
||||
// 如果已经过期则跳过
|
||||
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) { |
||||
continue; |
||||
} |
||||
userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token)); |
||||
} |
||||
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { |
||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
||||
StringUtils.equals(ipaddr, userOnline.getIpaddr()) && |
||||
StringUtils.equals(userName, userOnline.getUserName()) |
||||
); |
||||
} else if (StringUtils.isNotEmpty(ipaddr)) { |
||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
||||
StringUtils.equals(ipaddr, userOnline.getIpaddr()) |
||||
); |
||||
} else if (StringUtils.isNotEmpty(userName)) { |
||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
||||
StringUtils.equals(userName, userOnline.getUserName()) |
||||
); |
||||
} |
||||
Collections.reverse(userOnlineDTOList); |
||||
userOnlineDTOList.removeAll(Collections.singleton(null)); |
||||
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class); |
||||
return TableDataInfo.build(userOnlineList); |
||||
} |
||||
|
||||
/** |
||||
* 强退用户 |
||||
* |
||||
* @param tokenId token值 |
||||
*/ |
||||
@SaCheckPermission("monitor:online:forceLogout") |
||||
@Log(title = "在线用户", businessType = BusinessType.FORCE) |
||||
@DeleteMapping("/{tokenId}") |
||||
public R<Void> forceLogout(@PathVariable String tokenId) { |
||||
try { |
||||
StpUtil.kickoutByTokenValue(tokenId); |
||||
} catch (NotLoginException ignored) { |
||||
} |
||||
return R.ok(); |
||||
} |
||||
} |
@ -0,0 +1,137 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.domain.SysConfig; |
||||
import com.ruoyi.system.service.ISysConfigService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 参数配置 信息操作处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/config") |
||||
public class SysConfigController extends BaseController { |
||||
|
||||
private final ISysConfigService configService; |
||||
|
||||
/** |
||||
* 获取参数配置列表 |
||||
*/ |
||||
@SaCheckPermission("system:config:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysConfig> list(SysConfig config, PageQuery pageQuery) { |
||||
return configService.selectPageConfigList(config, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出参数配置列表 |
||||
*/ |
||||
@Log(title = "参数管理", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("system:config:export") |
||||
@PostMapping("/export") |
||||
public void export(SysConfig config, HttpServletResponse response) { |
||||
List<SysConfig> list = configService.selectConfigList(config); |
||||
ExcelUtil.exportExcel(list, "参数数据", SysConfig.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 根据参数编号获取详细信息 |
||||
* |
||||
* @param configId 参数ID |
||||
*/ |
||||
@SaCheckPermission("system:config:query") |
||||
@GetMapping(value = "/{configId}") |
||||
public R<SysConfig> getInfo(@PathVariable Long configId) { |
||||
return R.ok(configService.selectConfigById(configId)); |
||||
} |
||||
|
||||
/** |
||||
* 根据参数键名查询参数值 |
||||
* |
||||
* @param configKey 参数Key |
||||
*/ |
||||
@GetMapping(value = "/configKey/{configKey}") |
||||
public R<Void> getConfigKey(@PathVariable String configKey) { |
||||
return R.ok(configService.selectConfigByKey(configKey)); |
||||
} |
||||
|
||||
/** |
||||
* 新增参数配置 |
||||
*/ |
||||
@SaCheckPermission("system:config:add") |
||||
@Log(title = "参数管理", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysConfig config) { |
||||
if (!configService.checkConfigKeyUnique(config)) { |
||||
return R.fail("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); |
||||
} |
||||
configService.insertConfig(config); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 修改参数配置 |
||||
*/ |
||||
@SaCheckPermission("system:config:edit") |
||||
@Log(title = "参数管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysConfig config) { |
||||
if (!configService.checkConfigKeyUnique(config)) { |
||||
return R.fail("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); |
||||
} |
||||
configService.updateConfig(config); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 根据参数键名修改参数配置 |
||||
*/ |
||||
@SaCheckPermission("system:config:edit") |
||||
@Log(title = "参数管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/updateByKey") |
||||
public R<Void> updateByKey(@RequestBody SysConfig config) { |
||||
configService.updateConfig(config); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 删除参数配置 |
||||
* |
||||
* @param configIds 参数ID串 |
||||
*/ |
||||
@SaCheckPermission("system:config:remove") |
||||
@Log(title = "参数管理", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{configIds}") |
||||
public R<Void> remove(@PathVariable Long[] configIds) { |
||||
configService.deleteConfigByIds(configIds); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 刷新参数缓存 |
||||
*/ |
||||
@SaCheckPermission("system:config:remove") |
||||
@Log(title = "参数管理", businessType = BusinessType.CLEAN) |
||||
@DeleteMapping("/refreshCache") |
||||
public R<Void> refreshCache() { |
||||
configService.resetConfigCache(); |
||||
return R.ok(); |
||||
} |
||||
} |
@ -0,0 +1,119 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.convert.Convert; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysDept; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.system.service.ISysDeptService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 部门信息 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/dept") |
||||
public class SysDeptController extends BaseController { |
||||
|
||||
private final ISysDeptService deptService; |
||||
|
||||
/** |
||||
* 获取部门列表 |
||||
*/ |
||||
@SaCheckPermission("system:dept:list") |
||||
@GetMapping("/list") |
||||
public R<List<SysDept>> list(SysDept dept) { |
||||
List<SysDept> depts = deptService.selectDeptList(dept); |
||||
return R.ok(depts); |
||||
} |
||||
|
||||
/** |
||||
* 查询部门列表(排除节点) |
||||
* |
||||
* @param deptId 部门ID |
||||
*/ |
||||
@SaCheckPermission("system:dept:list") |
||||
@GetMapping("/list/exclude/{deptId}") |
||||
public R<List<SysDept>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { |
||||
List<SysDept> depts = deptService.selectDeptList(new SysDept()); |
||||
depts.removeIf(d -> d.getDeptId().equals(deptId) |
||||
|| StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId))); |
||||
return R.ok(depts); |
||||
} |
||||
|
||||
/** |
||||
* 根据部门编号获取详细信息 |
||||
* |
||||
* @param deptId 部门ID |
||||
*/ |
||||
@SaCheckPermission("system:dept:query") |
||||
@GetMapping(value = "/{deptId}") |
||||
public R<SysDept> getInfo(@PathVariable Long deptId) { |
||||
deptService.checkDeptDataScope(deptId); |
||||
return R.ok(deptService.selectDeptById(deptId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增部门 |
||||
*/ |
||||
@SaCheckPermission("system:dept:add") |
||||
@Log(title = "部门管理", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysDept dept) { |
||||
if (!deptService.checkDeptNameUnique(dept)) { |
||||
return R.fail("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); |
||||
} |
||||
return toAjax(deptService.insertDept(dept)); |
||||
} |
||||
|
||||
/** |
||||
* 修改部门 |
||||
*/ |
||||
@SaCheckPermission("system:dept:edit") |
||||
@Log(title = "部门管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysDept dept) { |
||||
Long deptId = dept.getDeptId(); |
||||
deptService.checkDeptDataScope(deptId); |
||||
if (!deptService.checkDeptNameUnique(dept)) { |
||||
return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); |
||||
} else if (dept.getParentId().equals(deptId)) { |
||||
return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); |
||||
} else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) |
||||
&& deptService.selectNormalChildrenDeptById(deptId) > 0) { |
||||
return R.fail("该部门包含未停用的子部门!"); |
||||
} |
||||
return toAjax(deptService.updateDept(dept)); |
||||
} |
||||
|
||||
/** |
||||
* 删除部门 |
||||
* |
||||
* @param deptId 部门ID |
||||
*/ |
||||
@SaCheckPermission("system:dept:remove") |
||||
@Log(title = "部门管理", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{deptId}") |
||||
public R<Void> remove(@PathVariable Long deptId) { |
||||
if (deptService.hasChildByDeptId(deptId)) { |
||||
return R.warn("存在下级部门,不允许删除"); |
||||
} |
||||
if (deptService.checkDeptExistUser(deptId)) { |
||||
return R.warn("部门存在用户,不允许删除"); |
||||
} |
||||
deptService.checkDeptDataScope(deptId); |
||||
return toAjax(deptService.deleteDeptById(deptId)); |
||||
} |
||||
} |
@ -0,0 +1,116 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysDictData; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.service.ISysDictDataService; |
||||
import com.ruoyi.system.service.ISysDictTypeService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 数据字典信息 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/dict/data") |
||||
public class SysDictDataController extends BaseController { |
||||
|
||||
private final ISysDictDataService dictDataService; |
||||
private final ISysDictTypeService dictTypeService; |
||||
|
||||
/** |
||||
* 查询字典数据列表 |
||||
*/ |
||||
@SaCheckPermission("system:dict:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysDictData> list(SysDictData dictData, PageQuery pageQuery) { |
||||
return dictDataService.selectPageDictDataList(dictData, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出字典数据列表 |
||||
*/ |
||||
@Log(title = "字典数据", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("system:dict:export") |
||||
@PostMapping("/export") |
||||
public void export(SysDictData dictData, HttpServletResponse response) { |
||||
List<SysDictData> list = dictDataService.selectDictDataList(dictData); |
||||
ExcelUtil.exportExcel(list, "字典数据", SysDictData.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 查询字典数据详细 |
||||
* |
||||
* @param dictCode 字典code |
||||
*/ |
||||
@SaCheckPermission("system:dict:query") |
||||
@GetMapping(value = "/{dictCode}") |
||||
public R<SysDictData> getInfo(@PathVariable Long dictCode) { |
||||
return R.ok(dictDataService.selectDictDataById(dictCode)); |
||||
} |
||||
|
||||
/** |
||||
* 根据字典类型查询字典数据信息 |
||||
* |
||||
* @param dictType 字典类型 |
||||
*/ |
||||
@GetMapping(value = "/type/{dictType}") |
||||
public R<List<SysDictData>> dictType(@PathVariable String dictType) { |
||||
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); |
||||
if (ObjectUtil.isNull(data)) { |
||||
data = new ArrayList<>(); |
||||
} |
||||
return R.ok(data); |
||||
} |
||||
|
||||
/** |
||||
* 新增字典类型 |
||||
*/ |
||||
@SaCheckPermission("system:dict:add") |
||||
@Log(title = "字典数据", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysDictData dict) { |
||||
dictDataService.insertDictData(dict); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 修改保存字典类型 |
||||
*/ |
||||
@SaCheckPermission("system:dict:edit") |
||||
@Log(title = "字典数据", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysDictData dict) { |
||||
dictDataService.updateDictData(dict); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 删除字典类型 |
||||
* |
||||
* @param dictCodes 字典code串 |
||||
*/ |
||||
@SaCheckPermission("system:dict:remove") |
||||
@Log(title = "字典类型", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{dictCodes}") |
||||
public R<Void> remove(@PathVariable Long[] dictCodes) { |
||||
dictDataService.deleteDictDataByIds(dictCodes); |
||||
return R.ok(); |
||||
} |
||||
} |
@ -0,0 +1,125 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysDictType; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.service.ISysDictTypeService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 数据字典信息 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/dict/type") |
||||
public class SysDictTypeController extends BaseController { |
||||
|
||||
private final ISysDictTypeService dictTypeService; |
||||
|
||||
/** |
||||
* 查询字典类型列表 |
||||
*/ |
||||
@SaCheckPermission("system:dict:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysDictType> list(SysDictType dictType, PageQuery pageQuery) { |
||||
return dictTypeService.selectPageDictTypeList(dictType, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出字典类型列表 |
||||
*/ |
||||
@Log(title = "字典类型", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("system:dict:export") |
||||
@PostMapping("/export") |
||||
public void export(SysDictType dictType, HttpServletResponse response) { |
||||
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); |
||||
ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 查询字典类型详细 |
||||
* |
||||
* @param dictId 字典ID |
||||
*/ |
||||
@SaCheckPermission("system:dict:query") |
||||
@GetMapping(value = "/{dictId}") |
||||
public R<SysDictType> getInfo(@PathVariable Long dictId) { |
||||
return R.ok(dictTypeService.selectDictTypeById(dictId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增字典类型 |
||||
*/ |
||||
@SaCheckPermission("system:dict:add") |
||||
@Log(title = "字典类型", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysDictType dict) { |
||||
if (!dictTypeService.checkDictTypeUnique(dict)) { |
||||
return R.fail("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); |
||||
} |
||||
dictTypeService.insertDictType(dict); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 修改字典类型 |
||||
*/ |
||||
@SaCheckPermission("system:dict:edit") |
||||
@Log(title = "字典类型", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysDictType dict) { |
||||
if (!dictTypeService.checkDictTypeUnique(dict)) { |
||||
return R.fail("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); |
||||
} |
||||
dictTypeService.updateDictType(dict); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 删除字典类型 |
||||
* |
||||
* @param dictIds 字典ID串 |
||||
*/ |
||||
@SaCheckPermission("system:dict:remove") |
||||
@Log(title = "字典类型", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{dictIds}") |
||||
public R<Void> remove(@PathVariable Long[] dictIds) { |
||||
dictTypeService.deleteDictTypeByIds(dictIds); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 刷新字典缓存 |
||||
*/ |
||||
@SaCheckPermission("system:dict:remove") |
||||
@Log(title = "字典类型", businessType = BusinessType.CLEAN) |
||||
@DeleteMapping("/refreshCache") |
||||
public R<Void> refreshCache() { |
||||
dictTypeService.resetDictCache(); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 获取字典选择框列表 |
||||
*/ |
||||
@GetMapping("/optionselect") |
||||
public R<List<SysDictType>> optionselect() { |
||||
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); |
||||
return R.ok(dictTypes); |
||||
} |
||||
} |
@ -0,0 +1,32 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore; |
||||
import com.ruoyi.common.config.RuoYiConfig; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
/** |
||||
* 首页 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
public class SysIndexController { |
||||
|
||||
/** |
||||
* 系统基础配置 |
||||
*/ |
||||
private final RuoYiConfig ruoyiConfig; |
||||
|
||||
/** |
||||
* 访问首页,提示语 |
||||
*/ |
||||
@SaIgnore |
||||
@GetMapping("/") |
||||
public String index() { |
||||
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); |
||||
} |
||||
} |
@ -0,0 +1,144 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore; |
||||
import com.ruoyi.common.constant.Constants; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysMenu; |
||||
import com.ruoyi.common.core.domain.entity.SysUser; |
||||
import com.ruoyi.common.core.domain.model.EmailLoginBody; |
||||
import com.ruoyi.common.core.domain.model.LoginBody; |
||||
import com.ruoyi.common.core.domain.model.LoginUser; |
||||
import com.ruoyi.common.core.domain.model.SmsLoginBody; |
||||
import com.ruoyi.common.helper.LoginHelper; |
||||
import com.ruoyi.system.domain.vo.RouterVo; |
||||
import com.ruoyi.system.service.ISysMenuService; |
||||
import com.ruoyi.system.service.ISysUserService; |
||||
import com.ruoyi.system.service.SysLoginService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 登录验证 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
public class SysLoginController { |
||||
|
||||
private final SysLoginService loginService; |
||||
private final ISysMenuService menuService; |
||||
private final ISysUserService userService; |
||||
|
||||
/** |
||||
* 登录方法 |
||||
* |
||||
* @param loginBody 登录信息 |
||||
* @return 结果 |
||||
*/ |
||||
@SaIgnore |
||||
@PostMapping("/login") |
||||
public R<Map<String, Object>> login(@Validated @RequestBody LoginBody loginBody) { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
// 生成令牌
|
||||
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), |
||||
loginBody.getUuid()); |
||||
ajax.put(Constants.TOKEN, token); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 短信登录 |
||||
* |
||||
* @param smsLoginBody 登录信息 |
||||
* @return 结果 |
||||
*/ |
||||
@SaIgnore |
||||
@PostMapping("/smsLogin") |
||||
public R<Map<String, Object>> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
// 生成令牌
|
||||
String token = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode()); |
||||
ajax.put(Constants.TOKEN, token); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 邮件登录 |
||||
* |
||||
* @param body 登录信息 |
||||
* @return 结果 |
||||
*/ |
||||
@PostMapping("/emailLogin") |
||||
public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
// 生成令牌
|
||||
String token = loginService.emailLogin(body.getEmail(), body.getEmailCode()); |
||||
ajax.put(Constants.TOKEN, token); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 小程序登录(示例) |
||||
* |
||||
* @param xcxCode 小程序code |
||||
* @return 结果 |
||||
*/ |
||||
@SaIgnore |
||||
@PostMapping("/xcxLogin") |
||||
public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
// 生成令牌
|
||||
String token = loginService.xcxLogin(xcxCode); |
||||
ajax.put(Constants.TOKEN, token); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 退出登录 |
||||
*/ |
||||
@SaIgnore |
||||
@PostMapping("/logout") |
||||
public R<Void> logout() { |
||||
loginService.logout(); |
||||
return R.ok("退出成功"); |
||||
} |
||||
|
||||
/** |
||||
* 获取用户信息 |
||||
* |
||||
* @return 用户信息 |
||||
*/ |
||||
@GetMapping("getInfo") |
||||
public R<Map<String, Object>> getInfo() { |
||||
LoginUser loginUser = LoginHelper.getLoginUser(); |
||||
SysUser user = userService.selectUserById(loginUser.getUserId()); |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
ajax.put("user", user); |
||||
ajax.put("roles", loginUser.getRolePermission()); |
||||
ajax.put("permissions", loginUser.getMenuPermission()); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 获取路由信息 |
||||
* |
||||
* @return 路由信息 |
||||
*/ |
||||
@GetMapping("getRouters") |
||||
public R<List<RouterVo>> getRouters() { |
||||
Long userId = LoginHelper.getUserId(); |
||||
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); |
||||
return R.ok(menuService.buildMenus(menus)); |
||||
} |
||||
} |
@ -0,0 +1,127 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.lang.tree.Tree; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysMenu; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.system.service.ISysMenuService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 菜单信息 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/menu") |
||||
public class SysMenuController extends BaseController { |
||||
|
||||
private final ISysMenuService menuService; |
||||
|
||||
/** |
||||
* 获取菜单列表 |
||||
*/ |
||||
@SaCheckPermission("system:menu:list") |
||||
@GetMapping("/list") |
||||
public R<List<SysMenu>> list(SysMenu menu) { |
||||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); |
||||
return R.ok(menus); |
||||
} |
||||
|
||||
/** |
||||
* 根据菜单编号获取详细信息 |
||||
* |
||||
* @param menuId 菜单ID |
||||
*/ |
||||
@SaCheckPermission("system:menu:query") |
||||
@GetMapping(value = "/{menuId}") |
||||
public R<SysMenu> getInfo(@PathVariable Long menuId) { |
||||
return R.ok(menuService.selectMenuById(menuId)); |
||||
} |
||||
|
||||
/** |
||||
* 获取菜单下拉树列表 |
||||
*/ |
||||
@GetMapping("/treeselect") |
||||
public R<List<Tree<Long>>> treeselect(SysMenu menu) { |
||||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); |
||||
return R.ok(menuService.buildMenuTreeSelect(menus)); |
||||
} |
||||
|
||||
/** |
||||
* 加载对应角色菜单列表树 |
||||
* |
||||
* @param roleId 角色ID |
||||
*/ |
||||
@GetMapping(value = "/roleMenuTreeselect/{roleId}") |
||||
public R<Map<String, Object>> roleMenuTreeselect(@PathVariable("roleId") Long roleId) { |
||||
List<SysMenu> menus = menuService.selectMenuList(getUserId()); |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); |
||||
ajax.put("menus", menuService.buildMenuTreeSelect(menus)); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 新增菜单 |
||||
*/ |
||||
@SaCheckPermission("system:menu:add") |
||||
@Log(title = "菜单管理", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysMenu menu) { |
||||
if (!menuService.checkMenuNameUnique(menu)) { |
||||
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); |
||||
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { |
||||
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); |
||||
} |
||||
return toAjax(menuService.insertMenu(menu)); |
||||
} |
||||
|
||||
/** |
||||
* 修改菜单 |
||||
*/ |
||||
@SaCheckPermission("system:menu:edit") |
||||
@Log(title = "菜单管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysMenu menu) { |
||||
if (!menuService.checkMenuNameUnique(menu)) { |
||||
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); |
||||
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { |
||||
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); |
||||
} else if (menu.getMenuId().equals(menu.getParentId())) { |
||||
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); |
||||
} |
||||
return toAjax(menuService.updateMenu(menu)); |
||||
} |
||||
|
||||
/** |
||||
* 删除菜单 |
||||
* |
||||
* @param menuId 菜单ID |
||||
*/ |
||||
@SaCheckPermission("system:menu:remove") |
||||
@Log(title = "菜单管理", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{menuId}") |
||||
public R<Void> remove(@PathVariable("menuId") Long menuId) { |
||||
if (menuService.hasChildByMenuId(menuId)) { |
||||
return R.warn("存在子菜单,不允许删除"); |
||||
} |
||||
if (menuService.checkMenuExistRole(menuId)) { |
||||
return R.warn("菜单已分配,不允许删除"); |
||||
} |
||||
return toAjax(menuService.deleteMenuById(menuId)); |
||||
} |
||||
} |
@ -0,0 +1,80 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.system.domain.SysNotice; |
||||
import com.ruoyi.system.service.ISysNoticeService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
/** |
||||
* 公告 信息操作处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/notice") |
||||
public class SysNoticeController extends BaseController { |
||||
|
||||
private final ISysNoticeService noticeService; |
||||
|
||||
/** |
||||
* 获取通知公告列表 |
||||
*/ |
||||
@SaCheckPermission("system:notice:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysNotice> list(SysNotice notice, PageQuery pageQuery) { |
||||
return noticeService.selectPageNoticeList(notice, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 根据通知公告编号获取详细信息 |
||||
* |
||||
* @param noticeId 公告ID |
||||
*/ |
||||
@SaCheckPermission("system:notice:query") |
||||
@GetMapping(value = "/{noticeId}") |
||||
public R<SysNotice> getInfo(@PathVariable Long noticeId) { |
||||
return R.ok(noticeService.selectNoticeById(noticeId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增通知公告 |
||||
*/ |
||||
@SaCheckPermission("system:notice:add") |
||||
@Log(title = "通知公告", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysNotice notice) { |
||||
return toAjax(noticeService.insertNotice(notice)); |
||||
} |
||||
|
||||
/** |
||||
* 修改通知公告 |
||||
*/ |
||||
@SaCheckPermission("system:notice:edit") |
||||
@Log(title = "通知公告", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysNotice notice) { |
||||
return toAjax(noticeService.updateNotice(notice)); |
||||
} |
||||
|
||||
/** |
||||
* 删除通知公告 |
||||
* |
||||
* @param noticeIds 公告ID串 |
||||
*/ |
||||
@SaCheckPermission("system:notice:remove") |
||||
@Log(title = "通知公告", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{noticeIds}") |
||||
public R<Void> remove(@PathVariable Long[] noticeIds) { |
||||
return toAjax(noticeService.deleteNoticeByIds(noticeIds)); |
||||
} |
||||
} |
@ -0,0 +1,105 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.annotation.RepeatSubmit; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.core.validate.AddGroup; |
||||
import com.ruoyi.common.core.validate.EditGroup; |
||||
import com.ruoyi.common.core.validate.QueryGroup; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.system.domain.bo.SysOssConfigBo; |
||||
import com.ruoyi.system.domain.vo.SysOssConfigVo; |
||||
import com.ruoyi.system.service.ISysOssConfigService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.validation.constraints.NotEmpty; |
||||
import javax.validation.constraints.NotNull; |
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* 对象存储配置 |
||||
* |
||||
* @author Lion Li |
||||
* @author 孤舟烟雨 |
||||
* @date 2021-08-13 |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/oss/config") |
||||
public class SysOssConfigController extends BaseController { |
||||
|
||||
private final ISysOssConfigService iSysOssConfigService; |
||||
|
||||
/** |
||||
* 查询对象存储配置列表 |
||||
*/ |
||||
@SaCheckPermission("system:oss:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { |
||||
return iSysOssConfigService.queryPageList(bo, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 获取对象存储配置详细信息 |
||||
* |
||||
* @param ossConfigId OSS配置ID |
||||
*/ |
||||
@SaCheckPermission("system:oss:query") |
||||
@GetMapping("/{ossConfigId}") |
||||
public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空") |
||||
@PathVariable Long ossConfigId) { |
||||
return R.ok(iSysOssConfigService.queryById(ossConfigId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增对象存储配置 |
||||
*/ |
||||
@SaCheckPermission("system:oss:add") |
||||
@Log(title = "对象存储配置", businessType = BusinessType.INSERT) |
||||
@RepeatSubmit() |
||||
@PostMapping() |
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { |
||||
return toAjax(iSysOssConfigService.insertByBo(bo)); |
||||
} |
||||
|
||||
/** |
||||
* 修改对象存储配置 |
||||
*/ |
||||
@SaCheckPermission("system:oss:edit") |
||||
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE) |
||||
@RepeatSubmit() |
||||
@PutMapping() |
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { |
||||
return toAjax(iSysOssConfigService.updateByBo(bo)); |
||||
} |
||||
|
||||
/** |
||||
* 删除对象存储配置 |
||||
* |
||||
* @param ossConfigIds OSS配置ID串 |
||||
*/ |
||||
@SaCheckPermission("system:oss:remove") |
||||
@Log(title = "对象存储配置", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{ossConfigIds}") |
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
@PathVariable Long[] ossConfigIds) { |
||||
return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true)); |
||||
} |
||||
|
||||
/** |
||||
* 状态修改 |
||||
*/ |
||||
@SaCheckPermission("system:oss:edit") |
||||
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/changeStatus") |
||||
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) { |
||||
return toAjax(iSysOssConfigService.updateOssConfigStatus(bo)); |
||||
} |
||||
} |
@ -0,0 +1,109 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.core.validate.QueryGroup; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.system.domain.bo.SysOssBo; |
||||
import com.ruoyi.system.domain.vo.SysOssVo; |
||||
import com.ruoyi.system.service.ISysOssService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.validation.constraints.NotEmpty; |
||||
import java.io.IOException; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 文件上传 控制层 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/oss") |
||||
public class SysOssController extends BaseController { |
||||
|
||||
private final ISysOssService iSysOssService; |
||||
|
||||
/** |
||||
* 查询OSS对象存储列表 |
||||
*/ |
||||
@SaCheckPermission("system:oss:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) { |
||||
return iSysOssService.queryPageList(bo, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 查询OSS对象基于id串 |
||||
* |
||||
* @param ossIds OSS对象ID串 |
||||
*/ |
||||
@SaCheckPermission("system:oss:list") |
||||
@GetMapping("/listByIds/{ossIds}") |
||||
public R<List<SysOssVo>> listByIds(@NotEmpty(message = "主键不能为空") |
||||
@PathVariable Long[] ossIds) { |
||||
List<SysOssVo> list = iSysOssService.listByIds(Arrays.asList(ossIds)); |
||||
return R.ok(list); |
||||
} |
||||
|
||||
/** |
||||
* 上传OSS对象存储 |
||||
* |
||||
* @param file 文件 |
||||
*/ |
||||
@SaCheckPermission("system:oss:upload") |
||||
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT) |
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
||||
public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) { |
||||
if (ObjectUtil.isNull(file)) { |
||||
return R.fail("上传文件不能为空"); |
||||
} |
||||
SysOssVo oss = iSysOssService.upload(file); |
||||
Map<String, String> map = new HashMap<>(2); |
||||
map.put("url", oss.getUrl()); |
||||
map.put("fileName", oss.getOriginalName()); |
||||
map.put("ossId", oss.getOssId().toString()); |
||||
return R.ok(map); |
||||
} |
||||
|
||||
/** |
||||
* 下载OSS对象 |
||||
* |
||||
* @param ossId OSS对象ID |
||||
*/ |
||||
@SaCheckPermission("system:oss:download") |
||||
@GetMapping("/download/{ossId}") |
||||
public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { |
||||
iSysOssService.download(ossId,response); |
||||
} |
||||
|
||||
/** |
||||
* 删除OSS对象存储 |
||||
* |
||||
* @param ossIds OSS对象ID串 |
||||
*/ |
||||
@SaCheckPermission("system:oss:remove") |
||||
@Log(title = "OSS对象存储", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{ossIds}") |
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
@PathVariable Long[] ossIds) { |
||||
return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,115 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.domain.SysPost; |
||||
import com.ruoyi.system.service.ISysPostService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 岗位信息操作处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/post") |
||||
public class SysPostController extends BaseController { |
||||
|
||||
private final ISysPostService postService; |
||||
|
||||
/** |
||||
* 获取岗位列表 |
||||
*/ |
||||
@SaCheckPermission("system:post:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysPost> list(SysPost post, PageQuery pageQuery) { |
||||
return postService.selectPagePostList(post, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出岗位列表 |
||||
*/ |
||||
@Log(title = "岗位管理", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("system:post:export") |
||||
@PostMapping("/export") |
||||
public void export(SysPost post, HttpServletResponse response) { |
||||
List<SysPost> list = postService.selectPostList(post); |
||||
ExcelUtil.exportExcel(list, "岗位数据", SysPost.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 根据岗位编号获取详细信息 |
||||
* |
||||
* @param postId 岗位ID |
||||
*/ |
||||
@SaCheckPermission("system:post:query") |
||||
@GetMapping(value = "/{postId}") |
||||
public R<SysPost> getInfo(@PathVariable Long postId) { |
||||
return R.ok(postService.selectPostById(postId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增岗位 |
||||
*/ |
||||
@SaCheckPermission("system:post:add") |
||||
@Log(title = "岗位管理", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysPost post) { |
||||
if (!postService.checkPostNameUnique(post)) { |
||||
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); |
||||
} else if (!postService.checkPostCodeUnique(post)) { |
||||
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); |
||||
} |
||||
return toAjax(postService.insertPost(post)); |
||||
} |
||||
|
||||
/** |
||||
* 修改岗位 |
||||
*/ |
||||
@SaCheckPermission("system:post:edit") |
||||
@Log(title = "岗位管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysPost post) { |
||||
if (!postService.checkPostNameUnique(post)) { |
||||
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); |
||||
} else if (!postService.checkPostCodeUnique(post)) { |
||||
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); |
||||
} |
||||
return toAjax(postService.updatePost(post)); |
||||
} |
||||
|
||||
/** |
||||
* 删除岗位 |
||||
* |
||||
* @param postIds 岗位ID串 |
||||
*/ |
||||
@SaCheckPermission("system:post:remove") |
||||
@Log(title = "岗位管理", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{postIds}") |
||||
public R<Void> remove(@PathVariable Long[] postIds) { |
||||
return toAjax(postService.deletePostByIds(postIds)); |
||||
} |
||||
|
||||
/** |
||||
* 获取岗位选择框列表 |
||||
*/ |
||||
@GetMapping("/optionselect") |
||||
public R<List<SysPost>> optionselect() { |
||||
List<SysPost> posts = postService.selectPostAll(); |
||||
return R.ok(posts); |
||||
} |
||||
} |
@ -0,0 +1,126 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.secure.BCrypt; |
||||
import cn.hutool.core.io.FileUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysUser; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.helper.LoginHelper; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.file.MimeTypeUtils; |
||||
import com.ruoyi.system.domain.SysOss; |
||||
import com.ruoyi.system.domain.vo.SysOssVo; |
||||
import com.ruoyi.system.service.ISysOssService; |
||||
import com.ruoyi.system.service.ISysUserService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 个人信息 业务处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/user/profile") |
||||
public class SysProfileController extends BaseController { |
||||
|
||||
private final ISysUserService userService; |
||||
private final ISysOssService iSysOssService; |
||||
|
||||
/** |
||||
* 个人信息 |
||||
*/ |
||||
@GetMapping |
||||
public R<Map<String, Object>> profile() { |
||||
SysUser user = userService.selectUserById(getUserId()); |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
ajax.put("user", user); |
||||
ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName())); |
||||
ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName())); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 修改用户 |
||||
*/ |
||||
@Log(title = "个人信息", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> updateProfile(@RequestBody SysUser user) { |
||||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { |
||||
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); |
||||
} |
||||
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { |
||||
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); |
||||
} |
||||
user.setUserId(getUserId()); |
||||
user.setUserName(null); |
||||
user.setPassword(null); |
||||
user.setAvatar(null); |
||||
user.setDeptId(null); |
||||
if (userService.updateUserProfile(user) > 0) { |
||||
return R.ok(); |
||||
} |
||||
return R.fail("修改个人信息异常,请联系管理员"); |
||||
} |
||||
|
||||
/** |
||||
* 重置密码 |
||||
* |
||||
* @param newPassword 旧密码 |
||||
* @param oldPassword 新密码 |
||||
*/ |
||||
@Log(title = "个人信息", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/updatePwd") |
||||
public R<Void> updatePwd(String oldPassword, String newPassword) { |
||||
SysUser user = userService.selectUserById(LoginHelper.getUserId()); |
||||
String userName = user.getUserName(); |
||||
String password = user.getPassword(); |
||||
if (!BCrypt.checkpw(oldPassword, password)) { |
||||
return R.fail("修改密码失败,旧密码错误"); |
||||
} |
||||
if (BCrypt.checkpw(newPassword, password)) { |
||||
return R.fail("新密码不能与旧密码相同"); |
||||
} |
||||
|
||||
if (userService.resetUserPwd(userName, BCrypt.hashpw(newPassword)) > 0) { |
||||
return R.ok(); |
||||
} |
||||
return R.fail("修改密码异常,请联系管理员"); |
||||
} |
||||
|
||||
/** |
||||
* 头像上传 |
||||
* |
||||
* @param avatarfile 用户头像 |
||||
*/ |
||||
@Log(title = "用户头像", businessType = BusinessType.UPDATE) |
||||
@PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
||||
public R<Map<String, Object>> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
if (!avatarfile.isEmpty()) { |
||||
String extension = FileUtil.extName(avatarfile.getOriginalFilename()); |
||||
if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { |
||||
return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); |
||||
} |
||||
SysOssVo oss = iSysOssService.upload(avatarfile); |
||||
String avatar = oss.getUrl(); |
||||
if (userService.updateUserAvatar(getUsername(), avatar)) { |
||||
ajax.put("imgUrl", avatar); |
||||
return R.ok(ajax); |
||||
} |
||||
} |
||||
return R.fail("上传图片异常,请联系管理员"); |
||||
} |
||||
} |
@ -0,0 +1,40 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.model.RegisterBody; |
||||
import com.ruoyi.system.service.ISysConfigService; |
||||
import com.ruoyi.system.service.SysRegisterService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
/** |
||||
* 注册验证 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
public class SysRegisterController extends BaseController { |
||||
|
||||
private final SysRegisterService registerService; |
||||
private final ISysConfigService configService; |
||||
|
||||
/** |
||||
* 用户注册 |
||||
*/ |
||||
@SaIgnore |
||||
@PostMapping("/register") |
||||
public R<Void> register(@Validated @RequestBody RegisterBody user) { |
||||
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) { |
||||
return R.fail("当前系统没有开启注册功能!"); |
||||
} |
||||
registerService.register(user); |
||||
return R.ok(); |
||||
} |
||||
} |
@ -0,0 +1,227 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysDept; |
||||
import com.ruoyi.common.core.domain.entity.SysRole; |
||||
import com.ruoyi.common.core.domain.entity.SysUser; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.domain.SysUserRole; |
||||
import com.ruoyi.system.service.ISysDeptService; |
||||
import com.ruoyi.system.service.ISysRoleService; |
||||
import com.ruoyi.system.service.ISysUserService; |
||||
import com.ruoyi.system.service.SysPermissionService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 角色信息 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/role") |
||||
public class SysRoleController extends BaseController { |
||||
|
||||
private final ISysRoleService roleService; |
||||
private final ISysUserService userService; |
||||
private final ISysDeptService deptService; |
||||
private final SysPermissionService permissionService; |
||||
|
||||
/** |
||||
* 获取角色信息列表 |
||||
*/ |
||||
@SaCheckPermission("system:role:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysRole> list(SysRole role, PageQuery pageQuery) { |
||||
return roleService.selectPageRoleList(role, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出角色信息列表 |
||||
*/ |
||||
@Log(title = "角色管理", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("system:role:export") |
||||
@PostMapping("/export") |
||||
public void export(SysRole role, HttpServletResponse response) { |
||||
List<SysRole> list = roleService.selectRoleList(role); |
||||
ExcelUtil.exportExcel(list, "角色数据", SysRole.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 根据角色编号获取详细信息 |
||||
* |
||||
* @param roleId 角色ID |
||||
*/ |
||||
@SaCheckPermission("system:role:query") |
||||
@GetMapping(value = "/{roleId}") |
||||
public R<SysRole> getInfo(@PathVariable Long roleId) { |
||||
roleService.checkRoleDataScope(roleId); |
||||
return R.ok(roleService.selectRoleById(roleId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增角色 |
||||
*/ |
||||
@SaCheckPermission("system:role:add") |
||||
@Log(title = "角色管理", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysRole role) { |
||||
if (!roleService.checkRoleNameUnique(role)) { |
||||
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); |
||||
} else if (!roleService.checkRoleKeyUnique(role)) { |
||||
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); |
||||
} |
||||
return toAjax(roleService.insertRole(role)); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 修改保存角色 |
||||
*/ |
||||
@SaCheckPermission("system:role:edit") |
||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysRole role) { |
||||
roleService.checkRoleAllowed(role); |
||||
roleService.checkRoleDataScope(role.getRoleId()); |
||||
if (!roleService.checkRoleNameUnique(role)) { |
||||
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); |
||||
} else if (!roleService.checkRoleKeyUnique(role)) { |
||||
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); |
||||
} |
||||
|
||||
if (roleService.updateRole(role) > 0) { |
||||
roleService.cleanOnlineUserByRole(role.getRoleId()); |
||||
return R.ok(); |
||||
} |
||||
return R.fail("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); |
||||
} |
||||
|
||||
/** |
||||
* 修改保存数据权限 |
||||
*/ |
||||
@SaCheckPermission("system:role:edit") |
||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/dataScope") |
||||
public R<Void> dataScope(@RequestBody SysRole role) { |
||||
roleService.checkRoleAllowed(role); |
||||
roleService.checkRoleDataScope(role.getRoleId()); |
||||
return toAjax(roleService.authDataScope(role)); |
||||
} |
||||
|
||||
/** |
||||
* 状态修改 |
||||
*/ |
||||
@SaCheckPermission("system:role:edit") |
||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/changeStatus") |
||||
public R<Void> changeStatus(@RequestBody SysRole role) { |
||||
roleService.checkRoleAllowed(role); |
||||
roleService.checkRoleDataScope(role.getRoleId()); |
||||
return toAjax(roleService.updateRoleStatus(role)); |
||||
} |
||||
|
||||
/** |
||||
* 删除角色 |
||||
* |
||||
* @param roleIds 角色ID串 |
||||
*/ |
||||
@SaCheckPermission("system:role:remove") |
||||
@Log(title = "角色管理", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{roleIds}") |
||||
public R<Void> remove(@PathVariable Long[] roleIds) { |
||||
return toAjax(roleService.deleteRoleByIds(roleIds)); |
||||
} |
||||
|
||||
/** |
||||
* 获取角色选择框列表 |
||||
*/ |
||||
@SaCheckPermission("system:role:query") |
||||
@GetMapping("/optionselect") |
||||
public R<List<SysRole>> optionselect() { |
||||
return R.ok(roleService.selectRoleAll()); |
||||
} |
||||
|
||||
/** |
||||
* 查询已分配用户角色列表 |
||||
*/ |
||||
@SaCheckPermission("system:role:list") |
||||
@GetMapping("/authUser/allocatedList") |
||||
public TableDataInfo<SysUser> allocatedList(SysUser user, PageQuery pageQuery) { |
||||
return userService.selectAllocatedList(user, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 查询未分配用户角色列表 |
||||
*/ |
||||
@SaCheckPermission("system:role:list") |
||||
@GetMapping("/authUser/unallocatedList") |
||||
public TableDataInfo<SysUser> unallocatedList(SysUser user, PageQuery pageQuery) { |
||||
return userService.selectUnallocatedList(user, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 取消授权用户 |
||||
*/ |
||||
@SaCheckPermission("system:role:edit") |
||||
@Log(title = "角色管理", businessType = BusinessType.GRANT) |
||||
@PutMapping("/authUser/cancel") |
||||
public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) { |
||||
return toAjax(roleService.deleteAuthUser(userRole)); |
||||
} |
||||
|
||||
/** |
||||
* 批量取消授权用户 |
||||
* |
||||
* @param roleId 角色ID |
||||
* @param userIds 用户ID串 |
||||
*/ |
||||
@SaCheckPermission("system:role:edit") |
||||
@Log(title = "角色管理", businessType = BusinessType.GRANT) |
||||
@PutMapping("/authUser/cancelAll") |
||||
public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) { |
||||
return toAjax(roleService.deleteAuthUsers(roleId, userIds)); |
||||
} |
||||
|
||||
/** |
||||
* 批量选择用户授权 |
||||
* |
||||
* @param roleId 角色ID |
||||
* @param userIds 用户ID串 |
||||
*/ |
||||
@SaCheckPermission("system:role:edit") |
||||
@Log(title = "角色管理", businessType = BusinessType.GRANT) |
||||
@PutMapping("/authUser/selectAll") |
||||
public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) { |
||||
roleService.checkRoleDataScope(roleId); |
||||
return toAjax(roleService.insertAuthUsers(roleId, userIds)); |
||||
} |
||||
|
||||
/** |
||||
* 获取对应角色部门树列表 |
||||
* |
||||
* @param roleId 角色ID |
||||
*/ |
||||
@SaCheckPermission("system:role:list") |
||||
@GetMapping(value = "/deptTree/{roleId}") |
||||
public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) { |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); |
||||
ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); |
||||
return R.ok(ajax); |
||||
} |
||||
} |
@ -0,0 +1,258 @@
|
||||
package com.ruoyi.web.controller.system; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin; |
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.dev33.satoken.secure.BCrypt; |
||||
import cn.hutool.core.bean.BeanUtil; |
||||
import cn.hutool.core.lang.tree.Tree; |
||||
import cn.hutool.core.util.ArrayUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.entity.SysDept; |
||||
import com.ruoyi.common.core.domain.entity.SysRole; |
||||
import com.ruoyi.common.core.domain.entity.SysUser; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.excel.ExcelResult; |
||||
import com.ruoyi.common.helper.LoginHelper; |
||||
import com.ruoyi.common.utils.StreamUtils; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.system.domain.vo.SysUserExportVo; |
||||
import com.ruoyi.system.domain.vo.SysUserImportVo; |
||||
import com.ruoyi.system.listener.SysUserImportListener; |
||||
import com.ruoyi.system.service.ISysDeptService; |
||||
import com.ruoyi.system.service.ISysPostService; |
||||
import com.ruoyi.system.service.ISysRoleService; |
||||
import com.ruoyi.system.service.ISysUserService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 用户信息 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/system/user") |
||||
public class SysUserController extends BaseController { |
||||
|
||||
private final ISysUserService userService; |
||||
private final ISysRoleService roleService; |
||||
private final ISysPostService postService; |
||||
private final ISysDeptService deptService; |
||||
|
||||
/** |
||||
* 获取用户列表 |
||||
*/ |
||||
@SaCheckPermission("system:user:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<SysUser> list(SysUser user, PageQuery pageQuery) { |
||||
return userService.selectPageUserList(user, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 查询用户列表,用于用户选择场景 |
||||
*/ |
||||
@SaCheckLogin |
||||
@GetMapping("/selectUser") |
||||
public TableDataInfo<SysUser> selectUser(SysUser user, PageQuery pageQuery) { |
||||
return userService.selectPageUserList(user, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出用户列表 |
||||
*/ |
||||
@Log(title = "用户管理", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("system:user:export") |
||||
@PostMapping("/export") |
||||
public void export(SysUser user, HttpServletResponse response) { |
||||
List<SysUser> list = userService.selectUserList(user); |
||||
List<SysUserExportVo> listVo = BeanUtil.copyToList(list, SysUserExportVo.class); |
||||
for (int i = 0; i < list.size(); i++) { |
||||
SysDept dept = list.get(i).getDept(); |
||||
SysUserExportVo vo = listVo.get(i); |
||||
if (ObjectUtil.isNotEmpty(dept)) { |
||||
vo.setDeptName(dept.getDeptName()); |
||||
vo.setLeader(dept.getLeader()); |
||||
} |
||||
} |
||||
ExcelUtil.exportExcel(listVo, "用户数据", SysUserExportVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 导入数据 |
||||
* |
||||
* @param file 导入文件 |
||||
* @param updateSupport 是否更新已存在数据 |
||||
*/ |
||||
@Log(title = "用户管理", businessType = BusinessType.IMPORT) |
||||
@SaCheckPermission("system:user:import") |
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
||||
public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { |
||||
ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); |
||||
return R.ok(result.getAnalysis()); |
||||
} |
||||
|
||||
/** |
||||
* 获取导入模板 |
||||
*/ |
||||
@PostMapping("/importTemplate") |
||||
public void importTemplate(HttpServletResponse response) { |
||||
ExcelUtil.exportExcel(new ArrayList<>(), "用户数据", SysUserImportVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 根据用户编号获取详细信息 |
||||
* |
||||
* @param userId 用户ID |
||||
*/ |
||||
@SaCheckPermission("system:user:query") |
||||
@GetMapping(value = {"/", "/{userId}"}) |
||||
public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) { |
||||
userService.checkUserDataScope(userId); |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
List<SysRole> roles = roleService.selectRoleAll(); |
||||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); |
||||
ajax.put("posts", postService.selectPostAll()); |
||||
if (ObjectUtil.isNotNull(userId)) { |
||||
SysUser sysUser = userService.selectUserById(userId); |
||||
ajax.put("user", sysUser); |
||||
ajax.put("postIds", postService.selectPostListByUserId(userId)); |
||||
ajax.put("roleIds", StreamUtils.toList(sysUser.getRoles(), SysRole::getRoleId)); |
||||
} |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 新增用户 |
||||
*/ |
||||
@SaCheckPermission("system:user:add") |
||||
@Log(title = "用户管理", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated @RequestBody SysUser user) { |
||||
if (!userService.checkUserNameUnique(user)) { |
||||
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); |
||||
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { |
||||
return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); |
||||
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { |
||||
return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); |
||||
} |
||||
user.setPassword(BCrypt.hashpw(user.getPassword())); |
||||
return toAjax(userService.insertUser(user)); |
||||
} |
||||
|
||||
/** |
||||
* 修改用户 |
||||
*/ |
||||
@SaCheckPermission("system:user:edit") |
||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated @RequestBody SysUser user) { |
||||
userService.checkUserAllowed(user); |
||||
userService.checkUserDataScope(user.getUserId()); |
||||
if (!userService.checkUserNameUnique(user)) { |
||||
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); |
||||
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { |
||||
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); |
||||
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { |
||||
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); |
||||
} |
||||
return toAjax(userService.updateUser(user)); |
||||
} |
||||
|
||||
/** |
||||
* 删除用户 |
||||
* |
||||
* @param userIds 角色ID串 |
||||
*/ |
||||
@SaCheckPermission("system:user:remove") |
||||
@Log(title = "用户管理", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{userIds}") |
||||
public R<Void> remove(@PathVariable Long[] userIds) { |
||||
if (ArrayUtil.contains(userIds, getUserId())) { |
||||
return R.fail("当前用户不能删除"); |
||||
} |
||||
return toAjax(userService.deleteUserByIds(userIds)); |
||||
} |
||||
|
||||
/** |
||||
* 重置密码 |
||||
*/ |
||||
@SaCheckPermission("system:user:resetPwd") |
||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/resetPwd") |
||||
public R<Void> resetPwd(@RequestBody SysUser user) { |
||||
userService.checkUserAllowed(user); |
||||
userService.checkUserDataScope(user.getUserId()); |
||||
user.setPassword(BCrypt.hashpw(user.getPassword())); |
||||
return toAjax(userService.resetPwd(user)); |
||||
} |
||||
|
||||
/** |
||||
* 状态修改 |
||||
*/ |
||||
@SaCheckPermission("system:user:edit") |
||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE) |
||||
@PutMapping("/changeStatus") |
||||
public R<Void> changeStatus(@RequestBody SysUser user) { |
||||
userService.checkUserAllowed(user); |
||||
userService.checkUserDataScope(user.getUserId()); |
||||
return toAjax(userService.updateUserStatus(user)); |
||||
} |
||||
|
||||
/** |
||||
* 根据用户编号获取授权角色 |
||||
* |
||||
* @param userId 用户ID |
||||
*/ |
||||
@SaCheckPermission("system:user:query") |
||||
@GetMapping("/authRole/{userId}") |
||||
public R<Map<String, Object>> authRole(@PathVariable Long userId) { |
||||
SysUser user = userService.selectUserById(userId); |
||||
List<SysRole> roles = roleService.selectRolesByUserId(userId); |
||||
Map<String, Object> ajax = new HashMap<>(); |
||||
ajax.put("user", user); |
||||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); |
||||
return R.ok(ajax); |
||||
} |
||||
|
||||
/** |
||||
* 用户授权角色 |
||||
* |
||||
* @param userId 用户Id |
||||
* @param roleIds 角色ID串 |
||||
*/ |
||||
@SaCheckPermission("system:user:edit") |
||||
@Log(title = "用户管理", businessType = BusinessType.GRANT) |
||||
@PutMapping("/authRole") |
||||
public R<Void> insertAuthRole(Long userId, Long[] roleIds) { |
||||
userService.checkUserDataScope(userId); |
||||
userService.insertUserAuth(userId, roleIds); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 获取部门树列表 |
||||
*/ |
||||
@SaCheckPermission("system:user:list") |
||||
@GetMapping("/deptTree") |
||||
public R<List<Tree<Long>>> deptTree(SysDept dept) { |
||||
return R.ok(deptService.selectDeptTreeList(dept)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,117 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin; |
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.annotation.RepeatSubmit; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.workflow.domain.WfCategory; |
||||
import com.ruoyi.workflow.domain.vo.WfCategoryVo; |
||||
import com.ruoyi.workflow.service.IWfCategoryService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.validation.constraints.NotEmpty; |
||||
import javax.validation.constraints.NotNull; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 流程分类Controller |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/3/10 00:12 |
||||
*/ |
||||
@Validated |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/category") |
||||
public class WfCategoryController extends BaseController { |
||||
|
||||
private final IWfCategoryService categoryService; |
||||
|
||||
/** |
||||
* 查询流程分类列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:category:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<WfCategoryVo> list(WfCategory category, PageQuery pageQuery) { |
||||
return categoryService.queryPageList(category, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 查询全部的流程分类列表 |
||||
*/ |
||||
@SaCheckLogin |
||||
@GetMapping("/listAll") |
||||
public R<List<WfCategoryVo>> listAll(WfCategory category) { |
||||
return R.ok(categoryService.queryList(category)); |
||||
} |
||||
|
||||
/** |
||||
* 导出流程分类列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:category:export") |
||||
@Log(title = "流程分类", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/export") |
||||
public void export(@Validated WfCategory category, HttpServletResponse response) { |
||||
List<WfCategoryVo> list = categoryService.queryList(category); |
||||
ExcelUtil.exportExcel(list, "流程分类", WfCategoryVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 获取流程分类详细信息 |
||||
* @param categoryId 分类主键 |
||||
*/ |
||||
@SaCheckPermission("workflow:category:query") |
||||
@GetMapping("/{categoryId}") |
||||
public R<WfCategoryVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable("categoryId") Long categoryId) { |
||||
return R.ok(categoryService.queryById(categoryId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增流程分类 |
||||
*/ |
||||
@SaCheckPermission("workflow:category:add") |
||||
@Log(title = "流程分类", businessType = BusinessType.INSERT) |
||||
@RepeatSubmit() |
||||
@PostMapping() |
||||
public R<Void> add(@Validated @RequestBody WfCategory category) { |
||||
if (!categoryService.checkCategoryCodeUnique(category)) { |
||||
return R.fail("新增流程分类'" + category.getCategoryName() + "'失败,流程编码已存在"); |
||||
} |
||||
return toAjax(categoryService.insertCategory(category)); |
||||
} |
||||
|
||||
/** |
||||
* 修改流程分类 |
||||
*/ |
||||
@SaCheckPermission("workflow:category:edit") |
||||
@Log(title = "流程分类", businessType = BusinessType.UPDATE) |
||||
@RepeatSubmit() |
||||
@PutMapping() |
||||
public R<Void> edit(@Validated @RequestBody WfCategory category) { |
||||
if (!categoryService.checkCategoryCodeUnique(category)) { |
||||
return R.fail("修改流程分类'" + category.getCategoryName() + "'失败,流程编码已存在"); |
||||
} |
||||
return toAjax(categoryService.updateCategory(category)); |
||||
} |
||||
|
||||
/** |
||||
* 删除流程分类 |
||||
* @param categoryIds 分类主键串 |
||||
*/ |
||||
@SaCheckPermission("workflow:category:remove") |
||||
@Log(title = "流程分类" , businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{categoryIds}") |
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] categoryIds) { |
||||
return toAjax(categoryService.deleteWithValidByIds(Arrays.asList(categoryIds), true)); |
||||
} |
||||
} |
@ -0,0 +1,107 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.JsonUtils; |
||||
import com.ruoyi.flowable.core.domain.ProcessQuery; |
||||
import com.ruoyi.workflow.domain.vo.WfDeployVo; |
||||
import com.ruoyi.workflow.domain.vo.WfFormVo; |
||||
import com.ruoyi.workflow.service.IWfDeployFormService; |
||||
import com.ruoyi.workflow.service.IWfDeployService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.validation.constraints.NotEmpty; |
||||
import java.util.Arrays; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
|
||||
/** |
||||
* 流程部署 |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/3/24 20:57 |
||||
*/ |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/deploy") |
||||
public class WfDeployController extends BaseController { |
||||
|
||||
private final IWfDeployService deployService; |
||||
private final IWfDeployFormService deployFormService; |
||||
|
||||
/** |
||||
* 查询流程部署列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:deploy:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<WfDeployVo> list(ProcessQuery processQuery, PageQuery pageQuery) { |
||||
return deployService.queryPageList(processQuery, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 查询流程部署版本列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:deploy:list") |
||||
@GetMapping("/publishList") |
||||
public TableDataInfo<WfDeployVo> publishList(@RequestParam String processKey, PageQuery pageQuery) { |
||||
return deployService.queryPublishList(processKey, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 激活或挂起流程 |
||||
* |
||||
* @param state 状态(active:激活 suspended:挂起) |
||||
* @param definitionId 流程定义ID |
||||
*/ |
||||
@SaCheckPermission("workflow:deploy:state") |
||||
@PutMapping(value = "/changeState") |
||||
public R<Void> changeState(@RequestParam String state, @RequestParam String definitionId) { |
||||
deployService.updateState(definitionId, state); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 读取xml文件 |
||||
* @param definitionId 流程定义ID |
||||
* @return |
||||
*/ |
||||
@SaCheckPermission("workflow:deploy:query") |
||||
@GetMapping("/bpmnXml/{definitionId}") |
||||
public R<String> getBpmnXml(@PathVariable(value = "definitionId") String definitionId) { |
||||
return R.ok(null, deployService.queryBpmnXmlById(definitionId)); |
||||
} |
||||
|
||||
/** |
||||
* 删除流程模型 |
||||
* @param deployIds 流程部署ids |
||||
*/ |
||||
@SaCheckPermission("workflow:deploy:remove") |
||||
@Log(title = "删除流程部署", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{deployIds}") |
||||
public R<String> remove(@NotEmpty(message = "主键不能为空") @PathVariable String[] deployIds) { |
||||
deployService.deleteByIds(Arrays.asList(deployIds)); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 查询流程部署关联表单信息 |
||||
* |
||||
* @param deployId 流程部署id |
||||
*/ |
||||
@GetMapping("/form/{deployId}") |
||||
public R<?> start(@PathVariable(value = "deployId") String deployId) { |
||||
WfFormVo formVo = deployFormService.selectDeployFormByDeployId(deployId); |
||||
if (Objects.isNull(formVo)) { |
||||
return R.fail("请先配置流程表单"); |
||||
} |
||||
return R.ok(JsonUtils.parseObject(formVo.getContent(), Map.class)); |
||||
} |
||||
} |
@ -0,0 +1,112 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.core.validate.QueryGroup; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.workflow.domain.WfDeployForm; |
||||
import com.ruoyi.workflow.domain.bo.WfFormBo; |
||||
import com.ruoyi.workflow.domain.vo.WfFormVo; |
||||
import com.ruoyi.workflow.service.IWfDeployFormService; |
||||
import com.ruoyi.workflow.service.IWfFormService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.validation.constraints.NotEmpty; |
||||
import javax.validation.constraints.NotNull; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 流程表单Controller |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/3/7 22:07 |
||||
*/ |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/form") |
||||
public class WfFormController extends BaseController { |
||||
|
||||
private final IWfFormService formService; |
||||
|
||||
private final IWfDeployFormService deployFormService; |
||||
|
||||
/** |
||||
* 查询流程表单列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:form:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<WfFormVo> list(@Validated(QueryGroup.class) WfFormBo bo, PageQuery pageQuery) { |
||||
return formService.queryPageList(bo, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出流程表单列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:form:export") |
||||
@Log(title = "流程表单", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/export") |
||||
public void export(@Validated WfFormBo bo, HttpServletResponse response) { |
||||
List<WfFormVo> list = formService.queryList(bo); |
||||
ExcelUtil.exportExcel(list, "流程表单", WfFormVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 获取流程表单详细信息 |
||||
* @param formId 主键 |
||||
*/ |
||||
@SaCheckPermission("workflow:form:query") |
||||
@GetMapping(value = "/{formId}") |
||||
public R<WfFormVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable("formId") Long formId) { |
||||
return R.ok(formService.queryById(formId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增流程表单 |
||||
*/ |
||||
@SaCheckPermission("workflow:form:add") |
||||
@Log(title = "流程表单", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@RequestBody WfFormBo bo) { |
||||
return toAjax(formService.insertForm(bo)); |
||||
} |
||||
|
||||
/** |
||||
* 修改流程表单 |
||||
*/ |
||||
@SaCheckPermission("workflow:form:edit") |
||||
@Log(title = "流程表单", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@RequestBody WfFormBo bo) { |
||||
return toAjax(formService.updateForm(bo)); |
||||
} |
||||
|
||||
/** |
||||
* 删除流程表单 |
||||
* @param formIds 主键串 |
||||
*/ |
||||
@SaCheckPermission("workflow:form:remove") |
||||
@Log(title = "流程表单", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{formIds}") |
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] formIds) { |
||||
return toAjax(formService.deleteWithValidByIds(Arrays.asList(formIds)) ? 1 : 0); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 挂载流程表单 |
||||
*/ |
||||
@Log(title = "流程表单", businessType = BusinessType.INSERT) |
||||
@PostMapping("/addDeployForm") |
||||
public R<Void> addDeployForm(@RequestBody WfDeployForm deployForm) { |
||||
return toAjax(deployFormService.insertWfDeployForm(deployForm)); |
||||
} |
||||
} |
@ -0,0 +1,71 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
|
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.workflow.domain.bo.WfTaskBo; |
||||
import com.ruoyi.workflow.service.IWfInstanceService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
/** |
||||
* 工作流流程实例管理 |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/3/10 00:12 |
||||
*/ |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/instance") |
||||
public class WfInstanceController { |
||||
|
||||
private final IWfInstanceService instanceService; |
||||
|
||||
/** |
||||
* 激活或挂起流程实例 |
||||
* |
||||
* @param state 1:激活,2:挂起 |
||||
* @param instanceId 流程实例ID |
||||
*/ |
||||
@PostMapping(value = "/updateState") |
||||
public R updateState(@RequestParam Integer state, @RequestParam String instanceId) { |
||||
instanceService.updateState(state, instanceId); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 结束流程实例 |
||||
* |
||||
* @param bo 流程任务业务对象 |
||||
*/ |
||||
@PostMapping(value = "/stopProcessInstance") |
||||
public R stopProcessInstance(@RequestBody WfTaskBo bo) { |
||||
instanceService.stopProcessInstance(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 删除流程实例 |
||||
* |
||||
* @param instanceId 流程实例ID |
||||
* @param deleteReason 删除原因 |
||||
*/ |
||||
@Deprecated |
||||
@DeleteMapping(value = "/delete") |
||||
public R delete(@RequestParam String instanceId, String deleteReason) { |
||||
instanceService.delete(instanceId, deleteReason); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 查询流程实例详情信息 |
||||
* |
||||
* @param procInsId 流程实例ID |
||||
* @param deployId 流程部署ID |
||||
*/ |
||||
@GetMapping("/detail") |
||||
public R detail(String procInsId, String deployId) { |
||||
return R.ok(instanceService.queryDetailProcess(procInsId, deployId)); |
||||
} |
||||
} |
@ -0,0 +1,187 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.bean.BeanUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.annotation.RepeatSubmit; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.core.validate.AddGroup; |
||||
import com.ruoyi.common.core.validate.EditGroup; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.workflow.domain.WfCategory; |
||||
import com.ruoyi.workflow.domain.bo.WfModelBo; |
||||
import com.ruoyi.workflow.domain.vo.WfCategoryVo; |
||||
import com.ruoyi.workflow.domain.vo.WfModelExportVo; |
||||
import com.ruoyi.workflow.domain.vo.WfModelVo; |
||||
import com.ruoyi.workflow.service.IWfCategoryService; |
||||
import com.ruoyi.workflow.service.IWfModelService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.validation.constraints.NotEmpty; |
||||
import javax.validation.constraints.NotNull; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 工作流流程模型管理 |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/6/21 9:09 |
||||
*/ |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/model") |
||||
public class WfModelController extends BaseController { |
||||
|
||||
private final IWfModelService modelService; |
||||
private final IWfCategoryService categoryService; |
||||
|
||||
/** |
||||
* 查询流程模型列表 |
||||
* |
||||
* @param modelBo 流程模型对象 |
||||
* @param pageQuery 分页参数 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:list") |
||||
@GetMapping("/list") |
||||
public TableDataInfo<WfModelVo> list(WfModelBo modelBo, PageQuery pageQuery) { |
||||
return modelService.list(modelBo, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 查询流程模型列表 |
||||
* |
||||
* @param modelBo 流程模型对象 |
||||
* @param pageQuery 分页参数 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:list") |
||||
@GetMapping("/historyList") |
||||
public TableDataInfo<WfModelVo> historyList(WfModelBo modelBo, PageQuery pageQuery) { |
||||
return modelService.historyList(modelBo, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 获取流程模型详细信息 |
||||
* |
||||
* @param modelId 模型主键 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:query") |
||||
@GetMapping(value = "/{modelId}") |
||||
public R<WfModelVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable("modelId") String modelId) { |
||||
return R.ok(modelService.getModel(modelId)); |
||||
} |
||||
|
||||
/** |
||||
* 获取流程表单详细信息 |
||||
* |
||||
* @param modelId 模型主键 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:query") |
||||
@GetMapping(value = "/bpmnXml/{modelId}") |
||||
public R<String> getBpmnXml(@NotNull(message = "主键不能为空") @PathVariable("modelId") String modelId) { |
||||
return R.ok("操作成功", modelService.queryBpmnXmlById(modelId)); |
||||
} |
||||
|
||||
/** |
||||
* 新增流程模型 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:add") |
||||
@Log(title = "流程模型", businessType = BusinessType.INSERT) |
||||
@PostMapping |
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody WfModelBo modelBo) { |
||||
modelService.insertModel(modelBo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 修改流程模型 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:edit") |
||||
@Log(title = "流程模型", businessType = BusinessType.UPDATE) |
||||
@PutMapping |
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfModelBo modelBo) { |
||||
modelService.updateModel(modelBo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 保存流程模型 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:save") |
||||
@Log(title = "保存流程模型", businessType = BusinessType.INSERT) |
||||
@RepeatSubmit() |
||||
@PostMapping("/save") |
||||
public R<String> save(@RequestBody WfModelBo modelBo) { |
||||
modelService.saveModel(modelBo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 设为最新流程模型 |
||||
* @param modelId |
||||
* @return |
||||
*/ |
||||
@SaCheckPermission("workflow:model:save") |
||||
@Log(title = "设为最新流程模型", businessType = BusinessType.INSERT) |
||||
@RepeatSubmit() |
||||
@PostMapping("/latest") |
||||
public R<?> latest(@RequestParam String modelId) { |
||||
modelService.latestModel(modelId); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 删除流程模型 |
||||
* |
||||
* @param modelIds 流程模型主键串 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:remove") |
||||
@Log(title = "删除流程模型", businessType = BusinessType.DELETE) |
||||
@DeleteMapping("/{modelIds}") |
||||
public R<String> remove(@NotEmpty(message = "主键不能为空") @PathVariable String[] modelIds) { |
||||
modelService.deleteByIds(Arrays.asList(modelIds)); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 部署流程模型 |
||||
* |
||||
* @param modelId 流程模型主键 |
||||
*/ |
||||
@SaCheckPermission("workflow:model:deploy") |
||||
@Log(title = "部署流程模型", businessType = BusinessType.INSERT) |
||||
@RepeatSubmit() |
||||
@PostMapping("/deploy") |
||||
public R<Void> deployModel(@RequestParam String modelId) { |
||||
return toAjax(modelService.deployModel(modelId)); |
||||
} |
||||
|
||||
/** |
||||
* 导出流程模型数据 |
||||
*/ |
||||
@Log(title = "导出流程模型数据", businessType = BusinessType.EXPORT) |
||||
@SaCheckPermission("workflow:model:export") |
||||
@PostMapping("/export") |
||||
public void export(WfModelBo modelBo, HttpServletResponse response) { |
||||
List<WfModelVo> list = modelService.list(modelBo); |
||||
List<WfModelExportVo> listVo = BeanUtil.copyToList(list, WfModelExportVo.class); |
||||
List<WfCategoryVo> categoryVos = categoryService.queryList(new WfCategory()); |
||||
Map<String, String> categoryMap = categoryVos.stream() |
||||
.collect(Collectors.toMap(WfCategoryVo::getCode, WfCategoryVo::getCategoryName)); |
||||
for (WfModelExportVo exportVo : listVo) { |
||||
exportVo.setCategoryName(categoryMap.get(exportVo.getCategory())); |
||||
} |
||||
ExcelUtil.exportExcel(listVo, "流程模型数据", WfModelExportVo.class, response); |
||||
} |
||||
} |
@ -0,0 +1,239 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.bean.BeanUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.ruoyi.common.annotation.Log; |
||||
import com.ruoyi.common.core.controller.BaseController; |
||||
import com.ruoyi.common.core.domain.PageQuery; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.page.TableDataInfo; |
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.flowable.core.domain.ProcessQuery; |
||||
import com.ruoyi.workflow.domain.bo.WfCopyBo; |
||||
import com.ruoyi.workflow.domain.vo.*; |
||||
import com.ruoyi.workflow.service.IWfCopyService; |
||||
import com.ruoyi.workflow.service.IWfProcessService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.validation.annotation.Validated; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 工作流流程管理 |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/3/24 18:54 |
||||
*/ |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/process") |
||||
public class WfProcessController extends BaseController { |
||||
|
||||
private final IWfProcessService processService; |
||||
private final IWfCopyService copyService; |
||||
|
||||
/** |
||||
* 查询可发起流程列表 |
||||
* |
||||
* @param pageQuery 分页参数 |
||||
*/ |
||||
@GetMapping(value = "/list") |
||||
@SaCheckPermission("workflow:process:startList") |
||||
public TableDataInfo<WfDefinitionVo> startProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
||||
return processService.selectPageStartProcessList(processQuery, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 我拥有的流程 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:ownList") |
||||
@GetMapping(value = "/ownList") |
||||
public TableDataInfo<WfTaskVo> ownProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
||||
return processService.selectPageOwnProcessList(processQuery, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 获取待办列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:todoList") |
||||
@GetMapping(value = "/todoList") |
||||
public TableDataInfo<WfTaskVo> todoProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
||||
return processService.selectPageTodoProcessList(processQuery, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 获取待签列表 |
||||
* |
||||
* @param processQuery 流程业务对象 |
||||
* @param pageQuery 分页参数 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:claimList") |
||||
@GetMapping(value = "/claimList") |
||||
public TableDataInfo<WfTaskVo> claimProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
||||
return processService.selectPageClaimProcessList(processQuery, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 获取已办列表 |
||||
* |
||||
* @param pageQuery 分页参数 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:finishedList") |
||||
@GetMapping(value = "/finishedList") |
||||
public TableDataInfo<WfTaskVo> finishedProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
||||
return processService.selectPageFinishedProcessList(processQuery, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 获取抄送列表 |
||||
* |
||||
* @param copyBo 流程抄送对象 |
||||
* @param pageQuery 分页参数 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:copyList") |
||||
@GetMapping(value = "/copyList") |
||||
public TableDataInfo<WfCopyVo> copyProcessList(WfCopyBo copyBo, PageQuery pageQuery) { |
||||
copyBo.setUserId(getUserId()); |
||||
return copyService.selectPageList(copyBo, pageQuery); |
||||
} |
||||
|
||||
/** |
||||
* 导出可发起流程列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:startExport") |
||||
@Log(title = "可发起流程", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/startExport") |
||||
public void startExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
||||
List<WfDefinitionVo> list = processService.selectStartProcessList(processQuery); |
||||
ExcelUtil.exportExcel(list, "可发起流程", WfDefinitionVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 导出我拥有流程列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:ownExport") |
||||
@Log(title = "我拥有流程", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/ownExport") |
||||
public void ownExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
||||
List<WfTaskVo> list = processService.selectOwnProcessList(processQuery); |
||||
List<WfOwnTaskExportVo> listVo = BeanUtil.copyToList(list, WfOwnTaskExportVo.class); |
||||
for (WfOwnTaskExportVo exportVo : listVo) { |
||||
exportVo.setStatus(ObjectUtil.isNull(exportVo.getFinishTime()) ? "进行中" : "已完成"); |
||||
} |
||||
ExcelUtil.exportExcel(listVo, "我拥有流程", WfOwnTaskExportVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 导出待办流程列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:todoExport") |
||||
@Log(title = "待办流程", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/todoExport") |
||||
public void todoExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
||||
List<WfTaskVo> list = processService.selectTodoProcessList(processQuery); |
||||
List<WfTodoTaskExportVo> listVo = BeanUtil.copyToList(list, WfTodoTaskExportVo.class); |
||||
ExcelUtil.exportExcel(listVo, "待办流程", WfTodoTaskExportVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 导出待签流程列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:claimExport") |
||||
@Log(title = "待签流程", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/claimExport") |
||||
public void claimExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
||||
List<WfTaskVo> list = processService.selectClaimProcessList(processQuery); |
||||
List<WfClaimTaskExportVo> listVo = BeanUtil.copyToList(list, WfClaimTaskExportVo.class); |
||||
ExcelUtil.exportExcel(listVo, "待签流程", WfClaimTaskExportVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 导出已办流程列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:finishedExport") |
||||
@Log(title = "已办流程", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/finishedExport") |
||||
public void finishedExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
||||
List<WfTaskVo> list = processService.selectFinishedProcessList(processQuery); |
||||
List<WfFinishedTaskExportVo> listVo = BeanUtil.copyToList(list, WfFinishedTaskExportVo.class); |
||||
ExcelUtil.exportExcel(listVo, "已办流程", WfFinishedTaskExportVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 导出抄送流程列表 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:copyExport") |
||||
@Log(title = "抄送流程", businessType = BusinessType.EXPORT) |
||||
@PostMapping("/copyExport") |
||||
public void copyExport(WfCopyBo copyBo, HttpServletResponse response) { |
||||
copyBo.setUserId(getUserId()); |
||||
List<WfCopyVo> list = copyService.selectList(copyBo); |
||||
ExcelUtil.exportExcel(list, "抄送流程", WfCopyVo.class, response); |
||||
} |
||||
|
||||
/** |
||||
* 查询流程部署关联表单信息 |
||||
* |
||||
* @param definitionId 流程定义id |
||||
* @param deployId 流程部署id |
||||
*/ |
||||
@GetMapping("/getProcessForm") |
||||
@SaCheckPermission("workflow:process:start") |
||||
public R<?> getForm(@RequestParam(value = "definitionId") String definitionId, |
||||
@RequestParam(value = "deployId") String deployId, |
||||
@RequestParam(value = "procInsId", required = false) String procInsId) { |
||||
return R.ok(processService.selectFormContent(definitionId, deployId, procInsId)); |
||||
} |
||||
|
||||
/** |
||||
* 根据流程定义id启动流程实例 |
||||
* |
||||
* @param processDefId 流程定义id |
||||
* @param variables 变量集合,json对象 |
||||
*/ |
||||
@SaCheckPermission("workflow:process:start") |
||||
@PostMapping("/start/{processDefId}") |
||||
public R<Void> start(@PathVariable(value = "processDefId") String processDefId, @RequestBody Map<String, Object> variables) { |
||||
processService.startProcessByDefId(processDefId, variables); |
||||
return R.ok("流程启动成功"); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 删除流程实例 |
||||
* |
||||
* @param instanceIds 流程实例ID串 |
||||
*/ |
||||
@DeleteMapping("/instance/{instanceIds}") |
||||
public R<Void> delete(@PathVariable String[] instanceIds) { |
||||
processService.deleteProcessByIds(instanceIds); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 读取xml文件 |
||||
* @param processDefId 流程定义ID |
||||
*/ |
||||
@GetMapping("/bpmnXml/{processDefId}") |
||||
public R<String> getBpmnXml(@PathVariable(value = "processDefId") String processDefId) { |
||||
return R.ok(null, processService.queryBpmnXmlById(processDefId)); |
||||
} |
||||
|
||||
/** |
||||
* 查询流程详情信息 |
||||
* |
||||
* @param procInsId 流程实例ID |
||||
* @param taskId 任务ID |
||||
*/ |
||||
@GetMapping("/detail") |
||||
public R detail(String procInsId, String taskId) { |
||||
return R.ok(processService.queryProcessDetail(procInsId, taskId)); |
||||
} |
||||
} |
@ -0,0 +1,189 @@
|
||||
package com.ruoyi.web.controller.workflow; |
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.workflow.domain.bo.WfTaskBo; |
||||
import com.ruoyi.workflow.service.IWfTaskService; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.imageio.ImageIO; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
/** |
||||
* 工作流任务管理 |
||||
* |
||||
* @author KonBAI |
||||
* @createTime 2022/3/10 00:12 |
||||
*/ |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RestController |
||||
@RequestMapping("/workflow/task") |
||||
public class WfTaskController { |
||||
|
||||
private final IWfTaskService flowTaskService; |
||||
|
||||
/** |
||||
* 取消流程 |
||||
*/ |
||||
@PostMapping(value = "/stopProcess") |
||||
@SaCheckPermission("workflow:process:cancel") |
||||
public R stopProcess(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.stopProcess(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 撤回流程 |
||||
*/ |
||||
@PostMapping(value = "/revokeProcess") |
||||
@SaCheckPermission("workflow:process:revoke") |
||||
public R revokeProcess(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.revokeProcess(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 获取流程变量 |
||||
* @param taskId 流程任务Id |
||||
*/ |
||||
@GetMapping(value = "/processVariables/{taskId}") |
||||
@SaCheckPermission("workflow:process:query") |
||||
public R processVariables(@PathVariable(value = "taskId") String taskId) { |
||||
return R.ok(flowTaskService.getProcessVariables(taskId)); |
||||
} |
||||
|
||||
/** |
||||
* 审批任务 |
||||
*/ |
||||
@PostMapping(value = "/complete") |
||||
@SaCheckPermission("workflow:process:approval") |
||||
public R complete(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.complete(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 拒绝任务 |
||||
*/ |
||||
@PostMapping(value = "/reject") |
||||
@SaCheckPermission("workflow:process:approval") |
||||
public R taskReject(@RequestBody WfTaskBo taskBo) { |
||||
flowTaskService.taskReject(taskBo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 退回任务 |
||||
*/ |
||||
@PostMapping(value = "/return") |
||||
@SaCheckPermission("workflow:process:approval") |
||||
public R taskReturn(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.taskReturn(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 获取所有可回退的节点 |
||||
*/ |
||||
@PostMapping(value = "/returnList") |
||||
@SaCheckPermission("workflow:process:query") |
||||
public R findReturnTaskList(@RequestBody WfTaskBo bo) { |
||||
return R.ok(flowTaskService.findReturnTaskList(bo)); |
||||
} |
||||
|
||||
/** |
||||
* 删除任务 |
||||
*/ |
||||
@DeleteMapping(value = "/delete") |
||||
@SaCheckPermission("workflow:process:approval") |
||||
public R delete(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.deleteTask(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 认领/签收任务 |
||||
*/ |
||||
@PostMapping(value = "/claim") |
||||
@SaCheckPermission("workflow:process:claim") |
||||
public R claim(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.claim(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 取消认领/签收任务 |
||||
*/ |
||||
@PostMapping(value = "/unClaim") |
||||
@SaCheckPermission("workflow:process:claim") |
||||
public R unClaim(@RequestBody WfTaskBo bo) { |
||||
flowTaskService.unClaim(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 委派任务 |
||||
*/ |
||||
@PostMapping(value = "/delegate") |
||||
@SaCheckPermission("workflow:process:approval") |
||||
public R delegate(@RequestBody WfTaskBo bo) { |
||||
if (ObjectUtil.hasNull(bo.getTaskId(), bo.getUserId())) { |
||||
return R.fail("参数错误!"); |
||||
} |
||||
flowTaskService.delegateTask(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 转办任务 |
||||
*/ |
||||
@PostMapping(value = "/transfer") |
||||
@SaCheckPermission("workflow:process:approval") |
||||
public R transfer(@RequestBody WfTaskBo bo) { |
||||
if (ObjectUtil.hasNull(bo.getTaskId(), bo.getUserId())) { |
||||
return R.fail("参数错误!"); |
||||
} |
||||
flowTaskService.transferTask(bo); |
||||
return R.ok(); |
||||
} |
||||
|
||||
/** |
||||
* 生成流程图 |
||||
* |
||||
* @param processId 任务ID |
||||
*/ |
||||
@RequestMapping("/diagram/{processId}") |
||||
public void genProcessDiagram(HttpServletResponse response, |
||||
@PathVariable("processId") String processId) { |
||||
InputStream inputStream = flowTaskService.diagram(processId); |
||||
OutputStream os = null; |
||||
BufferedImage image = null; |
||||
try { |
||||
image = ImageIO.read(inputStream); |
||||
response.setContentType("image/png"); |
||||
os = response.getOutputStream(); |
||||
if (image != null) { |
||||
ImageIO.write(image, "png", os); |
||||
} |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
try { |
||||
if (os != null) { |
||||
os.flush(); |
||||
os.close(); |
||||
} |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,171 @@
|
||||
--- # 监控中心配置 |
||||
spring.boot.admin.client: |
||||
# 增加客户端开关 |
||||
enabled: true |
||||
url: http://localhost:9090/admin |
||||
instance: |
||||
service-host-type: IP |
||||
username: ruoyi |
||||
password: 123456 |
||||
|
||||
--- # xxl-job 配置 |
||||
xxl.job: |
||||
# 执行器开关 |
||||
enabled: false |
||||
# 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。 |
||||
admin-addresses: http://localhost:9100/xxl-job-admin |
||||
# 执行器通讯TOKEN:非空时启用 |
||||
access-token: xxl-job |
||||
executor: |
||||
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册 |
||||
appname: xxl-job-executor |
||||
# 执行器端口号 执行器从9101开始往后写 |
||||
port: 9101 |
||||
# 执行器注册:默认IP:PORT |
||||
address: |
||||
# 执行器IP:默认自动获取IP |
||||
ip: |
||||
# 执行器运行日志文件存储磁盘路径 |
||||
logpath: ./logs/xxl-job |
||||
# 执行器日志文件保存天数:大于3生效 |
||||
logretentiondays: 30 |
||||
|
||||
--- # 数据源配置 |
||||
spring: |
||||
datasource: |
||||
type: com.zaxxer.hikari.HikariDataSource |
||||
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content |
||||
dynamic: |
||||
# 性能分析插件(有性能损耗 不建议生产环境使用) |
||||
p6spy: true |
||||
# 设置默认的数据源或者数据源组,默认值即为 master |
||||
primary: master |
||||
# 严格模式 匹配不到数据源则报错 |
||||
strict: true |
||||
datasource: |
||||
# # 主库数据源 |
||||
# master: |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: com.mysql.cj.jdbc.Driver |
||||
# # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 |
||||
# # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) |
||||
# url: jdbc:mysql://localhost:3306/ry-flowable-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true |
||||
# username: root |
||||
# password: root |
||||
# # 从库数据源 |
||||
# slave: |
||||
# lazy: true |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: com.mysql.cj.jdbc.Driver |
||||
# url: jdbc:mysql://localhost:3306/ry-flowable-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true |
||||
# username: |
||||
# password: |
||||
# oracle: |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: oracle.jdbc.OracleDriver |
||||
# url: jdbc:oracle:thin:@//localhost:1521/XE |
||||
# username: ROOT |
||||
# password: root |
||||
# hikari: |
||||
# connectionTestQuery: SELECT 1 FROM DUAL |
||||
# postgres: |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: org.postgresql.Driver |
||||
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true |
||||
# username: root |
||||
# password: root |
||||
master: |
||||
type: ${spring.datasource.type} |
||||
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver |
||||
url: jdbc:sqlserver://localhost:1433;DatabaseName=mh_flowable;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true |
||||
username: sa |
||||
password: mh@803 |
||||
hikari: |
||||
# 最大连接池数量 |
||||
maxPoolSize: 20 |
||||
# 最小空闲线程数量 |
||||
minIdle: 10 |
||||
# 配置获取连接等待超时的时间 |
||||
connectionTimeout: 30000 |
||||
# 校验超时时间 |
||||
validationTimeout: 5000 |
||||
# 空闲连接存活最大时间,默认10分钟 |
||||
idleTimeout: 600000 |
||||
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 |
||||
maxLifetime: 1800000 |
||||
# 连接测试query(配置检测连接是否有效) |
||||
connectionTestQuery: SELECT 1 |
||||
# 多久检查一次连接的活性 |
||||
keepaliveTime: 30000 |
||||
|
||||
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) |
||||
spring: |
||||
redis: |
||||
# 地址 |
||||
host: localhost |
||||
# 端口,默认为6379 |
||||
port: 6379 |
||||
# 数据库索引 |
||||
database: 0 |
||||
# 密码(如没有密码请注释掉) |
||||
# password: |
||||
# 连接超时时间 |
||||
timeout: 10s |
||||
# 是否开启ssl |
||||
ssl: false |
||||
|
||||
redisson: |
||||
# redis key前缀 |
||||
keyPrefix: |
||||
# 线程池数量 |
||||
threads: 4 |
||||
# Netty线程池数量 |
||||
nettyThreads: 8 |
||||
# 单节点配置 |
||||
singleServerConfig: |
||||
# 客户端名称 |
||||
clientName: ${ruoyi.name} |
||||
# 最小空闲连接数 |
||||
connectionMinimumIdleSize: 8 |
||||
# 连接池大小 |
||||
connectionPoolSize: 32 |
||||
# 连接空闲超时,单位:毫秒 |
||||
idleConnectionTimeout: 10000 |
||||
# 命令等待超时,单位:毫秒 |
||||
timeout: 3000 |
||||
# 发布和订阅连接池大小 |
||||
subscriptionConnectionPoolSize: 50 |
||||
|
||||
--- # mail 邮件发送 |
||||
mail: |
||||
enabled: false |
||||
host: smtp.163.com |
||||
port: 465 |
||||
# 是否需要用户名密码验证 |
||||
auth: true |
||||
# 发送方,遵循RFC-822标准 |
||||
from: xxx@163.com |
||||
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号) |
||||
user: xxx@163.com |
||||
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) |
||||
pass: xxxxxxxxxx |
||||
# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 |
||||
starttlsEnable: true |
||||
# 使用SSL安全连接 |
||||
sslEnable: true |
||||
# SMTP超时时长,单位毫秒,缺省值不超时 |
||||
timeout: 0 |
||||
# Socket连接超时值,单位毫秒,缺省值不超时 |
||||
connectionTimeout: 0 |
||||
|
||||
--- # sms 短信 |
||||
sms: |
||||
enabled: false |
||||
# 阿里云 dysmsapi.aliyuncs.com |
||||
# 腾讯云 sms.tencentcloudapi.com |
||||
endpoint: "dysmsapi.aliyuncs.com" |
||||
accessKeyId: xxxxxxx |
||||
accessKeySecret: xxxxxx |
||||
signName: 测试 |
||||
# 腾讯专用 |
||||
sdkAppId: |
@ -0,0 +1,174 @@
|
||||
--- # 临时文件存储位置 避免临时文件被系统清理报错 |
||||
spring.servlet.multipart.location: /ruoyi/server/temp |
||||
|
||||
--- # 监控中心配置 |
||||
spring.boot.admin.client: |
||||
# 增加客户端开关 |
||||
enabled: true |
||||
url: http://localhost:9090/admin |
||||
instance: |
||||
service-host-type: IP |
||||
username: ruoyi |
||||
password: 123456 |
||||
|
||||
--- # xxl-job 配置 |
||||
xxl.job: |
||||
# 执行器开关 |
||||
enabled: false |
||||
# 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。 |
||||
admin-addresses: http://localhost:9100/xxl-job-admin |
||||
# 执行器通讯TOKEN:非空时启用 |
||||
access-token: xxl-job |
||||
executor: |
||||
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册 |
||||
appname: xxl-job-executor |
||||
# 执行器端口号 执行器从9101开始往后写 |
||||
port: 9101 |
||||
# 执行器注册:默认IP:PORT |
||||
address: |
||||
# 执行器IP:默认自动获取IP |
||||
ip: |
||||
# 执行器运行日志文件存储磁盘路径 |
||||
logpath: ./logs/xxl-job |
||||
# 执行器日志文件保存天数:大于3生效 |
||||
logretentiondays: 30 |
||||
|
||||
--- # 数据源配置 |
||||
spring: |
||||
datasource: |
||||
type: com.zaxxer.hikari.HikariDataSource |
||||
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content |
||||
dynamic: |
||||
# 性能分析插件(有性能损耗 不建议生产环境使用) |
||||
p6spy: false |
||||
# 设置默认的数据源或者数据源组,默认值即为 master |
||||
primary: master |
||||
# 严格模式 匹配不到数据源则报错 |
||||
strict: true |
||||
datasource: |
||||
# # 主库数据源 |
||||
# master: |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: com.mysql.cj.jdbc.Driver |
||||
# # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 |
||||
# # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) |
||||
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true |
||||
# username: root |
||||
# password: root |
||||
# # 从库数据源 |
||||
# slave: |
||||
# lazy: true |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: com.mysql.cj.jdbc.Driver |
||||
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true |
||||
# username: |
||||
# password: |
||||
# oracle: |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: oracle.jdbc.OracleDriver |
||||
# url: jdbc:oracle:thin:@//localhost:1521/XE |
||||
# username: ROOT |
||||
# password: root |
||||
# hikari: |
||||
# connectionTestQuery: SELECT 1 FROM DUAL |
||||
# postgres: |
||||
# type: ${spring.datasource.type} |
||||
# driverClassName: org.postgresql.Driver |
||||
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true |
||||
# username: root |
||||
# password: root |
||||
master: |
||||
type: ${spring.datasource.type} |
||||
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver |
||||
url: jdbc:sqlserver://127.0.0.1:62012;DatabaseName=mh_flowable;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true |
||||
username: flowable |
||||
password: ulu33dHOiBE8ByOhJIrdAu2 |
||||
hikari: |
||||
# 最大连接池数量 |
||||
maxPoolSize: 20 |
||||
# 最小空闲线程数量 |
||||
minIdle: 10 |
||||
# 配置获取连接等待超时的时间 |
||||
connectionTimeout: 30000 |
||||
# 校验超时时间 |
||||
validationTimeout: 5000 |
||||
# 空闲连接存活最大时间,默认10分钟 |
||||
idleTimeout: 600000 |
||||
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 |
||||
maxLifetime: 1800000 |
||||
# 连接测试query(配置检测连接是否有效) |
||||
connectionTestQuery: SELECT 1 |
||||
# 多久检查一次连接的活性 |
||||
keepaliveTime: 30000 |
||||
|
||||
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) |
||||
spring: |
||||
redis: |
||||
# 地址 |
||||
host: localhost |
||||
# 端口,默认为6379 |
||||
port: 6379 |
||||
# 数据库索引 |
||||
database: 0 |
||||
# 密码(如没有密码请注释掉) |
||||
# password: |
||||
# 连接超时时间 |
||||
timeout: 10s |
||||
# 是否开启ssl |
||||
ssl: false |
||||
|
||||
redisson: |
||||
# redis key前缀 |
||||
keyPrefix: |
||||
# 线程池数量 |
||||
threads: 16 |
||||
# Netty线程池数量 |
||||
nettyThreads: 32 |
||||
# 单节点配置 |
||||
singleServerConfig: |
||||
# 客户端名称 |
||||
clientName: ${ruoyi.name} |
||||
# 最小空闲连接数 |
||||
connectionMinimumIdleSize: 32 |
||||
# 连接池大小 |
||||
connectionPoolSize: 64 |
||||
# 连接空闲超时,单位:毫秒 |
||||
idleConnectionTimeout: 10000 |
||||
# 命令等待超时,单位:毫秒 |
||||
timeout: 3000 |
||||
# 发布和订阅连接池大小 |
||||
subscriptionConnectionPoolSize: 50 |
||||
|
||||
--- # mail 邮件发送 |
||||
mail: |
||||
enabled: false |
||||
host: smtp.163.com |
||||
port: 465 |
||||
# 是否需要用户名密码验证 |
||||
auth: true |
||||
# 发送方,遵循RFC-822标准 |
||||
from: xxx@163.com |
||||
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号) |
||||
user: xxx@163.com |
||||
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) |
||||
pass: xxxxxxxxxx |
||||
# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 |
||||
starttlsEnable: true |
||||
# 使用SSL安全连接 |
||||
sslEnable: true |
||||
# SMTP超时时长,单位毫秒,缺省值不超时 |
||||
timeout: 0 |
||||
# Socket连接超时值,单位毫秒,缺省值不超时 |
||||
connectionTimeout: 0 |
||||
|
||||
--- # sms 短信 |
||||
sms: |
||||
enabled: false |
||||
# 阿里云 dysmsapi.aliyuncs.com |
||||
# 腾讯云 sms.tencentcloudapi.com |
||||
endpoint: "dysmsapi.aliyuncs.com" |
||||
accessKeyId: xxxxxxx |
||||
accessKeySecret: xxxxxx |
||||
signName: 测试 |
||||
# 腾讯专用 |
||||
sdkAppId: |
@ -0,0 +1,287 @@
|
||||
# 项目相关配置 |
||||
ruoyi: |
||||
# 名称 |
||||
name: MH-Flowable-Plus |
||||
# 版本 |
||||
version: ${ruoyi-flowable-plus.version} |
||||
# 版权年份 |
||||
copyrightYear: 2024 |
||||
# 实例演示开关 |
||||
demoEnabled: true |
||||
# 获取ip地址开关 |
||||
addressEnabled: true |
||||
# 缓存懒加载 |
||||
cacheLazy: false |
||||
|
||||
captcha: |
||||
# 页面 <参数设置> 可开启关闭 验证码校验 |
||||
# 验证码类型 math 数组计算 char 字符验证 |
||||
type: MATH |
||||
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 |
||||
category: CIRCLE |
||||
# 数字验证码位数 |
||||
numberLength: 1 |
||||
# 字符验证码长度 |
||||
charLength: 4 |
||||
|
||||
# 开发环境配置 |
||||
server: |
||||
# 服务器的HTTP端口,默认为8080 |
||||
port: 8080 |
||||
servlet: |
||||
# 应用的访问路径 |
||||
context-path: / |
||||
# undertow 配置 |
||||
undertow: |
||||
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 |
||||
max-http-post-size: -1 |
||||
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 |
||||
# 每块buffer的空间大小,越小的空间被利用越充分 |
||||
buffer-size: 512 |
||||
# 是否分配的直接内存 |
||||
direct-buffers: true |
||||
threads: |
||||
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 |
||||
io: 8 |
||||
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 |
||||
worker: 256 |
||||
|
||||
# 日志配置 |
||||
logging: |
||||
level: |
||||
com.ruoyi: @logging.level@ |
||||
org.springframework: warn |
||||
config: classpath:logback-plus.xml |
||||
|
||||
# 用户配置 |
||||
user: |
||||
password: |
||||
# 密码最大错误次数 |
||||
maxRetryCount: 5 |
||||
# 密码锁定时间(默认10分钟) |
||||
lockTime: 10 |
||||
|
||||
# Spring配置 |
||||
spring: |
||||
application: |
||||
name: ${ruoyi.name} |
||||
# 资源信息 |
||||
messages: |
||||
# 国际化资源文件路径 |
||||
basename: i18n/messages |
||||
profiles: |
||||
active: prod |
||||
# 文件上传 |
||||
servlet: |
||||
multipart: |
||||
# 单个文件大小 |
||||
max-file-size: 10MB |
||||
# 设置总上传的文件大小 |
||||
max-request-size: 20MB |
||||
# 服务模块 |
||||
devtools: |
||||
restart: |
||||
# 热部署开关 |
||||
enabled: true |
||||
mvc: |
||||
format: |
||||
date-time: yyyy-MM-dd HH:mm:ss |
||||
jackson: |
||||
# 日期格式化 |
||||
date-format: yyyy-MM-dd HH:mm:ss |
||||
serialization: |
||||
# 格式化输出 |
||||
indent_output: false |
||||
# 忽略无法转换的对象 |
||||
fail_on_empty_beans: false |
||||
deserialization: |
||||
# 允许对象忽略json中不存在的属性 |
||||
fail_on_unknown_properties: false |
||||
|
||||
# Sa-Token配置 |
||||
sa-token: |
||||
# token名称 (同时也是cookie名称) |
||||
token-name: Authorization |
||||
# token有效期 设为一天 (必定过期) 单位: 秒 |
||||
timeout: 86400 |
||||
# token临时有效期 (指定时间无操作就过期) 单位: 秒 |
||||
activity-timeout: 1800 |
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) |
||||
is-concurrent: true |
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) |
||||
is-share: false |
||||
# 是否尝试从header里读取token |
||||
is-read-header: true |
||||
# 是否尝试从cookie里读取token |
||||
is-read-cookie: false |
||||
# token前缀 |
||||
token-prefix: "Bearer" |
||||
# jwt秘钥 |
||||
jwt-secret-key: abcdefghijklmnopqrstuvwxyz |
||||
|
||||
# security配置 |
||||
security: |
||||
# 排除路径 |
||||
excludes: |
||||
# 静态资源 |
||||
- /*.html |
||||
- /**/*.html |
||||
- /**/*.css |
||||
- /**/*.js |
||||
# 公共路径 |
||||
- /favicon.ico |
||||
- /error |
||||
# swagger 文档配置 |
||||
- /*/api-docs |
||||
- /*/api-docs/** |
||||
# actuator 监控配置 |
||||
- /actuator |
||||
- /actuator/** |
||||
|
||||
# MyBatisPlus配置 |
||||
# https://baomidou.com/config/ |
||||
mybatis-plus: |
||||
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级 |
||||
# 例如 com.**.**.mapper |
||||
mapperPackage: com.ruoyi.**.mapper |
||||
# 对应的 XML 文件位置 |
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml |
||||
# 实体扫描,多个package用逗号或者分号分隔 |
||||
typeAliasesPackage: com.ruoyi.**.domain |
||||
# 启动时是否检查 MyBatis XML 文件的存在,默认不检查 |
||||
checkConfigLocation: false |
||||
configuration: |
||||
# 自动驼峰命名规则(camel case)映射 |
||||
mapUnderscoreToCamelCase: true |
||||
# MyBatis 自动映射策略 |
||||
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射 |
||||
autoMappingBehavior: PARTIAL |
||||
# MyBatis 自动映射时未知列或未知属性处理策 |
||||
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息 |
||||
autoMappingUnknownColumnBehavior: NONE |
||||
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl |
||||
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl |
||||
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl |
||||
logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl |
||||
global-config: |
||||
# 是否打印 Logo banner |
||||
banner: true |
||||
dbConfig: |
||||
# 主键类型 |
||||
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID |
||||
idType: ASSIGN_ID |
||||
# 逻辑已删除值 |
||||
logicDeleteValue: 2 |
||||
# 逻辑未删除值 |
||||
logicNotDeleteValue: 0 |
||||
# 字段验证策略之 insert,在 insert 的时候的字段验证策略 |
||||
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL |
||||
insertStrategy: NOT_NULL |
||||
# 字段验证策略之 update,在 update 的时候的字段验证策略 |
||||
updateStrategy: NOT_NULL |
||||
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件 |
||||
where-strategy: NOT_NULL |
||||
|
||||
# 数据加密 |
||||
mybatis-encryptor: |
||||
# 是否开启加密 |
||||
enable: false |
||||
# 默认加密算法 |
||||
algorithm: BASE64 |
||||
# 编码方式 BASE64/HEX。默认BASE64 |
||||
encode: BASE64 |
||||
# 安全秘钥 对称算法的秘钥 如:AES,SM4 |
||||
password: |
||||
# 公私钥 非对称算法的公私钥 如:SM2,RSA |
||||
publicKey: |
||||
privateKey: |
||||
|
||||
# Swagger配置 |
||||
swagger: |
||||
info: |
||||
# 标题 |
||||
title: '标题:${ruoyi.name}后台管理系统_接口文档' |
||||
# 描述 |
||||
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...' |
||||
# 版本 |
||||
version: '版本号: ${ruoyi-flowable-plus.version}' |
||||
# 作者信息 |
||||
contact: |
||||
name: mh |
||||
email: 1527468660@qq.com |
||||
url: https://gitee.com/KonBAI-Q/ruoyi-flowable-plus |
||||
components: |
||||
# 鉴权方式配置 |
||||
security-schemes: |
||||
apiKey: |
||||
type: APIKEY |
||||
in: HEADER |
||||
name: ${sa-token.token-name} |
||||
|
||||
springdoc: |
||||
api-docs: |
||||
# 是否开启接口文档 |
||||
enabled: true |
||||
swagger-ui: |
||||
# 持久化认证数据 |
||||
persistAuthorization: true |
||||
#这里定义了两个分组,可定义多个,也可以不定义 |
||||
group-configs: |
||||
- group: 1.演示模块 |
||||
packages-to-scan: com.ruoyi.demo |
||||
- group: 2.系统模块 |
||||
packages-to-scan: com.ruoyi.web |
||||
- group: 3.代码生成模块 |
||||
packages-to-scan: com.ruoyi.generator |
||||
|
||||
# 防止XSS攻击 |
||||
xss: |
||||
# 过滤开关 |
||||
enabled: true |
||||
# 排除链接(多个用逗号分隔) |
||||
excludes: /system/notice |
||||
# 匹配链接 |
||||
urlPatterns: /system/*,/monitor/*,/tool/* |
||||
|
||||
# 全局线程池相关配置 |
||||
thread-pool: |
||||
# 是否开启线程池 |
||||
enabled: false |
||||
# 队列最大长度 |
||||
queueCapacity: 128 |
||||
# 线程池维护线程所允许的空闲时间 |
||||
keepAliveSeconds: 300 |
||||
|
||||
--- # 分布式锁 lock4j 全局配置 |
||||
lock4j: |
||||
# 获取分布式锁超时时间,默认为 3000 毫秒 |
||||
acquire-timeout: 3000 |
||||
# 分布式锁的超时时间,默认为 30 秒 |
||||
expire: 30000 |
||||
|
||||
--- # Actuator 监控端点的配置项 |
||||
management: |
||||
endpoints: |
||||
web: |
||||
exposure: |
||||
include: '*' |
||||
endpoint: |
||||
health: |
||||
show-details: ALWAYS |
||||
logfile: |
||||
external-file: ./logs/sys-console.log |
||||
|
||||
--- # Flowable 配置 |
||||
flowable: |
||||
# 关闭定时任务 job |
||||
async-executor-activate: false |
||||
# 库与数据库表结构不一致时,会自动将数据库表结构升级至新版本。 |
||||
database-schema-update: true |
||||
idm: |
||||
# 关闭idm引擎 数据库不会创建act_id_*表,流程流转不会使用act_id_*相关的表 |
||||
enabled: false |
||||
# 关闭流程定义文件自动检查 |
||||
check-process-definitions: false |
||||
# 关闭历史任务定时任务job |
||||
async-history-executor-activate: false |
||||
|
@ -0,0 +1,7 @@
|
||||
____ __ __ _ _____ _ _ _ ____ _ |
||||
| _ \ _ _ ___\ \ / /(_) | ___|| | ___ __ __ __ _ | |__ | | ___ | _ \ | | _ _ ___ |
||||
| |_) || | | | / _ \\ V / | | | |_ | | / _ \\ \ /\ / // _` || '_ \ | | / _ \ | |_) || || | | |/ __| |
||||
| _ < | |_| || (_) || | | | | _| | || (_) |\ V V /| (_| || |_) || || __/ | __/ | || |_| |\__ \ |
||||
|_| \_\ \__,_| \___/ |_| |_| |_| |_| \___/ \_/\_/ \__,_||_.__/ |_| \___| |_| |_| \__,_||___/ |
||||
|
||||
${AnsiColor.GREEN} :: RuoYi :: ${AnsiColor.BLUE} RuoYi-Flowable-Plus:${AnsiColor.RED}${spring.profiles.active}${AnsiColor.BRIGHT_WHITE} :: Application Version: ${ruoyi-flowable-plus.version} ${spring-boot.formatted-version} |
@ -0,0 +1,49 @@
|
||||
#错误消息 |
||||
not.null=* 必须填写 |
||||
user.jcaptcha.error=验证码错误 |
||||
user.jcaptcha.expire=验证码已失效 |
||||
user.not.exists=对不起, 您的账号:{0} 不存在. |
||||
user.password.not.match=用户不存在/密码错误 |
||||
user.password.retry.limit.count=密码输入错误{0}次 |
||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 |
||||
user.password.delete=对不起,您的账号:{0} 已被删除 |
||||
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员 |
||||
role.blocked=角色已封禁,请联系管理员 |
||||
user.logout.success=退出成功 |
||||
length.not.valid=长度必须在{min}到{max}个字符之间 |
||||
user.username.not.blank=用户名不能为空 |
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 |
||||
user.username.length.valid=账户长度必须在{min}到{max}个字符之间 |
||||
user.password.not.blank=用户密码不能为空 |
||||
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 |
||||
user.password.not.valid=* 5-50个字符 |
||||
user.email.not.valid=邮箱格式错误 |
||||
user.email.not.blank=邮箱不能为空 |
||||
user.phonenumber.not.blank=用户手机号不能为空 |
||||
user.mobile.phone.number.not.valid=手机号格式错误 |
||||
user.login.success=登录成功 |
||||
user.register.success=注册成功 |
||||
user.register.save.error=保存用户 {0} 失败,注册账号已存在 |
||||
user.register.error=注册失败,请联系系统管理人员 |
||||
user.notfound=请重新登录 |
||||
user.forcelogout=管理员强制退出,请重新登录 |
||||
user.unknown.error=未知错误,请重新登录 |
||||
##文件上传消息 |
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! |
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符 |
||||
##权限 |
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] |
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] |
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] |
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] |
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] |
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] |
||||
repeat.submit.message=不允许重复提交,请稍候再试 |
||||
rate.limiter.message=访问过于频繁,请稍候再试 |
||||
sms.code.not.blank=短信验证码不能为空 |
||||
sms.code.retry.limit.count=短信验证码输入错误{0}次 |
||||
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 |
||||
email.code.not.blank=邮箱验证码不能为空 |
||||
email.code.retry.limit.count=邮箱验证码输入错误{0}次 |
||||
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 |
||||
xcx.code.not.blank=小程序code不能为空 |
@ -0,0 +1,49 @@
|
||||
#错误消息 |
||||
not.null=* Required fill in |
||||
user.jcaptcha.error=Captcha error |
||||
user.jcaptcha.expire=Captcha invalid |
||||
user.not.exists=Sorry, your account: {0} does not exist |
||||
user.password.not.match=User does not exist/Password error |
||||
user.password.retry.limit.count=Password input error {0} times |
||||
user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes |
||||
user.password.delete=Sorry, your account:{0} has been deleted |
||||
user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator |
||||
role.blocked=Role disabled,please contact administrators |
||||
user.logout.success=Exit successful |
||||
length.not.valid=The length must be between {min} and {max} characters |
||||
user.username.not.blank=Username cannot be blank |
||||
user.username.not.valid=* 2 to 20 chinese characters, letters, numbers or underscores, and must start with a non number |
||||
user.username.length.valid=Account length must be between {min} and {max} characters |
||||
user.password.not.blank=Password cannot be empty |
||||
user.password.length.valid=Password length must be between {min} and {max} characters |
||||
user.password.not.valid=* 5-50 characters |
||||
user.email.not.valid=Mailbox format error |
||||
user.email.not.blank=Mailbox cannot be blank |
||||
user.phonenumber.not.blank=Phone number cannot be blank |
||||
user.mobile.phone.number.not.valid=Phone number format error |
||||
user.login.success=Login successful |
||||
user.register.success=Register successful |
||||
user.register.save.error=Failed to save user {0}, The registered account already exists |
||||
user.register.error=Register failed, please contact system administrator |
||||
user.notfound=Please login again |
||||
user.forcelogout=The administrator is forced to exit,please login again |
||||
user.unknown.error=Unknown error, please login again |
||||
##文件上传消息 |
||||
upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is:{0}MB! |
||||
upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters |
||||
##权限 |
||||
no.permission=You do not have permission to the data,please contact your administrator to add permissions [{0}] |
||||
no.create.permission=You do not have permission to create data,please contact your administrator to add permissions [{0}] |
||||
no.update.permission=You do not have permission to modify data,please contact your administrator to add permissions [{0}] |
||||
no.delete.permission=You do not have permission to delete data,please contact your administrator to add permissions [{0}] |
||||
no.export.permission=You do not have permission to export data,please contact your administrator to add permissions [{0}] |
||||
no.view.permission=You do not have permission to view data,please contact your administrator to add permissions [{0}] |
||||
repeat.submit.message=Repeat submit is not allowed, please try again later |
||||
rate.limiter.message=Visit too frequently, please try again later |
||||
sms.code.not.blank=Sms code cannot be blank |
||||
sms.code.retry.limit.count=Sms code input error {0} times |
||||
sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes |
||||
email.code.not.blank=Email code cannot be blank |
||||
email.code.retry.limit.count=Email code input error {0} times |
||||
email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes |
||||
xcx.code.not.blank=Mini program code cannot be blank |
@ -0,0 +1,49 @@
|
||||
#错误消息 |
||||
not.null=* 必须填写 |
||||
user.jcaptcha.error=验证码错误 |
||||
user.jcaptcha.expire=验证码已失效 |
||||
user.not.exists=对不起, 您的账号:{0} 不存在. |
||||
user.password.not.match=用户不存在/密码错误 |
||||
user.password.retry.limit.count=密码输入错误{0}次 |
||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 |
||||
user.password.delete=对不起,您的账号:{0} 已被删除 |
||||
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员 |
||||
role.blocked=角色已封禁,请联系管理员 |
||||
user.logout.success=退出成功 |
||||
length.not.valid=长度必须在{min}到{max}个字符之间 |
||||
user.username.not.blank=用户名不能为空 |
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 |
||||
user.username.length.valid=账户长度必须在{min}到{max}个字符之间 |
||||
user.password.not.blank=用户密码不能为空 |
||||
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 |
||||
user.password.not.valid=* 5-50个字符 |
||||
user.email.not.valid=邮箱格式错误 |
||||
user.email.not.blank=邮箱不能为空 |
||||
user.phonenumber.not.blank=用户手机号不能为空 |
||||
user.mobile.phone.number.not.valid=手机号格式错误 |
||||
user.login.success=登录成功 |
||||
user.register.success=注册成功 |
||||
user.register.save.error=保存用户 {0} 失败,注册账号已存在 |
||||
user.register.error=注册失败,请联系系统管理人员 |
||||
user.notfound=请重新登录 |
||||
user.forcelogout=管理员强制退出,请重新登录 |
||||
user.unknown.error=未知错误,请重新登录 |
||||
##文件上传消息 |
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! |
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符 |
||||
##权限 |
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] |
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] |
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] |
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] |
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] |
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] |
||||
repeat.submit.message=不允许重复提交,请稍候再试 |
||||
rate.limiter.message=访问过于频繁,请稍候再试 |
||||
sms.code.not.blank=短信验证码不能为空 |
||||
sms.code.retry.limit.count=短信验证码输入错误{0}次 |
||||
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 |
||||
email.code.not.blank=邮箱验证码不能为空 |
||||
email.code.retry.limit.count=邮箱验证码输入错误{0}次 |
||||
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 |
||||
xcx.code.not.blank=小程序code不能为空 |
Binary file not shown.
@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<configuration> |
||||
<property name="log.path" value="./logs"/> |
||||
<property name="console.log.pattern" |
||||
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/> |
||||
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/> |
||||
|
||||
<!-- 控制台输出 --> |
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
||||
<encoder> |
||||
<pattern>${console.log.pattern}</pattern> |
||||
<charset>utf-8</charset> |
||||
</encoder> |
||||
</appender> |
||||
|
||||
<!-- 控制台输出 --> |
||||
<appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
<file>${log.path}/sys-console.log</file> |
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
||||
<!-- 日志文件名格式 --> |
||||
<fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern> |
||||
<!-- 日志最大 1天 --> |
||||
<maxHistory>1</maxHistory> |
||||
</rollingPolicy> |
||||
<encoder> |
||||
<pattern>${log.pattern}</pattern> |
||||
<charset>utf-8</charset> |
||||
</encoder> |
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
||||
<!-- 过滤的级别 --> |
||||
<level>INFO</level> |
||||
</filter> |
||||
</appender> |
||||
|
||||
<!-- 系统日志输出 --> |
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
<file>${log.path}/sys-info.log</file> |
||||
<!-- 循环政策:基于时间创建日志文件 --> |
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
||||
<!-- 日志文件名格式 --> |
||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> |
||||
<!-- 日志最大的历史 60天 --> |
||||
<maxHistory>60</maxHistory> |
||||
</rollingPolicy> |
||||
<encoder> |
||||
<pattern>${log.pattern}</pattern> |
||||
</encoder> |
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> |
||||
<!-- 过滤的级别 --> |
||||
<level>INFO</level> |
||||
<!-- 匹配时的操作:接收(记录) --> |
||||
<onMatch>ACCEPT</onMatch> |
||||
<!-- 不匹配时的操作:拒绝(不记录) --> |
||||
<onMismatch>DENY</onMismatch> |
||||
</filter> |
||||
</appender> |
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
<file>${log.path}/sys-error.log</file> |
||||
<!-- 循环政策:基于时间创建日志文件 --> |
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
||||
<!-- 日志文件名格式 --> |
||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> |
||||
<!-- 日志最大的历史 60天 --> |
||||
<maxHistory>60</maxHistory> |
||||
</rollingPolicy> |
||||
<encoder> |
||||
<pattern>${log.pattern}</pattern> |
||||
</encoder> |
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> |
||||
<!-- 过滤的级别 --> |
||||
<level>ERROR</level> |
||||
<!-- 匹配时的操作:接收(记录) --> |
||||
<onMatch>ACCEPT</onMatch> |
||||
<!-- 不匹配时的操作:拒绝(不记录) --> |
||||
<onMismatch>DENY</onMismatch> |
||||
</filter> |
||||
</appender> |
||||
|
||||
<!-- info异步输出 --> |
||||
<appender name="async_info" class="ch.qos.logback.classic.AsyncAppender"> |
||||
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> |
||||
<discardingThreshold>0</discardingThreshold> |
||||
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> |
||||
<queueSize>512</queueSize> |
||||
<!-- 添加附加的appender,最多只能添加一个 --> |
||||
<appender-ref ref="file_info"/> |
||||
</appender> |
||||
|
||||
<!-- error异步输出 --> |
||||
<appender name="async_error" class="ch.qos.logback.classic.AsyncAppender"> |
||||
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> |
||||
<discardingThreshold>0</discardingThreshold> |
||||
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> |
||||
<queueSize>512</queueSize> |
||||
<!-- 添加附加的appender,最多只能添加一个 --> |
||||
<appender-ref ref="file_error"/> |
||||
</appender> |
||||
|
||||
<!-- 整合 skywalking 控制台输出 tid --> |
||||
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">--> |
||||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> |
||||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> |
||||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> |
||||
<!-- </layout>--> |
||||
<!-- <charset>utf-8</charset>--> |
||||
<!-- </encoder>--> |
||||
<!-- </appender>--> |
||||
|
||||
<!-- 整合 skywalking 推送采集日志 --> |
||||
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">--> |
||||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> |
||||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> |
||||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> |
||||
<!-- </layout>--> |
||||
<!-- <charset>utf-8</charset>--> |
||||
<!-- </encoder>--> |
||||
<!-- </appender>--> |
||||
|
||||
<!--系统操作日志--> |
||||
<root level="info"> |
||||
<appender-ref ref="console" /> |
||||
<appender-ref ref="async_info" /> |
||||
<appender-ref ref="async_error" /> |
||||
<appender-ref ref="file_console" /> |
||||
<!-- <appender-ref ref="sky_log"/>--> |
||||
</root> |
||||
|
||||
</configuration> |
@ -0,0 +1,28 @@
|
||||
# p6spy 性能分析插件配置文件 |
||||
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory |
||||
# 自定义日志打印 |
||||
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger |
||||
#日志输出到控制台 |
||||
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger |
||||
# 使用日志系统记录 sql |
||||
#appender=com.p6spy.engine.spy.appender.Slf4JLogger |
||||
# 设置 p6spy driver 代理 |
||||
#deregisterdrivers=true |
||||
# 取消JDBC URL前缀 |
||||
useprefix=true |
||||
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. |
||||
excludecategories=info,debug,result,commit,resultset |
||||
# 日期格式 |
||||
dateformat=yyyy-MM-dd HH:mm:ss |
||||
# SQL语句打印时间格式 |
||||
databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss |
||||
# 实际驱动可多个 |
||||
#driverlist=org.h2.Driver |
||||
# 是否开启慢SQL记录 |
||||
outagedetection=true |
||||
# 慢SQL记录标准 2 秒 |
||||
outagedetectioninterval=2 |
||||
# 是否过滤 Log |
||||
filter=true |
||||
# 过滤 Log 时所排除的 sql 关键字,以逗号分隔 |
||||
exclude=SELECT 1 |
@ -0,0 +1,45 @@
|
||||
package com.ruoyi.test; |
||||
|
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.DisplayName; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
/** |
||||
* 断言单元测试案例 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@DisplayName("断言单元测试案例") |
||||
public class AssertUnitTest { |
||||
|
||||
@DisplayName("测试 assertEquals 方法") |
||||
@Test |
||||
public void testAssertEquals() { |
||||
Assertions.assertEquals("666", new String("666")); |
||||
Assertions.assertNotEquals("666", new String("666")); |
||||
} |
||||
|
||||
@DisplayName("测试 assertSame 方法") |
||||
@Test |
||||
public void testAssertSame() { |
||||
Object obj = new Object(); |
||||
Object obj1 = obj; |
||||
Assertions.assertSame(obj, obj1); |
||||
Assertions.assertNotSame(obj, obj1); |
||||
} |
||||
|
||||
@DisplayName("测试 assertTrue 方法") |
||||
@Test |
||||
public void testAssertTrue() { |
||||
Assertions.assertTrue(true); |
||||
Assertions.assertFalse(true); |
||||
} |
||||
|
||||
@DisplayName("测试 assertNull 方法") |
||||
@Test |
||||
public void testAssertNull() { |
||||
Assertions.assertNull(null); |
||||
Assertions.assertNotNull(null); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,70 @@
|
||||
package com.ruoyi.test; |
||||
|
||||
import com.ruoyi.common.config.RuoYiConfig; |
||||
import org.junit.jupiter.api.*; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
/** |
||||
* 单元测试案例 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件
|
||||
@DisplayName("单元测试案例") |
||||
public class DemoUnitTest { |
||||
|
||||
@Autowired |
||||
private RuoYiConfig ruoYiConfig; |
||||
|
||||
@DisplayName("测试 @SpringBootTest @Test @DisplayName 注解") |
||||
@Test |
||||
public void testTest() { |
||||
System.out.println(ruoYiConfig); |
||||
} |
||||
|
||||
@Disabled |
||||
@DisplayName("测试 @Disabled 注解") |
||||
@Test |
||||
public void testDisabled() { |
||||
System.out.println(ruoYiConfig); |
||||
} |
||||
|
||||
@Timeout(value = 2L, unit = TimeUnit.SECONDS) |
||||
@DisplayName("测试 @Timeout 注解") |
||||
@Test |
||||
public void testTimeout() throws InterruptedException { |
||||
Thread.sleep(3000); |
||||
System.out.println(ruoYiConfig); |
||||
} |
||||
|
||||
|
||||
@DisplayName("测试 @RepeatedTest 注解") |
||||
@RepeatedTest(3) |
||||
public void testRepeatedTest() { |
||||
System.out.println(666); |
||||
} |
||||
|
||||
@BeforeAll |
||||
public static void testBeforeAll() { |
||||
System.out.println("@BeforeAll =================="); |
||||
} |
||||
|
||||
@BeforeEach |
||||
public void testBeforeEach() { |
||||
System.out.println("@BeforeEach =================="); |
||||
} |
||||
|
||||
@AfterEach |
||||
public void testAfterEach() { |
||||
System.out.println("@AfterEach =================="); |
||||
} |
||||
|
||||
@AfterAll |
||||
public static void testAfterAll() { |
||||
System.out.println("@AfterAll =================="); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,72 @@
|
||||
package com.ruoyi.test; |
||||
|
||||
import com.ruoyi.common.enums.UserType; |
||||
import org.junit.jupiter.api.AfterEach; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.DisplayName; |
||||
import org.junit.jupiter.params.ParameterizedTest; |
||||
import org.junit.jupiter.params.provider.EnumSource; |
||||
import org.junit.jupiter.params.provider.MethodSource; |
||||
import org.junit.jupiter.params.provider.NullSource; |
||||
import org.junit.jupiter.params.provider.ValueSource; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.stream.Stream; |
||||
|
||||
/** |
||||
* 带参数单元测试案例 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@DisplayName("带参数单元测试案例") |
||||
public class ParamUnitTest { |
||||
|
||||
@DisplayName("测试 @ValueSource 注解") |
||||
@ParameterizedTest |
||||
@ValueSource(strings = {"t1", "t2", "t3"}) |
||||
public void testValueSource(String str) { |
||||
System.out.println(str); |
||||
} |
||||
|
||||
@DisplayName("测试 @NullSource 注解") |
||||
@ParameterizedTest |
||||
@NullSource |
||||
public void testNullSource(String str) { |
||||
System.out.println(str); |
||||
} |
||||
|
||||
@DisplayName("测试 @EnumSource 注解") |
||||
@ParameterizedTest |
||||
@EnumSource(UserType.class) |
||||
public void testEnumSource(UserType type) { |
||||
System.out.println(type.getUserType()); |
||||
} |
||||
|
||||
@DisplayName("测试 @MethodSource 注解") |
||||
@ParameterizedTest |
||||
@MethodSource("getParam") |
||||
public void testMethodSource(String str) { |
||||
System.out.println(str); |
||||
} |
||||
|
||||
public static Stream<String> getParam() { |
||||
List<String> list = new ArrayList<>(); |
||||
list.add("t1"); |
||||
list.add("t2"); |
||||
list.add("t3"); |
||||
return list.stream(); |
||||
} |
||||
|
||||
@BeforeEach |
||||
public void testBeforeEach() { |
||||
System.out.println("@BeforeEach =================="); |
||||
} |
||||
|
||||
@AfterEach |
||||
public void testAfterEach() { |
||||
System.out.println("@AfterEach =================="); |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.ruoyi.test; |
||||
|
||||
import org.junit.jupiter.api.*; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
||||
/** |
||||
* 标签单元测试案例 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@SpringBootTest |
||||
@DisplayName("标签单元测试案例") |
||||
public class TagUnitTest { |
||||
|
||||
@Tag("dev") |
||||
@DisplayName("测试 @Tag dev") |
||||
@Test |
||||
public void testTagDev() { |
||||
System.out.println("dev"); |
||||
} |
||||
|
||||
@Tag("prod") |
||||
@DisplayName("测试 @Tag prod") |
||||
@Test |
||||
public void testTagProd() { |
||||
System.out.println("prod"); |
||||
} |
||||
|
||||
@Tag("local") |
||||
@DisplayName("测试 @Tag local") |
||||
@Test |
||||
public void testTagLocal() { |
||||
System.out.println("local"); |
||||
} |
||||
|
||||
@Tag("exclude") |
||||
@DisplayName("测试 @Tag exclude") |
||||
@Test |
||||
public void testTagExclude() { |
||||
System.out.println("exclude"); |
||||
} |
||||
|
||||
@BeforeEach |
||||
public void testBeforeEach() { |
||||
System.out.println("@BeforeEach =================="); |
||||
} |
||||
|
||||
@AfterEach |
||||
public void testAfterEach() { |
||||
System.out.println("@AfterEach =================="); |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<parent> |
||||
<artifactId>ruoyi-flowable-plus</artifactId> |
||||
<groupId>com.ruoyi</groupId> |
||||
<version>0.8.3</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>ruoyi-common</artifactId> |
||||
|
||||
<description> |
||||
common通用工具 |
||||
</description> |
||||
|
||||
<dependencies> |
||||
|
||||
<!-- Spring框架基本的核心工具 --> |
||||
<dependency> |
||||
<groupId>org.springframework</groupId> |
||||
<artifactId>spring-context-support</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- SpringWeb模块 --> |
||||
<dependency> |
||||
<groupId>org.springframework</groupId> |
||||
<artifactId>spring-web</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ --> |
||||
<dependency> |
||||
<groupId>cn.dev33</groupId> |
||||
<artifactId>sa-token-spring-boot-starter</artifactId> |
||||
</dependency> |
||||
<!-- Sa-Token 整合 jwt --> |
||||
<dependency> |
||||
<groupId>cn.dev33</groupId> |
||||
<artifactId>sa-token-jwt</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- 自定义验证注解 --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-validation</artifactId> |
||||
</dependency> |
||||
|
||||
<!--常用工具类 --> |
||||
<dependency> |
||||
<groupId>org.apache.commons</groupId> |
||||
<artifactId>commons-lang3</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- JSON工具类 --> |
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-databind</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>easyexcel</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- yml解析器 --> |
||||
<dependency> |
||||
<groupId>org.yaml</groupId> |
||||
<artifactId>snakeyaml</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- servlet包 --> |
||||
<dependency> |
||||
<groupId>javax.servlet</groupId> |
||||
<artifactId>javax.servlet-api</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- dynamic-datasource 多数据源--> |
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-core</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-http</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-captcha</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-jwt</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>cn.hutool</groupId> |
||||
<artifactId>hutool-extra</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.sun.mail</groupId> |
||||
<artifactId>jakarta.mail</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.projectlombok</groupId> |
||||
<artifactId>lombok</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springdoc</groupId> |
||||
<artifactId>springdoc-openapi-webmvc-core</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springdoc</groupId> |
||||
<artifactId>springdoc-openapi-javadoc</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- 自动生成YML配置关联JSON文件 --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-configuration-processor</artifactId> |
||||
</dependency> |
||||
|
||||
<!--redisson--> |
||||
<dependency> |
||||
<groupId>org.redisson</groupId> |
||||
<artifactId>redisson-spring-boot-starter</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.redisson</groupId> |
||||
<artifactId>redisson-spring-data-27</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- 加密包引入 --> |
||||
<dependency> |
||||
<groupId>org.bouncycastle</groupId> |
||||
<artifactId>bcprov-jdk15to18</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- 离线IP地址定位库 --> |
||||
<dependency> |
||||
<groupId>org.lionsoul</groupId> |
||||
<artifactId>ip2region</artifactId> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
|
||||
</project> |
@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.ruoyi.common.excel.CellMergeStrategy; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* excel 列单元格合并(合并列相同项) |
||||
* |
||||
* 需搭配 {@link CellMergeStrategy} 策略使用 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Target(ElementType.FIELD) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Inherited |
||||
public @interface CellMerge { |
||||
|
||||
/** |
||||
* col index |
||||
*/ |
||||
int index() default -1; |
||||
|
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 数据权限 |
||||
* |
||||
* 一个注解只能对应一个模板 |
||||
* |
||||
* @author Lion Li |
||||
* @version 3.5.0 |
||||
*/ |
||||
@Target(ElementType.METHOD) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface DataColumn { |
||||
|
||||
/** |
||||
* 占位符关键字 |
||||
*/ |
||||
String[] key() default "deptName"; |
||||
|
||||
/** |
||||
* 占位符替换值 |
||||
*/ |
||||
String[] value() default "dept_id"; |
||||
|
||||
} |
@ -0,0 +1,18 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 数据权限组 |
||||
* |
||||
* @author Lion Li |
||||
* @version 3.5.0 |
||||
*/ |
||||
@Target({ElementType.METHOD, ElementType.TYPE}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface DataPermission { |
||||
|
||||
DataColumn[] value(); |
||||
|
||||
} |
@ -0,0 +1,29 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
||||
import com.ruoyi.common.jackson.DictDataJsonSerializer; |
||||
|
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* 字典数据映射注解 |
||||
* |
||||
* @author itino |
||||
* @deprecated 建议使用通用翻译注解 |
||||
*/ |
||||
@Deprecated |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target({ElementType.FIELD, ElementType.METHOD}) |
||||
@JacksonAnnotationsInside |
||||
@JsonSerialize(using = DictDataJsonSerializer.class) |
||||
public @interface DictDataMapper { |
||||
|
||||
/** |
||||
* 设置字典的type值 (如: sys_user_sex) |
||||
*/ |
||||
String dictType() default ""; |
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.ruoyi.common.enums.AlgorithmType; |
||||
import com.ruoyi.common.enums.EncodeType; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 字段加密注解 |
||||
* |
||||
* @author 老马 |
||||
*/ |
||||
@Documented |
||||
@Inherited |
||||
@Target({ElementType.FIELD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
public @interface EncryptField { |
||||
|
||||
/** |
||||
* 加密算法 |
||||
*/ |
||||
AlgorithmType algorithm() default AlgorithmType.DEFAULT; |
||||
|
||||
/** |
||||
* 秘钥。AES、SM4需要 |
||||
*/ |
||||
String password() default ""; |
||||
|
||||
/** |
||||
* 公钥。RSA、SM2需要 |
||||
*/ |
||||
String publicKey() default ""; |
||||
|
||||
/** |
||||
* 公钥。RSA、SM2需要 |
||||
*/ |
||||
String privateKey() default ""; |
||||
|
||||
/** |
||||
* 编码方式。对加密算法为BASE64的不起作用 |
||||
*/ |
||||
EncodeType encode() default EncodeType.DEFAULT; |
||||
|
||||
} |
@ -0,0 +1,32 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.ruoyi.common.utils.StringUtils; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 字典格式化 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Target({ElementType.FIELD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Inherited |
||||
public @interface ExcelDictFormat { |
||||
|
||||
/** |
||||
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex) |
||||
*/ |
||||
String dictType() default ""; |
||||
|
||||
/** |
||||
* 读取内容转表达式 (如: 0=男,1=女,2=未知) |
||||
*/ |
||||
String readConverterExp() default ""; |
||||
|
||||
/** |
||||
* 分隔符,读取字符串组内容 |
||||
*/ |
||||
String separator() default StringUtils.SEPARATOR; |
||||
|
||||
} |
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 枚举格式化 |
||||
* |
||||
* @author Liang |
||||
*/ |
||||
@Target({ElementType.FIELD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Inherited |
||||
public @interface ExcelEnumFormat { |
||||
|
||||
/** |
||||
* 字典枚举类型 |
||||
*/ |
||||
Class<? extends Enum<?>> enumClass(); |
||||
|
||||
/** |
||||
* 字典枚举类中对应的code属性名称,默认为code |
||||
*/ |
||||
String codeField() default "code"; |
||||
|
||||
/** |
||||
* 字典枚举类中对应的text属性名称,默认为text |
||||
*/ |
||||
String textField() default "text"; |
||||
|
||||
} |
@ -0,0 +1,47 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.ruoyi.common.enums.BusinessType; |
||||
import com.ruoyi.common.enums.OperatorType; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 自定义操作日志记录注解 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
@Target({ElementType.PARAMETER, ElementType.METHOD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface Log { |
||||
/** |
||||
* 模块 |
||||
*/ |
||||
String title() default ""; |
||||
|
||||
/** |
||||
* 功能 |
||||
*/ |
||||
BusinessType businessType() default BusinessType.OTHER; |
||||
|
||||
/** |
||||
* 操作人类别 |
||||
*/ |
||||
OperatorType operatorType() default OperatorType.MANAGE; |
||||
|
||||
/** |
||||
* 是否保存请求的参数 |
||||
*/ |
||||
boolean isSaveRequestData() default true; |
||||
|
||||
/** |
||||
* 是否保存响应的参数 |
||||
*/ |
||||
boolean isSaveResponseData() default true; |
||||
|
||||
/** |
||||
* 排除指定的请求参数 |
||||
*/ |
||||
String[] excludeParamNames() default {}; |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.ruoyi.common.enums.LimitType; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 限流注解 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Target(ElementType.METHOD) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface RateLimiter { |
||||
/** |
||||
* 限流key,支持使用Spring el表达式来动态获取方法上的参数值 |
||||
* 格式类似于 #code.id #{#code} |
||||
*/ |
||||
String key() default ""; |
||||
|
||||
/** |
||||
* 限流时间,单位秒 |
||||
*/ |
||||
int time() default 60; |
||||
|
||||
/** |
||||
* 限流次数 |
||||
*/ |
||||
int count() default 100; |
||||
|
||||
/** |
||||
* 限流类型 |
||||
*/ |
||||
LimitType limitType() default LimitType.DEFAULT; |
||||
|
||||
/** |
||||
* 提示消息 支持国际化 格式为 {code} |
||||
*/ |
||||
String message() default "{rate.limiter.message}"; |
||||
} |
@ -0,0 +1,29 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import java.lang.annotation.*; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
/** |
||||
* 自定义注解防止表单重复提交 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Inherited |
||||
@Target(ElementType.METHOD) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface RepeatSubmit { |
||||
|
||||
/** |
||||
* 间隔时间(ms),小于此时间视为重复提交 |
||||
*/ |
||||
int interval() default 5000; |
||||
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS; |
||||
|
||||
/** |
||||
* 提示消息 支持国际化 格式为 {code} |
||||
*/ |
||||
String message() default "{repeat.submit.message}"; |
||||
|
||||
} |
@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
||||
import com.ruoyi.common.enums.SensitiveStrategy; |
||||
import com.ruoyi.common.jackson.SensitiveJsonSerializer; |
||||
|
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* 数据脱敏注解 |
||||
* |
||||
* @author zhujie |
||||
*/ |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target(ElementType.FIELD) |
||||
@JacksonAnnotationsInside |
||||
@JsonSerialize(using = SensitiveJsonSerializer.class) |
||||
public @interface Sensitive { |
||||
SensitiveStrategy strategy(); |
||||
} |
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
||||
import com.ruoyi.common.translation.handler.TranslationHandler; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 通用翻译注解 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Inherited |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target({ElementType.FIELD, ElementType.METHOD}) |
||||
@Documented |
||||
@JacksonAnnotationsInside |
||||
@JsonSerialize(using = TranslationHandler.class) |
||||
public @interface Translation { |
||||
|
||||
/** |
||||
* 类型 (需与实现类上的 {@link com.ruoyi.common.annotation.TranslationType} 注解type对应) |
||||
* <p> |
||||
* 默认取当前字段的值 如果设置了 @{@link Translation#mapper()} 则取映射字段的值 |
||||
*/ |
||||
String type(); |
||||
|
||||
/** |
||||
* 映射字段 (如果不为空则取此字段的值) |
||||
*/ |
||||
String mapper() default ""; |
||||
|
||||
/** |
||||
* 其他条件 例如: 字典type(sys_user_sex) |
||||
*/ |
||||
String other() default ""; |
||||
|
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.ruoyi.common.annotation; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/** |
||||
* 翻译类型注解 (标注到{@link com.ruoyi.common.translation.TranslationInterface} 的实现类) |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Inherited |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target({ElementType.TYPE}) |
||||
@Documented |
||||
public @interface TranslationType { |
||||
|
||||
/** |
||||
* 类型 |
||||
*/ |
||||
String type(); |
||||
|
||||
} |
@ -0,0 +1,85 @@
|
||||
package com.ruoyi.common.captcha; |
||||
|
||||
import cn.hutool.captcha.generator.CodeGenerator; |
||||
import cn.hutool.core.math.Calculator; |
||||
import cn.hutool.core.util.CharUtil; |
||||
import cn.hutool.core.util.RandomUtil; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
|
||||
/** |
||||
* 无符号计算生成器 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
public class UnsignedMathGenerator implements CodeGenerator { |
||||
|
||||
private static final long serialVersionUID = -5514819971774091076L; |
||||
|
||||
private static final String OPERATORS = "+-*"; |
||||
|
||||
/** |
||||
* 参与计算数字最大长度 |
||||
*/ |
||||
private final int numberLength; |
||||
|
||||
/** |
||||
* 构造 |
||||
*/ |
||||
public UnsignedMathGenerator() { |
||||
this(2); |
||||
} |
||||
|
||||
/** |
||||
* 构造 |
||||
* |
||||
* @param numberLength 参与计算最大数字位数 |
||||
*/ |
||||
public UnsignedMathGenerator(int numberLength) { |
||||
this.numberLength = numberLength; |
||||
} |
||||
|
||||
@Override |
||||
public String generate() { |
||||
final int limit = getLimit(); |
||||
int a = RandomUtil.randomInt(limit); |
||||
int b = RandomUtil.randomInt(limit); |
||||
String max = Integer.toString(Math.max(a,b)); |
||||
String min = Integer.toString(Math.min(a,b)); |
||||
max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE); |
||||
min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE); |
||||
|
||||
return max + RandomUtil.randomChar(OPERATORS) + min + '='; |
||||
} |
||||
|
||||
@Override |
||||
public boolean verify(String code, String userInputCode) { |
||||
int result; |
||||
try { |
||||
result = Integer.parseInt(userInputCode); |
||||
} catch (NumberFormatException e) { |
||||
// 用户输入非数字
|
||||
return false; |
||||
} |
||||
|
||||
final int calculateResult = (int) Calculator.conversion(code); |
||||
return result == calculateResult; |
||||
} |
||||
|
||||
/** |
||||
* 获取验证码长度 |
||||
* |
||||
* @return 验证码长度 |
||||
*/ |
||||
public int getLength() { |
||||
return this.numberLength * 2 + 2; |
||||
} |
||||
|
||||
/** |
||||
* 根据长度获取参与计算数字最大值 |
||||
* |
||||
* @return 最大值 |
||||
*/ |
||||
private int getLimit() { |
||||
return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength)); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.ruoyi.common.config; |
||||
|
||||
import lombok.Data; |
||||
import lombok.Getter; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* 读取项目相关配置 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@Component |
||||
@ConfigurationProperties(prefix = "ruoyi") |
||||
public class RuoYiConfig { |
||||
|
||||
/** |
||||
* 项目名称 |
||||
*/ |
||||
private String name; |
||||
|
||||
/** |
||||
* 版本 |
||||
*/ |
||||
private String version; |
||||
|
||||
/** |
||||
* 版权年份 |
||||
*/ |
||||
private String copyrightYear; |
||||
|
||||
/** |
||||
* 实例演示开关 |
||||
*/ |
||||
private boolean demoEnabled; |
||||
|
||||
/** |
||||
* 缓存懒加载 |
||||
*/ |
||||
private boolean cacheLazy; |
||||
|
||||
/** |
||||
* 获取地址开关 |
||||
*/ |
||||
@Getter |
||||
private static boolean addressEnabled; |
||||
|
||||
public void setAddressEnabled(boolean addressEnabled) { |
||||
RuoYiConfig.addressEnabled = addressEnabled; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 缓存的key 常量 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
public interface CacheConstants { |
||||
|
||||
/** |
||||
* 在线用户 redis key |
||||
*/ |
||||
String ONLINE_TOKEN_KEY = "online_tokens:"; |
||||
|
||||
/** |
||||
* 验证码 redis key |
||||
*/ |
||||
String CAPTCHA_CODE_KEY = "captcha_codes:"; |
||||
|
||||
/** |
||||
* 参数管理 cache key |
||||
*/ |
||||
String SYS_CONFIG_KEY = "sys_config:"; |
||||
|
||||
/** |
||||
* 字典管理 cache key |
||||
*/ |
||||
String SYS_DICT_KEY = "sys_dict:"; |
||||
|
||||
/** |
||||
* 防重提交 redis key |
||||
*/ |
||||
String REPEAT_SUBMIT_KEY = "repeat_submit:"; |
||||
|
||||
/** |
||||
* 限流 redis key |
||||
*/ |
||||
String RATE_LIMIT_KEY = "rate_limit:"; |
||||
|
||||
/** |
||||
* 登录账户密码错误次数 redis key |
||||
*/ |
||||
String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; |
||||
} |
@ -0,0 +1,63 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 缓存组名称常量 |
||||
* <p> |
||||
* key 格式为 cacheNames#ttl#maxIdleTime#maxSize |
||||
* <p> |
||||
* ttl 过期时间 如果设置为0则不过期 默认为0 |
||||
* maxIdleTime 最大空闲时间 根据LRU算法清理空闲数据 如果设置为0则不检测 默认为0 |
||||
* maxSize 组最大长度 根据LRU算法清理溢出数据 如果设置为0则无限长 默认为0 |
||||
* <p> |
||||
* 例子: test#60s、test#0#60s、test#0#1m#1000、test#1h#0#500 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
public interface CacheNames { |
||||
|
||||
/** |
||||
* 演示案例 |
||||
*/ |
||||
String DEMO_CACHE = "demo:cache#60s#10m#20"; |
||||
|
||||
/** |
||||
* 系统配置 |
||||
*/ |
||||
String SYS_CONFIG = "sys_config"; |
||||
|
||||
/** |
||||
* 数据字典 |
||||
*/ |
||||
String SYS_DICT = "sys_dict"; |
||||
|
||||
/** |
||||
* 用户账户 |
||||
*/ |
||||
String SYS_USER_NAME = "sys_user_name#30d"; |
||||
|
||||
/** |
||||
* 用户昵称 |
||||
*/ |
||||
String SYS_NICK_NAME = "sys_nick_name#30d"; |
||||
|
||||
/** |
||||
* 部门 |
||||
*/ |
||||
String SYS_DEPT = "sys_dept#30d"; |
||||
|
||||
/** |
||||
* OSS内容 |
||||
*/ |
||||
String SYS_OSS = "sys_oss#30d"; |
||||
|
||||
/** |
||||
* OSS配置 |
||||
*/ |
||||
String SYS_OSS_CONFIG = "sys_oss_config"; |
||||
|
||||
/** |
||||
* 在线用户 |
||||
*/ |
||||
String ONLINE_TOKEN = "online_tokens"; |
||||
|
||||
} |
@ -0,0 +1,76 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 通用常量信息 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
public interface Constants { |
||||
|
||||
/** |
||||
* UTF-8 字符集 |
||||
*/ |
||||
String UTF8 = "UTF-8"; |
||||
|
||||
/** |
||||
* GBK 字符集 |
||||
*/ |
||||
String GBK = "GBK"; |
||||
|
||||
/** |
||||
* www主域 |
||||
*/ |
||||
String WWW = "www."; |
||||
|
||||
/** |
||||
* http请求 |
||||
*/ |
||||
String HTTP = "http://"; |
||||
|
||||
/** |
||||
* https请求 |
||||
*/ |
||||
String HTTPS = "https://"; |
||||
|
||||
/** |
||||
* 通用成功标识 |
||||
*/ |
||||
String SUCCESS = "0"; |
||||
|
||||
/** |
||||
* 通用失败标识 |
||||
*/ |
||||
String FAIL = "1"; |
||||
|
||||
/** |
||||
* 登录成功 |
||||
*/ |
||||
String LOGIN_SUCCESS = "Success"; |
||||
|
||||
/** |
||||
* 注销 |
||||
*/ |
||||
String LOGOUT = "Logout"; |
||||
|
||||
/** |
||||
* 注册 |
||||
*/ |
||||
String REGISTER = "Register"; |
||||
|
||||
/** |
||||
* 登录失败 |
||||
*/ |
||||
String LOGIN_FAIL = "Error"; |
||||
|
||||
/** |
||||
* 验证码有效期(分钟) |
||||
*/ |
||||
Integer CAPTCHA_EXPIRATION = 2; |
||||
|
||||
/** |
||||
* 令牌 |
||||
*/ |
||||
String TOKEN = "token"; |
||||
|
||||
} |
||||
|
@ -0,0 +1,193 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 代码生成通用常量 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
public interface GenConstants { |
||||
/** |
||||
* 单表(增删改查) |
||||
*/ |
||||
String TPL_CRUD = "crud"; |
||||
|
||||
/** |
||||
* 树表(增删改查) |
||||
*/ |
||||
String TPL_TREE = "tree"; |
||||
|
||||
/** |
||||
* 主子表(增删改查) |
||||
*/ |
||||
String TPL_SUB = "sub"; |
||||
|
||||
/** |
||||
* 树编码字段 |
||||
*/ |
||||
String TREE_CODE = "treeCode"; |
||||
|
||||
/** |
||||
* 树父编码字段 |
||||
*/ |
||||
String TREE_PARENT_CODE = "treeParentCode"; |
||||
|
||||
/** |
||||
* 树名称字段 |
||||
*/ |
||||
String TREE_NAME = "treeName"; |
||||
|
||||
/** |
||||
* 上级菜单ID字段 |
||||
*/ |
||||
String PARENT_MENU_ID = "parentMenuId"; |
||||
|
||||
/** |
||||
* 上级菜单名称字段 |
||||
*/ |
||||
String PARENT_MENU_NAME = "parentMenuName"; |
||||
|
||||
/** |
||||
* 数据库字符串类型 |
||||
*/ |
||||
String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"}; |
||||
|
||||
/** |
||||
* 数据库文本类型 |
||||
*/ |
||||
String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"}; |
||||
|
||||
/** |
||||
* 数据库时间类型 |
||||
*/ |
||||
String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"}; |
||||
|
||||
/** |
||||
* 数据库数字类型 |
||||
*/ |
||||
String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer", |
||||
"bit", "bigint", "float", "double", "decimal"}; |
||||
|
||||
/** |
||||
* BO对象 不需要添加字段 |
||||
*/ |
||||
String[] COLUMNNAME_NOT_ADD = {"create_by", "create_time", "del_flag", "update_by", |
||||
"update_time", "version"}; |
||||
|
||||
/** |
||||
* BO对象 不需要编辑字段 |
||||
*/ |
||||
String[] COLUMNNAME_NOT_EDIT = {"create_by", "create_time", "del_flag", "update_by", |
||||
"update_time", "version"}; |
||||
|
||||
/** |
||||
* VO对象 不需要返回字段 |
||||
*/ |
||||
String[] COLUMNNAME_NOT_LIST = {"create_by", "create_time", "del_flag", "update_by", |
||||
"update_time", "version"}; |
||||
|
||||
/** |
||||
* BO对象 不需要查询字段 |
||||
*/ |
||||
String[] COLUMNNAME_NOT_QUERY = {"id", "create_by", "create_time", "del_flag", "update_by", |
||||
"update_time", "remark", "version"}; |
||||
|
||||
/** |
||||
* Entity基类字段 |
||||
*/ |
||||
String[] BASE_ENTITY = {"createBy", "createTime", "updateBy", "updateTime"}; |
||||
|
||||
/** |
||||
* Tree基类字段 |
||||
*/ |
||||
String[] TREE_ENTITY = {"parentName", "parentId", "children"}; |
||||
|
||||
/** |
||||
* 文本框 |
||||
*/ |
||||
String HTML_INPUT = "input"; |
||||
|
||||
/** |
||||
* 文本域 |
||||
*/ |
||||
String HTML_TEXTAREA = "textarea"; |
||||
|
||||
/** |
||||
* 下拉框 |
||||
*/ |
||||
String HTML_SELECT = "select"; |
||||
|
||||
/** |
||||
* 单选框 |
||||
*/ |
||||
String HTML_RADIO = "radio"; |
||||
|
||||
/** |
||||
* 复选框 |
||||
*/ |
||||
String HTML_CHECKBOX = "checkbox"; |
||||
|
||||
/** |
||||
* 日期控件 |
||||
*/ |
||||
String HTML_DATETIME = "datetime"; |
||||
|
||||
/** |
||||
* 图片上传控件 |
||||
*/ |
||||
String HTML_IMAGE_UPLOAD = "imageUpload"; |
||||
|
||||
/** |
||||
* 文件上传控件 |
||||
*/ |
||||
String HTML_FILE_UPLOAD = "fileUpload"; |
||||
|
||||
/** |
||||
* 富文本控件 |
||||
*/ |
||||
String HTML_EDITOR = "editor"; |
||||
|
||||
/** |
||||
* 字符串类型 |
||||
*/ |
||||
String TYPE_STRING = "String"; |
||||
|
||||
/** |
||||
* 整型 |
||||
*/ |
||||
String TYPE_INTEGER = "Integer"; |
||||
|
||||
/** |
||||
* 长整型 |
||||
*/ |
||||
String TYPE_LONG = "Long"; |
||||
|
||||
/** |
||||
* 浮点型 |
||||
*/ |
||||
String TYPE_DOUBLE = "Double"; |
||||
|
||||
/** |
||||
* 高精度计算类型 |
||||
*/ |
||||
String TYPE_BIGDECIMAL = "BigDecimal"; |
||||
|
||||
/** |
||||
* 时间类型 |
||||
*/ |
||||
String TYPE_DATE = "Date"; |
||||
|
||||
/** |
||||
* 模糊查询 |
||||
*/ |
||||
String QUERY_LIKE = "LIKE"; |
||||
|
||||
/** |
||||
* 相等查询 |
||||
*/ |
||||
String QUERY_EQ = "EQ"; |
||||
|
||||
/** |
||||
* 需要 |
||||
*/ |
||||
String REQUIRE = "1"; |
||||
} |
@ -0,0 +1,93 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 返回状态码 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
public interface HttpStatus { |
||||
/** |
||||
* 操作成功 |
||||
*/ |
||||
int SUCCESS = 200; |
||||
|
||||
/** |
||||
* 对象创建成功 |
||||
*/ |
||||
int CREATED = 201; |
||||
|
||||
/** |
||||
* 请求已经被接受 |
||||
*/ |
||||
int ACCEPTED = 202; |
||||
|
||||
/** |
||||
* 操作已经执行成功,但是没有返回数据 |
||||
*/ |
||||
int NO_CONTENT = 204; |
||||
|
||||
/** |
||||
* 资源已被移除 |
||||
*/ |
||||
int MOVED_PERM = 301; |
||||
|
||||
/** |
||||
* 重定向 |
||||
*/ |
||||
int SEE_OTHER = 303; |
||||
|
||||
/** |
||||
* 资源没有被修改 |
||||
*/ |
||||
int NOT_MODIFIED = 304; |
||||
|
||||
/** |
||||
* 参数列表错误(缺少,格式不匹配) |
||||
*/ |
||||
int BAD_REQUEST = 400; |
||||
|
||||
/** |
||||
* 未授权 |
||||
*/ |
||||
int UNAUTHORIZED = 401; |
||||
|
||||
/** |
||||
* 访问受限,授权过期 |
||||
*/ |
||||
int FORBIDDEN = 403; |
||||
|
||||
/** |
||||
* 资源,服务未找到 |
||||
*/ |
||||
int NOT_FOUND = 404; |
||||
|
||||
/** |
||||
* 不允许的http方法 |
||||
*/ |
||||
int BAD_METHOD = 405; |
||||
|
||||
/** |
||||
* 资源冲突,或者资源被锁 |
||||
*/ |
||||
int CONFLICT = 409; |
||||
|
||||
/** |
||||
* 不支持的数据,媒体类型 |
||||
*/ |
||||
int UNSUPPORTED_TYPE = 415; |
||||
|
||||
/** |
||||
* 系统内部错误 |
||||
*/ |
||||
int ERROR = 500; |
||||
|
||||
/** |
||||
* 接口未实现 |
||||
*/ |
||||
int NOT_IMPLEMENTED = 501; |
||||
|
||||
/** |
||||
* 系统警告消息 |
||||
*/ |
||||
int WARN = 601; |
||||
} |
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 翻译常量 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
public interface TransConstant { |
||||
|
||||
/** |
||||
* 用户id转账号 |
||||
*/ |
||||
String USER_ID_TO_NAME = "user_id_to_name"; |
||||
|
||||
/** |
||||
* 部门id转名称 |
||||
*/ |
||||
String DEPT_ID_TO_NAME = "dept_id_to_name"; |
||||
|
||||
/** |
||||
* 字典type转label |
||||
*/ |
||||
String DICT_TYPE_TO_LABEL = "dict_type_to_label"; |
||||
|
||||
/** |
||||
* ossId转url |
||||
*/ |
||||
String OSS_ID_TO_URL = "oss_id_to_url"; |
||||
|
||||
} |
@ -0,0 +1,132 @@
|
||||
package com.ruoyi.common.constant; |
||||
|
||||
/** |
||||
* 用户常量信息 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
public interface UserConstants { |
||||
|
||||
/** |
||||
* 平台内系统用户的唯一标志 |
||||
*/ |
||||
String SYS_USER = "SYS_USER"; |
||||
|
||||
/** |
||||
* 正常状态 |
||||
*/ |
||||
String NORMAL = "0"; |
||||
|
||||
/** |
||||
* 异常状态 |
||||
*/ |
||||
String EXCEPTION = "1"; |
||||
|
||||
/** |
||||
* 用户正常状态 |
||||
*/ |
||||
String USER_NORMAL = "0"; |
||||
|
||||
/** |
||||
* 用户封禁状态 |
||||
*/ |
||||
String USER_DISABLE = "1"; |
||||
|
||||
/** |
||||
* 角色正常状态 |
||||
*/ |
||||
String ROLE_NORMAL = "0"; |
||||
|
||||
/** |
||||
* 角色封禁状态 |
||||
*/ |
||||
String ROLE_DISABLE = "1"; |
||||
|
||||
/** |
||||
* 部门正常状态 |
||||
*/ |
||||
String DEPT_NORMAL = "0"; |
||||
|
||||
/** |
||||
* 部门停用状态 |
||||
*/ |
||||
String DEPT_DISABLE = "1"; |
||||
|
||||
/** |
||||
* 字典正常状态 |
||||
*/ |
||||
String DICT_NORMAL = "0"; |
||||
|
||||
/** |
||||
* 是否为系统默认(是) |
||||
*/ |
||||
String YES = "Y"; |
||||
|
||||
/** |
||||
* 是否菜单外链(是) |
||||
*/ |
||||
String YES_FRAME = "0"; |
||||
|
||||
/** |
||||
* 是否菜单外链(否) |
||||
*/ |
||||
String NO_FRAME = "1"; |
||||
|
||||
/** |
||||
* 菜单正常状态 |
||||
*/ |
||||
String MENU_NORMAL = "0"; |
||||
|
||||
/** |
||||
* 菜单停用状态 |
||||
*/ |
||||
String MENU_DISABLE = "1"; |
||||
|
||||
/** |
||||
* 菜单类型(目录) |
||||
*/ |
||||
String TYPE_DIR = "M"; |
||||
|
||||
/** |
||||
* 菜单类型(菜单) |
||||
*/ |
||||
String TYPE_MENU = "C"; |
||||
|
||||
/** |
||||
* 菜单类型(按钮) |
||||
*/ |
||||
String TYPE_BUTTON = "F"; |
||||
|
||||
/** |
||||
* Layout组件标识 |
||||
*/ |
||||
String LAYOUT = "Layout"; |
||||
|
||||
/** |
||||
* ParentView组件标识 |
||||
*/ |
||||
String PARENT_VIEW = "ParentView"; |
||||
|
||||
/** |
||||
* InnerLink组件标识 |
||||
*/ |
||||
String INNER_LINK = "InnerLink"; |
||||
|
||||
/** |
||||
* 用户名长度限制 |
||||
*/ |
||||
int USERNAME_MIN_LENGTH = 2; |
||||
int USERNAME_MAX_LENGTH = 20; |
||||
|
||||
/** |
||||
* 密码长度限制 |
||||
*/ |
||||
int PASSWORD_MIN_LENGTH = 5; |
||||
int PASSWORD_MAX_LENGTH = 20; |
||||
|
||||
/** |
||||
* 管理员ID |
||||
*/ |
||||
Long ADMIN_ID = 1L; |
||||
|
||||
} |
@ -0,0 +1,52 @@
|
||||
package com.ruoyi.common.convert; |
||||
|
||||
import cn.hutool.core.convert.Convert; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.alibaba.excel.converters.Converter; |
||||
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
import com.alibaba.excel.metadata.GlobalConfiguration; |
||||
import com.alibaba.excel.metadata.data.ReadCellData; |
||||
import com.alibaba.excel.metadata.data.WriteCellData; |
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
/** |
||||
* 大数值转换 |
||||
* Excel 数值长度位15位 大于15位的数值转换位字符串 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Slf4j |
||||
public class ExcelBigNumberConvert implements Converter<Long> { |
||||
|
||||
@Override |
||||
public Class<Long> supportJavaTypeKey() { |
||||
return Long.class; |
||||
} |
||||
|
||||
@Override |
||||
public CellDataTypeEnum supportExcelTypeKey() { |
||||
return CellDataTypeEnum.STRING; |
||||
} |
||||
|
||||
@Override |
||||
public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
return Convert.toLong(cellData.getData()); |
||||
} |
||||
|
||||
@Override |
||||
public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
if (ObjectUtil.isNotNull(object)) { |
||||
String str = Convert.toStr(object); |
||||
if (str.length() > 15) { |
||||
return new WriteCellData<>(str); |
||||
} |
||||
} |
||||
WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object)); |
||||
cellData.setType(CellDataTypeEnum.NUMBER); |
||||
return cellData; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,73 @@
|
||||
package com.ruoyi.common.convert; |
||||
|
||||
import cn.hutool.core.annotation.AnnotationUtil; |
||||
import cn.hutool.core.convert.Convert; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.alibaba.excel.converters.Converter; |
||||
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
import com.alibaba.excel.metadata.GlobalConfiguration; |
||||
import com.alibaba.excel.metadata.data.ReadCellData; |
||||
import com.alibaba.excel.metadata.data.WriteCellData; |
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
import com.ruoyi.common.annotation.ExcelDictFormat; |
||||
import com.ruoyi.common.core.service.DictService; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.poi.ExcelUtil; |
||||
import com.ruoyi.common.utils.spring.SpringUtils; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import java.lang.reflect.Field; |
||||
|
||||
/** |
||||
* 字典格式化转换处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Slf4j |
||||
public class ExcelDictConvert implements Converter<Object> { |
||||
|
||||
@Override |
||||
public Class<Object> supportJavaTypeKey() { |
||||
return Object.class; |
||||
} |
||||
|
||||
@Override |
||||
public CellDataTypeEnum supportExcelTypeKey() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
ExcelDictFormat anno = getAnnotation(contentProperty.getField()); |
||||
String type = anno.dictType(); |
||||
String label = cellData.getStringValue(); |
||||
String value; |
||||
if (StringUtils.isBlank(type)) { |
||||
value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator()); |
||||
} else { |
||||
value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator()); |
||||
} |
||||
return Convert.convert(contentProperty.getField().getType(), value); |
||||
} |
||||
|
||||
@Override |
||||
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
if (ObjectUtil.isNull(object)) { |
||||
return new WriteCellData<>(""); |
||||
} |
||||
ExcelDictFormat anno = getAnnotation(contentProperty.getField()); |
||||
String type = anno.dictType(); |
||||
String value = Convert.toStr(object); |
||||
String label; |
||||
if (StringUtils.isBlank(type)) { |
||||
label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator()); |
||||
} else { |
||||
label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator()); |
||||
} |
||||
return new WriteCellData<>(label); |
||||
} |
||||
|
||||
private ExcelDictFormat getAnnotation(Field field) { |
||||
return AnnotationUtil.getAnnotation(field, ExcelDictFormat.class); |
||||
} |
||||
} |
@ -0,0 +1,75 @@
|
||||
package com.ruoyi.common.convert; |
||||
|
||||
import cn.hutool.core.annotation.AnnotationUtil; |
||||
import cn.hutool.core.convert.Convert; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.alibaba.excel.converters.Converter; |
||||
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
import com.alibaba.excel.metadata.GlobalConfiguration; |
||||
import com.alibaba.excel.metadata.data.ReadCellData; |
||||
import com.alibaba.excel.metadata.data.WriteCellData; |
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
import com.ruoyi.common.annotation.ExcelEnumFormat; |
||||
import com.ruoyi.common.utils.reflect.ReflectUtils; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 枚举格式化转换处理 |
||||
* |
||||
* @author Liang |
||||
*/ |
||||
@Slf4j |
||||
public class ExcelEnumConvert implements Converter<Object> { |
||||
|
||||
@Override |
||||
public Class<Object> supportJavaTypeKey() { |
||||
return Object.class; |
||||
} |
||||
|
||||
@Override |
||||
public CellDataTypeEnum supportExcelTypeKey() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
Object codeValue = cellData.getData(); |
||||
// 如果是空值
|
||||
if (ObjectUtil.isNull(codeValue)) { |
||||
return null; |
||||
} |
||||
Map<Object, String> enumValueMap = beforeConvert(contentProperty); |
||||
String textValue = enumValueMap.get(codeValue); |
||||
return Convert.convert(contentProperty.getField().getType(), textValue); |
||||
} |
||||
|
||||
@Override |
||||
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
if (ObjectUtil.isNull(object)) { |
||||
return new WriteCellData<>(""); |
||||
} |
||||
Map<Object, String> enumValueMap = beforeConvert(contentProperty); |
||||
String value = Convert.toStr(enumValueMap.get(object), ""); |
||||
return new WriteCellData<>(value); |
||||
} |
||||
|
||||
private Map<Object, String> beforeConvert(ExcelContentProperty contentProperty) { |
||||
ExcelEnumFormat anno = getAnnotation(contentProperty.getField()); |
||||
Map<Object, String> enumValueMap = new HashMap<>(); |
||||
Enum<?>[] enumConstants = anno.enumClass().getEnumConstants(); |
||||
for (Enum<?> enumConstant : enumConstants) { |
||||
Object codeValue = ReflectUtils.invokeGetter(enumConstant, anno.codeField()); |
||||
String textValue = ReflectUtils.invokeGetter(enumConstant, anno.textField()); |
||||
enumValueMap.put(codeValue, textValue); |
||||
} |
||||
return enumValueMap; |
||||
} |
||||
|
||||
private ExcelEnumFormat getAnnotation(Field field) { |
||||
return AnnotationUtil.getAnnotation(field, ExcelEnumFormat.class); |
||||
} |
||||
} |
@ -0,0 +1,69 @@
|
||||
package com.ruoyi.common.core.controller; |
||||
|
||||
import com.ruoyi.common.core.domain.R; |
||||
import com.ruoyi.common.core.domain.model.LoginUser; |
||||
import com.ruoyi.common.helper.LoginHelper; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
|
||||
/** |
||||
* web层通用数据处理 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
public class BaseController { |
||||
|
||||
/** |
||||
* 响应返回结果 |
||||
* |
||||
* @param rows 影响行数 |
||||
* @return 操作结果 |
||||
*/ |
||||
protected R<Void> toAjax(int rows) { |
||||
return rows > 0 ? R.ok() : R.fail(); |
||||
} |
||||
|
||||
/** |
||||
* 响应返回结果 |
||||
* |
||||
* @param result 结果 |
||||
* @return 操作结果 |
||||
*/ |
||||
protected R<Void> toAjax(boolean result) { |
||||
return result ? R.ok() : R.fail(); |
||||
} |
||||
|
||||
/** |
||||
* 页面跳转 |
||||
*/ |
||||
public String redirect(String url) { |
||||
return StringUtils.format("redirect:{}", url); |
||||
} |
||||
|
||||
/** |
||||
* 获取用户缓存信息 |
||||
*/ |
||||
public LoginUser getLoginUser() { |
||||
return LoginHelper.getLoginUser(); |
||||
} |
||||
|
||||
/** |
||||
* 获取登录用户id |
||||
*/ |
||||
public Long getUserId() { |
||||
return LoginHelper.getUserId(); |
||||
} |
||||
|
||||
/** |
||||
* 获取登录部门id |
||||
*/ |
||||
public Long getDeptId() { |
||||
return LoginHelper.getDeptId(); |
||||
} |
||||
|
||||
/** |
||||
* 获取登录用户名 |
||||
*/ |
||||
public String getUsername() { |
||||
return LoginHelper.getUsername(); |
||||
} |
||||
} |
@ -0,0 +1,63 @@
|
||||
package com.ruoyi.common.core.domain; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill; |
||||
import com.baomidou.mybatisplus.annotation.TableField; |
||||
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.Date; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Entity基类 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
public class BaseEntity implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 搜索值 |
||||
*/ |
||||
@JsonIgnore |
||||
@TableField(exist = false) |
||||
private String searchValue; |
||||
|
||||
/** |
||||
* 创建者 |
||||
*/ |
||||
@TableField(fill = FieldFill.INSERT) |
||||
private String createBy; |
||||
|
||||
/** |
||||
* 创建时间 |
||||
*/ |
||||
@TableField(fill = FieldFill.INSERT) |
||||
private Date createTime; |
||||
|
||||
/** |
||||
* 更新者 |
||||
*/ |
||||
@TableField(fill = FieldFill.INSERT_UPDATE) |
||||
private String updateBy; |
||||
|
||||
/** |
||||
* 更新时间 |
||||
*/ |
||||
@TableField(fill = FieldFill.INSERT_UPDATE) |
||||
private Date updateTime; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
*/ |
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
||||
@TableField(exist = false) |
||||
private Map<String, Object> params = new HashMap<>(); |
||||
|
||||
} |
@ -0,0 +1,112 @@
|
||||
package com.ruoyi.common.core.domain; |
||||
|
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem; |
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
import com.ruoyi.common.exception.ServiceException; |
||||
import com.ruoyi.common.utils.StringUtils; |
||||
import com.ruoyi.common.utils.sql.SqlUtil; |
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 分页查询实体类 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
public class PageQuery implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 分页大小 |
||||
*/ |
||||
private Integer pageSize; |
||||
|
||||
/** |
||||
* 当前页数 |
||||
*/ |
||||
private Integer pageNum; |
||||
|
||||
/** |
||||
* 排序列 |
||||
*/ |
||||
private String orderByColumn; |
||||
|
||||
/** |
||||
* 排序的方向desc或者asc |
||||
*/ |
||||
private String isAsc; |
||||
|
||||
/** |
||||
* 当前记录起始索引 默认值 |
||||
*/ |
||||
public static final int DEFAULT_PAGE_NUM = 1; |
||||
|
||||
/** |
||||
* 每页显示记录数 默认值 默认查全部 |
||||
*/ |
||||
public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE; |
||||
|
||||
public <T> Page<T> build() { |
||||
Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM); |
||||
Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE); |
||||
if (pageNum <= 0) { |
||||
pageNum = DEFAULT_PAGE_NUM; |
||||
} |
||||
Page<T> page = new Page<>(pageNum, pageSize); |
||||
List<OrderItem> orderItems = buildOrderItem(); |
||||
if (CollUtil.isNotEmpty(orderItems)) { |
||||
page.addOrder(orderItems); |
||||
} |
||||
return page; |
||||
} |
||||
|
||||
/** |
||||
* 构建排序 |
||||
* |
||||
* 支持的用法如下: |
||||
* {isAsc:"asc",orderByColumn:"id"} order by id asc |
||||
* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc |
||||
* {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc |
||||
* {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc |
||||
*/ |
||||
private List<OrderItem> buildOrderItem() { |
||||
if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) { |
||||
return null; |
||||
} |
||||
String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); |
||||
orderBy = StringUtils.toUnderScoreCase(orderBy); |
||||
|
||||
// 兼容前端排序类型
|
||||
isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"}); |
||||
|
||||
String[] orderByArr = orderBy.split(StringUtils.SEPARATOR); |
||||
String[] isAscArr = isAsc.split(StringUtils.SEPARATOR); |
||||
if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) { |
||||
throw new ServiceException("排序参数有误"); |
||||
} |
||||
|
||||
List<OrderItem> list = new ArrayList<>(); |
||||
// 每个字段各自排序
|
||||
for (int i = 0; i < orderByArr.length; i++) { |
||||
String orderByStr = orderByArr[i]; |
||||
String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i]; |
||||
if ("asc".equals(isAscStr)) { |
||||
list.add(OrderItem.asc(orderByStr)); |
||||
} else if ("desc".equals(isAscStr)) { |
||||
list.add(OrderItem.desc(orderByStr)); |
||||
} else { |
||||
throw new ServiceException("排序参数有误"); |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,107 @@
|
||||
package com.ruoyi.common.core.domain; |
||||
|
||||
import com.ruoyi.common.constant.HttpStatus; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 响应信息主体 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Data |
||||
@NoArgsConstructor |
||||
public class R<T> implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 成功 |
||||
*/ |
||||
public static final int SUCCESS = 200; |
||||
|
||||
/** |
||||
* 失败 |
||||
*/ |
||||
public static final int FAIL = 500; |
||||
|
||||
private int code; |
||||
|
||||
private String msg; |
||||
|
||||
private T data; |
||||
|
||||
public static <T> R<T> ok() { |
||||
return restResult(null, SUCCESS, "操作成功"); |
||||
} |
||||
|
||||
public static <T> R<T> ok(T data) { |
||||
return restResult(data, SUCCESS, "操作成功"); |
||||
} |
||||
|
||||
public static <T> R<T> ok(String msg) { |
||||
return restResult(null, SUCCESS, msg); |
||||
} |
||||
|
||||
public static <T> R<T> ok(String msg, T data) { |
||||
return restResult(data, SUCCESS, msg); |
||||
} |
||||
|
||||
public static <T> R<T> fail() { |
||||
return restResult(null, FAIL, "操作失败"); |
||||
} |
||||
|
||||
public static <T> R<T> fail(String msg) { |
||||
return restResult(null, FAIL, msg); |
||||
} |
||||
|
||||
public static <T> R<T> fail(T data) { |
||||
return restResult(data, FAIL, "操作失败"); |
||||
} |
||||
|
||||
public static <T> R<T> fail(String msg, T data) { |
||||
return restResult(data, FAIL, msg); |
||||
} |
||||
|
||||
public static <T> R<T> fail(int code, String msg) { |
||||
return restResult(null, code, msg); |
||||
} |
||||
|
||||
/** |
||||
* 返回警告消息 |
||||
* |
||||
* @param msg 返回内容 |
||||
* @return 警告消息 |
||||
*/ |
||||
public static <T> R<T> warn(String msg) { |
||||
return restResult(null, HttpStatus.WARN, msg); |
||||
} |
||||
|
||||
/** |
||||
* 返回警告消息 |
||||
* |
||||
* @param msg 返回内容 |
||||
* @param data 数据对象 |
||||
* @return 警告消息 |
||||
*/ |
||||
public static <T> R<T> warn(String msg, T data) { |
||||
return restResult(data, HttpStatus.WARN, msg); |
||||
} |
||||
|
||||
private static <T> R<T> restResult(T data, int code, String msg) { |
||||
R<T> r = new R<>(); |
||||
r.setCode(code); |
||||
r.setData(data); |
||||
r.setMsg(msg); |
||||
return r; |
||||
} |
||||
|
||||
public static <T> Boolean isError(R<T> ret) { |
||||
return !isSuccess(ret); |
||||
} |
||||
|
||||
public static <T> Boolean isSuccess(R<T> ret) { |
||||
return R.SUCCESS == ret.getCode(); |
||||
} |
||||
} |
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.common.core.domain; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Tree基类 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class TreeEntity<T> extends BaseEntity { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 父菜单名称 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private String parentName; |
||||
|
||||
/** |
||||
* 父菜单ID |
||||
*/ |
||||
private Long parentId; |
||||
|
||||
/** |
||||
* 子部门 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private List<T> children = new ArrayList<>(); |
||||
|
||||
} |
@ -0,0 +1,38 @@
|
||||
package com.ruoyi.common.core.domain.dto; |
||||
|
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 角色 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
public class RoleDTO implements Serializable { |
||||
|
||||
/** |
||||
* 角色ID |
||||
*/ |
||||
private Long roleId; |
||||
|
||||
/** |
||||
* 角色名称 |
||||
*/ |
||||
private String roleName; |
||||
|
||||
/** |
||||
* 角色权限 |
||||
*/ |
||||
private String roleKey; |
||||
|
||||
/** |
||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) |
||||
*/ |
||||
private String dataScope; |
||||
|
||||
} |
@ -0,0 +1,60 @@
|
||||
package com.ruoyi.common.core.domain.dto; |
||||
|
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 当前在线会话 |
||||
* |
||||
* @author ruoyi |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
public class UserOnlineDTO implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 会话编号 |
||||
*/ |
||||
private String tokenId; |
||||
|
||||
/** |
||||
* 部门名称 |
||||
*/ |
||||
private String deptName; |
||||
|
||||
/** |
||||
* 用户名称 |
||||
*/ |
||||
private String userName; |
||||
|
||||
/** |
||||
* 登录IP地址 |
||||
*/ |
||||
private String ipaddr; |
||||
|
||||
/** |
||||
* 登录地址 |
||||
*/ |
||||
private String loginLocation; |
||||
|
||||
/** |
||||
* 浏览器类型 |
||||
*/ |
||||
private String browser; |
||||
|
||||
/** |
||||
* 操作系统 |
||||
*/ |
||||
private String os; |
||||
|
||||
/** |
||||
* 登录时间 |
||||
*/ |
||||
private Long loginTime; |
||||
|
||||
} |
@ -0,0 +1,80 @@
|
||||
package com.ruoyi.common.core.domain.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableLogic; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import com.ruoyi.common.core.domain.TreeEntity; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import javax.validation.constraints.Email; |
||||
import javax.validation.constraints.NotBlank; |
||||
import javax.validation.constraints.NotNull; |
||||
import javax.validation.constraints.Size; |
||||
|
||||
/** |
||||
* 部门表 sys_dept |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@TableName("sys_dept") |
||||
public class SysDept extends TreeEntity<SysDept> { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 部门ID |
||||
*/ |
||||
@TableId(value = "dept_id") |
||||
private Long deptId; |
||||
|
||||
/** |
||||
* 部门名称 |
||||
*/ |
||||
@NotBlank(message = "部门名称不能为空") |
||||
@Size(min = 0, max = 30, message = "部门名称长度不能超过{max}个字符") |
||||
private String deptName; |
||||
|
||||
/** |
||||
* 显示顺序 |
||||
*/ |
||||
@NotNull(message = "显示顺序不能为空") |
||||
private Integer orderNum; |
||||
|
||||
/** |
||||
* 负责人 |
||||
*/ |
||||
private String leader; |
||||
|
||||
/** |
||||
* 联系电话 |
||||
*/ |
||||
@Size(min = 0, max = 11, message = "联系电话长度不能超过{max}个字符") |
||||
private String phone; |
||||
|
||||
/** |
||||
* 邮箱 |
||||
*/ |
||||
@Email(message = "邮箱格式不正确") |
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符") |
||||
private String email; |
||||
|
||||
/** |
||||
* 部门状态:0正常,1停用 |
||||
*/ |
||||
private String status; |
||||
|
||||
/** |
||||
* 删除标志(0代表存在 2代表删除) |
||||
*/ |
||||
@TableLogic |
||||
private String delFlag; |
||||
|
||||
/** |
||||
* 祖级列表 |
||||
*/ |
||||
private String ancestors; |
||||
|
||||
} |
@ -0,0 +1,100 @@
|
||||
package com.ruoyi.common.core.domain.entity; |
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
||||
import com.alibaba.excel.annotation.ExcelProperty; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import com.ruoyi.common.annotation.ExcelDictFormat; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.convert.ExcelDictConvert; |
||||
import com.ruoyi.common.core.domain.BaseEntity; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
import javax.validation.constraints.Size; |
||||
|
||||
/** |
||||
* 字典数据表 sys_dict_data |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@TableName("sys_dict_data") |
||||
@ExcelIgnoreUnannotated |
||||
public class SysDictData extends BaseEntity { |
||||
|
||||
/** |
||||
* 字典编码 |
||||
*/ |
||||
@ExcelProperty(value = "字典编码") |
||||
@TableId(value = "dict_code") |
||||
private Long dictCode; |
||||
|
||||
/** |
||||
* 字典排序 |
||||
*/ |
||||
@ExcelProperty(value = "字典排序") |
||||
private Integer dictSort; |
||||
|
||||
/** |
||||
* 字典标签 |
||||
*/ |
||||
@ExcelProperty(value = "字典标签") |
||||
@NotBlank(message = "字典标签不能为空") |
||||
@Size(min = 0, max = 100, message = "字典标签长度不能超过{max}个字符") |
||||
private String dictLabel; |
||||
|
||||
/** |
||||
* 字典键值 |
||||
*/ |
||||
@ExcelProperty(value = "字典键值") |
||||
@NotBlank(message = "字典键值不能为空") |
||||
@Size(min = 0, max = 100, message = "字典键值长度不能超过{max}个字符") |
||||
private String dictValue; |
||||
|
||||
/** |
||||
* 字典类型 |
||||
*/ |
||||
@ExcelProperty(value = "字典类型") |
||||
@NotBlank(message = "字典类型不能为空") |
||||
@Size(min = 0, max = 100, message = "字典类型长度不能超过{max}个字符") |
||||
private String dictType; |
||||
|
||||
/** |
||||
* 样式属性(其他样式扩展) |
||||
*/ |
||||
@Size(min = 0, max = 100, message = "样式属性长度不能超过{max}个字符") |
||||
private String cssClass; |
||||
|
||||
/** |
||||
* 表格字典样式 |
||||
*/ |
||||
private String listClass; |
||||
|
||||
/** |
||||
* 是否默认(Y是 N否) |
||||
*/ |
||||
@ExcelProperty(value = "是否默认", converter = ExcelDictConvert.class) |
||||
@ExcelDictFormat(dictType = "sys_yes_no") |
||||
private String isDefault; |
||||
|
||||
/** |
||||
* 状态(0正常 1停用) |
||||
*/ |
||||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) |
||||
@ExcelDictFormat(dictType = "sys_normal_disable") |
||||
private String status; |
||||
|
||||
/** |
||||
* 备注 |
||||
*/ |
||||
private String remark; |
||||
|
||||
public boolean getDefault() { |
||||
return UserConstants.YES.equals(this.isDefault); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,65 @@
|
||||
package com.ruoyi.common.core.domain.entity; |
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
||||
import com.alibaba.excel.annotation.ExcelProperty; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import com.ruoyi.common.annotation.ExcelDictFormat; |
||||
import com.ruoyi.common.convert.ExcelDictConvert; |
||||
import com.ruoyi.common.core.domain.BaseEntity; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
import javax.validation.constraints.Pattern; |
||||
import javax.validation.constraints.Size; |
||||
|
||||
/** |
||||
* 字典类型表 sys_dict_type |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@TableName("sys_dict_type") |
||||
@ExcelIgnoreUnannotated |
||||
public class SysDictType extends BaseEntity { |
||||
|
||||
/** |
||||
* 字典主键 |
||||
*/ |
||||
@ExcelProperty(value = "字典主键") |
||||
@TableId(value = "dict_id") |
||||
private Long dictId; |
||||
|
||||
/** |
||||
* 字典名称 |
||||
*/ |
||||
@ExcelProperty(value = "字典名称") |
||||
@NotBlank(message = "字典名称不能为空") |
||||
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过{max}个字符") |
||||
private String dictName; |
||||
|
||||
/** |
||||
* 字典类型 |
||||
*/ |
||||
@ExcelProperty(value = "字典类型") |
||||
@NotBlank(message = "字典类型不能为空") |
||||
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过{max}个字符") |
||||
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") |
||||
private String dictType; |
||||
|
||||
/** |
||||
* 状态(0正常 1停用) |
||||
*/ |
||||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) |
||||
@ExcelDictFormat(dictType = "sys_normal_disable") |
||||
private String status; |
||||
|
||||
/** |
||||
* 备注 |
||||
*/ |
||||
private String remark; |
||||
|
||||
} |
@ -0,0 +1,104 @@
|
||||
package com.ruoyi.common.core.domain.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
import com.ruoyi.common.core.domain.TreeEntity; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
import javax.validation.constraints.NotNull; |
||||
import javax.validation.constraints.Size; |
||||
|
||||
/** |
||||
* 菜单权限表 sys_menu |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@TableName("sys_menu") |
||||
public class SysMenu extends TreeEntity<SysMenu> { |
||||
|
||||
/** |
||||
* 菜单ID |
||||
*/ |
||||
@TableId(value = "menu_id") |
||||
private Long menuId; |
||||
|
||||
/** |
||||
* 菜单名称 |
||||
*/ |
||||
@NotBlank(message = "菜单名称不能为空") |
||||
@Size(min = 0, max = 50, message = "菜单名称长度不能超过{max}个字符") |
||||
private String menuName; |
||||
|
||||
/** |
||||
* 显示顺序 |
||||
*/ |
||||
@NotNull(message = "显示顺序不能为空") |
||||
private Integer orderNum; |
||||
|
||||
/** |
||||
* 路由地址 |
||||
*/ |
||||
@Size(min = 0, max = 200, message = "路由地址不能超过{max}个字符") |
||||
private String path; |
||||
|
||||
/** |
||||
* 组件路径 |
||||
*/ |
||||
@Size(min = 0, max = 200, message = "组件路径不能超过{max}个字符") |
||||
private String component; |
||||
|
||||
/** |
||||
* 路由参数 |
||||
*/ |
||||
private String queryParam; |
||||
|
||||
/** |
||||
* 是否为外链(0是 1否) |
||||
*/ |
||||
private String isFrame; |
||||
|
||||
/** |
||||
* 是否缓存(0缓存 1不缓存) |
||||
*/ |
||||
private String isCache; |
||||
|
||||
/** |
||||
* 类型(M目录 C菜单 F按钮) |
||||
*/ |
||||
@NotBlank(message = "菜单类型不能为空") |
||||
private String menuType; |
||||
|
||||
/** |
||||
* 显示状态(0显示 1隐藏) |
||||
*/ |
||||
private String visible; |
||||
|
||||
/** |
||||
* 菜单状态(0正常 1停用) |
||||
*/ |
||||
private String status; |
||||
|
||||
/** |
||||
* 权限字符串 |
||||
*/ |
||||
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||
@Size(min = 0, max = 100, message = "权限标识长度不能超过{max}个字符") |
||||
private String perms; |
||||
|
||||
/** |
||||
* 菜单图标 |
||||
*/ |
||||
private String icon; |
||||
|
||||
/** |
||||
* 备注 |
||||
*/ |
||||
private String remark; |
||||
|
||||
} |
@ -0,0 +1,124 @@
|
||||
package com.ruoyi.common.core.domain.entity; |
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
||||
import com.alibaba.excel.annotation.ExcelProperty; |
||||
import com.baomidou.mybatisplus.annotation.TableField; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableLogic; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import com.ruoyi.common.annotation.ExcelDictFormat; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.convert.ExcelDictConvert; |
||||
import com.ruoyi.common.core.domain.BaseEntity; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
import javax.validation.constraints.NotNull; |
||||
import javax.validation.constraints.Size; |
||||
|
||||
/** |
||||
* 角色表 sys_role |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@TableName("sys_role") |
||||
@ExcelIgnoreUnannotated |
||||
public class SysRole extends BaseEntity { |
||||
|
||||
/** |
||||
* 角色ID |
||||
*/ |
||||
@ExcelProperty(value = "角色序号") |
||||
@TableId(value = "role_id") |
||||
private Long roleId; |
||||
|
||||
/** |
||||
* 角色名称 |
||||
*/ |
||||
@ExcelProperty(value = "角色名称") |
||||
@NotBlank(message = "角色名称不能为空") |
||||
@Size(min = 0, max = 30, message = "角色名称长度不能超过{max}个字符") |
||||
private String roleName; |
||||
|
||||
/** |
||||
* 角色权限 |
||||
*/ |
||||
@ExcelProperty(value = "角色权限") |
||||
@NotBlank(message = "权限字符不能为空") |
||||
@Size(min = 0, max = 100, message = "权限字符长度不能超过{max}个字符") |
||||
private String roleKey; |
||||
|
||||
/** |
||||
* 角色排序 |
||||
*/ |
||||
@ExcelProperty(value = "角色排序") |
||||
@NotNull(message = "显示顺序不能为空") |
||||
private Integer roleSort; |
||||
|
||||
/** |
||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) |
||||
*/ |
||||
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class) |
||||
@ExcelDictFormat(readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") |
||||
private String dataScope; |
||||
|
||||
/** |
||||
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) |
||||
*/ |
||||
private Boolean menuCheckStrictly; |
||||
|
||||
/** |
||||
* 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) |
||||
*/ |
||||
private Boolean deptCheckStrictly; |
||||
|
||||
/** |
||||
* 角色状态(0正常 1停用) |
||||
*/ |
||||
@ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class) |
||||
@ExcelDictFormat(dictType = "sys_normal_disable") |
||||
private String status; |
||||
|
||||
/** |
||||
* 删除标志(0代表存在 2代表删除) |
||||
*/ |
||||
@TableLogic |
||||
private String delFlag; |
||||
|
||||
/** |
||||
* 备注 |
||||
*/ |
||||
private String remark; |
||||
|
||||
/** |
||||
* 用户是否存在此角色标识 默认不存在 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private boolean flag = false; |
||||
|
||||
/** |
||||
* 菜单组 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long[] menuIds; |
||||
|
||||
/** |
||||
* 部门组(数据权限) |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long[] deptIds; |
||||
|
||||
public SysRole(Long roleId) { |
||||
this.roleId = roleId; |
||||
} |
||||
|
||||
public boolean isAdmin() { |
||||
return UserConstants.ADMIN_ID.equals(this.roleId); |
||||
} |
||||
} |
@ -0,0 +1,168 @@
|
||||
package com.ruoyi.common.core.domain.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.*; |
||||
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import com.ruoyi.common.annotation.Sensitive; |
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import com.ruoyi.common.core.domain.BaseEntity; |
||||
import com.ruoyi.common.enums.SensitiveStrategy; |
||||
import com.ruoyi.common.xss.Xss; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.validation.constraints.Email; |
||||
import javax.validation.constraints.NotBlank; |
||||
import javax.validation.constraints.Size; |
||||
import java.util.Date; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 用户对象 sys_user |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@TableName("sys_user") |
||||
public class SysUser extends BaseEntity { |
||||
|
||||
/** |
||||
* 用户ID |
||||
*/ |
||||
@TableId(value = "user_id") |
||||
private Long userId; |
||||
|
||||
/** |
||||
* 部门ID |
||||
*/ |
||||
private Long deptId; |
||||
|
||||
/** |
||||
* 用户账号 |
||||
*/ |
||||
@Xss(message = "用户账号不能包含脚本字符") |
||||
@NotBlank(message = "用户账号不能为空") |
||||
@Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符") |
||||
private String userName; |
||||
|
||||
/** |
||||
* 用户昵称 |
||||
*/ |
||||
@Xss(message = "用户昵称不能包含脚本字符") |
||||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过{max}个字符") |
||||
private String nickName; |
||||
|
||||
/** |
||||
* 用户类型(sys_user系统用户) |
||||
*/ |
||||
private String userType; |
||||
|
||||
/** |
||||
* 用户邮箱 |
||||
*/ |
||||
@Sensitive(strategy = SensitiveStrategy.EMAIL) |
||||
@Email(message = "邮箱格式不正确") |
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符") |
||||
private String email; |
||||
|
||||
/** |
||||
* 手机号码 |
||||
*/ |
||||
@Sensitive(strategy = SensitiveStrategy.PHONE) |
||||
private String phonenumber; |
||||
|
||||
/** |
||||
* 用户性别 |
||||
*/ |
||||
private String sex; |
||||
|
||||
/** |
||||
* 用户头像 |
||||
*/ |
||||
private String avatar; |
||||
|
||||
/** |
||||
* 密码 |
||||
*/ |
||||
@TableField( |
||||
insertStrategy = FieldStrategy.NOT_EMPTY, |
||||
updateStrategy = FieldStrategy.NOT_EMPTY, |
||||
whereStrategy = FieldStrategy.NOT_EMPTY |
||||
) |
||||
private String password; |
||||
|
||||
@JsonIgnore |
||||
@JsonProperty |
||||
public String getPassword() { |
||||
return password; |
||||
} |
||||
|
||||
/** |
||||
* 帐号状态(0正常 1停用) |
||||
*/ |
||||
private String status; |
||||
|
||||
/** |
||||
* 删除标志(0代表存在 2代表删除) |
||||
*/ |
||||
@TableLogic |
||||
private String delFlag; |
||||
|
||||
/** |
||||
* 最后登录IP |
||||
*/ |
||||
private String loginIp; |
||||
|
||||
/** |
||||
* 最后登录时间 |
||||
*/ |
||||
private Date loginDate; |
||||
|
||||
/** |
||||
* 备注 |
||||
*/ |
||||
private String remark; |
||||
|
||||
/** |
||||
* 部门对象 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private SysDept dept; |
||||
|
||||
/** |
||||
* 角色对象 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private List<SysRole> roles; |
||||
|
||||
/** |
||||
* 角色组 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long[] roleIds; |
||||
|
||||
/** |
||||
* 岗位组 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long[] postIds; |
||||
|
||||
/** |
||||
* 数据权限 当前角色ID |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long roleId; |
||||
|
||||
public SysUser(Long userId) { |
||||
this.userId = userId; |
||||
} |
||||
|
||||
public boolean isAdmin() { |
||||
return UserConstants.ADMIN_ID.equals(this.userId); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.ruoyi.common.core.domain.event; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 登录事件 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
public class LogininforEvent implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 用户账号 |
||||
*/ |
||||
private String username; |
||||
|
||||
/** |
||||
* 登录状态 0成功 1失败 |
||||
*/ |
||||
private String status; |
||||
|
||||
/** |
||||
* 提示消息 |
||||
*/ |
||||
private String message; |
||||
|
||||
/** |
||||
* 请求体 |
||||
*/ |
||||
private HttpServletRequest request; |
||||
|
||||
/** |
||||
* 其他参数 |
||||
*/ |
||||
private Object[] args; |
||||
|
||||
} |
@ -0,0 +1,104 @@
|
||||
package com.ruoyi.common.core.domain.event; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* 操作日志事件 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
public class OperLogEvent implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 日志主键 |
||||
*/ |
||||
private Long operId; |
||||
|
||||
/** |
||||
* 操作模块 |
||||
*/ |
||||
private String title; |
||||
|
||||
/** |
||||
* 业务类型(0其它 1新增 2修改 3删除) |
||||
*/ |
||||
private Integer businessType; |
||||
|
||||
/** |
||||
* 业务类型数组 |
||||
*/ |
||||
private Integer[] businessTypes; |
||||
|
||||
/** |
||||
* 请求方法 |
||||
*/ |
||||
private String method; |
||||
|
||||
/** |
||||
* 请求方式 |
||||
*/ |
||||
private String requestMethod; |
||||
|
||||
/** |
||||
* 操作类别(0其它 1后台用户 2手机端用户) |
||||
*/ |
||||
private Integer operatorType; |
||||
|
||||
/** |
||||
* 操作人员 |
||||
*/ |
||||
private String operName; |
||||
|
||||
/** |
||||
* 部门名称 |
||||
*/ |
||||
private String deptName; |
||||
|
||||
/** |
||||
* 请求url |
||||
*/ |
||||
private String operUrl; |
||||
|
||||
/** |
||||
* 操作地址 |
||||
*/ |
||||
private String operIp; |
||||
|
||||
/** |
||||
* 操作地点 |
||||
*/ |
||||
private String operLocation; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
*/ |
||||
private String operParam; |
||||
|
||||
/** |
||||
* 返回参数 |
||||
*/ |
||||
private String jsonResult; |
||||
|
||||
/** |
||||
* 操作状态(0正常 1异常) |
||||
*/ |
||||
private Integer status; |
||||
|
||||
/** |
||||
* 错误消息 |
||||
*/ |
||||
private String errorMsg; |
||||
|
||||
/** |
||||
* 操作时间 |
||||
*/ |
||||
private Date operTime; |
||||
|
||||
} |
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.core.domain.model; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import javax.validation.constraints.Email; |
||||
import javax.validation.constraints.NotBlank; |
||||
|
||||
/** |
||||
* 短信登录对象 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
public class EmailLoginBody { |
||||
|
||||
/** |
||||
* 邮箱 |
||||
*/ |
||||
@NotBlank(message = "{user.email.not.blank}") |
||||
@Email(message = "{user.email.not.valid}") |
||||
private String email; |
||||
|
||||
/** |
||||
* 邮箱code |
||||
*/ |
||||
@NotBlank(message = "{email.code.not.blank}") |
||||
private String emailCode; |
||||
|
||||
} |
@ -0,0 +1,42 @@
|
||||
package com.ruoyi.common.core.domain.model; |
||||
|
||||
import com.ruoyi.common.constant.UserConstants; |
||||
import lombok.Data; |
||||
import org.hibernate.validator.constraints.Length; |
||||
|
||||
import javax.validation.constraints.NotBlank; |
||||
|
||||
/** |
||||
* 用户登录对象 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
public class LoginBody { |
||||
|
||||
/** |
||||
* 用户名 |
||||
*/ |
||||
@NotBlank(message = "{user.username.not.blank}") |
||||
@Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}") |
||||
private String username; |
||||
|
||||
/** |
||||
* 用户密码 |
||||
*/ |
||||
@NotBlank(message = "{user.password.not.blank}") |
||||
@Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}") |
||||
private String password; |
||||
|
||||
/** |
||||
* 验证码 |
||||
*/ |
||||
private String code; |
||||
|
||||
/** |
||||
* 唯一标识 |
||||
*/ |
||||
private String uuid; |
||||
|
||||
} |
@ -0,0 +1,121 @@
|
||||
package com.ruoyi.common.core.domain.model; |
||||
|
||||
import com.ruoyi.common.core.domain.dto.RoleDTO; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 登录用户身份权限 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
public class LoginUser implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 用户ID |
||||
*/ |
||||
private Long userId; |
||||
|
||||
/** |
||||
* 部门ID |
||||
*/ |
||||
private Long deptId; |
||||
|
||||
/** |
||||
* 部门名 |
||||
*/ |
||||
private String deptName; |
||||
|
||||
/** |
||||
* 用户唯一标识 |
||||
*/ |
||||
private String token; |
||||
|
||||
/** |
||||
* 用户类型 |
||||
*/ |
||||
private String userType; |
||||
|
||||
/** |
||||
* 登录时间 |
||||
*/ |
||||
private Long loginTime; |
||||
|
||||
/** |
||||
* 过期时间 |
||||
*/ |
||||
private Long expireTime; |
||||
|
||||
/** |
||||
* 登录IP地址 |
||||
*/ |
||||
private String ipaddr; |
||||
|
||||
/** |
||||
* 登录地点 |
||||
*/ |
||||
private String loginLocation; |
||||
|
||||
/** |
||||
* 浏览器类型 |
||||
*/ |
||||
private String browser; |
||||
|
||||
/** |
||||
* 操作系统 |
||||
*/ |
||||
private String os; |
||||
|
||||
/** |
||||
* 菜单权限 |
||||
*/ |
||||
private Set<String> menuPermission; |
||||
|
||||
/** |
||||
* 角色权限 |
||||
*/ |
||||
private Set<String> rolePermission; |
||||
|
||||
/** |
||||
* 用户名 |
||||
*/ |
||||
private String username; |
||||
|
||||
/** |
||||
* 用户名 |
||||
*/ |
||||
private String nickName; |
||||
|
||||
/** |
||||
* 角色对象 |
||||
*/ |
||||
private List<RoleDTO> roles; |
||||
|
||||
/** |
||||
* 数据权限 当前角色ID |
||||
*/ |
||||
private Long roleId; |
||||
|
||||
/** |
||||
* 获取登录id |
||||
*/ |
||||
public String getLoginId() { |
||||
if (userType == null) { |
||||
throw new IllegalArgumentException("用户类型不能为空"); |
||||
} |
||||
if (userId == null) { |
||||
throw new IllegalArgumentException("用户ID不能为空"); |
||||
} |
||||
return userType + ":" + userId; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.ruoyi.common.core.domain.model; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
/** |
||||
* 用户注册对象 |
||||
* |
||||
* @author Lion Li |
||||
*/ |
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class RegisterBody extends LoginBody { |
||||
|
||||
private String userType; |
||||
|
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue