Pre Merge pull request !445 from 中科嘉迪/dev

pull/445/MERGE
中科嘉迪 2025-12-23 08:44:11 +00:00 committed by Gitee
commit aa326f6326
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
126 changed files with 7212 additions and 3695 deletions

View File

@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.7</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.5.0.9</h1>
<h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4> <h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.7-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.5.0.9-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>

724
pom.xml
View File

@ -1,331 +1,395 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依微服务系统</description> <description>若依微服务系统</description>
<properties> <properties>
<ruoyi.version>3.6.7</ruoyi.version> <ruoyi.version>3.6.5.0.9</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-boot.version>2.7.18</spring-boot.version> <spring-boot.version>2.7.18</spring-boot.version>
<spring-cloud.version>2021.0.9</spring-cloud.version> <spring-cloud.version>2021.0.9</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.6.1</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.0.6.1</spring-cloud-alibaba.version>
<spring-boot-admin.version>2.7.16</spring-boot-admin.version> <spring-boot-admin.version>2.7.16</spring-boot-admin.version>
<tobato.version>1.27.2</tobato.version> <tobato.version>1.27.2</tobato.version>
<kaptcha.version>2.3.3</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>2.0.0</pagehelper.boot.version> <pagehelper.boot.version>2.0.0</pagehelper.boot.version>
<druid.version>1.2.27</druid.version> <druid.version>1.2.23</druid.version>
<dynamic-ds.version>4.3.1</dynamic-ds.version> <dynamic-ds.version>4.3.1</dynamic-ds.version>
<commons.io.version>2.21.0</commons.io.version> <commons.io.version>2.19.0</commons.io.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<fastjson.version>2.0.60</fastjson.version> <fastjson.version>2.0.53</fastjson.version>
<jjwt.version>0.9.1</jjwt.version> <jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version> <minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<springdoc.version>1.6.9</springdoc.version> <springdoc.version>1.6.9</springdoc.version>
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version> <transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
<!-- override dependency version --> <!-- override dependency version -->
<tomcat.version>9.0.112</tomcat.version> <tomcat.version>9.0.105</tomcat.version>
<logback.version>1.2.13</logback.version> <logback.version>1.2.13</logback.version>
<spring-framework.version>5.3.39</spring-framework.version> <spring-framework.version>5.3.39</spring-framework.version>
</properties> <kotlin.version>2.0.0</kotlin.version>
<spring-boot-admin>2.7.9</spring-boot-admin>
<!-- 依赖声明 --> </properties>
<dependencyManagement>
<dependencies> <!-- 依赖声明 -->
<dependencyManagement>
<!-- 覆盖SpringFramework的依赖配置--> <dependencies>
<dependency>
<groupId>org.springframework</groupId> <!-- 覆盖SpringFramework的依赖配置-->
<artifactId>spring-framework-bom</artifactId> <dependency>
<version>${spring-framework.version}</version> <groupId>org.springframework</groupId>
<type>pom</type> <artifactId>spring-framework-bom</artifactId>
<scope>import</scope> <version>${spring-framework.version}</version>
</dependency> <type>pom</type>
<scope>import</scope>
<!-- SpringCloud 微服务 --> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId> <!-- SpringCloud 微服务 -->
<artifactId>spring-cloud-dependencies</artifactId> <dependency>
<version>${spring-cloud.version}</version> <groupId>org.springframework.cloud</groupId>
<type>pom</type> <artifactId>spring-cloud-dependencies</artifactId>
<scope>import</scope> <version>${spring-cloud.version}</version>
</dependency> <type>pom</type>
<scope>import</scope>
<!-- SpringCloud Alibaba 微服务 --> </dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId> <!-- SpringCloud Alibaba 微服务 -->
<artifactId>spring-cloud-alibaba-dependencies</artifactId> <dependency>
<version>${spring-cloud-alibaba.version}</version> <groupId>com.alibaba.cloud</groupId>
<type>pom</type> <artifactId>spring-cloud-alibaba-dependencies</artifactId>
<scope>import</scope> <version>${spring-cloud-alibaba.version}</version>
</dependency> <type>pom</type>
<scope>import</scope>
<!-- SpringBoot 依赖配置 --> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId> <!-- SpringBoot 依赖配置 -->
<artifactId>spring-boot-dependencies</artifactId> <dependency>
<version>${spring-boot.version}</version> <groupId>org.springframework.boot</groupId>
<type>pom</type> <artifactId>spring-boot-dependencies</artifactId>
<scope>import</scope> <version>${spring-boot.version}</version>
</dependency> <type>pom</type>
<scope>import</scope>
<!-- 覆盖logback的依赖配置--> </dependency>
<dependency>
<groupId>ch.qos.logback</groupId> <!-- 覆盖logback的依赖配置-->
<artifactId>logback-core</artifactId> <dependency>
<version>${logback.version}</version> <groupId>ch.qos.logback</groupId>
</dependency> <artifactId>logback-core</artifactId>
<version>${logback.version}</version>
<dependency> </dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <dependency>
<version>${logback.version}</version> <groupId>ch.qos.logback</groupId>
</dependency> <artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<!-- 覆盖tomcat的依赖配置--> </dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId> <!-- 覆盖tomcat的依赖配置-->
<artifactId>tomcat-embed-core</artifactId> <dependency>
<version>${tomcat.version}</version> <groupId>org.apache.tomcat.embed</groupId>
</dependency> <artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
<dependency> </dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId> <dependency>
<version>${tomcat.version}</version> <groupId>org.apache.tomcat.embed</groupId>
</dependency> <artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
<dependency> </dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId> <dependency>
<version>${tomcat.version}</version> <groupId>org.apache.tomcat.embed</groupId>
</dependency> <artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
<!-- FastDFS 分布式文件系统 --> </dependency>
<dependency>
<groupId>com.github.tobato</groupId> <!-- FastDFS 分布式文件系统 -->
<artifactId>fastdfs-client</artifactId> <dependency>
<version>${tobato.version}</version> <groupId>com.github.tobato</groupId>
</dependency> <artifactId>fastdfs-client</artifactId>
<version>${tobato.version}</version>
<!-- Springdoc webmvc 依赖配置 --> </dependency>
<dependency>
<groupId>org.springdoc</groupId> <!-- Springdoc webmvc 依赖配置 -->
<artifactId>springdoc-openapi-ui</artifactId> <dependency>
<version>${springdoc.version}</version> <groupId>org.springdoc</groupId>
</dependency> <artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version>
<!-- 验证码 --> </dependency>
<dependency>
<groupId>pro.fessional</groupId> <!-- 验证码 -->
<artifactId>kaptcha</artifactId> <dependency>
<version>${kaptcha.version}</version> <groupId>pro.fessional</groupId>
</dependency> <artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
<!-- pagehelper 分页插件 --> </dependency>
<dependency>
<groupId>com.github.pagehelper</groupId> <!-- pagehelper 分页插件 -->
<artifactId>pagehelper-spring-boot-starter</artifactId> <dependency>
<version>${pagehelper.boot.version}</version> <groupId>com.github.pagehelper</groupId>
</dependency> <artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
<!-- io常用工具类 --> </dependency>
<dependency>
<groupId>commons-io</groupId> <!-- io常用工具类 -->
<artifactId>commons-io</artifactId> <dependency>
<version>${commons.io.version}</version> <groupId>commons-io</groupId>
</dependency> <artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
<!-- excel工具 --> </dependency>
<dependency>
<groupId>org.apache.poi</groupId> <!-- excel工具 -->
<artifactId>poi-ooxml</artifactId> <dependency>
<version>${poi.version}</version> <groupId>org.apache.poi</groupId>
</dependency> <artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
<!-- 代码生成使用模板 --> </dependency>
<dependency>
<groupId>org.apache.velocity</groupId> <!-- 代码生成使用模板 -->
<artifactId>velocity-engine-core</artifactId> <dependency>
<version>${velocity.version}</version> <groupId>org.apache.velocity</groupId>
</dependency> <artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
<!-- JSON 解析器和生成器 --> </dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId> <!-- JSON 解析器和生成器 -->
<artifactId>fastjson2</artifactId> <dependency>
<version>${fastjson.version}</version> <groupId>com.alibaba.fastjson2</groupId>
</dependency> <artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
<!-- JWT --> </dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId> <!-- JWT -->
<artifactId>jjwt</artifactId> <dependency>
<version>${jjwt.version}</version> <groupId>io.jsonwebtoken</groupId>
</dependency> <artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
<!-- 线程传递值 --> </dependency>
<dependency>
<groupId>com.alibaba</groupId> <!-- 线程传递值 -->
<artifactId>transmittable-thread-local</artifactId> <dependency>
<version>${transmittable-thread-local.version}</version> <groupId>com.alibaba</groupId>
</dependency> <artifactId>transmittable-thread-local</artifactId>
<version>${transmittable-thread-local.version}</version>
<!-- 核心模块 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 核心模块 -->
<artifactId>ruoyi-common-core</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-core</artifactId>
<version>${ruoyi.version}</version>
<!-- 接口模块 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 接口模块 -->
<artifactId>ruoyi-common-swagger</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-swagger</artifactId>
<version>${ruoyi.version}</version>
<!-- 安全模块 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 安全模块 -->
<artifactId>ruoyi-common-security</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-security</artifactId>
<version>${ruoyi.version}</version>
<!-- 数据脱敏 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 数据脱敏 -->
<artifactId>ruoyi-common-sensitive</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-sensitive</artifactId>
<version>${ruoyi.version}</version>
<!-- 权限范围 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 权限范围 -->
<artifactId>ruoyi-common-datascope</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-datascope</artifactId>
<version>${ruoyi.version}</version>
<!-- 多数据源 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 多数据源 -->
<artifactId>ruoyi-common-datasource</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-datasource</artifactId>
<version>${ruoyi.version}</version>
<!-- 分布式事务 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 分布式事务 -->
<artifactId>ruoyi-common-seata</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-seata</artifactId>
<version>${ruoyi.version}</version>
<!-- 日志记录 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 日志记录 -->
<artifactId>ruoyi-common-log</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-log</artifactId>
<version>${ruoyi.version}</version>
<!-- 缓存服务 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 缓存服务 -->
<artifactId>ruoyi-common-redis</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-common-redis</artifactId>
<version>${ruoyi.version}</version>
<!-- 系统接口 --> </dependency>
<dependency>
<groupId>com.ruoyi</groupId> <!-- 系统接口 -->
<artifactId>ruoyi-api-system</artifactId> <dependency>
<version>${ruoyi.version}</version> <groupId>com.ruoyi</groupId>
</dependency> <artifactId>ruoyi-api-system</artifactId>
<version>${ruoyi.version}</version>
</dependencies> </dependency>
</dependencyManagement> <dependency>
<groupId>de.codecentric</groupId>
<modules> <artifactId>spring-boot-admin-starter-client</artifactId>
<module>ruoyi-auth</module> <version>${spring-boot-admin}</version>
<module>ruoyi-gateway</module> </dependency>
<module>ruoyi-visual</module> </dependencies>
<module>ruoyi-modules</module> </dependencyManagement>
<module>ruoyi-api</module>
<module>ruoyi-common</module> <modules>
</modules> <module>ruoyi-auth</module>
<packaging>pom</packaging> <module>ruoyi-gateway</module>
<module>ruoyi-visual</module>
<dependencies> <module>ruoyi-modules</module>
<!-- bootstrap 启动器 --> <module>ruoyi-api</module>
<dependency> <module>ruoyi-common</module>
<groupId>org.springframework.cloud</groupId> </modules>
<artifactId>spring-cloud-starter-bootstrap</artifactId> <packaging>pom</packaging>
</dependency>
</dependencies> <dependencies>
<!-- bootstrap 启动器 -->
<build> <dependency>
<plugins> <groupId>org.springframework.cloud</groupId>
<plugin> <artifactId>spring-cloud-starter-bootstrap</artifactId>
<groupId>org.apache.maven.plugins</groupId> </dependency>
<artifactId>maven-compiler-plugin</artifactId> <dependency>
<configuration> <groupId>org.springframework.boot</groupId>
<source>${java.version}</source> <artifactId>spring-boot-starter-test</artifactId>
<target>${java.version}</target> <scope>test</scope>
<encoding>${project.build.sourceEncoding}</encoding> </dependency>
</configuration> <dependency>
</plugin> <groupId>org.jetbrains.kotlin</groupId>
</plugins> <artifactId>kotlin-stdlib-jdk8</artifactId>
<pluginManagement> <version>${kotlin.version}</version>
<plugins> </dependency>
<plugin> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>kotlin-test-junit</artifactId>
<version>${spring-boot.version}</version> <version>${kotlin.version}</version>
<executions> <scope>test</scope>
<execution> </dependency>
<goals> </dependencies>
<goal>repackage</goal>
</goals> <build>
</execution> <plugins>
</executions> <!-- 指定多个源代码目录、多个资源文件目录 -->
</plugin> <plugin>
</plugins> <groupId>org.codehaus.mojo</groupId>
</pluginManagement> <artifactId>build-helper-maven-plugin</artifactId>
</build> <version>1.8</version>
<executions>
<repositories> <execution>
<repository> <id>add-source</id>
<id>public</id> <phase>generate-sources</phase>
<name>aliyun nexus</name> <goals>
<url>https://maven.aliyun.com/repository/public</url> <goal>add-source</goal>
<releases> </goals>
<enabled>true</enabled> <configuration>
</releases> <sources>
</repository> <source>src/main/java</source>
</repositories> <source>src/main/kotlin</source>
</sources>
<pluginRepositories> </configuration>
<pluginRepository> </execution>
<id>public</id> </executions>
<name>aliyun nexus</name> </plugin>
<url>https://maven.aliyun.com/repository/public</url> <plugin>
<releases> <groupId>org.apache.maven.plugins</groupId>
<enabled>true</enabled> <artifactId>maven-compiler-plugin</artifactId>
</releases> <configuration>
<snapshots> <source>${java.version}</source>
<enabled>false</enabled> <target>${java.version}</target>
</snapshots> <encoding>${project.build.sourceEncoding}</encoding>
</pluginRepository> </configuration>
</pluginRepositories> </plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project> </project>

View File

@ -1,22 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<modules> <modules>
<module>ruoyi-api-system</module> <module>ruoyi-api-system</module>
</modules> </modules>
<artifactId>ruoyi-api</artifactId> <artifactId>ruoyi-api</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<description> <description>
ruoyi-api系统接口 ruoyi-api系统接口
</description> </description>
</project> </project>

View File

@ -1,28 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api</artifactId> <artifactId>ruoyi-api</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-api-system</artifactId> <artifactId>ruoyi-api-system</artifactId>
<description> <description>
ruoyi-api-system系统接口模块 ruoyi-api-system系统接口模块
</description> </description>
<dependencies> <dependencies>
<!-- RuoYi Common Core--> <!-- RuoYi Common Core-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-core</artifactId> <artifactId>ruoyi-common-core</artifactId>
</dependency> </dependency>
<dependency>
</dependencies> <groupId>com.zkjiadi</groupId>
<artifactId>zkjiadi-mall-api</artifactId>
<version>1.0.7</version>
<exclusions>
<exclusion>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -1,54 +1,61 @@
package com.ruoyi.system.api; package com.ruoyi.system.api;
import org.springframework.cloud.openfeign.FeignClient; import com.ruoyi.system.api.inner.InnerRemoteUserService;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestBody;
import com.ruoyi.common.core.constant.SecurityConstants; import org.springframework.web.bind.annotation.RequestHeader;
import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.factory.RemoteUserFallbackFactory; import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser; import com.ruoyi.system.api.factory.RemoteUserFallbackFactory;
import com.ruoyi.system.api.model.LoginUser;
/**
* /**
* *
* @author ruoyi *
*/ * @author ruoyi
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) */
public interface RemoteUserService @FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
{ public interface RemoteUserService extends InnerRemoteUserService
/** {
* /**
* *
* @param username *
* @param source * @param username
* @return * @param source
*/ * @return
@GetMapping("/user/info/{username}") */
public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); @GetMapping("/user/info/{username}")
public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* /**
* *
* @param sysUser *
* @param source * @param sysUser
* @return * @param source
*/ * @return
@PostMapping("/user/register") */
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); @PostMapping("/user/register")
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* IP /**
* * IP
* @param sysUser *
* @param source * @param sysUser
* @return * @param source
*/ * @return
@PutMapping("/user/recordlogin") */
public R<Boolean> recordUserLogin(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); @PutMapping("/user/recordlogin")
} public R<Boolean> recordUserLogin(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* go
*/
@PostMapping("/user/syncGO")
public R<Boolean> syncGO(@RequestBody SysUser sysUser);
}

View File

@ -81,6 +81,12 @@ public class SysUser extends BaseEntity
}) })
private SysDept dept; private SysDept dept;
/** 部门对象 */
@Excels({
@Excel(name = "微信UnionId", targetAttr = "wxUnionId", type = Type.EXPORT)
})
private KSysUserAccount sysUserAccount;
/** 角色对象 */ /** 角色对象 */
private List<SysRole> roles; private List<SysRole> roles;
@ -271,6 +277,14 @@ public class SysUser extends BaseEntity
this.dept = dept; this.dept = dept;
} }
public KSysUserAccount getSysUserAccount() {
return sysUserAccount;
}
public void setSysUserAccount(KSysUserAccount sysUserAccount) {
this.sysUserAccount = sysUserAccount;
}
public List<SysRole> getRoles() public List<SysRole> getRoles()
{ {
return roles; return roles;
@ -334,6 +348,7 @@ public class SysUser extends BaseEntity
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.append("dept", getDept()) .append("dept", getDept())
.append("userAccount", getSysUserAccount())
.toString(); .toString();
} }
} }

View File

@ -1,47 +1,93 @@
package com.ruoyi.system.api.factory; package com.ruoyi.system.api.factory;
import org.slf4j.Logger; import com.github.pagehelper.Page;
import org.slf4j.LoggerFactory; import com.ruoyi.system.api.domain.KSysUserAccount;
import org.springframework.cloud.openfeign.FallbackFactory; import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component; import org.slf4j.Logger;
import com.ruoyi.common.core.domain.R; import org.slf4j.LoggerFactory;
import com.ruoyi.system.api.RemoteUserService; import org.springframework.cloud.openfeign.FallbackFactory;
import com.ruoyi.system.api.domain.SysUser; import org.springframework.stereotype.Component;
import com.ruoyi.system.api.model.LoginUser; import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.RemoteUserService;
/** import com.ruoyi.system.api.domain.SysUser;
* import com.ruoyi.system.api.model.LoginUser;
*
* @author ruoyi /**
*/ *
@Component *
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService> * @author ruoyi
{ */
private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class); @Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService>
@Override {
public RemoteUserService create(Throwable throwable) private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);
{
log.error("用户服务调用失败:{}", throwable.getMessage()); @Override
return new RemoteUserService() public RemoteUserService create(Throwable throwable)
{ {
@Override log.error("用户服务调用失败:{}", throwable.getMessage());
public R<LoginUser> getUserInfo(String username, String source) return new RemoteUserService()
{ {
return R.fail("获取用户失败:" + throwable.getMessage()); @NotNull
} @Override
public R<LoginUser> getById_Inner(Long userId, @NotNull String source) {
@Override return R.fail("获取用户失败:" + throwable.getMessage());
public R<Boolean> registerUserInfo(SysUser sysUser, String source) }
{
return R.fail("注册用户失败:" + throwable.getMessage()); @Override
} public R<LoginUser> getByWxUnionId_Inner(String unionid, String source) {
return R.fail("获取用户失败:" + throwable.getMessage());
@Override }
public R<Boolean> recordUserLogin(SysUser sysUser, String source)
{ @Override
return R.fail("记录用户登录信息失败:" + throwable.getMessage()); public R<LoginUser> getUserInfo(String username, String source)
} {
}; return R.fail("获取用户失败:" + throwable.getMessage());
} }
}
@NotNull
@Override
public R<LoginUser> getByPhoneNumber_Inner(@NotNull String phoneNumber, @NotNull String source) {
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<Page<SysUser>> findByPhoneNumberStartingWith_Inner(String phoneNumber, String source) {
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> registerUserInfo(SysUser sysUser, String source)
{
return R.fail("注册用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> recordUserLogin(SysUser sysUser, String source)
{
return R.fail("记录用户登录信息失败:" + throwable.getMessage());
}
@Override
public R<Boolean> syncGO(SysUser sysUser) {
return R.fail("同步用户信息至GO失败:" + throwable.getMessage());
}
@NotNull
@Override
public R<LoginUser> edit_Inner(@NotNull LoginUser user, @NotNull String source) {
return R.fail("修改用户信息失败:" + throwable.getMessage());
}
@Override
public R<Boolean> registerUserBySysUserAccount_Inner(KSysUserAccount sysUserAccount, Long deptId, String source) {
return R.fail("注册用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> unbindWeixin_Inner(Long userId, String source) {
return R.fail("解绑微信失败:" + throwable.getMessage());
}
};
}
}

View File

@ -0,0 +1,77 @@
package com.ruoyi.system.api.inner;
import com.github.pagehelper.Page;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.domain.KSysUserAccount;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
public interface InnerRemoteUserService {
/**
* ID
*
* @param userId ID
* @param source
* @return
*/
@GetMapping("/inner/user/detail/{userId}")
R<LoginUser> getById_Inner(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* ID
*
* @param unionid unionid
* @param source
* @return
*/
@GetMapping("/inner/user/detail/wx/unionid/{unionid}")
R<LoginUser> getByWxUnionId_Inner(@PathVariable("unionid") String unionid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
*
* @param phoneNumber
* @param source
* @return
*/
@GetMapping("/inner/user/info/phoneNumber/{phoneNumber:\\d+}")
R<LoginUser> getByPhoneNumber_Inner(@PathVariable("phoneNumber") String phoneNumber, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
*
* @param phoneNumber
* @param source
* @return
*/
@GetMapping("/inner/user/list/phoneNumber/{phoneNumber:\\d+}")
R<Page<SysUser>> findByPhoneNumberStartingWith_Inner(@PathVariable("phoneNumber") String phoneNumber, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PutMapping("/inner/user")
R<LoginUser> edit_Inner(@RequestBody LoginUser user, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
*
* @param sysUserAccount unionId
* @param deptId ID
* @param source
* @return
*/
@PostMapping("/inner/user/register/dept/{deptId}/wx/unionid")
R<Boolean> registerUserBySysUserAccount_Inner(@RequestBody KSysUserAccount sysUserAccount, @PathVariable("deptId") Long deptId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
*
* @param userId ID
* @param source
* @return
*/
@PutMapping("/inner/user/{userId}/unbind/weixin")
R<Boolean> unbindWeixin_Inner(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -0,0 +1,19 @@
package com.ruoyi.system.api
import com.ruoyi.common.core.constant.ServiceNameConstants
import com.ruoyi.system.api.factory.RemoteUserFallbackFactory
import com.ruoyi.system.api.inner.InnerRemoteSysNoticeService
import org.springframework.cloud.openfeign.FeignClient
/**
* 公告服务
* @author 栾成伟
*/
@FeignClient(
contextId = "remoteSysNoticeService",
value = ServiceNameConstants.SYSTEM_SERVICE,
fallbackFactory = RemoteUserFallbackFactory::class
)
interface RemoteSysNoticeService : InnerRemoteSysNoticeService {
}

View File

@ -0,0 +1,21 @@
package com.ruoyi.system.api.domain
import com.cyl.manager.ums.domain.entity.MemberWechat
open class KSysUserAccount : MemberWechat() {
/** 用户ID */
open var userId: Long? = null
set(value) {
memberId = value
field = value
}
get() = memberId
/** 微信UnionId */
open var wxUnionId: String? = null
set(value) {
unionid = value
field = value
}
get() = unionid
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.system.api.factory
import com.ruoyi.common.core.domain.R
import com.ruoyi.system.api.RemoteSysNoticeService
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.cloud.openfeign.FallbackFactory
import org.springframework.stereotype.Component
@Component
open class RemoteSysNoticeFallbackFactory : FallbackFactory<RemoteSysNoticeService> {
companion object {
var log: Logger = LoggerFactory.getLogger(RemoteSysNoticeFallbackFactory::class.java)
}
override fun create(throwable: Throwable): RemoteSysNoticeService {
log.error("公告服务调用失败:{}", throwable.message)
return object : RemoteSysNoticeService {
override fun getById_Inner(noticeId: Long, source: String): R<Any> {
return R.fail("获取公告失败")
}
}
}
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.system.api.inner
import com.ruoyi.common.core.constant.SecurityConstants
import com.ruoyi.common.core.domain.R
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestParam
interface InnerRemoteSysNoticeService {
/**
* 根据公告ID查询公告信息
* @param noticeId 公告ID
* @return 公告信息
*/
@GetMapping("/inner/notice/detail")
fun getById_Inner(
@RequestParam("noticeId") noticeId: Long,
@RequestHeader(SecurityConstants.FROM_SOURCE) source: String
): R<Any>
}

View File

@ -1,74 +1,77 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-auth</artifactId> <artifactId>ruoyi-auth</artifactId>
<description> <description>
ruoyi-auth认证授权中心 ruoyi-auth认证授权中心
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Alibaba Nacos --> <!-- SpringCloud Alibaba Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos Config --> <!-- SpringCloud Alibaba Nacos Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel --> <!-- SpringCloud Alibaba Sentinel -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- SpringBoot Web --> <!-- SpringBoot Web -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Security--> <!-- RuoYi Common Security-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-security</artifactId> <artifactId>ruoyi-common-security</artifactId>
</dependency> </dependency>
<dependency>
</dependencies> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<build> </dependency>
<finalName>${project.artifactId}</finalName> </dependencies>
<plugins>
<plugin> <build>
<groupId>org.springframework.boot</groupId> <finalName>${project.artifactId}</finalName>
<artifactId>spring-boot-maven-plugin</artifactId> <plugins>
<executions> <plugin>
<execution> <groupId>org.springframework.boot</groupId>
<goals> <artifactId>spring-boot-maven-plugin</artifactId>
<goal>repackage</goal> <executions>
</goals> <execution>
</execution> <goals>
</executions> <goal>repackage</goal>
</plugin> </goals>
</plugins> </execution>
</build> </executions>
</plugin>
</project> </plugins>
</build>
</project>

View File

@ -1,11 +1,11 @@
package com.ruoyi.auth.controller; package com.ruoyi.auth.controller;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.auth.form.LoginBody; import com.ruoyi.auth.form.LoginBody;
import com.ruoyi.auth.form.RegisterBody; import com.ruoyi.auth.form.RegisterBody;
import com.ruoyi.auth.service.SysLoginService; import com.ruoyi.auth.service.SysLoginService;
@ -46,11 +46,16 @@ public class TokenController
String token = SecurityUtils.getToken(request); String token = SecurityUtils.getToken(request);
if (StringUtils.isNotEmpty(token)) if (StringUtils.isNotEmpty(token))
{ {
String username = JwtUtils.getUserName(token); try{
// 删除用户缓存记录 String username = JwtUtils.getUserName(token);
AuthUtil.logoutByToken(token); // 删除用户缓存记录
// 记录用户退出日志 AuthUtil.logoutByToken(token);
sysLoginService.logout(username); // 记录用户退出日志
sysLoginService.logout(username);
}catch (Exception e){
System.out.println(e.getMessage());
return R.ok();
}
} }
return R.ok(); return R.ok();
} }
@ -75,4 +80,18 @@ public class TokenController
sysLoginService.register(registerBody.getUsername(), registerBody.getPassword()); sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
return R.ok(); return R.ok();
} }
/**
*
*
*
* @return ResponseEntity:
*/
@RequestMapping("verify")
public ResponseEntity<?> verifyToken(HttpServletResponse response) {
response.setHeader("X-User-ID", String.valueOf(SecurityUtils.getUserId()));
// 返回一个HTTP 200 OK响应表示令牌有效
return ResponseEntity.ok().build();
}
} }

View File

@ -0,0 +1,140 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Configuration properties for web management endpoints.
*
* @author Madhura Bhave
* @author Phillip Webb
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.endpoints.web")
public class WebEndpointProperties {
private final Exposure exposure = new Exposure();
/**
* Base path for Web endpoints. Relative to the servlet context path
* (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when
* the management server is sharing the main server port. Relative to the management
* server base path (management.server.base-path) when a separate management server
* port (management.server.port) is configured.
*/
private String basePath = "/actuator";
private String baseUrl = null;
/**
* Mapping between endpoint IDs and the path that should expose them.
*/
private final Map<String, String> pathMapping = new LinkedHashMap<>();
private final Discovery discovery = new Discovery();
public Exposure getExposure() {
return this.exposure;
}
public String getBasePath() {
return this.basePath;
}
public void setBasePath(String basePath) {
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty");
this.basePath = cleanBasePath(basePath);
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
private String cleanBasePath(String basePath) {
if (StringUtils.hasText(basePath) && basePath.endsWith("/")) {
return basePath.substring(0, basePath.length() - 1);
}
return basePath;
}
public Map<String, String> getPathMapping() {
return this.pathMapping;
}
public Discovery getDiscovery() {
return this.discovery;
}
public static class Exposure {
/**
* Endpoint IDs that should be included or '*' for all.
*/
private Set<String> include = new LinkedHashSet<>();
/**
* Endpoint IDs that should be excluded or '*' for all.
*/
private Set<String> exclude = new LinkedHashSet<>();
public Set<String> getInclude() {
return this.include;
}
public void setInclude(Set<String> include) {
this.include = include;
}
public Set<String> getExclude() {
return this.exclude;
}
public void setExclude(Set<String> exclude) {
this.exclude = exclude;
}
}
public static class Discovery {
/**
* Whether the discovery page is enabled.
*/
private boolean enabled = true;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.web.servlet;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* A custom {@link HandlerMapping} that makes web endpoints available over HTTP using
* Spring MVC.
*
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0
*/
public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping {
private final EndpointLinksResolver linksResolver;
@Lazy
@Resource
private WebEndpointProperties webEndpointProperties;
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping);
this.linksResolver = linksResolver;
setOrder(-100);
}
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
* @param pathPatternParser the path pattern parser
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping,
PathPatternParser pathPatternParser) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping,
pathPatternParser);
this.linksResolver = linksResolver;
setOrder(-100);
}
@Override
protected LinksHandler getLinksHandler() {
return new WebMvcLinksHandler();
}
/**
* Handler for root endpoint providing links.
*/
class WebMvcLinksHandler implements LinksHandler {
@Override
@ResponseBody
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath())));
}
@Override
public String toString() {
return "Actuator root web endpoint";
}
}
}

View File

@ -0,0 +1,33 @@
# Tomcat
server:
port: 9200
#测试环境
spring:
application:
# 应用名称
name: ruoyi-auth
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: prod-ruoyi-auth.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,33 @@
# Tomcat
server:
port: 9200
# Spring
spring:
application:
# 应用名称
name: ruoyi-auth
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: dev-ruoyi-auth.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,34 @@
# Tomcat
server:
port: 9200
#测试环境
spring:
application:
# 应用名称
name: ruoyi-auth
cloud:
nacos:
discovery:
ip: 8.155.60.167
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: prod-ruoyi-auth.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,33 @@
# Tomcat
server:
port: 9200
#测试环境
spring:
application:
# 应用名称
name: ruoyi-auth
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: test-ruoyi-auth.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -1,25 +1,4 @@
# Tomcat # Spring默认环境配置
server: spring:
port: 9200 profiles:
active: dev
# Spring
spring:
application:
# 应用名称
name: ruoyi-auth
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<modules> <modules>
<module>ruoyi-common-log</module> <module>ruoyi-common-log</module>
<module>ruoyi-common-core</module> <module>ruoyi-common-core</module>
<module>ruoyi-common-redis</module> <module>ruoyi-common-redis</module>
<module>ruoyi-common-seata</module> <module>ruoyi-common-seata</module>
<module>ruoyi-common-swagger</module> <module>ruoyi-common-swagger</module>
<module>ruoyi-common-security</module> <module>ruoyi-common-security</module>
<module>ruoyi-common-sensitive</module> <module>ruoyi-common-sensitive</module>
<module>ruoyi-common-datascope</module> <module>ruoyi-common-datascope</module>
<module>ruoyi-common-datasource</module> <module>ruoyi-common-datasource</module>
</modules> </modules>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<description> <description>
ruoyi-common通用模块 ruoyi-common通用模块
</description> </description>
</project> </project>

View File

@ -1,112 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-core</artifactId> <artifactId>ruoyi-common-core</artifactId>
<description> <description>
ruoyi-common-core核心模块 ruoyi-common-core核心模块
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Openfeign --> <!-- SpringCloud Openfeign -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> </dependency>
<!-- SpringCloud Loadbalancer --> <!-- SpringCloud Loadbalancer -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId> <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency> </dependency>
<!-- Spring Context Support --> <!-- Spring Context Support -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId> <artifactId>spring-context-support</artifactId>
</dependency> </dependency>
<!-- Spring Web --> <!-- Spring Web -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId> <artifactId>spring-web</artifactId>
</dependency> </dependency>
<!-- Transmittable ThreadLocal --> <!-- Transmittable ThreadLocal -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId> <artifactId>transmittable-thread-local</artifactId>
</dependency> </dependency>
<!-- Pagehelper --> <!-- Pagehelper -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId> <artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency> </dependency>
<!-- Hibernate Validator --> <!-- Hibernate Validator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
</dependency> </dependency>
<!-- Jackson --> <!-- Jackson -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<!-- Alibaba Fastjson --> <!-- Alibaba Fastjson -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId> <artifactId>fastjson2</artifactId>
</dependency> </dependency>
<!-- Jwt --> <!-- Jwt -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId> <artifactId>jjwt</artifactId>
</dependency> </dependency>
<!-- Jaxb --> <!-- Jaxb -->
<dependency> <dependency>
<groupId>javax.xml.bind</groupId> <groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId> <artifactId>jaxb-api</artifactId>
</dependency> </dependency>
<!-- Apache Lang3 --> <!-- Apache Lang3 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<!-- Commons Io --> <!-- Commons Io -->
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
</dependency> </dependency>
<!-- excel工具 --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
</dependency> </dependency>
<!-- Java Servlet --> <!-- Java Servlet -->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -12,6 +12,20 @@ public class SecurityConstants
*/ */
public static final String DETAILS_USER_ID = "user_id"; public static final String DETAILS_USER_ID = "user_id";
/**
* ID
*/
public static final String DETAILS_SUB = "sub";
/**
* ID
*/
public static final String DETAILS_IAT= "iat";
/**
* ID
*/
public static final String DETAILS_EXP= "exp";
/** /**
* *
*/ */
@ -22,6 +36,11 @@ public class SecurityConstants
*/ */
public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String AUTHORIZATION_HEADER = "Authorization";
/**
* WEBSOCKET
*/
public final static String WEBSOCKET_HEADER = "Sec-WebSocket-Key";
/** /**
* *
*/ */

View File

@ -16,5 +16,4 @@ public class TokenConstants
* *
*/ */
public final static String SECRET = "abcdefghijklmnopqrstuvwxyz"; public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
} }

View File

@ -1,13 +1,18 @@
package com.ruoyi.common.core.utils; package com.ruoyi.common.core.utils;
import java.util.Base64;
import java.util.Map; import java.util.Map;
import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.TokenConstants; import com.ruoyi.common.core.constant.TokenConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureAlgorithm;
import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletResponse;
/** /**
* Jwt * Jwt
* *
@ -15,7 +20,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
*/ */
public class JwtUtils public class JwtUtils
{ {
public static String secret = TokenConstants.SECRET; public static String secret = Base64.getEncoder().encodeToString(TokenConstants.SECRET.getBytes()) ;
/** /**
* *

View File

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-datascope</artifactId> <artifactId>ruoyi-common-datascope</artifactId>
<description> <description>
ruoyi-common-datascope权限范围 ruoyi-common-datascope权限范围
</description> </description>
<dependencies> <dependencies>
<!-- RuoYi Common Security --> <!-- RuoYi Common Security -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-security</artifactId> <artifactId>ruoyi-common-security</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,35 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-datasource</artifactId> <artifactId>ruoyi-common-datasource</artifactId>
<description> <description>
ruoyi-common-datasource多数据源 ruoyi-common-datasource多数据源
</description> </description>
<dependencies> <dependencies>
<!-- Druid --> <!-- Druid -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version> <version>${druid.version}</version>
</dependency> </dependency>
<!-- Dynamic DataSource --> <!-- Dynamic DataSource -->
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version> <version>${dynamic-ds.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-log</artifactId> <artifactId>ruoyi-common-log</artifactId>
<description> <description>
ruoyi-common-log日志记录 ruoyi-common-log日志记录
</description> </description>
<dependencies> <dependencies>
<!-- RuoYi Common Security --> <!-- RuoYi Common Security -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-security</artifactId> <artifactId>ruoyi-common-security</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,33 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-redis</artifactId> <artifactId>ruoyi-common-redis</artifactId>
<description> <description>
ruoyi-common-redis缓存服务 ruoyi-common-redis缓存服务
</description> </description>
<dependencies> <dependencies>
<!-- SpringBoot Boot Redis --> <!-- SpringBoot Boot Redis -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Core--> <!-- RuoYi Common Core-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-core</artifactId> <artifactId>ruoyi-common-core</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

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

View File

@ -1,39 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-security</artifactId> <artifactId>ruoyi-common-security</artifactId>
<description> <description>
ruoyi-common-security安全模块 ruoyi-common-security安全模块
</description> </description>
<dependencies> <dependencies>
<!-- Spring Web --> <!-- Spring Web -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId> <artifactId>spring-webmvc</artifactId>
</dependency> </dependency>
<!-- RuoYi Api System --> <!-- RuoYi Api System -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-system</artifactId> <artifactId>ruoyi-api-system</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Redis--> <!-- RuoYi Common Redis-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-redis</artifactId> <artifactId>ruoyi-common-redis</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,9 +1,15 @@
package com.ruoyi.common.security.service; package com.ruoyi.common.security.service;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.impl.DefaultClaims;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -61,7 +67,10 @@ public class TokenService
claimsMap.put(SecurityConstants.USER_KEY, token); claimsMap.put(SecurityConstants.USER_KEY, token);
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
claimsMap.put(SecurityConstants.DETAILS_SUB,userId);
int now = Math.toIntExact(System.currentTimeMillis() / 1000);
claimsMap.put(SecurityConstants.DETAILS_IAT,now);
claimsMap.put(SecurityConstants.DETAILS_EXP,now+TOKEN_EXPIRE_TIME*60);
// 接口返回信息 // 接口返回信息
Map<String, Object> rspMap = new HashMap<String, Object>(); Map<String, Object> rspMap = new HashMap<String, Object>();
rspMap.put("access_token", JwtUtils.createToken(claimsMap)); rspMap.put("access_token", JwtUtils.createToken(claimsMap));

View File

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

View File

@ -1,33 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-swagger</artifactId> <artifactId>ruoyi-common-swagger</artifactId>
<description> <description>
ruoyi-common-swagger系统接口 ruoyi-common-swagger系统接口
</description> </description>
<dependencies> <dependencies>
<!-- SpringBoot Web --> <!-- SpringBoot Web -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- SpringDoc webmvc --> <!-- SpringDoc webmvc -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId> <artifactId>springdoc-openapi-ui</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,105 +1,166 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-gateway</artifactId> <artifactId>ruoyi-gateway</artifactId>
<description> <description>
ruoyi-gateway网关模块 ruoyi-gateway网关模块
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Gateway --> <!-- SpringCloud Gateway -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId> <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos --> <!-- SpringCloud Alibaba Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos Config --> <!-- SpringCloud Alibaba Nacos Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel --> <!-- SpringCloud Alibaba Sentinel -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel Gateway --> <!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency> </dependency>
<!-- Sentinel Datasource Nacos --> <!-- Sentinel Datasource Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.csp</groupId> <groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId> <artifactId>sentinel-datasource-nacos</artifactId>
</dependency> </dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- SpringCloud Loadbalancer --> <!-- SpringCloud Loadbalancer -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId> <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency> </dependency>
<!--验证码 --> <!--验证码 -->
<dependency> <dependency>
<groupId>pro.fessional</groupId> <groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Redis--> <!-- RuoYi Common Redis-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-redis</artifactId> <artifactId>ruoyi-common-redis</artifactId>
</dependency> </dependency>
<!-- Springdoc --> <dependency>
<dependency> <groupId>com.squareup.okhttp3</groupId>
<groupId>org.springdoc</groupId> <artifactId>okhttp</artifactId>
<artifactId>springdoc-openapi-webflux-ui</artifactId> <version>3.12.13</version>
<version>${springdoc.version}</version> </dependency>
</dependency> <dependency>
<groupId>com.ujcms</groupId>
</dependencies> <artifactId>ujcms-commons</artifactId>
<version>9.6.0.0.1</version>
<build> <exclusions>
<finalName>${project.artifactId}</finalName> <exclusion>
<plugins> <groupId>org.springframework</groupId>
<plugin> <artifactId>spring-core</artifactId>
<groupId>org.springframework.boot</groupId> </exclusion>
<artifactId>spring-boot-maven-plugin</artifactId> <exclusion>
<executions> <groupId>org.springframework</groupId>
<execution> <artifactId>spring-web</artifactId>
<goals> </exclusion>
<goal>repackage</goal> </exclusions>
</goals> </dependency>
</execution>
</executions> <!-- Springdoc -->
</plugin> <dependency>
</plugins> <groupId>org.springdoc</groupId>
</build> <artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>${springdoc.version}</version>
</project> </dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework</groupId>-->
<!-- <artifactId>spring-webmvc</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,83 +1,115 @@
package com.ruoyi.gateway.config; package com.ruoyi.gateway.config;
import java.util.Properties; import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.beans.factory.annotation.Value;
import com.google.code.kaptcha.impl.DefaultKaptcha; import org.springframework.context.annotation.Bean;
import com.google.code.kaptcha.util.Config; import org.springframework.context.annotation.Configuration;
import static com.google.code.kaptcha.Constants.*; import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
/**
* import static com.google.code.kaptcha.Constants.*;
*
* @author ruoyi /**
*/ *
@Configuration *
public class CaptchaConfig * @author ruoyi
{ */
@Bean(name = "captchaProducer") @Configuration
public DefaultKaptcha getKaptchaBean() public class CaptchaConfig {
{ @Value("${" + KAPTCHA_TEXTPRODUCER_CHAR_LENGTH + "}")
DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); private String textProducerCharLength;
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yesno @Bean(name = "captchaProducer")
properties.setProperty(KAPTCHA_BORDER, "yes"); public DefaultKaptcha getKaptchaBean() {
// 验证码文本字符颜色 默认为Color.BLACK DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); Properties properties = new Properties();
// 验证码图片宽度 默认为200 // 是否有边框 默认为true 我们可以自己设置yesno
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); properties.setProperty(KAPTCHA_BORDER, "yes");
// 验证码图片高度 默认为50 // 验证码文本字符颜色 默认为Color.BLACK
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 验证码文本字符大小 默认为40 // 验证码图片宽度 默认为200
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// KAPTCHA_SESSION_KEY // 验证码图片高度 默认为50
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// 验证码文本字符长度 默认为5 // 验证码文本字符大小 默认为40
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) // KAPTCHA_SESSION_KEY
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy // 验证码文本字符长度 默认为5
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, textProducerCharLength);
Config config = new Config(properties); // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
defaultKaptcha.setConfig(config); properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
return defaultKaptcha; // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
} properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, com.google.code.kaptcha.impl.ShadowGimpy.class.getName());
Config config = new Config(properties);
@Bean(name = "captchaProducerMath") defaultKaptcha.setConfig(config);
public DefaultKaptcha getKaptchaBeanMath() return defaultKaptcha;
{ }
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties(); @Bean(name = "captchaProducerMath")
// 是否有边框 默认为true 我们可以自己设置yesno public DefaultKaptcha getKaptchaBeanMath() {
properties.setProperty(KAPTCHA_BORDER, "yes"); DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
// 边框颜色 默认为Color.BLACK Properties properties = new Properties();
properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); // 是否有边框 默认为true 我们可以自己设置yesno
// 验证码文本字符颜色 默认为Color.BLACK properties.setProperty(KAPTCHA_BORDER, "yes");
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); // 边框颜色 默认为Color.BLACK
// 验证码图片宽度 默认为200 properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); // 验证码文本字符颜色 默认为Color.BLACK
// 验证码图片高度 默认为50 properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); // 验证码图片宽度 默认为200
// 验证码文本字符大小 默认为40 properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); // 验证码图片高度 默认为50
// KAPTCHA_SESSION_KEY properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); // 验证码文本字符大小 默认为40
// 验证码文本生成器 properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); // KAPTCHA_SESSION_KEY
// 验证码文本字符间距 默认为2 properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); // 验证码文本生成器
// 验证码文本字符长度 默认为5 properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, com.ruoyi.gateway.config.KaptchaTextCreator.class.getName());
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); // 验证码文本字符间距 默认为2
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); // 验证码文本字符长度 默认为5
// 验证码噪点颜色 默认为Color.BLACK properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
// 干扰实现类 properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); // 验证码噪点颜色 默认为Color.BLACK
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); // 干扰实现类
Config config = new Config(properties); properties.setProperty(KAPTCHA_NOISE_IMPL, com.google.code.kaptcha.impl.NoNoise.class.getName());
defaultKaptcha.setConfig(config); // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
return defaultKaptcha; properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, com.google.code.kaptcha.impl.ShadowGimpy.class.getName());
} Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
@Bean(name = "captchaProducerNumber")
public DefaultKaptcha getKaptchaBeanNumber() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yesno
properties.setProperty(KAPTCHA_BORDER, "yes");
// 验证码文本字符颜色 默认为Color.BLACK
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 验证码图片宽度 默认为200
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// 验证码图片高度 默认为50
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// 验证码文本字符大小 默认为40
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
// KAPTCHA_SESSION_KEY
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// 验证码文本生成器
properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, com.ruoyi.gateway.config.KaptchaNumberCreator.class.getName());
// 验证码文本字符长度 默认为5
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, textProducerCharLength);
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, com.google.code.kaptcha.impl.ShadowGimpy.class.getName());
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
} }

View File

@ -0,0 +1,17 @@
package com.ruoyi.gateway.config;
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
import com.ujcms.commons.security.Secures;
/**
*
*
* @author hsdllcw
*/
public class KaptchaNumberCreator extends DefaultTextCreator {
@Override
public String getText() {
return Secures.randomNumeric(getConfig().getTextProducerCharLength());
}
}

View File

@ -1,46 +1,84 @@
package com.ruoyi.gateway.config.properties; package com.ruoyi.gateway.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
@RefreshScope @RefreshScope
@ConfigurationProperties(prefix = "security.captcha") @ConfigurationProperties(prefix = "security.captcha")
public class CaptchaProperties public class CaptchaProperties
{ {
/** /**
* *
*/ */
private Boolean enabled; private Boolean enabled;
/** /**
* math char * math char
*/ */
private String type; private String type;
public Boolean getEnabled() public Boolean getEnabled()
{ {
return enabled; return enabled;
} }
public void setEnabled(Boolean enabled) public void setEnabled(Boolean enabled)
{ {
this.enabled = enabled; this.enabled = enabled;
} }
public String getType() public String getType()
{ {
return type; return type;
} }
public void setType(String type) public void setType(String type)
{ {
this.type = type; this.type = type;
} }
}
public static class SMS {
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "security.captcha.sms.aliyuncs")
public static class Aliyuncs {
private String accessKeyId;
private String accessKeySecret;
private String signName;
private String templateCode;
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getSignName() {
return signName;
}
public void setSignName(String signName) {
this.signName = signName;
}
public String getTemplateCode() {
return templateCode;
}
public void setTemplateCode(String templateCode) {
this.templateCode = templateCode;
}
}
}
}

View File

@ -44,7 +44,6 @@ public class AuthFilter implements GlobalFilter, Ordered
{ {
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest.Builder mutate = request.mutate(); ServerHttpRequest.Builder mutate = request.mutate();
String url = request.getURI().getPath(); String url = request.getURI().getPath();
// 跳过不需要验证的路径 // 跳过不需要验证的路径
if (StringUtils.matches(url, ignoreWhite.getWhites())) if (StringUtils.matches(url, ignoreWhite.getWhites()))
@ -56,11 +55,19 @@ public class AuthFilter implements GlobalFilter, Ordered
{ {
return unauthorizedResponse(exchange, "令牌不能为空"); return unauthorizedResponse(exchange, "令牌不能为空");
} }
Claims claims = JwtUtils.parseToken(token); /*Claims claims = JwtUtils.parseToken(token);
if (claims == null) if (claims == null)
{ {
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
} }*/
Claims claims;
try{
claims = JwtUtils.parseToken(token);
if (claims == null)
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
}catch (Exception e){
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
}
String userkey = JwtUtils.getUserKey(claims); String userkey = JwtUtils.getUserKey(claims);
boolean islogin = redisService.hasKey(getTokenKey(userkey)); boolean islogin = redisService.hasKey(getTokenKey(userkey));
if (!islogin) if (!islogin)

View File

@ -34,7 +34,6 @@ public class GatewayExceptionHandler implements ErrorWebExceptionHandler
} }
String msg; String msg;
if (ex instanceof NotFoundException) if (ex instanceof NotFoundException)
{ {
msg = "服务未找到"; msg = "服务未找到";

View File

@ -1,41 +1,55 @@
package com.ruoyi.gateway.handler; package com.ruoyi.gateway.handler;
import java.io.IOException; import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired; import java.util.Objects;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component; import com.ruoyi.common.core.utils.uuid.IdUtils;
import org.springframework.web.reactive.function.BodyInserters; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.BodyInserters;
import com.ruoyi.common.core.exception.CaptchaException; import org.springframework.web.reactive.function.server.HandlerFunction;
import com.ruoyi.common.core.web.domain.AjaxResult; import org.springframework.web.reactive.function.server.ServerRequest;
import com.ruoyi.gateway.service.ValidateCodeService; import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono; import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.web.domain.AjaxResult;
/** import com.ruoyi.gateway.service.ValidateCodeService;
* import reactor.core.publisher.Mono;
*
* @author ruoyi /**
*/ *
@Component *
public class ValidateCodeHandler implements HandlerFunction<ServerResponse> * @author ruoyi
{ */
@Autowired @Component
private ValidateCodeService validateCodeService; public class ValidateCodeHandler implements HandlerFunction<ServerResponse>
{
@Override @Autowired
public Mono<ServerResponse> handle(ServerRequest serverRequest) private ValidateCodeService validateCodeService;
{
AjaxResult ajax; @Override
try public Mono<ServerResponse> handle(ServerRequest serverRequest)
{ {
ajax = validateCodeService.createCaptcha(); AjaxResult ajax;
} try
catch (CaptchaException | IOException e) {
{ switch (serverRequest.queryParam("type").orElse("image")) {
return Mono.error(e); case "sms":
} if (Objects.nonNull(serverRequest.queryParam("receiver").orElse(null))) {
return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); ajax = validateCodeService.createSMSCaptcha(
} serverRequest.queryParam("receiver").orElse(null),
} serverRequest.queryParam("uuid").orElse(IdUtils.simpleUUID())
);
break;
}
default:
ajax = validateCodeService.createCaptcha();
}
}
catch (CaptchaException | IOException e)
{
return Mono.error(e);
}
return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax));
}
}

View File

@ -1,23 +1,28 @@
package com.ruoyi.gateway.service; package com.ruoyi.gateway.service;
import java.io.IOException; import java.io.IOException;
import com.ruoyi.common.core.exception.CaptchaException; import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
public interface ValidateCodeService public interface ValidateCodeService
{ {
/** /**
* *
*/ */
public AjaxResult createCaptcha() throws IOException, CaptchaException; public AjaxResult createCaptcha() throws IOException, CaptchaException;
/** /**
* *
*/ */
public void checkCaptcha(String key, String value) throws CaptchaException; public AjaxResult createSMSCaptcha(String receiver,String uuid) throws IOException, CaptchaException;
}
/**
*
*/
public void checkCaptcha(String key, String value) throws CaptchaException;
}

View File

@ -1,118 +1,173 @@
package com.ruoyi.gateway.service.impl; package com.ruoyi.gateway.service.impl;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.TimeUnit; import java.util.Arrays;
import javax.annotation.Resource; import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO; import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired; import javax.imageio.ImageIO;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream; import com.alibaba.fastjson2.JSONObject;
import com.google.code.kaptcha.Producer; import com.ujcms.commons.sms.AliyunUtils;
import com.ruoyi.common.core.constant.CacheConstants; import org.springframework.beans.factory.annotation.Autowired;
import com.ruoyi.common.core.constant.Constants; import org.springframework.core.env.Environment;
import com.ruoyi.common.core.exception.CaptchaException; import org.springframework.stereotype.Service;
import com.ruoyi.common.core.utils.StringUtils; import org.springframework.util.FastByteArrayOutputStream;
import com.ruoyi.common.core.utils.sign.Base64; import com.google.code.kaptcha.Producer;
import com.ruoyi.common.core.utils.uuid.IdUtils; import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.gateway.config.properties.CaptchaProperties; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.gateway.service.ValidateCodeService; import com.ruoyi.common.core.utils.sign.Base64;
import com.ruoyi.common.core.utils.uuid.IdUtils;
/** import com.ruoyi.common.core.web.domain.AjaxResult;
* import com.ruoyi.common.redis.service.RedisService;
* import com.ruoyi.gateway.config.properties.CaptchaProperties;
* @author ruoyi import com.ruoyi.gateway.service.ValidateCodeService;
*/
@Service /**
public class ValidateCodeServiceImpl implements ValidateCodeService *
{ *
@Resource(name = "captchaProducer") * @author ruoyi
private Producer captchaProducer; */
@Service
@Resource(name = "captchaProducerMath") public class ValidateCodeServiceImpl implements ValidateCodeService
private Producer captchaProducerMath; {
@Resource(name = "captchaProducer")
@Autowired private Producer captchaProducer;
private RedisService redisService;
@Resource(name = "captchaProducerMath")
@Autowired private Producer captchaProducerMath;
private CaptchaProperties captchaProperties;
@Resource(name = "captchaProducerNumber")
/** private Producer captchaProducerNumber;
*
*/ @Autowired
@Override private RedisService redisService;
public AjaxResult createCaptcha() throws IOException, CaptchaException
{ @Autowired
AjaxResult ajax = AjaxResult.success(); private CaptchaProperties captchaProperties;
boolean captchaEnabled = captchaProperties.getEnabled();
ajax.put("captchaEnabled", captchaEnabled); @Autowired
if (!captchaEnabled) private CaptchaProperties.SMS.Aliyuncs smsAliyuncs;
{
return ajax; @Autowired
} private Environment environment;
// 保存验证码信息 /**
String uuid = IdUtils.simpleUUID(); *
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; */
@Override
String capStr = null, code = null; public AjaxResult createCaptcha() throws IOException, CaptchaException
BufferedImage image = null; {
AjaxResult ajax = AjaxResult.success();
String captchaType = captchaProperties.getType(); boolean captchaEnabled = captchaProperties.getEnabled();
// 生成验证码 ajax.put("captchaEnabled", captchaEnabled);
if ("math".equals(captchaType)) if (!captchaEnabled)
{ {
String capText = captchaProducerMath.createText(); return ajax;
capStr = capText.substring(0, capText.lastIndexOf("@")); }
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr); // 保存验证码信息
} String uuid = IdUtils.simpleUUID();
else if ("char".equals(captchaType)) String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
{
capStr = code = captchaProducer.createText(); String capStr = null, code = null;
image = captchaProducer.createImage(capStr); BufferedImage image = null;
}
String captchaType = captchaProperties.getType();
redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); // 生成验证码
// 转换流信息写出 switch (captchaType) {
FastByteArrayOutputStream os = new FastByteArrayOutputStream(); case "number": {
try capStr = code = captchaProducerNumber.createText();
{ image = captchaProducerNumber.createImage(capStr);
ImageIO.write(image, "jpg", os); }
} break;
catch (IOException e) case "math": {
{ String capText = captchaProducerMath.createText();
return AjaxResult.error(e.getMessage()); capStr = capText.substring(0, capText.lastIndexOf("@"));
} code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
ajax.put("uuid", uuid); }
ajax.put("img", Base64.encode(os.toByteArray())); break;
return ajax; default: {
} capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
/** }
* break;
*/ }
@Override
public void checkCaptcha(String code, String uuid) throws CaptchaException redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
{ // 转换流信息写出
if (StringUtils.isEmpty(code)) FastByteArrayOutputStream os = new FastByteArrayOutputStream();
{ try
throw new CaptchaException("验证码不能为空"); {
} ImageIO.write(image, "jpg", os);
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); }
String captcha = redisService.getCacheObject(verifyKey); catch (IOException e)
if (captcha == null) {
{ return AjaxResult.error(e.getMessage());
throw new CaptchaException("验证码已失效"); }
}
redisService.deleteObject(verifyKey); ajax.put("uuid", uuid);
if (!code.equalsIgnoreCase(captcha)) ajax.put("img", Base64.encode(os.toByteArray()));
{ return ajax;
throw new CaptchaException("验证码错误"); }
}
} @Override
} public AjaxResult createSMSCaptcha(String receiver, String uuid) throws IOException, CaptchaException {
AjaxResult ajax = AjaxResult.success();
boolean captchaEnabled = captchaProperties.getEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled) {
return ajax;
}
// 保存验证码信息
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + receiver + ":" + uuid;
long expire = redisService.getExpire(verifyKey);
if (expire <= 0) {
String code = captchaProducerNumber.createText();
redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
expire = redisService.getExpire(verifyKey);
if (Arrays.stream(environment.getActiveProfiles()).toList().contains("prod")) {
AliyunUtils.sendSms(
smsAliyuncs.getAccessKeyId(),
smsAliyuncs.getAccessKeySecret(),
smsAliyuncs.getSignName(),
smsAliyuncs.getTemplateCode(),
JSONObject.of("code", code),
receiver
);
} else {
ajax.put("captchaCode",code);
}
ajax.put("codeLength", code.length());
}
ajax.put("expire", expire);
ajax.put("uuid", uuid);
return ajax;
}
/**
*
*/
@Override
public void checkCaptcha(String code, String uuid) throws CaptchaException
{
if (StringUtils.isEmpty(code))
{
throw new CaptchaException("验证码不能为空");
}
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisService.getCacheObject(verifyKey);
if (captcha == null)
{
throw new CaptchaException("验证码已失效");
}
redisService.deleteObject(verifyKey);
if (!code.equalsIgnoreCase(captcha))
{
throw new CaptchaException("验证码错误");
}
}
}

View File

@ -0,0 +1,39 @@
package com.ruoyi.gateway.config
import org.apache.commons.lang3.ObjectUtils
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.web.server.WebFilter
@Configuration
open class CorsConfig {
@Value("\${cors.orgins}")
private val corsOrgins: String? = null
@Bean
open fun corsFilter(): WebFilter {
return WebFilter { exchange, chain ->
val response = exchange.response
val request = exchange.request
if (!ObjectUtils.isEmpty(corsOrgins)) {
response.headers["Access-Control-Allow-Origin"] = corsOrgins
} else {
response.headers["Access-Control-Allow-Origin"] = "*"
}
response.headers["Access-Control-Expose-Headers"] = "*"
response.headers["Access-Control-Allow-Credentials"] = "true"
response.headers["Access-Control-Max-Age"] = "3600"
response.headers["Access-Control-Allow-Methods"] = "GET,POST,PUT,DELETE,OPTIONS,HEAD"
response.headers["Access-Control-Allow-Headers"] = "*"
if (HttpMethod.OPTIONS.equals(request.method)) {
response.statusCode = HttpStatus.OK
chain.filter(exchange)
}
chain.filter(exchange.mutate().request(request.mutate().build()).build())
}
}
}

View File

@ -0,0 +1,48 @@
# Tomcat
server:
port: 8080
# Spring
spring:
application:
# 应用名称
name: ruoyi-gateway
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: nacos.zkjiadi.cc:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: nacos.zkjiadi.cc
dataId: sentinel-ruoyi-gateway
groupId: DEFAULT_GROUP
data-type: json
rule-type: gw-flow
logging:
file:
name: dev-ruoyi-gateway.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,49 @@
# Tomcat
server:
port: 8080
# Spring
spring:
application:
# 应用名称
name: ruoyi-gateway
cloud:
nacos:
discovery:
ip: 8.155.60.167
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: nacos.zkjiadi.cc:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: nacos.zkjiadi.cc
dataId: sentinel-ruoyi-gateway
groupId: DEFAULT_GROUP
data-type: json
rule-type: gw-flow
logging:
file:
name: prod-ruoyi-gateway.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,48 @@
# Tomcat
server:
port: 8080
# Spring
spring:
application:
# 应用名称
name: ruoyi-gateway
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: nacos.zkjiadi.cc:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: nacos.zkjiadi.cc
dataId: sentinel-ruoyi-gateway
groupId: DEFAULT_GROUP
data-type: json
rule-type: gw-flow
logging:
file:
name: test-ruoyi-gateway.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -1,40 +1,4 @@
# Tomcat # Spring默认环境配置
server: spring:
port: 8080 profiles:
active: dev
# Spring
spring:
application:
# 应用名称
name: ruoyi-gateway
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: sentinel-ruoyi-gateway
groupId: DEFAULT_GROUP
data-type: json
rule-type: gw-flow

View File

@ -1,25 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<modules> <modules>
<module>ruoyi-system</module> <module>ruoyi-system</module>
<module>ruoyi-gen</module> <module>ruoyi-gen</module>
<module>ruoyi-job</module> <module>ruoyi-job</module>
<module>ruoyi-file</module> <module>ruoyi-file</module>
</modules> </modules>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<description> <description>
ruoyi-modules业务模块 ruoyi-modules业务模块
</description> </description>
</project> </project>

View File

@ -1,88 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-modules-file</artifactId> <artifactId>ruoyi-modules-file</artifactId>
<description> <description>
ruoyi-modules-file文件服务 ruoyi-modules-file文件服务
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Alibaba Nacos --> <!-- SpringCloud Alibaba Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos Config --> <!-- SpringCloud Alibaba Nacos Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel --> <!-- SpringCloud Alibaba Sentinel -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- SpringBoot Web --> <!-- SpringBoot Web -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- FastDFS --> <!-- FastDFS -->
<dependency> <dependency>
<groupId>com.github.tobato</groupId> <groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId> <artifactId>fastdfs-client</artifactId>
</dependency> </dependency>
<!-- Minio --> <!-- Minio -->
<dependency> <dependency>
<groupId>io.minio</groupId> <groupId>io.minio</groupId>
<artifactId>minio</artifactId> <artifactId>minio</artifactId>
<version>${minio.version}</version> <version>${minio.version}</version>
</dependency> </dependency>
<!-- RuoYi Api System --> <!-- RuoYi Api System -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-system</artifactId> <artifactId>ruoyi-api-system</artifactId>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>de.codecentric</groupId>
<build> <artifactId>spring-boot-admin-starter-client</artifactId>
<finalName>${project.artifactId}</finalName> </dependency>
<plugins> </dependencies>
<plugin>
<groupId>org.springframework.boot</groupId> <build>
<artifactId>spring-boot-maven-plugin</artifactId> <finalName>${project.artifactId}</finalName>
<executions> <plugins>
<execution> <plugin>
<goals> <groupId>org.springframework.boot</groupId>
<goal>repackage</goal> <artifactId>spring-boot-maven-plugin</artifactId>
</goals> <executions>
</execution> <execution>
</executions> <goals>
</plugin> <goal>repackage</goal>
</plugins> </goals>
</build> </execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -0,0 +1,140 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Configuration properties for web management endpoints.
*
* @author Madhura Bhave
* @author Phillip Webb
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.endpoints.web")
public class WebEndpointProperties {
private final Exposure exposure = new Exposure();
/**
* Base path for Web endpoints. Relative to the servlet context path
* (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when
* the management server is sharing the main server port. Relative to the management
* server base path (management.server.base-path) when a separate management server
* port (management.server.port) is configured.
*/
private String basePath = "/actuator";
private String baseUrl = null;
/**
* Mapping between endpoint IDs and the path that should expose them.
*/
private final Map<String, String> pathMapping = new LinkedHashMap<>();
private final Discovery discovery = new Discovery();
public Exposure getExposure() {
return this.exposure;
}
public String getBasePath() {
return this.basePath;
}
public void setBasePath(String basePath) {
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty");
this.basePath = cleanBasePath(basePath);
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
private String cleanBasePath(String basePath) {
if (StringUtils.hasText(basePath) && basePath.endsWith("/")) {
return basePath.substring(0, basePath.length() - 1);
}
return basePath;
}
public Map<String, String> getPathMapping() {
return this.pathMapping;
}
public Discovery getDiscovery() {
return this.discovery;
}
public static class Exposure {
/**
* Endpoint IDs that should be included or '*' for all.
*/
private Set<String> include = new LinkedHashSet<>();
/**
* Endpoint IDs that should be excluded or '*' for all.
*/
private Set<String> exclude = new LinkedHashSet<>();
public Set<String> getInclude() {
return this.include;
}
public void setInclude(Set<String> include) {
this.include = include;
}
public Set<String> getExclude() {
return this.exclude;
}
public void setExclude(Set<String> exclude) {
this.exclude = exclude;
}
}
public static class Discovery {
/**
* Whether the discovery page is enabled.
*/
private boolean enabled = true;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.web.servlet;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* A custom {@link HandlerMapping} that makes web endpoints available over HTTP using
* Spring MVC.
*
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0
*/
public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping {
private final EndpointLinksResolver linksResolver;
@Lazy
@Resource
private WebEndpointProperties webEndpointProperties;
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping);
this.linksResolver = linksResolver;
setOrder(-100);
}
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
* @param pathPatternParser the path pattern parser
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping,
PathPatternParser pathPatternParser) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping,
pathPatternParser);
this.linksResolver = linksResolver;
setOrder(-100);
}
@Override
protected LinksHandler getLinksHandler() {
return new WebMvcLinksHandler();
}
/**
* Handler for root endpoint providing links.
*/
class WebMvcLinksHandler implements LinksHandler {
@Override
@ResponseBody
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath())));
}
@Override
public String toString() {
return "Actuator root web endpoint";
}
}
}

View File

@ -0,0 +1,28 @@
# Tomcat
server:
port: 9300
# Spring
spring:
application:
# 应用名称
name: ruoyi-file
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -0,0 +1,29 @@
# Tomcat
server:
port: 9300
# Spring
spring:
application:
# 应用名称
name: ruoyi-file
cloud:
nacos:
discovery:
ip: 8.155.60.167
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -0,0 +1,28 @@
# Tomcat
server:
port: 9300
# Spring
spring:
application:
# 应用名称
name: ruoyi-file
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -1,25 +1,4 @@
# Tomcat # Spring默认环境配置
server: spring:
port: 9300 profiles:
active: dev
# Spring
spring:
application:
# 应用名称
name: ruoyi-file
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -1,87 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-modules-gen</artifactId> <artifactId>ruoyi-modules-gen</artifactId>
<description> <description>
ruoyi-modules-gen代码生成 ruoyi-modules-gen代码生成
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Alibaba Nacos --> <!-- SpringCloud Alibaba Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos Config --> <!-- SpringCloud Alibaba Nacos Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel --> <!-- SpringCloud Alibaba Sentinel -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- Apache Velocity --> <!-- Apache Velocity -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId> <artifactId>velocity-engine-core</artifactId>
</dependency> </dependency>
<!-- Mysql Connector --> <!-- Mysql Connector -->
<dependency> <dependency>
<groupId>com.mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId> <artifactId>mysql-connector-j</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Log --> <!-- RuoYi Common Log -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId> <artifactId>ruoyi-common-log</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Swagger --> <!-- RuoYi Common Swagger -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId> <artifactId>ruoyi-common-swagger</artifactId>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>de.codecentric</groupId>
<build> <artifactId>spring-boot-admin-starter-client</artifactId>
<finalName>${project.artifactId}</finalName> </dependency>
<plugins> </dependencies>
<plugin>
<groupId>org.springframework.boot</groupId> <build>
<artifactId>spring-boot-maven-plugin</artifactId> <finalName>${project.artifactId}</finalName>
<executions> <plugins>
<execution> <plugin>
<goals> <groupId>org.springframework.boot</groupId>
<goal>repackage</goal> <artifactId>spring-boot-maven-plugin</artifactId>
</goals> <executions>
</execution> <execution>
</executions> <goals>
</plugin> <goal>repackage</goal>
</plugins> </goals>
</build> </execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -0,0 +1,140 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Configuration properties for web management endpoints.
*
* @author Madhura Bhave
* @author Phillip Webb
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.endpoints.web")
public class WebEndpointProperties {
private final Exposure exposure = new Exposure();
/**
* Base path for Web endpoints. Relative to the servlet context path
* (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when
* the management server is sharing the main server port. Relative to the management
* server base path (management.server.base-path) when a separate management server
* port (management.server.port) is configured.
*/
private String basePath = "/actuator";
private String baseUrl = null;
/**
* Mapping between endpoint IDs and the path that should expose them.
*/
private final Map<String, String> pathMapping = new LinkedHashMap<>();
private final Discovery discovery = new Discovery();
public Exposure getExposure() {
return this.exposure;
}
public String getBasePath() {
return this.basePath;
}
public void setBasePath(String basePath) {
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty");
this.basePath = cleanBasePath(basePath);
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
private String cleanBasePath(String basePath) {
if (StringUtils.hasText(basePath) && basePath.endsWith("/")) {
return basePath.substring(0, basePath.length() - 1);
}
return basePath;
}
public Map<String, String> getPathMapping() {
return this.pathMapping;
}
public Discovery getDiscovery() {
return this.discovery;
}
public static class Exposure {
/**
* Endpoint IDs that should be included or '*' for all.
*/
private Set<String> include = new LinkedHashSet<>();
/**
* Endpoint IDs that should be excluded or '*' for all.
*/
private Set<String> exclude = new LinkedHashSet<>();
public Set<String> getInclude() {
return this.include;
}
public void setInclude(Set<String> include) {
this.include = include;
}
public Set<String> getExclude() {
return this.exclude;
}
public void setExclude(Set<String> exclude) {
this.exclude = exclude;
}
}
public static class Discovery {
/**
* Whether the discovery page is enabled.
*/
private boolean enabled = true;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.web.servlet;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* A custom {@link HandlerMapping} that makes web endpoints available over HTTP using
* Spring MVC.
*
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0
*/
public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping {
private final EndpointLinksResolver linksResolver;
@Lazy
@Resource
private WebEndpointProperties webEndpointProperties;
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping);
this.linksResolver = linksResolver;
setOrder(-100);
}
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
* @param pathPatternParser the path pattern parser
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping,
PathPatternParser pathPatternParser) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping,
pathPatternParser);
this.linksResolver = linksResolver;
setOrder(-100);
}
@Override
protected LinksHandler getLinksHandler() {
return new WebMvcLinksHandler();
}
/**
* Handler for root endpoint providing links.
*/
class WebMvcLinksHandler implements LinksHandler {
@Override
@ResponseBody
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath())));
}
@Override
public String toString() {
return "Actuator root web endpoint";
}
}
}

View File

@ -0,0 +1,28 @@
# Tomcat
server:
port: 9202
# Spring
spring:
application:
# 应用名称
name: ruoyi-gen
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -0,0 +1,29 @@
# Tomcat
server:
port: 9202
# Spring
spring:
application:
# 应用名称
name: ruoyi-gen
cloud:
nacos:
discovery:
ip: 8.155.60.167
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -0,0 +1,28 @@
# Tomcat
server:
port: 9202
# Spring
spring:
application:
# 应用名称
name: ruoyi-gen
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -1,25 +1,4 @@
# Tomcat # Spring默认环境配置
server: spring:
port: 9202 profiles:
active: dev
# Spring
spring:
application:
# 应用名称
name: ruoyi-gen
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -1,93 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-modules-job</artifactId> <artifactId>ruoyi-modules-job</artifactId>
<description> <description>
ruoyi-modules-job定时任务 ruoyi-modules-job定时任务
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Alibaba Nacos --> <!-- SpringCloud Alibaba Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos Config --> <!-- SpringCloud Alibaba Nacos Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel --> <!-- SpringCloud Alibaba Sentinel -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- Quartz --> <!-- Quartz -->
<dependency> <dependency>
<groupId>org.quartz-scheduler</groupId> <groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId> <artifactId>quartz</artifactId>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>com.mchange</groupId> <groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId> <artifactId>c3p0</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!-- Mysql Connector --> <!-- Mysql Connector -->
<dependency> <dependency>
<groupId>com.mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId> <artifactId>mysql-connector-j</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Log --> <!-- RuoYi Common Log -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId> <artifactId>ruoyi-common-log</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Swagger --> <!-- RuoYi Common Swagger -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId> <artifactId>ruoyi-common-swagger</artifactId>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>de.codecentric</groupId>
<build> <artifactId>spring-boot-admin-starter-client</artifactId>
<finalName>${project.artifactId}</finalName> </dependency>
<plugins> <dependency>
<plugin> <groupId>com.squareup.okhttp3</groupId>
<groupId>org.springframework.boot</groupId> <artifactId>okhttp</artifactId>
<artifactId>spring-boot-maven-plugin</artifactId> <version>3.12.13</version>
<executions> </dependency>
<execution> <dependency>
<goals> <groupId>com.ujcms</groupId>
<goal>repackage</goal> <artifactId>ujcms-commons</artifactId>
</goals> <version>9.6.0.0.1</version>
</execution> <scope>compile</scope>
</executions> </dependency>
</plugin>
</plugins> </dependencies>
</build>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -0,0 +1,23 @@
package com.ruoyi.job.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author ruoyi
*/
@Data
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.sms.aliyuncs")
public class SmsConfig
{
private String accessKeyId;
private String accessKeySecret;
private String signName;
private String templateCode;
}

View File

@ -0,0 +1,78 @@
package com.ruoyi.job.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.common.core.web.domain.BaseEntity;
import com.ruoyi.job.util.ProgressFormatterUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.annotation.Id;
import java.math.BigDecimal;
/**
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ScClassUserInfo extends BaseEntity {
@Id
private Long id;
//@ExcelIgnore // 不导出该字段
private Long userId;
//@ExcelIgnore // 不导出该字段
private Long classId;
//@ColumnWidth(25)
// @ExcelProperty("名称(报名时)")
private String name;
//@ColumnWidth(25)
//@ExcelProperty("单位")
private String firm;
//@ColumnWidth(25)
//@ExcelProperty("专业")
private String specialized;
//@ColumnWidth(35)
//@ExcelProperty("手机号")
private String phonenumber;
//@ColumnWidth(35)
//@ExcelProperty("昵称")
private String nickName;
/**
*
*/
//@ExcelProperty("客户订单编号")
private String userSn;
//@ExcelIgnore
private Boolean todayAttendanceIs;
@JsonIgnore
// @ExcelProperty("是否打卡")
private String attendanceIs;
//@ExcelProperty("签到次数")
private Integer attendanceCount;
//@ExcelIgnore
private BigDecimal progress;
//@ExcelProperty("总学习进度")
private String progressPercent;
public String getAttendanceIs() {
return attendanceCount.compareTo(0) > 0 ? "是" : "否";
}
public String getProgressPercent() {
return ProgressFormatterUtil.format(this.progress.multiply(BigDecimal.valueOf(100)));
}
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.job.mapper;
import com.ruoyi.job.domain.ScClassUserInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
//@Mapper
//public interface ScClassUserInfoMapper extends tk.mybatis.mapper.common.Mapper<ScClassUserInfo>
public interface ScClassUserInfoMapper
{
List<ScClassUserInfo> waitNoticeCourseUser();
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.job.service;
import com.ruoyi.common.core.exception.CaptchaException;
/**
*
*
* @author ruoyi
*/
public interface SmsService
{
/**
*
*/
public void sendStudyNoticeSms(String phone) throws CaptchaException;
}

View File

@ -0,0 +1,35 @@
package com.ruoyi.job.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.job.config.SmsConfig;
import com.ruoyi.job.service.SmsService;
import com.ujcms.commons.sms.AliyunUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*
*
* @author ruoyi
*/
@Service
public class SmsServiceImpl implements SmsService
{
@Autowired
private SmsConfig smsConfig;
/**
*
*/
@Override
public void sendStudyNoticeSms(String phone) throws CaptchaException {
AliyunUtils.sendSms(smsConfig.getAccessKeyId(),
smsConfig.getAccessKeySecret(),
smsConfig.getSignName(),
smsConfig.getTemplateCode(),
JSONObject.of(),
phone
);
}
}

View File

@ -0,0 +1,36 @@
package com.ruoyi.job.task;
import com.ruoyi.job.config.SmsConfig;
import com.ruoyi.job.domain.ScClassUserInfo;
import com.ruoyi.job.mapper.ScClassUserInfoMapper;
import com.ruoyi.job.service.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Component("liveTask")
public class LiveTask {
@Resource
ScClassUserInfoMapper scClassUserInfoMapper;
@Autowired
private SmsService smsAliyuncs;
@Autowired
private SmsConfig smsConfig;
/**
*
*/
public void CourseSmsNotice(){
List<ScClassUserInfo> list = scClassUserInfoMapper.waitNoticeCourseUser();
list.forEach(item->{
if (item.getPhonenumber() != null && !item.getPhonenumber().trim().isEmpty()){
log.info("发送打卡提醒 {} {} {}",item.getUserId(),item.getNickName(),item.getPhonenumber());
smsAliyuncs.sendStudyNoticeSms(item.getPhonenumber());
}
});
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.job.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
public class ProgressFormatterUtil {
public static String format(BigDecimal progress ) {
if (progress == null) return "0";
// 保留两位小数(四舍五入)
BigDecimal scaled = progress.setScale(2, RoundingMode.HALF_UP);
// 去除末尾零和小数点
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(0);
return nf.format(scaled) + "%";
}
}

View File

@ -0,0 +1,140 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Configuration properties for web management endpoints.
*
* @author Madhura Bhave
* @author Phillip Webb
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.endpoints.web")
public class WebEndpointProperties {
private final Exposure exposure = new Exposure();
/**
* Base path for Web endpoints. Relative to the servlet context path
* (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when
* the management server is sharing the main server port. Relative to the management
* server base path (management.server.base-path) when a separate management server
* port (management.server.port) is configured.
*/
private String basePath = "/actuator";
private String baseUrl = null;
/**
* Mapping between endpoint IDs and the path that should expose them.
*/
private final Map<String, String> pathMapping = new LinkedHashMap<>();
private final Discovery discovery = new Discovery();
public Exposure getExposure() {
return this.exposure;
}
public String getBasePath() {
return this.basePath;
}
public void setBasePath(String basePath) {
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty");
this.basePath = cleanBasePath(basePath);
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
private String cleanBasePath(String basePath) {
if (StringUtils.hasText(basePath) && basePath.endsWith("/")) {
return basePath.substring(0, basePath.length() - 1);
}
return basePath;
}
public Map<String, String> getPathMapping() {
return this.pathMapping;
}
public Discovery getDiscovery() {
return this.discovery;
}
public static class Exposure {
/**
* Endpoint IDs that should be included or '*' for all.
*/
private Set<String> include = new LinkedHashSet<>();
/**
* Endpoint IDs that should be excluded or '*' for all.
*/
private Set<String> exclude = new LinkedHashSet<>();
public Set<String> getInclude() {
return this.include;
}
public void setInclude(Set<String> include) {
this.include = include;
}
public Set<String> getExclude() {
return this.exclude;
}
public void setExclude(Set<String> exclude) {
this.exclude = exclude;
}
}
public static class Discovery {
/**
* Whether the discovery page is enabled.
*/
private boolean enabled = true;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.web.servlet;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* A custom {@link HandlerMapping} that makes web endpoints available over HTTP using
* Spring MVC.
*
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0
*/
public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping {
private final EndpointLinksResolver linksResolver;
@Lazy
@Resource
private WebEndpointProperties webEndpointProperties;
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping);
this.linksResolver = linksResolver;
setOrder(-100);
}
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
* @param pathPatternParser the path pattern parser
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping,
PathPatternParser pathPatternParser) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping,
pathPatternParser);
this.linksResolver = linksResolver;
setOrder(-100);
}
@Override
protected LinksHandler getLinksHandler() {
return new WebMvcLinksHandler();
}
/**
* Handler for root endpoint providing links.
*/
class WebMvcLinksHandler implements LinksHandler {
@Override
@ResponseBody
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath())));
}
@Override
public String toString() {
return "Actuator root web endpoint";
}
}
}

View File

@ -0,0 +1,28 @@
# Tomcat
server:
port: 9203
# Spring
spring:
application:
# 应用名称
name: ruoyi-job
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -0,0 +1,29 @@
# Tomcat
server:
port: 9203
# Spring
spring:
application:
# 应用名称
name: ruoyi-job
cloud:
nacos:
discovery:
ip: 8.155.60.167
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -0,0 +1,28 @@
# Tomcat
server:
port: 9203
# Spring
spring:
application:
# 应用名称
name: ruoyi-job
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA

View File

@ -1,25 +1,4 @@
# Tomcat # Spring默认环境配置
server: spring:
port: 9203 profiles:
active: dev
# Spring
spring:
application:
# 应用名称
name: ruoyi-job
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ruoyi.job.mapper.ScClassUserInfoMapper">
<resultMap id="scClassUserInfo" type="com.ruoyi.job.domain.ScClassUserInfo">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="firm" property="firm"/>
<result column="specialized" property="specialized"/>
<result column="nick_name" property="nickName"/>
<result column="todayAttendanceIs" property="todayAttendanceIs"/>
<result column="attendanceCount" property="attendanceCount"/>
<result column="progress" property="progress"/>
</resultMap>
<select id="waitNoticeCourseUser" resultMap="scClassUserInfo">
SELECT
progress.id,
progress.userId,
progress.classId,
progress.`name`,
progress.email,
progress.phonenumber,
progress.userSn,
progress.firm,
progress.posts,
progress.areas_of_focus,
progress.issue,
progress.specialized,
progress.nick_name,
attendance.todayAttendanceIs,
attendance.attendanceCount,
progress.progress
FROM
(
SELECT
scui.id,
COUNT( sua_today.id ) AS todayAttendanceIs,
COUNT( sua_count.id ) AS attendanceCount
FROM
sc_class_user_info scui
LEFT JOIN sc_user_attendance sua_today ON (
sua_today.class_info_id = scui.class_id
AND sua_today.user_id = scui.user_id
AND sua_today.`status` = 1
AND to_days( sua_today.create_time ) = to_days(
now())
)
LEFT JOIN sc_user_attendance sua_count ON ( sua_count.class_info_id = scui.class_id AND sua_count.user_id = scui.user_id AND sua_count.`status` = 1 )
WHERE
scui.`status` = 1
AND scui.end_time > now()
AND ( scui.delete_flag != scui.id OR scui.delete_flag IS NULL )
GROUP BY
scui.id
) attendance
INNER JOIN (
SELECT
scui.id,
scui.user_id AS userId,
scui.class_id AS classId,
scui.`name`,
scui.email,
scui.phonenumber,
scui.user_sn AS userSn,
scui.firm,
scui.posts,
scui.areas_of_focus,
scui.issue,
scui.specialized,
y.nick_name,
CASE
WHEN COUNT( DISTINCT video.id ) = 0 THEN
0 ELSE (
COUNT(
DISTINCT
CASE
WHEN ( TIME_TO_SEC( video.duration ) = 0 AND record.type_id IS NOT NULL )
OR (
record.total_duration >= 0.8 * TIME_TO_SEC( video.duration )) THEN
video.id
END
)
) / COUNT(DISTINCT video.id )
END AS progress
FROM
sc_class_user_info scui
INNER JOIN sys_user y ON scui.user_id = y.user_id
LEFT JOIN sc_video video ON ( video.class_info_id = scui.class_id AND video.`status` = 1 )
LEFT JOIN sc_class_user_record_info record ON ( record.type = 'ScVideo' AND record.type_id = video.id AND scui.user_id = record.user_id )
WHERE
scui.`status` = 1
AND scui.end_time > now()
AND ( scui.delete_flag != scui.id OR scui.delete_flag IS NULL )
GROUP BY
scui.id
) progress ON attendance.id = progress.id WHERE progress.progress &lt; 1 GROUP BY progress.userId
</select>
</mapper>

View File

@ -1,93 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version> <version>3.6.5.0.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-modules-system</artifactId> <artifactId>ruoyi-modules-system</artifactId>
<description> <description>
ruoyi-modules-system系统模块 ruoyi-modules-system系统模块
</description> </description>
<dependencies> <dependencies>
<!-- SpringCloud Alibaba Nacos --> <!-- SpringCloud Alibaba Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Nacos Config --> <!-- SpringCloud Alibaba Nacos Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency> </dependency>
<!-- SpringCloud Alibaba Sentinel --> <!-- SpringCloud Alibaba Sentinel -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- Mysql Connector --> <!-- Mysql Connector -->
<dependency> <dependency>
<groupId>com.mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId> <artifactId>mysql-connector-j</artifactId>
</dependency> </dependency>
<!-- RuoYi Common DataSource --> <!-- RuoYi Common DataSource -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId> <artifactId>ruoyi-common-datasource</artifactId>
</dependency> </dependency>
<!-- RuoYi Common DataScope --> <!-- RuoYi Common DataScope -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datascope</artifactId> <artifactId>ruoyi-common-datascope</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Log --> <!-- RuoYi Common Log -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId> <artifactId>ruoyi-common-log</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Swagger --> <!-- RuoYi Common Swagger -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId> <artifactId>ruoyi-common-swagger</artifactId>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>de.codecentric</groupId>
<build> <artifactId>spring-boot-admin-starter-client</artifactId>
<finalName>${project.artifactId}</finalName> </dependency>
<plugins> </dependencies>
<plugin>
<groupId>org.springframework.boot</groupId> <build>
<artifactId>spring-boot-maven-plugin</artifactId> <finalName>${project.artifactId}</finalName>
<executions> <plugins>
<execution> <plugin>
<goals> <groupId>org.jetbrains.kotlin</groupId>
<goal>repackage</goal> <artifactId>kotlin-maven-plugin</artifactId>
</goals> <version>${kotlin.version}</version>
</execution> <executions>
</executions> <execution>
</plugin> <id>compile</id>
</plugins> <phase>process-sources</phase>
</build> <goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -89,4 +89,13 @@ public class SysNoticeController extends BaseController
{ {
return toAjax(noticeService.deleteNoticeByIds(noticeIds)); return toAjax(noticeService.deleteNoticeByIds(noticeIds));
} }
/**
*
*/
@GetMapping("/no-login/{noticeTitle}")
public AjaxResult getInfo(@PathVariable String noticeTitle)
{
return success(noticeService.selectNoticeByNoticeTitle(noticeTitle));
}
} }

View File

@ -1,380 +1,390 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil; import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo; import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType; import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.InnerAuth; import com.ruoyi.common.security.annotation.InnerAuth;
import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysDept; import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysRole; import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser; import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPermissionService; import com.ruoyi.system.service.ISysPermissionService;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/user") @RequestMapping("/user")
public class SysUserController extends BaseController public class SysUserController extends BaseController
{ {
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired @Autowired
private ISysDeptService deptService; private ISysDeptService deptService;
@Autowired @Autowired
private ISysPostService postService; private ISysPostService postService;
@Autowired @Autowired
private ISysPermissionService permissionService; private ISysPermissionService permissionService;
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
/** /**
* *
*/ */
@RequiresPermissions("system:user:list") @RequiresPermissions("system:user:list")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysUser user) public TableDataInfo list(SysUser user)
{ {
startPage(); startPage();
List<SysUser> list = userService.selectUserList(user); List<SysUser> list = userService.selectUserList(user);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "用户管理", businessType = BusinessType.EXPORT) @Log(title = "用户管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:user:export") @RequiresPermissions("system:user:export")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysUser user) public void export(HttpServletResponse response, SysUser user)
{ {
List<SysUser> list = userService.selectUserList(user); List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.exportExcel(response, list, "用户数据"); util.exportExcel(response, list, "用户数据");
} }
@Log(title = "用户管理", businessType = BusinessType.IMPORT) @Log(title = "用户管理", businessType = BusinessType.IMPORT)
@RequiresPermissions("system:user:import") @RequiresPermissions("system:user:import")
@PostMapping("/importData") @PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{ {
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream()); List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = SecurityUtils.getUsername(); String operName = SecurityUtils.getUsername();
String message = userService.importUser(userList, updateSupport, operName); String message = userService.importUser(userList, updateSupport, operName);
return success(message); return success(message);
} }
@PostMapping("/importTemplate") @PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) throws IOException public void importTemplate(HttpServletResponse response) throws IOException
{ {
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.importTemplateExcel(response, "用户数据"); util.importTemplateExcel(response, "用户数据");
} }
/** /**
* *
*/ */
@InnerAuth @InnerAuth
@GetMapping("/info/{username}") @GetMapping("/info/{username}")
public R<LoginUser> info(@PathVariable("username") String username) public R<LoginUser> info(@PathVariable("username") String username)
{ {
SysUser sysUser = userService.selectUserByUserName(username); SysUser sysUser = userService.selectUserByUserName(username);
if (StringUtils.isNull(sysUser)) if (StringUtils.isNull(sysUser))
{ {
return R.fail("用户名或密码错误"); return R.fail("用户名或密码错误");
} }
// 角色集合 // 角色集合
Set<String> roles = permissionService.getRolePermission(sysUser); Set<String> roles = permissionService.getRolePermission(sysUser);
// 权限集合 // 权限集合
Set<String> permissions = permissionService.getMenuPermission(sysUser); Set<String> permissions = permissionService.getMenuPermission(sysUser);
LoginUser sysUserVo = new LoginUser(); LoginUser sysUserVo = new LoginUser();
sysUserVo.setSysUser(sysUser); sysUserVo.setSysUser(sysUser);
sysUserVo.setRoles(roles); sysUserVo.setRoles(roles);
sysUserVo.setPermissions(permissions); sysUserVo.setPermissions(permissions);
return R.ok(sysUserVo); return R.ok(sysUserVo);
} }
/** /**
* *
*/ */
@InnerAuth @InnerAuth
@PostMapping("/register") @PostMapping("/register")
public R<Boolean> register(@RequestBody SysUser sysUser) public R<Boolean> register(@RequestBody SysUser sysUser)
{ {
String username = sysUser.getUserName(); String username = sysUser.getUserName();
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{ {
return R.fail("当前系统没有开启注册功能!"); return R.fail("当前系统没有开启注册功能!");
} }
if (!userService.checkUserNameUnique(sysUser)) if (!userService.checkUserNameUnique(sysUser))
{ {
return R.fail("保存用户'" + username + "'失败,注册账号已存在"); return R.fail("保存用户'" + username + "'失败,注册账号已存在");
} }
return R.ok(userService.registerUser(sysUser)); return R.ok(userService.registerUser(sysUser));
} }
/** /**
*IP *IP
*/ */
@InnerAuth @InnerAuth
@PutMapping("/recordlogin") @PutMapping("/recordlogin")
public R<Boolean> recordlogin(@RequestBody SysUser sysUser) public R<Boolean> recordlogin(@RequestBody SysUser sysUser)
{ {
return R.ok(userService.updateLoginInfo(sysUser)); return R.ok(userService.updateUserProfile(sysUser));
} }
/** /**
* *IP
* */
* @return @InnerAuth
*/ @PutMapping("/syncGO")
@GetMapping("getInfo") public R<Boolean> syncGO(@RequestBody SysUser sysUser)
public AjaxResult getInfo() {
{ return R.ok(userService.syncGO(sysUser));
LoginUser loginUser = SecurityUtils.getLoginUser(); }
SysUser user = loginUser.getSysUser();
// 角色集合 /**
Set<String> roles = permissionService.getRolePermission(user); *
// 权限集合 *
Set<String> permissions = permissionService.getMenuPermission(user); * @return
if (!loginUser.getPermissions().equals(permissions)) */
{ @GetMapping("getInfo")
loginUser.setPermissions(permissions); public AjaxResult getInfo()
tokenService.refreshToken(loginUser); {
} LoginUser loginUser = SecurityUtils.getLoginUser();
AjaxResult ajax = AjaxResult.success(); SysUser user = loginUser.getSysUser();
ajax.put("user", user); // 角色集合
ajax.put("roles", roles); Set<String> roles = permissionService.getRolePermission(user);
ajax.put("permissions", permissions); // 权限集合
ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); Set<String> permissions = permissionService.getMenuPermission(user);
ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); if (!loginUser.getPermissions().equals(permissions))
return ajax; {
} loginUser.setPermissions(permissions);
tokenService.refreshToken(loginUser);
// 检查初始密码是否提醒修改 }
public boolean initPasswordIsModify(Date pwdUpdateDate) AjaxResult ajax = AjaxResult.success();
{ ajax.put("user", user);
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); ajax.put("roles", roles);
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; ajax.put("permissions", permissions);
} ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
// 检查密码是否过期 return ajax;
public boolean passwordIsExpiration(Date pwdUpdateDate) }
{
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); // 检查初始密码是否提醒修改
if (passwordValidateDays != null && passwordValidateDays > 0) public boolean initPasswordIsModify(Date pwdUpdateDate)
{ {
if (StringUtils.isNull(pwdUpdateDate)) Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
{ return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
// 如果从未修改过初始密码,直接提醒过期 }
return true;
} // 检查密码是否过期
Date nowDate = DateUtils.getNowDate(); public boolean passwordIsExpiration(Date pwdUpdateDate)
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; {
} Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
return false; if (passwordValidateDays != null && passwordValidateDays > 0)
} {
if (StringUtils.isNull(pwdUpdateDate))
/** {
* // 如果从未修改过初始密码,直接提醒过期
*/ return true;
@RequiresPermissions("system:user:query") }
@GetMapping(value = { "/", "/{userId}" }) Date nowDate = DateUtils.getNowDate();
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
{ }
AjaxResult ajax = AjaxResult.success(); return false;
if (StringUtils.isNotNull(userId)) }
{
userService.checkUserDataScope(userId); /**
SysUser sysUser = userService.selectUserById(userId); *
ajax.put(AjaxResult.DATA_TAG, sysUser); */
ajax.put("postIds", postService.selectPostListByUserId(userId)); @RequiresPermissions("system:user:query")
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); @GetMapping(value = { "/", "/{userId}" })
} public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
List<SysRole> roles = roleService.selectRoleAll(); {
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); AjaxResult ajax = AjaxResult.success();
ajax.put("posts", postService.selectPostAll()); if (StringUtils.isNotNull(userId))
return ajax; {
} userService.checkUserDataScope(userId);
SysUser sysUser = userService.selectUserById(userId);
/** ajax.put(AjaxResult.DATA_TAG, sysUser);
* ajax.put("postIds", postService.selectPostListByUserId(userId));
*/ ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
@RequiresPermissions("system:user:add") }
@Log(title = "用户管理", businessType = BusinessType.INSERT) List<SysRole> roles = roleService.selectRoleAll();
@PostMapping ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
public AjaxResult add(@Validated @RequestBody SysUser user) ajax.put("posts", postService.selectPostAll());
{ return ajax;
deptService.checkDeptDataScope(user.getDeptId()); }
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) /**
{ *
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); */
} @RequiresPermissions("system:user:add")
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) @Log(title = "用户管理", businessType = BusinessType.INSERT)
{ @PostMapping
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); public AjaxResult add(@Validated @RequestBody SysUser user)
} {
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) deptService.checkDeptDataScope(user.getDeptId());
{ roleService.checkRoleDataScope(user.getRoleIds());
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); if (!userService.checkUserNameUnique(user))
} {
user.setCreateBy(SecurityUtils.getUsername()); return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); }
return toAjax(userService.insertUser(user)); else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
} {
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
/** }
* else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
*/ {
@RequiresPermissions("system:user:edit") return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
@Log(title = "用户管理", businessType = BusinessType.UPDATE) }
@PutMapping user.setCreateBy(SecurityUtils.getUsername());
public AjaxResult edit(@Validated @RequestBody SysUser user) user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
{ return toAjax(userService.insertUser(user));
userService.checkUserAllowed(user); }
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId()); /**
roleService.checkRoleDataScope(user.getRoleIds()); *
if (!userService.checkUserNameUnique(user)) */
{ @RequiresPermissions("system:user:edit")
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); @Log(title = "用户管理", businessType = BusinessType.UPDATE)
} @PutMapping
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) public AjaxResult edit(@Validated @RequestBody SysUser user)
{ {
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); userService.checkUserAllowed(user);
} userService.checkUserDataScope(user.getUserId());
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) deptService.checkDeptDataScope(user.getDeptId());
{ roleService.checkRoleDataScope(user.getRoleIds());
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); if (!userService.checkUserNameUnique(user))
} {
user.setUpdateBy(SecurityUtils.getUsername()); return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
return toAjax(userService.updateUser(user)); }
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
/** return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
* }
*/ else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
@RequiresPermissions("system:user:remove") {
@Log(title = "用户管理", businessType = BusinessType.DELETE) return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
@DeleteMapping("/{userIds}") }
public AjaxResult remove(@PathVariable Long[] userIds) user.setUpdateBy(SecurityUtils.getUsername());
{ return toAjax(userService.updateUser(user));
if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) }
{
return error("当前用户不能删除"); /**
} *
return toAjax(userService.deleteUserByIds(userIds)); */
} @RequiresPermissions("system:user:remove")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
/** @DeleteMapping("/{userIds}")
* public AjaxResult remove(@PathVariable Long[] userIds)
*/ {
@RequiresPermissions("system:user:edit") if (ArrayUtils.contains(userIds, SecurityUtils.getUserId()))
@Log(title = "用户管理", businessType = BusinessType.UPDATE) {
@PutMapping("/resetPwd") return error("当前用户不能删除");
public AjaxResult resetPwd(@RequestBody SysUser user) }
{ return toAjax(userService.deleteUserByIds(userIds));
userService.checkUserAllowed(user); }
userService.checkUserDataScope(user.getUserId());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); /**
user.setUpdateBy(SecurityUtils.getUsername()); *
return toAjax(userService.resetPwd(user)); */
} @RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
/** @PutMapping("/resetPwd")
* public AjaxResult resetPwd(@RequestBody SysUser user)
*/ {
@RequiresPermissions("system:user:edit") userService.checkUserAllowed(user);
@Log(title = "用户管理", businessType = BusinessType.UPDATE) userService.checkUserDataScope(user.getUserId());
@PutMapping("/changeStatus") user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
public AjaxResult changeStatus(@RequestBody SysUser user) user.setUpdateBy(SecurityUtils.getUsername());
{ return toAjax(userService.resetPwd(user));
userService.checkUserAllowed(user); }
userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(SecurityUtils.getUsername()); /**
return toAjax(userService.updateUserStatus(user)); *
} */
@RequiresPermissions("system:user:edit")
/** @Log(title = "用户管理", businessType = BusinessType.UPDATE)
* @PutMapping("/changeStatus")
*/ public AjaxResult changeStatus(@RequestBody SysUser user)
@RequiresPermissions("system:user:query") {
@GetMapping("/authRole/{userId}") userService.checkUserAllowed(user);
public AjaxResult authRole(@PathVariable("userId") Long userId) userService.checkUserDataScope(user.getUserId());
{ user.setUpdateBy(SecurityUtils.getUsername());
AjaxResult ajax = AjaxResult.success(); return toAjax(userService.updateUserStatus(user));
SysUser user = userService.selectUserById(userId); }
List<SysRole> roles = roleService.selectRolesByUserId(userId);
ajax.put("user", user); /**
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); *
return ajax; */
} @RequiresPermissions("system:user:query")
@GetMapping("/authRole/{userId}")
/** public AjaxResult authRole(@PathVariable("userId") Long userId)
* {
*/ AjaxResult ajax = AjaxResult.success();
@RequiresPermissions("system:user:edit") SysUser user = userService.selectUserById(userId);
@Log(title = "用户管理", businessType = BusinessType.GRANT) List<SysRole> roles = roleService.selectRolesByUserId(userId);
@PutMapping("/authRole") ajax.put("user", user);
public AjaxResult insertAuthRole(Long userId, Long[] roleIds) ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
{ return ajax;
userService.checkUserDataScope(userId); }
roleService.checkRoleDataScope(roleIds);
userService.insertUserAuth(userId, roleIds); /**
return success(); *
} */
@RequiresPermissions("system:user:edit")
/** @Log(title = "用户管理", businessType = BusinessType.GRANT)
* @PutMapping("/authRole")
*/ public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
@RequiresPermissions("system:user:list") {
@GetMapping("/deptTree") userService.checkUserDataScope(userId);
public AjaxResult deptTree(SysDept dept) roleService.checkRoleDataScope(roleIds);
{ userService.insertUserAuth(userId, roleIds);
return success(deptService.selectDeptTreeList(dept)); return success();
} }
}
/**
*
*/
@RequiresPermissions("system:user:list")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept)
{
return success(deptService.selectDeptTreeList(dept));
}
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.system.domain;
import lombok.Data;
@Data
public class SyncGoUser {
private Integer userId;
private String nickname;
private String username;
private String mobile;
private String lastIp;
private String remark;
private String avatar;
private Integer status;
private String openId;
private String unionId;
}

View File

@ -57,4 +57,12 @@ public interface SysNoticeMapper
* @return * @return
*/ */
public int deleteNoticeByIds(Long[] noticeIds); public int deleteNoticeByIds(Long[] noticeIds);
/**
*
*
* @param noticeTitle
* @return
*/
public SysNotice selectNoticeByNoticeTitle(String noticeTitle);
} }

View File

@ -1,144 +1,145 @@
package com.ruoyi.system.mapper; package com.ruoyi.system.mapper;
import java.util.List; import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.system.api.domain.SysUser; import com.github.pagehelper.Page;
import org.apache.ibatis.annotations.Param;
/** import com.ruoyi.system.api.domain.SysUser;
*
* /**
* @author ruoyi *
*/ *
public interface SysUserMapper * @author ruoyi
{ */
/** public interface SysUserMapper
* {
* /**
* @param sysUser *
* @return *
*/ * @param sysUser
public List<SysUser> selectUserList(SysUser sysUser); * @return
*/
/** public List<SysUser> selectUserList(SysUser sysUser);
*
* /**
* @param user *
* @return *
*/ * @param user
public List<SysUser> selectAllocatedList(SysUser user); * @return
*/
/** public List<SysUser> selectAllocatedList(SysUser user);
*
* /**
* @param user *
* @return *
*/ * @param user
public List<SysUser> selectUnallocatedList(SysUser user); * @return
*/
/** public List<SysUser> selectUnallocatedList(SysUser user);
*
* /**
* @param userName *
* @return *
*/ * @param userName
public SysUser selectUserByUserName(String userName); * @return
*/
/** public SysUser selectUserByUserName(String userName);
* ID
* /**
* @param userId ID *
* @return *
*/ * @param phoneNumber
public SysUser selectUserById(Long userId); * @return
*/
/** public SysUser selectUserByPhoneNumber(String phoneNumber);
*
* /**
* @param user *
* @return *
*/ * @param phoneNumber
public int insertUser(SysUser user); * @return
*/
/** public Page<SysUser> findByPhoneNumberStartingWith(String phoneNumber);
*
* /**
* @param user * ID
* @return *
*/ * @param userId ID
public int updateUser(SysUser user); * @return
*/
/** public SysUser selectUserById(Long userId);
*
* /**
* @param userId ID *
* @param avatar *
* @return * @param user
*/ * @return
public int updateUserAvatar(@Param("userId") Long userId, @Param("avatar") String avatar); */
public int insertUser(SysUser user);
/**
* /**
* *
* @param userId ID *
* @param status * @param user
* @return * @return
*/ */
public int updateUserStatus(@Param("userId") Long userId, @Param("status") String status); public int updateUser(SysUser user);
/** /**
* IP *
* *
* @param user * @param userName
* @return * @param avatar
*/ * @return
public int updateLoginInfo(SysUser user); */
public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
/**
* /**
* *
* @param userId ID *
* @param password * @param userName
* @return * @param password
*/ * @return
public int resetUserPwd(@Param("userId") Long userId, @Param("password") String password); */
public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
/**
* ID /**
* * ID
* @param userId ID *
* @return * @param userId ID
*/ * @return
public int deleteUserById(Long userId); */
public int deleteUserById(Long userId);
/**
* /**
* *
* @param userIds ID *
* @return * @param userIds ID
*/ * @return
public int deleteUserByIds(Long[] userIds); */
public int deleteUserByIds(Long[] userIds);
/**
* /**
* *
* @param userName *
* @return * @param userName
*/ * @return
public SysUser checkUserNameUnique(String userName); */
public SysUser checkUserNameUnique(String userName);
/**
* /**
* *
* @param phonenumber *
* @return * @param phonenumber
*/ * @return
public SysUser checkPhoneUnique(String phonenumber); */
public SysUser checkPhoneUnique(String phonenumber);
/**
* email /**
* * email
* @param email *
* @return * @param email
*/ * @return
public SysUser checkEmailUnique(String email); */
} public SysUser checkEmailUnique(String email);
}

View File

@ -57,4 +57,12 @@ public interface ISysNoticeService
* @return * @return
*/ */
public int deleteNoticeByIds(Long[] noticeIds); public int deleteNoticeByIds(Long[] noticeIds);
/**
*
*
* @param noticeTitle
* @return
*/
public SysNotice selectNoticeByNoticeTitle(String noticeTitle);
} }

View File

@ -1,214 +1,232 @@
package com.ruoyi.system.service; package com.ruoyi.system.service;
import java.util.List; import java.util.List;
import com.ruoyi.system.api.domain.SysUser;
import com.github.pagehelper.Page;
/** import com.ruoyi.system.api.domain.SysUser;
*
* /**
* @author ruoyi *
*/ *
public interface ISysUserService * @author ruoyi
{ */
/** public interface ISysUserService
* {
* /**
* @param user *
* @return *
*/ * @param user
public List<SysUser> selectUserList(SysUser user); * @return
*/
/** public List<SysUser> selectUserList(SysUser user);
*
* /**
* @param user *
* @return *
*/ * @param user
public List<SysUser> selectAllocatedList(SysUser user); * @return
*/
/** public List<SysUser> selectAllocatedList(SysUser user);
*
* /**
* @param user *
* @return *
*/ * @param user
public List<SysUser> selectUnallocatedList(SysUser user); * @return
*/
/** public List<SysUser> selectUnallocatedList(SysUser user);
*
* /**
* @param userName *
* @return *
*/ * @param userName
public SysUser selectUserByUserName(String userName); * @return
*/
/** public SysUser selectUserByUserName(String userName);
* ID
* /**
* @param userId ID *
* @return *
*/ * @param phoneNumber
public SysUser selectUserById(Long userId); * @return
*/
/** public SysUser selectUserByPhoneNumber(String phoneNumber);
* ID
* /**
* @param userName * ID
* @return *
*/ * @param userId ID
public String selectUserRoleGroup(String userName); * @return
*/
/** public SysUser selectUserById(Long userId);
* ID
* /**
* @param userName *
* @return *
*/ * @param phoneNumber
public String selectUserPostGroup(String userName); * @return
*/
/** public Page<SysUser> findByPhoneNumberStartingWith(String phoneNumber);
*
* /**
* @param user * ID
* @return *
*/ * @param userName
public boolean checkUserNameUnique(SysUser user); * @return
*/
/** public String selectUserRoleGroup(String userName);
*
* /**
* @param user * ID
* @return *
*/ * @param userName
public boolean checkPhoneUnique(SysUser user); * @return
*/
/** public String selectUserPostGroup(String userName);
* email
* /**
* @param user *
* @return *
*/ * @param user
public boolean checkEmailUnique(SysUser user); * @return
*/
/** public boolean checkUserNameUnique(SysUser user);
*
* /**
* @param user *
*/ *
public void checkUserAllowed(SysUser user); * @param user
* @return
/** */
* public boolean checkPhoneUnique(SysUser user);
*
* @param userId id /**
*/ * email
public void checkUserDataScope(Long userId); *
* @param user
/** * @return
* */
* public boolean checkEmailUnique(SysUser user);
* @param user
* @return /**
*/ *
public int insertUser(SysUser user); *
* @param user
/** */
* public void checkUserAllowed(SysUser user);
*
* @param user /**
* @return *
*/ *
public boolean registerUser(SysUser user); * @param userId id
*/
/** public void checkUserDataScope(Long userId);
*
* /**
* @param user *
* @return *
*/ * @param user
public int updateUser(SysUser user); * @return
*/
/** public int insertUser(SysUser user);
*
* /**
* @param userId ID *
* @param roleIds *
*/ * @param user
public void insertUserAuth(Long userId, Long[] roleIds); * @return
*/
/** public boolean registerUser(SysUser user);
*
* /**
* @param user *
* @return *
*/ * @param user
public int updateUserStatus(SysUser user); * @return
*/
/** public int updateUser(SysUser user);
*
* /**
* @param user *
* @return *
*/ * @param userId ID
public boolean updateUserProfile(SysUser user); * @param roleIds
*/
/** public void insertUserAuth(Long userId, Long[] roleIds);
*
* /**
* @param userId ID *
* @param avatar *
* @return * @param user
*/ * @return
public boolean updateUserAvatar(Long userId, String avatar); */
public int updateUserStatus(SysUser user);
/**
* IP /**
* *
* @param user *
* @return * @param user
*/ * @return
public boolean updateLoginInfo(SysUser user); */
public boolean updateUserProfile(SysUser user);
/**
* /**
* *
* @param user *
* @return * @param user
*/ * @return
public int resetPwd(SysUser user); */
public boolean syncGO(SysUser user);
/**
* /**
* *
* @param userId ID *
* @param password * @param userName
* @return * @param avatar
*/ * @return
public int resetUserPwd(Long userId, String password); */
public boolean updateUserAvatar(String userName, String avatar);
/**
* ID /**
* *
* @param userId ID *
* @return * @param user
*/ * @return
public int deleteUserById(Long userId); */
public int resetPwd(SysUser user);
/**
* /**
* *
* @param userIds ID *
* @return * @param userName
*/ * @param password
public int deleteUserByIds(Long[] userIds); * @return
*/
/** public int resetUserPwd(String userName, String password);
*
* /**
* @param userList * ID
* @param isUpdateSupport *
* @param operName * @param userId ID
* @return * @return
*/ */
public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName); public int deleteUserById(Long userId);
}
/**
*
*
* @param userIds ID
* @return
*/
public int deleteUserByIds(Long[] userIds);
/**
*
*
* @param userList
* @param isUpdateSupport
* @param operName
* @return
*/
public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
}

View File

@ -89,4 +89,15 @@ public class SysNoticeServiceImpl implements ISysNoticeService
{ {
return noticeMapper.deleteNoticeByIds(noticeIds); return noticeMapper.deleteNoticeByIds(noticeIds);
} }
/**
*
*
* @param noticeTitle
* @return
*/
@Override
public SysNotice selectNoticeByNoticeTitle(String noticeTitle) {
return noticeMapper.selectNoticeByNoticeTitle(noticeTitle);
}
} }

View File

@ -0,0 +1,140 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Configuration properties for web management endpoints.
*
* @author Madhura Bhave
* @author Phillip Webb
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.endpoints.web")
public class WebEndpointProperties {
private final Exposure exposure = new Exposure();
/**
* Base path for Web endpoints. Relative to the servlet context path
* (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when
* the management server is sharing the main server port. Relative to the management
* server base path (management.server.base-path) when a separate management server
* port (management.server.port) is configured.
*/
private String basePath = "/actuator";
private String baseUrl = null;
/**
* Mapping between endpoint IDs and the path that should expose them.
*/
private final Map<String, String> pathMapping = new LinkedHashMap<>();
private final Discovery discovery = new Discovery();
public Exposure getExposure() {
return this.exposure;
}
public String getBasePath() {
return this.basePath;
}
public void setBasePath(String basePath) {
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty");
this.basePath = cleanBasePath(basePath);
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
private String cleanBasePath(String basePath) {
if (StringUtils.hasText(basePath) && basePath.endsWith("/")) {
return basePath.substring(0, basePath.length() - 1);
}
return basePath;
}
public Map<String, String> getPathMapping() {
return this.pathMapping;
}
public Discovery getDiscovery() {
return this.discovery;
}
public static class Exposure {
/**
* Endpoint IDs that should be included or '*' for all.
*/
private Set<String> include = new LinkedHashSet<>();
/**
* Endpoint IDs that should be excluded or '*' for all.
*/
private Set<String> exclude = new LinkedHashSet<>();
public Set<String> getInclude() {
return this.include;
}
public void setInclude(Set<String> include) {
this.include = include;
}
public Set<String> getExclude() {
return this.exclude;
}
public void setExclude(Set<String> exclude) {
this.exclude = exclude;
}
}
public static class Discovery {
/**
* Whether the discovery page is enabled.
*/
private boolean enabled = true;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.web.servlet;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* A custom {@link HandlerMapping} that makes web endpoints available over HTTP using
* Spring MVC.
*
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0
*/
public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping {
private final EndpointLinksResolver linksResolver;
@Lazy
@Resource
private WebEndpointProperties webEndpointProperties;
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping);
this.linksResolver = linksResolver;
setOrder(-100);
}
/**
* Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings
* for the given endpoints.
* @param endpointMapping the base mapping for all endpoints
* @param endpoints the web endpoints
* @param endpointMediaTypes media types consumed and produced by the endpoints
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
* @param linksResolver resolver for determining links to available endpoints
* @param shouldRegisterLinksMapping whether the links endpoint should be registered
* @param pathPatternParser the path pattern parser
*/
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping,
PathPatternParser pathPatternParser) {
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping,
pathPatternParser);
this.linksResolver = linksResolver;
setOrder(-100);
}
@Override
protected LinksHandler getLinksHandler() {
return new WebMvcLinksHandler();
}
/**
* Handler for root endpoint providing links.
*/
class WebMvcLinksHandler implements LinksHandler {
@Override
@ResponseBody
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath())));
}
@Override
public String toString() {
return "Actuator root web endpoint";
}
}
}

View File

@ -0,0 +1,30 @@
package com.ruoyi.system.controller.inner
import com.ruoyi.common.core.domain.R
import com.ruoyi.common.core.web.controller.BaseController
import com.ruoyi.common.security.annotation.InnerAuth
import com.ruoyi.system.service.ISysNoticeService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
/**
* 内部调用公告信息
*/
@RestController
@RequestMapping("/inner/notice")
open class InnerSysNoticeController : BaseController() {
@Autowired
open lateinit var noticeService: ISysNoticeService
/**
* 根据ID获取公告信息
*/
@InnerAuth
@GetMapping("/detail")
fun infoById(@RequestParam("noticeId") noticeId: Long): R<Any> {
return R.ok(noticeService.selectNoticeById(noticeId))
}
}

View File

@ -0,0 +1,178 @@
package com.ruoyi.system.controller.inner
import com.github.pagehelper.Page
import com.ruoyi.common.core.domain.R
import com.ruoyi.common.core.utils.StringUtils
import com.ruoyi.common.core.utils.ip.IpUtils
import com.ruoyi.common.core.web.controller.BaseController
import com.ruoyi.common.core.web.domain.AjaxResult
import com.ruoyi.common.log.annotation.Log
import com.ruoyi.common.log.enums.BusinessType
import com.ruoyi.common.security.annotation.InnerAuth
import com.ruoyi.common.security.service.TokenService
import com.ruoyi.common.security.utils.SecurityUtils
import com.ruoyi.system.api.domain.KSysUserAccount
import com.ruoyi.system.api.domain.SysUser
import com.ruoyi.system.api.model.LoginUser
import com.ruoyi.system.service.IKSysUserService
import com.ruoyi.system.service.ISysConfigService
import com.ruoyi.system.service.ISysPermissionService
import com.ruoyi.system.service.ISysUserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
/**
* 用户信息
*
* @author hsdllcw
*/
@RestController
@RequestMapping("/inner/user")
open class InnerSysUserController : BaseController() {
@Autowired
open lateinit var userService: ISysUserService
@Autowired
open lateinit var kSysUserService: IKSysUserService
@Autowired
open lateinit var permissionService: ISysPermissionService
@Autowired
open lateinit var tokenService: TokenService
@Autowired
open lateinit var configService: ISysConfigService
/**
* 获取当前用户信息
*/
@InnerAuth
@GetMapping("/info/phoneNumber/{phoneNumber:\\d+}")
fun infoByPhone(@PathVariable("phoneNumber") phoneNumber: String?): R<LoginUser> {
val sysUser: SysUser = userService.selectUserByPhoneNumber(phoneNumber)
if (StringUtils.isNull(sysUser)) {
return R.fail("用户名或密码错误")
}
// 角色集合
val roles: Set<String> = permissionService.getRolePermission(sysUser)
// 权限集合
val permissions: Set<String> = permissionService.getMenuPermission(sysUser)
val sysUserVo = LoginUser()
sysUserVo.sysUser = sysUser
sysUserVo.roles = roles
sysUserVo.permissions = permissions
return R.ok(sysUserVo)
}
/**
* 获取当前用户信息
*/
@InnerAuth
@GetMapping("/list/phoneNumber/{phoneNumber:\\d+}")
fun findByPhoneNumberStartingWith(@PathVariable("phoneNumber") phoneNumber: String?): R<Page<SysUser>> {
return R.ok(userService.findByPhoneNumberStartingWith(phoneNumber))
}
/**
* 根据ID获取用户信息
*/
@InnerAuth
@GetMapping("/detail/{userId}")
fun infoById(@PathVariable("userId") userId: Long): R<LoginUser> {
val sysUser: SysUser = userService.selectUserById(userId)
// 角色集合
val roles: Set<String> = permissionService.getRolePermission(sysUser)
// 权限集合
val permissions: Set<String> = permissionService.getMenuPermission(sysUser)
val sysUserVo = LoginUser()
sysUserVo.sysUser = sysUser
sysUserVo.roles = roles
sysUserVo.permissions = permissions
return R.ok(sysUserVo)
}
/**
* 根据微信unionid获取用户信息
*/
@InnerAuth
@GetMapping("/detail/wx/unionid/{unionid}")
fun infoByWxUnionId(@PathVariable("unionid") unionid: String): R<LoginUser> {
val sysUser = kSysUserService.selectUserByWxUnionId(unionid)
if (StringUtils.isNull(sysUser)) {
return R.fail("unionid错误")
}
// 角色集合
val roles: Set<String> = permissionService.getRolePermission(sysUser)
// 权限集合
val permissions: Set<String> = permissionService.getMenuPermission(sysUser)
val sysUserVo = LoginUser()
sysUserVo.userid = sysUser?.userId
sysUserVo.ipaddr = IpUtils.getIpAddr()
sysUserVo.sysUser = sysUser
sysUserVo.roles = roles
sysUserVo.permissions = permissions
return R.ok(sysUserVo)
}
/**
* 修改用户
*/
@InnerAuth
@PutMapping
@Log(title = "用户修改本人信息", businessType = BusinessType.UPDATE)
fun edit(@Validated @RequestBody loginUser: LoginUser): AjaxResult {
val targetUser = loginUser.sysUser
if (!userService.checkUserNameUnique(targetUser)) {
return error("修改用户'" + targetUser.userName + "'失败,登录账号已存在")
} else if (StringUtils.isNotEmpty(targetUser.phonenumber) && !userService.checkPhoneUnique(targetUser)) {
return error("修改用户'" + targetUser.userName + "'失败,手机号码已存在")
} else if (StringUtils.isNotEmpty(targetUser.email) && !userService.checkEmailUnique(targetUser)) {
return error("修改用户'" + targetUser.userName + "'失败,邮箱账号已存在")
}
val originUser = userService.selectUserById(targetUser.userId)
originUser.userName = targetUser.userName ?: originUser.userName
originUser.nickName = targetUser.nickName ?: originUser.nickName
originUser.phonenumber = targetUser.phonenumber ?: originUser.phonenumber
originUser.email = targetUser.email ?: originUser.email
originUser.avatar = targetUser.avatar ?: originUser.avatar
originUser.sex = targetUser.sex ?: originUser.sex
originUser.updateBy = originUser.userName
if (loginUser.sysUser.sysUserAccount != null){
originUser.sysUserAccount = loginUser.sysUser.sysUserAccount.apply { this.userId = originUser.userId }
}
userService.updateUser(originUser)
// 更新缓存用户信息
tokenService.setLoginUser(loginUser)
return success(loginUser)
}
/**
* 注册用户信息
*/
@InnerAuth
@PostMapping("/register/dept/{deptId}/wx/unionid")
fun registerUserBySysUserAccount(@RequestBody sysUserAccount: KSysUserAccount, @PathVariable deptId: Long): R<Boolean> {
if ("true" != configService.selectConfigByKey("sys.account.registerUser")) {
return R.fail("当前系统没有开启注册功能!")
}
if (sysUserAccount.wxUnionId == null) return R.fail("微信unionid不存在无法注册")
if (!kSysUserService.checkWxUnionIdUnique(sysUserAccount.wxUnionId!!)) {
return R.fail("保存用户'$sysUserAccount.wxUnionId'失败,注册账号已存在")
}
return R.ok(kSysUserService.registerUserBySysUserAccount(sysUserAccount, deptId))
}
@InnerAuth
@PutMapping("/{userId}/unbind/weixin")
@Log(title = "解绑微信", businessType = BusinessType.UPDATE)
fun unbindWeChat(@PathVariable("userId") userId: Long): AjaxResult {
val loginUser = SecurityUtils.getLoginUser()
kSysUserService.unBindWxByUserId(userId)
// 更新缓存用户信息
tokenService.loginUser = loginUser
return success(loginUser)
}
}

View File

@ -0,0 +1,42 @@
package com.ruoyi.system.mapper
import com.ruoyi.system.api.domain.KSysUserAccount
import com.ruoyi.system.api.domain.SysUser
import org.apache.ibatis.annotations.Param
/**
* 用户表 数据层
*
* @author hsdllcw
*/
interface KSysUserMapper {
/**
* 通过id查询用户
*
* @param userId
* @return 用户对象信息
*/
fun selectUserById(userId: Long): KSysUserAccount?
/**
* 通过用户名查询用户
*
* @param wxUnionId 微信unionid
* @return 用户对象信息
*/
fun selectUserByWxUnionId(wxUnionId: String): SysUser?
/**
* 校验微信unionid是否唯一
*
* @param wxUnionId 微信unionid
* @return 结果
*/
fun checkWxUnionIdUnique(wxUnionId: String): SysUser?
fun insertSysUserAccount(sysUserAccount: KSysUserAccount): Int
fun updateSysUserAccount(sysUserAccount: KSysUserAccount): Int
fun unBindWxByUserId(@Param("userId") userId: Long): Int
}

View File

@ -0,0 +1,48 @@
package com.ruoyi.system.service
import com.ruoyi.system.api.domain.KSysUserAccount
import com.ruoyi.system.api.domain.SysUser
interface IKSysUserService {
fun getISysUserService(): ISysUserService
/**
* 通过id查询用户
*
* @param userId
* @return 用户对象信息
*/
fun selectUserById(userId: Long): KSysUserAccount?
/**
* 通过微信unionid查询用户
*
* @param wxUnionId 微信unionid
* @return 用户对象信息
*/
fun selectUserByWxUnionId(wxUnionId: String): SysUser?
/**
* 校验微信unionid是否唯一
*
* @param wxUnionId 微信unionid
* @return 用户对象信息
*/
fun checkWxUnionIdUnique(wxUnionId: String): Boolean
/**
* 注册用户信息
*
* @param sysUserAccount 包含微信unionId
* @return 结果
*/
fun registerUserBySysUserAccount(sysUserAccount: KSysUserAccount, deptId: Long): Boolean
/**
* 绑定微信
*/
fun updateSysUserAccount(sysUserAccount: KSysUserAccount): Int
/**
* 解绑微信
*/
fun unBindWxByUserId(userId: Long): Int
}

View File

@ -0,0 +1,56 @@
package com.ruoyi.system.service.impl
import com.ruoyi.common.core.constant.UserConstants
import com.ruoyi.common.core.utils.uuid.IdUtils
import com.ruoyi.common.security.utils.SecurityUtils
import com.ruoyi.system.api.domain.KSysUserAccount
import com.ruoyi.system.api.domain.SysUser
import com.ruoyi.system.mapper.KSysUserMapper
import com.ruoyi.system.service.IKSysUserService
import com.ruoyi.system.service.ISysUserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service
@Service
open class KSysUserServiceImpl : IKSysUserService {
@Lazy
@Autowired
lateinit var sysUserService: ISysUserService
@Autowired
lateinit var kSysUserMapper: KSysUserMapper
override fun getISysUserService() = sysUserService
override fun selectUserById(userId: Long) = kSysUserMapper.selectUserById(userId)
override fun selectUserByWxUnionId(wxUnionId: String) = kSysUserMapper.selectUserByWxUnionId(wxUnionId)
override fun checkWxUnionIdUnique(wxUnionId: String) =
kSysUserMapper.checkWxUnionIdUnique(wxUnionId)?.run { UserConstants.NOT_UNIQUE } ?: UserConstants.UNIQUE
/**
* 注册用户信息
*
* @param sysUserAccount 包含微信unionId
* @param deptId 部门ID
* @return 结果
*/
override fun registerUserBySysUserAccount(sysUserAccount: KSysUserAccount, deptId: Long): Boolean {
val user = SysUser().apply {
userName = IdUtils.randomUUID().replace("-".toRegex(), "").substring(0, 30)
nickName = "嘉迪微信用户"
password = SecurityUtils.encryptPassword(IdUtils.randomUUID())
this.deptId = deptId
}
return sysUserService.registerUser(user).apply {
sysUserAccount.memberId = sysUserService.selectUserByUserName(user.userName).userId
kSysUserMapper.insertSysUserAccount(sysUserAccount)
}
}
override fun updateSysUserAccount(sysUserAccount: KSysUserAccount): Int {
return kSysUserMapper.updateSysUserAccount(sysUserAccount)
}
override fun unBindWxByUserId(userId: Long): Int {
return kSysUserMapper.unBindWxByUserId(userId)
}
}

View File

@ -0,0 +1,33 @@
# Tomcat
server:
port: 9201
# Spring
spring:
application:
# 应用名称
name: ruoyi-system
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 78a7f41e-46cc-437a-9716-735888227693
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: dev-ruoyi-system.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,33 @@
# Tomcat
server:
port: 9201
#测试环境
spring:
application:
# 应用名称
name: ruoyi-system
cloud:
nacos:
discovery:
ip: 8.155.60.167
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: e2708b29-ca15-4f63-a919-d33932ebdfda
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: prod-ruoyi-system.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -0,0 +1,32 @@
# Tomcat
server:
port: 9201
#测试环境
spring:
application:
# 应用名称
name: ruoyi-system
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacos.zkjiadi.cc
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
config:
# 配置中心地址
server-addr: nacos.zkjiadi.cc
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392
username: nacos
password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA
logging:
file:
name: test-ruoyi-system.log
pattern:
file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

View File

@ -1,25 +1,4 @@
# Tomcat # Spring默认环境配置
server: spring:
port: 9201 profiles:
active: dev
# Spring
spring:
application:
# 应用名称
name: ruoyi-system
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

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