!277 项目结构重构
Merge pull request !277 from MichelleChung/5.X
已删除280个文件
已添加310个文件
已重命名76个文件
已修改9个文件
| | |
| | | <scope>import</scope> |
| | | </dependency> |
| | | |
| | | <!-- common çä¾èµé
ç½®--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-bom</artifactId> |
| | | <version>${revision}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springdoc</groupId> |
| | | <artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
| | |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-core</artifactId> |
| | | <version>${satoken.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- dynamic-datasource 夿°æ®æº--> |
| | | <dependency> |
| | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | <version>${mybatis-plus.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-annotation</artifactId> |
| | | <version>${mybatis-plus.version}</version> |
| | | </dependency> |
| | | |
| | |
| | | <artifactId>snakeyaml</artifactId> |
| | | <version>${snakeyaml.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- 宿¶ä»»å¡ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-job</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- 代ç çæ--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-generator</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- æ ¸å¿æ¨¡å--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-framework</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- ç³»ç»æ¨¡å--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-system</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- éç¨å·¥å
·--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- OSS对象å卿¨¡å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-oss</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- SMSç信模å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-sms</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- demo模å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-demo</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | </dependencyManagement> |
| | | |
| | | <modules> |
| | | <module>ruoyi-admin</module> |
| | | <module>ruoyi-framework</module> |
| | | <module>ruoyi-system</module> |
| | | <module>ruoyi-job</module> |
| | | <module>ruoyi-generator</module> |
| | | <module>ruoyi-common</module> |
| | | <module>ruoyi-demo</module> |
| | | <module>ruoyi-extend</module> |
| | | <module>ruoyi-oss</module> |
| | | <module>ruoyi-sms</module> |
| | | <module>ruoyi-modules</module> |
| | | </modules> |
| | | <packaging>pom</packaging> |
| | | |
| | |
| | | <artifactId>mssql-jdbc</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- æ ¸å¿æ¨¡å--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-framework</artifactId> |
| | | <artifactId>ruoyi-system</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-system</artifactId> |
| | | <artifactId>ruoyi-common-doc</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-oss</artifactId> |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-oss</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- 代ç çæ--> |
| | |
| | | import cn.hutool.captcha.generator.CodeGenerator; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import com.ruoyi.common.constant.CacheConstants; |
| | | import com.ruoyi.common.constant.Constants; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.enums.CaptchaType; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.redis.RedisUtils; |
| | | import com.ruoyi.common.utils.reflect.ReflectUtils; |
| | | import com.ruoyi.common.utils.spring.SpringUtils; |
| | | import com.ruoyi.framework.config.properties.CaptchaProperties; |
| | | import com.ruoyi.sms.config.properties.SmsProperties; |
| | | import com.ruoyi.sms.core.SmsTemplate; |
| | | import com.ruoyi.sms.entity.SmsResult; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.reflect.ReflectUtils; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import com.ruoyi.common.sms.config.properties.SmsProperties; |
| | | import com.ruoyi.common.sms.core.SmsTemplate; |
| | | import com.ruoyi.common.sms.entity.SmsResult; |
| | | import com.ruoyi.common.web.config.properties.CaptchaProperties; |
| | | import com.ruoyi.common.web.enums.CaptchaType; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | package com.ruoyi.web.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaIgnore; |
| | | import com.ruoyi.common.config.RuoYiConfig; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.core.config.RuoYiConfig; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | |
| | | package com.ruoyi.web.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaIgnore; |
| | | import com.ruoyi.common.constant.Constants; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import com.ruoyi.system.domain.SysMenu; |
| | | import com.ruoyi.system.domain.SysUser; |
| | | import com.ruoyi.common.core.domain.model.LoginBody; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.core.domain.model.SmsLoginBody; |
| | | import com.ruoyi.common.helper.LoginHelper; |
| | | import com.ruoyi.system.domain.vo.RouterVo; |
| | | import com.ruoyi.system.service.ISysMenuService; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | |
| | | package com.ruoyi.web.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaIgnore; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.domain.model.RegisterBody; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | |
| | | package com.ruoyi.test; |
| | | |
| | | import com.ruoyi.common.config.RuoYiConfig; |
| | | import com.ruoyi.common.core.config.RuoYiConfig; |
| | | import org.junit.jupiter.api.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | |
| | | package com.ruoyi.test; |
| | | |
| | | import com.ruoyi.common.enums.UserType; |
| | | import com.ruoyi.common.core.enums.UserType; |
| | | import org.junit.jupiter.api.AfterEach; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.DisplayName; |
| | |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <modules> |
| | | <module>ruoyi-common-bom</module> |
| | | <module>ruoyi-common-core</module> |
| | | <module>ruoyi-common-dict</module> |
| | | <module>ruoyi-common-doc</module> |
| | | <module>ruoyi-common-excel</module> |
| | | <module>ruoyi-common-idempotent</module> |
| | | <module>ruoyi-common-log</module> |
| | | <module>ruoyi-common-mail</module> |
| | | <module>ruoyi-common-mybatis</module> |
| | | <module>ruoyi-common-oss</module> |
| | | <module>ruoyi-common-ratelimiter</module> |
| | | <module>ruoyi-common-redis</module> |
| | | <module>ruoyi-common-satoken</module> |
| | | <module>ruoyi-common-security</module> |
| | | <module>ruoyi-common-sms</module> |
| | | <module>ruoyi-common-web</module> |
| | | </modules> |
| | | |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <packaging>pom</packaging> |
| | | |
| | | <description> |
| | | commonéç¨å·¥å
· |
| | | common éç¨æ¨¡å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | |
| | | <!-- Springæ¡æ¶åºæ¬çæ ¸å¿å·¥å
· --> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-context-support</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- SpringWeb模å --> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-web</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Sa-Token æé认è¯, å¨çº¿ææ¡£ï¼http://sa-token.dev33.cn/ --> |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-spring-boot3-starter</artifactId> |
| | | </dependency> |
| | | <!-- Sa-Token æ´å jwt --> |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-jwt</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- èªå®ä¹éªè¯æ³¨è§£ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-validation</artifactId> |
| | | </dependency> |
| | | |
| | | <!--常ç¨å·¥å
·ç±» --> |
| | | <dependency> |
| | | <groupId>org.apache.commons</groupId> |
| | | <artifactId>commons-lang3</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- JSONå·¥å
·ç±» --> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-databind</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>easyexcel</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- ymlè§£æå¨ --> |
| | | <dependency> |
| | | <groupId>org.yaml</groupId> |
| | | <artifactId>snakeyaml</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- servletå
--> |
| | | <dependency> |
| | | <groupId>jakarta.servlet</groupId> |
| | | <artifactId>jakarta.servlet-api</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- dynamic-datasource 夿°æ®æº--> |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>dynamic-datasource-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-http</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-captcha</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-jwt</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-extra</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>jakarta.mail</groupId> |
| | | <artifactId>jakarta.mail-api</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springdoc</groupId> |
| | | <artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.github.therapi</groupId> |
| | | <artifactId>therapi-runtime-javadoc</artifactId> |
| | | </dependency> |
| | | |
| | | <!--redisson--> |
| | | <dependency> |
| | | <groupId>org.redisson</groupId> |
| | | <artifactId>redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>lock4j-redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- èªå¨çæYMLé
ç½®å
³èJSONæä»¶ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-configuration-processor</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-properties-migrator</artifactId> |
| | | <scope>runtime</scope> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-bom</artifactId> |
| | | <version>${revision}</version> |
| | | <packaging>pom</packaging> |
| | | |
| | | <description> |
| | | ruoyi-common-bom commonä¾èµé¡¹ |
| | | </description> |
| | | |
| | | <properties> |
| | | <revision>5.0.0-SNAPSHOT</revision> |
| | | </properties> |
| | | |
| | | <dependencyManagement> |
| | | <dependencies> |
| | | <!-- æ ¸å¿æ¨¡å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- åå
¸ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-dict</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- æ¥å£æ¨¡å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-doc</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- excel --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-excel</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- å¹ç --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-idempotent</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- æ¥å¿è®°å½ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- é®ä»¶æå¡ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-mail</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- æ°æ®åºæå¡ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- OSS --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-oss</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- éæµ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-ratelimiter</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- ç¼åæå¡ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- satoken --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- å®å
¨æ¨¡å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-security</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- ç信模å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-sms</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- webæå¡ --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </dependencyManagement> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-core æ ¸å¿æ¨¡å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <!-- Springæ¡æ¶åºæ¬çæ ¸å¿å·¥å
· --> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-context-support</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- SpringWeb模å --> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-annotation</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- èªå®ä¹éªè¯æ³¨è§£ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-validation</artifactId> |
| | | </dependency> |
| | | |
| | | <!--常ç¨å·¥å
·ç±» --> |
| | | <dependency> |
| | | <groupId>org.apache.commons</groupId> |
| | | <artifactId>commons-lang3</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- JSONå·¥å
·ç±» --> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-databind</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.datatype</groupId> |
| | | <artifactId>jackson-datatype-jsr310</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- ymlè§£æå¨ --> |
| | | <dependency> |
| | | <groupId>org.yaml</groupId> |
| | | <artifactId>snakeyaml</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- servletå
--> |
| | | <dependency> |
| | | <groupId>jakarta.servlet</groupId> |
| | | <artifactId>jakarta.servlet-api</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-http</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-captcha</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-jwt</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-extra</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- èªå¨çæYMLé
ç½®å
³èJSONæä»¶ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-configuration-processor</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-properties-migrator</artifactId> |
| | | <scope>runtime</scope> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.annotation; |
| | | |
| | | import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
| | | import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
| | | import com.ruoyi.common.core.enums.SensitiveStrategy; |
| | | import com.ruoyi.common.core.jackson.SensitiveJsonSerializer; |
| | | |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | |
| | | /** |
| | | * æ°æ®è±ææ³¨è§£ |
| | | * |
| | | * @author zhujie |
| | | */ |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Target(ElementType.FIELD) |
| | | @JacksonAnnotationsInside |
| | | @JsonSerialize(using = SensitiveJsonSerializer.class) |
| | | public @interface Sensitive { |
| | | SensitiveStrategy strategy(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config; |
| | | |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.EnableAspectJAutoProxy; |
| | | |
| | | /** |
| | | * ç¨åºæ³¨è§£é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | // 表示éè¿aopæ¡æ¶æ´é²è¯¥ä»£ç对象,AopContextè½å¤è®¿é® |
| | | @EnableAspectJAutoProxy(exposeProxy = true) |
| | | public class ApplicationConfig { |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config; |
| | | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.scheduling.annotation.AsyncConfigurer; |
| | | import org.springframework.scheduling.annotation.EnableAsync; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.concurrent.Executor; |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | |
| | | /** |
| | | * 弿¥é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @EnableAsync(proxyTargetClass = true) |
| | | @AutoConfiguration |
| | | public class AsyncConfig implements AsyncConfigurer { |
| | | |
| | | @Autowired |
| | | @Qualifier("scheduledExecutorService") |
| | | private ScheduledExecutorService scheduledExecutorService; |
| | | |
| | | /** |
| | | * èªå®ä¹ @Async 注解使ç¨ç³»ç»çº¿ç¨æ± |
| | | */ |
| | | @Override |
| | | public Executor getAsyncExecutor() { |
| | | return scheduledExecutorService; |
| | | } |
| | | |
| | | /** |
| | | * 弿¥æ§è¡å¼å¸¸å¤ç |
| | | */ |
| | | @Override |
| | | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { |
| | | return (throwable, method, objects) -> { |
| | | throwable.printStackTrace(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("Exception message - ").append(throwable.getMessage()) |
| | | .append(", Method name - ").append(method.getName()); |
| | | if (ArrayUtil.isNotEmpty(objects)) { |
| | | sb.append(", Parameter value - ").append(Arrays.toString(objects)); |
| | | } |
| | | throw new ServiceException(sb.toString()); |
| | | }; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config; |
| | | |
| | | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| | | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
| | | import com.ruoyi.common.core.jackson.BigNumberSerializer; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; |
| | | import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.BigInteger; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.TimeZone; |
| | | |
| | | /** |
| | | * jackson é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @AutoConfiguration(before = JacksonAutoConfiguration.class) |
| | | public class JacksonConfig { |
| | | |
| | | @Bean |
| | | public Jackson2ObjectMapperBuilderCustomizer customizer() { |
| | | return builder -> { |
| | | // å
¨å±é
ç½®åºååè¿å JSON å¤ç |
| | | JavaTimeModule javaTimeModule = new JavaTimeModule(); |
| | | javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); |
| | | javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); |
| | | javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); |
| | | javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); |
| | | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); |
| | | builder.modules(javaTimeModule); |
| | | builder.timeZone(TimeZone.getDefault()); |
| | | log.info("åå§å jackson é
ç½®"); |
| | | }; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config; |
| | | |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 读å项ç®ç¸å
³é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "ruoyi") |
| | | public class RuoYiConfig { |
| | | |
| | | /** |
| | | * 项ç®åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | private String version; |
| | | |
| | | /** |
| | | * çæå¹´ä»½ |
| | | */ |
| | | private String copyrightYear; |
| | | |
| | | /** |
| | | * å®ä¾æ¼ç¤ºå¼å
³ |
| | | */ |
| | | private boolean demoEnabled; |
| | | |
| | | /** |
| | | * ç¼åæå è½½ |
| | | */ |
| | | private boolean cacheLazy; |
| | | |
| | | /** |
| | | * è·åå°åå¼å
³ |
| | | */ |
| | | @Getter |
| | | private static boolean addressEnabled; |
| | | |
| | | public void setAddressEnabled(boolean addressEnabled) { |
| | | RuoYiConfig.addressEnabled = addressEnabled; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config; |
| | | |
| | | import com.ruoyi.common.core.config.properties.ThreadPoolProperties; |
| | | import com.ruoyi.common.core.utils.Threads; |
| | | import org.apache.commons.lang3.concurrent.BasicThreadFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | import java.util.concurrent.ScheduledThreadPoolExecutor; |
| | | import java.util.concurrent.ThreadPoolExecutor; |
| | | |
| | | /** |
| | | * çº¿ç¨æ± é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | **/ |
| | | @AutoConfiguration |
| | | public class ThreadPoolConfig { |
| | | |
| | | /** |
| | | * æ ¸å¿çº¿ç¨æ° = cpu æ ¸å¿æ° + 1 |
| | | */ |
| | | private final int core = Runtime.getRuntime().availableProcessors() + 1; |
| | | |
| | | @Autowired |
| | | private ThreadPoolProperties threadPoolProperties; |
| | | |
| | | @Bean(name = "threadPoolTaskExecutor") |
| | | @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true") |
| | | public ThreadPoolTaskExecutor threadPoolTaskExecutor() { |
| | | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); |
| | | executor.setCorePoolSize(core); |
| | | executor.setMaxPoolSize(core * 2); |
| | | executor.setQueueCapacity(threadPoolProperties.getQueueCapacity()); |
| | | executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds()); |
| | | executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); |
| | | return executor; |
| | | } |
| | | |
| | | /** |
| | | * æ§è¡å¨ææ§æå®æ¶ä»»å¡ |
| | | */ |
| | | @Bean(name = "scheduledExecutorService") |
| | | protected ScheduledExecutorService scheduledExecutorService() { |
| | | return new ScheduledThreadPoolExecutor(core, |
| | | new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(), |
| | | new ThreadPoolExecutor.CallerRunsPolicy()) { |
| | | @Override |
| | | protected void afterExecute(Runnable r, Throwable t) { |
| | | super.afterExecute(r, t); |
| | | Threads.printException(r, t); |
| | | } |
| | | }; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config; |
| | | |
| | | import org.hibernate.validator.HibernateValidator; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.MessageSource; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; |
| | | |
| | | import jakarta.validation.Validator; |
| | | import java.util.Properties; |
| | | |
| | | /** |
| | | * æ ¡éªæ¡æ¶é
置类 |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | public class ValidatorConfig { |
| | | |
| | | @Autowired |
| | | private MessageSource messageSource; |
| | | |
| | | /** |
| | | * é
ç½®æ ¡éªæ¡æ¶ å¿«éè¿åæ¨¡å¼ |
| | | */ |
| | | @Bean |
| | | public Validator validator() { |
| | | LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean(); |
| | | // å½é
å |
| | | factoryBean.setValidationMessageSource(messageSource); |
| | | // è®¾ç½®ä½¿ç¨ HibernateValidator æ ¡éªå¨ |
| | | factoryBean.setProviderClass(HibernateValidator.class); |
| | | Properties properties = new Properties(); |
| | | // 设置 å¿«éå¼å¸¸è¿å |
| | | properties.setProperty("hibernate.validator.fail_fast", "true"); |
| | | factoryBean.setValidationProperties(properties); |
| | | // å è½½é
ç½® |
| | | factoryBean.afterPropertiesSet(); |
| | | return factoryBean.getValidator(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.config.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * çº¿ç¨æ± é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "thread-pool") |
| | | public class ThreadPoolProperties { |
| | | |
| | | /** |
| | | * æ¯å¦å¼å¯çº¿ç¨æ± |
| | | */ |
| | | private boolean enabled; |
| | | |
| | | /** |
| | | * éåæå¤§é¿åº¦ |
| | | */ |
| | | private int queueCapacity; |
| | | |
| | | /** |
| | | * çº¿ç¨æ± ç»´æ¤çº¿ç¨æå
许çç©ºé²æ¶é´ |
| | | */ |
| | | private int keepAliveSeconds; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.constant; |
| | | |
| | | /** |
| | | * ç¼åçkey 常é |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public interface CacheConstants { |
| | | |
| | | /** |
| | | * ç»å½ç¨æ· redis key |
| | | */ |
| | | String LOGIN_TOKEN_KEY = "Authorization:login:token:"; |
| | | |
| | | /** |
| | | * å¨çº¿ç¨æ· redis key |
| | | */ |
| | | String ONLINE_TOKEN_KEY = "online_tokens:"; |
| | | |
| | | /** |
| | | * éªè¯ç redis key |
| | | */ |
| | | String CAPTCHA_CODE_KEY = "captcha_codes:"; |
| | | |
| | | /** |
| | | * åæ°ç®¡ç cache key |
| | | */ |
| | | String SYS_CONFIG_KEY = "sys_config:"; |
| | | |
| | | /** |
| | | * åå
¸ç®¡ç cache key |
| | | */ |
| | | String SYS_DICT_KEY = "sys_dict:"; |
| | | |
| | | /** |
| | | * é²éæäº¤ redis key |
| | | */ |
| | | String REPEAT_SUBMIT_KEY = "repeat_submit:"; |
| | | |
| | | /** |
| | | * éæµ redis key |
| | | */ |
| | | String RATE_LIMIT_KEY = "rate_limit:"; |
| | | |
| | | /** |
| | | * ç»å½è´¦æ·å¯ç éè¯¯æ¬¡æ° redis key |
| | | */ |
| | | String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.constant; |
| | | |
| | | /** |
| | | * ç¼åç»å称常é |
| | | * <p> |
| | | * key æ ¼å¼ä¸º cacheNames#ttl#maxIdleTime#maxSize |
| | | * <p> |
| | | * ttl è¿ææ¶é´ å¦æè®¾ç½®ä¸º0åä¸è¿æ é»è®¤ä¸º0 |
| | | * maxIdleTime æå¤§ç©ºé²æ¶é´ æ ¹æ®LRUç®æ³æ¸
çç©ºé²æ°æ® å¦æè®¾ç½®ä¸º0å䏿£æµ é»è®¤ä¸º0 |
| | | * maxSize ç»æå¤§é¿åº¦ æ ¹æ®LRUç®æ³æ¸
çæº¢åºæ°æ® å¦æè®¾ç½®ä¸º0åæ éé¿ é»è®¤ä¸º0 |
| | | * <p> |
| | | * ä¾å: test#60sãtest#0#60sãtest#0#1m#1000ãtest#1h#0#500 |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public interface CacheNames { |
| | | |
| | | /** |
| | | * æ¼ç¤ºæ¡ä¾ |
| | | */ |
| | | String DEMO_CACHE = "demo:cache#60s#10m#20"; |
| | | |
| | | /** |
| | | * ç³»ç»é
ç½® |
| | | */ |
| | | String SYS_CONFIG = "sys_config"; |
| | | |
| | | /** |
| | | * æ°æ®åå
¸ |
| | | */ |
| | | String SYS_DICT = "sys_dict"; |
| | | |
| | | /** |
| | | * OSSå
容 |
| | | */ |
| | | String SYS_OSS = "sys_oss#30d"; |
| | | |
| | | /** |
| | | * OSSé
ç½® |
| | | */ |
| | | String SYS_OSS_CONFIG = "sys_oss_config"; |
| | | |
| | | /** |
| | | * å¨çº¿ç¨æ· |
| | | */ |
| | | String ONLINE_TOKEN = "online_tokens"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.constant; |
| | | |
| | | /** |
| | | * éç¨å¸¸éä¿¡æ¯ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public interface Constants { |
| | | |
| | | /** |
| | | * UTF-8 å符é |
| | | */ |
| | | String UTF8 = "UTF-8"; |
| | | |
| | | /** |
| | | * GBK å符é |
| | | */ |
| | | String GBK = "GBK"; |
| | | |
| | | /** |
| | | * www主å |
| | | */ |
| | | String WWW = "www."; |
| | | |
| | | /** |
| | | * httpè¯·æ± |
| | | */ |
| | | String HTTP = "http://"; |
| | | |
| | | /** |
| | | * httpsè¯·æ± |
| | | */ |
| | | String HTTPS = "https://"; |
| | | |
| | | /** |
| | | * éç¨æåæ è¯ |
| | | */ |
| | | String SUCCESS = "0"; |
| | | |
| | | /** |
| | | * éç¨å¤±è´¥æ è¯ |
| | | */ |
| | | String FAIL = "1"; |
| | | |
| | | /** |
| | | * ç»å½æå |
| | | */ |
| | | String LOGIN_SUCCESS = "Success"; |
| | | |
| | | /** |
| | | * 注é |
| | | */ |
| | | String LOGOUT = "Logout"; |
| | | |
| | | /** |
| | | * 注å |
| | | */ |
| | | String REGISTER = "Register"; |
| | | |
| | | /** |
| | | * ç»å½å¤±è´¥ |
| | | */ |
| | | String LOGIN_FAIL = "Error"; |
| | | |
| | | /** |
| | | * éªè¯ç æææï¼åéï¼ |
| | | */ |
| | | Integer CAPTCHA_EXPIRATION = 2; |
| | | |
| | | /** |
| | | * 令ç |
| | | */ |
| | | String TOKEN = "token"; |
| | | |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.constant; |
| | | |
| | | /** |
| | | * 代ç çæéç¨å¸¸é |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public interface GenConstants { |
| | | /** |
| | | * å表ï¼å¢å æ¹æ¥ï¼ |
| | | */ |
| | | String TPL_CRUD = "crud"; |
| | | |
| | | /** |
| | | * æ 表ï¼å¢å æ¹æ¥ï¼ |
| | | */ |
| | | String TPL_TREE = "tree"; |
| | | |
| | | /** |
| | | * æ ç¼ç åæ®µ |
| | | */ |
| | | String TREE_CODE = "treeCode"; |
| | | |
| | | /** |
| | | * æ ç¶ç¼ç åæ®µ |
| | | */ |
| | | String TREE_PARENT_CODE = "treeParentCode"; |
| | | |
| | | /** |
| | | * æ åç§°åæ®µ |
| | | */ |
| | | String TREE_NAME = "treeName"; |
| | | |
| | | /** |
| | | * ä¸çº§èåIDåæ®µ |
| | | */ |
| | | String PARENT_MENU_ID = "parentMenuId"; |
| | | |
| | | /** |
| | | * ä¸çº§èååç§°åæ®µ |
| | | */ |
| | | String PARENT_MENU_NAME = "parentMenuName"; |
| | | |
| | | /** |
| | | * æ°æ®åºå符串类å |
| | | */ |
| | | String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"}; |
| | | |
| | | /** |
| | | * æ°æ®åºææ¬ç±»å |
| | | */ |
| | | String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"}; |
| | | |
| | | /** |
| | | * æ°æ®åºæ¶é´ç±»å |
| | | */ |
| | | String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"}; |
| | | |
| | | /** |
| | | * æ°æ®åºæ°åç±»å |
| | | */ |
| | | String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer", |
| | | "bit", "bigint", "float", "double", "decimal"}; |
| | | |
| | | /** |
| | | * BO对象 ä¸éè¦æ·»å åæ®µ |
| | | */ |
| | | String[] COLUMNNAME_NOT_ADD = {"create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version"}; |
| | | |
| | | /** |
| | | * BO对象 ä¸éè¦ç¼è¾å段 |
| | | */ |
| | | String[] COLUMNNAME_NOT_EDIT = {"create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version"}; |
| | | |
| | | /** |
| | | * VO对象 ä¸éè¦è¿ååæ®µ |
| | | */ |
| | | String[] COLUMNNAME_NOT_LIST = {"create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version"}; |
| | | |
| | | /** |
| | | * BO对象 ä¸éè¦æ¥è¯¢å段 |
| | | */ |
| | | String[] COLUMNNAME_NOT_QUERY = {"id", "create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "remark", "version"}; |
| | | |
| | | /** |
| | | * Entityåºç±»å段 |
| | | */ |
| | | String[] BASE_ENTITY = {"createBy", "createTime", "updateBy", "updateTime"}; |
| | | |
| | | /** |
| | | * Treeåºç±»å段 |
| | | */ |
| | | String[] TREE_ENTITY = {"parentName", "parentId", "children"}; |
| | | |
| | | /** |
| | | * ææ¬æ¡ |
| | | */ |
| | | String HTML_INPUT = "input"; |
| | | |
| | | /** |
| | | * ææ¬å |
| | | */ |
| | | String HTML_TEXTAREA = "textarea"; |
| | | |
| | | /** |
| | | * ä¸ææ¡ |
| | | */ |
| | | String HTML_SELECT = "select"; |
| | | |
| | | /** |
| | | * åéæ¡ |
| | | */ |
| | | String HTML_RADIO = "radio"; |
| | | |
| | | /** |
| | | * å¤éæ¡ |
| | | */ |
| | | String HTML_CHECKBOX = "checkbox"; |
| | | |
| | | /** |
| | | * æ¥ææ§ä»¶ |
| | | */ |
| | | String HTML_DATETIME = "datetime"; |
| | | |
| | | /** |
| | | * å¾çä¸ä¼ æ§ä»¶ |
| | | */ |
| | | String HTML_IMAGE_UPLOAD = "imageUpload"; |
| | | |
| | | /** |
| | | * æä»¶ä¸ä¼ æ§ä»¶ |
| | | */ |
| | | String HTML_FILE_UPLOAD = "fileUpload"; |
| | | |
| | | /** |
| | | * å¯ææ¬æ§ä»¶ |
| | | */ |
| | | String HTML_EDITOR = "editor"; |
| | | |
| | | /** |
| | | * å符串类å |
| | | */ |
| | | String TYPE_STRING = "String"; |
| | | |
| | | /** |
| | | * æ´å |
| | | */ |
| | | String TYPE_INTEGER = "Integer"; |
| | | |
| | | /** |
| | | * é¿æ´å |
| | | */ |
| | | String TYPE_LONG = "Long"; |
| | | |
| | | /** |
| | | * æµ®ç¹å |
| | | */ |
| | | String TYPE_DOUBLE = "Double"; |
| | | |
| | | /** |
| | | * é«ç²¾åº¦è®¡ç®ç±»å |
| | | */ |
| | | String TYPE_BIGDECIMAL = "BigDecimal"; |
| | | |
| | | /** |
| | | * æ¶é´ç±»å |
| | | */ |
| | | String TYPE_DATE = "Date"; |
| | | |
| | | /** |
| | | * æ¨¡ç³æ¥è¯¢ |
| | | */ |
| | | String QUERY_LIKE = "LIKE"; |
| | | |
| | | /** |
| | | * ç¸çæ¥è¯¢ |
| | | */ |
| | | String QUERY_EQ = "EQ"; |
| | | |
| | | /** |
| | | * éè¦ |
| | | */ |
| | | String REQUIRE = "1"; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.constant; |
| | | |
| | | /** |
| | | * è¿åç¶æç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public interface HttpStatus { |
| | | /** |
| | | * æä½æå |
| | | */ |
| | | int SUCCESS = 200; |
| | | |
| | | /** |
| | | * 对象å建æå |
| | | */ |
| | | int CREATED = 201; |
| | | |
| | | /** |
| | | * 请æ±å·²ç»è¢«æ¥å |
| | | */ |
| | | int ACCEPTED = 202; |
| | | |
| | | /** |
| | | * æä½å·²ç»æ§è¡æåï¼ä½æ¯æ²¡æè¿åæ°æ® |
| | | */ |
| | | int NO_CONTENT = 204; |
| | | |
| | | /** |
| | | * èµæºå·²è¢«ç§»é¤ |
| | | */ |
| | | int MOVED_PERM = 301; |
| | | |
| | | /** |
| | | * éå®å |
| | | */ |
| | | int SEE_OTHER = 303; |
| | | |
| | | /** |
| | | * èµæºæ²¡æè¢«ä¿®æ¹ |
| | | */ |
| | | int NOT_MODIFIED = 304; |
| | | |
| | | /** |
| | | * åæ°å表é误ï¼ç¼ºå°ï¼æ ¼å¼ä¸å¹é
ï¼ |
| | | */ |
| | | int BAD_REQUEST = 400; |
| | | |
| | | /** |
| | | * æªææ |
| | | */ |
| | | int UNAUTHORIZED = 401; |
| | | |
| | | /** |
| | | * 访é®åéï¼ææè¿æ |
| | | */ |
| | | int FORBIDDEN = 403; |
| | | |
| | | /** |
| | | * èµæºï¼æå¡æªæ¾å° |
| | | */ |
| | | int NOT_FOUND = 404; |
| | | |
| | | /** |
| | | * ä¸å
许çhttpæ¹æ³ |
| | | */ |
| | | int BAD_METHOD = 405; |
| | | |
| | | /** |
| | | * èµæºå²çªï¼æè
èµæºè¢«é |
| | | */ |
| | | int CONFLICT = 409; |
| | | |
| | | /** |
| | | * 䏿¯æçæ°æ®ï¼åªä½ç±»å |
| | | */ |
| | | int UNSUPPORTED_TYPE = 415; |
| | | |
| | | /** |
| | | * ç³»ç»å
é¨é误 |
| | | */ |
| | | int ERROR = 500; |
| | | |
| | | /** |
| | | * æ¥å£æªå®ç° |
| | | */ |
| | | int NOT_IMPLEMENTED = 501; |
| | | |
| | | /** |
| | | * ç³»ç»è¦åæ¶æ¯ |
| | | */ |
| | | int WARN = 601; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.constant; |
| | | |
| | | /** |
| | | * ç¨æ·å¸¸éä¿¡æ¯ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public interface UserConstants { |
| | | |
| | | /** |
| | | * å¹³å°å
ç³»ç»ç¨æ·çå¯ä¸æ å¿ |
| | | */ |
| | | String SYS_USER = "SYS_USER"; |
| | | |
| | | /** |
| | | * æ£å¸¸ç¶æ |
| | | */ |
| | | String NORMAL = "0"; |
| | | |
| | | /** |
| | | * å¼å¸¸ç¶æ |
| | | */ |
| | | String EXCEPTION = "1"; |
| | | |
| | | /** |
| | | * ç¨æ·æ£å¸¸ç¶æ |
| | | */ |
| | | String USER_NORMAL = "0"; |
| | | |
| | | /** |
| | | * ç¨æ·å°ç¦ç¶æ |
| | | */ |
| | | String USER_DISABLE = "1"; |
| | | |
| | | /** |
| | | * è§è²æ£å¸¸ç¶æ |
| | | */ |
| | | String ROLE_NORMAL = "0"; |
| | | |
| | | /** |
| | | * è§è²å°ç¦ç¶æ |
| | | */ |
| | | String ROLE_DISABLE = "1"; |
| | | |
| | | /** |
| | | * é¨é¨æ£å¸¸ç¶æ |
| | | */ |
| | | String DEPT_NORMAL = "0"; |
| | | |
| | | /** |
| | | * é¨é¨åç¨ç¶æ |
| | | */ |
| | | String DEPT_DISABLE = "1"; |
| | | |
| | | /** |
| | | * åå
¸æ£å¸¸ç¶æ |
| | | */ |
| | | String DICT_NORMAL = "0"; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºç³»ç»é»è®¤ï¼æ¯ï¼ |
| | | */ |
| | | String YES = "Y"; |
| | | |
| | | /** |
| | | * æ¯å¦èåå¤é¾ï¼æ¯ï¼ |
| | | */ |
| | | String YES_FRAME = "0"; |
| | | |
| | | /** |
| | | * æ¯å¦èåå¤é¾ï¼å¦ï¼ |
| | | */ |
| | | String NO_FRAME = "1"; |
| | | |
| | | /** |
| | | * èåæ£å¸¸ç¶æ |
| | | */ |
| | | String MENU_NORMAL = "0"; |
| | | |
| | | /** |
| | | * èååç¨ç¶æ |
| | | */ |
| | | String MENU_DISABLE = "1"; |
| | | |
| | | /** |
| | | * èåç±»åï¼ç®å½ï¼ |
| | | */ |
| | | String TYPE_DIR = "M"; |
| | | |
| | | /** |
| | | * èåç±»åï¼èåï¼ |
| | | */ |
| | | String TYPE_MENU = "C"; |
| | | |
| | | /** |
| | | * èåç±»åï¼æé®ï¼ |
| | | */ |
| | | String TYPE_BUTTON = "F"; |
| | | |
| | | /** |
| | | * Layoutç»ä»¶æ è¯ |
| | | */ |
| | | String LAYOUT = "Layout"; |
| | | |
| | | /** |
| | | * ParentViewç»ä»¶æ è¯ |
| | | */ |
| | | String PARENT_VIEW = "ParentView"; |
| | | |
| | | /** |
| | | * InnerLinkç»ä»¶æ è¯ |
| | | */ |
| | | String INNER_LINK = "InnerLink"; |
| | | |
| | | /** |
| | | * æ ¡éªè¿åç»æç |
| | | */ |
| | | String UNIQUE = "0"; |
| | | String NOT_UNIQUE = "1"; |
| | | |
| | | /** |
| | | * ç¨æ·åé¿åº¦éå¶ |
| | | */ |
| | | int USERNAME_MIN_LENGTH = 2; |
| | | int USERNAME_MAX_LENGTH = 20; |
| | | |
| | | /** |
| | | * å¯ç é¿åº¦éå¶ |
| | | */ |
| | | int PASSWORD_MIN_LENGTH = 5; |
| | | int PASSWORD_MAX_LENGTH = 20; |
| | | |
| | | /** |
| | | * 管çåID |
| | | */ |
| | | Long ADMIN_ID = 1L; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.domain; |
| | | |
| | | import com.ruoyi.common.core.constant.HttpStatus; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ååºä¿¡æ¯ä¸»ä½ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class R<T> implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æå |
| | | */ |
| | | public static final int SUCCESS = 200; |
| | | |
| | | /** |
| | | * 失败 |
| | | */ |
| | | public static final int FAIL = 500; |
| | | |
| | | private int code; |
| | | |
| | | private String msg; |
| | | |
| | | private T data; |
| | | |
| | | public static <T> R<T> ok() { |
| | | return restResult(null, SUCCESS, "æä½æå"); |
| | | } |
| | | |
| | | public static <T> R<T> ok(T data) { |
| | | return restResult(data, SUCCESS, "æä½æå"); |
| | | } |
| | | |
| | | public static <T> R<T> ok(String msg) { |
| | | return restResult(null, SUCCESS, msg); |
| | | } |
| | | |
| | | public static <T> R<T> ok(String msg, T data) { |
| | | return restResult(data, SUCCESS, msg); |
| | | } |
| | | |
| | | public static <T> R<T> fail() { |
| | | return restResult(null, FAIL, "æä½å¤±è´¥"); |
| | | } |
| | | |
| | | public static <T> R<T> fail(String msg) { |
| | | return restResult(null, FAIL, msg); |
| | | } |
| | | |
| | | public static <T> R<T> fail(T data) { |
| | | return restResult(data, FAIL, "æä½å¤±è´¥"); |
| | | } |
| | | |
| | | public static <T> R<T> fail(String msg, T data) { |
| | | return restResult(data, FAIL, msg); |
| | | } |
| | | |
| | | public static <T> R<T> fail(int code, String msg) { |
| | | return restResult(null, code, msg); |
| | | } |
| | | |
| | | /** |
| | | * è¿åè¦åæ¶æ¯ |
| | | * |
| | | * @param msg è¿åå
容 |
| | | * @return è¦åæ¶æ¯ |
| | | */ |
| | | public static <T> R<T> warn(String msg) { |
| | | return restResult(null, HttpStatus.WARN, msg); |
| | | } |
| | | |
| | | /** |
| | | * è¿åè¦åæ¶æ¯ |
| | | * |
| | | * @param msg è¿åå
容 |
| | | * @param data æ°æ®å¯¹è±¡ |
| | | * @return è¦åæ¶æ¯ |
| | | */ |
| | | public static <T> R<T> warn(String msg, T data) { |
| | | return restResult(data, HttpStatus.WARN, msg); |
| | | } |
| | | |
| | | private static <T> R<T> restResult(T data, int code, String msg) { |
| | | R<T> r = new R<>(); |
| | | r.setCode(code); |
| | | r.setData(data); |
| | | r.setMsg(msg); |
| | | return r; |
| | | } |
| | | |
| | | public static <T> Boolean isError(R<T> ret) { |
| | | return !isSuccess(ret); |
| | | } |
| | | |
| | | public static <T> Boolean isSuccess(R<T> ret) { |
| | | return R.SUCCESS == ret.getCode(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.domain.model; |
| | | |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import lombok.Data; |
| | | import org.hibernate.validator.constraints.Length; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * ç¨æ·ç»å½å¯¹è±¡ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class LoginBody { |
| | | |
| | | /** |
| | | * ç¨æ·å |
| | | */ |
| | | @NotBlank(message = "{user.username.not.blank}") |
| | | @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}") |
| | | private String username; |
| | | |
| | | /** |
| | | * ç¨æ·å¯ç |
| | | */ |
| | | @NotBlank(message = "{user.password.not.blank}") |
| | | @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}") |
| | | private String password; |
| | | |
| | | /** |
| | | * éªè¯ç |
| | | */ |
| | | private String code; |
| | | |
| | | /** |
| | | * å¯ä¸æ è¯ |
| | | */ |
| | | private String uuid; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.domain.model; |
| | | |
| | | import com.ruoyi.common.core.domain.dto.RoleDTO; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * ç»å½ç¨æ·èº«ä»½æé |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class LoginUser implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¨æ·ID |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * é¨é¨å |
| | | */ |
| | | private String deptName; |
| | | |
| | | /** |
| | | * ç¨æ·å¯ä¸æ è¯ |
| | | */ |
| | | private String token; |
| | | |
| | | /** |
| | | * ç¨æ·ç±»å |
| | | */ |
| | | private String userType; |
| | | |
| | | /** |
| | | * ç»å½æ¶é´ |
| | | */ |
| | | private Long loginTime; |
| | | |
| | | /** |
| | | * è¿ææ¶é´ |
| | | */ |
| | | private Long expireTime; |
| | | |
| | | /** |
| | | * ç»å½IPå°å |
| | | */ |
| | | private String ipaddr; |
| | | |
| | | /** |
| | | * ç»å½å°ç¹ |
| | | */ |
| | | private String loginLocation; |
| | | |
| | | /** |
| | | * æµè§å¨ç±»å |
| | | */ |
| | | private String browser; |
| | | |
| | | /** |
| | | * æä½ç³»ç» |
| | | */ |
| | | private String os; |
| | | |
| | | /** |
| | | * èåæé |
| | | */ |
| | | private Set<String> menuPermission; |
| | | |
| | | /** |
| | | * è§è²æé |
| | | */ |
| | | private Set<String> rolePermission; |
| | | |
| | | /** |
| | | * ç¨æ·å |
| | | */ |
| | | private String username; |
| | | |
| | | /** |
| | | * è§è²å¯¹è±¡ |
| | | */ |
| | | private List<RoleDTO> roles; |
| | | |
| | | /** |
| | | * æ°æ®æé å½åè§è²ID |
| | | */ |
| | | private Long roleId; |
| | | |
| | | /** |
| | | * è·åç»å½id |
| | | */ |
| | | public String getLoginId() { |
| | | if (userType == null) { |
| | | throw new IllegalArgumentException("ç¨æ·ç±»åä¸è½ä¸ºç©º"); |
| | | } |
| | | if (userId == null) { |
| | | throw new IllegalArgumentException("ç¨æ·IDä¸è½ä¸ºç©º"); |
| | | } |
| | | return userType + ":" + userId; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 设å¤ç±»å |
| | | * é对ä¸å¥ ç¨æ·ä½ç³» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum DeviceType { |
| | | |
| | | /** |
| | | * pc端 |
| | | */ |
| | | PC("pc"), |
| | | |
| | | /** |
| | | * app端 |
| | | */ |
| | | APP("app"), |
| | | |
| | | /** |
| | | * å°ç¨åºç«¯ |
| | | */ |
| | | XCX("xcx"); |
| | | |
| | | private final String device; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * ç»å½ç±»å |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum LoginType { |
| | | |
| | | /** |
| | | * å¯ç ç»å½ |
| | | */ |
| | | PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"), |
| | | |
| | | /** |
| | | * çä¿¡ç»å½ |
| | | */ |
| | | SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"), |
| | | |
| | | /** |
| | | * å°ç¨åºç»å½ |
| | | */ |
| | | XCX("", ""); |
| | | |
| | | /** |
| | | * ç»å½éè¯è¶
åºéå¶æç¤º |
| | | */ |
| | | final String retryLimitExceed; |
| | | |
| | | /** |
| | | * ç»å½éè¯éå¶è®¡æ°æç¤º |
| | | */ |
| | | final String retryLimitCount; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.enums; |
| | | |
| | | import cn.hutool.core.util.DesensitizedUtil; |
| | | import lombok.AllArgsConstructor; |
| | | |
| | | import java.util.function.Function; |
| | | |
| | | /** |
| | | * è±æçç¥ |
| | | * |
| | | * @author Yjoioooo |
| | | * @version 3.6.0 |
| | | */ |
| | | @AllArgsConstructor |
| | | public enum SensitiveStrategy { |
| | | |
| | | /** |
| | | * 身份è¯è±æ |
| | | */ |
| | | ID_CARD(s -> DesensitizedUtil.idCardNum(s, 3, 4)), |
| | | |
| | | /** |
| | | * ææºå·è±æ |
| | | */ |
| | | PHONE(DesensitizedUtil::mobilePhone), |
| | | |
| | | /** |
| | | * å°åè±æ |
| | | */ |
| | | ADDRESS(s -> DesensitizedUtil.address(s, 8)), |
| | | |
| | | /** |
| | | * é®ç®±è±æ |
| | | */ |
| | | EMAIL(DesensitizedUtil::email), |
| | | |
| | | /** |
| | | * é¶è¡å¡ |
| | | */ |
| | | BANK_CARD(DesensitizedUtil::bankCard); |
| | | |
| | | //å¯èªè¡æ·»å å
¶ä»è±æçç¥ |
| | | |
| | | private final Function<String, String> desensitizer; |
| | | |
| | | public Function<String, String> desensitizer() { |
| | | return desensitizer; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.enums; |
| | | |
| | | /** |
| | | * ç¨æ·ç¶æ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum UserStatus { |
| | | OK("0", "æ£å¸¸"), DISABLE("1", "åç¨"), DELETED("2", "å é¤"); |
| | | |
| | | private final String code; |
| | | private final String info; |
| | | |
| | | UserStatus(String code, String info) { |
| | | this.code = code; |
| | | this.info = info; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public String getInfo() { |
| | | return info; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.enums; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 设å¤ç±»å |
| | | * é对å¤å¥ ç¨æ·ä½ç³» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum UserType { |
| | | |
| | | /** |
| | | * pc端 |
| | | */ |
| | | SYS_USER("sys_user"), |
| | | |
| | | /** |
| | | * app端 |
| | | */ |
| | | APP_USER("app_user"); |
| | | |
| | | private final String userType; |
| | | |
| | | public static UserType getUserType(String str) { |
| | | for (UserType value : values()) { |
| | | if (StringUtils.contains(str, value.getUserType())) { |
| | | return value; |
| | | } |
| | | } |
| | | throw new RuntimeException("'UserType' not found By " + str); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æ¼ç¤ºæ¨¡å¼å¼å¸¸ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class DemoModeException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public DemoModeException() { |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * å
¨å±å¼å¸¸ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class GlobalException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * é误æç¤º |
| | | */ |
| | | private String message; |
| | | |
| | | /** |
| | | * é误æç»ï¼å
é¨è°è¯é误 |
| | | */ |
| | | private String detailMessage; |
| | | |
| | | /** |
| | | * 空æé æ¹æ³ï¼é¿å
ååºååé®é¢ |
| | | */ |
| | | public GlobalException() { |
| | | } |
| | | |
| | | public GlobalException(String message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | public String getDetailMessage() { |
| | | return detailMessage; |
| | | } |
| | | |
| | | public GlobalException setDetailMessage(String detailMessage) { |
| | | this.detailMessage = detailMessage; |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public GlobalException setMessage(String message) { |
| | | this.message = message; |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * ä¸å¡å¼å¸¸ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public final class ServiceException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * é误ç |
| | | */ |
| | | private Integer code; |
| | | |
| | | /** |
| | | * é误æç¤º |
| | | */ |
| | | private String message; |
| | | |
| | | /** |
| | | * é误æç»ï¼å
é¨è°è¯é误 |
| | | */ |
| | | private String detailMessage; |
| | | |
| | | /** |
| | | * 空æé æ¹æ³ï¼é¿å
ååºååé®é¢ |
| | | */ |
| | | public ServiceException() { |
| | | } |
| | | |
| | | public ServiceException(String message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | public ServiceException(String message, Integer code) { |
| | | this.message = message; |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getDetailMessage() { |
| | | return detailMessage; |
| | | } |
| | | |
| | | @Override |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public Integer getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public ServiceException setMessage(String message) { |
| | | this.message = message; |
| | | return this; |
| | | } |
| | | |
| | | public ServiceException setDetailMessage(String detailMessage) { |
| | | this.detailMessage = detailMessage; |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * å·¥å
·ç±»å¼å¸¸ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UtilException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 8247610319171014183L; |
| | | |
| | | public UtilException(Throwable e) { |
| | | super(e.getMessage(), e); |
| | | } |
| | | |
| | | public UtilException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public UtilException(String message, Throwable throwable) { |
| | | super(message, throwable); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.base; |
| | | |
| | | import com.ruoyi.common.core.utils.MessageUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * åºç¡å¼å¸¸ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @NoArgsConstructor |
| | | public class BaseException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æå±æ¨¡å |
| | | */ |
| | | private String module; |
| | | |
| | | /** |
| | | * é误ç |
| | | */ |
| | | private String code; |
| | | |
| | | /** |
| | | * é误ç 对åºçåæ° |
| | | */ |
| | | private Object[] args; |
| | | |
| | | /** |
| | | * éè¯¯æ¶æ¯ |
| | | */ |
| | | private String defaultMessage; |
| | | |
| | | public BaseException(String module, String code, Object[] args, String defaultMessage) { |
| | | this.module = module; |
| | | this.code = code; |
| | | this.args = args; |
| | | this.defaultMessage = defaultMessage; |
| | | } |
| | | |
| | | public BaseException(String module, String code, Object[] args) { |
| | | this(module, code, args, null); |
| | | } |
| | | |
| | | public BaseException(String module, String defaultMessage) { |
| | | this(module, null, null, defaultMessage); |
| | | } |
| | | |
| | | public BaseException(String code, Object[] args) { |
| | | this(null, code, args, null); |
| | | } |
| | | |
| | | public BaseException(String defaultMessage) { |
| | | this(null, null, null, defaultMessage); |
| | | } |
| | | |
| | | @Override |
| | | public String getMessage() { |
| | | String message = null; |
| | | if (!StringUtils.isEmpty(code)) { |
| | | message = MessageUtils.message(code, args); |
| | | } |
| | | if (message == null) { |
| | | message = defaultMessage; |
| | | } |
| | | return message; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.file; |
| | | |
| | | import com.ruoyi.common.core.exception.base.BaseException; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æä»¶ä¿¡æ¯å¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class FileException extends BaseException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public FileException(String code, Object[] args) { |
| | | super("file", code, args, null); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.file; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æä»¶åç§°è¶
é¿éå¶å¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class FileNameLengthLimitExceededException extends FileException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public FileNameLengthLimitExceededException(int defaultFileNameLength) { |
| | | super("upload.filename.exceed.length", new Object[]{defaultFileNameLength}); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.file; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æä»¶å大å°éå¶å¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class FileSizeLimitExceededException extends FileException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public FileSizeLimitExceededException(long defaultMaxSize) { |
| | | super("upload.exceed.maxSize", new Object[]{defaultMaxSize}); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.user; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * éªè¯ç é误å¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class CaptchaException extends UserException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public CaptchaException() { |
| | | super("user.jcaptcha.error"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.user; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * éªè¯ç 失æå¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class CaptchaExpireException extends UserException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public CaptchaExpireException() { |
| | | super("user.jcaptcha.expire"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.user; |
| | | |
| | | import com.ruoyi.common.core.exception.base.BaseException; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * ç¨æ·ä¿¡æ¯å¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UserException extends BaseException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public UserException(String code, Object... args) { |
| | | super("user", code, args, null); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.user; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * ç¨æ·å¯ç 䏿£ç¡®æä¸ç¬¦åè§èå¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UserPasswordNotMatchException extends UserException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public UserPasswordNotMatchException() { |
| | | super("user.password.not.match"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.exception.user; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * ç¨æ·é误æå¤§æ¬¡æ°å¼å¸¸ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UserPasswordRetryLimitExceedException extends UserException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) { |
| | | super("user.password.retry.limit.exceed", retryLimitCount, lockTime); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.jackson; |
| | | |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.SerializerProvider; |
| | | import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; |
| | | import com.fasterxml.jackson.databind.ser.std.NumberSerializer; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * è¶
åº JS æå¤§æå°å¼ å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @JacksonStdImpl |
| | | public class BigNumberSerializer extends NumberSerializer { |
| | | |
| | | /** |
| | | * æ ¹æ® JS Number.MAX_SAFE_INTEGER ä¸ Number.MIN_SAFE_INTEGER 徿¥ |
| | | */ |
| | | private static final long MAX_SAFE_INTEGER = 9007199254740991L; |
| | | private static final long MIN_SAFE_INTEGER = -9007199254740991L; |
| | | |
| | | /** |
| | | * æä¾å®ä¾ |
| | | */ |
| | | public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class); |
| | | |
| | | public BigNumberSerializer(Class<? extends Number> rawType) { |
| | | super(rawType); |
| | | } |
| | | |
| | | @Override |
| | | public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException { |
| | | // è¶
åºèå´ åºååä½å符串 |
| | | if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) { |
| | | super.serialize(value, gen, provider); |
| | | } else { |
| | | gen.writeString(value.toString()); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.jackson; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.BeanProperty; |
| | | import com.fasterxml.jackson.databind.JsonMappingException; |
| | | import com.fasterxml.jackson.databind.JsonSerializer; |
| | | import com.fasterxml.jackson.databind.SerializerProvider; |
| | | import com.fasterxml.jackson.databind.ser.ContextualSerializer; |
| | | import com.ruoyi.common.core.annotation.Sensitive; |
| | | import com.ruoyi.common.core.enums.SensitiveStrategy; |
| | | import com.ruoyi.common.core.service.SensitiveService; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.BeansException; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æ°æ®è±æjsonåºååå·¥å
· |
| | | * |
| | | * @author Yjoioooo |
| | | */ |
| | | @Slf4j |
| | | public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { |
| | | |
| | | private SensitiveStrategy strategy; |
| | | |
| | | @Override |
| | | public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { |
| | | try { |
| | | SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class); |
| | | if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive()) { |
| | | gen.writeString(strategy.desensitizer().apply(value)); |
| | | } else { |
| | | gen.writeString(value); |
| | | } |
| | | } catch (BeansException e) { |
| | | log.error("è±æå®ç°ä¸åå¨, éç¨é»è®¤å¤ç => {}", e.getMessage()); |
| | | gen.writeString(value); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { |
| | | Sensitive annotation = property.getAnnotation(Sensitive.class); |
| | | if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) { |
| | | this.strategy = annotation.strategy(); |
| | | return this; |
| | | } |
| | | return prov.findValueSerializer(property.getType(), property); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.manager; |
| | | |
| | | import com.ruoyi.common.core.utils.Threads; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import jakarta.annotation.PreDestroy; |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | |
| | | /** |
| | | * ç¡®ä¿åºç¨éåºæ¶è½å
³éåå°çº¿ç¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class ShutdownManager { |
| | | |
| | | @Autowired |
| | | @Qualifier("scheduledExecutorService") |
| | | private ScheduledExecutorService scheduledExecutorService; |
| | | |
| | | @PreDestroy |
| | | public void destroy() { |
| | | shutdownAsyncManager(); |
| | | } |
| | | |
| | | /** |
| | | * 忢弿¥æ§è¡ä»»å¡ |
| | | */ |
| | | private void shutdownAsyncManager() { |
| | | try { |
| | | log.info("====å
³éåå°ä»»å¡ä»»å¡çº¿ç¨æ± ===="); |
| | | Threads.shutdownAndAwaitTermination(scheduledExecutorService); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.SimpleCache; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.cglib.beans.BeanCopier; |
| | | import org.springframework.cglib.beans.BeanMap; |
| | | import org.springframework.cglib.core.Converter; |
| | | |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * beanæ·±æ·è´å·¥å
·(åºäº cglib æ§è½ä¼å¼) |
| | | * <p> |
| | | * éç¹ cglib 䏿¯æ æ·è´å°é¾å¼å¯¹è±¡ |
| | | * ä¾å¦: æºå¯¹è±¡ æ·è´å° ç®æ (é¾å¼å¯¹è±¡) |
| | | * 请åºå好`æµ
æ·è´`å`æ·±æ·è´`ååä½¿ç¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class BeanCopyUtils { |
| | | |
| | | /** |
| | | * å对象åºäºclasså建æ·è´ |
| | | * |
| | | * @param source æ°æ®æ¥æºå®ä½ |
| | | * @param desc æè¿°å¯¹è±¡ 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V copy(T source, Class<V> desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(desc)) { |
| | | return null; |
| | | } |
| | | final V target = ReflectUtil.newInstanceIfPossible(desc); |
| | | return copy(source, target); |
| | | } |
| | | |
| | | /** |
| | | * å对象åºäºå¯¹è±¡å建æ·è´ |
| | | * |
| | | * @param source æ°æ®æ¥æºå®ä½ |
| | | * @param desc 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V copy(T source, V desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(desc)) { |
| | | return null; |
| | | } |
| | | BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(source.getClass(), desc.getClass(), null); |
| | | beanCopier.copy(source, desc, null); |
| | | return desc; |
| | | } |
| | | |
| | | /** |
| | | * å表对象åºäºclasså建æ·è´ |
| | | * |
| | | * @param sourceList æ°æ®æ¥æºå®ä½å表 |
| | | * @param desc æè¿°å¯¹è±¡ 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> List<V> copyList(List<T> sourceList, Class<V> desc) { |
| | | if (ObjectUtil.isNull(sourceList)) { |
| | | return null; |
| | | } |
| | | if (CollUtil.isEmpty(sourceList)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return StreamUtils.toList(sourceList, source -> { |
| | | V target = ReflectUtil.newInstanceIfPossible(desc); |
| | | copy(source, target); |
| | | return target; |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * beanæ·è´å°map |
| | | * |
| | | * @param bean æ°æ®æ¥æºå®ä½ |
| | | * @return map对象 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> Map<String, Object> copyToMap(T bean) { |
| | | if (ObjectUtil.isNull(bean)) { |
| | | return null; |
| | | } |
| | | return BeanMap.create(bean); |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°bean |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param beanClass beanç±» |
| | | * @return bean对象 |
| | | */ |
| | | public static <T> T mapToBean(Map<String, Object> map, Class<T> beanClass) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(beanClass)) { |
| | | return null; |
| | | } |
| | | T bean = ReflectUtil.newInstanceIfPossible(beanClass); |
| | | return mapToBean(map, bean); |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°bean |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param bean bean对象 |
| | | * @return bean对象 |
| | | */ |
| | | public static <T> T mapToBean(Map<String, Object> map, T bean) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(bean)) { |
| | | return null; |
| | | } |
| | | BeanMap.create(bean).putAll(map); |
| | | return bean; |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°map |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param clazz è¿åç对象类å |
| | | * @return map对象 |
| | | */ |
| | | public static <T, V> Map<String, V> mapToMap(Map<String, T> map, Class<V> clazz) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(clazz)) { |
| | | return null; |
| | | } |
| | | Map<String, V> copyMap = new LinkedHashMap<>(map.size()); |
| | | map.forEach((k, v) -> copyMap.put(k, copy(v, clazz))); |
| | | return copyMap; |
| | | } |
| | | |
| | | /** |
| | | * BeanCopier屿§ç¼å<br> |
| | | * ç¼åç¨äºé²æ¢å¤æ¬¡åå°é æçæ§è½é®é¢ |
| | | * |
| | | * @author Looly |
| | | * @since 5.4.1 |
| | | */ |
| | | public enum BeanCopierCache { |
| | | /** |
| | | * BeanCopier屿§ç¼ååä¾ |
| | | */ |
| | | INSTANCE; |
| | | |
| | | private final SimpleCache<String, BeanCopier> cache = new SimpleCache<>(); |
| | | |
| | | /** |
| | | * è·å¾ç±»ä¸è½¬æ¢å¨çæçkeyå¨{@link BeanCopier}çMapä¸å¯¹åºçå
ç´ |
| | | * |
| | | * @param srcClass æºBeançç±» |
| | | * @param targetClass ç®æ Beançç±» |
| | | * @param converter 转æ¢å¨ |
| | | * @return Mapä¸å¯¹åºçBeanCopier |
| | | */ |
| | | public BeanCopier get(Class<?> srcClass, Class<?> targetClass, Converter converter) { |
| | | final String key = genKey(srcClass, targetClass, converter); |
| | | return cache.get(key, () -> BeanCopier.create(srcClass, targetClass, converter != null)); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç±»ä¸è½¬æ¢å¨çæçkey |
| | | * |
| | | * @param srcClass æºBeançç±» |
| | | * @param targetClass ç®æ Beançç±» |
| | | * @param converter 转æ¢å¨ |
| | | * @return 屿§ååMapæ å°çkey |
| | | */ |
| | | private String genKey(Class<?> srcClass, Class<?> targetClass, Converter converter) { |
| | | final StringBuilder key = StrUtil.builder() |
| | | .append(srcClass.getName()).append('#').append(targetClass.getName()); |
| | | if (null != converter) { |
| | | key.append('#').append(converter.getClass().getName()); |
| | | } |
| | | return key.toString(); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.apache.commons.lang3.time.DateFormatUtils; |
| | | |
| | | import java.lang.management.ManagementFactory; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.ZoneId; |
| | | import java.time.ZonedDateTime; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æ¶é´å·¥å
·ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class DateUtils extends org.apache.commons.lang3.time.DateUtils { |
| | | |
| | | public static final String YYYY = "yyyy"; |
| | | |
| | | public static final String YYYY_MM = "yyyy-MM"; |
| | | |
| | | public static final String YYYY_MM_DD = "yyyy-MM-dd"; |
| | | |
| | | public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; |
| | | |
| | | public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; |
| | | |
| | | private static final String[] PARSE_PATTERNS = { |
| | | "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", |
| | | "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", |
| | | "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; |
| | | |
| | | /** |
| | | * è·åå½åDate忥æ |
| | | * |
| | | * @return Date() å½åæ¥æ |
| | | */ |
| | | public static Date getNowDate() { |
| | | return new Date(); |
| | | } |
| | | |
| | | /** |
| | | * è·åå½åæ¥æ, é»è®¤æ ¼å¼ä¸ºyyyy-MM-dd |
| | | * |
| | | * @return String |
| | | */ |
| | | public static String getDate() { |
| | | return dateTimeNow(YYYY_MM_DD); |
| | | } |
| | | |
| | | public static String getTime() { |
| | | return dateTimeNow(YYYY_MM_DD_HH_MM_SS); |
| | | } |
| | | |
| | | public static String dateTimeNow() { |
| | | return dateTimeNow(YYYYMMDDHHMMSS); |
| | | } |
| | | |
| | | public static String dateTimeNow(final String format) { |
| | | return parseDateToStr(format, new Date()); |
| | | } |
| | | |
| | | public static String dateTime(final Date date) { |
| | | return parseDateToStr(YYYY_MM_DD, date); |
| | | } |
| | | |
| | | public static String parseDateToStr(final String format, final Date date) { |
| | | return new SimpleDateFormat(format).format(date); |
| | | } |
| | | |
| | | public static Date dateTime(final String format, final String ts) { |
| | | try { |
| | | return new SimpleDateFormat(format).parse(ts); |
| | | } catch (ParseException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¥æè·¯å¾ å³å¹´/æ/æ¥ å¦2018/08/08 |
| | | */ |
| | | public static String datePath() { |
| | | Date now = new Date(); |
| | | return DateFormatUtils.format(now, "yyyy/MM/dd"); |
| | | } |
| | | |
| | | /** |
| | | * æ¥æè·¯å¾ å³å¹´/æ/æ¥ å¦20180808 |
| | | */ |
| | | public static String dateTime() { |
| | | Date now = new Date(); |
| | | return DateFormatUtils.format(now, "yyyyMMdd"); |
| | | } |
| | | |
| | | /** |
| | | * æ¥æåå符串转åä¸ºæ¥æ æ ¼å¼ |
| | | */ |
| | | public static Date parseDate(Object str) { |
| | | if (str == null) { |
| | | return null; |
| | | } |
| | | try { |
| | | return parseDate(str.toString(), PARSE_PATTERNS); |
| | | } catch (ParseException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åæå¡å¨å¯å¨æ¶é´ |
| | | */ |
| | | public static Date getServerStartDate() { |
| | | long time = ManagementFactory.getRuntimeMXBean().getStartTime(); |
| | | return new Date(time); |
| | | } |
| | | |
| | | /** |
| | | * 计ç®ç¸å·®å¤©æ° |
| | | */ |
| | | public static int differentDaysByMillisecond(Date date1, Date date2) { |
| | | return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); |
| | | } |
| | | |
| | | /** |
| | | * 计ç®ä¸¤ä¸ªæ¶é´å·® |
| | | */ |
| | | public static String getDatePoor(Date endDate, Date nowDate) { |
| | | long nd = 1000 * 24 * 60 * 60; |
| | | long nh = 1000 * 60 * 60; |
| | | long nm = 1000 * 60; |
| | | // long ns = 1000; |
| | | // è·å¾ä¸¤ä¸ªæ¶é´çæ¯«ç§æ¶é´å·®å¼ |
| | | long diff = endDate.getTime() - nowDate.getTime(); |
| | | // 计ç®å·®å¤å°å¤© |
| | | long day = diff / nd; |
| | | // 计ç®å·®å¤å°å°æ¶ |
| | | long hour = diff % nd / nh; |
| | | // 计ç®å·®å¤å°åé |
| | | long min = diff % nd % nh / nm; |
| | | // 计ç®å·®å¤å°ç§//è¾åºç»æ |
| | | // long sec = diff % nd % nh % nm / ns; |
| | | return day + "天" + hour + "å°æ¶" + min + "åé"; |
| | | } |
| | | |
| | | /** |
| | | * å¢å LocalDateTime ==> Date |
| | | */ |
| | | public static Date toDate(LocalDateTime temporalAccessor) { |
| | | ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); |
| | | return Date.from(zdt.toInstant()); |
| | | } |
| | | |
| | | /** |
| | | * å¢å LocalDate ==> Date |
| | | */ |
| | | public static Date toDate(LocalDate temporalAccessor) { |
| | | LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); |
| | | ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); |
| | | return Date.from(zdt.toInstant()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.exc.MismatchedInputException; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * JSON å·¥å
·ç±» |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class JsonUtils { |
| | | |
| | | private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class); |
| | | |
| | | public static ObjectMapper getObjectMapper() { |
| | | return OBJECT_MAPPER; |
| | | } |
| | | |
| | | public static String toJsonString(Object object) { |
| | | if (ObjectUtil.isNull(object)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.writeValueAsString(object); |
| | | } catch (JsonProcessingException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> T parseObject(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, clazz); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> T parseObject(byte[] bytes, Class<T> clazz) { |
| | | if (ArrayUtil.isEmpty(bytes)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(bytes, clazz); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> T parseObject(String text, TypeReference<T> typeReference) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, typeReference); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static Dict parseMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class)); |
| | | } catch (MismatchedInputException e) { |
| | | // ç±»åä¸å¹é
说æä¸æ¯json |
| | | return null; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static List<Dict> parseArrayMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class)); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> List<T> parseArray(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz)); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.context.MessageSource; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | | |
| | | /** |
| | | * è·åi18nèµæºæä»¶ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class MessageUtils { |
| | | |
| | | private static final MessageSource MESSAGE_SOURCE = SpringUtils.getBean(MessageSource.class); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¶æ¯é®ååæ° è·åæ¶æ¯ å§æç»spring messageSource |
| | | * |
| | | * @param code æ¶æ¯é® |
| | | * @param args åæ° |
| | | * @return è·åå½é
åç¿»è¯å¼ |
| | | */ |
| | | public static String message(String code, Object... args) { |
| | | return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.extra.servlet.JakartaServletUtil; |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import jakarta.servlet.ServletRequest; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.servlet.http.HttpSession; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.context.request.RequestAttributes; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URLDecoder; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 客æ·ç«¯å·¥å
·ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class ServletUtils extends JakartaServletUtil { |
| | | |
| | | /** |
| | | * è·åStringåæ° |
| | | */ |
| | | public static String getParameter(String name) { |
| | | return getRequest().getParameter(name); |
| | | } |
| | | |
| | | /** |
| | | * è·åStringåæ° |
| | | */ |
| | | public static String getParameter(String name, String defaultValue) { |
| | | return Convert.toStr(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * è·åIntegeråæ° |
| | | */ |
| | | public static Integer getParameterToInt(String name) { |
| | | return Convert.toInt(getRequest().getParameter(name)); |
| | | } |
| | | |
| | | /** |
| | | * è·åIntegeråæ° |
| | | */ |
| | | public static Integer getParameterToInt(String name, Integer defaultValue) { |
| | | return Convert.toInt(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * è·åBooleanåæ° |
| | | */ |
| | | public static Boolean getParameterToBool(String name) { |
| | | return Convert.toBool(getRequest().getParameter(name)); |
| | | } |
| | | |
| | | /** |
| | | * è·åBooleanåæ° |
| | | */ |
| | | public static Boolean getParameterToBool(String name, Boolean defaultValue) { |
| | | return Convert.toBool(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ææè¯·æ±åæ° |
| | | * |
| | | * @param request 请æ±å¯¹è±¡{@link ServletRequest} |
| | | * @return Map |
| | | */ |
| | | public static Map<String, String[]> getParams(ServletRequest request) { |
| | | final Map<String, String[]> map = request.getParameterMap(); |
| | | return Collections.unmodifiableMap(map); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ææè¯·æ±åæ° |
| | | * |
| | | * @param request 请æ±å¯¹è±¡{@link ServletRequest} |
| | | * @return Map |
| | | */ |
| | | public static Map<String, String> getParamMap(ServletRequest request) { |
| | | Map<String, String> params = new HashMap<>(); |
| | | for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) { |
| | | params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); |
| | | } |
| | | return params; |
| | | } |
| | | |
| | | /** |
| | | * è·årequest |
| | | */ |
| | | public static HttpServletRequest getRequest() { |
| | | return getRequestAttributes().getRequest(); |
| | | } |
| | | |
| | | /** |
| | | * è·åresponse |
| | | */ |
| | | public static HttpServletResponse getResponse() { |
| | | return getRequestAttributes().getResponse(); |
| | | } |
| | | |
| | | /** |
| | | * è·åsession |
| | | */ |
| | | public static HttpSession getSession() { |
| | | return getRequest().getSession(); |
| | | } |
| | | |
| | | public static ServletRequestAttributes getRequestAttributes() { |
| | | RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); |
| | | return (ServletRequestAttributes) attributes; |
| | | } |
| | | |
| | | /** |
| | | * å°å符串渲æå°å®¢æ·ç«¯ |
| | | * |
| | | * @param response 渲æå¯¹è±¡ |
| | | * @param string å¾
渲æçå符串 |
| | | */ |
| | | public static void renderString(HttpServletResponse response, String string) { |
| | | try { |
| | | response.setStatus(HttpStatus.HTTP_OK); |
| | | response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
| | | response.setCharacterEncoding(StandardCharsets.UTF_8.toString()); |
| | | response.getWriter().print(string); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦æ¯Ajax弿¥è¯·æ± |
| | | * |
| | | * @param request |
| | | */ |
| | | public static boolean isAjaxRequest(HttpServletRequest request) { |
| | | |
| | | String accept = request.getHeader("accept"); |
| | | if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) { |
| | | return true; |
| | | } |
| | | |
| | | String xRequestedWith = request.getHeader("X-Requested-With"); |
| | | if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) { |
| | | return true; |
| | | } |
| | | |
| | | String uri = request.getRequestURI(); |
| | | if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) { |
| | | return true; |
| | | } |
| | | |
| | | String ajax = request.getParameter("__ajax"); |
| | | return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml"); |
| | | } |
| | | |
| | | public static String getClientIP() { |
| | | return getClientIP(getRequest()); |
| | | } |
| | | |
| | | /** |
| | | * å
容ç¼ç |
| | | * |
| | | * @param str å
容 |
| | | * @return ç¼ç åçå
容 |
| | | */ |
| | | public static String urlEncode(String str) { |
| | | try { |
| | | return URLEncoder.encode(str, Constants.UTF8); |
| | | } catch (UnsupportedEncodingException e) { |
| | | return StringUtils.EMPTY; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å
容解ç |
| | | * |
| | | * @param str å
容 |
| | | * @return è§£ç åçå
容 |
| | | */ |
| | | public static String urlDecode(String str) { |
| | | try { |
| | | return URLDecoder.decode(str, Constants.UTF8); |
| | | } catch (UnsupportedEncodingException e) { |
| | | return StringUtils.EMPTY; |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.extra.spring.SpringUtil; |
| | | import org.springframework.aop.framework.AopContext; |
| | | import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * springå·¥å
·ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Component |
| | | public final class SpringUtils extends SpringUtil { |
| | | |
| | | /** |
| | | * 妿BeanFactoryå
å«ä¸ä¸ªä¸æç»åç§°å¹é
çbeanå®ä¹ï¼åè¿åtrue |
| | | * |
| | | * @param name |
| | | * @return boolean |
| | | */ |
| | | public static boolean containsBean(String name) { |
| | | return getBeanFactory().containsBean(name); |
| | | } |
| | | |
| | | /** |
| | | * 夿以ç»å®ååæ³¨åçbeanå®ä¹æ¯ä¸ä¸ªsingletonè¿æ¯ä¸ä¸ªprototypeã |
| | | * 妿ä¸ç»å®ååç¸åºçbeanå®ä¹æ²¡æè¢«æ¾å°ï¼å°ä¼æåºä¸ä¸ªå¼å¸¸ï¼NoSuchBeanDefinitionExceptionï¼ |
| | | * |
| | | * @param name |
| | | * @return boolean |
| | | */ |
| | | public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().isSingleton(name); |
| | | } |
| | | |
| | | /** |
| | | * @param name |
| | | * @return Class 注å对象çç±»å |
| | | */ |
| | | public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().getType(name); |
| | | } |
| | | |
| | | /** |
| | | * 妿ç»å®çbeanååå¨beanå®ä¹ä¸æå«åï¼åè¿åè¿äºå«å |
| | | * |
| | | * @param name |
| | | */ |
| | | public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().getAliases(name); |
| | | } |
| | | |
| | | /** |
| | | * è·åaop代ç对象 |
| | | * |
| | | * @param invoker |
| | | * @return |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> T getAopProxy(T invoker) { |
| | | return (T) AopContext.currentProxy(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * è·åspringä¸ä¸æ |
| | | */ |
| | | public static ApplicationContext context() { |
| | | return getApplicationContext(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.*; |
| | | import java.util.function.BiFunction; |
| | | import java.util.function.Function; |
| | | import java.util.function.Predicate; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * stream æµå·¥å
·ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class StreamUtils { |
| | | |
| | | /** |
| | | * å°collectionè¿æ»¤ |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function è¿æ»¤æ¹æ³ |
| | | * @return è¿æ»¤åçlist |
| | | */ |
| | | public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return collection.stream().filter(function).collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæ¼æ¥ |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function æ¼æ¥æ¹æ³ |
| | | * @return æ¼æ¥åçlist |
| | | */ |
| | | public static <E> String join(Collection<E> collection, Function<E, String> function) { |
| | | return join(collection, function, ","); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæ¼æ¥ |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function æ¼æ¥æ¹æ³ |
| | | * @param delimiter æ¼æ¥ç¬¦ |
| | | * @return æ¼æ¥åçlist |
| | | */ |
| | | public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return StringUtils.EMPTY; |
| | | } |
| | | return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter)); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæåº |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param comparing æåºæ¹æ³ |
| | | * @return æåºåçlist |
| | | */ |
| | | public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return collection.stream().sorted(comparing).collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å°collection转å为类åä¸åçmap<br> |
| | | * <B>{@code Collection<V> ----> Map<K,V>}</B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param key Vç±»å转å为Kç±»åçlambdaæ¹æ³ |
| | | * @param <V> collectionä¸çæ³å |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @return 转ååçmap |
| | | */ |
| | | public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l)); |
| | | } |
| | | |
| | | /** |
| | | * å°Collection转å为map(valueç±»åä¸collectionçæ³åä¸å)<br> |
| | | * <B>{@code Collection<E> -----> Map<K,V> }</B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param key Eç±»å转å为Kç±»åçlambdaæ¹æ³ |
| | | * @param value Eç±»å转å为Vç±»åçlambdaæ¹æ³ |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @param <V> mapä¸çvalueç±»å |
| | | * @return 转ååçmap |
| | | */ |
| | | public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l)); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæç
§è§å(æ¯å¦æç¸åçç级id)åç±»æmap<br> |
| | | * <B>{@code Collection<E> -------> Map<K,List<E>> } </B> |
| | | * |
| | | * @param collection éè¦åç±»çéå |
| | | * @param key åç±»çè§å |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @return åç±»åçmap |
| | | */ |
| | | public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList())); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæç
§ä¸¤ä¸ªè§å(æ¯å¦æç¸åç年级id,ç级id)åç±»æåå±map<br> |
| | | * <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B> |
| | | * |
| | | * @param collection éè¦åç±»çéå |
| | | * @param key1 第ä¸ä¸ªåç±»çè§å |
| | | * @param key2 第äºä¸ªåç±»çè§å |
| | | * @param <E> éåå
ç´ ç±»å |
| | | * @param <K> 第ä¸ä¸ªmapä¸çkeyç±»å |
| | | * @param <U> 第äºä¸ªmapä¸çkeyç±»å |
| | | * @return åç±»åçmap |
| | | */ |
| | | public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList()))); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæç
§ä¸¤ä¸ªè§å(æ¯å¦æç¸åç年级id,ç级id)åç±»æåå±map<br> |
| | | * <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B> |
| | | * |
| | | * @param collection éè¦åç±»çéå |
| | | * @param key1 第ä¸ä¸ªåç±»çè§å |
| | | * @param key2 第äºä¸ªåç±»çè§å |
| | | * @param <T> 第ä¸ä¸ªmapä¸çkeyç±»å |
| | | * @param <U> 第äºä¸ªmapä¸çkeyç±»å |
| | | * @param <E> collectionä¸çæ³å |
| | | * @return åç±»åçmap |
| | | */ |
| | | public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) { |
| | | if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l))); |
| | | } |
| | | |
| | | /** |
| | | * å°collection转å为Listéåï¼ä½æ¯ä¸¤è
çæ³åä¸å<br> |
| | | * <B>{@code Collection<E> ------> List<T> } </B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function collectionä¸çæ³å转å为listæ³åçlambdaè¡¨è¾¾å¼ |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <T> Listä¸çæ³å |
| | | * @return 转ååçlist |
| | | */ |
| | | public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .map(function) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å°collection转å为Setéåï¼ä½æ¯ä¸¤è
çæ³åä¸å<br> |
| | | * <B>{@code Collection<E> ------> Set<T> } </B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function collectionä¸çæ³å转å为setæ³åçlambdaè¡¨è¾¾å¼ |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <T> Setä¸çæ³å |
| | | * @return 转ååçSet |
| | | */ |
| | | public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) { |
| | | if (CollUtil.isEmpty(collection) || function == null) { |
| | | return CollUtil.newHashSet(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .map(function) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * å并两个ç¸åkeyç±»åçmap |
| | | * |
| | | * @param map1 第ä¸ä¸ªéè¦åå¹¶ç map |
| | | * @param map2 第äºä¸ªéè¦åå¹¶ç map |
| | | * @param merge åå¹¶çlambdaï¼å°key value1 value2åå¹¶ææç»çç±»å,注ævalueå¯è½ä¸ºç©ºçæ
åµ |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @param <X> 第ä¸ä¸ª mapçvalueç±»å |
| | | * @param <Y> 第äºä¸ª mapçvalueç±»å |
| | | * @param <V> æç»mapçvalueç±»å |
| | | * @return åå¹¶åçmap |
| | | */ |
| | | public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) { |
| | | if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) { |
| | | return MapUtil.newHashMap(); |
| | | } else if (MapUtil.isEmpty(map1)) { |
| | | map1 = MapUtil.newHashMap(); |
| | | } else if (MapUtil.isEmpty(map2)) { |
| | | map2 = MapUtil.newHashMap(); |
| | | } |
| | | Set<K> key = new HashSet<>(); |
| | | key.addAll(map1.keySet()); |
| | | key.addAll(map2.keySet()); |
| | | Map<K, V> map = new HashMap<>(); |
| | | for (K t : key) { |
| | | X x = map1.get(t); |
| | | Y y = map2.get(t); |
| | | V z = merge.apply(x, y); |
| | | if (z != null) { |
| | | map.put(t, z); |
| | | } |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.Validator; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.util.AntPathMatcher; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * å符串工å
·ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class StringUtils extends org.apache.commons.lang3.StringUtils { |
| | | |
| | | /** |
| | | * è·ååæ°ä¸ä¸ºç©ºå¼ |
| | | * |
| | | * @param str defaultValue è¦å¤æçvalue |
| | | * @return value è¿åå¼ |
| | | */ |
| | | public static String blankToDefault(String str, String defaultValue) { |
| | | return StrUtil.blankToDefault(str, defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * * 夿ä¸ä¸ªå符串æ¯å¦ä¸ºç©ºä¸² |
| | | * |
| | | * @param str String |
| | | * @return trueï¼ä¸ºç©º falseï¼é空 |
| | | */ |
| | | public static boolean isEmpty(String str) { |
| | | return StrUtil.isEmpty(str); |
| | | } |
| | | |
| | | /** |
| | | * * 夿ä¸ä¸ªå符串æ¯å¦ä¸ºé空串 |
| | | * |
| | | * @param str String |
| | | * @return trueï¼é空串 falseï¼ç©ºä¸² |
| | | */ |
| | | public static boolean isNotEmpty(String str) { |
| | | return !isEmpty(str); |
| | | } |
| | | |
| | | /** |
| | | * å»ç©ºæ ¼ |
| | | */ |
| | | public static String trim(String str) { |
| | | return StrUtil.trim(str); |
| | | } |
| | | |
| | | /** |
| | | * æªåå符串 |
| | | * |
| | | * @param str å符串 |
| | | * @param start å¼å§ |
| | | * @return ç»æ |
| | | */ |
| | | public static String substring(final String str, int start) { |
| | | return substring(str, start, str.length()); |
| | | } |
| | | |
| | | /** |
| | | * æªåå符串 |
| | | * |
| | | * @param str å符串 |
| | | * @param start å¼å§ |
| | | * @param end ç»æ |
| | | * @return ç»æ |
| | | */ |
| | | public static String substring(final String str, int start, int end) { |
| | | return StrUtil.sub(str, start, end); |
| | | } |
| | | |
| | | /** |
| | | * æ ¼å¼åææ¬, {} 表示å ä½ç¬¦<br> |
| | | * æ¤æ¹æ³åªæ¯ç®åå°å ä½ç¬¦ {} æç
§é¡ºåºæ¿æ¢ä¸ºåæ°<br> |
| | | * 妿æ³è¾åº {} ä½¿ç¨ \\è½¬ä¹ { å³å¯ï¼å¦ææ³è¾åº {} ä¹åç \ 使ç¨å转ä¹ç¬¦ \\\\ å³å¯<br> |
| | | * ä¾ï¼<br> |
| | | * é常使ç¨ï¼format("this is {} for {}", "a", "b") -> this is a for b<br> |
| | | * 转ä¹{}ï¼ format("this is \\{} for {}", "a", "b") -> this is {} for a<br> |
| | | * 转ä¹\ï¼ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> |
| | | * |
| | | * @param template ææ¬æ¨¡æ¿ï¼è¢«æ¿æ¢çé¨åç¨ {} 表示 |
| | | * @param params åæ°å¼ |
| | | * @return æ ¼å¼ååçææ¬ |
| | | */ |
| | | public static String format(String template, Object... params) { |
| | | return StrUtil.format(template, params); |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºhttp(s)://å¼å¤´ |
| | | * |
| | | * @param link 龿¥ |
| | | * @return ç»æ |
| | | */ |
| | | public static boolean ishttp(String link) { |
| | | return Validator.isUrl(link); |
| | | } |
| | | |
| | | /** |
| | | * å符串转set |
| | | * |
| | | * @param str å符串 |
| | | * @param sep åé符 |
| | | * @return setéå |
| | | */ |
| | | public static Set<String> str2Set(String str, String sep) { |
| | | return new HashSet<>(str2List(str, sep, true, false)); |
| | | } |
| | | |
| | | /** |
| | | * å符串转list |
| | | * |
| | | * @param str å符串 |
| | | * @param sep åé符 |
| | | * @param filterBlank è¿æ»¤çº¯ç©ºç½ |
| | | * @param trim 廿é¦å°¾ç©ºç½ |
| | | * @return listéå |
| | | */ |
| | | public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) { |
| | | List<String> list = new ArrayList<>(); |
| | | if (isEmpty(str)) { |
| | | return list; |
| | | } |
| | | |
| | | // è¿æ»¤ç©ºç½å符串 |
| | | if (filterBlank && isBlank(str)) { |
| | | return list; |
| | | } |
| | | String[] split = str.split(sep); |
| | | for (String string : split) { |
| | | if (filterBlank && isBlank(string)) { |
| | | continue; |
| | | } |
| | | if (trim) { |
| | | string = trim(string); |
| | | } |
| | | list.add(string); |
| | | } |
| | | |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * æ¥æ¾æå®å符串æ¯å¦å
嫿å®å符串å表ä¸çä»»æä¸ä¸ªåç¬¦ä¸²åæ¶ä¸²å¿½ç¥å¤§å°å |
| | | * |
| | | * @param cs æå®å符串 |
| | | * @param searchCharSequences éè¦æ£æ¥çå符串æ°ç» |
| | | * @return æ¯å¦å
å«ä»»æä¸ä¸ªå符串 |
| | | */ |
| | | public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) { |
| | | return StrUtil.containsAnyIgnoreCase(cs, searchCharSequences); |
| | | } |
| | | |
| | | /** |
| | | * 驼峰转ä¸å线å½å |
| | | */ |
| | | public static String toUnderScoreCase(String str) { |
| | | return StrUtil.toUnderlineCase(str); |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦å
å«å符串 |
| | | * |
| | | * @param str éªè¯å符串 |
| | | * @param strs åç¬¦ä¸²ç» |
| | | * @return å
å«è¿åtrue |
| | | */ |
| | | public static boolean inStringIgnoreCase(String str, String... strs) { |
| | | return StrUtil.equalsAnyIgnoreCase(str, strs); |
| | | } |
| | | |
| | | /** |
| | | * å°ä¸åçº¿å¤§åæ¹å¼å½åçå符串转æ¢ä¸ºé©¼å³°å¼ãå¦æè½¬æ¢åçä¸åçº¿å¤§åæ¹å¼å½åçå符串为空ï¼åè¿å空å符串ã ä¾å¦ï¼HELLO_WORLD->HelloWorld |
| | | * |
| | | * @param name 转æ¢åçä¸åçº¿å¤§åæ¹å¼å½åçå符串 |
| | | * @return 转æ¢åç驼峰å¼å½åçå符串 |
| | | */ |
| | | public static String convertToCamelCase(String name) { |
| | | return StrUtil.upperFirst(StrUtil.toCamelCase(name)); |
| | | } |
| | | |
| | | /** |
| | | * 驼峰å¼å½åæ³ ä¾å¦ï¼user_name->userName |
| | | */ |
| | | public static String toCamelCase(String s) { |
| | | return StrUtil.toCamelCase(s); |
| | | } |
| | | |
| | | /** |
| | | * æ¥æ¾æå®å符串æ¯å¦å¹é
æå®å符串å表ä¸çä»»æä¸ä¸ªå符串 |
| | | * |
| | | * @param str æå®å符串 |
| | | * @param strs éè¦æ£æ¥çå符串æ°ç» |
| | | * @return æ¯å¦å¹é
|
| | | */ |
| | | public static boolean matches(String str, List<String> strs) { |
| | | if (isEmpty(str) || CollUtil.isEmpty(strs)) { |
| | | return false; |
| | | } |
| | | for (String pattern : strs) { |
| | | if (isMatch(pattern, str)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 夿urlæ¯å¦ä¸è§åé
ç½®: |
| | | * ? 表示å个å符; |
| | | * * 表示ä¸å±è·¯å¾å
çä»»æå符串ï¼ä¸å¯è·¨å±çº§; |
| | | * ** 表示任æå±è·¯å¾; |
| | | * |
| | | * @param pattern å¹é
è§å |
| | | * @param url éè¦å¹é
çurl |
| | | * @return |
| | | */ |
| | | public static boolean isMatch(String pattern, String url) { |
| | | AntPathMatcher matcher = new AntPathMatcher(); |
| | | return matcher.match(pattern, url); |
| | | } |
| | | |
| | | /** |
| | | * æ°å左边补é½0ï¼ä½¿ä¹è¾¾å°æå®é¿åº¦ã注æï¼å¦ææ°å转æ¢ä¸ºå符串åï¼é¿åº¦å¤§äºsizeï¼ååªä¿ç æåsize个å符ã |
| | | * |
| | | * @param num æ°å对象 |
| | | * @param size å符串æå®é¿åº¦ |
| | | * @return è¿åæ°åçåç¬¦ä¸²æ ¼å¼ï¼è¯¥å符串为æå®é¿åº¦ã |
| | | */ |
| | | public static final String padl(final Number num, final int size) { |
| | | return padl(num.toString(), size, '0'); |
| | | } |
| | | |
| | | /** |
| | | * å符串左补é½ã妿åå§å符串sé¿åº¦å¤§äºsizeï¼ååªä¿çæåsize个å符ã |
| | | * |
| | | * @param s åå§å符串 |
| | | * @param size å符串æå®é¿åº¦ |
| | | * @param c ç¨äºè¡¥é½çå符 |
| | | * @return è¿åæå®é¿åº¦çå符串ï¼ç±ååç¬¦ä¸²å·¦è¡¥é½ææªåå¾å°ã |
| | | */ |
| | | public static final String padl(final String s, final int size, final char c) { |
| | | final StringBuilder sb = new StringBuilder(size); |
| | | if (s != null) { |
| | | final int len = s.length(); |
| | | if (s.length() <= size) { |
| | | for (int i = size - len; i > 0; i--) { |
| | | sb.append(c); |
| | | } |
| | | sb.append(s); |
| | | } else { |
| | | return s.substring(len - size, len); |
| | | } |
| | | } else { |
| | | for (int i = size; i > 0; i--) { |
| | | sb.append(c); |
| | | } |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.concurrent.*; |
| | | |
| | | /** |
| | | * 线ç¨ç¸å
³å·¥å
·ç±». |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Slf4j |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class Threads { |
| | | |
| | | /** |
| | | * sleepçå¾
,åä½ä¸ºæ¯«ç§ |
| | | */ |
| | | public static void sleep(long milliseconds) { |
| | | try { |
| | | Thread.sleep(milliseconds); |
| | | } catch (InterruptedException e) { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * åæ¢çº¿ç¨æ± |
| | | * å
使ç¨shutdown, åæ¢æ¥æ¶æ°ä»»å¡å¹¶å°è¯å®æææå·²åå¨ä»»å¡. |
| | | * 妿è¶
æ¶, åè°ç¨shutdownNow, åæ¶å¨workQueueä¸Pendingçä»»å¡,并䏿ææé»å¡å½æ°. |
| | | * 妿ä»ç¶è¶
æï¼åå¼·å¶éåº. |
| | | * å¦å¯¹å¨shutdownæ¶çº¿ç¨æ¬èº«è¢«è°ç¨ä¸æåäºå¤ç. |
| | | */ |
| | | public static void shutdownAndAwaitTermination(ExecutorService pool) { |
| | | if (pool != null && !pool.isShutdown()) { |
| | | pool.shutdown(); |
| | | try { |
| | | if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { |
| | | pool.shutdownNow(); |
| | | if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { |
| | | log.info("Pool did not terminate"); |
| | | } |
| | | } |
| | | } catch (InterruptedException ie) { |
| | | pool.shutdownNow(); |
| | | Thread.currentThread().interrupt(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æå°çº¿ç¨å¼å¸¸ä¿¡æ¯ |
| | | */ |
| | | public static void printException(Runnable r, Throwable t) { |
| | | if (t == null && r instanceof Future<?>) { |
| | | try { |
| | | Future<?> future = (Future<?>) r; |
| | | if (future.isDone()) { |
| | | future.get(); |
| | | } |
| | | } catch (CancellationException ce) { |
| | | t = ce; |
| | | } catch (ExecutionException ee) { |
| | | t = ee.getCause(); |
| | | } catch (InterruptedException ie) { |
| | | Thread.currentThread().interrupt(); |
| | | } |
| | | } |
| | | if (t != null) { |
| | | log.error(t.getMessage(), t); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.tree.Tree; |
| | | import cn.hutool.core.lang.tree.TreeNodeConfig; |
| | | import cn.hutool.core.lang.tree.TreeUtil; |
| | | import cn.hutool.core.lang.tree.parser.NodeParser; |
| | | import com.ruoyi.common.core.utils.reflect.ReflectUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ©å± hutool TreeUtil å°è£
ç³»ç»æ æå»º |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class TreeBuildUtils extends TreeUtil { |
| | | |
| | | /** |
| | | * æ ¹æ®å端å®å¶å·®å¼ååæ®µ |
| | | */ |
| | | public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label"); |
| | | |
| | | public static <T, K> List<Tree<K>> build(List<T> list, NodeParser<T, K> nodeParser) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | return null; |
| | | } |
| | | K k = ReflectUtils.invokeGetter(list.get(0), "parentId"); |
| | | return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import jakarta.validation.ConstraintViolation; |
| | | import jakarta.validation.ConstraintViolationException; |
| | | import jakarta.validation.Validator; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Validator æ ¡éªæ¡æ¶å·¥å
· |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class ValidatorUtils { |
| | | |
| | | private static final Validator VALID = SpringUtils.getBean(Validator.class); |
| | | |
| | | public static <T> void validate(T object, Class<?>... groups) { |
| | | Set<ConstraintViolation<T>> validate = VALID.validate(object, groups); |
| | | if (!validate.isEmpty()) { |
| | | throw new ConstraintViolationException("åæ°æ ¡éªå¼å¸¸", validate); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils.file; |
| | | |
| | | import cn.hutool.core.io.FileUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | /** |
| | | * æä»¶å¤çå·¥å
·ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class FileUtils extends FileUtil { |
| | | |
| | | /** |
| | | * ä¸è½½æä»¶åéæ°ç¼ç |
| | | * |
| | | * @param response ååºå¯¹è±¡ |
| | | * @param realFileName ç宿件å |
| | | */ |
| | | public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException { |
| | | String percentEncodedFileName = percentEncode(realFileName); |
| | | |
| | | StringBuilder contentDispositionValue = new StringBuilder(); |
| | | contentDispositionValue.append("attachment; filename=") |
| | | .append(percentEncodedFileName) |
| | | .append(";") |
| | | .append("filename*=") |
| | | .append("utf-8''") |
| | | .append(percentEncodedFileName); |
| | | |
| | | response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); |
| | | response.setHeader("Content-disposition", contentDispositionValue.toString()); |
| | | response.setHeader("download-filename", percentEncodedFileName); |
| | | } |
| | | |
| | | /** |
| | | * ç¾åå·ç¼ç å·¥å
·æ¹æ³ |
| | | * |
| | | * @param s éè¦ç¾åå·ç¼ç çå符串 |
| | | * @return ç¾åå·ç¼ç åçå符串 |
| | | */ |
| | | public static String percentEncode(String s) throws UnsupportedEncodingException { |
| | | String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); |
| | | return encode.replaceAll("\\+", "%20"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils.file; |
| | | |
| | | /** |
| | | * åªä½ç±»åå·¥å
·ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class MimeTypeUtils { |
| | | public static final String IMAGE_PNG = "image/png"; |
| | | |
| | | public static final String IMAGE_JPG = "image/jpg"; |
| | | |
| | | public static final String IMAGE_JPEG = "image/jpeg"; |
| | | |
| | | public static final String IMAGE_BMP = "image/bmp"; |
| | | |
| | | public static final String IMAGE_GIF = "image/gif"; |
| | | |
| | | public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"}; |
| | | |
| | | public static final String[] FLASH_EXTENSION = {"swf", "flv"}; |
| | | |
| | | public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", |
| | | "asf", "rm", "rmvb"}; |
| | | |
| | | public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"}; |
| | | |
| | | public static final String[] DEFAULT_ALLOWED_EXTENSION = { |
| | | // å¾ç |
| | | "bmp", "gif", "jpg", "jpeg", "png", |
| | | // word excel powerpoint |
| | | "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", |
| | | // å缩æä»¶ |
| | | "rar", "zip", "gz", "bz2", |
| | | // è§é¢æ ¼å¼ |
| | | "mp4", "avi", "rmvb", |
| | | // pdf |
| | | "pdf"}; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils.ip; |
| | | |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.net.NetUtil; |
| | | import cn.hutool.http.HtmlUtil; |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.ruoyi.common.core.config.RuoYiConfig; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | /** |
| | | * è·åå°åç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class AddressUtils { |
| | | |
| | | // IPå°åæ¥è¯¢ |
| | | public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; |
| | | |
| | | // æªç¥å°å |
| | | public static final String UNKNOWN = "XX XX"; |
| | | |
| | | public static String getRealAddressByIP(String ip) { |
| | | String address = UNKNOWN; |
| | | if (StringUtils.isBlank(ip)) { |
| | | return address; |
| | | } |
| | | // å
ç½ä¸æ¥è¯¢ |
| | | ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); |
| | | if (NetUtil.isInnerIP(ip)) { |
| | | return "å
ç½IP"; |
| | | } |
| | | if (RuoYiConfig.isAddressEnabled()) { |
| | | try { |
| | | String rspStr = HttpUtil.createGet(IP_URL) |
| | | .body("ip=" + ip + "&json=true", Constants.GBK) |
| | | .execute() |
| | | .body(); |
| | | if (StringUtils.isEmpty(rspStr)) { |
| | | log.error("è·åå°çä½ç½®å¼å¸¸ {}", ip); |
| | | return UNKNOWN; |
| | | } |
| | | Dict obj = JsonUtils.parseMap(rspStr); |
| | | String region = obj.getStr("pro"); |
| | | String city = obj.getStr("city"); |
| | | return String.format("%s %s", region, city); |
| | | } catch (Exception e) { |
| | | log.error("è·åå°çä½ç½®å¼å¸¸ {}", ip); |
| | | } |
| | | } |
| | | return UNKNOWN; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils.reflect; |
| | | |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * åå°å·¥å
·ç±». æä¾è°ç¨getter/setteræ¹æ³, 访é®ç§æåé, è°ç¨ç§ææ¹æ³, è·åæ³åç±»åClass, 被AOPè¿ççå®ç±»çå·¥å
·å½æ°. |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class ReflectUtils extends ReflectUtil { |
| | | |
| | | private static final String SETTER_PREFIX = "set"; |
| | | |
| | | private static final String GETTER_PREFIX = "get"; |
| | | |
| | | /** |
| | | * è°ç¨Getteræ¹æ³. |
| | | * æ¯æå¤çº§ï¼å¦ï¼å¯¹è±¡å.对象å.æ¹æ³ |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <E> E invokeGetter(Object obj, String propertyName) { |
| | | Object object = obj; |
| | | for (String name : StringUtils.split(propertyName, ".")) { |
| | | String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); |
| | | object = invoke(object, getterMethodName); |
| | | } |
| | | return (E) object; |
| | | } |
| | | |
| | | /** |
| | | * è°ç¨Setteræ¹æ³, ä»
å¹é
æ¹æ³åã |
| | | * æ¯æå¤çº§ï¼å¦ï¼å¯¹è±¡å.对象å.æ¹æ³ |
| | | */ |
| | | public static <E> void invokeSetter(Object obj, String propertyName, E value) { |
| | | Object object = obj; |
| | | String[] names = StringUtils.split(propertyName, "."); |
| | | for (int i = 0; i < names.length; i++) { |
| | | if (i < names.length - 1) { |
| | | String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); |
| | | object = invoke(object, getterMethodName); |
| | | } else { |
| | | String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); |
| | | Method method = getMethodByName(object.getClass(), setterMethodName); |
| | | invoke(object, method, value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils.sql; |
| | | |
| | | import com.ruoyi.common.core.exception.UtilException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * sqlæä½å·¥å
·ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class SqlUtil { |
| | | |
| | | /** |
| | | * å®ä¹å¸¸ç¨ç sqlå
³é®å |
| | | */ |
| | | public static final String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare "; |
| | | |
| | | /** |
| | | * ä»
æ¯æåæ¯ãæ°åãä¸å线ãç©ºæ ¼ãéå·ãå°æ°ç¹ï¼æ¯æå¤ä¸ªå段æåºï¼ |
| | | */ |
| | | public static final String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; |
| | | |
| | | /** |
| | | * æ£æ¥å符ï¼é²æ¢æ³¨å
¥ç»è¿ |
| | | */ |
| | | public static String escapeOrderBySql(String value) { |
| | | if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) { |
| | | throw new UtilException("åæ°ä¸ç¬¦åè§èï¼ä¸è½è¿è¡æ¥è¯¢"); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * éªè¯ order by è¯æ³æ¯å¦ç¬¦åè§è |
| | | */ |
| | | public static boolean isValidOrderBySql(String value) { |
| | | return value.matches(SQL_PATTERN); |
| | | } |
| | | |
| | | /** |
| | | * SQLå
³é®åæ£æ¥ |
| | | */ |
| | | public static void filterKeyword(String value) { |
| | | if (StringUtils.isEmpty(value)) { |
| | | return; |
| | | } |
| | | String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); |
| | | for (String sqlKeyword : sqlKeywords) { |
| | | if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) { |
| | | throw new UtilException("åæ°åå¨SQL注å
¥é£é©"); |
| | | } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.web.controller; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | |
| | | /** |
| | | * webå±éç¨æ°æ®å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class BaseController { |
| | | |
| | | /** |
| | | * ååºè¿åç»æ |
| | | * |
| | | * @param rows å½±åè¡æ° |
| | | * @return æä½ç»æ |
| | | */ |
| | | protected R<Void> toAjax(int rows) { |
| | | return rows > 0 ? R.ok() : R.fail(); |
| | | } |
| | | |
| | | /** |
| | | * ååºè¿åç»æ |
| | | * |
| | | * @param result ç»æ |
| | | * @return æä½ç»æ |
| | | */ |
| | | protected R<Void> toAjax(boolean result) { |
| | | return result ? R.ok() : R.fail(); |
| | | } |
| | | |
| | | /** |
| | | * 页é¢è·³è½¬ |
| | | */ |
| | | public String redirect(String url) { |
| | | return StringUtils.format("redirect:{}", url); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.web.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Entityåºç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class BaseEntity implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æç´¢å¼ |
| | | */ |
| | | @JsonIgnore |
| | | @TableField(exist = false) |
| | | private String searchValue; |
| | | |
| | | /** |
| | | * å建è
|
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private String createBy; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * æ´æ°è
|
| | | */ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private String updateBy; |
| | | |
| | | /** |
| | | * æ´æ°æ¶é´ |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 请æ±åæ° |
| | | */ |
| | | @JsonInclude(JsonInclude.Include.NON_EMPTY) |
| | | @TableField(exist = false) |
| | | private Map<String, Object> params = new HashMap<>(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.web.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Treeåºç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class TreeEntity<T> extends BaseEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¶èååç§° |
| | | */ |
| | | @TableField(exist = false) |
| | | private String parentName; |
| | | |
| | | /** |
| | | * ç¶èåID |
| | | */ |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * åé¨é¨ |
| | | */ |
| | | @TableField(exist = false) |
| | | private List<T> children = new ArrayList<>(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.xss; |
| | | |
| | | import jakarta.validation.Constraint; |
| | | import jakarta.validation.Payload; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | |
| | | /** |
| | | * èªå®ä¹xssæ ¡éªæ³¨è§£ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) |
| | | @Constraint(validatedBy = {XssValidator.class}) |
| | | public @interface Xss { |
| | | |
| | | String message() default "ä¸å
许任ä½èæ¬è¿è¡"; |
| | | |
| | | Class<?>[] groups() default {}; |
| | | |
| | | Class<? extends Payload>[] payload() default {}; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.xss; |
| | | |
| | | import cn.hutool.core.util.ReUtil; |
| | | import cn.hutool.http.HtmlUtil; |
| | | |
| | | import jakarta.validation.ConstraintValidator; |
| | | import jakarta.validation.ConstraintValidatorContext; |
| | | |
| | | /** |
| | | * èªå®ä¹xssæ ¡éªæ³¨è§£å®ç° |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class XssValidator implements ConstraintValidator<Xss, String> { |
| | | |
| | | @Override |
| | | public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { |
| | | return !ReUtil.contains(HtmlUtil.RE_HTML_MARK, value); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.core.config.ApplicationConfig |
| | | com.ruoyi.common.core.config.AsyncConfig |
| | | com.ruoyi.common.core.config.JacksonConfig |
| | | com.ruoyi.common.core.config.RuoYiConfig |
| | | com.ruoyi.common.core.config.ThreadPoolConfig |
| | | com.ruoyi.common.core.config.ValidatorConfig |
| | | com.ruoyi.common.core.utils.SpringUtils |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-dict</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-dict åå
¸ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.dict.annotation; |
| | | |
| | | import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
| | | import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
| | | import com.ruoyi.common.dict.jackson.DictDataJsonSerializer; |
| | | |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | |
| | | /** |
| | | * åå
¸æ°æ®æ å°æ³¨è§£ |
| | | * |
| | | * @author itino |
| | | */ |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Target({ElementType.FIELD, ElementType.METHOD}) |
| | | @JacksonAnnotationsInside |
| | | @JsonSerialize(using = DictDataJsonSerializer.class) |
| | | public @interface DictDataMapper { |
| | | |
| | | /** |
| | | * 设置åå
¸çtypeå¼ (å¦: sys_user_sex) |
| | | */ |
| | | String dictType() default ""; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.dict.jackson; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.BeanProperty; |
| | | import com.fasterxml.jackson.databind.JsonMappingException; |
| | | import com.fasterxml.jackson.databind.JsonSerializer; |
| | | import com.fasterxml.jackson.databind.SerializerProvider; |
| | | import com.fasterxml.jackson.databind.ser.ContextualSerializer; |
| | | import com.ruoyi.common.core.service.DictService; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.dict.annotation.DictDataMapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.BeansException; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * åå
¸æ°æ®jsonåºååå·¥å
· |
| | | * |
| | | * @author itino |
| | | */ |
| | | @Slf4j |
| | | public class DictDataJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { |
| | | |
| | | private String dictType; |
| | | |
| | | @Override |
| | | public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { |
| | | try { |
| | | DictService dictService = SpringUtils.getBean(DictService.class); |
| | | if (ObjectUtil.isNotNull(dictService)) { |
| | | String label = dictService.getDictLabel(dictType, value); |
| | | gen.writeString(StringUtils.isNotBlank(label) ? label : value); |
| | | } else { |
| | | gen.writeString(value); |
| | | } |
| | | } catch (BeansException e) { |
| | | log.error("åå
¸æ°æ®æªæ¥å°, éç¨é»è®¤å¤ç => {}", e.getMessage()); |
| | | gen.writeString(value); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { |
| | | DictDataMapper anno = property.getAnnotation(DictDataMapper.class); |
| | | if (Objects.nonNull(anno) && StrUtil.isNotBlank(anno.dictType())) { |
| | | this.dictType = anno.dictType(); |
| | | return this; |
| | | } |
| | | return prov.findValueSerializer(property.getType(), property); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-doc</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-doc ç³»ç»æ¥å£ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springdoc</groupId> |
| | | <artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.github.therapi</groupId> |
| | | <artifactId>therapi-runtime-javadoc</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.doc.config; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.doc.config.properties.SwaggerProperties; |
| | | import com.ruoyi.common.doc.handler.OpenApiHandler; |
| | | import io.swagger.v3.oas.models.OpenAPI; |
| | | import io.swagger.v3.oas.models.Paths; |
| | | import io.swagger.v3.oas.models.info.Info; |
| | | import io.swagger.v3.oas.models.security.SecurityRequirement; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springdoc.core.configuration.SpringDocConfiguration; |
| | | import org.springdoc.core.customizers.OpenApiBuilderCustomizer; |
| | | import org.springdoc.core.customizers.OpenApiCustomizer; |
| | | import org.springdoc.core.customizers.ServerBaseUrlCustomizer; |
| | | import org.springdoc.core.properties.SpringDocConfigProperties; |
| | | import org.springdoc.core.providers.JavadocProvider; |
| | | import org.springdoc.core.service.OpenAPIService; |
| | | import org.springdoc.core.service.SecurityService; |
| | | import org.springdoc.core.utils.PropertyResolverUtils; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.autoconfigure.web.ServerProperties; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Swagger ææ¡£é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @AutoConfiguration(before = SpringDocConfiguration.class) |
| | | @ConditionalOnProperty(name = "swagger.enabled", havingValue = "true", matchIfMissing = true) |
| | | public class SwaggerConfig { |
| | | |
| | | private final SwaggerProperties swaggerProperties; |
| | | private final ServerProperties serverProperties; |
| | | |
| | | @Bean |
| | | @ConditionalOnMissingBean(OpenAPI.class) |
| | | public OpenAPI openApi() { |
| | | OpenAPI openApi = new OpenAPI(); |
| | | // ææ¡£åºæ¬ä¿¡æ¯ |
| | | SwaggerProperties.InfoProperties infoProperties = swaggerProperties.getInfo(); |
| | | Info info = convertInfo(infoProperties); |
| | | openApi.info(info); |
| | | // æ©å±ææ¡£ä¿¡æ¯ |
| | | openApi.externalDocs(swaggerProperties.getExternalDocs()); |
| | | openApi.tags(swaggerProperties.getTags()); |
| | | openApi.paths(swaggerProperties.getPaths()); |
| | | openApi.components(swaggerProperties.getComponents()); |
| | | Set<String> keySet = swaggerProperties.getComponents().getSecuritySchemes().keySet(); |
| | | List<SecurityRequirement> list = new ArrayList<>(); |
| | | SecurityRequirement securityRequirement = new SecurityRequirement(); |
| | | keySet.forEach(securityRequirement::addList); |
| | | list.add(securityRequirement); |
| | | openApi.security(list); |
| | | |
| | | return openApi; |
| | | } |
| | | |
| | | private Info convertInfo(SwaggerProperties.InfoProperties infoProperties) { |
| | | Info info = new Info(); |
| | | info.setTitle(infoProperties.getTitle()); |
| | | info.setDescription(infoProperties.getDescription()); |
| | | info.setContact(infoProperties.getContact()); |
| | | info.setLicense(infoProperties.getLicense()); |
| | | info.setVersion(infoProperties.getVersion()); |
| | | return info; |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹ openapi å¤çå¨ |
| | | */ |
| | | @Bean |
| | | public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI, |
| | | SecurityService securityParser, |
| | | SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils, |
| | | Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers, |
| | | Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers, Optional<JavadocProvider> javadocProvider) { |
| | | return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider); |
| | | } |
| | | |
| | | /** |
| | | * 对已ç»çæå¥½ç OpenApi è¿è¡èªå®ä¹æä½ |
| | | */ |
| | | @Bean |
| | | public OpenApiCustomizer openApiCustomiser() { |
| | | String contextPath = serverProperties.getServlet().getContextPath(); |
| | | String finalContextPath; |
| | | if (StringUtils.isBlank(contextPath) || "/".equals(contextPath)) { |
| | | finalContextPath = ""; |
| | | } else { |
| | | finalContextPath = contextPath; |
| | | } |
| | | // 对ææè·¯å¾å¢å åç½®ä¸ä¸æè·¯å¾ |
| | | return openApi -> { |
| | | Paths oldPaths = openApi.getPaths(); |
| | | if (oldPaths instanceof PlusPaths) { |
| | | return; |
| | | } |
| | | PlusPaths newPaths = new PlusPaths(); |
| | | oldPaths.forEach((k, v) -> newPaths.addPathItem(finalContextPath + k, v)); |
| | | openApi.setPaths(newPaths); |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * åç¬ä½¿ç¨ä¸ä¸ªç±»ä¾¿äºå¤æ è§£å³springdocè·¯å¾æ¼æ¥éå¤é®é¢ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | static class PlusPaths extends Paths { |
| | | |
| | | public PlusPaths() { |
| | | super(); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.doc.config.properties; |
| | | |
| | | import io.swagger.v3.oas.models.Components; |
| | | import io.swagger.v3.oas.models.ExternalDocumentation; |
| | | import io.swagger.v3.oas.models.Paths; |
| | | import io.swagger.v3.oas.models.info.Contact; |
| | | import io.swagger.v3.oas.models.info.License; |
| | | import io.swagger.v3.oas.models.tags.Tag; |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.boot.context.properties.NestedConfigurationProperty; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * swagger é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "swagger") |
| | | public class SwaggerProperties { |
| | | |
| | | /** |
| | | * æ¯å¦å¼å¯ openApi ææ¡£ |
| | | */ |
| | | private Boolean enabled = true; |
| | | |
| | | /** |
| | | * ææ¡£åºæ¬ä¿¡æ¯ |
| | | */ |
| | | @NestedConfigurationProperty |
| | | private InfoProperties info = new InfoProperties(); |
| | | |
| | | /** |
| | | * æ©å±ææ¡£å°å |
| | | */ |
| | | @NestedConfigurationProperty |
| | | private ExternalDocumentation externalDocs; |
| | | |
| | | /** |
| | | * æ ç¾ |
| | | */ |
| | | private List<Tag> tags = null; |
| | | |
| | | /** |
| | | * è·¯å¾ |
| | | */ |
| | | @NestedConfigurationProperty |
| | | private Paths paths = null; |
| | | |
| | | /** |
| | | * ç»ä»¶ |
| | | */ |
| | | @NestedConfigurationProperty |
| | | private Components components = null; |
| | | |
| | | /** |
| | | * <p> |
| | | * ææ¡£çåºç¡å±æ§ä¿¡æ¯ |
| | | * </p> |
| | | * |
| | | * @see io.swagger.v3.oas.models.info.Info |
| | | * |
| | | * ä¸ºäº springboot èªå¨ç产é
ç½®æç¤ºä¿¡æ¯ï¼æä»¥è¿éå¤å¶ä¸ä¸ªç±»åºæ¥ |
| | | */ |
| | | @Data |
| | | public static class InfoProperties { |
| | | |
| | | /** |
| | | * æ é¢ |
| | | */ |
| | | private String title = null; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private String description = null; |
| | | |
| | | /** |
| | | * èç³»äººä¿¡æ¯ |
| | | */ |
| | | @NestedConfigurationProperty |
| | | private Contact contact = null; |
| | | |
| | | /** |
| | | * 许å¯è¯ |
| | | */ |
| | | @NestedConfigurationProperty |
| | | private License license = null; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | private String version = null; |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.doc.handler; |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import io.swagger.v3.core.jackson.TypeNameResolver; |
| | | import io.swagger.v3.core.util.AnnotationsUtils; |
| | | import io.swagger.v3.oas.annotations.tags.Tags; |
| | | import io.swagger.v3.oas.models.Components; |
| | | import io.swagger.v3.oas.models.OpenAPI; |
| | | import io.swagger.v3.oas.models.Operation; |
| | | import io.swagger.v3.oas.models.Paths; |
| | | import io.swagger.v3.oas.models.tags.Tag; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springdoc.core.customizers.OpenApiBuilderCustomizer; |
| | | import org.springdoc.core.customizers.ServerBaseUrlCustomizer; |
| | | import org.springdoc.core.properties.SpringDocConfigProperties; |
| | | import org.springdoc.core.providers.JavadocProvider; |
| | | import org.springdoc.core.service.OpenAPIService; |
| | | import org.springdoc.core.service.SecurityService; |
| | | import org.springdoc.core.utils.PropertyResolverUtils; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.core.annotation.AnnotatedElementUtils; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.method.HandlerMethod; |
| | | |
| | | import java.io.StringReader; |
| | | import java.lang.reflect.Method; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | /** |
| | | * èªå®ä¹ openapi å¤çå¨ |
| | | * 对æºç åè½è¿è¡ä¿®æ¹ å¢å¼ºä½¿ç¨ |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("all") |
| | | public class OpenApiHandler extends OpenAPIService { |
| | | |
| | | /** |
| | | * The Basic error controller. |
| | | */ |
| | | private static Class<?> basicErrorController; |
| | | |
| | | /** |
| | | * The Security parser. |
| | | */ |
| | | private final SecurityService securityParser; |
| | | |
| | | /** |
| | | * The Mappings map. |
| | | */ |
| | | private final Map<String, Object> mappingsMap = new HashMap<>(); |
| | | |
| | | /** |
| | | * The Springdoc tags. |
| | | */ |
| | | private final Map<HandlerMethod, Tag> springdocTags = new HashMap<>(); |
| | | |
| | | /** |
| | | * The Open api builder customisers. |
| | | */ |
| | | private final Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers; |
| | | |
| | | /** |
| | | * The server base URL customisers. |
| | | */ |
| | | private final Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers; |
| | | |
| | | /** |
| | | * The Spring doc config properties. |
| | | */ |
| | | private final SpringDocConfigProperties springDocConfigProperties; |
| | | |
| | | /** |
| | | * The Cached open api map. |
| | | */ |
| | | private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>(); |
| | | |
| | | /** |
| | | * The Property resolver utils. |
| | | */ |
| | | private final PropertyResolverUtils propertyResolverUtils; |
| | | |
| | | /** |
| | | * The javadoc provider. |
| | | */ |
| | | private final Optional<JavadocProvider> javadocProvider; |
| | | |
| | | /** |
| | | * The Context. |
| | | */ |
| | | private ApplicationContext context; |
| | | |
| | | /** |
| | | * The Open api. |
| | | */ |
| | | private OpenAPI openAPI; |
| | | |
| | | /** |
| | | * The Is servers present. |
| | | */ |
| | | private boolean isServersPresent; |
| | | |
| | | /** |
| | | * The Server base url. |
| | | */ |
| | | private String serverBaseUrl; |
| | | |
| | | /** |
| | | * Instantiates a new Open api builder. |
| | | * |
| | | * @param openAPI the open api |
| | | * @param securityParser the security parser |
| | | * @param springDocConfigProperties the spring doc config properties |
| | | * @param propertyResolverUtils the property resolver utils |
| | | * @param openApiBuilderCustomizers the open api builder customisers |
| | | * @param serverBaseUrlCustomizers the server base url customizers |
| | | * @param javadocProvider the javadoc provider |
| | | */ |
| | | public OpenApiHandler(Optional<OpenAPI> openAPI, SecurityService securityParser, |
| | | SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils, |
| | | Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers, |
| | | Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers, |
| | | Optional<JavadocProvider> javadocProvider) { |
| | | super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider); |
| | | if (openAPI.isPresent()) { |
| | | this.openAPI = openAPI.get(); |
| | | if (this.openAPI.getComponents() == null) |
| | | this.openAPI.setComponents(new Components()); |
| | | if (this.openAPI.getPaths() == null) |
| | | this.openAPI.setPaths(new Paths()); |
| | | if (!CollectionUtils.isEmpty(this.openAPI.getServers())) |
| | | this.isServersPresent = true; |
| | | } |
| | | this.propertyResolverUtils = propertyResolverUtils; |
| | | this.securityParser = securityParser; |
| | | this.springDocConfigProperties = springDocConfigProperties; |
| | | this.openApiBuilderCustomisers = openApiBuilderCustomizers; |
| | | this.serverBaseUrlCustomizers = serverBaseUrlCustomizers; |
| | | this.javadocProvider = javadocProvider; |
| | | if (springDocConfigProperties.isUseFqn()) |
| | | TypeNameResolver.std.setUseFqn(true); |
| | | } |
| | | |
| | | @Override |
| | | public Operation buildTags(HandlerMethod handlerMethod, Operation operation, OpenAPI openAPI, Locale locale) { |
| | | |
| | | Set<Tag> tags = new HashSet<>(); |
| | | Set<String> tagsStr = new HashSet<>(); |
| | | |
| | | buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr, locale); |
| | | buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr, locale); |
| | | |
| | | if (!CollectionUtils.isEmpty(tagsStr)) |
| | | tagsStr = tagsStr.stream() |
| | | .map(str -> propertyResolverUtils.resolve(str, locale)) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | if (springdocTags.containsKey(handlerMethod)) { |
| | | io.swagger.v3.oas.models.tags.Tag tag = springdocTags.get(handlerMethod); |
| | | tagsStr.add(tag.getName()); |
| | | if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) { |
| | | openAPI.addTagsItem(tag); |
| | | } |
| | | } |
| | | |
| | | if (!CollectionUtils.isEmpty(tagsStr)) { |
| | | if (CollectionUtils.isEmpty(operation.getTags())) |
| | | operation.setTags(new ArrayList<>(tagsStr)); |
| | | else { |
| | | Set<String> operationTagsSet = new HashSet<>(operation.getTags()); |
| | | operationTagsSet.addAll(tagsStr); |
| | | operation.getTags().clear(); |
| | | operation.getTags().addAll(operationTagsSet); |
| | | } |
| | | } |
| | | |
| | | if (isAutoTagClasses(operation)) { |
| | | |
| | | |
| | | if (javadocProvider.isPresent()) { |
| | | String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType()); |
| | | if (StringUtils.isNotBlank(description)) { |
| | | io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag(); |
| | | |
| | | // èªå®ä¹é¨å ä¿®æ¹ä½¿ç¨java注éå½tagå |
| | | List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>()); |
| | | // tag.setName(tagAutoName); |
| | | tag.setName(list.get(0)); |
| | | operation.addTagsItem(list.get(0)); |
| | | |
| | | tag.setDescription(description); |
| | | if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) { |
| | | openAPI.addTagsItem(tag); |
| | | } |
| | | } |
| | | } else { |
| | | String tagAutoName = splitCamelCase(handlerMethod.getBeanType().getSimpleName()); |
| | | operation.addTagsItem(tagAutoName); |
| | | } |
| | | } |
| | | |
| | | if (!CollectionUtils.isEmpty(tags)) { |
| | | // Existing tags |
| | | List<io.swagger.v3.oas.models.tags.Tag> openApiTags = openAPI.getTags(); |
| | | if (!CollectionUtils.isEmpty(openApiTags)) |
| | | tags.addAll(openApiTags); |
| | | openAPI.setTags(new ArrayList<>(tags)); |
| | | } |
| | | |
| | | // Handle SecurityRequirement at operation level |
| | | io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser |
| | | .getSecurityRequirements(handlerMethod); |
| | | if (securityRequirements != null) { |
| | | if (securityRequirements.length == 0) |
| | | operation.setSecurity(Collections.emptyList()); |
| | | else |
| | | securityParser.buildSecurityRequirement(securityRequirements, operation); |
| | | } |
| | | |
| | | return operation; |
| | | } |
| | | |
| | | private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) { |
| | | // method tags |
| | | Set<Tags> tagsSet = AnnotatedElementUtils |
| | | .findAllMergedAnnotations(method, Tags.class); |
| | | Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream() |
| | | .flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet()); |
| | | methodTags.addAll(AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class)); |
| | | if (!CollectionUtils.isEmpty(methodTags)) { |
| | | tagsStr.addAll(methodTags.stream().map(tag -> propertyResolverUtils.resolve(tag.name(), locale)).collect(Collectors.toSet())); |
| | | List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags); |
| | | addTags(allTags, tags, locale); |
| | | } |
| | | } |
| | | |
| | | private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) { |
| | | Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils |
| | | .getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true); |
| | | optionalTagSet.ifPresent(tagsSet -> { |
| | | tagsSet.forEach(tag -> { |
| | | tag.name(propertyResolverUtils.resolve(tag.getName(), locale)); |
| | | tag.description(propertyResolverUtils.resolve(tag.getDescription(), locale)); |
| | | if (tags.stream().noneMatch(t -> t.getName().equals(tag.getName()))) |
| | | tags.add(tag); |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.doc.config.SwaggerConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-excel</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-excel |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>easyexcel</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.annotation; |
| | | |
| | | import com.ruoyi.common.excel.core.CellMergeStrategy; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * excel ååå
æ ¼åå¹¶(åå¹¶åç¸å项) |
| | | * |
| | | * éæé
{@link CellMergeStrategy} çç¥ä½¿ç¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Target(ElementType.FIELD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Inherited |
| | | public @interface CellMerge { |
| | | |
| | | /** |
| | | * col index |
| | | */ |
| | | int index() default -1; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * åå
¸æ ¼å¼å |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Target({ElementType.FIELD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Inherited |
| | | public @interface ExcelDictFormat { |
| | | |
| | | /** |
| | | * 妿æ¯åå
¸ç±»åï¼è¯·è®¾ç½®åå
¸çtypeå¼ (å¦: sys_user_sex) |
| | | */ |
| | | String dictType() default ""; |
| | | |
| | | /** |
| | | * 读åå
å®¹è½¬è¡¨è¾¾å¼ (å¦: 0=ç·,1=女,2=æªç¥) |
| | | */ |
| | | String readConverterExp() default ""; |
| | | |
| | | /** |
| | | * åé符ï¼è¯»åå符串ç»å
容 |
| | | */ |
| | | String separator() default ","; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.convert; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.alibaba.excel.converters.Converter; |
| | | import com.alibaba.excel.enums.CellDataTypeEnum; |
| | | import com.alibaba.excel.metadata.GlobalConfiguration; |
| | | import com.alibaba.excel.metadata.data.ReadCellData; |
| | | import com.alibaba.excel.metadata.data.WriteCellData; |
| | | import com.alibaba.excel.metadata.property.ExcelContentProperty; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 大æ°å¼è½¬æ¢ |
| | | * Excel æ°å¼é¿åº¦ä½15ä½ å¤§äº15ä½çæ°å¼è½¬æ¢ä½å符串 |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | public class ExcelBigNumberConvert implements Converter<Long> { |
| | | |
| | | @Override |
| | | public Class<Long> supportJavaTypeKey() { |
| | | return Long.class; |
| | | } |
| | | |
| | | @Override |
| | | public CellDataTypeEnum supportExcelTypeKey() { |
| | | return CellDataTypeEnum.STRING; |
| | | } |
| | | |
| | | @Override |
| | | public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
| | | return Convert.toLong(cellData.getData()); |
| | | } |
| | | |
| | | @Override |
| | | public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
| | | if (ObjectUtil.isNotNull(object)) { |
| | | String str = Convert.toStr(object); |
| | | if (str.length() > 15) { |
| | | return new WriteCellData<>(str); |
| | | } |
| | | } |
| | | WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object)); |
| | | cellData.setType(CellDataTypeEnum.NUMBER); |
| | | return cellData; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.convert; |
| | | |
| | | import cn.hutool.core.annotation.AnnotationUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.alibaba.excel.converters.Converter; |
| | | import com.alibaba.excel.enums.CellDataTypeEnum; |
| | | import com.alibaba.excel.metadata.GlobalConfiguration; |
| | | import com.alibaba.excel.metadata.data.ReadCellData; |
| | | import com.alibaba.excel.metadata.data.WriteCellData; |
| | | import com.alibaba.excel.metadata.property.ExcelContentProperty; |
| | | import com.ruoyi.common.excel.annotation.ExcelDictFormat; |
| | | import com.ruoyi.common.core.service.DictService; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.lang.reflect.Field; |
| | | |
| | | /** |
| | | * åå
¸æ ¼å¼å转æ¢å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | public class ExcelDictConvert implements Converter<Object> { |
| | | |
| | | @Override |
| | | public Class<Object> supportJavaTypeKey() { |
| | | return Object.class; |
| | | } |
| | | |
| | | @Override |
| | | public CellDataTypeEnum supportExcelTypeKey() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
| | | ExcelDictFormat anno = getAnnotation(contentProperty.getField()); |
| | | String type = anno.dictType(); |
| | | String label = cellData.getStringValue(); |
| | | String value; |
| | | if (StringUtils.isBlank(type)) { |
| | | value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator()); |
| | | } else { |
| | | value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator()); |
| | | } |
| | | return Convert.convert(contentProperty.getField().getType(), value); |
| | | } |
| | | |
| | | @Override |
| | | public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
| | | if (ObjectUtil.isNull(object)) { |
| | | return new WriteCellData<>(""); |
| | | } |
| | | ExcelDictFormat anno = getAnnotation(contentProperty.getField()); |
| | | String type = anno.dictType(); |
| | | String value = Convert.toStr(object); |
| | | String label; |
| | | if (StringUtils.isBlank(type)) { |
| | | label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator()); |
| | | } else { |
| | | label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator()); |
| | | } |
| | | return new WriteCellData<>(label); |
| | | } |
| | | |
| | | private ExcelDictFormat getAnnotation(Field field) { |
| | | return AnnotationUtil.getAnnotation(field, ExcelDictFormat.class); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.core; |
| | | |
| | | import com.alibaba.excel.metadata.Head; |
| | | import com.alibaba.excel.write.merge.AbstractMergeStrategy; |
| | | import com.ruoyi.common.excel.annotation.CellMerge; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.poi.ss.usermodel.Cell; |
| | | import org.apache.poi.ss.usermodel.Sheet; |
| | | import org.apache.poi.ss.util.CellRangeAddress; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.Method; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * åå¼éå¤åå¹¶çç¥ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class CellMergeStrategy extends AbstractMergeStrategy { |
| | | |
| | | private List<?> list; |
| | | private boolean hasTitle; |
| | | |
| | | @Override |
| | | protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { |
| | | List<CellRangeAddress> cellList = handle(list, hasTitle); |
| | | // judge the list is not null |
| | | if (CollectionUtils.isNotEmpty(cellList)) { |
| | | // the judge is necessary |
| | | if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) { |
| | | for (CellRangeAddress item : cellList) { |
| | | sheet.addMergedRegion(item); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | @SneakyThrows |
| | | private static List<CellRangeAddress> handle(List<?> list, boolean hasTitle) { |
| | | List<CellRangeAddress> cellList = new ArrayList<>(); |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | return cellList; |
| | | } |
| | | Class<?> clazz = list.get(0).getClass(); |
| | | Field[] fields = clazz.getDeclaredFields(); |
| | | // ææ³¨è§£çåæ®µ |
| | | List<Field> mergeFields = new ArrayList<>(); |
| | | List<Integer> mergeFieldsIndex = new ArrayList<>(); |
| | | for (int i = 0; i < fields.length; i++) { |
| | | Field field = fields[i]; |
| | | if (field.isAnnotationPresent(CellMerge.class)) { |
| | | CellMerge cm = field.getAnnotation(CellMerge.class); |
| | | mergeFields.add(field); |
| | | mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index()); |
| | | } |
| | | } |
| | | // è¡åå¹¶å¼å§ä¸æ |
| | | int rowIndex = hasTitle ? 1 : 0; |
| | | Map<Field, RepeatCell> map = new HashMap<>(); |
| | | // çæä¸¤ä¸¤åå¹¶åå
æ ¼ |
| | | for (int i = 0; i < list.size(); i++) { |
| | | for (int j = 0; j < mergeFields.size(); j++) { |
| | | Field field = mergeFields.get(j); |
| | | String name = field.getName(); |
| | | String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); |
| | | Method readMethod = clazz.getMethod(methodName); |
| | | Object val = readMethod.invoke(list.get(i)); |
| | | |
| | | int colNum = mergeFieldsIndex.get(j); |
| | | if (!map.containsKey(field)) { |
| | | map.put(field, new RepeatCell(val, i)); |
| | | } else { |
| | | RepeatCell repeatCell = map.get(field); |
| | | Object cellValue = repeatCell.getValue(); |
| | | if (cellValue == null || "".equals(cellValue)) { |
| | | // 空å¼è·³è¿ä¸åå¹¶ |
| | | continue; |
| | | } |
| | | if (!cellValue.equals(val)) { |
| | | if (i - repeatCell.getCurrent() > 1) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); |
| | | } |
| | | map.put(field, new RepeatCell(val, i)); |
| | | } else if (i == list.size() - 1) { |
| | | if (i > repeatCell.getCurrent()) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return cellList; |
| | | } |
| | | |
| | | @Data |
| | | @AllArgsConstructor |
| | | static class RepeatCell { |
| | | |
| | | private Object value; |
| | | |
| | | private int current; |
| | | |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.core; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.excel.context.AnalysisContext; |
| | | import com.alibaba.excel.event.AnalysisEventListener; |
| | | import com.alibaba.excel.exception.ExcelAnalysisException; |
| | | import com.alibaba.excel.exception.ExcelDataConvertException; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StreamUtils; |
| | | import com.ruoyi.common.core.utils.ValidatorUtils; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import jakarta.validation.ConstraintViolation; |
| | | import jakarta.validation.ConstraintViolationException; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Excel 导å
¥çå¬ |
| | | * |
| | | * @author Yjoioooo |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @NoArgsConstructor |
| | | public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements ExcelListener<T> { |
| | | |
| | | /** |
| | | * æ¯å¦Validatoræ£éªï¼é»è®¤ä¸ºæ¯ |
| | | */ |
| | | private Boolean isValidate = Boolean.TRUE; |
| | | |
| | | /** |
| | | * excel è¡¨å¤´æ°æ® |
| | | */ |
| | | private Map<Integer, String> headMap; |
| | | |
| | | /** |
| | | * 导å
¥åæ§ |
| | | */ |
| | | private ExcelResult<T> excelResult; |
| | | |
| | | public DefaultExcelListener(boolean isValidate) { |
| | | this.excelResult = new DefautExcelResult<>(); |
| | | this.isValidate = isValidate; |
| | | } |
| | | |
| | | /** |
| | | * å¤çå¼å¸¸ |
| | | * |
| | | * @param exception ExcelDataConvertException |
| | | * @param context Excel ä¸ä¸æ |
| | | */ |
| | | @Override |
| | | public void onException(Exception exception, AnalysisContext context) throws Exception { |
| | | String errMsg = null; |
| | | if (exception instanceof ExcelDataConvertException) { |
| | | // å¦ææ¯æä¸ä¸ªåå
æ ¼ç转æ¢å¼å¸¸ è½è·åå°å
·ä½è¡å· |
| | | ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception; |
| | | Integer rowIndex = excelDataConvertException.getRowIndex(); |
| | | Integer columnIndex = excelDataConvertException.getColumnIndex(); |
| | | errMsg = StrUtil.format("第{}è¡-第{}å-表头{}: è§£æå¼å¸¸<br/>", |
| | | rowIndex + 1, columnIndex + 1, headMap.get(columnIndex)); |
| | | if (log.isDebugEnabled()) { |
| | | log.error(errMsg); |
| | | } |
| | | } |
| | | if (exception instanceof ConstraintViolationException) { |
| | | ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception; |
| | | Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations(); |
| | | String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", "); |
| | | errMsg = StrUtil.format("第{}è¡æ°æ®æ ¡éªå¼å¸¸: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg); |
| | | if (log.isDebugEnabled()) { |
| | | log.error(errMsg); |
| | | } |
| | | } |
| | | excelResult.getErrorList().add(errMsg); |
| | | throw new ExcelAnalysisException(errMsg); |
| | | } |
| | | |
| | | @Override |
| | | public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { |
| | | this.headMap = headMap; |
| | | log.debug("è§£æå°ä¸æ¡è¡¨å¤´æ°æ®: {}", JsonUtils.toJsonString(headMap)); |
| | | } |
| | | |
| | | @Override |
| | | public void invoke(T data, AnalysisContext context) { |
| | | if (isValidate) { |
| | | ValidatorUtils.validate(data); |
| | | } |
| | | excelResult.getList().add(data); |
| | | } |
| | | |
| | | @Override |
| | | public void doAfterAllAnalysed(AnalysisContext context) { |
| | | log.debug("æææ°æ®è§£æå®æï¼"); |
| | | } |
| | | |
| | | @Override |
| | | public ExcelResult<T> getExcelResult() { |
| | | return excelResult; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.core; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * é»è®¤excelè¿å对象 |
| | | * |
| | | * @author Yjoioooo |
| | | * @author Lion Li |
| | | */ |
| | | public class DefautExcelResult<T> implements ExcelResult<T> { |
| | | |
| | | /** |
| | | * æ°æ®å¯¹è±¡list |
| | | */ |
| | | @Setter |
| | | private List<T> list; |
| | | |
| | | /** |
| | | * é误信æ¯å表 |
| | | */ |
| | | @Setter |
| | | private List<String> errorList; |
| | | |
| | | public DefautExcelResult() { |
| | | this.list = new ArrayList<>(); |
| | | this.errorList = new ArrayList<>(); |
| | | } |
| | | |
| | | public DefautExcelResult(List<T> list, List<String> errorList) { |
| | | this.list = list; |
| | | this.errorList = errorList; |
| | | } |
| | | |
| | | public DefautExcelResult(ExcelResult<T> excelResult) { |
| | | this.list = excelResult.getList(); |
| | | this.errorList = excelResult.getErrorList(); |
| | | } |
| | | |
| | | @Override |
| | | public List<T> getList() { |
| | | return list; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getErrorList() { |
| | | return errorList; |
| | | } |
| | | |
| | | /** |
| | | * è·å导å
¥åæ§ |
| | | * |
| | | * @return 导å
¥åæ§ |
| | | */ |
| | | @Override |
| | | public String getAnalysis() { |
| | | int successCount = list.size(); |
| | | int errorCount = errorList.size(); |
| | | if (successCount == 0) { |
| | | return "读åå¤±è´¥ï¼æªè§£æå°æ°æ®"; |
| | | } else { |
| | | if (errorCount == 0) { |
| | | return StrUtil.format("æåæ¨ï¼å
¨é¨è¯»åæåï¼å
±{}æ¡", successCount); |
| | | } else { |
| | | return ""; |
| | | } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.core; |
| | | |
| | | import com.alibaba.excel.read.listener.ReadListener; |
| | | |
| | | /** |
| | | * Excel 导å
¥çå¬ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public interface ExcelListener<T> extends ReadListener<T> { |
| | | |
| | | ExcelResult<T> getExcelResult(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.core; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * excelè¿å对象 |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public interface ExcelResult<T> { |
| | | |
| | | /** |
| | | * 对象å表 |
| | | */ |
| | | List<T> getList(); |
| | | |
| | | /** |
| | | * é误å表 |
| | | */ |
| | | List<String> getErrorList(); |
| | | |
| | | /** |
| | | * 导å
¥åæ§ |
| | | */ |
| | | String getAnalysis(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.excel.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.io.resource.ClassPathResource; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.alibaba.excel.EasyExcel; |
| | | import com.alibaba.excel.ExcelWriter; |
| | | import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; |
| | | import com.alibaba.excel.write.metadata.WriteSheet; |
| | | import com.alibaba.excel.write.metadata.fill.FillConfig; |
| | | import com.alibaba.excel.write.metadata.fill.FillWrapper; |
| | | import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.file.FileUtils; |
| | | import com.ruoyi.common.excel.convert.ExcelBigNumberConvert; |
| | | import com.ruoyi.common.excel.core.CellMergeStrategy; |
| | | import com.ruoyi.common.excel.core.DefaultExcelListener; |
| | | import com.ruoyi.common.excel.core.ExcelListener; |
| | | import com.ruoyi.common.excel.core.ExcelResult; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import jakarta.servlet.ServletOutputStream; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Excelç¸å
³å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class ExcelUtil { |
| | | |
| | | /** |
| | | * 忥坼å
¥(éç¨äºå°æ°æ®é) |
| | | * |
| | | * @param is è¾å
¥æµ |
| | | * @return 转æ¢åéå |
| | | */ |
| | | public static <T> List<T> importExcel(InputStream is, Class<T> clazz) { |
| | | return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * ä½¿ç¨æ ¡éªçå¬å¨ 弿¥å¯¼å
¥ 忥è¿å |
| | | * |
| | | * @param is è¾å
¥æµ |
| | | * @param clazz 对象类å |
| | | * @param isValidate æ¯å¦ Validator æ£éª é»è®¤ä¸ºæ¯ |
| | | * @return 转æ¢åéå |
| | | */ |
| | | public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, boolean isValidate) { |
| | | DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate); |
| | | EasyExcel.read(is, clazz, listener).sheet().doRead(); |
| | | return listener.getExcelResult(); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨èªå®ä¹çå¬å¨ 弿¥å¯¼å
¥ èªå®ä¹è¿å |
| | | * |
| | | * @param is è¾å
¥æµ |
| | | * @param clazz 对象类å |
| | | * @param listener èªå®ä¹çå¬å¨ |
| | | * @return 转æ¢åéå |
| | | */ |
| | | public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, ExcelListener<T> listener) { |
| | | EasyExcel.read(is, clazz, listener).sheet().doRead(); |
| | | return listener.getExcelResult(); |
| | | } |
| | | |
| | | /** |
| | | * 导åºexcel |
| | | * |
| | | * @param list å¯¼åºæ°æ®éå |
| | | * @param sheetName å·¥ä½è¡¨çåç§° |
| | | * @param clazz å®ä½ç±» |
| | | * @param response ååºä½ |
| | | */ |
| | | public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) { |
| | | try { |
| | | resetResponse(sheetName, response); |
| | | ServletOutputStream os = response.getOutputStream(); |
| | | exportExcel(list, sheetName, clazz, false, os); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("导åºExcelå¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 导åºexcel |
| | | * |
| | | * @param list å¯¼åºæ°æ®éå |
| | | * @param sheetName å·¥ä½è¡¨çåç§° |
| | | * @param clazz å®ä½ç±» |
| | | * @param merge æ¯å¦åå¹¶åå
æ ¼ |
| | | * @param response ååºä½ |
| | | */ |
| | | public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, HttpServletResponse response) { |
| | | try { |
| | | resetResponse(sheetName, response); |
| | | ServletOutputStream os = response.getOutputStream(); |
| | | exportExcel(list, sheetName, clazz, merge, os); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("导åºExcelå¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 导åºexcel |
| | | * |
| | | * @param list å¯¼åºæ°æ®éå |
| | | * @param sheetName å·¥ä½è¡¨çåç§° |
| | | * @param clazz å®ä½ç±» |
| | | * @param os è¾åºæµ |
| | | */ |
| | | public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, OutputStream os) { |
| | | exportExcel(list, sheetName, clazz, false, os); |
| | | } |
| | | |
| | | /** |
| | | * 导åºexcel |
| | | * |
| | | * @param list å¯¼åºæ°æ®éå |
| | | * @param sheetName å·¥ä½è¡¨çåç§° |
| | | * @param clazz å®ä½ç±» |
| | | * @param merge æ¯å¦åå¹¶åå
æ ¼ |
| | | * @param os è¾åºæµ |
| | | */ |
| | | public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, OutputStream os) { |
| | | ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz) |
| | | .autoCloseStream(false) |
| | | // èªå¨éé
|
| | | .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) |
| | | // 大æ°å¼èªå¨è½¬æ¢ 鲿¢å¤±ç |
| | | .registerConverter(new ExcelBigNumberConvert()) |
| | | .sheet(sheetName); |
| | | if (merge) { |
| | | // åå¹¶å¤çå¨ |
| | | builder.registerWriteHandler(new CellMergeStrategy(list, true)); |
| | | } |
| | | builder.doWrite(list); |
| | | } |
| | | |
| | | /** |
| | | * åè¡¨å¤æ°æ®æ¨¡æ¿å¯¼åº æ¨¡æ¿æ ¼å¼ä¸º {.屿§} |
| | | * |
| | | * @param filename æä»¶å |
| | | * @param templatePath 模æ¿è·¯å¾ resource ç®å½ä¸çè·¯å¾å
æ¬æ¨¡æ¿æä»¶å |
| | | * ä¾å¦: excel/temp.xlsx |
| | | * éç¹: æ¨¡æ¿æä»¶å¿
é¡»æ¾ç½®å°å¯å¨ç±»å¯¹åºç resource ç®å½ä¸ |
| | | * @param data 模æ¿éè¦çæ°æ® |
| | | * @param response ååºä½ |
| | | */ |
| | | public static void exportTemplate(List<Object> data, String filename, String templatePath, HttpServletResponse response) { |
| | | try { |
| | | resetResponse(filename, response); |
| | | ServletOutputStream os = response.getOutputStream(); |
| | | exportTemplate(data, templatePath, os); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("导åºExcelå¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * åè¡¨å¤æ°æ®æ¨¡æ¿å¯¼åº æ¨¡æ¿æ ¼å¼ä¸º {.屿§} |
| | | * |
| | | * @param templatePath 模æ¿è·¯å¾ resource ç®å½ä¸çè·¯å¾å
æ¬æ¨¡æ¿æä»¶å |
| | | * ä¾å¦: excel/temp.xlsx |
| | | * éç¹: æ¨¡æ¿æä»¶å¿
é¡»æ¾ç½®å°å¯å¨ç±»å¯¹åºç resource ç®å½ä¸ |
| | | * @param data 模æ¿éè¦çæ°æ® |
| | | * @param os è¾åºæµ |
| | | */ |
| | | public static void exportTemplate(List<Object> data, String templatePath, OutputStream os) { |
| | | ClassPathResource templateResource = new ClassPathResource(templatePath); |
| | | ExcelWriter excelWriter = EasyExcel.write(os) |
| | | .withTemplate(templateResource.getStream()) |
| | | .autoCloseStream(false) |
| | | // 大æ°å¼èªå¨è½¬æ¢ 鲿¢å¤±ç |
| | | .registerConverter(new ExcelBigNumberConvert()) |
| | | .build(); |
| | | WriteSheet writeSheet = EasyExcel.writerSheet().build(); |
| | | if (CollUtil.isEmpty(data)) { |
| | | throw new IllegalArgumentException("æ°æ®ä¸ºç©º"); |
| | | } |
| | | // åè¡¨å¤æ°æ®å¯¼åº æ¨¡æ¿æ ¼å¼ä¸º {.屿§} |
| | | for (Object d : data) { |
| | | excelWriter.fill(d, writeSheet); |
| | | } |
| | | excelWriter.finish(); |
| | | } |
| | | |
| | | /** |
| | | * å¤è¡¨å¤æ°æ®æ¨¡æ¿å¯¼åº æ¨¡æ¿æ ¼å¼ä¸º {key.屿§} |
| | | * |
| | | * @param filename æä»¶å |
| | | * @param templatePath 模æ¿è·¯å¾ resource ç®å½ä¸çè·¯å¾å
æ¬æ¨¡æ¿æä»¶å |
| | | * ä¾å¦: excel/temp.xlsx |
| | | * éç¹: æ¨¡æ¿æä»¶å¿
é¡»æ¾ç½®å°å¯å¨ç±»å¯¹åºç resource ç®å½ä¸ |
| | | * @param data 模æ¿éè¦çæ°æ® |
| | | * @param response ååºä½ |
| | | */ |
| | | public static void exportTemplateMultiList(Map<String, Object> data, String filename, String templatePath, HttpServletResponse response) { |
| | | try { |
| | | resetResponse(filename, response); |
| | | ServletOutputStream os = response.getOutputStream(); |
| | | exportTemplateMultiList(data, templatePath, os); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("导åºExcelå¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤è¡¨å¤æ°æ®æ¨¡æ¿å¯¼åº æ¨¡æ¿æ ¼å¼ä¸º {key.屿§} |
| | | * |
| | | * @param templatePath 模æ¿è·¯å¾ resource ç®å½ä¸çè·¯å¾å
æ¬æ¨¡æ¿æä»¶å |
| | | * ä¾å¦: excel/temp.xlsx |
| | | * éç¹: æ¨¡æ¿æä»¶å¿
é¡»æ¾ç½®å°å¯å¨ç±»å¯¹åºç resource ç®å½ä¸ |
| | | * @param data 模æ¿éè¦çæ°æ® |
| | | * @param os è¾åºæµ |
| | | */ |
| | | public static void exportTemplateMultiList(Map<String, Object> data, String templatePath, OutputStream os) { |
| | | ClassPathResource templateResource = new ClassPathResource(templatePath); |
| | | ExcelWriter excelWriter = EasyExcel.write(os) |
| | | .withTemplate(templateResource.getStream()) |
| | | .autoCloseStream(false) |
| | | // 大æ°å¼èªå¨è½¬æ¢ 鲿¢å¤±ç |
| | | .registerConverter(new ExcelBigNumberConvert()) |
| | | .build(); |
| | | WriteSheet writeSheet = EasyExcel.writerSheet().build(); |
| | | if (CollUtil.isEmpty(data)) { |
| | | throw new IllegalArgumentException("æ°æ®ä¸ºç©º"); |
| | | } |
| | | for (Map.Entry<String, Object> map : data.entrySet()) { |
| | | // 设置å表åç»è¿ææ°æ® |
| | | FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); |
| | | if (map.getValue() instanceof Collection) { |
| | | // å¤è¡¨å¯¼åºå¿
é¡»ä½¿ç¨ FillWrapper |
| | | excelWriter.fill(new FillWrapper(map.getKey(), (Collection<?>) map.getValue()), fillConfig, writeSheet); |
| | | } else { |
| | | excelWriter.fill(map.getValue(), writeSheet); |
| | | } |
| | | } |
| | | excelWriter.finish(); |
| | | } |
| | | |
| | | /** |
| | | * éç½®ååºä½ |
| | | */ |
| | | private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException { |
| | | String filename = encodingFilename(sheetName); |
| | | FileUtils.setAttachmentResponseHeader(response, filename); |
| | | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); |
| | | } |
| | | |
| | | /** |
| | | * è§£æå¯¼åºå¼ 0=ç·,1=女,2=æªç¥ |
| | | * |
| | | * @param propertyValue åæ°å¼ |
| | | * @param converterExp ç¿»è¯æ³¨è§£ |
| | | * @param separator åé符 |
| | | * @return è§£æåå¼ |
| | | */ |
| | | public static String convertByExp(String propertyValue, String converterExp, String separator) { |
| | | StringBuilder propertyString = new StringBuilder(); |
| | | String[] convertSource = converterExp.split(","); |
| | | for (String item : convertSource) { |
| | | String[] itemArray = item.split("="); |
| | | if (StringUtils.containsAny(propertyValue, separator)) { |
| | | for (String value : propertyValue.split(separator)) { |
| | | if (itemArray[0].equals(value)) { |
| | | propertyString.append(itemArray[1] + separator); |
| | | break; |
| | | } |
| | | } |
| | | } else { |
| | | if (itemArray[0].equals(propertyValue)) { |
| | | return itemArray[1]; |
| | | } |
| | | } |
| | | } |
| | | return StringUtils.stripEnd(propertyString.toString(), separator); |
| | | } |
| | | |
| | | /** |
| | | * ååè§£æå¼ ç·=0,女=1,æªç¥=2 |
| | | * |
| | | * @param propertyValue åæ°å¼ |
| | | * @param converterExp ç¿»è¯æ³¨è§£ |
| | | * @param separator åé符 |
| | | * @return è§£æåå¼ |
| | | */ |
| | | public static String reverseByExp(String propertyValue, String converterExp, String separator) { |
| | | StringBuilder propertyString = new StringBuilder(); |
| | | String[] convertSource = converterExp.split(","); |
| | | for (String item : convertSource) { |
| | | String[] itemArray = item.split("="); |
| | | if (StringUtils.containsAny(propertyValue, separator)) { |
| | | for (String value : propertyValue.split(separator)) { |
| | | if (itemArray[1].equals(value)) { |
| | | propertyString.append(itemArray[0] + separator); |
| | | break; |
| | | } |
| | | } |
| | | } else { |
| | | if (itemArray[1].equals(propertyValue)) { |
| | | return itemArray[0]; |
| | | } |
| | | } |
| | | } |
| | | return StringUtils.stripEnd(propertyString.toString(), separator); |
| | | } |
| | | |
| | | /** |
| | | * ç¼ç æä»¶å |
| | | */ |
| | | public static String encodingFilename(String filename) { |
| | | return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx"; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-idempotent</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-idempotent å¹çåè½ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-crypto</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-core</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.idempotent.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * èªå®ä¹æ³¨è§£é²æ¢è¡¨åéå¤æäº¤ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Inherited |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface RepeatSubmit { |
| | | |
| | | /** |
| | | * é´éæ¶é´(ms)ï¼å°äºæ¤æ¶é´è§ä¸ºéå¤æäº¤ |
| | | */ |
| | | int interval() default 5000; |
| | | |
| | | TimeUnit timeUnit() default TimeUnit.MILLISECONDS; |
| | | |
| | | /** |
| | | * æç¤ºæ¶æ¯ æ¯æå½é
å æ ¼å¼ä¸º {code} |
| | | */ |
| | | String message() default "{repeat.submit.message}"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.idempotent.aspectj; |
| | | |
| | | import cn.dev33.satoken.SaManager; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.MessageUtils; |
| | | import com.ruoyi.common.core.utils.ServletUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.idempotent.annotation.RepeatSubmit; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.springframework.validation.BindingResult; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.time.Duration; |
| | | import java.util.Collection; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 鲿¢éå¤æäº¤(åèç¾å¢GTISé²éç³»ç») |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Aspect |
| | | public class RepeatSubmitAspect { |
| | | |
| | | private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>(); |
| | | |
| | | @Before("@annotation(repeatSubmit)") |
| | | public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable { |
| | | // å¦ææ³¨è§£ä¸ä¸º0 åä½¿ç¨æ³¨è§£æ°å¼ |
| | | long interval = 0; |
| | | if (repeatSubmit.interval() > 0) { |
| | | interval = repeatSubmit.timeUnit().toMillis(repeatSubmit.interval()); |
| | | } |
| | | if (interval < 1000) { |
| | | throw new ServiceException("éå¤æäº¤é´éæ¶é´ä¸è½å°äº'1'ç§"); |
| | | } |
| | | HttpServletRequest request = ServletUtils.getRequest(); |
| | | String nowParams = argsArrayToString(point.getArgs()); |
| | | |
| | | // 请æ±å°åï¼ä½ä¸ºåæ¾cacheçkeyå¼ï¼ |
| | | String url = request.getRequestURI(); |
| | | |
| | | // å¯ä¸å¼ï¼æ²¡ææ¶æ¯å¤´å使ç¨è¯·æ±å°åï¼ |
| | | String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName())); |
| | | |
| | | submitKey = SecureUtil.md5(submitKey + ":" + nowParams); |
| | | // å¯ä¸æ è¯ï¼æå®key + url + æ¶æ¯å¤´ï¼ |
| | | String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; |
| | | String key = RedisUtils.getCacheObject(cacheRepeatKey); |
| | | if (key == null) { |
| | | RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval)); |
| | | KEY_CACHE.set(cacheRepeatKey); |
| | | } else { |
| | | String message = repeatSubmit.message(); |
| | | if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) { |
| | | message = MessageUtils.message(StringUtils.substring(message, 1, message.length() - 1)); |
| | | } |
| | | throw new ServiceException(message); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤çå®è¯·æ±åæ§è¡ |
| | | * |
| | | * @param joinPoint åç¹ |
| | | */ |
| | | @AfterReturning(pointcut = "@annotation(repeatSubmit)", returning = "jsonResult") |
| | | public void doAfterReturning(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Object jsonResult) { |
| | | if (jsonResult instanceof R) { |
| | | try { |
| | | R<?> r = (R<?>) jsonResult; |
| | | // æååä¸å é¤redisæ°æ® ä¿è¯å¨æææ¶é´å
æ æ³éå¤æäº¤ |
| | | if (r.getCode() == R.SUCCESS) { |
| | | return; |
| | | } |
| | | RedisUtils.deleteObject(KEY_CACHE.get()); |
| | | } finally { |
| | | KEY_CACHE.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¦æªå¼å¸¸æä½ |
| | | * |
| | | * @param joinPoint åç¹ |
| | | * @param e å¼å¸¸ |
| | | */ |
| | | @AfterThrowing(value = "@annotation(repeatSubmit)", throwing = "e") |
| | | public void doAfterThrowing(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Exception e) { |
| | | RedisUtils.deleteObject(KEY_CACHE.get()); |
| | | KEY_CACHE.remove(); |
| | | } |
| | | |
| | | /** |
| | | * åæ°æ¼è£
|
| | | */ |
| | | private String argsArrayToString(Object[] paramsArray) { |
| | | StringBuilder params = new StringBuilder(); |
| | | if (paramsArray != null && paramsArray.length > 0) { |
| | | for (Object o : paramsArray) { |
| | | if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) { |
| | | try { |
| | | params.append(JsonUtils.toJsonString(o)).append(" "); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return params.toString().trim(); |
| | | } |
| | | |
| | | /** |
| | | * 夿æ¯å¦éè¦è¿æ»¤ç对象ã |
| | | * |
| | | * @param o 对象信æ¯ã |
| | | * @return 妿æ¯éè¦è¿æ»¤ç对象ï¼åè¿åtrueï¼å¦åè¿åfalseã |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public boolean isFilterObject(final Object o) { |
| | | Class<?> clazz = o.getClass(); |
| | | if (clazz.isArray()) { |
| | | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); |
| | | } else if (Collection.class.isAssignableFrom(clazz)) { |
| | | Collection collection = (Collection) o; |
| | | for (Object value : collection) { |
| | | return value instanceof MultipartFile; |
| | | } |
| | | } else if (Map.class.isAssignableFrom(clazz)) { |
| | | Map map = (Map) o; |
| | | for (Object value : map.entrySet()) { |
| | | Map.Entry entry = (Map.Entry) value; |
| | | return entry.getValue() instanceof MultipartFile; |
| | | } |
| | | } |
| | | return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse |
| | | || o instanceof BindingResult; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.idempotent.config; |
| | | |
| | | import com.ruoyi.common.idempotent.aspectj.RepeatSubmitAspect; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.data.redis.connection.RedisConfiguration; |
| | | |
| | | /** |
| | | * å¹çåè½é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration(after = RedisConfiguration.class) |
| | | public class IdempotentConfig { |
| | | |
| | | @Bean |
| | | public RepeatSubmitAspect repeatSubmitAspect() { |
| | | return new RepeatSubmitAspect(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.idempotent.config.IdempotentConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-log æ¥å¿è®°å½ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.annotation; |
| | | |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.log.enums.OperatorType; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * èªå®ä¹æä½æ¥å¿è®°å½æ³¨è§£ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Target({ElementType.PARAMETER, ElementType.METHOD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface Log { |
| | | /** |
| | | * 模å |
| | | */ |
| | | String title() default ""; |
| | | |
| | | /** |
| | | * åè½ |
| | | */ |
| | | BusinessType businessType() default BusinessType.OTHER; |
| | | |
| | | /** |
| | | * æä½äººç±»å« |
| | | */ |
| | | OperatorType operatorType() default OperatorType.MANAGE; |
| | | |
| | | /** |
| | | * æ¯å¦ä¿å请æ±çåæ° |
| | | */ |
| | | boolean isSaveRequestData() default true; |
| | | |
| | | /** |
| | | * æ¯å¦ä¿åååºçåæ° |
| | | */ |
| | | boolean isSaveResponseData() default true; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.aspect; |
| | | |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.ServletUtils; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.log.enums.BusinessStatus; |
| | | import com.ruoyi.common.log.event.OperLogEvent; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.validation.BindingResult; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.Collection; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æä½æ¥å¿è®°å½å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @Aspect |
| | | @AutoConfiguration |
| | | public class LogAspect { |
| | | |
| | | /** |
| | | * æé¤ææå±æ§å段 |
| | | */ |
| | | public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; |
| | | |
| | | /** |
| | | * å¤çå®è¯·æ±åæ§è¡ |
| | | * |
| | | * @param joinPoint åç¹ |
| | | */ |
| | | @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") |
| | | public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) { |
| | | handleLog(joinPoint, controllerLog, null, jsonResult); |
| | | } |
| | | |
| | | /** |
| | | * æ¦æªå¼å¸¸æä½ |
| | | * |
| | | * @param joinPoint åç¹ |
| | | * @param e å¼å¸¸ |
| | | */ |
| | | @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") |
| | | public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) { |
| | | handleLog(joinPoint, controllerLog, e, null); |
| | | } |
| | | |
| | | protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) { |
| | | try { |
| | | |
| | | // *========æ°æ®åºæ¥å¿=========*// |
| | | OperLogEvent operLog = new OperLogEvent(); |
| | | operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); |
| | | // 请æ±çå°å |
| | | String ip = ServletUtils.getClientIP(); |
| | | operLog.setOperIp(ip); |
| | | operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); |
| | | operLog.setOperName(LoginHelper.getUsername()); |
| | | |
| | | if (e != null) { |
| | | operLog.setStatus(BusinessStatus.FAIL.ordinal()); |
| | | operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); |
| | | } |
| | | // è®¾ç½®æ¹æ³åç§° |
| | | String className = joinPoint.getTarget().getClass().getName(); |
| | | String methodName = joinPoint.getSignature().getName(); |
| | | operLog.setMethod(className + "." + methodName + "()"); |
| | | // è®¾ç½®è¯·æ±æ¹å¼ |
| | | operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); |
| | | // å¤ç设置注解ä¸çåæ° |
| | | getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); |
| | | // åå¸äºä»¶ä¿åæ°æ®åº |
| | | SpringUtils.context().publishEvent(operLog); |
| | | } catch (Exception exp) { |
| | | // è®°å½æ¬å°å¼å¸¸æ¥å¿ |
| | | log.error("å¼å¸¸ä¿¡æ¯:{}", exp.getMessage()); |
| | | exp.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å注解ä¸å¯¹æ¹æ³çæè¿°ä¿¡æ¯ ç¨äºController屿³¨è§£ |
| | | * |
| | | * @param log æ¥å¿ |
| | | * @param operLog æä½æ¥å¿ |
| | | * @throws Exception |
| | | */ |
| | | public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception { |
| | | // 设置actionå¨ä½ |
| | | operLog.setBusinessType(log.businessType().ordinal()); |
| | | // 设置æ é¢ |
| | | operLog.setTitle(log.title()); |
| | | // 设置æä½äººç±»å« |
| | | operLog.setOperatorType(log.operatorType().ordinal()); |
| | | // æ¯å¦éè¦ä¿årequestï¼åæ°åå¼ |
| | | if (log.isSaveRequestData()) { |
| | | // è·ååæ°çä¿¡æ¯ï¼ä¼ å
¥å°æ°æ®åºä¸ã |
| | | setRequestValue(joinPoint, operLog); |
| | | } |
| | | // æ¯å¦éè¦ä¿åresponseï¼åæ°åå¼ |
| | | if (log.isSaveResponseData() && ObjectUtil.isNotNull(jsonResult)) { |
| | | operLog.setJsonResult(StringUtils.substring(JsonUtils.toJsonString(jsonResult), 0, 2000)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å请æ±çåæ°ï¼æ¾å°logä¸ |
| | | * |
| | | * @param operLog æä½æ¥å¿ |
| | | * @throws Exception å¼å¸¸ |
| | | */ |
| | | private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog) throws Exception { |
| | | String requestMethod = operLog.getRequestMethod(); |
| | | if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) { |
| | | String params = argsArrayToString(joinPoint.getArgs()); |
| | | operLog.setOperParam(StringUtils.substring(params, 0, 2000)); |
| | | } else { |
| | | Map<String, String> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); |
| | | MapUtil.removeAny(paramsMap, EXCLUDE_PROPERTIES); |
| | | operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 2000)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * åæ°æ¼è£
|
| | | */ |
| | | private String argsArrayToString(Object[] paramsArray) { |
| | | StringBuilder params = new StringBuilder(); |
| | | if (paramsArray != null && paramsArray.length > 0) { |
| | | for (Object o : paramsArray) { |
| | | if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) { |
| | | try { |
| | | String str = JsonUtils.toJsonString(o); |
| | | Dict dict = JsonUtils.parseMap(str); |
| | | if (MapUtil.isNotEmpty(dict)) { |
| | | MapUtil.removeAny(dict, EXCLUDE_PROPERTIES); |
| | | str = JsonUtils.toJsonString(dict); |
| | | } |
| | | params.append(str).append(" "); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return params.toString().trim(); |
| | | } |
| | | |
| | | /** |
| | | * 夿æ¯å¦éè¦è¿æ»¤ç对象ã |
| | | * |
| | | * @param o 对象信æ¯ã |
| | | * @return 妿æ¯éè¦è¿æ»¤ç对象ï¼åè¿åtrueï¼å¦åè¿åfalseã |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public boolean isFilterObject(final Object o) { |
| | | Class<?> clazz = o.getClass(); |
| | | if (clazz.isArray()) { |
| | | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); |
| | | } else if (Collection.class.isAssignableFrom(clazz)) { |
| | | Collection collection = (Collection) o; |
| | | for (Object value : collection) { |
| | | return value instanceof MultipartFile; |
| | | } |
| | | } else if (Map.class.isAssignableFrom(clazz)) { |
| | | Map map = (Map) o; |
| | | for (Object value : map.entrySet()) { |
| | | Map.Entry entry = (Map.Entry) value; |
| | | return entry.getValue() instanceof MultipartFile; |
| | | } |
| | | } |
| | | return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse |
| | | || o instanceof BindingResult; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.enums; |
| | | |
| | | /** |
| | | * æä½ç¶æ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum BusinessStatus { |
| | | /** |
| | | * æå |
| | | */ |
| | | SUCCESS, |
| | | |
| | | /** |
| | | * 失败 |
| | | */ |
| | | FAIL, |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.enums; |
| | | |
| | | /** |
| | | * ä¸å¡æä½ç±»å |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum BusinessType { |
| | | /** |
| | | * å
¶å® |
| | | */ |
| | | OTHER, |
| | | |
| | | /** |
| | | * æ°å¢ |
| | | */ |
| | | INSERT, |
| | | |
| | | /** |
| | | * ä¿®æ¹ |
| | | */ |
| | | UPDATE, |
| | | |
| | | /** |
| | | * å é¤ |
| | | */ |
| | | DELETE, |
| | | |
| | | /** |
| | | * ææ |
| | | */ |
| | | GRANT, |
| | | |
| | | /** |
| | | * å¯¼åº |
| | | */ |
| | | EXPORT, |
| | | |
| | | /** |
| | | * 导å
¥ |
| | | */ |
| | | IMPORT, |
| | | |
| | | /** |
| | | * 强é |
| | | */ |
| | | FORCE, |
| | | |
| | | /** |
| | | * çæä»£ç |
| | | */ |
| | | GENCODE, |
| | | |
| | | /** |
| | | * æ¸
ç©ºæ°æ® |
| | | */ |
| | | CLEAN, |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.enums; |
| | | |
| | | /** |
| | | * æä½äººç±»å« |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum OperatorType { |
| | | /** |
| | | * å
¶å® |
| | | */ |
| | | OTHER, |
| | | |
| | | /** |
| | | * åå°ç¨æ· |
| | | */ |
| | | MANAGE, |
| | | |
| | | /** |
| | | * ææºç«¯ç¨æ· |
| | | */ |
| | | MOBILE |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.event; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç»å½äºä»¶ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class LogininforEvent implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¨æ·è´¦å· |
| | | */ |
| | | private String username; |
| | | |
| | | /** |
| | | * ç»å½ç¶æ 0æå 1失败 |
| | | */ |
| | | private String status; |
| | | |
| | | /** |
| | | * æç¤ºæ¶æ¯ |
| | | */ |
| | | private String message; |
| | | |
| | | /** |
| | | * 请æ±ä½ |
| | | */ |
| | | private HttpServletRequest request; |
| | | |
| | | /** |
| | | * å
¶ä»åæ° |
| | | */ |
| | | private Object[] args; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.log.event; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æä½æ¥å¿äºä»¶ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class OperLogEvent implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æ¥å¿ä¸»é® |
| | | */ |
| | | private Long operId; |
| | | |
| | | /** |
| | | * æä½æ¨¡å |
| | | */ |
| | | private String title; |
| | | |
| | | /** |
| | | * ä¸å¡ç±»åï¼0å
¶å® 1æ°å¢ 2ä¿®æ¹ 3å é¤ï¼ |
| | | */ |
| | | private Integer businessType; |
| | | |
| | | /** |
| | | * ä¸å¡ç±»åæ°ç» |
| | | */ |
| | | private Integer[] businessTypes; |
| | | |
| | | /** |
| | | * è¯·æ±æ¹æ³ |
| | | */ |
| | | private String method; |
| | | |
| | | /** |
| | | * è¯·æ±æ¹å¼ |
| | | */ |
| | | private String requestMethod; |
| | | |
| | | /** |
| | | * æä½ç±»å«ï¼0å
¶å® 1åå°ç¨æ· 2ææºç«¯ç¨æ·ï¼ |
| | | */ |
| | | private Integer operatorType; |
| | | |
| | | /** |
| | | * æä½äººå |
| | | */ |
| | | private String operName; |
| | | |
| | | /** |
| | | * é¨é¨åç§° |
| | | */ |
| | | private String deptName; |
| | | |
| | | /** |
| | | * 请æ±url |
| | | */ |
| | | private String operUrl; |
| | | |
| | | /** |
| | | * æä½å°å |
| | | */ |
| | | private String operIp; |
| | | |
| | | /** |
| | | * æä½å°ç¹ |
| | | */ |
| | | private String operLocation; |
| | | |
| | | /** |
| | | * 请æ±åæ° |
| | | */ |
| | | private String operParam; |
| | | |
| | | /** |
| | | * è¿ååæ° |
| | | */ |
| | | private String jsonResult; |
| | | |
| | | /** |
| | | * æä½ç¶æï¼0æ£å¸¸ 1å¼å¸¸ï¼ |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * éè¯¯æ¶æ¯ |
| | | */ |
| | | private String errorMsg; |
| | | |
| | | /** |
| | | * æä½æ¶é´ |
| | | */ |
| | | private Date operTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.log.aspect.LogAspect |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-mail</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-mail é®ä»¶æ¨¡å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>jakarta.mail</groupId> |
| | | <artifactId>jakarta.mail-api</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mail.config; |
| | | |
| | | import cn.hutool.extra.mail.MailAccount; |
| | | import com.ruoyi.common.mail.config.properties.MailProperties; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | /** |
| | | * JavaMail é
ç½® |
| | | * |
| | | * @author Michelle.Chung |
| | | */ |
| | | @AutoConfiguration |
| | | @ConditionalOnProperty(value = "mail.enabled", havingValue = "true") |
| | | @EnableConfigurationProperties(MailProperties.class) |
| | | public class MailConfig { |
| | | |
| | | @Bean |
| | | public MailAccount mailAccount(MailProperties mailProperties) { |
| | | MailAccount account = new MailAccount(); |
| | | account.setHost(mailProperties.getHost()); |
| | | account.setPort(mailProperties.getPort()); |
| | | account.setAuth(mailProperties.getAuth()); |
| | | account.setFrom(mailProperties.getFrom()); |
| | | account.setUser(mailProperties.getUser()); |
| | | account.setPass(mailProperties.getPass()); |
| | | account.setSocketFactoryPort(mailProperties.getPort()); |
| | | account.setStarttlsEnable(mailProperties.getStarttlsEnable()); |
| | | account.setSslEnable(mailProperties.getSslEnable()); |
| | | account.setTimeout(mailProperties.getTimeout()); |
| | | account.setConnectionTimeout(mailProperties.getConnectionTimeout()); |
| | | return account; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mail.config.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * JavaMail é
ç½®å±æ§ |
| | | * |
| | | * @author Michelle.Chung |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "mail") |
| | | public class MailProperties { |
| | | |
| | | /** |
| | | * è¿æ»¤å¼å
³ |
| | | */ |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * SMTPæå¡å¨åå |
| | | */ |
| | | private String host; |
| | | |
| | | /** |
| | | * SMTPæå¡ç«¯å£ |
| | | */ |
| | | private Integer port; |
| | | |
| | | /** |
| | | * æ¯å¦éè¦ç¨æ·åå¯ç éªè¯ |
| | | */ |
| | | private Boolean auth; |
| | | |
| | | /** |
| | | * ç¨æ·å |
| | | */ |
| | | private String user; |
| | | |
| | | /** |
| | | * å¯ç |
| | | */ |
| | | private String pass; |
| | | |
| | | /** |
| | | * åéæ¹ï¼éµå¾ªRFC-822æ å |
| | | */ |
| | | private String from; |
| | | |
| | | /** |
| | | * ä½¿ç¨ STARTTLSå®å
¨è¿æ¥ï¼STARTTLSæ¯å¯¹çº¯ææ¬éä¿¡åè®®çæ©å±ãå®å°çº¯ææ¬è¿æ¥å级为å å¯è¿æ¥ï¼TLSæSSLï¼ï¼ è䏿¯ä½¿ç¨ä¸ä¸ªåç¬çå å¯é信端å£ã |
| | | */ |
| | | private Boolean starttlsEnable; |
| | | |
| | | /** |
| | | * ä½¿ç¨ SSLå®å
¨è¿æ¥ |
| | | */ |
| | | private Boolean sslEnable; |
| | | |
| | | /** |
| | | * SMTPè¶
æ¶æ¶é¿ï¼å使¯«ç§ï¼ç¼ºçå¼ä¸è¶
æ¶ |
| | | */ |
| | | private Long timeout; |
| | | |
| | | /** |
| | | * Socketè¿æ¥è¶
æ¶å¼ï¼å使¯«ç§ï¼ç¼ºçå¼ä¸è¶
æ¶ |
| | | */ |
| | | private Long connectionTimeout; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mail.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.CharUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.extra.mail.*; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import jakarta.mail.Authenticator; |
| | | import jakarta.mail.Session; |
| | | import java.io.File; |
| | | import java.io.InputStream; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | /** |
| | | * é®ä»¶å·¥å
·ç±» |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class MailUtils { |
| | | |
| | | private static final MailAccount ACCOUNT = SpringUtils.getBean(MailAccount.class); |
| | | |
| | | /** |
| | | * è·åé®ä»¶åéå®ä¾ |
| | | */ |
| | | public static MailAccount getMailAccount() { |
| | | return ACCOUNT; |
| | | } |
| | | |
| | | /** |
| | | * è·åé®ä»¶åéå®ä¾ (èªå®ä¹åéäººä»¥åææç ) |
| | | * |
| | | * @param user åé人 |
| | | * @param pass ææç |
| | | */ |
| | | public static MailAccount getMailAccount(String from, String user, String pass) { |
| | | ACCOUNT.setFrom(StringUtils.blankToDefault(from, ACCOUNT.getFrom())); |
| | | ACCOUNT.setUser(StringUtils.blankToDefault(user, ACCOUNT.getUser())); |
| | | ACCOUNT.setPass(StringUtils.blankToDefault(pass, ACCOUNT.getPass())); |
| | | return ACCOUNT; |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéææ¬é®ä»¶ï¼åéç»å个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººå¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äºº |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String sendText(String to, String subject, String content, File... files) { |
| | | return send(to, subject, content, false, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéHTMLé®ä»¶ï¼åéç»å个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººå¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äºº |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String sendHtml(String to, String subject, String content, File... files) { |
| | | return send(to, subject, content, true, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéå个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººå¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äºº |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | */ |
| | | public static String send(String to, String subject, String content, boolean isHtml, File... files) { |
| | | return send(splitAddress(to), subject, content, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéå个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººãæé人ãå¯é人å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äººï¼å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * @param cc æé人ï¼å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * @param bcc å¯é人ï¼å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.0.3 |
| | | */ |
| | | public static String send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) { |
| | | return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéææ¬é®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | */ |
| | | public static String sendText(Collection<String> tos, String subject, String content, File... files) { |
| | | return send(tos, subject, content, false, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéHTMLé®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String sendHtml(Collection<String> tos, String subject, String content, File... files) { |
| | | return send(tos, subject, content, true, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | */ |
| | | public static String send(Collection<String> tos, String subject, String content, boolean isHtml, File... files) { |
| | | return send(tos, null, null, subject, content, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param ccs æé人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param bccs å¯é人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.0.3 |
| | | */ |
| | | public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) { |
| | | return send(getMailAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files); |
| | | } |
| | | |
| | | // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶è®¤è¯å¯¹è±¡ |
| | | * @param to æ¶ä»¶äººï¼å¤ä¸ªæ¶ä»¶äººéå·æè
åå·éå¼ |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) { |
| | | return send(mailAccount, splitAddress(to), subject, content, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶å¸æ·ä¿¡æ¯ |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | */ |
| | | public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, boolean isHtml, File... files) { |
| | | return send(mailAccount, tos, null, null, subject, content, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶å¸æ·ä¿¡æ¯ |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param ccs æé人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param bccs å¯é人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.0.3 |
| | | */ |
| | | public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) { |
| | | return send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéHTMLé®ä»¶ï¼åéç»å个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººå¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äºº |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String sendHtml(String to, String subject, String content, Map<String, InputStream> imageMap, File... files) { |
| | | return send(to, subject, content, imageMap, true, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéå个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººå¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äºº |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | */ |
| | | public static String send(String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | return send(splitAddress(to), subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéå个æå¤ä¸ªæ¶ä»¶äºº<br> |
| | | * å¤ä¸ªæ¶ä»¶äººãæé人ãå¯é人å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * |
| | | * @param to æ¶ä»¶äººï¼å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * @param cc æé人ï¼å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * @param bcc å¯é人ï¼å¯ä»¥ä½¿ç¨éå·â,âåéï¼ä¹å¯ä»¥éè¿åå·â;âåé |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.0.3 |
| | | */ |
| | | public static String send(String to, String cc, String bcc, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéHTMLé®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String sendHtml(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, File... files) { |
| | | return send(tos, subject, content, imageMap, true, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | */ |
| | | public static String send(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | return send(tos, null, null, subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨é
ç½®æä»¶ä¸è®¾ç½®çè´¦æ·åéé®ä»¶ï¼åéç»å¤äºº |
| | | * |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param ccs æé人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param bccs å¯é人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTML |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.0.3 |
| | | */ |
| | | public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | return send(getMailAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶è®¤è¯å¯¹è±¡ |
| | | * @param to æ¶ä»¶äººï¼å¤ä¸ªæ¶ä»¶äººéå·æè
åå·éå¼ |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 3.2.0 |
| | | */ |
| | | public static String send(MailAccount mailAccount, String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | return send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶å¸æ·ä¿¡æ¯ |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.6.3 |
| | | */ |
| | | public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | return send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶å¸æ·ä¿¡æ¯ |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param ccs æé人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param bccs å¯é人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:$IMAGE_PLACEHOLDER |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.6.3 |
| | | */ |
| | | public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap, |
| | | boolean isHtml, File... files) { |
| | | return send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®é
ç½®æä»¶ï¼è·åé®ä»¶å®¢æ·ç«¯ä¼è¯ |
| | | * |
| | | * @param mailAccount é®ä»¶è´¦æ·é
ç½® |
| | | * @param isSingleton æ¯å¦åä¾ï¼å
¨å±å
±äº«ä¼è¯ï¼ |
| | | * @return {@link Session} |
| | | * @since 5.5.7 |
| | | */ |
| | | public static Session getSession(MailAccount mailAccount, boolean isSingleton) { |
| | | Authenticator authenticator = null; |
| | | if (mailAccount.isAuth()) { |
| | | authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); |
| | | } |
| | | |
| | | return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) // |
| | | : Session.getInstance(mailAccount.getSmtpProps(), authenticator); |
| | | } |
| | | |
| | | // ------------------------------------------------------------------------------------------------------------------------ Private method start |
| | | |
| | | /** |
| | | * åéé®ä»¶ç»å¤äºº |
| | | * |
| | | * @param mailAccount é®ä»¶å¸æ·ä¿¡æ¯ |
| | | * @param useGlobalSession æ¯å¦å
¨å±å
񄧮Session |
| | | * @param tos æ¶ä»¶äººå表 |
| | | * @param ccs æé人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param bccs å¯é人å表ï¼å¯ä»¥ä¸ºnullæç©º |
| | | * @param subject æ é¢ |
| | | * @param content æ£æ |
| | | * @param imageMap å¾çä¸å ä½ç¬¦ï¼å ä½ç¬¦æ ¼å¼ä¸ºcid:${cid} |
| | | * @param isHtml æ¯å¦ä¸ºHTMLæ ¼å¼ |
| | | * @param files éä»¶å表 |
| | | * @return message-id |
| | | * @since 4.6.3 |
| | | */ |
| | | private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, |
| | | Map<String, InputStream> imageMap, boolean isHtml, File... files) { |
| | | final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession); |
| | | |
| | | // å¯éæé人 |
| | | if (CollUtil.isNotEmpty(ccs)) { |
| | | mail.setCcs(ccs.toArray(new String[0])); |
| | | } |
| | | // å¯éå¯é人 |
| | | if (CollUtil.isNotEmpty(bccs)) { |
| | | mail.setBccs(bccs.toArray(new String[0])); |
| | | } |
| | | |
| | | mail.setTos(tos.toArray(new String[0])); |
| | | mail.setTitle(subject); |
| | | mail.setContent(content); |
| | | mail.setHtml(isHtml); |
| | | mail.setFiles(files); |
| | | |
| | | // å¾ç |
| | | if (MapUtil.isNotEmpty(imageMap)) { |
| | | for (Map.Entry<String, InputStream> entry : imageMap.entrySet()) { |
| | | mail.addImage(entry.getKey(), entry.getValue()); |
| | | // å
³éæµ |
| | | IoUtil.close(entry.getValue()); |
| | | } |
| | | } |
| | | |
| | | return mail.send(); |
| | | } |
| | | |
| | | /** |
| | | * å°å¤ä¸ªè系人转为å表ï¼åé符为éå·æè
åå· |
| | | * |
| | | * @param addresses å¤ä¸ªè系人ï¼å¦æä¸ºç©ºè¿ånull |
| | | * @return è系人å表 |
| | | */ |
| | | private static List<String> splitAddress(String addresses) { |
| | | if (StrUtil.isBlank(addresses)) { |
| | | return null; |
| | | } |
| | | |
| | | List<String> result; |
| | | if (StrUtil.contains(addresses, CharUtil.COMMA)) { |
| | | result = StrUtil.splitTrim(addresses, CharUtil.COMMA); |
| | | } else if (StrUtil.contains(addresses, ';')) { |
| | | result = StrUtil.splitTrim(addresses, ';'); |
| | | } else { |
| | | result = CollUtil.newArrayList(addresses); |
| | | } |
| | | return result; |
| | | } |
| | | // ------------------------------------------------------------------------------------------------------------------------ Private method end |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mail.utils; |
| | | |
| | | import jakarta.mail.Authenticator; |
| | | import jakarta.mail.PasswordAuthentication; |
| | | |
| | | /** |
| | | * ç¨æ·åå¯ç éªè¯å¨ |
| | | * |
| | | * @author looly |
| | | * @since 3.1.2 |
| | | */ |
| | | public class UserPassAuthenticator extends Authenticator { |
| | | |
| | | private final String user; |
| | | private final String pass; |
| | | |
| | | /** |
| | | * æé |
| | | * |
| | | * @param user ç¨æ·å |
| | | * @param pass å¯ç |
| | | */ |
| | | public UserPassAuthenticator(String user, String pass) { |
| | | this.user = user; |
| | | this.pass = pass; |
| | | } |
| | | |
| | | @Override |
| | | protected PasswordAuthentication getPasswordAuthentication() { |
| | | return new PasswordAuthentication(this.user, this.pass); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.mail.config.MailConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-mybatis æ°æ®åºæå¡ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- dynamic-datasource 夿°æ®æº--> |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>dynamic-datasource-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- sqlæ§è½åææä»¶ --> |
| | | <dependency> |
| | | <groupId>p6spy</groupId> |
| | | <artifactId>p6spy</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * æ°æ®æé |
| | | * |
| | | * ä¸ä¸ªæ³¨è§£åªè½å¯¹åºä¸ä¸ªæ¨¡æ¿ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface DataColumn { |
| | | |
| | | /** |
| | | * å ä½ç¬¦å
³é®å |
| | | */ |
| | | String[] key() default "deptName"; |
| | | |
| | | /** |
| | | * å ä½ç¬¦æ¿æ¢å¼ |
| | | */ |
| | | String[] value() default "dept_id"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * æ°æ®æéç» |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | @Target({ElementType.METHOD, ElementType.TYPE}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface DataPermission { |
| | | |
| | | DataColumn[] value(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.config; |
| | | |
| | | import cn.hutool.core.net.NetUtil; |
| | | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
| | | import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator; |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
| | | import com.ruoyi.common.mybatis.handler.CreateAndUpdateMetaObjectHandler; |
| | | import com.ruoyi.common.mybatis.interceptor.PlusDataPermissionInterceptor; |
| | | import org.mybatis.spring.annotation.MapperScan; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.transaction.annotation.EnableTransactionManagement; |
| | | |
| | | /** |
| | | * mybatis-plusé
置类(䏿¹æ³¨éææä»¶ä»ç») |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @EnableTransactionManagement(proxyTargetClass = true) |
| | | @AutoConfiguration |
| | | @MapperScan("${mybatis-plus.mapperPackage}") |
| | | public class MybatisPlusConfig { |
| | | |
| | | @Bean |
| | | public MybatisPlusInterceptor mybatisPlusInterceptor() { |
| | | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
| | | // æ°æ®æéå¤ç |
| | | interceptor.addInnerInterceptor(dataPermissionInterceptor()); |
| | | // å页æä»¶ |
| | | interceptor.addInnerInterceptor(paginationInnerInterceptor()); |
| | | // ä¹è§éæä»¶ |
| | | interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor()); |
| | | return interceptor; |
| | | } |
| | | |
| | | /** |
| | | * æ°æ®æéæ¦æªå¨ |
| | | */ |
| | | public PlusDataPermissionInterceptor dataPermissionInterceptor() { |
| | | return new PlusDataPermissionInterceptor(); |
| | | } |
| | | |
| | | /** |
| | | * å页æä»¶ï¼èªå¨è¯å«æ°æ®åºç±»å |
| | | */ |
| | | public PaginationInnerInterceptor paginationInnerInterceptor() { |
| | | PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); |
| | | // 设置æå¤§å页éå¶æ°éï¼é»è®¤ 500 æ¡ï¼-1 ä¸åéå¶ |
| | | paginationInnerInterceptor.setMaxLimit(-1L); |
| | | // å页åçå |
| | | paginationInnerInterceptor.setOverflow(true); |
| | | return paginationInnerInterceptor; |
| | | } |
| | | |
| | | /** |
| | | * ä¹è§éæä»¶ |
| | | */ |
| | | public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() { |
| | | return new OptimisticLockerInnerInterceptor(); |
| | | } |
| | | |
| | | /** |
| | | * å
å¯¹è±¡åæ®µå¡«å
æ§å¶å¨ |
| | | */ |
| | | @Bean |
| | | public MetaObjectHandler metaObjectHandler() { |
| | | return new CreateAndUpdateMetaObjectHandler(); |
| | | } |
| | | |
| | | /** |
| | | * 使ç¨ç½å¡ä¿¡æ¯ç»å®éªè±çæå¨ |
| | | * 鲿¢é群éªè±IDéå¤ |
| | | */ |
| | | @Bean |
| | | public IdentifierGenerator idGenerator() { |
| | | return new DefaultIdentifierGenerator(NetUtil.getLocalhost()); |
| | | } |
| | | |
| | | /** |
| | | * PaginationInnerInterceptor å页æä»¶ï¼èªå¨è¯å«æ°æ®åºç±»å |
| | | * https://baomidou.com/pages/97710a/ |
| | | * OptimisticLockerInnerInterceptor ä¹è§éæä»¶ |
| | | * https://baomidou.com/pages/0d93c0/ |
| | | * MetaObjectHandler å
å¯¹è±¡åæ®µå¡«å
æ§å¶å¨ |
| | | * https://baomidou.com/pages/4c6bcf/ |
| | | * ISqlInjector sql注å
¥å¨ |
| | | * https://baomidou.com/pages/42ea4a/ |
| | | * BlockAttackInnerInterceptor 妿æ¯å¯¹å
¨è¡¨çå é¤ææ´æ°æä½ï¼å°±ä¼ç»æ¢è¯¥æä½ |
| | | * https://baomidou.com/pages/f9a237/ |
| | | * IllegalSQLInnerInterceptor sqlæ§è½è§èæä»¶(åå¾SQLæ¦æª) |
| | | * IdentifierGenerator èªå®ä¹ä¸»é®çç¥ |
| | | * https://baomidou.com/pages/568eb2/ |
| | | * TenantLineInnerInterceptor å¤ç§æ·æä»¶ |
| | | * https://baomidou.com/pages/aef2f2/ |
| | | * DynamicTableNameInnerInterceptor å¨æè¡¨åæä»¶ |
| | | * https://baomidou.com/pages/2a45ff/ |
| | | */ |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.core.mapper; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.*; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.toolkit.Db; |
| | | import com.ruoyi.common.core.utils.BeanCopyUtils; |
| | | import org.apache.ibatis.logging.Log; |
| | | import org.apache.ibatis.logging.LogFactory; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * èªå®ä¹ Mapper æ¥å£, å®ç° èªå®ä¹æ©å± |
| | | * |
| | | * @param <M> mapper æ³å |
| | | * @param <T> table æ³å |
| | | * @param <V> vo æ³å |
| | | * @author Lion Li |
| | | * @since 2021-05-13 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> { |
| | | |
| | | Log log = LogFactory.getLog(BaseMapperPlus.class); |
| | | |
| | | default Class<V> currentVoClass() { |
| | | return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 2); |
| | | } |
| | | |
| | | default Class<T> currentModelClass() { |
| | | return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1); |
| | | } |
| | | |
| | | default Class<M> currentMapperClass() { |
| | | return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0); |
| | | } |
| | | |
| | | default List<T> selectList() { |
| | | return this.selectList(new QueryWrapper<>()); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥ |
| | | */ |
| | | default boolean insertBatch(Collection<T> entityList) { |
| | | return Db.saveBatch(entityList); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæ´æ° |
| | | */ |
| | | default boolean updateBatchById(Collection<T> entityList) { |
| | | return Db.updateBatchById(entityList); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥ææ´æ° |
| | | */ |
| | | default boolean insertOrUpdateBatch(Collection<T> entityList) { |
| | | return Db.saveOrUpdateBatch(entityList); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean insertBatch(Collection<T> entityList, int batchSize) { |
| | | return Db.saveBatch(entityList, batchSize); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæ´æ°(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean updateBatchById(Collection<T> entityList, int batchSize) { |
| | | return Db.updateBatchById(entityList, batchSize); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥ææ´æ°(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) { |
| | | return Db.saveOrUpdateBatch(entityList, batchSize); |
| | | } |
| | | |
| | | /** |
| | | * æå
¥ææ´æ°(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean insertOrUpdate(T entity) { |
| | | return Db.saveOrUpdate(entity); |
| | | } |
| | | |
| | | default V selectVoById(Serializable id) { |
| | | return selectVoById(id, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® ID æ¥è¯¢ |
| | | */ |
| | | default <C> C selectVoById(Serializable id, Class<C> voClass) { |
| | | T obj = this.selectById(id); |
| | | if (ObjectUtil.isNull(obj)) { |
| | | return null; |
| | | } |
| | | return BeanCopyUtils.copy(obj, voClass); |
| | | } |
| | | |
| | | default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) { |
| | | return selectVoBatchIds(idList, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ï¼æ ¹æ®ID æ¹éæ¥è¯¢ï¼ |
| | | */ |
| | | default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) { |
| | | List<T> list = this.selectBatchIds(idList); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return BeanCopyUtils.copyList(list, voClass); |
| | | } |
| | | |
| | | default List<V> selectVoByMap(Map<String, Object> map) { |
| | | return selectVoByMap(map, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ï¼æ ¹æ® columnMap æ¡ä»¶ï¼ |
| | | */ |
| | | default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) { |
| | | List<T> list = this.selectByMap(map); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return BeanCopyUtils.copyList(list, voClass); |
| | | } |
| | | |
| | | default V selectVoOne(Wrapper<T> wrapper) { |
| | | return selectVoOne(wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® entity æ¡ä»¶ï¼æ¥è¯¢ä¸æ¡è®°å½ |
| | | */ |
| | | default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) { |
| | | T obj = this.selectOne(wrapper); |
| | | if (ObjectUtil.isNull(obj)) { |
| | | return null; |
| | | } |
| | | return BeanCopyUtils.copy(obj, voClass); |
| | | } |
| | | |
| | | default List<V> selectVoList(Wrapper<T> wrapper) { |
| | | return selectVoList(wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® entity æ¡ä»¶ï¼æ¥è¯¢å
¨é¨è®°å½ |
| | | */ |
| | | default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) { |
| | | List<T> list = this.selectList(wrapper); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return BeanCopyUtils.copyList(list, voClass); |
| | | } |
| | | |
| | | default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) { |
| | | return selectVoPage(page, wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢VO |
| | | */ |
| | | default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) { |
| | | IPage<T> pageData = this.selectPage(page, wrapper); |
| | | IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal()); |
| | | if (CollUtil.isEmpty(pageData.getRecords())) { |
| | | return (P) voPage; |
| | | } |
| | | voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass)); |
| | | return (P) voPage; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.core.page; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.metadata.OrderItem; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.sql.SqlUtil; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å®ä½ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class PageQuery implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * åé¡µå¤§å° |
| | | */ |
| | | private Integer pageSize; |
| | | |
| | | /** |
| | | * å½åé¡µæ° |
| | | */ |
| | | private Integer pageNum; |
| | | |
| | | /** |
| | | * æåºå |
| | | */ |
| | | private String orderByColumn; |
| | | |
| | | /** |
| | | * æåºçæ¹ådescæè
asc |
| | | */ |
| | | private String isAsc; |
| | | |
| | | /** |
| | | * å½åè®°å½èµ·å§ç´¢å¼ é»è®¤å¼ |
| | | */ |
| | | public static final int DEFAULT_PAGE_NUM = 1; |
| | | |
| | | /** |
| | | * æ¯é¡µæ¾ç¤ºè®°å½æ° é»è®¤å¼ é»è®¤æ¥å
¨é¨ |
| | | */ |
| | | public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE; |
| | | |
| | | public <T> Page<T> build() { |
| | | Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM); |
| | | Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE); |
| | | if (pageNum <= 0) { |
| | | pageNum = DEFAULT_PAGE_NUM; |
| | | } |
| | | Page<T> page = new Page<>(pageNum, pageSize); |
| | | List<OrderItem> orderItems = buildOrderItem(); |
| | | if (CollUtil.isNotEmpty(orderItems)) { |
| | | page.addOrder(orderItems); |
| | | } |
| | | return page; |
| | | } |
| | | |
| | | /** |
| | | * æå»ºæåº |
| | | * |
| | | * æ¯æçç¨æ³å¦ä¸: |
| | | * {isAsc:"asc",orderByColumn:"id"} order by id asc |
| | | * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc |
| | | * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc |
| | | * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc |
| | | */ |
| | | private List<OrderItem> buildOrderItem() { |
| | | if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) { |
| | | return null; |
| | | } |
| | | String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); |
| | | orderBy = StringUtils.toUnderScoreCase(orderBy); |
| | | |
| | | // å
¼å®¹å端æåºç±»å |
| | | isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"}); |
| | | |
| | | String[] orderByArr = orderBy.split(","); |
| | | String[] isAscArr = isAsc.split(","); |
| | | if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) { |
| | | throw new ServiceException("æåºåæ°æè¯¯"); |
| | | } |
| | | |
| | | List<OrderItem> list = new ArrayList<>(); |
| | | // æ¯ä¸ªå段åèªæåº |
| | | for (int i = 0; i < orderByArr.length; i++) { |
| | | String orderByStr = orderByArr[i]; |
| | | String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i]; |
| | | if ("asc".equals(isAscStr)) { |
| | | list.add(OrderItem.asc(orderByStr)); |
| | | } else if ("desc".equals(isAscStr)) { |
| | | list.add(OrderItem.desc(orderByStr)); |
| | | } else { |
| | | throw new ServiceException("æåºåæ°æè¯¯"); |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.core.page; |
| | | |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * è¡¨æ ¼åé¡µæ°æ®å¯¹è±¡ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class TableDataInfo<T> implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æ»è®°å½æ° |
| | | */ |
| | | private long total; |
| | | |
| | | /** |
| | | * åè¡¨æ°æ® |
| | | */ |
| | | private List<T> rows; |
| | | |
| | | /** |
| | | * æ¶æ¯ç¶æç |
| | | */ |
| | | private int code; |
| | | |
| | | /** |
| | | * æ¶æ¯å
容 |
| | | */ |
| | | private String msg; |
| | | |
| | | /** |
| | | * å页 |
| | | * |
| | | * @param list åè¡¨æ°æ® |
| | | * @param total æ»è®°å½æ° |
| | | */ |
| | | public TableDataInfo(List<T> list, long total) { |
| | | this.rows = list; |
| | | this.total = total; |
| | | } |
| | | |
| | | public static <T> TableDataInfo<T> build(IPage<T> page) { |
| | | TableDataInfo<T> rspData = new TableDataInfo<>(); |
| | | rspData.setCode(HttpStatus.HTTP_OK); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | rspData.setRows(page.getRecords()); |
| | | rspData.setTotal(page.getTotal()); |
| | | return rspData; |
| | | } |
| | | |
| | | public static <T> TableDataInfo<T> build(List<T> list) { |
| | | TableDataInfo<T> rspData = new TableDataInfo<>(); |
| | | rspData.setCode(HttpStatus.HTTP_OK); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | rspData.setRows(list); |
| | | rspData.setTotal(list.size()); |
| | | return rspData; |
| | | } |
| | | |
| | | public static <T> TableDataInfo<T> build() { |
| | | TableDataInfo<T> rspData = new TableDataInfo<>(); |
| | | rspData.setCode(HttpStatus.HTTP_OK); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | return rspData; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.enums; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * æ°æ®åºç±»å |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum DataBaseType { |
| | | |
| | | /** |
| | | * MySQL |
| | | */ |
| | | MY_SQL("MySQL"), |
| | | |
| | | /** |
| | | * Oracle |
| | | */ |
| | | ORACLE("Oracle"), |
| | | |
| | | /** |
| | | * PostgreSQL |
| | | */ |
| | | POSTGRE_SQL("PostgreSQL"), |
| | | |
| | | /** |
| | | * SQL Server |
| | | */ |
| | | SQL_SERVER("Microsoft SQL Server"); |
| | | |
| | | private final String type; |
| | | |
| | | public static DataBaseType find(String databaseProductName) { |
| | | if (StringUtils.isBlank(databaseProductName)) { |
| | | return null; |
| | | } |
| | | for (DataBaseType type : values()) { |
| | | if (type.getType().equals(databaseProductName)) { |
| | | return type; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.enums; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * æ°æ®æéç±»å |
| | | * <p> |
| | | * è¯æ³æ¯æ spel 模æ¿è¡¨è¾¾å¼ |
| | | * <p> |
| | | * å
ç½®æ°æ® user å½åç¨æ· å
容åè LoginUser |
| | | * å¦éæ©å±æ°æ® å¯ä½¿ç¨ {@link com.ruoyi.common.mybatis.helper.DataPermissionHelper} æä½ |
| | | * å
ç½®æå¡ sdss ç³»ç»æ°æ®æéæå¡ å
容åè SysDataScopeService |
| | | * å¦éæ©å±æ´å¤èªå®ä¹æå¡ å¯ä»¥åè sdss èªè¡ç¼å |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum DataScopeType { |
| | | |
| | | /** |
| | | * å
¨é¨æ°æ®æé |
| | | */ |
| | | ALL("1", "", ""), |
| | | |
| | | /** |
| | | * èªå®æ°æ®æé |
| | | */ |
| | | CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", ""), |
| | | |
| | | /** |
| | | * é¨é¨æ°æ®æé |
| | | */ |
| | | DEPT("3", " #{#deptName} = #{#user.deptId} ", ""), |
| | | |
| | | /** |
| | | * é¨é¨å以䏿°æ®æé |
| | | */ |
| | | DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", ""), |
| | | |
| | | /** |
| | | * ä»
æ¬äººæ°æ®æé |
| | | */ |
| | | SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 "); |
| | | |
| | | private final String code; |
| | | |
| | | /** |
| | | * è¯æ³ éç¨ spel 模æ¿è¡¨è¾¾å¼ |
| | | */ |
| | | private final String sqlTemplate; |
| | | |
| | | /** |
| | | * 䏿»¡è¶³ sqlTemplate åå¡«å
|
| | | */ |
| | | private final String elseSql; |
| | | |
| | | public static DataScopeType findCode(String code) { |
| | | if (StringUtils.isBlank(code)) { |
| | | return null; |
| | | } |
| | | for (DataScopeType type : values()) { |
| | | if (type.getCode().equals(code)) { |
| | | return type; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.handler; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.reflection.MetaObject; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * MP注å
¥å¤çå¨ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021/4/25 |
| | | */ |
| | | @Slf4j |
| | | public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler { |
| | | |
| | | @Override |
| | | public void insertFill(MetaObject metaObject) { |
| | | try { |
| | | if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) { |
| | | BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject(); |
| | | Date current = ObjectUtil.isNotNull(baseEntity.getCreateTime()) |
| | | ? baseEntity.getCreateTime() : new Date(); |
| | | baseEntity.setCreateTime(current); |
| | | baseEntity.setUpdateTime(current); |
| | | String username = StringUtils.isNotBlank(baseEntity.getCreateBy()) |
| | | ? baseEntity.getCreateBy() : getLoginUsername(); |
| | | // å½åå·²ç»å½ ä¸ å建人为空 åå¡«å
|
| | | baseEntity.setCreateBy(username); |
| | | // å½åå·²ç»å½ ä¸ æ´æ°äººä¸ºç©º åå¡«å
|
| | | baseEntity.setUpdateBy(username); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new ServiceException("èªå¨æ³¨å
¥å¼å¸¸ => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void updateFill(MetaObject metaObject) { |
| | | try { |
| | | if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) { |
| | | BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject(); |
| | | Date current = new Date(); |
| | | // æ´æ°æ¶é´å¡«å
(ä¸ç®¡ä¸ºä¸ä¸ºç©º) |
| | | baseEntity.setUpdateTime(current); |
| | | String username = getLoginUsername(); |
| | | // å½åå·²ç»å½ æ´æ°äººå¡«å
(ä¸ç®¡ä¸ºä¸ä¸ºç©º) |
| | | if (StringUtils.isNotBlank(username)) { |
| | | baseEntity.setUpdateBy(username); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | throw new ServiceException("èªå¨æ³¨å
¥å¼å¸¸ => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åç»å½ç¨æ·å |
| | | */ |
| | | private String getLoginUsername() { |
| | | LoginUser loginUser; |
| | | try { |
| | | loginUser = LoginHelper.getLoginUser(); |
| | | } catch (Exception e) { |
| | | log.warn("èªå¨æ³¨å
¥è¦å => ç¨æ·æªç»å½"); |
| | | return null; |
| | | } |
| | | return loginUser.getUsername(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.handler; |
| | | |
| | | import cn.hutool.core.annotation.AnnotationUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.collection.ConcurrentHashSet; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ClassUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.core.domain.dto.RoleDTO; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StreamUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.mybatis.annotation.DataColumn; |
| | | import com.ruoyi.common.mybatis.annotation.DataPermission; |
| | | import com.ruoyi.common.mybatis.enums.DataScopeType; |
| | | import com.ruoyi.common.mybatis.helper.DataPermissionHelper; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import net.sf.jsqlparser.JSQLParserException; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import net.sf.jsqlparser.expression.Parenthesis; |
| | | import net.sf.jsqlparser.expression.operators.conditional.AndExpression; |
| | | import net.sf.jsqlparser.parser.CCJSqlParserUtil; |
| | | import org.springframework.context.expression.BeanFactoryResolver; |
| | | import org.springframework.expression.BeanResolver; |
| | | import org.springframework.expression.ExpressionParser; |
| | | import org.springframework.expression.ParserContext; |
| | | import org.springframework.expression.common.TemplateParserContext; |
| | | import org.springframework.expression.spel.standard.SpelExpressionParser; |
| | | import org.springframework.expression.spel.support.StandardEvaluationContext; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * æ°æ®æéè¿æ»¤ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | @Slf4j |
| | | public class PlusDataPermissionHandler { |
| | | |
| | | /** |
| | | * æ¹æ³æç±»(åç§°) ä¸ æ³¨è§£çæ å°å
³ç³»ç¼å |
| | | */ |
| | | private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * æ ææ³¨è§£æ¹æ³ç¼åç¨äºå¿«éè¿å |
| | | */ |
| | | private final Set<String> invalidCacheSet = new ConcurrentHashSet<>(); |
| | | |
| | | /** |
| | | * spel è§£æå¨ |
| | | */ |
| | | private final ExpressionParser parser = new SpelExpressionParser(); |
| | | private final ParserContext parserContext = new TemplateParserContext(); |
| | | /** |
| | | * beanè§£æå¨ ç¨äºå¤ç spel 表达å¼ä¸å¯¹ bean çè°ç¨ |
| | | */ |
| | | private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory()); |
| | | |
| | | |
| | | public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) { |
| | | DataColumn[] dataColumns = findAnnotation(mappedStatementId); |
| | | if (ArrayUtil.isEmpty(dataColumns)) { |
| | | invalidCacheSet.add(mappedStatementId); |
| | | return where; |
| | | } |
| | | LoginUser currentUser = DataPermissionHelper.getVariable("user"); |
| | | if (ObjectUtil.isNull(currentUser)) { |
| | | currentUser = LoginHelper.getLoginUser(); |
| | | DataPermissionHelper.setVariable("user", currentUser); |
| | | } |
| | | // 妿æ¯è¶
级管çåï¼åä¸è¿æ»¤æ°æ® |
| | | if (LoginHelper.isAdmin()) { |
| | | return where; |
| | | } |
| | | String dataFilterSql = buildDataFilter(dataColumns, isSelect); |
| | | if (StringUtils.isBlank(dataFilterSql)) { |
| | | return where; |
| | | } |
| | | try { |
| | | Expression expression = CCJSqlParserUtil.parseExpression(dataFilterSql); |
| | | // æ°æ®æé使ç¨åç¬çæ¬å· 鲿¢ä¸å
¶ä»æ¡ä»¶å²çª |
| | | Parenthesis parenthesis = new Parenthesis(expression); |
| | | if (ObjectUtil.isNotNull(where)) { |
| | | return new AndExpression(where, parenthesis); |
| | | } else { |
| | | return parenthesis; |
| | | } |
| | | } catch (JSQLParserException e) { |
| | | throw new ServiceException("æ°æ®æéè§£æå¼å¸¸ => " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æé æ°æ®è¿æ»¤sql |
| | | */ |
| | | private String buildDataFilter(DataColumn[] dataColumns, boolean isSelect) { |
| | | // æ´æ°æå é¤éæ»¡è¶³æææ¡ä»¶ |
| | | String joinStr = isSelect ? " OR " : " AND "; |
| | | LoginUser user = DataPermissionHelper.getVariable("user"); |
| | | StandardEvaluationContext context = new StandardEvaluationContext(); |
| | | context.setBeanResolver(beanResolver); |
| | | DataPermissionHelper.getContext().forEach(context::setVariable); |
| | | Set<String> conditions = new HashSet<>(); |
| | | for (RoleDTO role : user.getRoles()) { |
| | | user.setRoleId(role.getRoleId()); |
| | | // è·åè§è²æéæ³å |
| | | DataScopeType type = DataScopeType.findCode(role.getDataScope()); |
| | | if (ObjectUtil.isNull(type)) { |
| | | throw new ServiceException("è§è²æ°æ®èå´å¼å¸¸ => " + role.getDataScope()); |
| | | } |
| | | // å
¨é¨æ°æ®æéç´æ¥è¿å |
| | | if (type == DataScopeType.ALL) { |
| | | return ""; |
| | | } |
| | | boolean isSuccess = false; |
| | | for (DataColumn dataColumn : dataColumns) { |
| | | if (dataColumn.key().length != dataColumn.value().length) { |
| | | throw new ServiceException("è§è²æ°æ®èå´å¼å¸¸ => keyä¸valueé¿åº¦ä¸å¹é
"); |
| | | } |
| | | // ä¸å
å« key åé åä¸å¤ç |
| | | if (!StringUtils.containsAny(type.getSqlTemplate(), |
| | | Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new) |
| | | )) { |
| | | continue; |
| | | } |
| | | // 设置注解åé key 为表达å¼åé value 为åéå¼ |
| | | for (int i = 0; i < dataColumn.key().length; i++) { |
| | | context.setVariable(dataColumn.key()[i], dataColumn.value()[i]); |
| | | } |
| | | |
| | | // è§£æsql模æ¿å¹¶å¡«å
|
| | | String sql = parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class); |
| | | conditions.add(joinStr + sql); |
| | | isSuccess = true; |
| | | } |
| | | // æªå¤çæååå¡«å
å
åºæ¹æ¡ |
| | | if (!isSuccess && StringUtils.isNotBlank(type.getElseSql())) { |
| | | conditions.add(joinStr + type.getElseSql()); |
| | | } |
| | | } |
| | | |
| | | if (CollUtil.isNotEmpty(conditions)) { |
| | | String sql = StreamUtils.join(conditions, Function.identity(), ""); |
| | | return sql.substring(joinStr.length()); |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | private DataColumn[] findAnnotation(String mappedStatementId) { |
| | | StringBuilder sb = new StringBuilder(mappedStatementId); |
| | | int index = sb.lastIndexOf("."); |
| | | String clazzName = sb.substring(0, index); |
| | | String methodName = sb.substring(index + 1, sb.length()); |
| | | Class<?> clazz = ClassUtil.loadClass(clazzName); |
| | | List<Method> methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz)) |
| | | .filter(method -> method.getName().equals(methodName)).collect(Collectors.toList()); |
| | | DataPermission dataPermission; |
| | | // è·åæ¹æ³æ³¨è§£ |
| | | for (Method method : methods) { |
| | | dataPermission = dataPermissionCacheMap.get(mappedStatementId); |
| | | if (ObjectUtil.isNotNull(dataPermission)) { |
| | | return dataPermission.value(); |
| | | } |
| | | if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) { |
| | | dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class); |
| | | dataPermissionCacheMap.put(mappedStatementId, dataPermission); |
| | | return dataPermission.value(); |
| | | } |
| | | } |
| | | dataPermission = dataPermissionCacheMap.get(clazz.getName()); |
| | | if (ObjectUtil.isNotNull(dataPermission)) { |
| | | return dataPermission.value(); |
| | | } |
| | | // è·å类注解 |
| | | if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) { |
| | | dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class); |
| | | dataPermissionCacheMap.put(clazz.getName(), dataPermission); |
| | | return dataPermission.value(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºæ ææ¹æ³ æ æ°æ®æé |
| | | */ |
| | | public boolean isInvalid(String mappedStatementId) { |
| | | return invalidCacheSet.contains(mappedStatementId); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.helper; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.mybatis.enums.DataBaseType; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import javax.sql.DataSource; |
| | | import java.sql.Connection; |
| | | import java.sql.DatabaseMetaData; |
| | | import java.sql.SQLException; |
| | | |
| | | /** |
| | | * æ°æ®åºå©æ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class DataBaseHelper { |
| | | |
| | | private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class); |
| | | |
| | | /** |
| | | * è·åå½åæ°æ®åºç±»å |
| | | */ |
| | | public static DataBaseType getDataBaseType() { |
| | | DataSource dataSource = DS.determineDataSource(); |
| | | try (Connection conn = dataSource.getConnection()) { |
| | | DatabaseMetaData metaData = conn.getMetaData(); |
| | | String databaseProductName = metaData.getDatabaseProductName(); |
| | | return DataBaseType.find(databaseProductName); |
| | | } catch (SQLException e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | public static boolean isMySql() { |
| | | return DataBaseType.MY_SQL == getDataBaseType(); |
| | | } |
| | | |
| | | public static boolean isOracle() { |
| | | return DataBaseType.ORACLE == getDataBaseType(); |
| | | } |
| | | |
| | | public static boolean isPostgerSql() { |
| | | return DataBaseType.POSTGRE_SQL == getDataBaseType(); |
| | | } |
| | | |
| | | public static boolean isSqlServer() { |
| | | return DataBaseType.SQL_SERVER == getDataBaseType(); |
| | | } |
| | | |
| | | public static String findInSet(Object var1, String var2) { |
| | | DataBaseType dataBasyType = getDataBaseType(); |
| | | String var = Convert.toStr(var1); |
| | | if (dataBasyType == DataBaseType.SQL_SERVER) { |
| | | // charindex(',100,' , ',0,100,101,') <> 0 |
| | | return "charindex('," + var + ",' , ','+" + var2 + "+',') <> 0"; |
| | | } else if (dataBasyType == DataBaseType.POSTGRE_SQL) { |
| | | // (select position(',100,' in ',0,100,101,')) <> 0 |
| | | return "(select position('," + var + ",' in ','||" + var2 + "||',')) <> 0"; |
| | | } else if (dataBasyType == DataBaseType.ORACLE) { |
| | | // instr(',0,100,101,' , ',100,') <> 0 |
| | | return "instr(','||" + var2 + "||',' , '," + var + ",') <> 0"; |
| | | } |
| | | // find_in_set(100 , '0,100,101') |
| | | return "find_in_set(" + var + " , " + var2 + ") <> 0"; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.helper; |
| | | |
| | | import cn.dev33.satoken.context.SaHolder; |
| | | import cn.dev33.satoken.context.model.SaStorage; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æ°æ®æé婿 |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | @SuppressWarnings("unchecked cast") |
| | | public class DataPermissionHelper { |
| | | |
| | | private static final String DATA_PERMISSION_KEY = "data:permission"; |
| | | |
| | | public static <T> T getVariable(String key) { |
| | | Map<String, Object> context = getContext(); |
| | | return (T) context.get(key); |
| | | } |
| | | |
| | | |
| | | public static void setVariable(String key, Object value) { |
| | | Map<String, Object> context = getContext(); |
| | | context.put(key, value); |
| | | } |
| | | |
| | | public static Map<String, Object> getContext() { |
| | | SaStorage saStorage = SaHolder.getStorage(); |
| | | Object attribute = saStorage.get(DATA_PERMISSION_KEY); |
| | | if (ObjectUtil.isNull(attribute)) { |
| | | saStorage.set(DATA_PERMISSION_KEY, new HashMap<>()); |
| | | attribute = saStorage.get(DATA_PERMISSION_KEY); |
| | | } |
| | | if (attribute instanceof Map) { |
| | | return (Map<String, Object>) attribute; |
| | | } |
| | | throw new NullPointerException("data permission context type exception"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.helper; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.mybatis.spring.MyBatisSystemException; |
| | | import org.springframework.dao.DuplicateKeyException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | |
| | | /** |
| | | * Mybatiså¼å¸¸å¤çå¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @RestControllerAdvice |
| | | public class MybatisExceptionHandler { |
| | | |
| | | /** |
| | | * 䏻鮿UNIQUEç´¢å¼ï¼æ°æ®éå¤å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(DuplicateKeyException.class) |
| | | public R<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',æ°æ®åºä¸å·²åå¨è®°å½'{}'", requestURI, e.getMessage()); |
| | | return R.fail("æ°æ®åºä¸å·²åå¨è¯¥è®°å½ï¼è¯·è系管çå确认"); |
| | | } |
| | | |
| | | /** |
| | | * Mybatisç³»ç»å¼å¸¸ éç¨å¤ç |
| | | */ |
| | | @ExceptionHandler(MyBatisSystemException.class) |
| | | public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | String message = e.getMessage(); |
| | | if (message.contains("CannotFindDataSourceException")) { |
| | | log.error("请æ±å°å'{}', æªæ¾å°æ°æ®æº", requestURI); |
| | | return R.fail("æªæ¾å°æ°æ®æºï¼è¯·è系管çå确认"); |
| | | } |
| | | log.error("请æ±å°å'{}', Mybatisç³»ç»å¼å¸¸", requestURI, e); |
| | | return R.fail(message); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.mybatis.interceptor; |
| | | |
| | | import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; |
| | | import com.baomidou.mybatisplus.core.toolkit.PluginUtils; |
| | | import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; |
| | | import com.ruoyi.common.mybatis.handler.PlusDataPermissionHandler; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import net.sf.jsqlparser.statement.delete.Delete; |
| | | import net.sf.jsqlparser.statement.select.PlainSelect; |
| | | import net.sf.jsqlparser.statement.select.Select; |
| | | import net.sf.jsqlparser.statement.select.SelectBody; |
| | | import net.sf.jsqlparser.statement.select.SetOperationList; |
| | | import net.sf.jsqlparser.statement.update.Update; |
| | | import org.apache.ibatis.executor.Executor; |
| | | import org.apache.ibatis.executor.statement.StatementHandler; |
| | | import org.apache.ibatis.mapping.BoundSql; |
| | | import org.apache.ibatis.mapping.MappedStatement; |
| | | import org.apache.ibatis.mapping.SqlCommandType; |
| | | import org.apache.ibatis.session.ResultHandler; |
| | | import org.apache.ibatis.session.RowBounds; |
| | | |
| | | import java.sql.Connection; |
| | | import java.sql.SQLException; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ°æ®æéæ¦æªå¨ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | public class PlusDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor { |
| | | |
| | | private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler(); |
| | | |
| | | @Override |
| | | public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { |
| | | // æ£æ¥å¿½ç¥æ³¨è§£ |
| | | if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) { |
| | | return; |
| | | } |
| | | // æ£æ¥æ¯å¦æ æ æ æ°æ®æé注解 |
| | | if (dataPermissionHandler.isInvalid(ms.getId())) { |
| | | return; |
| | | } |
| | | // è§£æ sql åé
å¯¹åºæ¹æ³ |
| | | PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); |
| | | mpBs.sql(parserSingle(mpBs.sql(), ms.getId())); |
| | | } |
| | | |
| | | @Override |
| | | public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { |
| | | PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); |
| | | MappedStatement ms = mpSh.mappedStatement(); |
| | | SqlCommandType sct = ms.getSqlCommandType(); |
| | | if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) { |
| | | if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) { |
| | | return; |
| | | } |
| | | PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); |
| | | mpBs.sql(parserMulti(mpBs.sql(), ms.getId())); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected void processSelect(Select select, int index, String sql, Object obj) { |
| | | SelectBody selectBody = select.getSelectBody(); |
| | | if (selectBody instanceof PlainSelect) { |
| | | this.setWhere((PlainSelect) selectBody, (String) obj); |
| | | } else if (selectBody instanceof SetOperationList) { |
| | | SetOperationList setOperationList = (SetOperationList) selectBody; |
| | | List<SelectBody> selectBodyList = setOperationList.getSelects(); |
| | | selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj)); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected void processUpdate(Update update, int index, String sql, Object obj) { |
| | | Expression sqlSegment = dataPermissionHandler.getSqlSegment(update.getWhere(), (String) obj, false); |
| | | if (null != sqlSegment) { |
| | | update.setWhere(sqlSegment); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected void processDelete(Delete delete, int index, String sql, Object obj) { |
| | | Expression sqlSegment = dataPermissionHandler.getSqlSegment(delete.getWhere(), (String) obj, false); |
| | | if (null != sqlSegment) { |
| | | delete.setWhere(sqlSegment); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置 where æ¡ä»¶ |
| | | * |
| | | * @param plainSelect æ¥è¯¢å¯¹è±¡ |
| | | * @param mappedStatementId æ§è¡æ¹æ³id |
| | | */ |
| | | protected void setWhere(PlainSelect plainSelect, String mappedStatementId) { |
| | | Expression sqlSegment = dataPermissionHandler.getSqlSegment(plainSelect.getWhere(), mappedStatementId, true); |
| | | if (null != sqlSegment) { |
| | | plainSelect.setWhere(sqlSegment); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.mybatis.config.MybatisPlusConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-oss</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-oss ossæå¡ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.amazonaws</groupId> |
| | | <artifactId>aws-java-sdk-s3</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.constant; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 对象åå¨å¸¸é |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public interface OssConstant { |
| | | |
| | | /** |
| | | * é»è®¤é
ç½®KEY |
| | | */ |
| | | String DEFAULT_CONFIG_KEY = "sys_oss:default_config"; |
| | | |
| | | /** |
| | | * é¢è§åè¡¨èµæºå¼å
³Key |
| | | */ |
| | | String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource"; |
| | | |
| | | /** |
| | | * ç³»ç»æ°æ®ids |
| | | */ |
| | | List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L); |
| | | |
| | | /** |
| | | * äºæå¡å |
| | | */ |
| | | String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"}; |
| | | |
| | | /** |
| | | * https ç¶æ |
| | | */ |
| | | String IS_HTTPS = "Y"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.core; |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.amazonaws.ClientConfiguration; |
| | | import com.amazonaws.HttpMethod; |
| | | import com.amazonaws.Protocol; |
| | | import com.amazonaws.auth.AWSCredentials; |
| | | import com.amazonaws.auth.AWSCredentialsProvider; |
| | | import com.amazonaws.auth.AWSStaticCredentialsProvider; |
| | | import com.amazonaws.auth.BasicAWSCredentials; |
| | | import com.amazonaws.client.builder.AwsClientBuilder; |
| | | import com.amazonaws.services.s3.AmazonS3; |
| | | import com.amazonaws.services.s3.AmazonS3Client; |
| | | import com.amazonaws.services.s3.AmazonS3ClientBuilder; |
| | | import com.amazonaws.services.s3.model.*; |
| | | import com.ruoyi.common.core.utils.DateUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.oss.constant.OssConstant; |
| | | import com.ruoyi.common.oss.entity.UploadResult; |
| | | import com.ruoyi.common.oss.enumd.AccessPolicyType; |
| | | import com.ruoyi.common.oss.enumd.PolicyType; |
| | | import com.ruoyi.common.oss.exception.OssException; |
| | | import com.ruoyi.common.oss.properties.OssProperties; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.InputStream; |
| | | import java.net.URL; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * S3 åå¨åè®® ææå
¼å®¹S3åè®®çäºåå忝æ |
| | | * é¿éäº è
¾è®¯äº ä¸çäº minio |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class OssClient { |
| | | |
| | | private final String configKey; |
| | | |
| | | private final OssProperties properties; |
| | | |
| | | private final AmazonS3 client; |
| | | |
| | | public OssClient(String configKey, OssProperties ossProperties) { |
| | | this.configKey = configKey; |
| | | this.properties = ossProperties; |
| | | try { |
| | | AwsClientBuilder.EndpointConfiguration endpointConfig = |
| | | new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion()); |
| | | |
| | | AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey()); |
| | | AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials); |
| | | ClientConfiguration clientConfig = new ClientConfiguration(); |
| | | if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) { |
| | | clientConfig.setProtocol(Protocol.HTTPS); |
| | | } else { |
| | | clientConfig.setProtocol(Protocol.HTTP); |
| | | } |
| | | AmazonS3ClientBuilder build = AmazonS3Client.builder() |
| | | .withEndpointConfiguration(endpointConfig) |
| | | .withClientConfiguration(clientConfig) |
| | | .withCredentials(credentialsProvider) |
| | | .disableChunkedEncoding(); |
| | | if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) { |
| | | // minio 使ç¨httpséå¶ä½¿ç¨ååè®¿é® éè¦æ¤é
ç½® ç«ç¹å¡«åå |
| | | build.enablePathStyleAccess(); |
| | | } |
| | | this.client = build.build(); |
| | | |
| | | createBucket(); |
| | | } catch (Exception e) { |
| | | if (e instanceof OssException) { |
| | | throw e; |
| | | } |
| | | throw new OssException("é
ç½®é误! è¯·æ£æ¥ç³»ç»é
ç½®:[" + e.getMessage() + "]"); |
| | | } |
| | | } |
| | | |
| | | public void createBucket() { |
| | | try { |
| | | String bucketName = properties.getBucketName(); |
| | | if (client.doesBucketExistV2(bucketName)) { |
| | | return; |
| | | } |
| | | CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); |
| | | AccessPolicyType accessPolicy = getAccessPolicy(); |
| | | createBucketRequest.setCannedAcl(accessPolicy.getAcl()); |
| | | client.createBucket(createBucketRequest); |
| | | client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType())); |
| | | } catch (Exception e) { |
| | | throw new OssException("å建Bucket失败, è¯·æ ¸å¯¹é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | } |
| | | |
| | | public UploadResult upload(byte[] data, String path, String contentType) { |
| | | return upload(new ByteArrayInputStream(data), path, contentType); |
| | | } |
| | | |
| | | public UploadResult upload(InputStream inputStream, String path, String contentType) { |
| | | if (!(inputStream instanceof ByteArrayInputStream)) { |
| | | inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream)); |
| | | } |
| | | try { |
| | | ObjectMetadata metadata = new ObjectMetadata(); |
| | | metadata.setContentType(contentType); |
| | | metadata.setContentLength(inputStream.available()); |
| | | PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata); |
| | | // 设置ä¸ä¼ 对象ç Acl 为å
Œ
±è¯» |
| | | putObjectRequest.setCannedAcl(getAccessPolicy().getAcl()); |
| | | client.putObject(putObjectRequest); |
| | | } catch (Exception e) { |
| | | throw new OssException("ä¸ä¼ æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build(); |
| | | } |
| | | |
| | | public void delete(String path) { |
| | | path = path.replace(getUrl() + "/", ""); |
| | | try { |
| | | client.deleteObject(properties.getBucketName(), path); |
| | | } catch (Exception e) { |
| | | throw new OssException("å é¤æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | } |
| | | |
| | | public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { |
| | | return upload(data, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { |
| | | return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | /** |
| | | * è·åæä»¶å
æ°æ® |
| | | * |
| | | * @param path 宿´æä»¶è·¯å¾ |
| | | */ |
| | | public ObjectMetadata getObjectMetadata(String path) { |
| | | path = path.replace(getUrl() + "/", ""); |
| | | S3Object object = client.getObject(properties.getBucketName(), path); |
| | | return object.getObjectMetadata(); |
| | | } |
| | | |
| | | public InputStream getObjectContent(String path) { |
| | | path = path.replace(getUrl() + "/", ""); |
| | | S3Object object = client.getObject(properties.getBucketName(), path); |
| | | return object.getObjectContent(); |
| | | } |
| | | |
| | | public String getUrl() { |
| | | String domain = properties.getDomain(); |
| | | String endpoint = properties.getEndpoint(); |
| | | String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://"; |
| | | // äºæå¡åç´æ¥è¿å |
| | | if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { |
| | | if (StringUtils.isNotBlank(domain)) { |
| | | return header + domain; |
| | | } |
| | | return header + properties.getBucketName() + "." + endpoint; |
| | | } |
| | | // minio åç¬å¤ç |
| | | if (StringUtils.isNotBlank(domain)) { |
| | | return header + domain + "/" + properties.getBucketName(); |
| | | } |
| | | return header + endpoint + "/" + properties.getBucketName(); |
| | | } |
| | | |
| | | public String getPath(String prefix, String suffix) { |
| | | // çæuuid |
| | | String uuid = IdUtil.fastSimpleUUID(); |
| | | // æä»¶è·¯å¾ |
| | | String path = DateUtils.datePath() + "/" + uuid; |
| | | if (StringUtils.isNotBlank(prefix)) { |
| | | path = prefix + "/" + path; |
| | | } |
| | | return path + suffix; |
| | | } |
| | | |
| | | |
| | | public String getConfigKey() { |
| | | return configKey; |
| | | } |
| | | |
| | | public String getPrivateUrl(String objectKey, Integer second) { |
| | | GeneratePresignedUrlRequest generatePresignedUrlRequest = |
| | | new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey) |
| | | .withMethod(HttpMethod.GET) |
| | | .withExpiration(new Date(System.currentTimeMillis() + 1000L * second)); |
| | | URL url = client.generatePresignedUrl(generatePresignedUrlRequest); |
| | | return url.toString(); |
| | | } |
| | | |
| | | /** |
| | | * è·åå½åæ¡¶æéç±»å |
| | | * |
| | | * @return å½åæ¡¶æéç±»åcode |
| | | */ |
| | | public AccessPolicyType getAccessPolicy() { |
| | | return AccessPolicyType.getByType(properties.getAccessPolicy()); |
| | | } |
| | | |
| | | private static String getPolicy(String bucketName, PolicyType policyType) { |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n"); |
| | | if (policyType == PolicyType.WRITE) { |
| | | builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n"); |
| | | } else if (policyType == PolicyType.READ_WRITE) { |
| | | builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n"); |
| | | } else { |
| | | builder.append("\"s3:GetBucketLocation\"\n"); |
| | | } |
| | | builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); |
| | | builder.append(bucketName); |
| | | builder.append("\"\n},\n"); |
| | | if (policyType == PolicyType.READ) { |
| | | builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); |
| | | builder.append(bucketName); |
| | | builder.append("\"\n},\n"); |
| | | } |
| | | builder.append("{\n\"Action\": "); |
| | | switch (policyType) { |
| | | case WRITE: |
| | | builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"); |
| | | break; |
| | | case READ_WRITE: |
| | | builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"); |
| | | break; |
| | | default: |
| | | builder.append("\"s3:GetObject\",\n"); |
| | | break; |
| | | } |
| | | builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); |
| | | builder.append(bucketName); |
| | | builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n"); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.entity; |
| | | |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * ä¸ä¼ è¿åä½ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Builder |
| | | public class UploadResult { |
| | | |
| | | /** |
| | | * æä»¶è·¯å¾ |
| | | */ |
| | | private String url; |
| | | |
| | | /** |
| | | * æä»¶å |
| | | */ |
| | | private String filename; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.enumd; |
| | | |
| | | import com.amazonaws.services.s3.model.CannedAccessControlList; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 桶访é®çç¥é
ç½® |
| | | * |
| | | * @author éè³ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum AccessPolicyType { |
| | | |
| | | /** |
| | | * private |
| | | */ |
| | | PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE), |
| | | |
| | | /** |
| | | * public |
| | | */ |
| | | PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ), |
| | | |
| | | /** |
| | | * custom |
| | | */ |
| | | CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ); |
| | | |
| | | /** |
| | | * æ¡¶ æéç±»å |
| | | */ |
| | | private final String type; |
| | | |
| | | /** |
| | | * æä»¶å¯¹è±¡ æéç±»å |
| | | */ |
| | | private final CannedAccessControlList acl; |
| | | |
| | | /** |
| | | * æ¡¶çç¥ç±»å |
| | | */ |
| | | private final PolicyType policyType; |
| | | |
| | | public static AccessPolicyType getByType(String type) { |
| | | for (AccessPolicyType value : values()) { |
| | | if (value.getType().equals(type)) { |
| | | return value; |
| | | } |
| | | } |
| | | throw new RuntimeException("'type' not found By " + type); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.enumd; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * minioçç¥é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum PolicyType { |
| | | |
| | | /** |
| | | * åªè¯» |
| | | */ |
| | | READ("read-only"), |
| | | |
| | | /** |
| | | * åªå |
| | | */ |
| | | WRITE("write-only"), |
| | | |
| | | /** |
| | | * 读å |
| | | */ |
| | | READ_WRITE("read-write"); |
| | | |
| | | /** |
| | | * ç±»å |
| | | */ |
| | | private final String type; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.exception; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * OSSå¼å¸¸ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class OssException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public OssException(String msg) { |
| | | super(msg); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.factory; |
| | | |
| | | import com.ruoyi.common.core.constant.CacheNames; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.oss.constant.OssConstant; |
| | | import com.ruoyi.common.oss.core.OssClient; |
| | | import com.ruoyi.common.oss.exception.OssException; |
| | | import com.ruoyi.common.oss.properties.OssProperties; |
| | | import com.ruoyi.common.redis.utils.CacheUtils; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * æä»¶ä¸ä¼ Factory |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | public class OssFactory { |
| | | |
| | | private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * åå§åå·¥å |
| | | */ |
| | | public static void init() { |
| | | log.info("åå§åOSSå·¥å"); |
| | | RedisUtils.subscribe(OssConstant.DEFAULT_CONFIG_KEY, String.class, configKey -> { |
| | | OssClient client = getClient(configKey); |
| | | // æªåå§åä¸å¤ç |
| | | if (client != null) { |
| | | refresh(configKey); |
| | | log.info("订é
å·æ°OSSé
ç½® => " + configKey); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * è·åé»è®¤å®ä¾ |
| | | */ |
| | | public static OssClient instance() { |
| | | // è·åredis é»è®¤ç±»å |
| | | String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY); |
| | | if (StringUtils.isEmpty(configKey)) { |
| | | throw new OssException("æä»¶å卿å¡ç±»åæ æ³æ¾å°!"); |
| | | } |
| | | return instance(configKey); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç±»åè·åå®ä¾ |
| | | */ |
| | | public static OssClient instance(String configKey) { |
| | | OssClient client = getClient(configKey); |
| | | if (client == null) { |
| | | refresh(configKey); |
| | | return getClient(configKey); |
| | | } |
| | | return client; |
| | | } |
| | | |
| | | private static void refresh(String configKey) { |
| | | String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey); |
| | | if (json == null) { |
| | | throw new OssException("ç³»ç»å¼å¸¸, '" + configKey + "'é
置信æ¯ä¸åå¨!"); |
| | | } |
| | | OssProperties properties = JsonUtils.parseObject(json, OssProperties.class); |
| | | CLIENT_CACHE.put(configKey, new OssClient(configKey, properties)); |
| | | } |
| | | |
| | | private static OssClient getClient(String configKey) { |
| | | return CLIENT_CACHE.get(configKey); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.oss.properties; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * OSS对象åå¨ é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | public class OssProperties { |
| | | |
| | | /** |
| | | * 访é®ç«ç¹ |
| | | */ |
| | | private String endpoint; |
| | | |
| | | /** |
| | | * èªå®ä¹åå |
| | | */ |
| | | private String domain; |
| | | |
| | | /** |
| | | * åç¼ |
| | | */ |
| | | private String prefix; |
| | | |
| | | /** |
| | | * ACCESS_KEY |
| | | */ |
| | | private String accessKey; |
| | | |
| | | /** |
| | | * SECRET_KEY |
| | | */ |
| | | private String secretKey; |
| | | |
| | | /** |
| | | * åå¨ç©ºé´å |
| | | */ |
| | | private String bucketName; |
| | | |
| | | /** |
| | | * åå¨åºå |
| | | */ |
| | | private String region; |
| | | |
| | | /** |
| | | * æ¯å¦httpsï¼Y=æ¯,N=å¦ï¼ |
| | | */ |
| | | private String isHttps; |
| | | |
| | | /** |
| | | * æ¡¶æéç±»å(0private 1public 2custom) |
| | | */ |
| | | private String accessPolicy; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-ratelimiter</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-ratelimiter éæµåè½ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.ratelimiter.annotation; |
| | | |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.ratelimiter.enums.LimitType; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * éæµæ³¨è§£ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface RateLimiter { |
| | | /** |
| | | * éæµkey |
| | | */ |
| | | String key() default CacheConstants.RATE_LIMIT_KEY; |
| | | |
| | | /** |
| | | * éæµæ¶é´,åä½ç§ |
| | | */ |
| | | int time() default 60; |
| | | |
| | | /** |
| | | * éæµæ¬¡æ° |
| | | */ |
| | | int count() default 100; |
| | | |
| | | /** |
| | | * éæµç±»å |
| | | */ |
| | | LimitType limitType() default LimitType.DEFAULT; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.ratelimiter.aspectj; |
| | | |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.MessageUtils; |
| | | import com.ruoyi.common.core.utils.ServletUtils; |
| | | import com.ruoyi.common.ratelimiter.annotation.RateLimiter; |
| | | import com.ruoyi.common.ratelimiter.enums.LimitType; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.redisson.api.RateType; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * éæµå¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @Aspect |
| | | public class RateLimiterAspect { |
| | | |
| | | @Before("@annotation(rateLimiter)") |
| | | public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable { |
| | | int time = rateLimiter.time(); |
| | | int count = rateLimiter.count(); |
| | | String combineKey = getCombineKey(rateLimiter, point); |
| | | try { |
| | | RateType rateType = RateType.OVERALL; |
| | | if (rateLimiter.limitType() == LimitType.CLUSTER) { |
| | | rateType = RateType.PER_CLIENT; |
| | | } |
| | | long number = RedisUtils.rateLimiter(combineKey, rateType, count, time); |
| | | if (number == -1) { |
| | | throw new ServiceException(MessageUtils.message("rate.limiter.message")); |
| | | } |
| | | log.info("éå¶ä»¤ç => {}, å©ä½ä»¤ç => {}, ç¼åkey => '{}'", count, number, combineKey); |
| | | } catch (ServiceException e) { |
| | | throw e; |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("æå¡å¨éæµå¼å¸¸ï¼è¯·ç¨ååè¯"); |
| | | } |
| | | } |
| | | |
| | | public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { |
| | | StringBuilder stringBuffer = new StringBuilder(rateLimiter.key()); |
| | | if (rateLimiter.limitType() == LimitType.IP) { |
| | | // è·å请æ±ip |
| | | stringBuffer.append(ServletUtils.getClientIP()).append("-"); |
| | | } else if (rateLimiter.limitType() == LimitType.CLUSTER) { |
| | | // è·å客æ·ç«¯å®ä¾id |
| | | stringBuffer.append(RedisUtils.getClient().getId()).append("-"); |
| | | } |
| | | MethodSignature signature = (MethodSignature) point.getSignature(); |
| | | Method method = signature.getMethod(); |
| | | Class<?> targetClass = method.getDeclaringClass(); |
| | | stringBuffer.append(targetClass.getName()).append("-").append(method.getName()); |
| | | return stringBuffer.toString(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.ratelimiter.config; |
| | | |
| | | import com.ruoyi.common.ratelimiter.aspectj.RateLimiterAspect; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.data.redis.connection.RedisConfiguration; |
| | | |
| | | /** |
| | | * @author guangxin |
| | | * @date 2023/1/18 |
| | | */ |
| | | @AutoConfiguration(after = RedisConfiguration.class) |
| | | public class RateLimiterConfig { |
| | | |
| | | @Bean |
| | | public RateLimiterAspect rateLimiterAspect() { |
| | | return new RateLimiterAspect(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.ratelimiter.enums; |
| | | |
| | | /** |
| | | * éæµç±»å |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | |
| | | public enum LimitType { |
| | | /** |
| | | * é»è®¤çç¥å
¨å±éæµ |
| | | */ |
| | | DEFAULT, |
| | | |
| | | /** |
| | | * æ ¹æ®è¯·æ±è
IPè¿è¡éæµ |
| | | */ |
| | | IP, |
| | | |
| | | /** |
| | | * å®ä¾éæµ(é群å¤å端å®ä¾) |
| | | */ |
| | | CLUSTER |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.ratelimiter.config.RateLimiterConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-redis ç¼åæå¡ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <!-- RuoYi Common Core--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <!--redisson--> |
| | | <dependency> |
| | | <groupId>org.redisson</groupId> |
| | | <artifactId>redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>lock4j-redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.redis.config; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.ruoyi.common.redis.config.properties.RedissonProperties; |
| | | import com.ruoyi.common.redis.handler.KeyPrefixHandler; |
| | | import com.ruoyi.common.redis.manager.PlusSpringCacheManager; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.redisson.codec.JsonJacksonCodec; |
| | | import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | /** |
| | | * redisé
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @AutoConfiguration |
| | | @EnableCaching |
| | | @EnableConfigurationProperties(RedissonProperties.class) |
| | | public class RedisConfig { |
| | | |
| | | @Autowired |
| | | private RedissonProperties redissonProperties; |
| | | |
| | | @Autowired |
| | | private ObjectMapper objectMapper; |
| | | |
| | | @Bean |
| | | public RedissonAutoConfigurationCustomizer redissonCustomizer() { |
| | | return config -> { |
| | | config.setThreads(redissonProperties.getThreads()) |
| | | .setNettyThreads(redissonProperties.getNettyThreads()) |
| | | .setCodec(new JsonJacksonCodec(objectMapper)); |
| | | RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); |
| | | if (ObjectUtil.isNotNull(singleServerConfig)) { |
| | | // 使ç¨åæºæ¨¡å¼ |
| | | config.useSingleServer() |
| | | //设置redis keyåç¼ |
| | | .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix())) |
| | | .setTimeout(singleServerConfig.getTimeout()) |
| | | .setClientName(singleServerConfig.getClientName()) |
| | | .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout()) |
| | | .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize()) |
| | | .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize()) |
| | | .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize()); |
| | | } |
| | | // é群é
ç½®æ¹å¼ åè䏿¹æ³¨é |
| | | RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig(); |
| | | if (ObjectUtil.isNotNull(clusterServersConfig)) { |
| | | config.useClusterServers() |
| | | //设置redis keyåç¼ |
| | | .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix())) |
| | | .setTimeout(clusterServersConfig.getTimeout()) |
| | | .setClientName(clusterServersConfig.getClientName()) |
| | | .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout()) |
| | | .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize()) |
| | | .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize()) |
| | | .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize()) |
| | | .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize()) |
| | | .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize()) |
| | | .setReadMode(clusterServersConfig.getReadMode()) |
| | | .setSubscriptionMode(clusterServersConfig.getSubscriptionMode()); |
| | | } |
| | | log.info("åå§å redis é
ç½®"); |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹ç¼å管çå¨ æ´åspring-cache |
| | | */ |
| | | @Bean |
| | | public CacheManager cacheManager() { |
| | | return new PlusSpringCacheManager(); |
| | | } |
| | | |
| | | /** |
| | | * redisé群é
ç½® yml |
| | | * |
| | | * --- # redis é群é
ç½®(åæºä¸é群åªè½å¼å¯ä¸ä¸ªå¦ä¸ä¸ªéè¦æ³¨éæ) |
| | | * spring: |
| | | * redis: |
| | | * cluster: |
| | | * nodes: |
| | | * - 192.168.0.100:6379 |
| | | * - 192.168.0.101:6379 |
| | | * - 192.168.0.102:6379 |
| | | * # å¯ç |
| | | * password: |
| | | * # è¿æ¥è¶
æ¶æ¶é´ |
| | | * timeout: 10s |
| | | * # æ¯å¦å¼å¯ssl |
| | | * ssl: false |
| | | * |
| | | * redisson: |
| | | * # çº¿ç¨æ± æ°é |
| | | * threads: 16 |
| | | * # Nettyçº¿ç¨æ± æ°é |
| | | * nettyThreads: 32 |
| | | * # é群é
ç½® |
| | | * clusterServersConfig: |
| | | * # 客æ·ç«¯åç§° |
| | | * clientName: ${ruoyi.name} |
| | | * # masteræå°ç©ºé²è¿æ¥æ° |
| | | * masterConnectionMinimumIdleSize: 32 |
| | | * # masterè¿æ¥æ± å¤§å° |
| | | * masterConnectionPoolSize: 64 |
| | | * # slaveæå°ç©ºé²è¿æ¥æ° |
| | | * slaveConnectionMinimumIdleSize: 32 |
| | | * # slaveè¿æ¥æ± å¤§å° |
| | | * slaveConnectionPoolSize: 64 |
| | | * # è¿æ¥ç©ºé²è¶
æ¶ï¼åä½ï¼æ¯«ç§ |
| | | * idleConnectionTimeout: 10000 |
| | | * # å½ä»¤çå¾
è¶
æ¶ï¼åä½ï¼æ¯«ç§ |
| | | * timeout: 3000 |
| | | * # åå¸å订é
è¿æ¥æ± å¤§å° |
| | | * subscriptionConnectionPoolSize: 50 |
| | | * # è¯»åæ¨¡å¼ |
| | | * readMode: "SLAVE" |
| | | * # 订é
æ¨¡å¼ |
| | | * subscriptionMode: "MASTER" |
| | | */ |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.redis.config.properties; |
| | | |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | import org.redisson.config.ReadMode; |
| | | import org.redisson.config.SubscriptionMode; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * Redisson é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "redisson") |
| | | public class RedissonProperties { |
| | | |
| | | /** |
| | | * redisç¼åkeyåç¼ |
| | | */ |
| | | private String keyPrefix; |
| | | |
| | | /** |
| | | * çº¿ç¨æ± æ°é,é»è®¤å¼ = å½åå¤çæ ¸æ°é * 2 |
| | | */ |
| | | private int threads; |
| | | |
| | | /** |
| | | * Nettyçº¿ç¨æ± æ°é,é»è®¤å¼ = å½åå¤çæ ¸æ°é * 2 |
| | | */ |
| | | private int nettyThreads; |
| | | |
| | | /** |
| | | * åæºæå¡é
ç½® |
| | | */ |
| | | private SingleServerConfig singleServerConfig; |
| | | |
| | | /** |
| | | * é群æå¡é
ç½® |
| | | */ |
| | | private ClusterServersConfig clusterServersConfig; |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | public static class SingleServerConfig { |
| | | |
| | | /** |
| | | * 客æ·ç«¯åç§° |
| | | */ |
| | | private String clientName; |
| | | |
| | | /** |
| | | * æå°ç©ºé²è¿æ¥æ° |
| | | */ |
| | | private int connectionMinimumIdleSize; |
| | | |
| | | /** |
| | | * è¿æ¥æ± å¤§å° |
| | | */ |
| | | private int connectionPoolSize; |
| | | |
| | | /** |
| | | * è¿æ¥ç©ºé²è¶
æ¶ï¼åä½ï¼æ¯«ç§ |
| | | */ |
| | | private int idleConnectionTimeout; |
| | | |
| | | /** |
| | | * å½ä»¤çå¾
è¶
æ¶ï¼åä½ï¼æ¯«ç§ |
| | | */ |
| | | private int timeout; |
| | | |
| | | /** |
| | | * åå¸å订é
è¿æ¥æ± å¤§å° |
| | | */ |
| | | private int subscriptionConnectionPoolSize; |
| | | |
| | | } |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | public static class ClusterServersConfig { |
| | | |
| | | /** |
| | | * 客æ·ç«¯åç§° |
| | | */ |
| | | private String clientName; |
| | | |
| | | /** |
| | | * masteræå°ç©ºé²è¿æ¥æ° |
| | | */ |
| | | private int masterConnectionMinimumIdleSize; |
| | | |
| | | /** |
| | | * masterè¿æ¥æ± å¤§å° |
| | | */ |
| | | private int masterConnectionPoolSize; |
| | | |
| | | /** |
| | | * slaveæå°ç©ºé²è¿æ¥æ° |
| | | */ |
| | | private int slaveConnectionMinimumIdleSize; |
| | | |
| | | /** |
| | | * slaveè¿æ¥æ± å¤§å° |
| | | */ |
| | | private int slaveConnectionPoolSize; |
| | | |
| | | /** |
| | | * è¿æ¥ç©ºé²è¶
æ¶ï¼åä½ï¼æ¯«ç§ |
| | | */ |
| | | private int idleConnectionTimeout; |
| | | |
| | | /** |
| | | * å½ä»¤çå¾
è¶
æ¶ï¼åä½ï¼æ¯«ç§ |
| | | */ |
| | | private int timeout; |
| | | |
| | | /** |
| | | * åå¸å订é
è¿æ¥æ± å¤§å° |
| | | */ |
| | | private int subscriptionConnectionPoolSize; |
| | | |
| | | /** |
| | | * è¯»åæ¨¡å¼ |
| | | */ |
| | | private ReadMode readMode; |
| | | |
| | | /** |
| | | * 订é
æ¨¡å¼ |
| | | */ |
| | | private SubscriptionMode subscriptionMode; |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.redis.handler; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import org.redisson.api.NameMapper; |
| | | |
| | | /** |
| | | * redisç¼åkeyåç¼å¤ç |
| | | * |
| | | * @author ye |
| | | * @date 2022/7/14 17:44 |
| | | * @since 4.3.0 |
| | | */ |
| | | public class KeyPrefixHandler implements NameMapper { |
| | | |
| | | private final String keyPrefix; |
| | | |
| | | public KeyPrefixHandler(String keyPrefix) { |
| | | //åç¼ä¸ºç©º åè¿å空åç¼ |
| | | this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + ":"; |
| | | } |
| | | |
| | | /** |
| | | * å¢å åç¼ |
| | | */ |
| | | @Override |
| | | public String map(String name) { |
| | | if (StringUtils.isBlank(name)) { |
| | | return null; |
| | | } |
| | | if (StringUtils.isNotBlank(keyPrefix) && !name.startsWith(keyPrefix)) { |
| | | return keyPrefix + name; |
| | | } |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * å»é¤åç¼ |
| | | */ |
| | | @Override |
| | | public String unmap(String name) { |
| | | if (StringUtils.isBlank(name)) { |
| | | return null; |
| | | } |
| | | if (StringUtils.isNotBlank(keyPrefix) && name.startsWith(keyPrefix)) { |
| | | return name.substring(keyPrefix.length()); |
| | | } |
| | | return name; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Copyright (c) 2013-2021 Nikita Koksharov |
| | | * |
| | | * 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 |
| | | * |
| | | * http://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 com.ruoyi.common.redis.manager; |
| | | |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import org.redisson.api.RMap; |
| | | import org.redisson.api.RMapCache; |
| | | import org.redisson.spring.cache.CacheConfig; |
| | | import org.redisson.spring.cache.RedissonCache; |
| | | import org.springframework.boot.convert.DurationStyle; |
| | | import org.springframework.cache.Cache; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.cache.transaction.TransactionAwareCacheDecorator; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | /** |
| | | * A {@link org.springframework.cache.CacheManager} implementation |
| | | * backed by Redisson instance. |
| | | * <p> |
| | | * ä¿®æ¹ RedissonSpringCacheManager æºç |
| | | * éå cacheName å¤çæ¹æ³ æ¯æå¤åæ° |
| | | * |
| | | * @author Nikita Koksharov |
| | | * |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public class PlusSpringCacheManager implements CacheManager { |
| | | |
| | | private boolean dynamic = true; |
| | | |
| | | private boolean allowNullValues = true; |
| | | |
| | | private boolean transactionAware = true; |
| | | |
| | | Map<String, CacheConfig> configMap = new ConcurrentHashMap<>(); |
| | | ConcurrentMap<String, Cache> instanceMap = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * Creates CacheManager supplied by Redisson instance |
| | | */ |
| | | public PlusSpringCacheManager() { |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Defines possibility of storing {@code null} values. |
| | | * <p> |
| | | * Default is <code>true</code> |
| | | * |
| | | * @param allowNullValues stores if <code>true</code> |
| | | */ |
| | | public void setAllowNullValues(boolean allowNullValues) { |
| | | this.allowNullValues = allowNullValues; |
| | | } |
| | | |
| | | /** |
| | | * Defines if cache aware of Spring-managed transactions. |
| | | * If {@code true} put/evict operations are executed only for successful transaction in after-commit phase. |
| | | * <p> |
| | | * Default is <code>false</code> |
| | | * |
| | | * @param transactionAware cache is transaction aware if <code>true</code> |
| | | */ |
| | | public void setTransactionAware(boolean transactionAware) { |
| | | this.transactionAware = transactionAware; |
| | | } |
| | | |
| | | /** |
| | | * Defines 'fixed' cache names. |
| | | * A new cache instance will not be created in dynamic for non-defined names. |
| | | * <p> |
| | | * `null` parameter setups dynamic mode |
| | | * |
| | | * @param names of caches |
| | | */ |
| | | public void setCacheNames(Collection<String> names) { |
| | | if (names != null) { |
| | | for (String name : names) { |
| | | getCache(name); |
| | | } |
| | | dynamic = false; |
| | | } else { |
| | | dynamic = true; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Set cache config mapped by cache name |
| | | * |
| | | * @param config object |
| | | */ |
| | | public void setConfig(Map<String, ? extends CacheConfig> config) { |
| | | this.configMap = (Map<String, CacheConfig>) config; |
| | | } |
| | | |
| | | protected CacheConfig createDefaultConfig() { |
| | | return new CacheConfig(); |
| | | } |
| | | |
| | | @Override |
| | | public Cache getCache(String name) { |
| | | Cache cache = instanceMap.get(name); |
| | | if (cache != null) { |
| | | return cache; |
| | | } |
| | | if (!dynamic) { |
| | | return cache; |
| | | } |
| | | |
| | | CacheConfig config = configMap.get(name); |
| | | if (config == null) { |
| | | config = createDefaultConfig(); |
| | | configMap.put(name, config); |
| | | } |
| | | |
| | | // éå cacheName æ¯æå¤åæ° |
| | | String[] array = StringUtils.delimitedListToStringArray(name, "#"); |
| | | name = array[0]; |
| | | if (array.length > 1) { |
| | | config.setTTL(DurationStyle.detectAndParse(array[1]).toMillis()); |
| | | } |
| | | if (array.length > 2) { |
| | | config.setMaxIdleTime(DurationStyle.detectAndParse(array[2]).toMillis()); |
| | | } |
| | | if (array.length > 3) { |
| | | config.setMaxSize(Integer.parseInt(array[3])); |
| | | } |
| | | |
| | | if (config.getMaxIdleTime() == 0 && config.getTTL() == 0 && config.getMaxSize() == 0) { |
| | | return createMap(name, config); |
| | | } |
| | | |
| | | return createMapCache(name, config); |
| | | } |
| | | |
| | | private Cache createMap(String name, CacheConfig config) { |
| | | RMap<Object, Object> map = RedisUtils.getClient().getMap(name); |
| | | |
| | | Cache cache = new RedissonCache(map, allowNullValues); |
| | | if (transactionAware) { |
| | | cache = new TransactionAwareCacheDecorator(cache); |
| | | } |
| | | Cache oldCache = instanceMap.putIfAbsent(name, cache); |
| | | if (oldCache != null) { |
| | | cache = oldCache; |
| | | } |
| | | return cache; |
| | | } |
| | | |
| | | private Cache createMapCache(String name, CacheConfig config) { |
| | | RMapCache<Object, Object> map = RedisUtils.getClient().getMapCache(name); |
| | | |
| | | Cache cache = new RedissonCache(map, config, allowNullValues); |
| | | if (transactionAware) { |
| | | cache = new TransactionAwareCacheDecorator(cache); |
| | | } |
| | | Cache oldCache = instanceMap.putIfAbsent(name, cache); |
| | | if (oldCache != null) { |
| | | cache = oldCache; |
| | | } else { |
| | | map.setMaxSize(config.getMaxSize()); |
| | | } |
| | | return cache; |
| | | } |
| | | |
| | | @Override |
| | | public Collection<String> getCacheNames() { |
| | | return Collections.unmodifiableSet(configMap.keySet()); |
| | | } |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.redis.utils; |
| | | |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.redisson.api.RMap; |
| | | import org.springframework.cache.Cache; |
| | | import org.springframework.cache.CacheManager; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * ç¼åæä½å·¥å
·ç±» {@link } |
| | | * |
| | | * @author Michelle.Chung |
| | | * @date 2022/8/13 |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | @SuppressWarnings(value = {"unchecked"}) |
| | | public class CacheUtils { |
| | | |
| | | private static final CacheManager CACHE_MANAGER = SpringUtils.getBean(CacheManager.class); |
| | | |
| | | /** |
| | | * è·åç¼åç»å
ææçKEY |
| | | * |
| | | * @param cacheNames ç¼åç»åç§° |
| | | */ |
| | | public static Set<Object> keys(String cacheNames) { |
| | | RMap<Object, Object> rmap = (RMap<Object, Object>) CACHE_MANAGER.getCache(cacheNames).getNativeCache(); |
| | | return rmap.keySet(); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¼åå¼ |
| | | * |
| | | * @param cacheNames ç¼åç»åç§° |
| | | * @param key ç¼åkey |
| | | */ |
| | | public static <T> T get(String cacheNames, Object key) { |
| | | Cache.ValueWrapper wrapper = CACHE_MANAGER.getCache(cacheNames).get(key); |
| | | return wrapper != null ? (T) wrapper.get() : null; |
| | | } |
| | | |
| | | /** |
| | | * ä¿åç¼åå¼ |
| | | * |
| | | * @param cacheNames ç¼åç»åç§° |
| | | * @param key ç¼åkey |
| | | * @param value ç¼åå¼ |
| | | */ |
| | | public static void put(String cacheNames, Object key, Object value) { |
| | | CACHE_MANAGER.getCache(cacheNames).put(key, value); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ç¼åå¼ |
| | | * |
| | | * @param cacheNames ç¼åç»åç§° |
| | | * @param key ç¼åkey |
| | | */ |
| | | public static void evict(String cacheNames, Object key) { |
| | | CACHE_MANAGER.getCache(cacheNames).evict(key); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
空ç¼åå¼ |
| | | * |
| | | * @param cacheNames ç¼åç»åç§° |
| | | */ |
| | | public static void clear(String cacheNames) { |
| | | CACHE_MANAGER.getCache(cacheNames).clear(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.redis.utils; |
| | | |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.redisson.api.*; |
| | | |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.function.Consumer; |
| | | |
| | | /** |
| | | * åå¸å¼éåå·¥å
· |
| | | * è½»é级éå ééçº§æ°æ®é è¯·ä½¿ç¨ MQ |
| | | * è¦æ± redis 5.X ä»¥ä¸ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.6.0 æ°å¢ |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class QueueUtils { |
| | | |
| | | private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class); |
| | | |
| | | |
| | | /** |
| | | * è·å客æ·ç«¯å®ä¾ |
| | | */ |
| | | public static RedissonClient getClient() { |
| | | return CLIENT; |
| | | } |
| | | |
| | | /** |
| | | * æ·»å æ®ééåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param data æ°æ® |
| | | */ |
| | | public static <T> boolean addQueueObject(String queueName, T data) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | return queue.offer(data); |
| | | } |
| | | |
| | | /** |
| | | * éç¨è·åä¸ä¸ªéåæ°æ® æ²¡ææ°æ®è¿å null(䏿¯æå»¶è¿éå) |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | public static <T> T getQueueObject(String queueName) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | return queue.poll(); |
| | | } |
| | | |
| | | /** |
| | | * éç¨å é¤éåæ°æ®(䏿¯æå»¶è¿éå) |
| | | */ |
| | | public static <T> boolean removeQueueObject(String queueName, T data) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | return queue.remove(data); |
| | | } |
| | | |
| | | /** |
| | | * éç¨éæ¯éå ææé»å¡çå¬ æ¥é(䏿¯æå»¶è¿éå) |
| | | */ |
| | | public static <T> boolean destroyQueue(String queueName) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | return queue.delete(); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å å»¶è¿éåæ°æ® é»è®¤æ¯«ç§ |
| | | * |
| | | * @param queueName éåå |
| | | * @param data æ°æ® |
| | | * @param time å»¶è¿æ¶é´ |
| | | */ |
| | | public static <T> void addDelayedQueueObject(String queueName, T data, long time) { |
| | | addDelayedQueueObject(queueName, data, time, TimeUnit.MILLISECONDS); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å å»¶è¿éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param data æ°æ® |
| | | * @param time å»¶è¿æ¶é´ |
| | | * @param timeUnit åä½ |
| | | */ |
| | | public static <T> void addDelayedQueueObject(String queueName, T data, long time, TimeUnit timeUnit) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue); |
| | | delayedQueue.offer(data, time, timeUnit); |
| | | } |
| | | |
| | | /** |
| | | * è·åä¸ä¸ªå»¶è¿éåæ°æ® æ²¡ææ°æ®è¿å null |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | public static <T> T getDelayedQueueObject(String queueName) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue); |
| | | return delayedQueue.poll(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å»¶è¿éåæ°æ® |
| | | */ |
| | | public static <T> boolean removeDelayedQueueObject(String queueName, T data) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue); |
| | | return delayedQueue.remove(data); |
| | | } |
| | | |
| | | /** |
| | | * 鿝延è¿éå ææé»å¡çå¬ æ¥é |
| | | */ |
| | | public static <T> void destroyDelayedQueue(String queueName) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue); |
| | | delayedQueue.destroy(); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å ä¼å
éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param data æ°æ® |
| | | */ |
| | | public static <T> boolean addPriorityQueueObject(String queueName, T data) { |
| | | RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName); |
| | | return priorityBlockingQueue.offer(data); |
| | | } |
| | | |
| | | /** |
| | | * å°è¯è®¾ç½® æçéå 容é ç¨äºéå¶æ°é |
| | | * |
| | | * @param queueName éåå |
| | | * @param capacity 容é |
| | | */ |
| | | public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity) { |
| | | RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName); |
| | | return boundedBlockingQueue.trySetCapacity(capacity); |
| | | } |
| | | |
| | | /** |
| | | * å°è¯è®¾ç½® æçéå 容é ç¨äºéå¶æ°é |
| | | * |
| | | * @param queueName éåå |
| | | * @param capacity 容é |
| | | * @param destroy å·²å卿¯å¦éæ¯ |
| | | */ |
| | | public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) { |
| | | RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName); |
| | | if (boundedBlockingQueue.isExists() && destroy) { |
| | | destroyQueue(queueName); |
| | | } |
| | | return boundedBlockingQueue.trySetCapacity(capacity); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å æçéåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param data æ°æ® |
| | | * @return æ·»å æå true 已达å°çé false |
| | | */ |
| | | public static <T> boolean addBoundedQueueObject(String queueName, T data) { |
| | | RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName); |
| | | return boundedBlockingQueue.offer(data); |
| | | } |
| | | |
| | | /** |
| | | * 订é
é»å¡éå(å¯è®¢é
ææå®ç°ç±» ä¾å¦: å»¶è¿ ä¼å
æç ç) |
| | | */ |
| | | public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer) { |
| | | RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName); |
| | | queue.subscribeOnElements(consumer); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.redis.utils; |
| | | |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.redisson.api.*; |
| | | |
| | | import java.time.Duration; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.function.Consumer; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | /** |
| | | * redis å·¥å
·ç±» |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.1.0 æ°å¢ |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | @SuppressWarnings(value = {"unchecked", "rawtypes"}) |
| | | public class RedisUtils { |
| | | |
| | | private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class); |
| | | |
| | | /** |
| | | * éæµ |
| | | * |
| | | * @param key éæµkey |
| | | * @param rateType éæµç±»å |
| | | * @param rate éç |
| | | * @param rateInterval éçé´é |
| | | * @return -1 表示失败 |
| | | */ |
| | | public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) { |
| | | RRateLimiter rateLimiter = CLIENT.getRateLimiter(key); |
| | | rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS); |
| | | if (rateLimiter.tryAcquire()) { |
| | | return rateLimiter.availablePermits(); |
| | | } else { |
| | | return -1L; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å客æ·ç«¯å®ä¾ |
| | | */ |
| | | public static RedissonClient getClient() { |
| | | return CLIENT; |
| | | } |
| | | |
| | | /** |
| | | * åå¸ééæ¶æ¯ |
| | | * |
| | | * @param channelKey éékey |
| | | * @param msg åéæ°æ® |
| | | * @param consumer èªå®ä¹å¤ç |
| | | */ |
| | | public static <T> void publish(String channelKey, T msg, Consumer<T> consumer) { |
| | | RTopic topic = CLIENT.getTopic(channelKey); |
| | | topic.publish(msg); |
| | | consumer.accept(msg); |
| | | } |
| | | |
| | | public static <T> void publish(String channelKey, T msg) { |
| | | RTopic topic = CLIENT.getTopic(channelKey); |
| | | topic.publish(msg); |
| | | } |
| | | |
| | | /** |
| | | * 订é
ééæ¥æ¶æ¶æ¯ |
| | | * |
| | | * @param channelKey éékey |
| | | * @param clazz æ¶æ¯ç±»å |
| | | * @param consumer èªå®ä¹å¤ç |
| | | */ |
| | | public static <T> void subscribe(String channelKey, Class<T> clazz, Consumer<T> consumer) { |
| | | RTopic topic = CLIENT.getTopic(channelKey); |
| | | topic.addListener(clazz, (channel, msg) -> consumer.accept(msg)); |
| | | } |
| | | |
| | | /** |
| | | * ç¼ååºæ¬ç对象ï¼IntegerãStringãå®ä½ç±»ç |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param value ç¼åçå¼ |
| | | */ |
| | | public static <T> void setCacheObject(final String key, final T value) { |
| | | setCacheObject(key, value, false); |
| | | } |
| | | |
| | | /** |
| | | * ç¼ååºæ¬ç对象ï¼ä¿çå½å对象 TTL æææ |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param value ç¼åçå¼ |
| | | * @param isSaveTtl æ¯å¦ä¿çTTLæææ(ä¾å¦: setä¹åttlå©ä½90 setä¹åè¿æ¯ä¸º90) |
| | | * @since Redis 6.X 以ä¸ä½¿ç¨ setAndKeepTTL å
¼å®¹ 5.X æ¹æ¡ |
| | | */ |
| | | public static <T> void setCacheObject(final String key, final T value, final boolean isSaveTtl) { |
| | | RBucket<T> bucket = CLIENT.getBucket(key); |
| | | if (isSaveTtl) { |
| | | try { |
| | | bucket.setAndKeepTTL(value); |
| | | } catch (Exception e) { |
| | | long timeToLive = bucket.remainTimeToLive(); |
| | | setCacheObject(key, value, Duration.ofMillis(timeToLive)); |
| | | } |
| | | } else { |
| | | bucket.set(value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç¼ååºæ¬ç对象ï¼IntegerãStringãå®ä½ç±»ç |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param value ç¼åçå¼ |
| | | * @param duration æ¶é´ |
| | | */ |
| | | public static <T> void setCacheObject(final String key, final T value, final Duration duration) { |
| | | RBatch batch = CLIENT.createBatch(); |
| | | RBucketAsync<T> bucket = batch.getBucket(key); |
| | | bucket.setAsync(value); |
| | | bucket.expireAsync(duration); |
| | | batch.execute(); |
| | | } |
| | | |
| | | /** |
| | | * 注å对象çå¬å¨ |
| | | * <p> |
| | | * key çå¬å¨éå¼å¯ `notify-keyspace-events` ç redis ç¸å
³é
ç½® |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param listener çå¬å¨é
ç½® |
| | | */ |
| | | public static <T> void addObjectListener(final String key, final ObjectListener listener) { |
| | | RBucket<T> result = CLIENT.getBucket(key); |
| | | result.addListener(listener); |
| | | } |
| | | |
| | | /** |
| | | * è®¾ç½®æææ¶é´ |
| | | * |
| | | * @param key Redisé® |
| | | * @param timeout è¶
æ¶æ¶é´ |
| | | * @return true=设置æåï¼false=设置失败 |
| | | */ |
| | | public static boolean expire(final String key, final long timeout) { |
| | | return expire(key, Duration.ofSeconds(timeout)); |
| | | } |
| | | |
| | | /** |
| | | * è®¾ç½®æææ¶é´ |
| | | * |
| | | * @param key Redisé® |
| | | * @param duration è¶
æ¶æ¶é´ |
| | | * @return true=设置æåï¼false=设置失败 |
| | | */ |
| | | public static boolean expire(final String key, final Duration duration) { |
| | | RBucket rBucket = CLIENT.getBucket(key); |
| | | return rBucket.expire(duration); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç¼åçåºæ¬å¯¹è±¡ã |
| | | * |
| | | * @param key ç¼åé®å¼ |
| | | * @return ç¼åé®å¼å¯¹åºçæ°æ® |
| | | */ |
| | | public static <T> T getCacheObject(final String key) { |
| | | RBucket<T> rBucket = CLIENT.getBucket(key); |
| | | return rBucket.get(); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾keyå©ä½åæ´»æ¶é´ |
| | | * |
| | | * @param key ç¼åé®å¼ |
| | | * @return å©ä½åæ´»æ¶é´ |
| | | */ |
| | | public static <T> long getTimeToLive(final String key) { |
| | | RBucket<T> rBucket = CLIENT.getBucket(key); |
| | | return rBucket.remainTimeToLive(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å个对象 |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | */ |
| | | public static boolean deleteObject(final String key) { |
| | | return CLIENT.getBucket(key).delete(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éå对象 |
| | | * |
| | | * @param collection å¤ä¸ªå¯¹è±¡ |
| | | */ |
| | | public static void deleteObject(final Collection collection) { |
| | | RBatch batch = CLIENT.createBatch(); |
| | | collection.forEach(t -> { |
| | | batch.getBucket(t.toString()).deleteAsync(); |
| | | }); |
| | | batch.execute(); |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥ç¼å对象æ¯å¦åå¨ |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | */ |
| | | public static boolean isExistsObject(final String key) { |
| | | return CLIENT.getBucket(key).isExists(); |
| | | } |
| | | |
| | | /** |
| | | * ç¼åListæ°æ® |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param dataList å¾
ç¼åçListæ°æ® |
| | | * @return ç¼åç对象 |
| | | */ |
| | | public static <T> boolean setCacheList(final String key, final List<T> dataList) { |
| | | RList<T> rList = CLIENT.getList(key); |
| | | return rList.addAll(dataList); |
| | | } |
| | | |
| | | /** |
| | | * 注åListçå¬å¨ |
| | | * <p> |
| | | * key çå¬å¨éå¼å¯ `notify-keyspace-events` ç redis ç¸å
³é
ç½® |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param listener çå¬å¨é
ç½® |
| | | */ |
| | | public static <T> void addListListener(final String key, final ObjectListener listener) { |
| | | RList<T> rList = CLIENT.getList(key); |
| | | rList.addListener(listener); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç¼åçlist对象 |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @return ç¼åé®å¼å¯¹åºçæ°æ® |
| | | */ |
| | | public static <T> List<T> getCacheList(final String key) { |
| | | RList<T> rList = CLIENT.getList(key); |
| | | return rList.readAll(); |
| | | } |
| | | |
| | | /** |
| | | * ç¼åSet |
| | | * |
| | | * @param key ç¼åé®å¼ |
| | | * @param dataSet ç¼åçæ°æ® |
| | | * @return ç¼åæ°æ®ç对象 |
| | | */ |
| | | public static <T> boolean setCacheSet(final String key, final Set<T> dataSet) { |
| | | RSet<T> rSet = CLIENT.getSet(key); |
| | | return rSet.addAll(dataSet); |
| | | } |
| | | |
| | | /** |
| | | * 注åSetçå¬å¨ |
| | | * <p> |
| | | * key çå¬å¨éå¼å¯ `notify-keyspace-events` ç redis ç¸å
³é
ç½® |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param listener çå¬å¨é
ç½® |
| | | */ |
| | | public static <T> void addSetListener(final String key, final ObjectListener listener) { |
| | | RSet<T> rSet = CLIENT.getSet(key); |
| | | rSet.addListener(listener); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç¼åçset |
| | | * |
| | | * @param key ç¼åçkey |
| | | * @return set对象 |
| | | */ |
| | | public static <T> Set<T> getCacheSet(final String key) { |
| | | RSet<T> rSet = CLIENT.getSet(key); |
| | | return rSet.readAll(); |
| | | } |
| | | |
| | | /** |
| | | * ç¼åMap |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param dataMap ç¼åçæ°æ® |
| | | */ |
| | | public static <T> void setCacheMap(final String key, final Map<String, T> dataMap) { |
| | | if (dataMap != null) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | rMap.putAll(dataMap); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 注åMapçå¬å¨ |
| | | * <p> |
| | | * key çå¬å¨éå¼å¯ `notify-keyspace-events` ç redis ç¸å
³é
ç½® |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @param listener çå¬å¨é
ç½® |
| | | */ |
| | | public static <T> void addMapListener(final String key, final ObjectListener listener) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | rMap.addListener(listener); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç¼åçMap |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @return map对象 |
| | | */ |
| | | public static <T> Map<String, T> getCacheMap(final String key) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | return rMap.getAll(rMap.keySet()); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç¼åMapçkeyå表 |
| | | * |
| | | * @param key ç¼åçé®å¼ |
| | | * @return keyå表 |
| | | */ |
| | | public static <T> Set<String> getCacheMapKeySet(final String key) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | return rMap.keySet(); |
| | | } |
| | | |
| | | /** |
| | | * å¾Hashä¸åå
¥æ°æ® |
| | | * |
| | | * @param key Redisé® |
| | | * @param hKey Hashé® |
| | | * @param value å¼ |
| | | */ |
| | | public static <T> void setCacheMapValue(final String key, final String hKey, final T value) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | rMap.put(hKey, value); |
| | | } |
| | | |
| | | /** |
| | | * è·åHashä¸çæ°æ® |
| | | * |
| | | * @param key Redisé® |
| | | * @param hKey Hashé® |
| | | * @return Hashä¸ç对象 |
| | | */ |
| | | public static <T> T getCacheMapValue(final String key, final String hKey) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | return rMap.get(hKey); |
| | | } |
| | | |
| | | /** |
| | | * å é¤Hashä¸çæ°æ® |
| | | * |
| | | * @param key Redisé® |
| | | * @param hKey Hashé® |
| | | * @return Hashä¸ç对象 |
| | | */ |
| | | public static <T> T delCacheMapValue(final String key, final String hKey) { |
| | | RMap<String, T> rMap = CLIENT.getMap(key); |
| | | return rMap.remove(hKey); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¤ä¸ªHashä¸çæ°æ® |
| | | * |
| | | * @param key Redisé® |
| | | * @param hKeys Hashé®éå |
| | | * @return Hash对象éå |
| | | */ |
| | | public static <K, V> Map<K, V> getMultiCacheMapValue(final String key, final Set<K> hKeys) { |
| | | RMap<K, V> rMap = CLIENT.getMap(key); |
| | | return rMap.getAll(hKeys); |
| | | } |
| | | |
| | | /** |
| | | * 设置ååå¼ |
| | | * |
| | | * @param key Redisé® |
| | | * @param value å¼ |
| | | */ |
| | | public static void setAtomicValue(String key, long value) { |
| | | RAtomicLong atomic = CLIENT.getAtomicLong(key); |
| | | atomic.set(value); |
| | | } |
| | | |
| | | /** |
| | | * è·åååå¼ |
| | | * |
| | | * @param key Redisé® |
| | | * @return å½åå¼ |
| | | */ |
| | | public static long getAtomicValue(String key) { |
| | | RAtomicLong atomic = CLIENT.getAtomicLong(key); |
| | | return atomic.get(); |
| | | } |
| | | |
| | | /** |
| | | * éå¢ååå¼ |
| | | * |
| | | * @param key Redisé® |
| | | * @return å½åå¼ |
| | | */ |
| | | public static long incrAtomicValue(String key) { |
| | | RAtomicLong atomic = CLIENT.getAtomicLong(key); |
| | | return atomic.incrementAndGet(); |
| | | } |
| | | |
| | | /** |
| | | * éåååå¼ |
| | | * |
| | | * @param key Redisé® |
| | | * @return å½åå¼ |
| | | */ |
| | | public static long decrAtomicValue(String key) { |
| | | RAtomicLong atomic = CLIENT.getAtomicLong(key); |
| | | return atomic.decrementAndGet(); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç¼åçåºæ¬å¯¹è±¡å表 |
| | | * |
| | | * @param pattern å符串åç¼ |
| | | * @return 对象å表 |
| | | */ |
| | | public static Collection<String> keys(final String pattern) { |
| | | Stream<String> stream = CLIENT.getKeys().getKeysStreamByPattern(pattern); |
| | | return stream.collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ç¼åçåºæ¬å¯¹è±¡å表 |
| | | * |
| | | * @param pattern å符串åç¼ |
| | | */ |
| | | public static void deleteKeys(final String pattern) { |
| | | CLIENT.getKeys().deleteByPattern(pattern); |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥redis䏿¯å¦åå¨key |
| | | * |
| | | * @param key é® |
| | | */ |
| | | public static Boolean hasKey(String key) { |
| | | RKeys rKeys = CLIENT.getKeys(); |
| | | return rKeys.countExists(key) > 0; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.redis.config.RedisConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- RuoYi Common Redis--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Sa-Token æé认è¯, å¨çº¿ææ¡£ï¼http://sa-token.dev33.cn/ --> |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-spring-boot3-starter</artifactId> |
| | | </dependency> |
| | | <!-- Sa-Token æ´å jwt --> |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-jwt</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.satoken.config; |
| | | |
| | | import cn.dev33.satoken.jwt.StpLogicJwtForSimple; |
| | | import cn.dev33.satoken.stp.StpLogic; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | /** |
| | | * sa-token é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | public class SaTokenConfig implements WebMvcConfigurer { |
| | | |
| | | @Bean |
| | | public StpLogic getStpLogicJwt() { |
| | | // Sa-Token æ´å jwt (ç®å模å¼) |
| | | return new StpLogicJwtForSimple(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.satoken.core.dao; |
| | | |
| | | import cn.dev33.satoken.dao.SaTokenDao; |
| | | import cn.dev33.satoken.util.SaFoxUtil; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.time.Duration; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Sa-Tokenæä¹
屿¥å£(ä½¿ç¨æ¡æ¶èªå¸¦RedisUtilså®ç° åè®®ç»ä¸) |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Component |
| | | public class PlusSaTokenDao implements SaTokenDao { |
| | | |
| | | /** |
| | | * è·åValueï¼å¦æ è¿ç©º |
| | | */ |
| | | @Override |
| | | public String get(String key) { |
| | | return RedisUtils.getCacheObject(key); |
| | | } |
| | | |
| | | /** |
| | | * åå
¥Valueï¼å¹¶è®¾å®åæ´»æ¶é´ (åä½: ç§) |
| | | */ |
| | | @Override |
| | | public void set(String key, String value, long timeout) { |
| | | if (timeout == 0 || timeout <= NOT_VALUE_EXPIRE) { |
| | | return; |
| | | } |
| | | // 夿æ¯å¦ä¸ºæ°¸ä¸è¿æ |
| | | if (timeout == NEVER_EXPIRE) { |
| | | RedisUtils.setCacheObject(key, value); |
| | | } else { |
| | | RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä¿®ä¿®æ¹æå®key-valueé®å¼å¯¹ (è¿ææ¶é´ä¸å) |
| | | */ |
| | | @Override |
| | | public void update(String key, String value) { |
| | | long expire = getTimeout(key); |
| | | // -2 = æ æ¤é® |
| | | if (expire == NOT_VALUE_EXPIRE) { |
| | | return; |
| | | } |
| | | this.set(key, value, expire); |
| | | } |
| | | |
| | | /** |
| | | * å é¤Value |
| | | */ |
| | | @Override |
| | | public void delete(String key) { |
| | | RedisUtils.deleteObject(key); |
| | | } |
| | | |
| | | /** |
| | | * è·åValueçå©ä½åæ´»æ¶é´ (åä½: ç§) |
| | | */ |
| | | @Override |
| | | public long getTimeout(String key) { |
| | | long timeout = RedisUtils.getTimeToLive(key); |
| | | return timeout < 0 ? timeout : timeout / 1000; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹Valueçå©ä½åæ´»æ¶é´ (åä½: ç§) |
| | | */ |
| | | @Override |
| | | public void updateTimeout(String key, long timeout) { |
| | | // 夿æ¯å¦æ³è¦è®¾ç½®ä¸ºæ°¸ä¹
|
| | | if (timeout == NEVER_EXPIRE) { |
| | | long expire = getTimeout(key); |
| | | if (expire == NEVER_EXPIRE) { |
| | | // 妿å
¶å·²ç»è¢«è®¾ç½®ä¸ºæ°¸ä¹
ï¼åä¸ä½ä»»ä½å¤ç |
| | | } else { |
| | | // 妿尿ªè¢«è®¾ç½®ä¸ºæ°¸ä¹
ï¼é£ä¹å次set䏿¬¡ |
| | | this.set(key, this.get(key), timeout); |
| | | } |
| | | return; |
| | | } |
| | | RedisUtils.expire(key, Duration.ofSeconds(timeout)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * è·åObjectï¼å¦æ è¿ç©º |
| | | */ |
| | | @Override |
| | | public Object getObject(String key) { |
| | | return RedisUtils.getCacheObject(key); |
| | | } |
| | | |
| | | /** |
| | | * åå
¥Objectï¼å¹¶è®¾å®åæ´»æ¶é´ (åä½: ç§) |
| | | */ |
| | | @Override |
| | | public void setObject(String key, Object object, long timeout) { |
| | | if (timeout == 0 || timeout <= NOT_VALUE_EXPIRE) { |
| | | return; |
| | | } |
| | | // 夿æ¯å¦ä¸ºæ°¸ä¸è¿æ |
| | | if (timeout == NEVER_EXPIRE) { |
| | | RedisUtils.setCacheObject(key, object); |
| | | } else { |
| | | RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ´æ°Object (è¿ææ¶é´ä¸å) |
| | | */ |
| | | @Override |
| | | public void updateObject(String key, Object object) { |
| | | long expire = getObjectTimeout(key); |
| | | // -2 = æ æ¤é® |
| | | if (expire == NOT_VALUE_EXPIRE) { |
| | | return; |
| | | } |
| | | this.setObject(key, object, expire); |
| | | } |
| | | |
| | | /** |
| | | * å é¤Object |
| | | */ |
| | | @Override |
| | | public void deleteObject(String key) { |
| | | RedisUtils.deleteObject(key); |
| | | } |
| | | |
| | | /** |
| | | * è·åObjectçå©ä½åæ´»æ¶é´ (åä½: ç§) |
| | | */ |
| | | @Override |
| | | public long getObjectTimeout(String key) { |
| | | long timeout = RedisUtils.getTimeToLive(key); |
| | | return timeout < 0 ? timeout : timeout / 1000; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹Objectçå©ä½åæ´»æ¶é´ (åä½: ç§) |
| | | */ |
| | | @Override |
| | | public void updateObjectTimeout(String key, long timeout) { |
| | | // 夿æ¯å¦æ³è¦è®¾ç½®ä¸ºæ°¸ä¹
|
| | | if (timeout == NEVER_EXPIRE) { |
| | | long expire = getObjectTimeout(key); |
| | | if (expire == NEVER_EXPIRE) { |
| | | // 妿å
¶å·²ç»è¢«è®¾ç½®ä¸ºæ°¸ä¹
ï¼åä¸ä½ä»»ä½å¤ç |
| | | } else { |
| | | // 妿尿ªè¢«è®¾ç½®ä¸ºæ°¸ä¹
ï¼é£ä¹å次set䏿¬¡ |
| | | this.setObject(key, this.getObject(key), timeout); |
| | | } |
| | | return; |
| | | } |
| | | RedisUtils.expire(key, Duration.ofSeconds(timeout)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æç´¢æ°æ® |
| | | */ |
| | | @Override |
| | | public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) { |
| | | Collection<String> keys = RedisUtils.keys(prefix + "*" + keyword + "*"); |
| | | List<String> list = new ArrayList<>(keys); |
| | | return SaFoxUtil.searchList(list, start, size, sortType); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.satoken.core.service; |
| | | |
| | | import cn.dev33.satoken.stp.StpInterface; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.core.enums.UserType; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * sa-token æé管çå®ç°ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Component |
| | | public class SaPermissionImpl implements StpInterface { |
| | | |
| | | /** |
| | | * è·åèåæéå表 |
| | | */ |
| | | @Override |
| | | public List<String> getPermissionList(Object loginId, String loginType) { |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | UserType userType = UserType.getUserType(loginUser.getUserType()); |
| | | if (userType == UserType.SYS_USER) { |
| | | return new ArrayList<>(loginUser.getMenuPermission()); |
| | | } else if (userType == UserType.APP_USER) { |
| | | // å
¶ä»ç«¯ èªè¡æ ¹æ®ä¸å¡ç¼å |
| | | } |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | /** |
| | | * è·åè§è²æéå表 |
| | | */ |
| | | @Override |
| | | public List<String> getRoleList(Object loginId, String loginType) { |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | UserType userType = UserType.getUserType(loginUser.getUserType()); |
| | | if (userType == UserType.SYS_USER) { |
| | | return new ArrayList<>(loginUser.getRolePermission()); |
| | | } else if (userType == UserType.APP_USER) { |
| | | // å
¶ä»ç«¯ èªè¡æ ¹æ®ä¸å¡ç¼å |
| | | } |
| | | return new ArrayList<>(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.satoken.listener; |
| | | |
| | | import cn.dev33.satoken.config.SaTokenConfig; |
| | | import cn.dev33.satoken.listener.SaTokenListener; |
| | | import cn.dev33.satoken.stp.SaLoginModel; |
| | | import cn.hutool.http.useragent.UserAgent; |
| | | import cn.hutool.http.useragent.UserAgentUtil; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.domain.dto.UserOnlineDTO; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.core.enums.UserType; |
| | | import com.ruoyi.common.core.utils.ServletUtils; |
| | | import com.ruoyi.common.core.utils.ip.AddressUtils; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.time.Duration; |
| | | |
| | | /** |
| | | * ç¨æ·è¡ä¸º 侦å¬å¨çå®ç° |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Component |
| | | @Slf4j |
| | | public class UserActionListener implements SaTokenListener { |
| | | |
| | | private final SaTokenConfig tokenConfig; |
| | | |
| | | /** |
| | | * æ¯æ¬¡ç»å½æ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { |
| | | UserType userType = UserType.getUserType(loginId.toString()); |
| | | if (userType == UserType.SYS_USER) { |
| | | UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); |
| | | String ip = ServletUtils.getClientIP(); |
| | | LoginUser user = LoginHelper.getLoginUser(); |
| | | UserOnlineDTO dto = new UserOnlineDTO(); |
| | | dto.setIpaddr(ip); |
| | | dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); |
| | | dto.setBrowser(userAgent.getBrowser().getName()); |
| | | dto.setOs(userAgent.getOs().getName()); |
| | | dto.setLoginTime(System.currentTimeMillis()); |
| | | dto.setTokenId(tokenValue); |
| | | dto.setUserName(user.getUsername()); |
| | | dto.setDeptName(user.getDeptName()); |
| | | if(tokenConfig.getTimeout() == -1) { |
| | | RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); |
| | | } else { |
| | | RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); |
| | | } |
| | | log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); |
| | | } else if (userType == UserType.APP_USER) { |
| | | // app端 èªè¡æ ¹æ®ä¸å¡ç¼å |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡æ³¨éæ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doLogout(String loginType, Object loginId, String tokenValue) { |
| | | RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); |
| | | log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue); |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡è¢«è¸¢ä¸çº¿æ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doKickout(String loginType, Object loginId, String tokenValue) { |
| | | RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); |
| | | log.info("user doLogoutByLoginId, userId:{}, token:{}", loginId, tokenValue); |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡è¢«é¡¶ä¸çº¿æ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doReplaced(String loginType, Object loginId, String tokenValue) { |
| | | RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); |
| | | log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue); |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡è¢«å°ç¦æ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) { |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡è¢«è§£å°æ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doUntieDisable(String loginType, Object loginId, String service) { |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡æå¼äºçº§è®¤è¯æ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) { |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡å建Sessionæ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doCloseSafe(String loginType, String tokenValue, String service) { |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡å建Sessionæ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doCreateSession(String id) { |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡æ³¨éSessionæ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doLogoutSession(String id) { |
| | | } |
| | | |
| | | /** |
| | | * æ¯æ¬¡Tokenç»ææ¶è§¦å |
| | | */ |
| | | @Override |
| | | public void doRenewTimeout(String tokenValue, Object loginId, long timeout) { |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.satoken.utils; |
| | | |
| | | import cn.dev33.satoken.context.SaHolder; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.core.enums.DeviceType; |
| | | import com.ruoyi.common.core.enums.UserType; |
| | | import com.ruoyi.common.core.exception.UtilException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * ç»å½é´æå©æ |
| | | * |
| | | * user_type 为 ç¨æ·ç±»å åä¸ä¸ªç¨æ·è¡¨ å¯ä»¥æå¤ç§ç¨æ·ç±»å ä¾å¦ pc,app |
| | | * deivce 为 设å¤ç±»å åä¸ä¸ªç¨æ·ç±»å å¯ä»¥æ å¤ç§è®¾å¤ç±»å ä¾å¦ web,ios |
| | | * å¯ä»¥ç»æ ç¨æ·ç±»åä¸è®¾å¤ç±»åå¤å¯¹å¤ç æéçµæ´»æ§å¶ |
| | | * |
| | | * å¤ç¨æ·ä½ç³» é对 å¤ç§ç¨æ·ç±»å 使鿧å¶ä¸ä¸è´ |
| | | * å¯ä»¥ç»æ å¤ç¨æ·ç±»å表ä¸å¤è®¾å¤ç±»å å嫿§å¶æé |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class LoginHelper { |
| | | |
| | | public static final String JOIN_CODE = ":"; |
| | | public static final String LOGIN_USER_KEY = "loginUser"; |
| | | |
| | | /** |
| | | * ç»å½ç³»ç» |
| | | * |
| | | * @param loginUser ç»å½ç¨æ·ä¿¡æ¯ |
| | | */ |
| | | public static void login(LoginUser loginUser) { |
| | | SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); |
| | | StpUtil.login(loginUser.getLoginId()); |
| | | setLoginUser(loginUser); |
| | | } |
| | | |
| | | /** |
| | | * ç»å½ç³»ç» åºäº 设å¤ç±»å |
| | | * é对ç¸åç¨æ·ä½ç³»ä¸åè®¾å¤ |
| | | * |
| | | * @param loginUser ç»å½ç¨æ·ä¿¡æ¯ |
| | | */ |
| | | public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) { |
| | | SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); |
| | | StpUtil.login(loginUser.getLoginId(), deviceType.getDevice()); |
| | | setLoginUser(loginUser); |
| | | } |
| | | |
| | | /** |
| | | * è®¾ç½®ç¨æ·æ°æ®(å¤çº§ç¼å) |
| | | */ |
| | | public static void setLoginUser(LoginUser loginUser) { |
| | | StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·(å¤çº§ç¼å) |
| | | */ |
| | | public static LoginUser getLoginUser() { |
| | | LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY); |
| | | if (loginUser != null) { |
| | | return loginUser; |
| | | } |
| | | loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY); |
| | | SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); |
| | | return loginUser; |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·id |
| | | */ |
| | | public static Long getUserId() { |
| | | LoginUser loginUser = getLoginUser(); |
| | | if (ObjectUtil.isNull(loginUser)) { |
| | | String loginId = StpUtil.getLoginIdAsString(); |
| | | String userId = null; |
| | | for (UserType value : UserType.values()) { |
| | | if (StringUtils.contains(loginId, value.getUserType())) { |
| | | String[] strs = StringUtils.split(loginId, JOIN_CODE); |
| | | // ç¨æ·id卿»æ¯å¨æå |
| | | userId = strs[strs.length - 1]; |
| | | } |
| | | } |
| | | if (StringUtils.isBlank(userId)) { |
| | | throw new UtilException("ç»å½ç¨æ·: LoginIdå¼å¸¸ => " + loginId); |
| | | } |
| | | return Long.parseLong(userId); |
| | | } |
| | | return loginUser.getUserId(); |
| | | } |
| | | |
| | | /** |
| | | * è·åé¨é¨ID |
| | | */ |
| | | public static Long getDeptId() { |
| | | return getLoginUser().getDeptId(); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·è´¦æ· |
| | | */ |
| | | public static String getUsername() { |
| | | return getLoginUser().getUsername(); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·ç±»å |
| | | */ |
| | | public static UserType getUserType() { |
| | | String loginId = StpUtil.getLoginIdAsString(); |
| | | return UserType.getUserType(loginId); |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºç®¡çå |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return ç»æ |
| | | */ |
| | | public static boolean isAdmin(Long userId) { |
| | | return UserConstants.ADMIN_ID.equals(userId); |
| | | } |
| | | |
| | | public static boolean isAdmin() { |
| | | return isAdmin(getUserId()); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.satoken.core.dao.PlusSaTokenDao |
| | | com.ruoyi.common.satoken.core.service.SaPermissionImpl |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-security</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-security å®å
¨æ¨¡å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Sa-Token æé认è¯, å¨çº¿ææ¡£ï¼http://sa-token.dev33.cn/ --> |
| | | <dependency> |
| | | <groupId>cn.dev33</groupId> |
| | | <artifactId>sa-token-spring-boot3-starter</artifactId> |
| | | <version>${satoken.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.security.config; |
| | | |
| | | import cn.dev33.satoken.interceptor.SaInterceptor; |
| | | import cn.dev33.satoken.router.SaRouter; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import com.ruoyi.common.security.config.properties.SecurityProperties; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | /** |
| | | * æéå®å
¨é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Slf4j |
| | | @AutoConfiguration |
| | | public class SecurityConfig implements WebMvcConfigurer { |
| | | |
| | | private final SecurityProperties securityProperties; |
| | | |
| | | /** |
| | | * 注åsa-tokençæ¦æªå¨ |
| | | */ |
| | | @Override |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | // 注åè·¯ç±æ¦æªå¨ï¼èªå®ä¹éªè¯è§å |
| | | registry.addInterceptor(new SaInterceptor(handler -> { |
| | | // ç»å½éªè¯ -- æé¤å¤ä¸ªè·¯å¾ |
| | | SaRouter |
| | | // è·åææç |
| | | .match("/**") |
| | | // å¯¹æªæé¤çè·¯å¾è¿è¡æ£æ¥ |
| | | .check(() -> { |
| | | // æ£æ¥æ¯å¦ç»å½ æ¯å¦ætoken |
| | | StpUtil.checkLogin(); |
| | | |
| | | // ææçå½±å ç¨äºä¸´æ¶æµè¯ |
| | | // if (log.isDebugEnabled()) { |
| | | // log.debug("å©ä½æææ¶é´: {}", StpUtil.getTokenTimeout()); |
| | | // log.debug("ä¸´æ¶æææ¶é´: {}", StpUtil.getTokenActivityTimeout()); |
| | | // } |
| | | |
| | | }); |
| | | })).addPathPatterns("/**") |
| | | // æé¤ä¸éè¦æ¦æªçè·¯å¾ |
| | | .excludePathPatterns(securityProperties.getExcludes()); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.security.config.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * Security é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "security") |
| | | public class SecurityProperties { |
| | | |
| | | /** |
| | | * æé¤è·¯å¾ |
| | | */ |
| | | private String[] excludes; |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.security.handler; |
| | | |
| | | import cn.dev33.satoken.exception.NotLoginException; |
| | | import cn.dev33.satoken.exception.NotPermissionException; |
| | | import cn.dev33.satoken.exception.NotRoleException; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.exception.DemoModeException; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StreamUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.support.DefaultMessageSourceResolvable; |
| | | import org.springframework.validation.BindException; |
| | | import org.springframework.web.HttpRequestMethodNotSupportedException; |
| | | import org.springframework.web.bind.MethodArgumentNotValidException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.validation.ConstraintViolation; |
| | | import jakarta.validation.ConstraintViolationException; |
| | | |
| | | /** |
| | | * å
¨å±å¼å¸¸å¤çå¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @RestControllerAdvice |
| | | public class GlobalExceptionHandler { |
| | | |
| | | /** |
| | | * æéç å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(NotPermissionException.class) |
| | | public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',æéç æ ¡éªå¤±è´¥'{}'", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_FORBIDDEN, "没æè®¿é®æéï¼è¯·è系管çåææ"); |
| | | } |
| | | |
| | | /** |
| | | * è§è²æéå¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(NotRoleException.class) |
| | | public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',è§è²æéæ ¡éªå¤±è´¥'{}'", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_FORBIDDEN, "没æè®¿é®æéï¼è¯·è系管çåææ"); |
| | | } |
| | | |
| | | /** |
| | | * 认è¯å¤±è´¥ |
| | | */ |
| | | @ExceptionHandler(NotLoginException.class) |
| | | public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',认è¯å¤±è´¥'{}',æ æ³è®¿é®ç³»ç»èµæº", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº"); |
| | | } |
| | | |
| | | /** |
| | | * è¯·æ±æ¹å¼ä¸æ¯æ |
| | | */ |
| | | @ExceptionHandler(HttpRequestMethodNotSupportedException.class) |
| | | public R<Void> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, |
| | | HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',䏿¯æ'{}'请æ±", requestURI, e.getMethod()); |
| | | return R.fail(e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | | * ä¸å¡å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(ServiceException.class) |
| | | public R<Void> handleServiceException(ServiceException e, HttpServletRequest request) { |
| | | log.error(e.getMessage(), e); |
| | | Integer code = e.getCode(); |
| | | return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | | * æ¦æªæªç¥çè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(RuntimeException.class) |
| | | public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',åçæªç¥å¼å¸¸.", requestURI, e); |
| | | return R.fail(e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | | * ç³»ç»å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(Exception.class) |
| | | public R<Void> handleException(Exception e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',åçç³»ç»å¼å¸¸.", requestURI, e); |
| | | return R.fail(e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹éªè¯å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(BindException.class) |
| | | public R<Void> handleBindException(BindException e) { |
| | | log.error(e.getMessage(), e); |
| | | String message = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ", "); |
| | | return R.fail(message); |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹éªè¯å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(ConstraintViolationException.class) |
| | | public R<Void> constraintViolationException(ConstraintViolationException e) { |
| | | log.error(e.getMessage(), e); |
| | | String message = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ", "); |
| | | return R.fail(message); |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹éªè¯å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(MethodArgumentNotValidException.class) |
| | | public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { |
| | | log.error(e.getMessage(), e); |
| | | String message = e.getBindingResult().getFieldError().getDefaultMessage(); |
| | | return R.fail(message); |
| | | } |
| | | |
| | | /** |
| | | * æ¼ç¤ºæ¨¡å¼å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(DemoModeException.class) |
| | | public R<Void> handleDemoModeException(DemoModeException e) { |
| | | return R.fail("æ¼ç¤ºæ¨¡å¼ï¼ä¸å
许æä½"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.security.handler.GlobalExceptionHandler |
| | | com.ruoyi.common.security.config.SecurityConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-sms</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-sms ç信模å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.aliyun</groupId> |
| | | <artifactId>dysmsapi20170525</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.tencentcloudapi</groupId> |
| | | <artifactId>tencentcloud-sdk-java-sms</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.config; |
| | | |
| | | import com.ruoyi.common.sms.config.properties.SmsProperties; |
| | | import com.ruoyi.common.sms.core.AliyunSmsTemplate; |
| | | import com.ruoyi.common.sms.core.SmsTemplate; |
| | | import com.ruoyi.common.sms.core.TencentSmsTemplate; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * çä¿¡é
置类 |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | */ |
| | | @AutoConfiguration |
| | | @EnableConfigurationProperties(SmsProperties.class) |
| | | public class SmsConfig { |
| | | |
| | | @Configuration |
| | | @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") |
| | | @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) |
| | | static class AliyunSmsConfig { |
| | | |
| | | @Bean |
| | | public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) { |
| | | return new AliyunSmsTemplate(smsProperties); |
| | | } |
| | | |
| | | } |
| | | |
| | | @Configuration |
| | | @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") |
| | | @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) |
| | | static class TencentSmsConfig { |
| | | |
| | | @Bean |
| | | public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) { |
| | | return new TencentSmsTemplate(smsProperties); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.config.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * SMSçä¿¡ é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "sms") |
| | | public class SmsProperties { |
| | | |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * é
ç½®èç¹ |
| | | * é¿éäº dysmsapi.aliyuncs.com |
| | | * è
¾è®¯äº sms.tencentcloudapi.com |
| | | */ |
| | | private String endpoint; |
| | | |
| | | /** |
| | | * key |
| | | */ |
| | | private String accessKeyId; |
| | | |
| | | /** |
| | | * å¯å |
| | | */ |
| | | private String accessKeySecret; |
| | | |
| | | /* |
| | | * çä¿¡ç¾å |
| | | */ |
| | | private String signName; |
| | | |
| | | /** |
| | | * çä¿¡åºç¨ID (è
¾è®¯ä¸å±) |
| | | */ |
| | | private String sdkAppId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.core; |
| | | |
| | | import com.aliyun.dysmsapi20170525.Client; |
| | | import com.aliyun.dysmsapi20170525.models.SendSmsRequest; |
| | | import com.aliyun.dysmsapi20170525.models.SendSmsResponse; |
| | | import com.aliyun.teaopenapi.models.Config; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.sms.config.properties.SmsProperties; |
| | | import com.ruoyi.common.sms.entity.SmsResult; |
| | | import com.ruoyi.common.sms.exception.SmsException; |
| | | import lombok.SneakyThrows; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Aliyun çä¿¡æ¨¡æ¿ |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | */ |
| | | public class AliyunSmsTemplate implements SmsTemplate { |
| | | |
| | | private SmsProperties properties; |
| | | |
| | | private Client client; |
| | | |
| | | @SneakyThrows(Exception.class) |
| | | public AliyunSmsTemplate(SmsProperties smsProperties) { |
| | | this.properties = smsProperties; |
| | | Config config = new Config() |
| | | // æ¨çAccessKey ID |
| | | .setAccessKeyId(smsProperties.getAccessKeyId()) |
| | | // æ¨çAccessKey Secret |
| | | .setAccessKeySecret(smsProperties.getAccessKeySecret()) |
| | | // 访é®çåå |
| | | .setEndpoint(smsProperties.getEndpoint()); |
| | | this.client = new Client(config); |
| | | } |
| | | |
| | | @Override |
| | | public SmsResult send(String phones, String templateId, Map<String, String> param) { |
| | | if (StringUtils.isBlank(phones)) { |
| | | throw new SmsException("ææºå·ä¸è½ä¸ºç©º"); |
| | | } |
| | | if (StringUtils.isBlank(templateId)) { |
| | | throw new SmsException("模æ¿IDä¸è½ä¸ºç©º"); |
| | | } |
| | | SendSmsRequest req = new SendSmsRequest() |
| | | .setPhoneNumbers(phones) |
| | | .setSignName(properties.getSignName()) |
| | | .setTemplateCode(templateId) |
| | | .setTemplateParam(JsonUtils.toJsonString(param)); |
| | | try { |
| | | SendSmsResponse resp = client.sendSms(req); |
| | | return SmsResult.builder() |
| | | .isSuccess("OK".equals(resp.getBody().getCode())) |
| | | .message(resp.getBody().getMessage()) |
| | | .response(JsonUtils.toJsonString(resp)) |
| | | .build(); |
| | | } catch (Exception e) { |
| | | throw new SmsException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.core; |
| | | |
| | | import com.ruoyi.common.sms.entity.SmsResult; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * çä¿¡æ¨¡æ¿ |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | */ |
| | | public interface SmsTemplate { |
| | | |
| | | /** |
| | | * åéçä¿¡ |
| | | * |
| | | * @param phones çµè¯å·(å¤ä¸ªéå·åå²) |
| | | * @param templateId 模æ¿id |
| | | * @param param 模æ¿å¯¹åºåæ° |
| | | * é¿é éä½¿ç¨ æ¨¡æ¿åéå称对åºå
容 ä¾å¦: code=1234 |
| | | * è
¾è®¯ éä½¿ç¨ æ¨¡æ¿åé顺åºå¯¹åºå
容 ä¾å¦: 1=1234, 1为模æ¿å
第ä¸ä¸ªåæ° |
| | | */ |
| | | SmsResult send(String phones, String templateId, Map<String, String> param); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.core; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.sms.config.properties.SmsProperties; |
| | | import com.ruoyi.common.sms.entity.SmsResult; |
| | | import com.ruoyi.common.sms.exception.SmsException; |
| | | import com.tencentcloudapi.common.Credential; |
| | | import com.tencentcloudapi.common.profile.ClientProfile; |
| | | import com.tencentcloudapi.common.profile.HttpProfile; |
| | | import com.tencentcloudapi.sms.v20190711.SmsClient; |
| | | import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; |
| | | import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; |
| | | import com.tencentcloudapi.sms.v20190711.models.SendStatus; |
| | | import lombok.SneakyThrows; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * Tencent çä¿¡æ¨¡æ¿ |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | */ |
| | | public class TencentSmsTemplate implements SmsTemplate { |
| | | |
| | | private SmsProperties properties; |
| | | |
| | | private SmsClient client; |
| | | |
| | | @SneakyThrows(Exception.class) |
| | | public TencentSmsTemplate(SmsProperties smsProperties) { |
| | | this.properties = smsProperties; |
| | | Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret()); |
| | | HttpProfile httpProfile = new HttpProfile(); |
| | | httpProfile.setEndpoint(smsProperties.getEndpoint()); |
| | | ClientProfile clientProfile = new ClientProfile(); |
| | | clientProfile.setHttpProfile(httpProfile); |
| | | this.client = new SmsClient(credential, "", clientProfile); |
| | | } |
| | | |
| | | @Override |
| | | public SmsResult send(String phones, String templateId, Map<String, String> param) { |
| | | if (StringUtils.isBlank(phones)) { |
| | | throw new SmsException("ææºå·ä¸è½ä¸ºç©º"); |
| | | } |
| | | if (StringUtils.isBlank(templateId)) { |
| | | throw new SmsException("模æ¿IDä¸è½ä¸ºç©º"); |
| | | } |
| | | SendSmsRequest req = new SendSmsRequest(); |
| | | Set<String> set = Arrays.stream(phones.split(",")).map(p -> "+86" + p).collect(Collectors.toSet()); |
| | | req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class)); |
| | | if (CollUtil.isNotEmpty(param)) { |
| | | req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class)); |
| | | } |
| | | req.setTemplateID(templateId); |
| | | req.setSign(properties.getSignName()); |
| | | req.setSmsSdkAppid(properties.getSdkAppId()); |
| | | try { |
| | | SendSmsResponse resp = client.SendSms(req); |
| | | SmsResult.SmsResultBuilder builder = SmsResult.builder() |
| | | .isSuccess(true) |
| | | .message("send success") |
| | | .response(JsonUtils.toJsonString(resp)); |
| | | for (SendStatus sendStatus : resp.getSendStatusSet()) { |
| | | if (!"Ok".equals(sendStatus.getCode())) { |
| | | builder.isSuccess(false).message(sendStatus.getMessage()); |
| | | break; |
| | | } |
| | | } |
| | | return builder.build(); |
| | | } catch (Exception e) { |
| | | throw new SmsException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.entity; |
| | | |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * ä¸ä¼ è¿åä½ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Builder |
| | | public class SmsResult { |
| | | |
| | | /** |
| | | * æ¯å¦æå |
| | | */ |
| | | private boolean isSuccess; |
| | | |
| | | /** |
| | | * ååºæ¶æ¯ |
| | | */ |
| | | private String message; |
| | | |
| | | /** |
| | | * å®é
ååºä½ |
| | | * <p> |
| | | * å¯èªè¡è½¬æ¢ä¸º SDK 对åºç SendSmsResponse |
| | | */ |
| | | private String response; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.sms.exception; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * Smså¼å¸¸ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class SmsException extends RuntimeException { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public SmsException(String msg) { |
| | | super(msg); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.sms.config.SmsConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | |
| | | <description> |
| | | ruoyi-common-web webæå¡ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- SpringBoot Webå®¹å¨ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | <groupId>org.springframework.boot</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <!-- web 容å¨ä½¿ç¨ undertow æ§è½æ´å¼º --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-undertow</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-crypto</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>transmittable-thread-local</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config; |
| | | |
| | | import cn.hutool.captcha.CaptchaUtil; |
| | | import cn.hutool.captcha.CircleCaptcha; |
| | | import cn.hutool.captcha.LineCaptcha; |
| | | import cn.hutool.captcha.ShearCaptcha; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Lazy; |
| | | |
| | | import java.awt.*; |
| | | |
| | | /** |
| | | * éªè¯ç é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | public class CaptchaConfig { |
| | | |
| | | private static final int WIDTH = 160; |
| | | private static final int HEIGHT = 60; |
| | | private static final Color BACKGROUND = Color.PINK; |
| | | private static final Font FONT = new Font("Arial", Font.BOLD, 48); |
| | | |
| | | /** |
| | | * ååå¹²æ°éªè¯ç |
| | | */ |
| | | @Lazy |
| | | @Bean |
| | | public CircleCaptcha circleCaptcha() { |
| | | CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(WIDTH, HEIGHT); |
| | | captcha.setBackground(BACKGROUND); |
| | | captcha.setFont(FONT); |
| | | return captcha; |
| | | } |
| | | |
| | | /** |
| | | * 线段干æ°çéªè¯ç |
| | | */ |
| | | @Lazy |
| | | @Bean |
| | | public LineCaptcha lineCaptcha() { |
| | | LineCaptcha captcha = CaptchaUtil.createLineCaptcha(WIDTH, HEIGHT); |
| | | captcha.setBackground(BACKGROUND); |
| | | captcha.setFont(FONT); |
| | | return captcha; |
| | | } |
| | | |
| | | /** |
| | | * ææ²å¹²æ°éªè¯ç |
| | | */ |
| | | @Lazy |
| | | @Bean |
| | | public ShearCaptcha shearCaptcha() { |
| | | ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(WIDTH, HEIGHT); |
| | | captcha.setBackground(BACKGROUND); |
| | | captcha.setFont(FONT); |
| | | return captcha; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.web.config.properties.XssProperties; |
| | | import com.ruoyi.common.web.filter.RepeatableFilter; |
| | | import com.ruoyi.common.web.filter.XssFilter; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import jakarta.servlet.DispatcherType; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Filteré
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | public class FilterConfig { |
| | | |
| | | @Autowired |
| | | private XssProperties xssProperties; |
| | | |
| | | @SuppressWarnings({"rawtypes", "unchecked"}) |
| | | @Bean |
| | | @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") |
| | | public FilterRegistrationBean xssFilterRegistration() { |
| | | FilterRegistrationBean registration = new FilterRegistrationBean(); |
| | | registration.setDispatcherTypes(DispatcherType.REQUEST); |
| | | registration.setFilter(new XssFilter()); |
| | | registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), ",")); |
| | | registration.setName("xssFilter"); |
| | | registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); |
| | | Map<String, String> initParameters = new HashMap<String, String>(); |
| | | initParameters.put("excludes", xssProperties.getExcludes()); |
| | | registration.setInitParameters(initParameters); |
| | | return registration; |
| | | } |
| | | |
| | | @SuppressWarnings({"rawtypes", "unchecked"}) |
| | | @Bean |
| | | public FilterRegistrationBean someFilterRegistration() { |
| | | FilterRegistrationBean registration = new FilterRegistrationBean(); |
| | | registration.setFilter(new RepeatableFilter()); |
| | | registration.addUrlPatterns("/*"); |
| | | registration.setName("repeatableFilter"); |
| | | registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); |
| | | return registration; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config; |
| | | |
| | | import com.ruoyi.common.web.core.I18nLocaleResolver; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | |
| | | /** |
| | | * å½é
åé
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration(before = WebMvcAutoConfiguration.class) |
| | | public class I18nConfig { |
| | | |
| | | @Bean |
| | | public LocaleResolver localeResolver() { |
| | | return new I18nLocaleResolver(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config; |
| | | |
| | | import com.ruoyi.common.web.interceptor.PlusWebInvokeTimeInterceptor; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.web.cors.CorsConfiguration; |
| | | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| | | import org.springframework.web.filter.CorsFilter; |
| | | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
| | | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | /** |
| | | * éç¨é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | public class ResourcesConfig implements WebMvcConfigurer { |
| | | |
| | | @Override |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | // å
¨å±è®¿é®æ§è½æ¦æª |
| | | registry.addInterceptor(new PlusWebInvokeTimeInterceptor()); |
| | | } |
| | | |
| | | @Override |
| | | public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| | | } |
| | | |
| | | /** |
| | | * è·¨åé
ç½® |
| | | */ |
| | | @Bean |
| | | public CorsFilter corsFilter() { |
| | | CorsConfiguration config = new CorsConfiguration(); |
| | | config.setAllowCredentials(true); |
| | | // è®¾ç½®è®¿é®æºå°å |
| | | config.addAllowedOriginPattern("*"); |
| | | // è®¾ç½®è®¿é®æºè¯·æ±å¤´ |
| | | config.addAllowedHeader("*"); |
| | | // è®¾ç½®è®¿é®æºè¯·æ±æ¹æ³ |
| | | config.addAllowedMethod("*"); |
| | | // æææ 1800ç§ |
| | | config.setMaxAge(1800L); |
| | | // æ·»å æ å°è·¯å¾ï¼æ¦æªä¸åè¯·æ± |
| | | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
| | | source.registerCorsConfiguration("/**", config); |
| | | // è¿åæ°çCorsFilter |
| | | return new CorsFilter(source); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config; |
| | | |
| | | import io.undertow.server.DefaultByteBufferPool; |
| | | import io.undertow.websockets.jsr.WebSocketDeploymentInfo; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; |
| | | import org.springframework.boot.web.server.WebServerFactoryCustomizer; |
| | | |
| | | /** |
| | | * Undertow èªå®ä¹é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> { |
| | | |
| | | /** |
| | | * 设置 Undertow ç websocket ç¼å²æ± |
| | | */ |
| | | @Override |
| | | public void customize(UndertowServletWebServerFactory factory) { |
| | | // é»è®¤ä¸ç´æ¥åé
å
å 妿项ç®ä¸ä½¿ç¨äº websocket å»ºè®®ç´æ¥åé
|
| | | factory.addDeploymentInfoCustomizers(deploymentInfo -> { |
| | | WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo(); |
| | | webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 512)); |
| | | deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo); |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config.properties; |
| | | |
| | | import com.ruoyi.common.web.enums.CaptchaCategory; |
| | | import com.ruoyi.common.web.enums.CaptchaType; |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * éªè¯ç é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "captcha") |
| | | public class CaptchaProperties { |
| | | |
| | | /** |
| | | * éªè¯ç ç±»å |
| | | */ |
| | | private CaptchaType type; |
| | | |
| | | /** |
| | | * éªè¯ç ç±»å« |
| | | */ |
| | | private CaptchaCategory category; |
| | | |
| | | /** |
| | | * æ°åéªè¯ç 使° |
| | | */ |
| | | private Integer numberLength; |
| | | |
| | | /** |
| | | * å符éªè¯ç é¿åº¦ |
| | | */ |
| | | private Integer charLength; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.config.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * xssè¿æ»¤ é
ç½®å±æ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "xss") |
| | | public class XssProperties { |
| | | |
| | | /** |
| | | * è¿æ»¤å¼å
³ |
| | | */ |
| | | private String enabled; |
| | | |
| | | /** |
| | | * æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | */ |
| | | private String excludes; |
| | | |
| | | /** |
| | | * å¹é
龿¥ |
| | | */ |
| | | private String urlPatterns; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.core; |
| | | |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.Locale; |
| | | |
| | | /** |
| | | * è·å请æ±å¤´å½é
åä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class I18nLocaleResolver implements LocaleResolver { |
| | | |
| | | @Override |
| | | public Locale resolveLocale(HttpServletRequest httpServletRequest) { |
| | | String language = httpServletRequest.getHeader("content-language"); |
| | | Locale locale = Locale.getDefault(); |
| | | if (language != null && language.length() > 0) { |
| | | String[] split = language.split("_"); |
| | | locale = new Locale(split[0], split[1]); |
| | | } |
| | | return locale; |
| | | } |
| | | |
| | | @Override |
| | | public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { |
| | | |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.enums; |
| | | |
| | | import cn.hutool.captcha.AbstractCaptcha; |
| | | import cn.hutool.captcha.CircleCaptcha; |
| | | import cn.hutool.captcha.LineCaptcha; |
| | | import cn.hutool.captcha.ShearCaptcha; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * éªè¯ç ç±»å« |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum CaptchaCategory { |
| | | |
| | | /** |
| | | * çº¿æ®µå¹²æ° |
| | | */ |
| | | LINE(LineCaptcha.class), |
| | | |
| | | /** |
| | | * ååå¹²æ° |
| | | */ |
| | | CIRCLE(CircleCaptcha.class), |
| | | |
| | | /** |
| | | * ææ²å¹²æ° |
| | | */ |
| | | SHEAR(ShearCaptcha.class); |
| | | |
| | | private final Class<? extends AbstractCaptcha> clazz; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.enums; |
| | | |
| | | import cn.hutool.captcha.generator.CodeGenerator; |
| | | import cn.hutool.captcha.generator.RandomGenerator; |
| | | import com.ruoyi.common.web.utils.UnsignedMathGenerator; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * éªè¯ç ç±»å |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum CaptchaType { |
| | | |
| | | /** |
| | | * æ°å |
| | | */ |
| | | MATH(UnsignedMathGenerator.class), |
| | | |
| | | /** |
| | | * å符 |
| | | */ |
| | | CHAR(RandomGenerator.class); |
| | | |
| | | private final Class<? extends CodeGenerator> clazz; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.filter; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import org.springframework.http.MediaType; |
| | | |
| | | import jakarta.servlet.*; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * Repeatable è¿æ»¤å¨ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class RepeatableFilter implements Filter { |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| | | throws IOException, ServletException { |
| | | ServletRequest requestWrapper = null; |
| | | if (request instanceof HttpServletRequest |
| | | && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { |
| | | requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); |
| | | } |
| | | if (null == requestWrapper) { |
| | | chain.doFilter(request, response); |
| | | } else { |
| | | chain.doFilter(requestWrapper, response); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() { |
| | | |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.filter; |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | |
| | | import jakarta.servlet.ReadListener; |
| | | import jakarta.servlet.ServletInputStream; |
| | | import jakarta.servlet.ServletResponse; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletRequestWrapper; |
| | | import java.io.BufferedReader; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStreamReader; |
| | | |
| | | /** |
| | | * æå»ºå¯éå¤è¯»åinputStreamçrequest |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper { |
| | | private final byte[] body; |
| | | |
| | | public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException { |
| | | super(request); |
| | | request.setCharacterEncoding(Constants.UTF8); |
| | | response.setCharacterEncoding(Constants.UTF8); |
| | | |
| | | body = IoUtil.readBytes(request.getInputStream(), false); |
| | | } |
| | | |
| | | @Override |
| | | public BufferedReader getReader() throws IOException { |
| | | return new BufferedReader(new InputStreamReader(getInputStream())); |
| | | } |
| | | |
| | | @Override |
| | | public ServletInputStream getInputStream() throws IOException { |
| | | final ByteArrayInputStream bais = new ByteArrayInputStream(body); |
| | | return new ServletInputStream() { |
| | | @Override |
| | | public int read() throws IOException { |
| | | return bais.read(); |
| | | } |
| | | |
| | | @Override |
| | | public int available() throws IOException { |
| | | return body.length; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isFinished() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public void setReadListener(ReadListener readListener) { |
| | | |
| | | } |
| | | }; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.filter; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import org.springframework.http.HttpMethod; |
| | | |
| | | import jakarta.servlet.*; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 鲿¢XSSæ»å»çè¿æ»¤å¨ |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class XssFilter implements Filter { |
| | | /** |
| | | * æé¤é¾æ¥ |
| | | */ |
| | | public List<String> excludes = new ArrayList<>(); |
| | | |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException { |
| | | String tempExcludes = filterConfig.getInitParameter("excludes"); |
| | | if (StringUtils.isNotEmpty(tempExcludes)) { |
| | | String[] url = tempExcludes.split(","); |
| | | for (int i = 0; url != null && i < url.length; i++) { |
| | | excludes.add(url[i]); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| | | throws IOException, ServletException { |
| | | HttpServletRequest req = (HttpServletRequest) request; |
| | | HttpServletResponse resp = (HttpServletResponse) response; |
| | | if (handleExcludeURL(req, resp)) { |
| | | chain.doFilter(request, response); |
| | | return; |
| | | } |
| | | XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); |
| | | chain.doFilter(xssRequest, response); |
| | | } |
| | | |
| | | private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { |
| | | String url = request.getServletPath(); |
| | | String method = request.getMethod(); |
| | | // GET DELETE ä¸è¿æ»¤ |
| | | if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) { |
| | | return true; |
| | | } |
| | | return StringUtils.matches(url, excludes); |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() { |
| | | |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.filter; |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.http.HtmlUtil; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | |
| | | import jakarta.servlet.ReadListener; |
| | | import jakarta.servlet.ServletInputStream; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletRequestWrapper; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.IOException; |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | /** |
| | | * XSSè¿æ»¤å¤ç |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { |
| | | /** |
| | | * @param request |
| | | */ |
| | | public XssHttpServletRequestWrapper(HttpServletRequest request) { |
| | | super(request); |
| | | } |
| | | |
| | | @Override |
| | | public String[] getParameterValues(String name) { |
| | | String[] values = super.getParameterValues(name); |
| | | if (values != null) { |
| | | int length = values.length; |
| | | String[] escapseValues = new String[length]; |
| | | for (int i = 0; i < length; i++) { |
| | | // é²xssæ»å»åè¿æ»¤ååç©ºæ ¼ |
| | | escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim(); |
| | | } |
| | | return escapseValues; |
| | | } |
| | | return super.getParameterValues(name); |
| | | } |
| | | |
| | | @Override |
| | | public ServletInputStream getInputStream() throws IOException { |
| | | // éjsonç±»åï¼ç´æ¥è¿å |
| | | if (!isJsonRequest()) { |
| | | return super.getInputStream(); |
| | | } |
| | | |
| | | // 为空ï¼ç´æ¥è¿å |
| | | String json = StrUtil.str(IoUtil.readBytes(super.getInputStream(), false), StandardCharsets.UTF_8); |
| | | if (StringUtils.isEmpty(json)) { |
| | | return super.getInputStream(); |
| | | } |
| | | |
| | | // xssè¿æ»¤ |
| | | json = HtmlUtil.cleanHtmlTag(json).trim(); |
| | | byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8); |
| | | final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes); |
| | | return new ServletInputStream() { |
| | | @Override |
| | | public boolean isFinished() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public int available() throws IOException { |
| | | return jsonBytes.length; |
| | | } |
| | | |
| | | @Override |
| | | public void setReadListener(ReadListener readListener) { |
| | | } |
| | | |
| | | @Override |
| | | public int read() throws IOException { |
| | | return bis.read(); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦æ¯Jsonè¯·æ± |
| | | */ |
| | | public boolean isJsonRequest() { |
| | | String header = super.getHeader(HttpHeaders.CONTENT_TYPE); |
| | | return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.interceptor; |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import com.alibaba.ttl.TransmittableThreadLocal; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.web.filter.RepeatedlyRequestWrapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.time.StopWatch; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.servlet.HandlerInterceptor; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.BufferedReader; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * webçè°ç¨æ¶é´ç»è®¡æ¦æªå¨ |
| | | * devç¯å¢ææ |
| | | * |
| | | * @author Lion Li |
| | | * @since 3.3.0 |
| | | */ |
| | | @Slf4j |
| | | public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { |
| | | |
| | | private final String prodProfile = "prod"; |
| | | |
| | | private final TransmittableThreadLocal<StopWatch> invokeTimeTL = new TransmittableThreadLocal<>(); |
| | | |
| | | @Override |
| | | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
| | | if (!prodProfile.equals(SpringUtils.getActiveProfile())) { |
| | | String url = request.getMethod() + " " + request.getRequestURI(); |
| | | |
| | | // æå°è¯·æ±åæ° |
| | | if (isJsonRequest(request)) { |
| | | String jsonParam = ""; |
| | | if (request instanceof RepeatedlyRequestWrapper) { |
| | | BufferedReader reader = request.getReader(); |
| | | jsonParam = IoUtil.read(reader); |
| | | } |
| | | log.debug("[PLUS]å¼å§è¯·æ± => URL[{}],åæ°ç±»å[json],åæ°:[{}]", url, jsonParam); |
| | | } else { |
| | | Map<String, String[]> parameterMap = request.getParameterMap(); |
| | | if (MapUtil.isNotEmpty(parameterMap)) { |
| | | String parameters = JsonUtils.toJsonString(parameterMap); |
| | | log.debug("[PLUS]å¼å§è¯·æ± => URL[{}],åæ°ç±»å[param],åæ°:[{}]", url, parameters); |
| | | } else { |
| | | log.debug("[PLUS]å¼å§è¯·æ± => URL[{}],æ åæ°", url); |
| | | } |
| | | } |
| | | |
| | | StopWatch stopWatch = new StopWatch(); |
| | | invokeTimeTL.set(stopWatch); |
| | | stopWatch.start(); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { |
| | | if (!prodProfile.equals(SpringUtils.getActiveProfile())) { |
| | | StopWatch stopWatch = invokeTimeTL.get(); |
| | | stopWatch.stop(); |
| | | log.debug("[PLUS]ç»æè¯·æ± => URL[{}],èæ¶:[{}]毫ç§", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); |
| | | invokeTimeTL.remove(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤ææ¬æ¬¡è¯·æ±çæ°æ®ç±»åæ¯å¦ä¸ºjson |
| | | * |
| | | * @param request request |
| | | * @return boolean |
| | | */ |
| | | private boolean isJsonRequest(HttpServletRequest request) { |
| | | String contentType = request.getContentType(); |
| | | if (contentType != null) { |
| | | return StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.web.utils; |
| | | |
| | | import cn.hutool.captcha.generator.CodeGenerator; |
| | | import cn.hutool.core.math.Calculator; |
| | | import cn.hutool.core.util.CharUtil; |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æ 符å·è®¡ç®çæå¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class UnsignedMathGenerator implements CodeGenerator { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = -5514819971774091076L; |
| | | |
| | | private static final String OPERATORS = "+-*"; |
| | | |
| | | /** |
| | | * åä¸è®¡ç®æ°åæå¤§é¿åº¦ |
| | | */ |
| | | private final int numberLength; |
| | | |
| | | /** |
| | | * æé |
| | | */ |
| | | public UnsignedMathGenerator() { |
| | | this(2); |
| | | } |
| | | |
| | | /** |
| | | * æé |
| | | * |
| | | * @param numberLength åä¸è®¡ç®æå¤§æ°å使° |
| | | */ |
| | | public UnsignedMathGenerator(int numberLength) { |
| | | this.numberLength = numberLength; |
| | | } |
| | | |
| | | @Override |
| | | public String generate() { |
| | | final int limit = getLimit(); |
| | | int a = RandomUtil.randomInt(limit); |
| | | int b = RandomUtil.randomInt(limit); |
| | | String max = Integer.toString(Math.max(a,b)); |
| | | String min = Integer.toString(Math.min(a,b)); |
| | | max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE); |
| | | min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE); |
| | | |
| | | return max + RandomUtil.randomChar(OPERATORS) + min + '='; |
| | | } |
| | | |
| | | @Override |
| | | public boolean verify(String code, String userInputCode) { |
| | | int result; |
| | | try { |
| | | result = Integer.parseInt(userInputCode); |
| | | } catch (NumberFormatException e) { |
| | | // ç¨æ·è¾å
¥éæ°å |
| | | return false; |
| | | } |
| | | |
| | | final int calculateResult = (int) Calculator.conversion(code); |
| | | return result == calculateResult; |
| | | } |
| | | |
| | | /** |
| | | * è·åéªè¯ç é¿åº¦ |
| | | * |
| | | * @return éªè¯ç é¿åº¦ |
| | | */ |
| | | public int getLength() { |
| | | return this.numberLength * 2 + 2; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®é¿åº¦è·ååä¸è®¡ç®æ°åæå¤§å¼ |
| | | * |
| | | * @return æå¤§å¼ |
| | | */ |
| | | private int getLimit() { |
| | | return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | com.ruoyi.common.web.config.CaptchaConfig |
| | | com.ruoyi.common.web.config.FilterConfig |
| | | com.ruoyi.common.web.config.I18nConfig |
| | | com.ruoyi.common.web.config.ResourcesConfig |
| | | com.ruoyi.common.web.config.UndertowConfig |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>ruoyi-vue-plus</artifactId> |
| | | <groupId>com.ruoyi</groupId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <modules> |
| | | <module>ruoyi-demo</module> |
| | | <module>ruoyi-generator</module> |
| | | <module>ruoyi-job</module> |
| | | <module>ruoyi-system</module> |
| | | </modules> |
| | | |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <packaging>pom</packaging> |
| | | |
| | | <description> |
| | | ruoyi-modules ä¸å¡æ¨¡å |
| | | </description> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-demo</artifactId> |
| | | |
| | | <description> |
| | | demo模å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <!-- éç¨å·¥å
·--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-sms</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-mail</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-idempotent</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-excel</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-ratelimiter</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- çä¿¡ ç¨åªä¸ªå¯¼å
¥åªä¸ªä¾èµ --> |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>com.aliyun</groupId>--> |
| | | <!-- <artifactId>dysmsapi20170525</artifactId>--> |
| | | <!-- </dependency>--> |
| | | |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>com.tencentcloudapi</groupId>--> |
| | | <!-- <artifactId>tencentcloud-sdk-java-sms</artifactId>--> |
| | | <!-- </dependency>--> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mail.utils.MailUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.io.File; |
| | | |
| | | |
| | | /** |
| | | * é®ä»¶åéæ¡ä¾ |
| | | * |
| | | * @author Michelle.Chung |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/mail") |
| | | public class MailController { |
| | | |
| | | /** |
| | | * åéé®ä»¶ |
| | | * |
| | | * @param to æ¥æ¶äºº |
| | | * @param subject æ é¢ |
| | | * @param text å
容 |
| | | */ |
| | | @GetMapping("/sendSimpleMessage") |
| | | public R<Void> sendSimpleMessage(String to, String subject, String text) { |
| | | MailUtils.sendText(to, subject, text); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * åéé®ä»¶ï¼å¸¦éä»¶ï¼ |
| | | * |
| | | * @param to æ¥æ¶äºº |
| | | * @param subject æ é¢ |
| | | * @param text å
容 |
| | | * @param filePath éä»¶è·¯å¾ |
| | | */ |
| | | @GetMapping("/sendMessageWithAttachment") |
| | | public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) { |
| | | MailUtils.sendText(to, subject, text, new File(filePath)); |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.constant.CacheNames; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.CachePut; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.time.Duration; |
| | | |
| | | /** |
| | | * spring-cache æ¼ç¤ºæ¡ä¾ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | // ç±»çº§å« ç¼åç»ä¸é
ç½® |
| | | //@CacheConfig(cacheNames = CacheNames.DEMO_CACHE) |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/cache") |
| | | public class RedisCacheController { |
| | | |
| | | /** |
| | | * æµè¯ @Cacheable |
| | | * <p> |
| | | * 表示è¿ä¸ªæ¹æ³æäºç¼åçåè½,æ¹æ³çè¿åå¼ä¼è¢«ç¼å䏿¥ |
| | | * ä¸ä¸æ¬¡è°ç¨è¯¥æ¹æ³å,ä¼å»æ£æ¥æ¯å¦ç¼åä¸å·²ç»æå¼ |
| | | * 妿æå°±ç´æ¥è¿å,ä¸è°ç¨æ¹æ³ |
| | | * å¦ææ²¡æ,å°±è°ç¨æ¹æ³,ç¶åæç»æç¼åèµ·æ¥ |
| | | * è¿ä¸ªæ³¨è§£ãä¸è¬ç¨å¨æ¥è¯¢æ¹æ³ä¸ã |
| | | * <p> |
| | | * éç¹è¯´æ: ç¼å注解严谨ä¸å
¶ä»çéæ°æ®åè½ä¸èµ·ä½¿ç¨ |
| | | * ä¾å¦: æ°æ®æé注解 ä¼é æ ç¼åå»ç©¿ ä¸ æ°æ®ä¸ä¸è´é®é¢ |
| | | * <p> |
| | | * cacheNames å½åè§å æ¥ç {@link CacheNames} æ³¨é æ¯æå¤åæ° |
| | | */ |
| | | @Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null") |
| | | @GetMapping("/test1") |
| | | public R<String> test1(String key, String value) { |
| | | return R.ok("æä½æå", value); |
| | | } |
| | | |
| | | /** |
| | | * æµè¯ @CachePut |
| | | * <p> |
| | | * å äº@CachePutæ³¨è§£çæ¹æ³,ä¼ææ¹æ³çè¿åå¼putå°ç¼åéé¢ç¼åèµ·æ¥,ä¾å
¶å®å°æ¹ä½¿ç¨ |
| | | * å®ãé常ç¨å¨æ°å¢æè
宿¶æ´æ°æ¹æ³ä¸ã |
| | | * <p> |
| | | * cacheNames å½åè§å æ¥ç {@link CacheNames} æ³¨é æ¯æå¤åæ° |
| | | */ |
| | | @CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null") |
| | | @GetMapping("/test2") |
| | | public R<String> test2(String key, String value) { |
| | | return R.ok("æä½æå", value); |
| | | } |
| | | |
| | | /** |
| | | * æµè¯ @CacheEvict |
| | | * <p> |
| | | * 使ç¨äºCacheEvictæ³¨è§£çæ¹æ³,伿¸
空æå®ç¼å |
| | | * ãä¸è¬ç¨å¨å é¤çæ¹æ³ä¸ã |
| | | * <p> |
| | | * cacheNames å½åè§å æ¥ç {@link CacheNames} æ³¨é æ¯æå¤åæ° |
| | | */ |
| | | @CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null") |
| | | @GetMapping("/test3") |
| | | public R<String> test3(String key, String value) { |
| | | return R.ok("æä½æå", value); |
| | | } |
| | | |
| | | /** |
| | | * æµè¯è®¾ç½®è¿ææ¶é´ |
| | | * æå¨è®¾ç½®è¿ææ¶é´10ç§ |
| | | * 11ç§åè·å 夿æ¯å¦ç¸ç |
| | | */ |
| | | @GetMapping("/test6") |
| | | public R<Boolean> test6(String key, String value) { |
| | | RedisUtils.setCacheObject(key, value); |
| | | boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10)); |
| | | System.out.println("***********" + flag); |
| | | try { |
| | | Thread.sleep(11 * 1000); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | Object obj = RedisUtils.getCacheObject(key); |
| | | return R.ok(value.equals(obj)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * Redis åå¸è®¢é
æ¼ç¤ºæ¡ä¾ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/redis/pubsub") |
| | | public class RedisPubSubController { |
| | | |
| | | /** |
| | | * å叿¶æ¯ |
| | | * |
| | | * @param key ééKey |
| | | * @param value åéå
容 |
| | | */ |
| | | @GetMapping("/pub") |
| | | public R<Void> pub(String key, String value) { |
| | | RedisUtils.publish(key, value, consumer -> { |
| | | System.out.println("åå¸éé => " + key + ", åéå¼ => " + value); |
| | | }); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * 订é
æ¶æ¯ |
| | | * |
| | | * @param key ééKey |
| | | */ |
| | | @GetMapping("/sub") |
| | | public R<Void> sub(String key) { |
| | | RedisUtils.subscribe(key, String.class, msg -> { |
| | | System.out.println("订é
éé => " + key + ", æ¥æ¶å¼ => " + msg); |
| | | }); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.ratelimiter.annotation.RateLimiter; |
| | | import com.ruoyi.common.ratelimiter.enums.LimitType; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | |
| | | /** |
| | | * æµè¯åå¸å¼éæµæ ·ä¾ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/demo/rateLimiter") |
| | | public class RedisRateLimiterController { |
| | | |
| | | /** |
| | | * æµè¯å
¨å±éæµ |
| | | * å
¨å±å½±å |
| | | */ |
| | | @RateLimiter(count = 2, time = 10) |
| | | @GetMapping("/test") |
| | | public R<String> test(String value) { |
| | | return R.ok("æä½æå", value); |
| | | } |
| | | |
| | | /** |
| | | * æµè¯è¯·æ±IPéæµ |
| | | * åä¸IP请æ±åå½±å |
| | | */ |
| | | @RateLimiter(count = 2, time = 10, limitType = LimitType.IP) |
| | | @GetMapping("/testip") |
| | | public R<String> testip(String value) { |
| | | return R.ok("æä½æå", value); |
| | | } |
| | | |
| | | /** |
| | | * æµè¯é群å®ä¾éæµ |
| | | * å¯å¨ä¸¤ä¸ªå端æå¡äºä¸å½±å |
| | | */ |
| | | @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER) |
| | | @GetMapping("/testcluster") |
| | | public R<String> testcluster(String value) { |
| | | return R.ok("æä½æå", value); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.utils.SpringUtils; |
| | | import com.ruoyi.common.sms.config.properties.SmsProperties; |
| | | import com.ruoyi.common.sms.core.SmsTemplate; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * çä¿¡æ¼ç¤ºæ¡ä¾ |
| | | * 请å
é
è¯»ææ¡£ å¦åæ æ³ä½¿ç¨ |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/sms") |
| | | public class SmsController { |
| | | |
| | | private final SmsProperties smsProperties; |
| | | // private final SmsTemplate smsTemplate; // å¯ä»¥ä½¿ç¨spring注å
¥ |
| | | // private final AliyunSmsTemplate smsTemplate; // ä¹å¯ä»¥æ³¨å
¥æä¸ªåå®¶çæ¨¡æ¿å·¥å
· |
| | | |
| | | /** |
| | | * åéçä¿¡Aliyun |
| | | * |
| | | * @param phones çµè¯å· |
| | | * @param templateId 模æ¿ID |
| | | */ |
| | | @GetMapping("/sendAliyun") |
| | | public R<Object> sendAliyun(String phones, String templateId) { |
| | | if (!smsProperties.getEnabled()) { |
| | | return R.fail("å½åç³»ç»æ²¡æå¼å¯çä¿¡åè½ï¼"); |
| | | } |
| | | if (!SpringUtils.containsBean("aliyunSmsTemplate")) { |
| | | return R.fail("é¿éäºä¾èµæªå¼å
¥ï¼"); |
| | | } |
| | | SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); |
| | | Map<String, String> map = new HashMap<>(1); |
| | | map.put("code", "1234"); |
| | | Object send = smsTemplate.send(phones, templateId, map); |
| | | return R.ok(send); |
| | | } |
| | | |
| | | /** |
| | | * åéçä¿¡Tencent |
| | | * |
| | | * @param phones çµè¯å· |
| | | * @param templateId 模æ¿ID |
| | | */ |
| | | @GetMapping("/sendTencent") |
| | | public R<Object> sendTencent(String phones, String templateId) { |
| | | if (!smsProperties.getEnabled()) { |
| | | return R.fail("å½åç³»ç»æ²¡æå¼å¯çä¿¡åè½ï¼"); |
| | | } |
| | | if (!SpringUtils.containsBean("tencentSmsTemplate")) { |
| | | return R.fail("è
¾è®¯äºä¾èµæªå¼å
¥ï¼"); |
| | | } |
| | | SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); |
| | | Map<String, String> map = new HashMap<>(1); |
| | | // map.put("2", "æµè¯æµè¯"); |
| | | map.put("1", "1234"); |
| | | Object send = smsTemplate.send(phones, templateId, map); |
| | | return R.ok(send); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.demo.domain.TestDemo; |
| | | import com.ruoyi.demo.mapper.TestDemoMapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.DeleteMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµè¯æ¹éæ¹æ³ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-05-30 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/batch") |
| | | public class TestBatchController extends BaseController { |
| | | |
| | | /** |
| | | * 为äºä¾¿äºæµè¯ ç´æ¥å¼å
¥mapper |
| | | */ |
| | | private final TestDemoMapper testDemoMapper; |
| | | |
| | | /** |
| | | * æ°å¢æ¹éæ¹æ³ å¯å®ç¾æ¿ä»£ saveBatch ç§çº§æå
¥ä¸ä¸æ°æ® (对mysqlè´è·è¾å¤§) |
| | | * <p> |
| | | * 3.5.0 çæ¬ å¢å rewriteBatchedStatements=true æ¹å¤çåæ° 使 MP åçæ¹å¤çå¯ä»¥è¾¾å°åæ ·çé度 |
| | | */ |
| | | @PostMapping("/add") |
| | | // @DS("slave") |
| | | public R<Void> add() { |
| | | List<TestDemo> list = new ArrayList<>(); |
| | | for (int i = 0; i < 1000; i++) { |
| | | TestDemo testDemo = new TestDemo(); |
| | | testDemo.setOrderNum(-1); |
| | | testDemo.setTestKey("æ¹éæ°å¢"); |
| | | testDemo.setValue("æµè¯æ°å¢"); |
| | | list.add(testDemo); |
| | | } |
| | | return toAjax(testDemoMapper.insertBatch(list)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ææ´æ° å¯å®ç¾æ¿ä»£ saveOrUpdateBatch 髿§è½ |
| | | * <p> |
| | | * 3.5.0 çæ¬ å¢å rewriteBatchedStatements=true æ¹å¤çåæ° 使 MP åçæ¹å¤çå¯ä»¥è¾¾å°åæ ·çé度 |
| | | */ |
| | | @PostMapping("/addOrUpdate") |
| | | // @DS("slave") |
| | | public R<Void> addOrUpdate() { |
| | | List<TestDemo> list = new ArrayList<>(); |
| | | for (int i = 0; i < 1000; i++) { |
| | | TestDemo testDemo = new TestDemo(); |
| | | testDemo.setOrderNum(-1); |
| | | testDemo.setTestKey("æ¹éæ°å¢"); |
| | | testDemo.setValue("æµè¯æ°å¢"); |
| | | list.add(testDemo); |
| | | } |
| | | testDemoMapper.insertBatch(list); |
| | | for (int i = 0; i < list.size(); i++) { |
| | | TestDemo testDemo = list.get(i); |
| | | testDemo.setTestKey("æ¹éæ°å¢æä¿®æ¹"); |
| | | testDemo.setValue("æ¹éæ°å¢æä¿®æ¹"); |
| | | if (i % 2 == 0) { |
| | | testDemo.setId(null); |
| | | } |
| | | } |
| | | return toAjax(testDemoMapper.insertOrUpdateBatch(list)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿¹éæ¹æ³ |
| | | */ |
| | | @DeleteMapping() |
| | | // @DS("slave") |
| | | public R<Void> remove() { |
| | | return toAjax(testDemoMapper.delete(new LambdaQueryWrapper<TestDemo>() |
| | | .eq(TestDemo::getOrderNum, -1L))); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.utils.ValidatorUtils; |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import com.ruoyi.common.core.validate.QueryGroup; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.idempotent.annotation.RepeatSubmit; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.excel.core.ExcelResult; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.demo.domain.TestDemo; |
| | | import com.ruoyi.demo.domain.bo.TestDemoBo; |
| | | import com.ruoyi.demo.domain.bo.TestDemoImportVo; |
| | | import com.ruoyi.demo.domain.vo.TestDemoVo; |
| | | import com.ruoyi.demo.service.ITestDemoService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * æµè¯å表Controller |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/demo") |
| | | public class TestDemoController extends BaseController { |
| | | |
| | | private final ITestDemoService iTestDemoService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµè¯å表å表 |
| | | */ |
| | | @SaCheckPermission("demo:demo:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { |
| | | return iTestDemoService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹å页æ¥è¯¢ |
| | | */ |
| | | @SaCheckPermission("demo:demo:list") |
| | | @GetMapping("/page") |
| | | public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { |
| | | return iTestDemoService.customPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥æ°æ® |
| | | * |
| | | * @param file 导å
¥æä»¶ |
| | | */ |
| | | @Log(title = "æµè¯å表", businessType = BusinessType.IMPORT) |
| | | @SaCheckPermission("demo:demo:import") |
| | | @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
| | | public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception { |
| | | ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true); |
| | | List<TestDemoImportVo> volist = excelResult.getList(); |
| | | List<TestDemo> list = BeanUtil.copyToList(volist, TestDemo.class); |
| | | iTestDemoService.saveBatch(list); |
| | | return R.ok(excelResult.getAnalysis()); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæµè¯å表å表 |
| | | */ |
| | | @SaCheckPermission("demo:demo:export") |
| | | @Log(title = "æµè¯å表", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(@Validated TestDemoBo bo, HttpServletResponse response) { |
| | | List<TestDemoVo> list = iTestDemoService.queryList(bo); |
| | | // æµè¯éªè±idå¯¼åº |
| | | // for (TestDemoVo vo : list) { |
| | | // vo.setId(1234567891234567893L); |
| | | // } |
| | | ExcelUtil.exportExcel(list, "æµè¯å表", TestDemoVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµè¯å表详ç»ä¿¡æ¯ |
| | | * |
| | | * @param id æµè¯ID |
| | | */ |
| | | @SaCheckPermission("demo:demo:query") |
| | | @GetMapping("/{id}") |
| | | public R<TestDemoVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable("id") Long id) { |
| | | return R.ok(iTestDemoService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµè¯å表 |
| | | */ |
| | | @SaCheckPermission("demo:demo:add") |
| | | @Log(title = "æµè¯å表", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}") |
| | | @PostMapping() |
| | | public R<Void> add(@RequestBody TestDemoBo bo) { |
| | | // ä½¿ç¨æ ¡éªå·¥å
·å¯¹æ @Validated(AddGroup.class) 注解 |
| | | // ç¨äºå¨é Controller çå°æ¹æ ¡éªå¯¹è±¡ |
| | | ValidatorUtils.validate(bo, AddGroup.class); |
| | | return toAjax(iTestDemoService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµè¯å表 |
| | | */ |
| | | @SaCheckPermission("demo:demo:edit") |
| | | @Log(title = "æµè¯å表", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) { |
| | | return toAjax(iTestDemoService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µè¯å表 |
| | | * |
| | | * @param ids æµè¯ID串 |
| | | */ |
| | | @SaCheckPermission("demo:demo:remove") |
| | | @Log(title = "æµè¯å表", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµè¯Excelåè½ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/demo/excel") |
| | | public class TestExcelController { |
| | | |
| | | /** |
| | | * ååè¡¨å¤æ°æ® |
| | | */ |
| | | @GetMapping("/exportTemplateOne") |
| | | public void exportTemplateOne(HttpServletResponse response) { |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("title", "ååè¡¨å¤æ°æ®"); |
| | | map.put("test1", "æ°æ®æµè¯1"); |
| | | map.put("test2", "æ°æ®æµè¯2"); |
| | | map.put("test3", "æ°æ®æµè¯3"); |
| | | map.put("test4", "æ°æ®æµè¯4"); |
| | | map.put("testTest", "666"); |
| | | List<TestObj> list = new ArrayList<>(); |
| | | list.add(new TestObj("åå表æµè¯1", "å表æµè¯1", "å表æµè¯2", "å表æµè¯3", "å表æµè¯4")); |
| | | list.add(new TestObj("åå表æµè¯2", "å表æµè¯5", "å表æµè¯6", "å表æµè¯7", "å表æµè¯8")); |
| | | list.add(new TestObj("åå表æµè¯3", "å表æµè¯9", "å表æµè¯10", "å表æµè¯11", "å表æµè¯12")); |
| | | ExcelUtil.exportTemplate(CollUtil.newArrayList(map, list), "åå表.xlsx", "excel/åå表.xlsx", response); |
| | | } |
| | | |
| | | /** |
| | | * å¤åè¡¨å¤æ°æ® |
| | | */ |
| | | @GetMapping("/exportTemplateMuliti") |
| | | public void exportTemplateMuliti(HttpServletResponse response) { |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("title1", "æ é¢1"); |
| | | map.put("title2", "æ é¢2"); |
| | | map.put("title3", "æ é¢3"); |
| | | map.put("title4", "æ é¢4"); |
| | | map.put("author", "Lion Li"); |
| | | List<TestObj1> list1 = new ArrayList<>(); |
| | | list1.add(new TestObj1("list1æµè¯1", "list1æµè¯2", "list1æµè¯3")); |
| | | list1.add(new TestObj1("list1æµè¯4", "list1æµè¯5", "list1æµè¯6")); |
| | | list1.add(new TestObj1("list1æµè¯7", "list1æµè¯8", "list1æµè¯9")); |
| | | List<TestObj1> list2 = new ArrayList<>(); |
| | | list2.add(new TestObj1("list2æµè¯1", "list2æµè¯2", "list2æµè¯3")); |
| | | list2.add(new TestObj1("list2æµè¯4", "list2æµè¯5", "list2æµè¯6")); |
| | | List<TestObj1> list3 = new ArrayList<>(); |
| | | list3.add(new TestObj1("list3æµè¯1", "list3æµè¯2", "list3æµè¯3")); |
| | | List<TestObj1> list4 = new ArrayList<>(); |
| | | list4.add(new TestObj1("list4æµè¯1", "list4æµè¯2", "list4æµè¯3")); |
| | | list4.add(new TestObj1("list4æµè¯4", "list4æµè¯5", "list4æµè¯6")); |
| | | list4.add(new TestObj1("list4æµè¯7", "list4æµè¯8", "list4æµè¯9")); |
| | | list4.add(new TestObj1("list4æµè¯10", "list4æµè¯11", "list4æµè¯12")); |
| | | Map<String, Object> multiListMap = new HashMap<>(); |
| | | multiListMap.put("map", map); |
| | | multiListMap.put("data1", list1); |
| | | multiListMap.put("data2", list2); |
| | | multiListMap.put("data3", list3); |
| | | multiListMap.put("data4", list4); |
| | | ExcelUtil.exportTemplateMultiList(multiListMap, "å¤å表.xlsx", "excel/å¤å表.xlsx", response); |
| | | } |
| | | |
| | | @Data |
| | | @AllArgsConstructor |
| | | static class TestObj1 { |
| | | private String test1; |
| | | private String test2; |
| | | private String test3; |
| | | } |
| | | |
| | | @Data |
| | | @AllArgsConstructor |
| | | static class TestObj { |
| | | private String name; |
| | | private String list1; |
| | | private String list2; |
| | | private String list3; |
| | | private String list4; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.utils.MessageUtils; |
| | | import lombok.Data; |
| | | import org.hibernate.validator.constraints.Range; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | |
| | | |
| | | /** |
| | | * æµè¯å½é
å |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RestController |
| | | @RequestMapping("/demo/i18n") |
| | | public class TestI18nController { |
| | | |
| | | /** |
| | | * éè¿codeè·åå½é
åå
容 |
| | | * code为 messages.properties ä¸ç key |
| | | * <p> |
| | | * æµè¯ä½¿ç¨ user.register.success |
| | | * |
| | | * @param code å½é
åcode |
| | | */ |
| | | @GetMapping() |
| | | public R<Void> get(String code) { |
| | | return R.ok(MessageUtils.message(code)); |
| | | } |
| | | |
| | | /** |
| | | * Validator æ ¡éªå½é
å |
| | | * ä¸ä¼ å¼ å嫿¥çå¼å¸¸è¿å |
| | | * <p> |
| | | * æµè¯ä½¿ç¨ not.null |
| | | */ |
| | | @GetMapping("/test1") |
| | | public R<Void> test1(@NotBlank(message = "{not.null}") String str) { |
| | | return R.ok(str); |
| | | } |
| | | |
| | | /** |
| | | * Bean æ ¡éªå½é
å |
| | | * ä¸ä¼ å¼ å嫿¥çå¼å¸¸è¿å |
| | | * <p> |
| | | * æµè¯ä½¿ç¨ not.null |
| | | */ |
| | | @GetMapping("/test2") |
| | | public R<TestI18nBo> test2(@Validated TestI18nBo bo) { |
| | | return R.ok(bo); |
| | | } |
| | | |
| | | @Data |
| | | public static class TestI18nBo { |
| | | |
| | | @NotBlank(message = "{not.null}") |
| | | private String name; |
| | | |
| | | @NotNull(message = "{not.null}") |
| | | @Range(min = 0, max = 100, message = "{length.not.valid}") |
| | | private Integer age; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import com.ruoyi.common.core.annotation.Sensitive; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.enums.SensitiveStrategy; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import lombok.Data; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * æµè¯æ°æ®è±ææ§å¶å¨ |
| | | * <p> |
| | | * é»è®¤ç®¡çåä¸è¿æ»¤ |
| | | * éèªè¡æ ¹æ®ä¸å¡éåå®ç° |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.6.0 |
| | | * @see com.ruoyi.common.core.service.SensitiveService |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/demo/sensitive") |
| | | public class TestSensitiveController extends BaseController { |
| | | |
| | | /** |
| | | * æµè¯æ°æ®è±æ |
| | | */ |
| | | @GetMapping("/test") |
| | | public R<TestSensitive> test() { |
| | | TestSensitive testSensitive = new TestSensitive(); |
| | | testSensitive.setIdCard("210397198608215431"); |
| | | testSensitive.setPhone("17640125371"); |
| | | testSensitive.setAddress("åäº¬å¸æé³åºææååé¢1203室"); |
| | | testSensitive.setEmail("17640125371@163.com"); |
| | | testSensitive.setBankCard("6226456952351452853"); |
| | | return R.ok(testSensitive); |
| | | } |
| | | |
| | | @Data |
| | | static class TestSensitive { |
| | | |
| | | /** |
| | | * èº«ä»½è¯ |
| | | */ |
| | | @Sensitive(strategy = SensitiveStrategy.ID_CARD) |
| | | private String idCard; |
| | | |
| | | /** |
| | | * çµè¯ |
| | | */ |
| | | @Sensitive(strategy = SensitiveStrategy.PHONE) |
| | | private String phone; |
| | | |
| | | /** |
| | | * å°å |
| | | */ |
| | | @Sensitive(strategy = SensitiveStrategy.ADDRESS) |
| | | private String address; |
| | | |
| | | /** |
| | | * é®ç®± |
| | | */ |
| | | @Sensitive(strategy = SensitiveStrategy.EMAIL) |
| | | private String email; |
| | | |
| | | /** |
| | | * é¶è¡å¡ |
| | | */ |
| | | @Sensitive(strategy = SensitiveStrategy.BANK_CARD) |
| | | private String bankCard; |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import com.ruoyi.common.core.validate.QueryGroup; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.common.idempotent.annotation.RepeatSubmit; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.demo.domain.bo.TestTreeBo; |
| | | import com.ruoyi.demo.domain.vo.TestTreeVo; |
| | | import com.ruoyi.demo.service.ITestTreeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµè¯æ 表Controller |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/tree") |
| | | public class TestTreeController extends BaseController { |
| | | |
| | | private final ITestTreeService iTestTreeService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµè¯æ 表å表 |
| | | */ |
| | | @SaCheckPermission("demo:tree:list") |
| | | @GetMapping("/list") |
| | | public R<List<TestTreeVo>> list(@Validated(QueryGroup.class) TestTreeBo bo) { |
| | | List<TestTreeVo> list = iTestTreeService.queryList(bo); |
| | | return R.ok(list); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæµè¯æ 表å表 |
| | | */ |
| | | @SaCheckPermission("demo:tree:export") |
| | | @Log(title = "æµè¯æ 表", businessType = BusinessType.EXPORT) |
| | | @GetMapping("/export") |
| | | public void export(@Validated TestTreeBo bo, HttpServletResponse response) { |
| | | List<TestTreeVo> list = iTestTreeService.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "æµè¯æ 表", TestTreeVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµè¯æ 表详ç»ä¿¡æ¯ |
| | | * |
| | | * @param id æµè¯æ ID |
| | | */ |
| | | @SaCheckPermission("demo:tree:query") |
| | | @GetMapping("/{id}") |
| | | public R<TestTreeVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable("id") Long id) { |
| | | return R.ok(iTestTreeService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµè¯æ 表 |
| | | */ |
| | | @SaCheckPermission("demo:tree:add") |
| | | @Log(title = "æµè¯æ 表", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit |
| | | @PostMapping() |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) { |
| | | return toAjax(iTestTreeService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµè¯æ 表 |
| | | */ |
| | | @SaCheckPermission("demo:tree:edit") |
| | | @Log(title = "æµè¯æ 表", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) { |
| | | return toAjax(iTestTreeService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µè¯æ 表 |
| | | * |
| | | * @param ids æµè¯æ ID串 |
| | | */ |
| | | @SaCheckPermission("demo:tree:remove") |
| | | @Log(title = "æµè¯æ 表", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller.queue; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.redis.utils.QueueUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * æçéå æ¼ç¤ºæ¡ä¾ |
| | | * <p> |
| | | * è½»é级éå ééçº§æ°æ®é è¯·ä½¿ç¨ MQ |
| | | * <p> |
| | | * é群æµè¯éè¿ åä¸ä¸ªæ°æ®åªä¼è¢«æ¶è´¹ä¸æ¬¡ å好äºå¡è¡¥å¿ |
| | | * é群æµè¯æµç¨ å¨å
¶ä¸ä¸å°åéæ°æ® ä¸¤ç«¯åå«è°ç¨è·åæ¥å£ 䏿¬¡è·å䏿¡ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.6.0 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/queue/bounded") |
| | | public class BoundedQueueController { |
| | | |
| | | |
| | | /** |
| | | * æ·»å éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param capacity 容é |
| | | */ |
| | | @GetMapping("/add") |
| | | public R<Void> add(String queueName, int capacity) { |
| | | // ç¨å®äºä¸å®è¦éæ¯ å¦åä¼ä¸ç´åå¨ |
| | | boolean b = QueueUtils.destroyQueue(queueName); |
| | | log.info("éé: {} , å é¤: {}", queueName, b); |
| | | // åå§åè®¾ç½®ä¸æ¬¡å³å¯ |
| | | if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) { |
| | | log.info("éé: {} , 设置容é: {}", queueName, capacity); |
| | | } else { |
| | | log.info("éé: {} , 设置容é失败", queueName); |
| | | return R.fail("æä½å¤±è´¥"); |
| | | } |
| | | for (int i = 0; i < 11; i++) { |
| | | String data = "data-" + i; |
| | | boolean flag = QueueUtils.addBoundedQueueObject(queueName, data); |
| | | if (flag == false) { |
| | | log.info("éé: {} , åéæ°æ®: {} 失败, éé已满", queueName, data); |
| | | } else { |
| | | log.info("éé: {} , åéæ°æ®: {}", queueName, data); |
| | | } |
| | | } |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | @GetMapping("/remove") |
| | | public R<Void> remove(String queueName) { |
| | | String data = "data-" + 5; |
| | | if (QueueUtils.removeQueueObject(queueName, data)) { |
| | | log.info("éé: {} , å 餿°æ®: {}", queueName, data); |
| | | } else { |
| | | return R.fail("æä½å¤±è´¥"); |
| | | } |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * è·åéåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | @GetMapping("/get") |
| | | public R<Void> get(String queueName) { |
| | | String data; |
| | | do { |
| | | data = QueueUtils.getQueueObject(queueName); |
| | | log.info("éé: {} , è·åæ°æ®: {}", queueName, data); |
| | | } while (data != null); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller.queue; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.redis.utils.QueueUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * å»¶è¿éå æ¼ç¤ºæ¡ä¾ |
| | | * <p> |
| | | * è½»é级éå ééçº§æ°æ®é è¯·ä½¿ç¨ MQ |
| | | * ä¾å¦: å建订å30åéåè¿æå¤ç |
| | | * <p> |
| | | * é群æµè¯éè¿ åä¸ä¸ªæ°æ®åªä¼è¢«æ¶è´¹ä¸æ¬¡ å好äºå¡è¡¥å¿ |
| | | * é群æµè¯æµç¨ 两å°é群åå«å¼å¯è®¢é
å¨å
¶ä¸ä¸å°åéæ°æ® è§å¯æ¥æ¶æ¶æ¯çè§å¾ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.6.0 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/queue/delayed") |
| | | public class DelayedQueueController { |
| | | |
| | | /** |
| | | * 订é
éå |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | @GetMapping("/subscribe") |
| | | public R<Void> subscribe(String queueName) { |
| | | log.info("éé: {} çå¬ä¸......", queueName); |
| | | // 项ç®åå§åè®¾ç½®ä¸æ¬¡å³å¯ |
| | | QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> { |
| | | // è§å¯æ¥æ¶æ¶é´ |
| | | log.info("éé: {}, æ¶å°æ°æ®: {}", queueName, orderNum); |
| | | }); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param orderNum 订åå· |
| | | * @param time å»¶è¿æ¶é´(ç§) |
| | | */ |
| | | @GetMapping("/add") |
| | | public R<Void> add(String queueName, String orderNum, Long time) { |
| | | QueueUtils.addDelayedQueueObject(queueName, orderNum, time, TimeUnit.SECONDS); |
| | | // è§å¯åéæ¶é´ |
| | | log.info("éé: {} , åéæ°æ®: {}", queueName, orderNum); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param orderNum 订åå· |
| | | */ |
| | | @GetMapping("/remove") |
| | | public R<Void> remove(String queueName, String orderNum) { |
| | | if (QueueUtils.removeDelayedQueueObject(queueName, orderNum)) { |
| | | log.info("éé: {} , å 餿°æ®: {}", queueName, orderNum); |
| | | } else { |
| | | return R.fail("æä½å¤±è´¥"); |
| | | } |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * 鿝éå |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | @GetMapping("/destroy") |
| | | public R<Void> destroy(String queueName) { |
| | | // ç¨å®äºä¸å®è¦éæ¯ å¦åä¼ä¸ç´åå¨ |
| | | QueueUtils.destroyDelayedQueue(queueName); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.controller.queue; |
| | | |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.redis.utils.QueueUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * ä¼å
éå æ¼ç¤ºæ¡ä¾ |
| | | * <p> |
| | | * è½»é级éå ééçº§æ°æ®é è¯·ä½¿ç¨ MQ |
| | | * <p> |
| | | * é群æµè¯éè¿ åä¸ä¸ªæ¶æ¯åªä¼è¢«æ¶è´¹ä¸æ¬¡ å好äºå¡è¡¥å¿ |
| | | * é群æµè¯æµç¨ å¨å
¶ä¸ä¸å°åéæ°æ® ä¸¤ç«¯åå«è°ç¨è·åæ¥å£ 䏿¬¡è·å䏿¡ |
| | | * |
| | | * @author Lion Li |
| | | * @version 3.6.0 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/queue/priority") |
| | | public class PriorityQueueController { |
| | | |
| | | /** |
| | | * æ·»å éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | @GetMapping("/add") |
| | | public R<Void> add(String queueName) { |
| | | // ç¨å®äºä¸å®è¦éæ¯ å¦åä¼ä¸ç´åå¨ |
| | | boolean b = QueueUtils.destroyQueue(queueName); |
| | | log.info("éé: {} , å é¤: {}", queueName, b); |
| | | |
| | | for (int i = 0; i < 10; i++) { |
| | | int randomNum = RandomUtil.randomInt(10); |
| | | PriorityDemo data = new PriorityDemo(); |
| | | data.setName("data-" + i); |
| | | data.setOrderNum(randomNum); |
| | | if (QueueUtils.addPriorityQueueObject(queueName, data)) { |
| | | log.info("éé: {} , åéæ°æ®: {}", queueName, data); |
| | | } else { |
| | | log.info("éé: {} , åéæ°æ®: {}, åé失败", queueName, data); |
| | | } |
| | | } |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | * @param name 对象å |
| | | * @param orderNum æåºå· |
| | | */ |
| | | @GetMapping("/remove") |
| | | public R<Void> remove(String queueName, String name, Integer orderNum) { |
| | | PriorityDemo data = new PriorityDemo(); |
| | | data.setName(name); |
| | | data.setOrderNum(orderNum); |
| | | if (QueueUtils.removeQueueObject(queueName, data)) { |
| | | log.info("éé: {} , å 餿°æ®: {}", queueName, data); |
| | | } else { |
| | | return R.fail("æä½å¤±è´¥"); |
| | | } |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * è·åéåæ°æ® |
| | | * |
| | | * @param queueName éåå |
| | | */ |
| | | @GetMapping("/get") |
| | | public R<Void> get(String queueName) { |
| | | PriorityDemo data; |
| | | do { |
| | | data = QueueUtils.getQueueObject(queueName); |
| | | log.info("éé: {} , è·åæ°æ®: {}", queueName, data); |
| | | } while (data != null); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æµè¯å表对象 test_demo |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("test_demo") |
| | | public class TestDemo extends BaseEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * ç¨æ·id |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * æåºå· |
| | | */ |
| | | @OrderBy(asc = false, sort = 1) |
| | | private Integer orderNum; |
| | | |
| | | /** |
| | | * keyé® |
| | | */ |
| | | private String testKey; |
| | | |
| | | /** |
| | | * å¼ |
| | | */ |
| | | private String value; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | @Version |
| | | private Long version; |
| | | |
| | | /** |
| | | * å 餿 å¿ |
| | | */ |
| | | @TableLogic |
| | | private Long delFlag; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.annotation.Version; |
| | | import com.ruoyi.common.core.web.domain.TreeEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æµè¯æ 表对象 test_tree |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("test_tree") |
| | | public class TestTree extends TreeEntity<TestTree> { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * ç¨æ·id |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * æ èç¹å |
| | | */ |
| | | private String treeName; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | @Version |
| | | private Long version; |
| | | |
| | | /** |
| | | * å 餿 å¿ |
| | | */ |
| | | @TableLogic |
| | | private Long delFlag; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.domain.bo; |
| | | |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | |
| | | /** |
| | | * æµè¯å表ä¸å¡å¯¹è±¡ test_demo |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class TestDemoBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long id; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | @NotNull(message = "é¨é¨idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * ç¨æ·id |
| | | */ |
| | | @NotNull(message = "ç¨æ·idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Long userId; |
| | | |
| | | /** |
| | | * æåºå· |
| | | */ |
| | | @NotNull(message = "æåºå·ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Integer orderNum; |
| | | |
| | | /** |
| | | * keyé® |
| | | */ |
| | | @NotBlank(message = "keyé®ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String testKey; |
| | | |
| | | /** |
| | | * å¼ |
| | | */ |
| | | @NotBlank(message = "å¼ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String value; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.domain.bo; |
| | | |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import com.ruoyi.common.core.web.domain.TreeEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | |
| | | /** |
| | | * æµè¯æ 表ä¸å¡å¯¹è±¡ test_tree |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class TestTreeBo extends TreeEntity<TestTreeBo> { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long id; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | @NotNull(message = "é¨é¨idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * ç¨æ·id |
| | | */ |
| | | @NotNull(message = "ç¨æ·idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Long userId; |
| | | |
| | | /** |
| | | * æ èç¹å |
| | | */ |
| | | @NotBlank(message = "æ èç¹åä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String treeName; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Constants; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.mybatis.annotation.DataColumn; |
| | | import com.ruoyi.common.mybatis.annotation.DataPermission; |
| | | import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import com.ruoyi.demo.domain.TestDemo; |
| | | import com.ruoyi.demo.domain.vo.TestDemoVo; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµè¯å表Mapperæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | public interface TestDemoMapper extends BaseMapperPlus<TestDemoMapper, TestDemo, TestDemoVo> { |
| | | |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper); |
| | | |
| | | @Override |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | <P extends IPage<TestDemo>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper); |
| | | |
| | | @Override |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | List<TestDemo> selectList(@Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper); |
| | | |
| | | @Override |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | int updateById(@Param(Constants.ENTITY) TestDemo entity); |
| | | |
| | | @Override |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | int deleteBatchIds(@Param(Constants.COLL) Collection<?> idList); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.mapper; |
| | | |
| | | import com.ruoyi.common.mybatis.annotation.DataColumn; |
| | | import com.ruoyi.common.mybatis.annotation.DataPermission; |
| | | import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import com.ruoyi.demo.domain.TestTree; |
| | | import com.ruoyi.demo.domain.vo.TestTreeVo; |
| | | |
| | | /** |
| | | * æµè¯æ 表Mapperæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | public interface TestTreeMapper extends BaseMapperPlus<TestTreeMapper, TestTree, TestTreeVo> { |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.service; |
| | | |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.demo.domain.TestDemo; |
| | | import com.ruoyi.demo.domain.bo.TestDemoBo; |
| | | import com.ruoyi.demo.domain.vo.TestDemoVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµè¯å表Serviceæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | public interface ITestDemoService { |
| | | |
| | | /** |
| | | * æ¥è¯¢å个 |
| | | * |
| | | * @return |
| | | */ |
| | | TestDemoVo queryById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢å表 |
| | | */ |
| | | TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * èªå®ä¹å页æ¥è¯¢ |
| | | */ |
| | | TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å表 |
| | | */ |
| | | List<TestDemoVo> queryList(TestDemoBo bo); |
| | | |
| | | /** |
| | | * æ ¹æ®æ°å¢ä¸å¡å¯¹è±¡æå
¥æµè¯å表 |
| | | * |
| | | * @param bo æµè¯å表æ°å¢ä¸å¡å¯¹è±¡ |
| | | * @return |
| | | */ |
| | | Boolean insertByBo(TestDemoBo bo); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¼è¾ä¸å¡å¯¹è±¡ä¿®æ¹æµè¯å表 |
| | | * |
| | | * @param bo æµè¯å表ç¼è¾ä¸å¡å¯¹è±¡ |
| | | * @return |
| | | */ |
| | | Boolean updateByBo(TestDemoBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶å 餿°æ® |
| | | * |
| | | * @param ids 主é®éå |
| | | * @param isValid æ¯å¦æ ¡éª,true-å é¤åæ ¡éª,false-䏿 ¡éª |
| | | * @return |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | |
| | | /** |
| | | * æ¹éä¿å |
| | | */ |
| | | Boolean saveBatch(List<TestDemo> list); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.demo.domain.TestDemo; |
| | | import com.ruoyi.demo.domain.bo.TestDemoBo; |
| | | import com.ruoyi.demo.domain.vo.TestDemoVo; |
| | | import com.ruoyi.demo.mapper.TestDemoMapper; |
| | | import com.ruoyi.demo.service.ITestDemoService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµè¯å表Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class TestDemoServiceImpl implements ITestDemoService { |
| | | |
| | | private final TestDemoMapper baseMapper; |
| | | |
| | | @Override |
| | | public TestDemoVo queryById(Long id) { |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo); |
| | | Page<TestDemoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹å页æ¥è¯¢ |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo); |
| | | Page<TestDemoVo> result = baseMapper.customPageList(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | @Override |
| | | public List<TestDemoVo> queryList(TestDemoBo bo) { |
| | | return baseMapper.selectVoList(buildQueryWrapper(bo)); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<TestDemo> buildQueryWrapper(TestDemoBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<TestDemo> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue()); |
| | | lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, |
| | | TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); |
| | | return lqw; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean insertByBo(TestDemoBo bo) { |
| | | TestDemo add = BeanUtil.toBean(bo, TestDemo.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean updateByBo(TestDemoBo bo) { |
| | | TestDemo update = BeanUtil.toBean(bo, TestDemo.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | * |
| | | * @param entity å®ä½ç±»æ°æ® |
| | | */ |
| | | private void validEntityBeforeSave(TestDemo entity) { |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if (isValid) { |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean saveBatch(List<TestDemo> list) { |
| | | return baseMapper.insertBatch(list); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.demo.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.demo.domain.TestTree; |
| | | import com.ruoyi.demo.domain.bo.TestTreeBo; |
| | | import com.ruoyi.demo.domain.vo.TestTreeVo; |
| | | import com.ruoyi.demo.mapper.TestTreeMapper; |
| | | import com.ruoyi.demo.service.ITestTreeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµè¯æ 表Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author Lion Li |
| | | * @date 2021-07-26 |
| | | */ |
| | | // @DS("slave") // 忢ä»åºæ¥è¯¢ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class TestTreeServiceImpl implements ITestTreeService { |
| | | |
| | | private final TestTreeMapper baseMapper; |
| | | |
| | | @Override |
| | | public TestTreeVo queryById(Long id) { |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | // @DS("slave") // 忢ä»åºæ¥è¯¢ |
| | | @Override |
| | | public List<TestTreeVo> queryList(TestTreeBo bo) { |
| | | LambdaQueryWrapper<TestTree> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<TestTree> buildQueryWrapper(TestTreeBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<TestTree> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName()); |
| | | lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, |
| | | TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); |
| | | return lqw; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean insertByBo(TestTreeBo bo) { |
| | | TestTree add = BeanUtil.toBean(bo, TestTree.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean updateByBo(TestTreeBo bo) { |
| | | TestTree update = BeanUtil.toBean(bo, TestTree.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | * |
| | | * @param entity å®ä½ç±»æ°æ® |
| | | */ |
| | | private void validEntityBeforeSave(TestTree entity) { |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if (isValid) { |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-generator</artifactId> |
| | | |
| | | <description> |
| | | generator 代ç çæ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <!-- éç¨å·¥å
·--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | </dependency> |
| | | |
| | | <!--velocity代ç çæä½¿ç¨æ¨¡æ¿ --> |
| | | <dependency> |
| | | <groupId>org.apache.velocity</groupId> |
| | | <artifactId>velocity-engine-core</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.generator.domain.GenTable; |
| | | import com.ruoyi.generator.domain.GenTableColumn; |
| | | import com.ruoyi.generator.service.IGenTableService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 代ç çæ æä½å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/tool/gen") |
| | | public class GenController extends BaseController { |
| | | |
| | | private final IGenTableService genTableService; |
| | | |
| | | /** |
| | | * æ¥è¯¢ä»£ç çæå表 |
| | | */ |
| | | @SaCheckPermission("tool:gen:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<GenTable> genList(GenTable genTable, PageQuery pageQuery) { |
| | | return genTableService.selectPageGenTableList(genTable, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä»£ç çæä¸å¡ |
| | | * |
| | | * @param tableId 表ID |
| | | */ |
| | | @SaCheckPermission("tool:gen:query") |
| | | @GetMapping(value = "/{tableId}") |
| | | public R<Map<String, Object>> getInfo(@PathVariable Long tableId) { |
| | | GenTable table = genTableService.selectGenTableById(tableId); |
| | | List<GenTable> tables = genTableService.selectGenTableAll(); |
| | | List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId); |
| | | Map<String, Object> map = new HashMap<String, Object>(); |
| | | map.put("info", table); |
| | | map.put("rows", list); |
| | | map.put("tables", tables); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æ°æ®åºå表 |
| | | */ |
| | | @SaCheckPermission("tool:gen:list") |
| | | @GetMapping("/db/list") |
| | | public TableDataInfo<GenTable> dataList(GenTable genTable, PageQuery pageQuery) { |
| | | return genTableService.selectPageDbTableList(genTable, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æ°æ®è¡¨å段å表 |
| | | * |
| | | * @param tableId 表ID |
| | | */ |
| | | @SaCheckPermission("tool:gen:list") |
| | | @GetMapping(value = "/column/{tableId}") |
| | | public TableDataInfo<GenTableColumn> columnList(Long tableId) { |
| | | TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>(); |
| | | List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId); |
| | | dataInfo.setRows(list); |
| | | dataInfo.setTotal(list.size()); |
| | | return dataInfo; |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥è¡¨ç»æï¼ä¿åï¼ |
| | | * |
| | | * @param tables 表å串 |
| | | */ |
| | | @SaCheckPermission("tool:gen:import") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.IMPORT) |
| | | @PostMapping("/importTable") |
| | | public R<Void> importTableSave(String tables) { |
| | | String[] tableNames = Convert.toStrArray(tables); |
| | | // æ¥è¯¢è¡¨ä¿¡æ¯ |
| | | List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames); |
| | | genTableService.importGenTable(tableList); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¿å代ç çæä¸å¡ |
| | | */ |
| | | @SaCheckPermission("tool:gen:edit") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> editSave(@Validated @RequestBody GenTable genTable) { |
| | | genTableService.validateEdit(genTable); |
| | | genTableService.updateGenTable(genTable); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ä»£ç çæ |
| | | * |
| | | * @param tableIds 表ID串 |
| | | */ |
| | | @SaCheckPermission("tool:gen:remove") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{tableIds}") |
| | | public R<Void> remove(@PathVariable Long[] tableIds) { |
| | | genTableService.deleteGenTableByIds(tableIds); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * é¢è§ä»£ç |
| | | * |
| | | * @param tableId 表ID |
| | | */ |
| | | @SaCheckPermission("tool:gen:preview") |
| | | @GetMapping("/preview/{tableId}") |
| | | public R<Map<String, String>> preview(@PathVariable("tableId") Long tableId) throws IOException { |
| | | Map<String, String> dataMap = genTableService.previewCode(tableId); |
| | | return R.ok(dataMap); |
| | | } |
| | | |
| | | /** |
| | | * çæä»£ç ï¼ä¸è½½æ¹å¼ï¼ |
| | | * |
| | | * @param tableName 表å |
| | | */ |
| | | @SaCheckPermission("tool:gen:code") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.GENCODE) |
| | | @GetMapping("/download/{tableName}") |
| | | public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException { |
| | | byte[] data = genTableService.downloadCode(tableName); |
| | | genCode(response, data); |
| | | } |
| | | |
| | | /** |
| | | * çæä»£ç ï¼èªå®ä¹è·¯å¾ï¼ |
| | | * |
| | | * @param tableName 表å |
| | | */ |
| | | @SaCheckPermission("tool:gen:code") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.GENCODE) |
| | | @GetMapping("/genCode/{tableName}") |
| | | public R<Void> genCode(@PathVariable("tableName") String tableName) { |
| | | genTableService.generatorCode(tableName); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * åæ¥æ°æ®åº |
| | | * |
| | | * @param tableName 表å |
| | | */ |
| | | @SaCheckPermission("tool:gen:edit") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.UPDATE) |
| | | @GetMapping("/synchDb/{tableName}") |
| | | public R<Void> synchDb(@PathVariable("tableName") String tableName) { |
| | | genTableService.synchDb(tableName); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éçæä»£ç |
| | | * |
| | | * @param tables 表å串 |
| | | */ |
| | | @SaCheckPermission("tool:gen:code") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.GENCODE) |
| | | @GetMapping("/batchGenCode") |
| | | public void batchGenCode(HttpServletResponse response, String tables) throws IOException { |
| | | String[] tableNames = Convert.toStrArray(tables); |
| | | byte[] data = genTableService.downloadCode(tableNames); |
| | | genCode(response, data); |
| | | } |
| | | |
| | | /** |
| | | * çæzipæä»¶ |
| | | */ |
| | | private void genCode(HttpServletResponse response, byte[] data) throws IOException { |
| | | response.reset(); |
| | | response.addHeader("Access-Control-Allow-Origin", "*"); |
| | | response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); |
| | | response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); |
| | | response.addHeader("Content-Length", "" + data.length); |
| | | response.setContentType("application/octet-stream; charset=UTF-8"); |
| | | IoUtil.write(response.getOutputStream(), false, data); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import com.ruoyi.common.core.constant.GenConstants; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import jakarta.validation.Valid; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.apache.commons.lang3.ArrayUtils; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ä¸å¡è¡¨ gen_table |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("gen_table") |
| | | public class GenTable extends BaseEntity { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId(value = "table_id") |
| | | private Long tableId; |
| | | |
| | | /** |
| | | * 表åç§° |
| | | */ |
| | | @NotBlank(message = "表åç§°ä¸è½ä¸ºç©º") |
| | | private String tableName; |
| | | |
| | | /** |
| | | * 表æè¿° |
| | | */ |
| | | @NotBlank(message = "表æè¿°ä¸è½ä¸ºç©º") |
| | | private String tableComment; |
| | | |
| | | /** |
| | | * å
³èç¶è¡¨ç表å |
| | | */ |
| | | private String subTableName; |
| | | |
| | | /** |
| | | * æ¬è¡¨å
³èç¶è¡¨çå¤é®å |
| | | */ |
| | | private String subTableFkName; |
| | | |
| | | /** |
| | | * å®ä½ç±»åç§°(é¦åæ¯å¤§å) |
| | | */ |
| | | @NotBlank(message = "å®ä½ç±»åç§°ä¸è½ä¸ºç©º") |
| | | private String className; |
| | | |
| | | /** |
| | | * 使ç¨ç模æ¿ï¼crudå表æä½ treeæ 表æä½ sub主å表æä½ï¼ |
| | | */ |
| | | private String tplCategory; |
| | | |
| | | /** |
| | | * çæå
è·¯å¾ |
| | | */ |
| | | @NotBlank(message = "çæå
è·¯å¾ä¸è½ä¸ºç©º") |
| | | private String packageName; |
| | | |
| | | /** |
| | | * çææ¨¡åå |
| | | */ |
| | | @NotBlank(message = "çææ¨¡ååä¸è½ä¸ºç©º") |
| | | private String moduleName; |
| | | |
| | | /** |
| | | * çæä¸å¡å |
| | | */ |
| | | @NotBlank(message = "çæä¸å¡åä¸è½ä¸ºç©º") |
| | | private String businessName; |
| | | |
| | | /** |
| | | * çæåè½å |
| | | */ |
| | | @NotBlank(message = "çæåè½åä¸è½ä¸ºç©º") |
| | | private String functionName; |
| | | |
| | | /** |
| | | * çæä½è
|
| | | */ |
| | | @NotBlank(message = "ä½è
ä¸è½ä¸ºç©º") |
| | | private String functionAuthor; |
| | | |
| | | /** |
| | | * çæä»£ç æ¹å¼ï¼0zipå缩å
1èªå®ä¹è·¯å¾ï¼ |
| | | */ |
| | | private String genType; |
| | | |
| | | /** |
| | | * çæè·¯å¾ï¼ä¸å¡«é»è®¤é¡¹ç®è·¯å¾ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) |
| | | private String genPath; |
| | | |
| | | /** |
| | | * 主é®ä¿¡æ¯ |
| | | */ |
| | | @TableField(exist = false) |
| | | private GenTableColumn pkColumn; |
| | | |
| | | /** |
| | | * 表åä¿¡æ¯ |
| | | */ |
| | | @Valid |
| | | @TableField(exist = false) |
| | | private List<GenTableColumn> columns; |
| | | |
| | | /** |
| | | * å
¶å®çæé项 |
| | | */ |
| | | private String options; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | /** |
| | | * æ ç¼ç åæ®µ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String treeCode; |
| | | |
| | | /** |
| | | * æ ç¶ç¼ç åæ®µ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String treeParentCode; |
| | | |
| | | /** |
| | | * æ åç§°åæ®µ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String treeName; |
| | | |
| | | /* |
| | | * èåidå表 |
| | | */ |
| | | @TableField(exist = false) |
| | | private List<Long> menuIds; |
| | | |
| | | /** |
| | | * ä¸çº§èåIDåæ®µ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String parentMenuId; |
| | | |
| | | /** |
| | | * ä¸çº§èååç§°åæ®µ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String parentMenuName; |
| | | |
| | | public boolean isTree() { |
| | | return isTree(this.tplCategory); |
| | | } |
| | | |
| | | public static boolean isTree(String tplCategory) { |
| | | return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); |
| | | } |
| | | |
| | | public boolean isCrud() { |
| | | return isCrud(this.tplCategory); |
| | | } |
| | | |
| | | public static boolean isCrud(String tplCategory) { |
| | | return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); |
| | | } |
| | | |
| | | public boolean isSuperColumn(String javaField) { |
| | | return isSuperColumn(this.tplCategory, javaField); |
| | | } |
| | | |
| | | public static boolean isSuperColumn(String tplCategory, String javaField) { |
| | | if (isTree(tplCategory)) { |
| | | return StringUtils.equalsAnyIgnoreCase(javaField, |
| | | ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); |
| | | } |
| | | return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldStrategy; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * 代ç çæä¸å¡å段表 gen_table_column |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("gen_table_column") |
| | | public class GenTableColumn extends BaseEntity { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId(value = "column_id") |
| | | private Long columnId; |
| | | |
| | | /** |
| | | * å½å±è¡¨ç¼å· |
| | | */ |
| | | private Long tableId; |
| | | |
| | | /** |
| | | * ååç§° |
| | | */ |
| | | private String columnName; |
| | | |
| | | /** |
| | | * åæè¿° |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String columnComment; |
| | | |
| | | /** |
| | | * åç±»å |
| | | */ |
| | | private String columnType; |
| | | |
| | | /** |
| | | * JAVAç±»å |
| | | */ |
| | | private String javaType; |
| | | |
| | | /** |
| | | * JAVAåæ®µå |
| | | */ |
| | | @NotBlank(message = "Java屿§ä¸è½ä¸ºç©º") |
| | | private String javaField; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸»é®ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isPk; |
| | | |
| | | /** |
| | | * æ¯å¦èªå¢ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isIncrement; |
| | | |
| | | /** |
| | | * æ¯å¦å¿
å¡«ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isRequired; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºæå
¥å段ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isInsert; |
| | | |
| | | /** |
| | | * æ¯å¦ç¼è¾å段ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isEdit; |
| | | |
| | | /** |
| | | * æ¯å¦åè¡¨åæ®µï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isList; |
| | | |
| | | /** |
| | | * æ¯å¦æ¥è¯¢å段ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | private String isQuery; |
| | | |
| | | /** |
| | | * æ¥è¯¢æ¹å¼ï¼EQçäºãNEä¸çäºãGT大äºãLTå°äºãLIKE模ç³ãBETWEENèå´ï¼ |
| | | */ |
| | | private String queryType; |
| | | |
| | | /** |
| | | * æ¾ç¤ºç±»åï¼inputææ¬æ¡ãtextareaææ¬åãselect䏿æ¡ãcheckboxå¤éæ¡ãradioåéæ¡ãdatetimeæ¥ææ§ä»¶ãimageå¾çä¸ä¼ æ§ä»¶ãuploadæä»¶ä¸ä¼ æ§ä»¶ãeditorå¯ææ¬æ§ä»¶ï¼ |
| | | */ |
| | | private String htmlType; |
| | | |
| | | /** |
| | | * åå
¸ç±»å |
| | | */ |
| | | private String dictType; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | private Integer sort; |
| | | |
| | | public String getCapJavaField() { |
| | | return StringUtils.capitalize(javaField); |
| | | } |
| | | |
| | | public boolean isPk() { |
| | | return isPk(this.isPk); |
| | | } |
| | | |
| | | public boolean isPk(String isPk) { |
| | | return isPk != null && StringUtils.equals("1", isPk); |
| | | } |
| | | |
| | | public boolean isIncrement() { |
| | | return isIncrement(this.isIncrement); |
| | | } |
| | | |
| | | public boolean isIncrement(String isIncrement) { |
| | | return isIncrement != null && StringUtils.equals("1", isIncrement); |
| | | } |
| | | |
| | | public boolean isRequired() { |
| | | return isRequired(this.isRequired); |
| | | } |
| | | |
| | | public boolean isRequired(String isRequired) { |
| | | return isRequired != null && StringUtils.equals("1", isRequired); |
| | | } |
| | | |
| | | public boolean isInsert() { |
| | | return isInsert(this.isInsert); |
| | | } |
| | | |
| | | public boolean isInsert(String isInsert) { |
| | | return isInsert != null && StringUtils.equals("1", isInsert); |
| | | } |
| | | |
| | | public boolean isEdit() { |
| | | return isInsert(this.isEdit); |
| | | } |
| | | |
| | | public boolean isEdit(String isEdit) { |
| | | return isEdit != null && StringUtils.equals("1", isEdit); |
| | | } |
| | | |
| | | public boolean isList() { |
| | | return isList(this.isList); |
| | | } |
| | | |
| | | public boolean isList(String isList) { |
| | | return isList != null && StringUtils.equals("1", isList); |
| | | } |
| | | |
| | | public boolean isQuery() { |
| | | return isQuery(this.isQuery); |
| | | } |
| | | |
| | | public boolean isQuery(String isQuery) { |
| | | return isQuery != null && StringUtils.equals("1", isQuery); |
| | | } |
| | | |
| | | public boolean isSuperColumn() { |
| | | return isSuperColumn(this.javaField); |
| | | } |
| | | |
| | | public static boolean isSuperColumn(String javaField) { |
| | | return StringUtils.equalsAnyIgnoreCase(javaField, |
| | | // BaseEntity |
| | | "createBy", "createTime", "updateBy", "updateTime", |
| | | // TreeEntity |
| | | "parentName", "parentId"); |
| | | } |
| | | |
| | | public boolean isUsableColumn() { |
| | | return isUsableColumn(javaField); |
| | | } |
| | | |
| | | public static boolean isUsableColumn(String javaField) { |
| | | // isSuperColumn()ä¸çååç¨äºé¿å
çæå¤ä½Domain屿§ï¼è¥æäºå±æ§å¨çæé¡µé¢æ¶éè¦ç¨å°ä¸è½å¿½ç¥ï¼åæ¾å¨æ¤å¤ç½åå |
| | | return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); |
| | | } |
| | | |
| | | public String readConverterExp() { |
| | | String remarks = StringUtils.substringBetween(this.columnComment, "ï¼", "ï¼"); |
| | | StringBuffer sb = new StringBuffer(); |
| | | if (StringUtils.isNotEmpty(remarks)) { |
| | | for (String value : remarks.split(" ")) { |
| | | if (StringUtils.isNotEmpty(value)) { |
| | | Object startStr = value.subSequence(0, 1); |
| | | String endStr = value.substring(1); |
| | | sb.append("").append(startStr).append("=").append(endStr).append(","); |
| | | } |
| | | } |
| | | return sb.deleteCharAt(sb.length() - 1).toString(); |
| | | } else { |
| | | return this.columnComment; |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| | | import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import com.ruoyi.generator.domain.GenTableColumn; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ä¸å¡å段 æ°æ®å± |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @InterceptorIgnore(dataPermission = "true") |
| | | public interface GenTableColumnMapper extends BaseMapperPlus<GenTableColumnMapper, GenTableColumn, GenTableColumn> { |
| | | /** |
| | | * æ ¹æ®è¡¨åç§°æ¥è¯¢åä¿¡æ¯ |
| | | * |
| | | * @param tableName 表åç§° |
| | | * @return åä¿¡æ¯ |
| | | */ |
| | | List<GenTableColumn> selectDbTableColumnsByName(String tableName); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import com.ruoyi.generator.domain.GenTable; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ä¸å¡ æ°æ®å± |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @InterceptorIgnore(dataPermission = "true") |
| | | public interface GenTableMapper extends BaseMapperPlus<GenTableMapper, GenTable, GenTable> { |
| | | |
| | | /** |
| | | * æ¥è¯¢æ®åºå表 |
| | | * |
| | | * @param genTable æ¥è¯¢æ¡ä»¶ |
| | | * @return æ°æ®åºè¡¨éå |
| | | */ |
| | | Page<GenTable> selectPageDbTableList(@Param("page") Page<GenTable> page, @Param("genTable") GenTable genTable); |
| | | |
| | | /** |
| | | * æ¥è¯¢æ®åºå表 |
| | | * |
| | | * @param tableNames 表åç§°ç» |
| | | * @return æ°æ®åºè¡¨éå |
| | | */ |
| | | List<GenTable> selectDbTableListByNames(String[] tableNames); |
| | | |
| | | /** |
| | | * æ¥è¯¢ææè¡¨ä¿¡æ¯ |
| | | * |
| | | * @return 表信æ¯éå |
| | | */ |
| | | List<GenTable> selectGenTableAll(); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨IDä¸å¡ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸å¡ID |
| | | * @return ä¸å¡ä¿¡æ¯ |
| | | */ |
| | | GenTable selectGenTableById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨åç§°ä¸å¡ä¿¡æ¯ |
| | | * |
| | | * @param tableName 表åç§° |
| | | * @return ä¸å¡ä¿¡æ¯ |
| | | */ |
| | | GenTable selectGenTableByName(String tableName); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.service; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import com.ruoyi.common.core.constant.GenConstants; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StreamUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.file.FileUtils; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import com.ruoyi.generator.domain.GenTable; |
| | | import com.ruoyi.generator.domain.GenTableColumn; |
| | | import com.ruoyi.generator.mapper.GenTableColumnMapper; |
| | | import com.ruoyi.generator.mapper.GenTableMapper; |
| | | import com.ruoyi.generator.util.GenUtils; |
| | | import com.ruoyi.generator.util.VelocityInitializer; |
| | | import com.ruoyi.generator.util.VelocityUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.velocity.Template; |
| | | import org.apache.velocity.VelocityContext; |
| | | import org.apache.velocity.app.Velocity; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.io.StringWriter; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.*; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipOutputStream; |
| | | |
| | | /** |
| | | * ä¸å¡ æå¡å±å®ç° |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @DS("#header.datasource") |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class GenTableServiceImpl implements IGenTableService { |
| | | |
| | | private final GenTableMapper baseMapper; |
| | | private final GenTableColumnMapper genTableColumnMapper; |
| | | private final IdentifierGenerator identifierGenerator; |
| | | |
| | | /** |
| | | * æ¥è¯¢ä¸å¡å段å表 |
| | | * |
| | | * @param tableId ä¸å¡å段ç¼å· |
| | | * @return ä¸å¡å段éå |
| | | */ |
| | | @Override |
| | | public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId) { |
| | | return genTableColumnMapper.selectList(new LambdaQueryWrapper<GenTableColumn>() |
| | | .eq(GenTableColumn::getTableId, tableId) |
| | | .orderByAsc(GenTableColumn::getSort)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ä¸å¡ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸å¡ID |
| | | * @return ä¸å¡ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public GenTable selectGenTableById(Long id) { |
| | | GenTable genTable = baseMapper.selectGenTableById(id); |
| | | setTableFromOptions(genTable); |
| | | return genTable; |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery) { |
| | | Page<GenTable> page = baseMapper.selectPage(pageQuery.build(), this.buildGenTableQueryWrapper(genTable)); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) { |
| | | Map<String, Object> params = genTable.getParams(); |
| | | QueryWrapper<GenTable> wrapper = Wrappers.query(); |
| | | wrapper.like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName())) |
| | | .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment())) |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "create_time", params.get("beginTime"), params.get("endTime")); |
| | | return wrapper; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) { |
| | | Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), genTable); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æ®åºå表 |
| | | * |
| | | * @param tableNames 表åç§°ç» |
| | | * @return æ°æ®åºè¡¨éå |
| | | */ |
| | | @Override |
| | | public List<GenTable> selectDbTableListByNames(String[] tableNames) { |
| | | return baseMapper.selectDbTableListByNames(tableNames); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ææè¡¨ä¿¡æ¯ |
| | | * |
| | | * @return 表信æ¯éå |
| | | */ |
| | | @Override |
| | | public List<GenTable> selectGenTableAll() { |
| | | return baseMapper.selectGenTableAll(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¸å¡ |
| | | * |
| | | * @param genTable ä¸å¡ä¿¡æ¯ |
| | | * @return ç»æ |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void updateGenTable(GenTable genTable) { |
| | | String options = JsonUtils.toJsonString(genTable.getParams()); |
| | | genTable.setOptions(options); |
| | | int row = baseMapper.updateById(genTable); |
| | | if (row > 0) { |
| | | for (GenTableColumn cenTableColumn : genTable.getColumns()) { |
| | | genTableColumnMapper.updateById(cenTableColumn); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å é¤ä¸å¡å¯¹è±¡ |
| | | * |
| | | * @param tableIds éè¦å é¤çæ°æ®ID |
| | | * @return ç»æ |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void deleteGenTableByIds(Long[] tableIds) { |
| | | List<Long> ids = Arrays.asList(tableIds); |
| | | baseMapper.deleteBatchIds(ids); |
| | | genTableColumnMapper.delete(new LambdaQueryWrapper<GenTableColumn>().in(GenTableColumn::getTableId, ids)); |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥è¡¨ç»æ |
| | | * |
| | | * @param tableList 导å
¥è¡¨å表 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void importGenTable(List<GenTable> tableList) { |
| | | String operName = LoginHelper.getUsername(); |
| | | try { |
| | | for (GenTable table : tableList) { |
| | | String tableName = table.getTableName(); |
| | | GenUtils.initTable(table, operName); |
| | | int row = baseMapper.insert(table); |
| | | if (row > 0) { |
| | | // ä¿ååä¿¡æ¯ |
| | | List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); |
| | | List<GenTableColumn> saveColumns = new ArrayList<>(); |
| | | for (GenTableColumn column : genTableColumns) { |
| | | GenUtils.initColumnField(column, table); |
| | | saveColumns.add(column); |
| | | } |
| | | if (CollUtil.isNotEmpty(saveColumns)) { |
| | | genTableColumnMapper.insertBatch(saveColumns); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | throw new ServiceException("导å
¥å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * é¢è§ä»£ç |
| | | * |
| | | * @param tableId 表ç¼å· |
| | | * @return é¢è§æ°æ®å表 |
| | | */ |
| | | @Override |
| | | public Map<String, String> previewCode(Long tableId) { |
| | | Map<String, String> dataMap = new LinkedHashMap<>(); |
| | | // æ¥è¯¢è¡¨ä¿¡æ¯ |
| | | GenTable table = baseMapper.selectGenTableById(tableId); |
| | | List<Long> menuIds = new ArrayList<>(); |
| | | for (int i = 0; i < 6; i++) { |
| | | menuIds.add(identifierGenerator.nextId(null).longValue()); |
| | | } |
| | | table.setMenuIds(menuIds); |
| | | // 设置主é®åä¿¡æ¯ |
| | | setPkColumn(table); |
| | | VelocityInitializer.initVelocity(); |
| | | |
| | | VelocityContext context = VelocityUtils.prepareContext(table); |
| | | |
| | | // è·å模æ¿å表 |
| | | List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); |
| | | for (String template : templates) { |
| | | // æ¸²ææ¨¡æ¿ |
| | | StringWriter sw = new StringWriter(); |
| | | Template tpl = Velocity.getTemplate(template, Constants.UTF8); |
| | | tpl.merge(context, sw); |
| | | dataMap.put(template, sw.toString()); |
| | | } |
| | | return dataMap; |
| | | } |
| | | |
| | | /** |
| | | * çæä»£ç ï¼ä¸è½½æ¹å¼ï¼ |
| | | * |
| | | * @param tableName 表åç§° |
| | | * @return æ°æ® |
| | | */ |
| | | @Override |
| | | public byte[] downloadCode(String tableName) { |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | ZipOutputStream zip = new ZipOutputStream(outputStream); |
| | | generatorCode(tableName, zip); |
| | | IoUtil.close(zip); |
| | | return outputStream.toByteArray(); |
| | | } |
| | | |
| | | /** |
| | | * çæä»£ç ï¼èªå®ä¹è·¯å¾ï¼ |
| | | * |
| | | * @param tableName 表åç§° |
| | | */ |
| | | @Override |
| | | public void generatorCode(String tableName) { |
| | | // æ¥è¯¢è¡¨ä¿¡æ¯ |
| | | GenTable table = baseMapper.selectGenTableByName(tableName); |
| | | // 设置主é®åä¿¡æ¯ |
| | | setPkColumn(table); |
| | | |
| | | VelocityInitializer.initVelocity(); |
| | | |
| | | VelocityContext context = VelocityUtils.prepareContext(table); |
| | | |
| | | // è·å模æ¿å表 |
| | | List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); |
| | | for (String template : templates) { |
| | | if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) { |
| | | // æ¸²ææ¨¡æ¿ |
| | | StringWriter sw = new StringWriter(); |
| | | Template tpl = Velocity.getTemplate(template, Constants.UTF8); |
| | | tpl.merge(context, sw); |
| | | try { |
| | | String path = getGenPath(table, template); |
| | | FileUtils.writeUtf8String(sw.toString(), path); |
| | | } catch (Exception e) { |
| | | throw new ServiceException("æ¸²ææ¨¡æ¿å¤±è´¥ï¼è¡¨åï¼" + table.getTableName()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * åæ¥æ°æ®åº |
| | | * |
| | | * @param tableName 表åç§° |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void synchDb(String tableName) { |
| | | GenTable table = baseMapper.selectGenTableByName(tableName); |
| | | List<GenTableColumn> tableColumns = table.getColumns(); |
| | | Map<String, GenTableColumn> tableColumnMap = StreamUtils.toIdentityMap(tableColumns, GenTableColumn::getColumnName); |
| | | |
| | | List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); |
| | | if (CollUtil.isEmpty(dbTableColumns)) { |
| | | throw new ServiceException("åæ¥æ°æ®å¤±è´¥ï¼åè¡¨ç»æä¸åå¨"); |
| | | } |
| | | List<String> dbTableColumnNames = StreamUtils.toList(dbTableColumns, GenTableColumn::getColumnName); |
| | | |
| | | List<GenTableColumn> saveColumns = new ArrayList<>(); |
| | | dbTableColumns.forEach(column -> { |
| | | GenUtils.initColumnField(column, table); |
| | | if (tableColumnMap.containsKey(column.getColumnName())) { |
| | | GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); |
| | | column.setColumnId(prevColumn.getColumnId()); |
| | | if (column.isList()) { |
| | | // 妿æ¯å表ï¼ç»§ç»ä¿çæ¥è¯¢æ¹å¼/åå
¸ç±»åé项 |
| | | column.setDictType(prevColumn.getDictType()); |
| | | column.setQueryType(prevColumn.getQueryType()); |
| | | } |
| | | if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() |
| | | && (column.isInsert() || column.isEdit()) |
| | | && ((column.isUsableColumn()) || (!column.isSuperColumn()))) { |
| | | // 妿æ¯(æ°å¢/ä¿®æ¹&é主é®/é忽ç¥åç¶å±æ§)ï¼ç»§ç»ä¿çå¿
å¡«/æ¾ç¤ºç±»åé项 |
| | | column.setIsRequired(prevColumn.getIsRequired()); |
| | | column.setHtmlType(prevColumn.getHtmlType()); |
| | | } |
| | | genTableColumnMapper.updateById(column); |
| | | } else { |
| | | genTableColumnMapper.insert(column); |
| | | } |
| | | }); |
| | | if (CollUtil.isNotEmpty(saveColumns)) { |
| | | genTableColumnMapper.insertBatch(saveColumns); |
| | | } |
| | | List<GenTableColumn> delColumns = StreamUtils.filter(tableColumns, column -> !dbTableColumnNames.contains(column.getColumnName())); |
| | | if (CollUtil.isNotEmpty(delColumns)) { |
| | | List<Long> ids = StreamUtils.toList(delColumns, GenTableColumn::getColumnId); |
| | | genTableColumnMapper.deleteBatchIds(ids); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¹éçæä»£ç ï¼ä¸è½½æ¹å¼ï¼ |
| | | * |
| | | * @param tableNames 表æ°ç» |
| | | * @return æ°æ® |
| | | */ |
| | | @Override |
| | | public byte[] downloadCode(String[] tableNames) { |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | ZipOutputStream zip = new ZipOutputStream(outputStream); |
| | | for (String tableName : tableNames) { |
| | | generatorCode(tableName, zip); |
| | | } |
| | | IoUtil.close(zip); |
| | | return outputStream.toByteArray(); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨ä¿¡æ¯å¹¶çæä»£ç |
| | | */ |
| | | private void generatorCode(String tableName, ZipOutputStream zip) { |
| | | // æ¥è¯¢è¡¨ä¿¡æ¯ |
| | | GenTable table = baseMapper.selectGenTableByName(tableName); |
| | | List<Long> menuIds = new ArrayList<>(); |
| | | for (int i = 0; i < 6; i++) { |
| | | menuIds.add(identifierGenerator.nextId(null).longValue()); |
| | | } |
| | | table.setMenuIds(menuIds); |
| | | // 设置主é®åä¿¡æ¯ |
| | | setPkColumn(table); |
| | | |
| | | VelocityInitializer.initVelocity(); |
| | | |
| | | VelocityContext context = VelocityUtils.prepareContext(table); |
| | | |
| | | // è·å模æ¿å表 |
| | | List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); |
| | | for (String template : templates) { |
| | | // æ¸²ææ¨¡æ¿ |
| | | StringWriter sw = new StringWriter(); |
| | | Template tpl = Velocity.getTemplate(template, Constants.UTF8); |
| | | tpl.merge(context, sw); |
| | | try { |
| | | // æ·»å å°zip |
| | | zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); |
| | | IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString()); |
| | | IoUtil.close(sw); |
| | | zip.flush(); |
| | | zip.closeEntry(); |
| | | } catch (IOException e) { |
| | | log.error("æ¸²ææ¨¡æ¿å¤±è´¥ï¼è¡¨åï¼" + table.getTableName(), e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¿ååæ°æ ¡éª |
| | | * |
| | | * @param genTable ä¸å¡ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public void validateEdit(GenTable genTable) { |
| | | if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) { |
| | | String options = JsonUtils.toJsonString(genTable.getParams()); |
| | | Dict paramsObj = JsonUtils.parseMap(options); |
| | | if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_CODE))) { |
| | | throw new ServiceException("æ ç¼ç åæ®µä¸è½ä¸ºç©º"); |
| | | } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_PARENT_CODE))) { |
| | | throw new ServiceException("æ ç¶ç¼ç åæ®µä¸è½ä¸ºç©º"); |
| | | } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_NAME))) { |
| | | throw new ServiceException("æ åç§°åæ®µä¸è½ä¸ºç©º"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置主é®åä¿¡æ¯ |
| | | * |
| | | * @param table ä¸å¡è¡¨ä¿¡æ¯ |
| | | */ |
| | | public void setPkColumn(GenTable table) { |
| | | for (GenTableColumn column : table.getColumns()) { |
| | | if (column.isPk()) { |
| | | table.setPkColumn(column); |
| | | break; |
| | | } |
| | | } |
| | | if (ObjectUtil.isNull(table.getPkColumn())) { |
| | | table.setPkColumn(table.getColumns().get(0)); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 设置代ç çæå
¶ä»éé¡¹å¼ |
| | | * |
| | | * @param genTable 设置åççæå¯¹è±¡ |
| | | */ |
| | | public void setTableFromOptions(GenTable genTable) { |
| | | Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); |
| | | if (ObjectUtil.isNotNull(paramsObj)) { |
| | | String treeCode = paramsObj.getStr(GenConstants.TREE_CODE); |
| | | String treeParentCode = paramsObj.getStr(GenConstants.TREE_PARENT_CODE); |
| | | String treeName = paramsObj.getStr(GenConstants.TREE_NAME); |
| | | String parentMenuId = paramsObj.getStr(GenConstants.PARENT_MENU_ID); |
| | | String parentMenuName = paramsObj.getStr(GenConstants.PARENT_MENU_NAME); |
| | | |
| | | genTable.setTreeCode(treeCode); |
| | | genTable.setTreeParentCode(treeParentCode); |
| | | genTable.setTreeName(treeName); |
| | | genTable.setParentMenuId(parentMenuId); |
| | | genTable.setParentMenuName(parentMenuName); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å代ç çæå°å |
| | | * |
| | | * @param table ä¸å¡è¡¨ä¿¡æ¯ |
| | | * @param template æ¨¡æ¿æä»¶è·¯å¾ |
| | | * @return çæå°å |
| | | */ |
| | | public static String getGenPath(GenTable table, String template) { |
| | | String genPath = table.getGenPath(); |
| | | if (StringUtils.equals(genPath, "/")) { |
| | | return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); |
| | | } |
| | | return genPath + File.separator + VelocityUtils.getFileName(template, table); |
| | | } |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.service; |
| | | |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.generator.domain.GenTable; |
| | | import com.ruoyi.generator.domain.GenTableColumn; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ä¸å¡ æå¡å± |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public interface IGenTableService { |
| | | |
| | | /** |
| | | * æ¥è¯¢ä¸å¡å段å表 |
| | | * |
| | | * @param tableId ä¸å¡å段ç¼å· |
| | | * @return ä¸å¡å段éå |
| | | */ |
| | | List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId); |
| | | |
| | | /** |
| | | * æ¥è¯¢ä¸å¡å表 |
| | | * |
| | | * @param genTable ä¸å¡ä¿¡æ¯ |
| | | * @return ä¸å¡éå |
| | | */ |
| | | TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æ®åºå表 |
| | | * |
| | | * @param genTable ä¸å¡ä¿¡æ¯ |
| | | * @return æ°æ®åºè¡¨éå |
| | | */ |
| | | TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æ®åºå表 |
| | | * |
| | | * @param tableNames 表åç§°ç» |
| | | * @return æ°æ®åºè¡¨éå |
| | | */ |
| | | List<GenTable> selectDbTableListByNames(String[] tableNames); |
| | | |
| | | /** |
| | | * æ¥è¯¢ææè¡¨ä¿¡æ¯ |
| | | * |
| | | * @return 表信æ¯éå |
| | | */ |
| | | List<GenTable> selectGenTableAll(); |
| | | |
| | | /** |
| | | * æ¥è¯¢ä¸å¡ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸å¡ID |
| | | * @return ä¸å¡ä¿¡æ¯ |
| | | */ |
| | | GenTable selectGenTableById(Long id); |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¸å¡ |
| | | * |
| | | * @param genTable ä¸å¡ä¿¡æ¯ |
| | | * @return ç»æ |
| | | */ |
| | | void updateGenTable(GenTable genTable); |
| | | |
| | | /** |
| | | * å é¤ä¸å¡ä¿¡æ¯ |
| | | * |
| | | * @param tableIds éè¦å é¤çè¡¨æ°æ®ID |
| | | * @return ç»æ |
| | | */ |
| | | void deleteGenTableByIds(Long[] tableIds); |
| | | |
| | | /** |
| | | * 导å
¥è¡¨ç»æ |
| | | * |
| | | * @param tableList 导å
¥è¡¨å表 |
| | | */ |
| | | void importGenTable(List<GenTable> tableList); |
| | | |
| | | /** |
| | | * é¢è§ä»£ç |
| | | * |
| | | * @param tableId 表ç¼å· |
| | | * @return é¢è§æ°æ®å表 |
| | | */ |
| | | Map<String, String> previewCode(Long tableId); |
| | | |
| | | /** |
| | | * çæä»£ç ï¼ä¸è½½æ¹å¼ï¼ |
| | | * |
| | | * @param tableName 表åç§° |
| | | * @return æ°æ® |
| | | */ |
| | | byte[] downloadCode(String tableName); |
| | | |
| | | /** |
| | | * çæä»£ç ï¼èªå®ä¹è·¯å¾ï¼ |
| | | * |
| | | * @param tableName 表åç§° |
| | | * @return æ°æ® |
| | | */ |
| | | void generatorCode(String tableName); |
| | | |
| | | /** |
| | | * åæ¥æ°æ®åº |
| | | * |
| | | * @param tableName 表åç§° |
| | | */ |
| | | void synchDb(String tableName); |
| | | |
| | | /** |
| | | * æ¹éçæä»£ç ï¼ä¸è½½æ¹å¼ï¼ |
| | | * |
| | | * @param tableNames 表æ°ç» |
| | | * @return æ°æ® |
| | | */ |
| | | byte[] downloadCode(String[] tableNames); |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¿ååæ°æ ¡éª |
| | | * |
| | | * @param genTable ä¸å¡ä¿¡æ¯ |
| | | */ |
| | | void validateEdit(GenTable genTable); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.util; |
| | | |
| | | import com.ruoyi.common.core.constant.GenConstants; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.generator.config.GenConfig; |
| | | import com.ruoyi.generator.domain.GenTable; |
| | | import com.ruoyi.generator.domain.GenTableColumn; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.apache.commons.lang3.RegExUtils; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * 代ç çæå¨ å·¥å
·ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class GenUtils { |
| | | |
| | | /** |
| | | * åå§åè¡¨ä¿¡æ¯ |
| | | */ |
| | | public static void initTable(GenTable genTable, String operName) { |
| | | genTable.setClassName(convertClassName(genTable.getTableName())); |
| | | genTable.setPackageName(GenConfig.getPackageName()); |
| | | genTable.setModuleName(getModuleName(GenConfig.getPackageName())); |
| | | genTable.setBusinessName(getBusinessName(genTable.getTableName())); |
| | | genTable.setFunctionName(replaceText(genTable.getTableComment())); |
| | | genTable.setFunctionAuthor(GenConfig.getAuthor()); |
| | | genTable.setCreateBy(operName); |
| | | } |
| | | |
| | | /** |
| | | * åå§åå屿§å段 |
| | | */ |
| | | public static void initColumnField(GenTableColumn column, GenTable table) { |
| | | String dataType = getDbType(column.getColumnType()); |
| | | String columnName = column.getColumnName(); |
| | | column.setTableId(table.getTableId()); |
| | | column.setCreateBy(table.getCreateBy()); |
| | | // 设置javaåæ®µå |
| | | column.setJavaField(StringUtils.toCamelCase(columnName)); |
| | | // 设置é»è®¤ç±»å |
| | | column.setJavaType(GenConstants.TYPE_STRING); |
| | | column.setQueryType(GenConstants.QUERY_EQ); |
| | | |
| | | if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) { |
| | | // å符串é¿åº¦è¶
è¿500è®¾ç½®ä¸ºææ¬å |
| | | Integer columnLength = getColumnLength(column.getColumnType()); |
| | | String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; |
| | | column.setHtmlType(htmlType); |
| | | } else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) { |
| | | column.setJavaType(GenConstants.TYPE_DATE); |
| | | column.setHtmlType(GenConstants.HTML_DATETIME); |
| | | } else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) { |
| | | column.setHtmlType(GenConstants.HTML_INPUT); |
| | | |
| | | // å¦ææ¯æµ®ç¹å ç»ä¸ç¨BigDecimal |
| | | String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); |
| | | if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) { |
| | | column.setJavaType(GenConstants.TYPE_BIGDECIMAL); |
| | | } |
| | | // å¦ææ¯æ´å½¢ |
| | | else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) { |
| | | column.setJavaType(GenConstants.TYPE_INTEGER); |
| | | } |
| | | // é¿æ´å½¢ |
| | | else { |
| | | column.setJavaType(GenConstants.TYPE_LONG); |
| | | } |
| | | } |
| | | |
| | | // BO对象 é»è®¤æå
¥å¾é |
| | | if (!arraysContains(GenConstants.COLUMNNAME_NOT_ADD, columnName) && !column.isPk()) { |
| | | column.setIsInsert(GenConstants.REQUIRE); |
| | | } |
| | | // BO对象 é»è®¤ç¼è¾å¾é |
| | | if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) { |
| | | column.setIsEdit(GenConstants.REQUIRE); |
| | | } |
| | | // BO对象 é»è®¤æ¯å¦å¿
å¡«å¾é |
| | | if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) { |
| | | column.setIsRequired(GenConstants.REQUIRE); |
| | | } |
| | | // VO对象 é»è®¤è¿åå¾é |
| | | if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName)) { |
| | | column.setIsList(GenConstants.REQUIRE); |
| | | } |
| | | // BO对象 é»è®¤æ¥è¯¢å¾é |
| | | if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) { |
| | | column.setIsQuery(GenConstants.REQUIRE); |
| | | } |
| | | |
| | | // æ¥è¯¢å段类å |
| | | if (StringUtils.endsWithIgnoreCase(columnName, "name")) { |
| | | column.setQueryType(GenConstants.QUERY_LIKE); |
| | | } |
| | | // ç¶æåæ®µè®¾ç½®åéæ¡ |
| | | if (StringUtils.endsWithIgnoreCase(columnName, "status")) { |
| | | column.setHtmlType(GenConstants.HTML_RADIO); |
| | | } |
| | | // ç±»å&æ§å«åæ®µè®¾ç½®ä¸ææ¡ |
| | | else if (StringUtils.endsWithIgnoreCase(columnName, "type") |
| | | || StringUtils.endsWithIgnoreCase(columnName, "sex")) { |
| | | column.setHtmlType(GenConstants.HTML_SELECT); |
| | | } |
| | | // å¾çåæ®µè®¾ç½®å¾çä¸ä¼ æ§ä»¶ |
| | | else if (StringUtils.endsWithIgnoreCase(columnName, "image")) { |
| | | column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); |
| | | } |
| | | // æä»¶å段设置æä»¶ä¸ä¼ æ§ä»¶ |
| | | else if (StringUtils.endsWithIgnoreCase(columnName, "file")) { |
| | | column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); |
| | | } |
| | | // å
容忮µè®¾ç½®å¯ææ¬æ§ä»¶ |
| | | else if (StringUtils.endsWithIgnoreCase(columnName, "content")) { |
| | | column.setHtmlType(GenConstants.HTML_EDITOR); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªæ°ç»æ¯å¦å
嫿å®å¼ |
| | | * |
| | | * @param arr æ°ç» |
| | | * @param targetValue å¼ |
| | | * @return æ¯å¦å
å« |
| | | */ |
| | | public static boolean arraysContains(String[] arr, String targetValue) { |
| | | return Arrays.asList(arr).contains(targetValue); |
| | | } |
| | | |
| | | /** |
| | | * è·å模åå |
| | | * |
| | | * @param packageName å
å |
| | | * @return 模åå |
| | | */ |
| | | public static String getModuleName(String packageName) { |
| | | int lastIndex = packageName.lastIndexOf("."); |
| | | int nameLength = packageName.length(); |
| | | return StringUtils.substring(packageName, lastIndex + 1, nameLength); |
| | | } |
| | | |
| | | /** |
| | | * è·åä¸å¡å |
| | | * |
| | | * @param tableName 表å |
| | | * @return ä¸å¡å |
| | | */ |
| | | public static String getBusinessName(String tableName) { |
| | | int firstIndex = tableName.indexOf("_"); |
| | | int nameLength = tableName.length(); |
| | | String businessName = StringUtils.substring(tableName, firstIndex + 1, nameLength); |
| | | businessName = StringUtils.toCamelCase(businessName); |
| | | return businessName; |
| | | } |
| | | |
| | | /** |
| | | * 表åè½¬æ¢æJavaç±»å |
| | | * |
| | | * @param tableName 表åç§° |
| | | * @return ç±»å |
| | | */ |
| | | public static String convertClassName(String tableName) { |
| | | boolean autoRemovePre = GenConfig.getAutoRemovePre(); |
| | | String tablePrefix = GenConfig.getTablePrefix(); |
| | | if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) { |
| | | String[] searchList = StringUtils.split(tablePrefix, ","); |
| | | tableName = replaceFirst(tableName, searchList); |
| | | } |
| | | return StringUtils.convertToCamelCase(tableName); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæ¿æ¢åç¼ |
| | | * |
| | | * @param replacementm æ¿æ¢å¼ |
| | | * @param searchList æ¿æ¢å表 |
| | | * @return |
| | | */ |
| | | public static String replaceFirst(String replacementm, String[] searchList) { |
| | | String text = replacementm; |
| | | for (String searchString : searchList) { |
| | | if (replacementm.startsWith(searchString)) { |
| | | text = replacementm.replaceFirst(searchString, ""); |
| | | break; |
| | | } |
| | | } |
| | | return text; |
| | | } |
| | | |
| | | /** |
| | | * å
³é®åæ¿æ¢ |
| | | * |
| | | * @param text éè¦è¢«æ¿æ¢çåå |
| | | * @return æ¿æ¢åçåå |
| | | */ |
| | | public static String replaceText(String text) { |
| | | return RegExUtils.replaceAll(text, "(?:表|è¥ä¾)", ""); |
| | | } |
| | | |
| | | /** |
| | | * è·åæ°æ®åºç±»ååæ®µ |
| | | * |
| | | * @param columnType åç±»å |
| | | * @return æªååçåç±»å |
| | | */ |
| | | public static String getDbType(String columnType) { |
| | | if (StringUtils.indexOf(columnType, '(') > 0) { |
| | | return StringUtils.substringBefore(columnType, "("); |
| | | } else { |
| | | return columnType; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·ååæ®µé¿åº¦ |
| | | * |
| | | * @param columnType åç±»å |
| | | * @return æªååçåç±»å |
| | | */ |
| | | public static Integer getColumnLength(String columnType) { |
| | | if (StringUtils.indexOf(columnType, '(') > 0) { |
| | | String length = StringUtils.substringBetween(columnType, "(", ")"); |
| | | return Integer.valueOf(length); |
| | | } else { |
| | | return 0; |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.util; |
| | | |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.apache.velocity.app.Velocity; |
| | | |
| | | import java.util.Properties; |
| | | |
| | | /** |
| | | * VelocityEngineå·¥å |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class VelocityInitializer { |
| | | |
| | | /** |
| | | * åå§åvmæ¹æ³ |
| | | */ |
| | | public static void initVelocity() { |
| | | Properties p = new Properties(); |
| | | try { |
| | | // å è½½classpathç®å½ä¸çvmæä»¶ |
| | | p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); |
| | | // å®ä¹å符é |
| | | p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); |
| | | // åå§åVelocityå¼æï¼æå®é
ç½®Properties |
| | | Velocity.init(p); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.generator.util; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.core.constant.GenConstants; |
| | | import com.ruoyi.common.core.utils.DateUtils; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.mybatis.helper.DataBaseHelper; |
| | | import com.ruoyi.generator.domain.GenTable; |
| | | import com.ruoyi.generator.domain.GenTableColumn; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.apache.velocity.VelocityContext; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 模æ¿å¤çå·¥å
·ç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class VelocityUtils { |
| | | |
| | | /** |
| | | * 项ç®ç©ºé´è·¯å¾ |
| | | */ |
| | | private static final String PROJECT_PATH = "main/java"; |
| | | |
| | | /** |
| | | * mybatis空é´è·¯å¾ |
| | | */ |
| | | private static final String MYBATIS_PATH = "main/resources/mapper"; |
| | | |
| | | /** |
| | | * é»è®¤ä¸çº§èåï¼ç³»ç»å·¥å
· |
| | | */ |
| | | private static final String DEFAULT_PARENT_MENU_ID = "3"; |
| | | |
| | | /** |
| | | * 设置模æ¿åéä¿¡æ¯ |
| | | * |
| | | * @return 模æ¿å表 |
| | | */ |
| | | public static VelocityContext prepareContext(GenTable genTable) { |
| | | String moduleName = genTable.getModuleName(); |
| | | String businessName = genTable.getBusinessName(); |
| | | String packageName = genTable.getPackageName(); |
| | | String tplCategory = genTable.getTplCategory(); |
| | | String functionName = genTable.getFunctionName(); |
| | | |
| | | VelocityContext velocityContext = new VelocityContext(); |
| | | velocityContext.put("tplCategory", genTable.getTplCategory()); |
| | | velocityContext.put("tableName", genTable.getTableName()); |
| | | velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "ã请填ååè½åç§°ã"); |
| | | velocityContext.put("ClassName", genTable.getClassName()); |
| | | velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); |
| | | velocityContext.put("moduleName", genTable.getModuleName()); |
| | | velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); |
| | | velocityContext.put("businessName", genTable.getBusinessName()); |
| | | velocityContext.put("basePackage", getPackagePrefix(packageName)); |
| | | velocityContext.put("packageName", packageName); |
| | | velocityContext.put("author", genTable.getFunctionAuthor()); |
| | | velocityContext.put("datetime", DateUtils.getDate()); |
| | | velocityContext.put("pkColumn", genTable.getPkColumn()); |
| | | velocityContext.put("importList", getImportList(genTable)); |
| | | velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); |
| | | velocityContext.put("columns", genTable.getColumns()); |
| | | velocityContext.put("table", genTable); |
| | | velocityContext.put("dicts", getDicts(genTable)); |
| | | setMenuVelocityContext(velocityContext, genTable); |
| | | if (GenConstants.TPL_TREE.equals(tplCategory)) { |
| | | setTreeVelocityContext(velocityContext, genTable); |
| | | } |
| | | return velocityContext; |
| | | } |
| | | |
| | | public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) { |
| | | String options = genTable.getOptions(); |
| | | Dict paramsObj = JsonUtils.parseMap(options); |
| | | String parentMenuId = getParentMenuId(paramsObj); |
| | | context.put("parentMenuId", parentMenuId); |
| | | } |
| | | |
| | | public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) { |
| | | String options = genTable.getOptions(); |
| | | Dict paramsObj = JsonUtils.parseMap(options); |
| | | String treeCode = getTreecode(paramsObj); |
| | | String treeParentCode = getTreeParentCode(paramsObj); |
| | | String treeName = getTreeName(paramsObj); |
| | | |
| | | context.put("treeCode", treeCode); |
| | | context.put("treeParentCode", treeParentCode); |
| | | context.put("treeName", treeName); |
| | | context.put("expandColumn", getExpandColumn(genTable)); |
| | | if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { |
| | | context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE)); |
| | | } |
| | | if (paramsObj.containsKey(GenConstants.TREE_NAME)) { |
| | | context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å模æ¿ä¿¡æ¯ |
| | | * |
| | | * @return 模æ¿å表 |
| | | */ |
| | | public static List<String> getTemplateList(String tplCategory) { |
| | | List<String> templates = new ArrayList<String>(); |
| | | templates.add("vm/java/domain.java.vm"); |
| | | templates.add("vm/java/vo.java.vm"); |
| | | templates.add("vm/java/bo.java.vm"); |
| | | templates.add("vm/java/mapper.java.vm"); |
| | | templates.add("vm/java/service.java.vm"); |
| | | templates.add("vm/java/serviceImpl.java.vm"); |
| | | templates.add("vm/java/controller.java.vm"); |
| | | templates.add("vm/xml/mapper.xml.vm"); |
| | | if (DataBaseHelper.isOracle()) { |
| | | templates.add("vm/sql/oracle/sql.vm"); |
| | | } else if (DataBaseHelper.isPostgerSql()) { |
| | | templates.add("vm/sql/postgres/sql.vm"); |
| | | } else if (DataBaseHelper.isSqlServer()) { |
| | | templates.add("vm/sql/sqlserver/sql.vm"); |
| | | } else { |
| | | templates.add("vm/sql/sql.vm"); |
| | | } |
| | | templates.add("vm/js/api.js.vm"); |
| | | if (GenConstants.TPL_CRUD.equals(tplCategory)) { |
| | | templates.add("vm/vue/index.vue.vm"); |
| | | } else if (GenConstants.TPL_TREE.equals(tplCategory)) { |
| | | templates.add("vm/vue/index-tree.vue.vm"); |
| | | } |
| | | return templates; |
| | | } |
| | | |
| | | /** |
| | | * è·åæä»¶å |
| | | */ |
| | | public static String getFileName(String template, GenTable genTable) { |
| | | // æä»¶åç§° |
| | | String fileName = ""; |
| | | // å
è·¯å¾ |
| | | String packageName = genTable.getPackageName(); |
| | | // 模åå |
| | | String moduleName = genTable.getModuleName(); |
| | | // 大åç±»å |
| | | String className = genTable.getClassName(); |
| | | // ä¸å¡åç§° |
| | | String businessName = genTable.getBusinessName(); |
| | | |
| | | String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); |
| | | String mybatisPath = MYBATIS_PATH + "/" + moduleName; |
| | | String vuePath = "vue"; |
| | | |
| | | if (template.contains("domain.java.vm")) { |
| | | fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); |
| | | } |
| | | if (template.contains("vo.java.vm")) { |
| | | fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className); |
| | | } |
| | | if (template.contains("bo.java.vm")) { |
| | | fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className); |
| | | } |
| | | if (template.contains("mapper.java.vm")) { |
| | | fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); |
| | | } else if (template.contains("service.java.vm")) { |
| | | fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); |
| | | } else if (template.contains("serviceImpl.java.vm")) { |
| | | fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); |
| | | } else if (template.contains("controller.java.vm")) { |
| | | fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); |
| | | } else if (template.contains("mapper.xml.vm")) { |
| | | fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); |
| | | } else if (template.contains("sql.vm")) { |
| | | fileName = businessName + "Menu.sql"; |
| | | } else if (template.contains("api.js.vm")) { |
| | | fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); |
| | | } else if (template.contains("index.vue.vm")) { |
| | | fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); |
| | | } else if (template.contains("index-tree.vue.vm")) { |
| | | fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); |
| | | } |
| | | return fileName; |
| | | } |
| | | |
| | | /** |
| | | * è·åå
åç¼ |
| | | * |
| | | * @param packageName å
åç§° |
| | | * @return å
åç¼åç§° |
| | | */ |
| | | public static String getPackagePrefix(String packageName) { |
| | | int lastIndex = packageName.lastIndexOf("."); |
| | | return StringUtils.substring(packageName, 0, lastIndex); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®åç±»åè·å导å
¥å
|
| | | * |
| | | * @param genTable ä¸å¡è¡¨å¯¹è±¡ |
| | | * @return è¿åéè¦å¯¼å
¥çå
å表 |
| | | */ |
| | | public static HashSet<String> getImportList(GenTable genTable) { |
| | | List<GenTableColumn> columns = genTable.getColumns(); |
| | | HashSet<String> importList = new HashSet<String>(); |
| | | for (GenTableColumn column : columns) { |
| | | if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) { |
| | | importList.add("java.util.Date"); |
| | | importList.add("com.fasterxml.jackson.annotation.JsonFormat"); |
| | | } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) { |
| | | importList.add("java.math.BigDecimal"); |
| | | } |
| | | } |
| | | return importList; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®åç±»åè·ååå
¸ç» |
| | | * |
| | | * @param genTable ä¸å¡è¡¨å¯¹è±¡ |
| | | * @return è¿ååå
¸ç» |
| | | */ |
| | | public static String getDicts(GenTable genTable) { |
| | | List<GenTableColumn> columns = genTable.getColumns(); |
| | | Set<String> dicts = new HashSet<String>(); |
| | | addDicts(dicts, columns); |
| | | return StringUtils.join(dicts, ", "); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å åå
¸å表 |
| | | * |
| | | * @param dicts åå
¸å表 |
| | | * @param columns åéå |
| | | */ |
| | | public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) { |
| | | for (GenTableColumn column : columns) { |
| | | if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( |
| | | column.getHtmlType(), |
| | | new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) { |
| | | dicts.add("'" + column.getDictType() + "'"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åæéåç¼ |
| | | * |
| | | * @param moduleName 模ååç§° |
| | | * @param businessName ä¸å¡åç§° |
| | | * @return è¿åæéåç¼ |
| | | */ |
| | | public static String getPermissionPrefix(String moduleName, String businessName) { |
| | | return StringUtils.format("{}:{}", moduleName, businessName); |
| | | } |
| | | |
| | | /** |
| | | * è·åä¸çº§èåIDåæ®µ |
| | | * |
| | | * @param paramsObj çæå
¶ä»é项 |
| | | * @return ä¸çº§èåIDåæ®µ |
| | | */ |
| | | public static String getParentMenuId(Dict paramsObj) { |
| | | if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) |
| | | && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) { |
| | | return paramsObj.getStr(GenConstants.PARENT_MENU_ID); |
| | | } |
| | | return DEFAULT_PARENT_MENU_ID; |
| | | } |
| | | |
| | | /** |
| | | * è·åæ ç¼ç |
| | | * |
| | | * @param paramsObj çæå
¶ä»é项 |
| | | * @return æ ç¼ç |
| | | */ |
| | | public static String getTreecode(Map<String, Object> paramsObj) { |
| | | if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) { |
| | | return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE))); |
| | | } |
| | | return StringUtils.EMPTY; |
| | | } |
| | | |
| | | /** |
| | | * è·åæ ç¶ç¼ç |
| | | * |
| | | * @param paramsObj çæå
¶ä»é项 |
| | | * @return æ ç¶ç¼ç |
| | | */ |
| | | public static String getTreeParentCode(Dict paramsObj) { |
| | | if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { |
| | | return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE)); |
| | | } |
| | | return StringUtils.EMPTY; |
| | | } |
| | | |
| | | /** |
| | | * è·åæ åç§° |
| | | * |
| | | * @param paramsObj çæå
¶ä»é项 |
| | | * @return æ åç§° |
| | | */ |
| | | public static String getTreeName(Dict paramsObj) { |
| | | if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) { |
| | | return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME)); |
| | | } |
| | | return StringUtils.EMPTY; |
| | | } |
| | | |
| | | /** |
| | | * è·åéè¦å¨åªä¸åä¸é¢æ¾ç¤ºå±å¼æé® |
| | | * |
| | | * @param genTable ä¸å¡è¡¨å¯¹è±¡ |
| | | * @return å±å¼æé®ååºå· |
| | | */ |
| | | public static int getExpandColumn(GenTable genTable) { |
| | | String options = genTable.getOptions(); |
| | | Dict paramsObj = JsonUtils.parseMap(options); |
| | | String treeName = paramsObj.getStr(GenConstants.TREE_NAME); |
| | | int num = 0; |
| | | for (GenTableColumn column : genTable.getColumns()) { |
| | | if (column.isList()) { |
| | | num++; |
| | | String columnName = column.getColumnName(); |
| | | if (columnName.equals(treeName)) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return num; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 代ç çæ |
| | | gen: |
| | | # ä½è
|
| | | author: ruoyi |
| | | # é»è®¤çæå
è·¯å¾ system éæ¹æèªå·±ç模ååç§° å¦ system monitor tool |
| | | packageName: com.ruoyi.system |
| | | # èªå¨å»é¤è¡¨åç¼ï¼é»è®¤æ¯false |
| | | autoRemovePre: false |
| | | # 表åç¼ï¼çæç±»åä¸ä¼å
å«è¡¨åç¼ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | tablePrefix: sys_ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?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.generator.mapper.GenTableColumnMapper"> |
| | | |
| | | <resultMap type="com.ruoyi.generator.domain.GenTableColumn" id="GenTableColumnResult"> |
| | | </resultMap> |
| | | |
| | | <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult"> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()"> |
| | | select column_name, |
| | | (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, |
| | | (case when column_key = 'PRI' then '1' else '0' end) as is_pk, |
| | | ordinal_position as sort, |
| | | column_comment, |
| | | (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, |
| | | column_type |
| | | from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName}) |
| | | order by ordinal_position |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()"> |
| | | select lower(temp.column_name) as column_name, |
| | | (case when (temp.nullable = 'N' and temp.constraint_type != 'P') then '1' else null end) as is_required, |
| | | (case when temp.constraint_type = 'P' then '1' else '0' end) as is_pk, |
| | | temp.column_id as sort, |
| | | temp.comments as column_comment, |
| | | (case when temp.constraint_type = 'P' then '1' else '0' end) as is_increment, |
| | | lower(temp.data_type) as column_type |
| | | from ( |
| | | select col.column_id, col.column_name,col.nullable, col.data_type, colc.comments, uc.constraint_type, row_number() |
| | | over (partition by col.column_name order by uc.constraint_type desc) as row_flg |
| | | from user_tab_columns col |
| | | left join user_col_comments colc on colc.table_name = col.table_name and colc.column_name = col.column_name |
| | | left join user_cons_columns ucc on ucc.table_name = col.table_name and ucc.column_name = col.column_name |
| | | left join user_constraints uc on uc.constraint_name = ucc.constraint_name |
| | | where col.table_name = upper(#{tableName}) |
| | | ) temp |
| | | WHERE temp.row_flg = 1 |
| | | ORDER BY temp.column_id |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> |
| | | SELECT column_name, is_required, is_pk, sort, column_comment, is_increment, column_type |
| | | FROM ( |
| | | SELECT c.relname AS table_name, |
| | | a.attname AS column_name, |
| | | d.description AS column_comment, |
| | | CASE WHEN a.attnotnull AND con.conname IS NULL THEN 1 ELSE 0 |
| | | END AS is_required, |
| | | CASE WHEN con.conname IS NOT NULL THEN 1 ELSE 0 |
| | | END AS is_pk, |
| | | a.attnum AS sort, |
| | | CASE WHEN "position"(pg_get_expr(ad.adbin, ad.adrelid), |
| | | ((c.relname::text || '_'::text) || a.attname::text) || '_seq'::text) > 0 THEN 1 ELSE 0 |
| | | END AS is_increment, |
| | | btrim( |
| | | CASE WHEN t.typelem <![CDATA[ <> ]]> 0::oid AND t.typlen = '-1'::integer THEN 'ARRAY'::text ELSE |
| | | CASE WHEN t.typtype = 'd'::"char" THEN format_type(t.typbasetype, NULL::integer) |
| | | ELSE format_type(a.atttypid, NULL::integer) END |
| | | END, '"'::text |
| | | ) AS column_type |
| | | FROM pg_attribute a |
| | | JOIN (pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid) ON a.attrelid = c.oid |
| | | LEFT JOIN pg_description d ON d.objoid = c.oid AND a.attnum = d.objsubid |
| | | LEFT JOIN pg_constraint con ON con.conrelid = c.oid AND (a.attnum = ANY (con.conkey)) |
| | | LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum |
| | | LEFT JOIN pg_type t ON a.atttypid = t.oid |
| | | WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) |
| | | AND a.attnum > 0 |
| | | AND n.nspname = 'public'::name |
| | | ORDER BY c.relname, a.attnum |
| | | ) temp |
| | | WHERE table_name = (#{tableName}) |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()"> |
| | | SELECT |
| | | cast(A.NAME as nvarchar) as column_name, |
| | | cast(B.NAME as nvarchar) + (case when B.NAME = 'numeric' then '(' + cast(A.prec as nvarchar) + ',' + cast(A.scale as nvarchar) + ')' else '' end) as column_type, |
| | | cast(G.[VALUE] as nvarchar) as column_comment, |
| | | (SELECT 1 FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE Z WHERE TABLE_NAME = D.NAME and A.NAME = Z.column_name ) as is_pk, |
| | | colorder as sort |
| | | FROM SYSCOLUMNS A |
| | | LEFT JOIN SYSTYPES B ON A.XTYPE = B.XUSERTYPE |
| | | INNER JOIN SYSOBJECTS D ON A.ID = D.ID AND D.XTYPE='U' AND D.NAME != 'DTPROPERTIES' |
| | | LEFT JOIN SYS.EXTENDED_PROPERTIES G ON A.ID = G.MAJOR_ID AND A.COLID = G.MINOR_ID |
| | | LEFT JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID AND F.MINOR_ID = 0 |
| | | WHERE D.NAME = #{tableName} |
| | | ORDER BY A.COLORDER |
| | | </if> |
| | | </select> |
| | | |
| | | </mapper> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?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.generator.mapper.GenTableMapper"> |
| | | |
| | | <!-- å¤ç»æåµå¥èªå¨æ å°é另䏿¯ä¸ªå®ä½ç主é®id å¦åæ å°ä¼å¤±è´¥ --> |
| | | <resultMap type="com.ruoyi.generator.domain.GenTable" id="GenTableResult"> |
| | | <id property="tableId" column="table_id" /> |
| | | <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" /> |
| | | </resultMap> |
| | | |
| | | <resultMap type="com.ruoyi.generator.domain.GenTableColumn" id="GenTableColumnResult"> |
| | | <id property="columnId" column="column_id"/> |
| | | </resultMap> |
| | | |
| | | <select id="selectPageDbTableList" resultMap="GenTableResult"> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()"> |
| | | select table_name, table_comment, create_time, update_time |
| | | from information_schema.tables |
| | | where table_schema = (select database()) |
| | | AND table_name NOT LIKE 'xxl_job_%' AND table_name NOT LIKE 'gen_%' |
| | | AND table_name NOT IN (select table_name from gen_table) |
| | | <if test="genTable.tableName != null and genTable.tableName != ''"> |
| | | AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%')) |
| | | </if> |
| | | <if test="genTable.tableComment != null and genTable.tableComment != ''"> |
| | | AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%')) |
| | | </if> |
| | | order by create_time desc |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()"> |
| | | select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time |
| | | from user_tables dt, user_tab_comments dtc, user_objects uo |
| | | where dt.table_name = dtc.table_name |
| | | and dt.table_name = uo.object_name |
| | | and uo.object_type = 'TABLE' |
| | | AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND lower(dt.table_name) NOT IN (select table_name from gen_table) |
| | | <if test="genTable.tableName != null and genTable.tableName != ''"> |
| | | AND lower(dt.table_name) like lower(concat(concat('%', #{genTable.tableName}), '%')) |
| | | </if> |
| | | <if test="genTable.tableComment != null and genTable.tableComment != ''"> |
| | | AND lower(dtc.comments) like lower(concat(concat('%', #{genTable.tableComment}), '%')) |
| | | </if> |
| | | order by create_time desc |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> |
| | | select table_name, table_comment, create_time, update_time |
| | | from ( |
| | | SELECT c.relname AS table_name, |
| | | obj_description(c.oid) AS table_comment, |
| | | CURRENT_TIMESTAMP AS create_time, |
| | | CURRENT_TIMESTAMP AS update_time |
| | | FROM pg_class c |
| | | LEFT JOIN pg_namespace n ON n.oid = c.relnamespace |
| | | WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) |
| | | AND c.relname != 'spatial_%'::text |
| | | AND n.nspname = 'public'::name |
| | | AND n.nspname <![CDATA[ <> ]]> ''::name |
| | | ) list_table |
| | | where table_name NOT LIKE 'xxl_job_%' AND table_name NOT LIKE 'gen_%' |
| | | AND table_name NOT IN (select table_name from gen_table) |
| | | <if test="genTable.tableName != null and genTable.tableName != ''"> |
| | | AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%')) |
| | | </if> |
| | | <if test="genTable.tableComment != null and genTable.tableComment != ''"> |
| | | AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%')) |
| | | </if> |
| | | order by create_time desc |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()"> |
| | | SELECT cast(D.NAME as nvarchar) as table_name, |
| | | cast(F.VALUE as nvarchar) as table_comment, |
| | | crdate as create_time, |
| | | refdate as update_time |
| | | FROM SYSOBJECTS D |
| | | INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID |
| | | AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' |
| | | AND D.NAME NOT LIKE 'xxl_job_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT IN (select table_name from gen_table) |
| | | <if test="genTable.tableName != null and genTable.tableName != ''"> |
| | | AND lower(D.NAME) like lower(concat(N'%', N'${genTable.tableName}', N'%')) |
| | | </if> |
| | | <if test="genTable.tableComment != null and genTable.tableComment != ''"> |
| | | AND lower(CAST(F.VALUE AS nvarchar)) like lower(concat(N'%', N'${genTable.tableComment}', N'%')) |
| | | </if> |
| | | order by crdate desc |
| | | </if> |
| | | </select> |
| | | |
| | | <select id="selectDbTableListByNames" resultMap="GenTableResult"> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()"> |
| | | select table_name, table_comment, create_time, update_time from information_schema.tables |
| | | where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) |
| | | and table_name in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | | </foreach> |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()"> |
| | | select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time |
| | | from user_tables dt, user_tab_comments dtc, user_objects uo |
| | | where dt.table_name = dtc.table_name |
| | | and dt.table_name = uo.object_name |
| | | and uo.object_type = 'TABLE' |
| | | AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND dt.table_name NOT IN (select table_name from gen_table) |
| | | and lower(dt.table_name) in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | | </foreach> |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> |
| | | select table_name, table_comment, create_time, update_time |
| | | from ( |
| | | SELECT c.relname AS table_name, |
| | | obj_description(c.oid) AS table_comment, |
| | | CURRENT_TIMESTAMP AS create_time, |
| | | CURRENT_TIMESTAMP AS update_time |
| | | FROM pg_class c |
| | | LEFT JOIN pg_namespace n ON n.oid = c.relnamespace |
| | | WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) |
| | | AND c.relname != 'spatial_%'::text |
| | | AND n.nspname = 'public'::name |
| | | AND n.nspname <![CDATA[ <> ]]> ''::name |
| | | ) list_table |
| | | where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' |
| | | and table_name in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | | </foreach> |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()"> |
| | | SELECT cast(D.NAME as nvarchar) as table_name, |
| | | cast(F.VALUE as nvarchar) as table_comment, |
| | | crdate as create_time, |
| | | refdate as update_time |
| | | FROM SYSOBJECTS D |
| | | INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID |
| | | AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' |
| | | AND D.NAME NOT LIKE 'xxl_job_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | | </foreach> |
| | | </if> |
| | | </select> |
| | | |
| | | <select id="selectTableByName" parameterType="String" resultMap="GenTableResult"> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()"> |
| | | select table_name, table_comment, create_time, update_time from information_schema.tables |
| | | where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) |
| | | and table_name = #{tableName} |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()"> |
| | | select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time |
| | | from user_tables dt, user_tab_comments dtc, user_objects uo |
| | | where dt.table_name = dtc.table_name |
| | | and dt.table_name = uo.object_name |
| | | and uo.object_type = 'TABLE' |
| | | AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND dt.table_name NOT IN (select table_name from gen_table) |
| | | and lower(dt.table_name) = #{tableName} |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> |
| | | select table_name, table_comment, create_time, update_time |
| | | from ( |
| | | SELECT c.relname AS table_name, |
| | | obj_description(c.oid) AS table_comment, |
| | | CURRENT_TIMESTAMP AS create_time, |
| | | CURRENT_TIMESTAMP AS update_time |
| | | FROM pg_class c |
| | | LEFT JOIN pg_namespace n ON n.oid = c.relnamespace |
| | | WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) |
| | | AND c.relname != 'spatial_%'::text |
| | | AND n.nspname = 'public'::name |
| | | AND n.nspname <![CDATA[ <> ]]> ''::name |
| | | ) list_table |
| | | where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' |
| | | and table_name = #{tableName} |
| | | </if> |
| | | <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()"> |
| | | SELECT cast(D.NAME as nvarchar) as table_name, |
| | | cast(F.VALUE as nvarchar) as table_comment, |
| | | crdate as create_time, |
| | | refdate as update_time |
| | | FROM SYSOBJECTS D |
| | | INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID |
| | | AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' |
| | | AND D.NAME NOT LIKE 'xxl_job_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME = #{tableName} |
| | | </if> |
| | | </select> |
| | | |
| | | <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult"> |
| | | SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark, |
| | | c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort |
| | | FROM gen_table t |
| | | LEFT JOIN gen_table_column c ON t.table_id = c.table_id |
| | | where t.table_id = #{tableId} order by c.sort |
| | | </select> |
| | | |
| | | <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult"> |
| | | SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark, |
| | | c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort |
| | | FROM gen_table t |
| | | LEFT JOIN gen_table_column c ON t.table_id = c.table_id |
| | | where t.table_name = #{tableName} order by c.sort |
| | | </select> |
| | | |
| | | <select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult"> |
| | | SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark, |
| | | c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort |
| | | FROM gen_table t |
| | | LEFT JOIN gen_table_column c ON t.table_id = c.table_id |
| | | order by c.sort |
| | | </select> |
| | | |
| | | </mapper> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.domain.bo; |
| | | |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import jakarta.validation.constraints.*; |
| | | |
| | | import java.util.Date; |
| | | |
| | | #foreach ($import in $importList) |
| | | import ${import}; |
| | | #end |
| | | #if($table.crud || $table.sub) |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | #elseif($table.tree) |
| | | import com.ruoyi.common.core.web.domain.TreeEntity; |
| | | #end |
| | | |
| | | /** |
| | | * ${functionName}ä¸å¡å¯¹è±¡ ${tableName} |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | #if($table.crud || $table.sub) |
| | | #set($Entity="BaseEntity") |
| | | #elseif($table.tree) |
| | | #set($Entity="TreeEntity<${ClassName}Bo>") |
| | | #end |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class ${ClassName}Bo extends ${Entity} { |
| | | |
| | | #foreach ($column in $columns) |
| | | #if(!$table.isSuperColumn($column.javaField) && ($column.query || $column.isInsert || $column.isEdit)) |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | #if($column.isInsert && $column.isEdit) |
| | | #set($Group="AddGroup.class, EditGroup.class") |
| | | #elseif($column.isInsert) |
| | | #set($Group="AddGroup.class") |
| | | #elseif($column.isEdit) |
| | | #set($Group="EditGroup.class") |
| | | #end |
| | | #if($column.isRequired == 1) |
| | | #if($column.javaType == 'String') |
| | | @NotBlank(message = "$column.columnCommentä¸è½ä¸ºç©º", groups = { $Group }) |
| | | #else |
| | | @NotNull(message = "$column.columnCommentä¸è½ä¸ºç©º", groups = { $Group }) |
| | | #end |
| | | #end |
| | | private $column.javaType $column.javaField; |
| | | |
| | | #end |
| | | #end |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.controller; |
| | | |
| | | import java.util.List; |
| | | import java.util.Arrays; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.*; |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import com.ruoyi.common.web.annotation.RepeatSubmit; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import ${packageName}.domain.vo.${ClassName}Vo; |
| | | import ${packageName}.domain.bo.${ClassName}Bo; |
| | | import ${packageName}.service.I${ClassName}Service; |
| | | #if($table.crud || $table.sub) |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | #elseif($table.tree) |
| | | #end |
| | | |
| | | /** |
| | | * ${functionName} |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/${moduleName}/${businessName}") |
| | | public class ${ClassName}Controller extends BaseController { |
| | | |
| | | private final I${ClassName}Service i${ClassName}Service; |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:list") |
| | | @GetMapping("/list") |
| | | #if($table.crud || $table.sub) |
| | | public TableDataInfo<${ClassName}Vo> list(${ClassName}Bo bo, PageQuery pageQuery) { |
| | | return i${ClassName}Service.queryPageList(bo, pageQuery); |
| | | } |
| | | #elseif($table.tree) |
| | | public R<List<${ClassName}Vo>> list(${ClassName}Bo bo) { |
| | | List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); |
| | | return R.ok(list); |
| | | } |
| | | #end |
| | | |
| | | /** |
| | | * 导åº${functionName}å表 |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:export") |
| | | @Log(title = "${functionName}", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(${ClassName}Bo bo, HttpServletResponse response) { |
| | | List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "${functionName}", ${ClassName}Vo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·å${functionName}详ç»ä¿¡æ¯ |
| | | * |
| | | * @param ${pkColumn.javaField} ä¸»é® |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:query") |
| | | @GetMapping("/{${pkColumn.javaField}}") |
| | | public R<${ClassName}Vo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable ${pkColumn.javaType} ${pkColumn.javaField}) { |
| | | return R.ok(i${ClassName}Service.queryById(${pkColumn.javaField})); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢${functionName} |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:add") |
| | | @Log(title = "${functionName}", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping() |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody ${ClassName}Bo bo) { |
| | | return toAjax(i${ClassName}Service.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹${functionName} |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:edit") |
| | | @Log(title = "${functionName}", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody ${ClassName}Bo bo) { |
| | | return toAjax(i${ClassName}Service.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤${functionName} |
| | | * |
| | | * @param ${pkColumn.javaField}s 主é®ä¸² |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:remove") |
| | | @Log(title = "${functionName}", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{${pkColumn.javaField}s}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) { |
| | | return toAjax(i${ClassName}Service.deleteWithValidByIds(Arrays.asList(${pkColumn.javaField}s), true)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.math.BigDecimal; |
| | | |
| | | #foreach ($import in $importList) |
| | | import ${import}; |
| | | #end |
| | | #if($table.crud || $table.sub) |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | #elseif($table.tree) |
| | | import com.ruoyi.common.core.web.domain.TreeEntity; |
| | | #end |
| | | |
| | | /** |
| | | * ${functionName}对象 ${tableName} |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | #if($table.crud || $table.sub) |
| | | #set($Entity="BaseEntity") |
| | | #elseif($table.tree) |
| | | #set($Entity="TreeEntity<${ClassName}>") |
| | | #end |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("${tableName}") |
| | | public class ${ClassName} extends ${Entity} { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | #foreach ($column in $columns) |
| | | #if(!$table.isSuperColumn($column.javaField)) |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | #if($column.javaField=='delFlag') |
| | | @TableLogic |
| | | #end |
| | | #if($column.javaField=='version') |
| | | @Version |
| | | #end |
| | | #if($column.isPk==1) |
| | | @TableId(value = "$column.columnName") |
| | | #end |
| | | private $column.javaType $column.javaField; |
| | | #end |
| | | #end |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.mapper; |
| | | |
| | | import ${packageName}.domain.${ClassName}; |
| | | import ${packageName}.domain.vo.${ClassName}Vo; |
| | | import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | |
| | | /** |
| | | * ${functionName}Mapperæ¥å£ |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | public interface ${ClassName}Mapper extends BaseMapperPlus<${ClassName}Mapper, ${ClassName}, ${ClassName}Vo> { |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.service; |
| | | |
| | | import ${packageName}.domain.${ClassName}; |
| | | import ${packageName}.domain.vo.${ClassName}Vo; |
| | | import ${packageName}.domain.bo.${ClassName}Bo; |
| | | #if($table.crud || $table.sub) |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | #end |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ${functionName}Serviceæ¥å£ |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | public interface I${ClassName}Service { |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName} |
| | | */ |
| | | ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}); |
| | | |
| | | #if($table.crud || $table.sub) |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | */ |
| | | TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery); |
| | | #end |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | */ |
| | | List<${ClassName}Vo> queryList(${ClassName}Bo bo); |
| | | |
| | | /** |
| | | * æ°å¢${functionName} |
| | | */ |
| | | Boolean insertByBo(${ClassName}Bo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹${functionName} |
| | | */ |
| | | Boolean updateByBo(${ClassName}Bo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤${functionName}ä¿¡æ¯ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | #if($table.crud || $table.sub) |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | #end |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import ${packageName}.domain.bo.${ClassName}Bo; |
| | | import ${packageName}.domain.vo.${ClassName}Vo; |
| | | import ${packageName}.domain.${ClassName}; |
| | | import ${packageName}.mapper.${ClassName}Mapper; |
| | | import ${packageName}.service.I${ClassName}Service; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Collection; |
| | | |
| | | /** |
| | | * ${functionName}Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ${ClassName}ServiceImpl implements I${ClassName}Service { |
| | | |
| | | private final ${ClassName}Mapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName} |
| | | */ |
| | | @Override |
| | | public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){ |
| | | return baseMapper.selectVoById(${pkColumn.javaField}); |
| | | } |
| | | |
| | | #if($table.crud || $table.sub) |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<${ClassName}> lqw = buildQueryWrapper(bo); |
| | | Page<${ClassName}Vo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | #end |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | */ |
| | | @Override |
| | | public List<${ClassName}Vo> queryList(${ClassName}Bo bo) { |
| | | LambdaQueryWrapper<${ClassName}> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<${ClassName}> buildQueryWrapper(${ClassName}Bo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery(); |
| | | #foreach($column in $columns) |
| | | #if($column.query) |
| | | #set($queryType=$column.queryType) |
| | | #set($javaField=$column.javaField) |
| | | #set($javaType=$column.javaType) |
| | | #set($columnName=$column.columnName) |
| | | #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) |
| | | #set($mpMethod=$column.queryType.toLowerCase()) |
| | | #if($queryType != 'BETWEEN') |
| | | #if($javaType == 'String') |
| | | #set($condition='StringUtils.isNotBlank(bo.get'+$AttrName+'())') |
| | | #else |
| | | #set($condition='bo.get'+$AttrName+'() != null') |
| | | #end |
| | | lqw.$mpMethod($condition, ${ClassName}::get$AttrName, bo.get$AttrName()); |
| | | #else |
| | | lqw.between(params.get("begin$AttrName") != null && params.get("end$AttrName") != null, |
| | | ${ClassName}::get$AttrName ,params.get("begin$AttrName"), params.get("end$AttrName")); |
| | | #end |
| | | #end |
| | | #end |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢${functionName} |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(${ClassName}Bo bo) { |
| | | ${ClassName} add = BeanUtil.toBean(bo, ${ClassName}.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | #set($pk=$pkColumn.javaField.substring(0,1).toUpperCase() + ${pkColumn.javaField.substring(1)}) |
| | | if (flag) { |
| | | bo.set$pk(add.get$pk()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹${functionName} |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(${ClassName}Bo bo) { |
| | | ${ClassName} update = BeanUtil.toBean(bo, ${ClassName}.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | */ |
| | | private void validEntityBeforeSave(${ClassName} entity){ |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤${functionName} |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) { |
| | | if(isValid){ |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package ${packageName}.domain.vo; |
| | | |
| | | #foreach ($import in $importList) |
| | | import ${import}; |
| | | #end |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.ruoyi.common.excel.annotation.ExcelDictFormat; |
| | | import com.ruoyi.common.excel.convert.ExcelDictConvert; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | |
| | | |
| | | /** |
| | | * ${functionName}è§å¾å¯¹è±¡ ${tableName} |
| | | * |
| | | * @author ${author} |
| | | * @date ${datetime} |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class ${ClassName}Vo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | #foreach ($column in $columns) |
| | | #if($column.isList) |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | #set($parentheseIndex=$column.columnComment.indexOf("ï¼")) |
| | | #if($parentheseIndex != -1) |
| | | #set($comment=$column.columnComment.substring(0, $parentheseIndex)) |
| | | #else |
| | | #set($comment=$column.columnComment) |
| | | #end |
| | | #if(${column.dictType} && ${column.dictType} != '') |
| | | @ExcelProperty(value = "${comment}", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(dictType = "${column.dictType}") |
| | | #elseif($parentheseIndex != -1) |
| | | @ExcelProperty(value = "${comment}", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") |
| | | #else |
| | | @ExcelProperty(value = "${comment}") |
| | | #end |
| | | private $column.javaType $column.javaField; |
| | | |
| | | #end |
| | | #end |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <packaging>jar</packaging> |
| | | <artifactId>ruoyi-job</artifactId> |
| | | |
| | | <description> |
| | | ä»»å¡è°åº¦ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | |
| | | <!-- éç¨å·¥å
·--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- xxl-job-core --> |
| | | <dependency> |
| | | <groupId>com.xuxueli</groupId> |
| | | <artifactId>xxl-job-core</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>ruoyi-system</artifactId> |
| | | |
| | | <description> |
| | | systemç³»ç»æ¨¡å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <!-- éç¨å·¥å
·--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-dict</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- OSSåè½æ¨¡å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-oss</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- excel--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-excel</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- SMSåè½æ¨¡å --> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-sms</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-security</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-idempotent</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.monitor; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.constant.CacheNames; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.utils.JsonUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.redis.utils.CacheUtils; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import com.ruoyi.system.domain.SysCache; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.redisson.spring.data.connection.RedissonConnectionFactory; |
| | | import org.springframework.data.redis.connection.RedisConnection; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * ç¼åçæ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/monitor/cache") |
| | | public class CacheController { |
| | | |
| | | private final RedissonConnectionFactory connectionFactory; |
| | | |
| | | private final static List<SysCache> CACHES = new ArrayList<>(); |
| | | |
| | | static { |
| | | CACHES.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "ç¨æ·ä¿¡æ¯")); |
| | | CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "å¨çº¿ç¨æ·")); |
| | | CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "é
置信æ¯")); |
| | | CACHES.add(new SysCache(CacheNames.SYS_DICT, "æ°æ®åå
¸")); |
| | | CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "éªè¯ç ")); |
| | | CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "é²éæäº¤")); |
| | | CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "éæµå¤ç")); |
| | | CACHES.add(new SysCache(CacheNames.SYS_OSS_CONFIG, "OSSé
ç½®")); |
| | | CACHES.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "å¯ç é误次æ°")); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¼åçæ§å表 |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @GetMapping() |
| | | public R<Map<String, Object>> getInfo() throws Exception { |
| | | RedisConnection connection = connectionFactory.getConnection(); |
| | | Properties info = connection.commands().info(); |
| | | Properties commandStats = connection.commands().info("commandstats"); |
| | | Long dbSize = connection.commands().dbSize(); |
| | | |
| | | Map<String, Object> result = new HashMap<>(3); |
| | | result.put("info", info); |
| | | result.put("dbSize", dbSize); |
| | | |
| | | List<Map<String, String>> pieList = new ArrayList<>(); |
| | | if (commandStats != null) { |
| | | commandStats.stringPropertyNames().forEach(key -> { |
| | | Map<String, String> data = new HashMap<>(2); |
| | | String property = commandStats.getProperty(key); |
| | | data.put("name", StringUtils.removeStart(key, "cmdstat_")); |
| | | data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); |
| | | pieList.add(data); |
| | | }); |
| | | } |
| | | result.put("commandStats", pieList); |
| | | return R.ok(result); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¼åçæ§ç¼ååå表 |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @GetMapping("/getNames") |
| | | public R<List<SysCache>> cache() { |
| | | return R.ok(CACHES); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¼åçæ§Keyå表 |
| | | * |
| | | * @param cacheName ç¼åå |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @GetMapping("/getKeys/{cacheName}") |
| | | public R<Collection<String>> getCacheKeys(@PathVariable String cacheName) { |
| | | Collection<String> cacheKeys = new HashSet<>(0); |
| | | if (isCacheNames(cacheName)) { |
| | | Set<Object> keys = CacheUtils.keys(cacheName); |
| | | if (CollUtil.isNotEmpty(keys)) { |
| | | cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList()); |
| | | } |
| | | } else { |
| | | cacheKeys = RedisUtils.keys(cacheName + "*"); |
| | | } |
| | | return R.ok(cacheKeys); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¼åçæ§ç¼åå¼è¯¦æ
|
| | | * |
| | | * @param cacheName ç¼åå |
| | | * @param cacheKey ç¼åkey |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @GetMapping("/getValue/{cacheName}/{cacheKey}") |
| | | public R<SysCache> getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) { |
| | | Object cacheValue; |
| | | if (isCacheNames(cacheName)) { |
| | | cacheValue = CacheUtils.get(cacheName, cacheKey); |
| | | } else { |
| | | cacheValue = RedisUtils.getCacheObject(cacheKey); |
| | | } |
| | | SysCache sysCache = new SysCache(cacheName, cacheKey, JsonUtils.toJsonString(cacheValue)); |
| | | return R.ok(sysCache); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
çç¼åçæ§ç¼åå |
| | | * |
| | | * @param cacheName ç¼åå |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @DeleteMapping("/clearCacheName/{cacheName}") |
| | | public R<Void> clearCacheName(@PathVariable String cacheName) { |
| | | if (isCacheNames(cacheName)) { |
| | | CacheUtils.clear(cacheName); |
| | | } else { |
| | | RedisUtils.deleteKeys(cacheName + "*"); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
çç¼åçæ§Key |
| | | * |
| | | * @param cacheKey keyå |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @DeleteMapping("/clearCacheKey/{cacheName}/{cacheKey}") |
| | | public R<Void> clearCacheKey(@PathVariable String cacheName, @PathVariable String cacheKey) { |
| | | if (isCacheNames(cacheName)) { |
| | | CacheUtils.evict(cacheName, cacheKey); |
| | | } else { |
| | | RedisUtils.deleteObject(cacheKey); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
çå
¨é¨ç¼åçæ§ |
| | | */ |
| | | @SaCheckPermission("monitor:cache:list") |
| | | @DeleteMapping("/clearCacheAll") |
| | | public R<Void> clearCacheAll() { |
| | | RedisUtils.deleteKeys("*"); |
| | | return R.ok(); |
| | | } |
| | | |
| | | private boolean isCacheNames(String cacheName) { |
| | | return !StringUtils.contains(cacheName, ":"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.monitor; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import com.ruoyi.system.domain.SysLogininfor; |
| | | import com.ruoyi.system.service.ISysLogininforService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç³»ç»è®¿é®è®°å½ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/monitor/logininfor") |
| | | public class SysLogininforController extends BaseController { |
| | | |
| | | private final ISysLogininforService logininforService; |
| | | |
| | | /** |
| | | * è·åç³»ç»è®¿é®è®°å½å表 |
| | | */ |
| | | @SaCheckPermission("monitor:logininfor:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysLogininfor> list(SysLogininfor logininfor, PageQuery pageQuery) { |
| | | return logininforService.selectPageLogininforList(logininfor, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºç³»ç»è®¿é®è®°å½å表 |
| | | */ |
| | | @Log(title = "ç»å½æ¥å¿", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("monitor:logininfor:export") |
| | | @PostMapping("/export") |
| | | public void export(SysLogininfor logininfor, HttpServletResponse response) { |
| | | List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); |
| | | ExcelUtil.exportExcel(list, "ç»å½æ¥å¿", SysLogininfor.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤ç»å½æ¥å¿ |
| | | * @param infoIds æ¥å¿ids |
| | | */ |
| | | @SaCheckPermission("monitor:logininfor:remove") |
| | | @Log(title = "ç»å½æ¥å¿", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{infoIds}") |
| | | public R<Void> remove(@PathVariable Long[] infoIds) { |
| | | return toAjax(logininforService.deleteLogininforByIds(infoIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
çç³»ç»è®¿é®è®°å½ |
| | | */ |
| | | @SaCheckPermission("monitor:logininfor:remove") |
| | | @Log(title = "ç»å½æ¥å¿", businessType = BusinessType.CLEAN) |
| | | @DeleteMapping("/clean") |
| | | public R<Void> clean() { |
| | | logininforService.cleanLogininfor(); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @SaCheckPermission("monitor:logininfor:unlock") |
| | | @Log(title = "è´¦æ·è§£é", businessType = BusinessType.OTHER) |
| | | @GetMapping("/unlock/{userName}") |
| | | public R<Void> unlock(@PathVariable("userName") String userName) { |
| | | String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; |
| | | if (RedisUtils.hasKey(loginName)) { |
| | | RedisUtils.deleteObject(loginName); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.monitor; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.domain.SysOperLog; |
| | | import com.ruoyi.system.service.ISysOperLogService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æä½æ¥å¿è®°å½ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/monitor/operlog") |
| | | public class SysOperlogController extends BaseController { |
| | | |
| | | private final ISysOperLogService operLogService; |
| | | |
| | | /** |
| | | * è·åæä½æ¥å¿è®°å½å表 |
| | | */ |
| | | @SaCheckPermission("monitor:operlog:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysOperLog> list(SysOperLog operLog, PageQuery pageQuery) { |
| | | return operLogService.selectPageOperLogList(operLog, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæä½æ¥å¿è®°å½å表 |
| | | */ |
| | | @Log(title = "æä½æ¥å¿", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("monitor:operlog:export") |
| | | @PostMapping("/export") |
| | | public void export(SysOperLog operLog, HttpServletResponse response) { |
| | | List<SysOperLog> list = operLogService.selectOperLogList(operLog); |
| | | ExcelUtil.exportExcel(list, "æä½æ¥å¿", SysOperLog.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå 餿使¥å¿è®°å½ |
| | | * @param operIds æ¥å¿ids |
| | | */ |
| | | @Log(title = "æä½æ¥å¿", businessType = BusinessType.DELETE) |
| | | @SaCheckPermission("monitor:operlog:remove") |
| | | @DeleteMapping("/{operIds}") |
| | | public R<Void> remove(@PathVariable Long[] operIds) { |
| | | return toAjax(operLogService.deleteOperLogByIds(operIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
çæä½æ¥å¿è®°å½ |
| | | */ |
| | | @Log(title = "æä½æ¥å¿", businessType = BusinessType.CLEAN) |
| | | @SaCheckPermission("monitor:operlog:remove") |
| | | @DeleteMapping("/clean") |
| | | public R<Void> clean() { |
| | | operLogService.cleanOperLog(); |
| | | return R.ok(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.monitor; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.dev33.satoken.exception.NotLoginException; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.domain.dto.UserOnlineDTO; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.core.utils.StreamUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.redis.utils.RedisUtils; |
| | | import com.ruoyi.system.domain.SysUserOnline; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å¨çº¿ç¨æ·çæ§ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/monitor/online") |
| | | public class SysUserOnlineController extends BaseController { |
| | | |
| | | /** |
| | | * è·åå¨çº¿ç¨æ·çæ§å表 |
| | | * |
| | | * @param ipaddr IPå°å |
| | | * @param userName ç¨æ·å |
| | | */ |
| | | @SaCheckPermission("monitor:online:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) { |
| | | // è·åæææªè¿æç token |
| | | List<String> keys = StpUtil.searchTokenValue("", 0, -1, false); |
| | | List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>(); |
| | | for (String key : keys) { |
| | | String token = key.replace(CacheConstants.LOGIN_TOKEN_KEY, ""); |
| | | // 妿已ç»è¿æåè·³è¿ |
| | | if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) { |
| | | continue; |
| | | } |
| | | userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token)); |
| | | } |
| | | if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { |
| | | userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
| | | StringUtils.equals(ipaddr, userOnline.getIpaddr()) && |
| | | StringUtils.equals(userName, userOnline.getUserName()) |
| | | ); |
| | | } else if (StringUtils.isNotEmpty(ipaddr)) { |
| | | userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
| | | StringUtils.equals(ipaddr, userOnline.getIpaddr()) |
| | | ); |
| | | } else if (StringUtils.isNotEmpty(userName)) { |
| | | userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
| | | StringUtils.equals(userName, userOnline.getUserName()) |
| | | ); |
| | | } |
| | | Collections.reverse(userOnlineDTOList); |
| | | userOnlineDTOList.removeAll(Collections.singleton(null)); |
| | | List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class); |
| | | return TableDataInfo.build(userOnlineList); |
| | | } |
| | | |
| | | /** |
| | | * 强éç¨æ· |
| | | * |
| | | * @param tokenId tokenå¼ |
| | | */ |
| | | @SaCheckPermission("monitor:online:forceLogout") |
| | | @Log(title = "å¨çº¿ç¨æ·", businessType = BusinessType.FORCE) |
| | | @DeleteMapping("/{tokenId}") |
| | | public R<Void> forceLogout(@PathVariable String tokenId) { |
| | | try { |
| | | StpUtil.kickoutByTokenValue(tokenId); |
| | | } catch (NotLoginException ignored) { |
| | | } |
| | | return R.ok(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.domain.SysConfig; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åæ°é
ç½® ä¿¡æ¯æä½å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/config") |
| | | public class SysConfigController extends BaseController { |
| | | |
| | | private final ISysConfigService configService; |
| | | |
| | | /** |
| | | * è·ååæ°é
ç½®å表 |
| | | */ |
| | | @SaCheckPermission("system:config:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysConfig> list(SysConfig config, PageQuery pageQuery) { |
| | | return configService.selectPageConfigList(config, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºåæ°é
ç½®å表 |
| | | */ |
| | | @Log(title = "åæ°ç®¡ç", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("system:config:export") |
| | | @PostMapping("/export") |
| | | public void export(SysConfig config, HttpServletResponse response) { |
| | | List<SysConfig> list = configService.selectConfigList(config); |
| | | ExcelUtil.exportExcel(list, "åæ°æ°æ®", SysConfig.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®åæ°ç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param configId åæ°ID |
| | | */ |
| | | @SaCheckPermission("system:config:query") |
| | | @GetMapping(value = "/{configId}") |
| | | public R<SysConfig> getInfo(@PathVariable Long configId) { |
| | | return R.ok(configService.selectConfigById(configId)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®åæ°é®åæ¥è¯¢åæ°å¼ |
| | | * |
| | | * @param configKey åæ°Key |
| | | */ |
| | | @GetMapping(value = "/configKey/{configKey}") |
| | | public R<Void> getConfigKey(@PathVariable String configKey) { |
| | | return R.ok(configService.selectConfigByKey(configKey)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢åæ°é
ç½® |
| | | */ |
| | | @SaCheckPermission("system:config:add") |
| | | @Log(title = "åæ°ç®¡ç", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysConfig config) { |
| | | if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) { |
| | | return R.fail("æ°å¢åæ°'" + config.getConfigName() + "'失败ï¼åæ°é®åå·²åå¨"); |
| | | } |
| | | configService.insertConfig(config); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹åæ°é
ç½® |
| | | */ |
| | | @SaCheckPermission("system:config:edit") |
| | | @Log(title = "åæ°ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysConfig config) { |
| | | if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) { |
| | | return R.fail("ä¿®æ¹åæ°'" + config.getConfigName() + "'失败ï¼åæ°é®åå·²åå¨"); |
| | | } |
| | | configService.updateConfig(config); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®åæ°é®åä¿®æ¹åæ°é
ç½® |
| | | */ |
| | | @SaCheckPermission("system:config:edit") |
| | | @Log(title = "åæ°ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/updateByKey") |
| | | public R<Void> updateByKey(@RequestBody SysConfig config) { |
| | | configService.updateConfig(config); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤åæ°é
ç½® |
| | | * |
| | | * @param configIds 忰ID䏲 |
| | | */ |
| | | @SaCheckPermission("system:config:remove") |
| | | @Log(title = "åæ°ç®¡ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{configIds}") |
| | | public R<Void> remove(@PathVariable Long[] configIds) { |
| | | configService.deleteConfigByIds(configIds); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å·æ°åæ°ç¼å |
| | | */ |
| | | @SaCheckPermission("system:config:remove") |
| | | @Log(title = "åæ°ç®¡ç", businessType = BusinessType.CLEAN) |
| | | @DeleteMapping("/refreshCache") |
| | | public R<Void> refreshCache() { |
| | | configService.resetConfigCache(); |
| | | return R.ok(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.system.domain.SysDept; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.system.service.ISysDeptService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * é¨é¨ä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/dept") |
| | | public class SysDeptController extends BaseController { |
| | | |
| | | private final ISysDeptService deptService; |
| | | |
| | | /** |
| | | * è·åé¨é¨å表 |
| | | */ |
| | | @SaCheckPermission("system:dept:list") |
| | | @GetMapping("/list") |
| | | public R<List<SysDept>> list(SysDept dept) { |
| | | List<SysDept> depts = deptService.selectDeptList(dept); |
| | | return R.ok(depts); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ |
| | | * |
| | | * @param deptId é¨é¨ID |
| | | */ |
| | | @SaCheckPermission("system:dept:list") |
| | | @GetMapping("/list/exclude/{deptId}") |
| | | public R<List<SysDept>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { |
| | | List<SysDept> depts = deptService.selectDeptList(new SysDept()); |
| | | depts.removeIf(d -> d.getDeptId().equals(deptId) |
| | | || ArrayUtil.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); |
| | | return R.ok(depts); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®é¨é¨ç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param deptId é¨é¨ID |
| | | */ |
| | | @SaCheckPermission("system:dept:query") |
| | | @GetMapping(value = "/{deptId}") |
| | | public R<SysDept> getInfo(@PathVariable Long deptId) { |
| | | deptService.checkDeptDataScope(deptId); |
| | | return R.ok(deptService.selectDeptById(deptId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢é¨é¨ |
| | | */ |
| | | @SaCheckPermission("system:dept:add") |
| | | @Log(title = "é¨é¨ç®¡ç", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysDept dept) { |
| | | if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) { |
| | | return R.fail("æ°å¢é¨é¨'" + dept.getDeptName() + "'失败ï¼é¨é¨åç§°å·²åå¨"); |
| | | } |
| | | return toAjax(deptService.insertDept(dept)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹é¨é¨ |
| | | */ |
| | | @SaCheckPermission("system:dept:edit") |
| | | @Log(title = "é¨é¨ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysDept dept) { |
| | | Long deptId = dept.getDeptId(); |
| | | deptService.checkDeptDataScope(deptId); |
| | | if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) { |
| | | return R.fail("ä¿®æ¹é¨é¨'" + dept.getDeptName() + "'失败ï¼é¨é¨åç§°å·²åå¨"); |
| | | } else if (dept.getParentId().equals(deptId)) { |
| | | return R.fail("ä¿®æ¹é¨é¨'" + dept.getDeptName() + "'失败ï¼ä¸çº§é¨é¨ä¸è½æ¯èªå·±"); |
| | | } else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) |
| | | && deptService.selectNormalChildrenDeptById(deptId) > 0) { |
| | | return R.fail("该é¨é¨å
嫿ªåç¨çåé¨é¨ï¼"); |
| | | } |
| | | return toAjax(deptService.updateDept(dept)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤é¨é¨ |
| | | * |
| | | * @param deptId é¨é¨ID |
| | | */ |
| | | @SaCheckPermission("system:dept:remove") |
| | | @Log(title = "é¨é¨ç®¡ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{deptId}") |
| | | public R<Void> remove(@PathVariable Long deptId) { |
| | | if (deptService.hasChildByDeptId(deptId)) { |
| | | return R.warn("åå¨ä¸çº§é¨é¨,ä¸å
许å é¤"); |
| | | } |
| | | if (deptService.checkDeptExistUser(deptId)) { |
| | | return R.warn("é¨é¨åå¨ç¨æ·,ä¸å
许å é¤"); |
| | | } |
| | | deptService.checkDeptDataScope(deptId); |
| | | return toAjax(deptService.deleteDeptById(deptId)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.system.domain.SysDictData; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.service.ISysDictDataService; |
| | | import com.ruoyi.system.service.ISysDictTypeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ°æ®åå
¸ä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/dict/data") |
| | | public class SysDictDataController extends BaseController { |
| | | |
| | | private final ISysDictDataService dictDataService; |
| | | private final ISysDictTypeService dictTypeService; |
| | | |
| | | /** |
| | | * æ¥è¯¢åå
¸æ°æ®å表 |
| | | */ |
| | | @SaCheckPermission("system:dict:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysDictData> list(SysDictData dictData, PageQuery pageQuery) { |
| | | return dictDataService.selectPageDictDataList(dictData, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºåå
¸æ°æ®å表 |
| | | */ |
| | | @Log(title = "åå
¸æ°æ®", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("system:dict:export") |
| | | @PostMapping("/export") |
| | | public void export(SysDictData dictData, HttpServletResponse response) { |
| | | List<SysDictData> list = dictDataService.selectDictDataList(dictData); |
| | | ExcelUtil.exportExcel(list, "åå
¸æ°æ®", SysDictData.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢åå
¸æ°æ®è¯¦ç» |
| | | * |
| | | * @param dictCode åå
¸code |
| | | */ |
| | | @SaCheckPermission("system:dict:query") |
| | | @GetMapping(value = "/{dictCode}") |
| | | public R<SysDictData> getInfo(@PathVariable Long dictCode) { |
| | | return R.ok(dictDataService.selectDictDataById(dictCode)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®åå
¸ç±»åæ¥è¯¢åå
¸æ°æ®ä¿¡æ¯ |
| | | * |
| | | * @param dictType åå
¸ç±»å |
| | | */ |
| | | @GetMapping(value = "/type/{dictType}") |
| | | public R<List<SysDictData>> dictType(@PathVariable String dictType) { |
| | | List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); |
| | | if (ObjectUtil.isNull(data)) { |
| | | data = new ArrayList<>(); |
| | | } |
| | | return R.ok(data); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢åå
¸ç±»å |
| | | */ |
| | | @SaCheckPermission("system:dict:add") |
| | | @Log(title = "åå
¸æ°æ®", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysDictData dict) { |
| | | dictDataService.insertDictData(dict); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¿ååå
¸ç±»å |
| | | */ |
| | | @SaCheckPermission("system:dict:edit") |
| | | @Log(title = "åå
¸æ°æ®", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysDictData dict) { |
| | | dictDataService.updateDictData(dict); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤åå
¸ç±»å |
| | | * |
| | | * @param dictCodes åå
¸code串 |
| | | */ |
| | | @SaCheckPermission("system:dict:remove") |
| | | @Log(title = "åå
¸ç±»å", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{dictCodes}") |
| | | public R<Void> remove(@PathVariable Long[] dictCodes) { |
| | | dictDataService.deleteDictDataByIds(dictCodes); |
| | | return R.ok(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.system.domain.SysDictType; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.service.ISysDictTypeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ°æ®åå
¸ä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/dict/type") |
| | | public class SysDictTypeController extends BaseController { |
| | | |
| | | private final ISysDictTypeService dictTypeService; |
| | | |
| | | /** |
| | | * æ¥è¯¢åå
¸ç±»åå表 |
| | | */ |
| | | @SaCheckPermission("system:dict:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysDictType> list(SysDictType dictType, PageQuery pageQuery) { |
| | | return dictTypeService.selectPageDictTypeList(dictType, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºåå
¸ç±»åå表 |
| | | */ |
| | | @Log(title = "åå
¸ç±»å", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("system:dict:export") |
| | | @PostMapping("/export") |
| | | public void export(SysDictType dictType, HttpServletResponse response) { |
| | | List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); |
| | | ExcelUtil.exportExcel(list, "åå
¸ç±»å", SysDictType.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢åå
¸ç±»åè¯¦ç» |
| | | * |
| | | * @param dictId åå
¸ID |
| | | */ |
| | | @SaCheckPermission("system:dict:query") |
| | | @GetMapping(value = "/{dictId}") |
| | | public R<SysDictType> getInfo(@PathVariable Long dictId) { |
| | | return R.ok(dictTypeService.selectDictTypeById(dictId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢åå
¸ç±»å |
| | | */ |
| | | @SaCheckPermission("system:dict:add") |
| | | @Log(title = "åå
¸ç±»å", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysDictType dict) { |
| | | if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) { |
| | | return R.fail("æ°å¢åå
¸'" + dict.getDictName() + "'失败ï¼åå
¸ç±»åå·²åå¨"); |
| | | } |
| | | dictTypeService.insertDictType(dict); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹åå
¸ç±»å |
| | | */ |
| | | @SaCheckPermission("system:dict:edit") |
| | | @Log(title = "åå
¸ç±»å", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysDictType dict) { |
| | | if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) { |
| | | return R.fail("ä¿®æ¹åå
¸'" + dict.getDictName() + "'失败ï¼åå
¸ç±»åå·²åå¨"); |
| | | } |
| | | dictTypeService.updateDictType(dict); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤åå
¸ç±»å |
| | | * |
| | | * @param dictIds åå
¸ID串 |
| | | */ |
| | | @SaCheckPermission("system:dict:remove") |
| | | @Log(title = "åå
¸ç±»å", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{dictIds}") |
| | | public R<Void> remove(@PathVariable Long[] dictIds) { |
| | | dictTypeService.deleteDictTypeByIds(dictIds); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å·æ°åå
¸ç¼å |
| | | */ |
| | | @SaCheckPermission("system:dict:remove") |
| | | @Log(title = "åå
¸ç±»å", businessType = BusinessType.CLEAN) |
| | | @DeleteMapping("/refreshCache") |
| | | public R<Void> refreshCache() { |
| | | dictTypeService.resetDictCache(); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * è·ååå
¸éæ©æ¡å表 |
| | | */ |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysDictType>> optionselect() { |
| | | List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); |
| | | return R.ok(dictTypes); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.lang.tree.Tree; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import com.ruoyi.system.domain.SysMenu; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.system.service.ISysMenuService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * èåä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/menu") |
| | | public class SysMenuController extends BaseController { |
| | | |
| | | private final ISysMenuService menuService; |
| | | |
| | | /** |
| | | * è·åèåå表 |
| | | */ |
| | | @SaCheckPermission("system:menu:list") |
| | | @GetMapping("/list") |
| | | public R<List<SysMenu>> list(SysMenu menu) { |
| | | List<SysMenu> menus = menuService.selectMenuList(menu, LoginHelper.getUserId()); |
| | | return R.ok(menus); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®èåç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param menuId èåID |
| | | */ |
| | | @SaCheckPermission("system:menu:query") |
| | | @GetMapping(value = "/{menuId}") |
| | | public R<SysMenu> getInfo(@PathVariable Long menuId) { |
| | | return R.ok(menuService.selectMenuById(menuId)); |
| | | } |
| | | |
| | | /** |
| | | * è·åèå䏿æ å表 |
| | | */ |
| | | @GetMapping("/treeselect") |
| | | public R<List<Tree<Long>>> treeselect(SysMenu menu) { |
| | | List<SysMenu> menus = menuService.selectMenuList(menu, LoginHelper.getUserId()); |
| | | return R.ok(menuService.buildMenuTreeSelect(menus)); |
| | | } |
| | | |
| | | /** |
| | | * å 载对åºè§è²èåå表æ |
| | | * |
| | | * @param roleId è§è²ID |
| | | */ |
| | | @GetMapping(value = "/roleMenuTreeselect/{roleId}") |
| | | public R<Map<String, Object>> roleMenuTreeselect(@PathVariable("roleId") Long roleId) { |
| | | List<SysMenu> menus = menuService.selectMenuList(LoginHelper.getUserId()); |
| | | Map<String, Object> ajax = new HashMap<>(); |
| | | ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); |
| | | ajax.put("menus", menuService.buildMenuTreeSelect(menus)); |
| | | return R.ok(ajax); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢èå |
| | | */ |
| | | @SaCheckPermission("system:menu:add") |
| | | @Log(title = "èå管ç", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysMenu menu) { |
| | | if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) { |
| | | return R.fail("æ°å¢èå'" + menu.getMenuName() + "'失败ï¼èååç§°å·²åå¨"); |
| | | } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { |
| | | return R.fail("æ°å¢èå'" + menu.getMenuName() + "'失败ï¼å°åå¿
须以http(s)://å¼å¤´"); |
| | | } |
| | | return toAjax(menuService.insertMenu(menu)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹èå |
| | | */ |
| | | @SaCheckPermission("system:menu:edit") |
| | | @Log(title = "èå管ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysMenu menu) { |
| | | if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) { |
| | | return R.fail("ä¿®æ¹èå'" + menu.getMenuName() + "'失败ï¼èååç§°å·²åå¨"); |
| | | } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { |
| | | return R.fail("ä¿®æ¹èå'" + menu.getMenuName() + "'失败ï¼å°åå¿
须以http(s)://å¼å¤´"); |
| | | } else if (menu.getMenuId().equals(menu.getParentId())) { |
| | | return R.fail("ä¿®æ¹èå'" + menu.getMenuName() + "'失败ï¼ä¸çº§èåä¸è½éæ©èªå·±"); |
| | | } |
| | | return toAjax(menuService.updateMenu(menu)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤èå |
| | | * |
| | | * @param menuId èåID |
| | | */ |
| | | @SaCheckPermission("system:menu:remove") |
| | | @Log(title = "èå管ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{menuId}") |
| | | public R<Void> remove(@PathVariable("menuId") Long menuId) { |
| | | if (menuService.hasChildByMenuId(menuId)) { |
| | | return R.warn("åå¨åèå,ä¸å
许å é¤"); |
| | | } |
| | | if (menuService.checkMenuExistRole(menuId)) { |
| | | return R.warn("èåå·²åé
,ä¸å
许å é¤"); |
| | | } |
| | | return toAjax(menuService.deleteMenuById(menuId)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.system.domain.SysNotice; |
| | | import com.ruoyi.system.service.ISysNoticeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | /** |
| | | * å
¬å ä¿¡æ¯æä½å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/notice") |
| | | public class SysNoticeController extends BaseController { |
| | | |
| | | private final ISysNoticeService noticeService; |
| | | |
| | | /** |
| | | * è·åéç¥å
¬åå表 |
| | | */ |
| | | @SaCheckPermission("system:notice:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysNotice> list(SysNotice notice, PageQuery pageQuery) { |
| | | return noticeService.selectPageNoticeList(notice, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®éç¥å
¬åç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param noticeId å
ŒID |
| | | */ |
| | | @SaCheckPermission("system:notice:query") |
| | | @GetMapping(value = "/{noticeId}") |
| | | public R<SysNotice> getInfo(@PathVariable Long noticeId) { |
| | | return R.ok(noticeService.selectNoticeById(noticeId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢éç¥å
Œ |
| | | */ |
| | | @SaCheckPermission("system:notice:add") |
| | | @Log(title = "éç¥å
Œ", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysNotice notice) { |
| | | return toAjax(noticeService.insertNotice(notice)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹éç¥å
Œ |
| | | */ |
| | | @SaCheckPermission("system:notice:edit") |
| | | @Log(title = "éç¥å
Œ", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysNotice notice) { |
| | | return toAjax(noticeService.updateNotice(notice)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éç¥å
Œ |
| | | * |
| | | * @param noticeIds å
¬åID串 |
| | | */ |
| | | @SaCheckPermission("system:notice:remove") |
| | | @Log(title = "éç¥å
Œ", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{noticeIds}") |
| | | public R<Void> remove(@PathVariable Long[] noticeIds) { |
| | | return toAjax(noticeService.deleteNoticeByIds(noticeIds)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.idempotent.annotation.RepeatSubmit; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.core.validate.AddGroup; |
| | | import com.ruoyi.common.core.validate.EditGroup; |
| | | import com.ruoyi.common.core.validate.QueryGroup; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.system.domain.bo.SysOssConfigBo; |
| | | import com.ruoyi.system.domain.vo.SysOssConfigVo; |
| | | import com.ruoyi.system.service.ISysOssConfigService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * 对象åå¨é
ç½® |
| | | * |
| | | * @author Lion Li |
| | | * @author å¤èçé¨ |
| | | * @date 2021-08-13 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/oss/config") |
| | | public class SysOssConfigController extends BaseController { |
| | | |
| | | private final ISysOssConfigService iSysOssConfigService; |
| | | |
| | | /** |
| | | * æ¥è¯¢å¯¹è±¡åå¨é
ç½®å表 |
| | | */ |
| | | @SaCheckPermission("system:oss:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { |
| | | return iSysOssConfigService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·å对象åå¨é
置详ç»ä¿¡æ¯ |
| | | * |
| | | * @param ossConfigId OSSé
ç½®ID |
| | | */ |
| | | @SaCheckPermission("system:oss:query") |
| | | @GetMapping("/{ossConfigId}") |
| | | public R<SysOssConfigVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long ossConfigId) { |
| | | return R.ok(iSysOssConfigService.queryById(ossConfigId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢å¯¹è±¡åå¨é
ç½® |
| | | */ |
| | | @SaCheckPermission("system:oss:add") |
| | | @Log(title = "对象åå¨é
ç½®", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping() |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { |
| | | return toAjax(iSysOssConfigService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹å¯¹è±¡åå¨é
ç½® |
| | | */ |
| | | @SaCheckPermission("system:oss:edit") |
| | | @Log(title = "对象åå¨é
ç½®", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { |
| | | return toAjax(iSysOssConfigService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å¯¹è±¡åå¨é
ç½® |
| | | * |
| | | * @param ossConfigIds OSSé
置ID串 |
| | | */ |
| | | @SaCheckPermission("system:oss:remove") |
| | | @Log(title = "对象åå¨é
ç½®", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ossConfigIds}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ossConfigIds) { |
| | | return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true)); |
| | | } |
| | | |
| | | /** |
| | | * ç¶æä¿®æ¹ |
| | | */ |
| | | @SaCheckPermission("system:oss:edit") |
| | | @Log(title = "对象åå¨ç¶æä¿®æ¹", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/changeStatus") |
| | | public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) { |
| | | return toAjax(iSysOssConfigService.updateOssConfigStatus(bo)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.http.HttpException; |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.core.validate.QueryGroup; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.core.utils.file.FileUtils; |
| | | import com.ruoyi.system.domain.bo.SysOssBo; |
| | | import com.ruoyi.system.domain.vo.SysOssVo; |
| | | import com.ruoyi.system.service.ISysOssService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import java.io.IOException; |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æä»¶ä¸ä¼ æ§å¶å± |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/oss") |
| | | public class SysOssController extends BaseController { |
| | | |
| | | private final ISysOssService iSysOssService; |
| | | |
| | | /** |
| | | * æ¥è¯¢OSS对象åå¨å表 |
| | | */ |
| | | @SaCheckPermission("system:oss:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) { |
| | | return iSysOssService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢OSS对象åºäºid串 |
| | | * |
| | | * @param ossIds OSS对象ID串 |
| | | */ |
| | | @SaCheckPermission("system:oss:list") |
| | | @GetMapping("/listByIds/{ossIds}") |
| | | public R<List<SysOssVo>> listByIds(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ossIds) { |
| | | List<SysOssVo> list = iSysOssService.listByIds(Arrays.asList(ossIds)); |
| | | return R.ok(list); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ OSS对象åå¨ |
| | | * |
| | | * @param file æä»¶ |
| | | */ |
| | | @SaCheckPermission("system:oss:upload") |
| | | @Log(title = "OSS对象åå¨", businessType = BusinessType.INSERT) |
| | | @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
| | | public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) { |
| | | if (ObjectUtil.isNull(file)) { |
| | | throw new ServiceException("ä¸ä¼ æä»¶ä¸è½ä¸ºç©º"); |
| | | } |
| | | SysOssVo oss = iSysOssService.upload(file); |
| | | Map<String, String> map = new HashMap<>(2); |
| | | map.put("url", oss.getUrl()); |
| | | map.put("fileName", oss.getOriginalName()); |
| | | map.put("ossId", oss.getOssId().toString()); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | /** |
| | | * ä¸è½½OSS对象 |
| | | * |
| | | * @param ossId OSS对象ID |
| | | */ |
| | | @SaCheckPermission("system:oss:download") |
| | | @GetMapping("/download/{ossId}") |
| | | public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { |
| | | iSysOssService.download(ossId,response); |
| | | } |
| | | |
| | | /** |
| | | * å é¤OSS对象åå¨ |
| | | * |
| | | * @param ossIds OSS对象ID串 |
| | | */ |
| | | @SaCheckPermission("system:oss:remove") |
| | | @Log(title = "OSS对象åå¨", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ossIds}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ossIds) { |
| | | return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.domain.SysPost; |
| | | import com.ruoyi.system.service.ISysPostService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å²ä½ä¿¡æ¯æä½å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/post") |
| | | public class SysPostController extends BaseController { |
| | | |
| | | private final ISysPostService postService; |
| | | |
| | | /** |
| | | * è·åå²ä½å表 |
| | | */ |
| | | @SaCheckPermission("system:post:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysPost> list(SysPost post, PageQuery pageQuery) { |
| | | return postService.selectPagePostList(post, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºå²ä½å表 |
| | | */ |
| | | @Log(title = "å²ä½ç®¡ç", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("system:post:export") |
| | | @PostMapping("/export") |
| | | public void export(SysPost post, HttpServletResponse response) { |
| | | List<SysPost> list = postService.selectPostList(post); |
| | | ExcelUtil.exportExcel(list, "å²ä½æ°æ®", SysPost.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®å²ä½ç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param postId å²ä½ID |
| | | */ |
| | | @SaCheckPermission("system:post:query") |
| | | @GetMapping(value = "/{postId}") |
| | | public R<SysPost> getInfo(@PathVariable Long postId) { |
| | | return R.ok(postService.selectPostById(postId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢å²ä½ |
| | | */ |
| | | @SaCheckPermission("system:post:add") |
| | | @Log(title = "å²ä½ç®¡ç", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysPost post) { |
| | | if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) { |
| | | return R.fail("æ°å¢å²ä½'" + post.getPostName() + "'失败ï¼å²ä½åç§°å·²åå¨"); |
| | | } else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) { |
| | | return R.fail("æ°å¢å²ä½'" + post.getPostName() + "'失败ï¼å²ä½ç¼ç å·²åå¨"); |
| | | } |
| | | return toAjax(postService.insertPost(post)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹å²ä½ |
| | | */ |
| | | @SaCheckPermission("system:post:edit") |
| | | @Log(title = "å²ä½ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysPost post) { |
| | | if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) { |
| | | return R.fail("ä¿®æ¹å²ä½'" + post.getPostName() + "'失败ï¼å²ä½åç§°å·²åå¨"); |
| | | } else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) { |
| | | return R.fail("ä¿®æ¹å²ä½'" + post.getPostName() + "'失败ï¼å²ä½ç¼ç å·²åå¨"); |
| | | } |
| | | return toAjax(postService.updatePost(post)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å²ä½ |
| | | * |
| | | * @param postIds å²ä½ID串 |
| | | */ |
| | | @SaCheckPermission("system:post:remove") |
| | | @Log(title = "å²ä½ç®¡ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{postIds}") |
| | | public R<Void> remove(@PathVariable Long[] postIds) { |
| | | return toAjax(postService.deletePostByIds(postIds)); |
| | | } |
| | | |
| | | /** |
| | | * è·åå²ä½éæ©æ¡å表 |
| | | */ |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysPost>> optionselect() { |
| | | List<SysPost> posts = postService.selectPostAll(); |
| | | return R.ok(posts); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.secure.BCrypt; |
| | | import cn.hutool.core.io.FileUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import com.ruoyi.system.domain.SysUser; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.file.MimeTypeUtils; |
| | | import com.ruoyi.system.domain.vo.SysOssVo; |
| | | import com.ruoyi.system.service.ISysOssService; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ä¸ªäººä¿¡æ¯ ä¸å¡å¤ç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/user/profile") |
| | | public class SysProfileController extends BaseController { |
| | | |
| | | private final ISysUserService userService; |
| | | private final ISysOssService iSysOssService; |
| | | |
| | | /** |
| | | * ä¸ªäººä¿¡æ¯ |
| | | */ |
| | | @GetMapping |
| | | public R<Map<String, Object>> profile() { |
| | | SysUser user = userService.selectUserById(LoginHelper.getUserId()); |
| | | Map<String, Object> ajax = new HashMap<>(); |
| | | ajax.put("user", user); |
| | | ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName())); |
| | | ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName())); |
| | | return R.ok(ajax); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¨æ· |
| | | */ |
| | | @Log(title = "个人信æ¯", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> updateProfile(@RequestBody SysUser user) { |
| | | if (StringUtils.isNotEmpty(user.getPhonenumber()) |
| | | && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { |
| | | return R.fail("ä¿®æ¹ç¨æ·'" + user.getUserName() + "'å¤±è´¥ï¼ææºå·ç å·²åå¨"); |
| | | } |
| | | if (StringUtils.isNotEmpty(user.getEmail()) |
| | | && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { |
| | | return R.fail("ä¿®æ¹ç¨æ·'" + user.getUserName() + "'失败ï¼é®ç®±è´¦å·å·²åå¨"); |
| | | } |
| | | user.setUserId(LoginHelper.getUserId()); |
| | | user.setUserName(null); |
| | | user.setPassword(null); |
| | | user.setAvatar(null); |
| | | user.setDeptId(null); |
| | | if (userService.updateUserProfile(user) > 0) { |
| | | return R.ok(); |
| | | } |
| | | return R.fail("ä¿®æ¹ä¸ªäººä¿¡æ¯å¼å¸¸ï¼è¯·è系管çå"); |
| | | } |
| | | |
| | | /** |
| | | * éç½®å¯ç |
| | | * |
| | | * @param newPassword æ§å¯ç |
| | | * @param oldPassword æ°å¯ç |
| | | */ |
| | | @Log(title = "个人信æ¯", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/updatePwd") |
| | | public R<Void> updatePwd(String oldPassword, String newPassword) { |
| | | SysUser user = userService.selectUserById(LoginHelper.getUserId()); |
| | | String userName = user.getUserName(); |
| | | String password = user.getPassword(); |
| | | if (!BCrypt.checkpw(oldPassword, password)) { |
| | | return R.fail("ä¿®æ¹å¯ç å¤±è´¥ï¼æ§å¯ç é误"); |
| | | } |
| | | if (BCrypt.checkpw(newPassword, password)) { |
| | | return R.fail("æ°å¯ç ä¸è½ä¸æ§å¯ç ç¸å"); |
| | | } |
| | | |
| | | if (userService.resetUserPwd(userName, BCrypt.hashpw(newPassword)) > 0) { |
| | | return R.ok(); |
| | | } |
| | | return R.fail("ä¿®æ¹å¯ç å¼å¸¸ï¼è¯·è系管çå"); |
| | | } |
| | | |
| | | /** |
| | | * 头åä¸ä¼ |
| | | * |
| | | * @param avatarfile ç¨æ·å¤´å |
| | | */ |
| | | @Log(title = "ç¨æ·å¤´å", businessType = BusinessType.UPDATE) |
| | | @PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
| | | public R<Map<String, Object>> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) { |
| | | Map<String, Object> ajax = new HashMap<>(); |
| | | if (!avatarfile.isEmpty()) { |
| | | String extension = FileUtil.extName(avatarfile.getOriginalFilename()); |
| | | if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { |
| | | return R.fail("æä»¶æ ¼å¼ä¸æ£ç¡®ï¼è¯·ä¸ä¼ " + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "æ ¼å¼"); |
| | | } |
| | | SysOssVo oss = iSysOssService.upload(avatarfile); |
| | | String avatar = oss.getUrl(); |
| | | if (userService.updateUserAvatar(LoginHelper.getUsername(), avatar)) { |
| | | ajax.put("imgUrl", avatar); |
| | | return R.ok(ajax); |
| | | } |
| | | } |
| | | return R.fail("ä¸ä¼ å¾çå¼å¸¸ï¼è¯·è系管çå"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import com.ruoyi.system.domain.SysDept; |
| | | import com.ruoyi.system.domain.SysRole; |
| | | import com.ruoyi.system.domain.SysUser; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.domain.SysUserRole; |
| | | import com.ruoyi.system.service.ISysDeptService; |
| | | import com.ruoyi.system.service.ISysRoleService; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | | import com.ruoyi.system.service.SysPermissionService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * è§è²ä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/role") |
| | | public class SysRoleController extends BaseController { |
| | | |
| | | private final ISysRoleService roleService; |
| | | private final ISysUserService userService; |
| | | private final ISysDeptService deptService; |
| | | private final SysPermissionService permissionService; |
| | | |
| | | /** |
| | | * è·åè§è²ä¿¡æ¯å表 |
| | | */ |
| | | @SaCheckPermission("system:role:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysRole> list(SysRole role, PageQuery pageQuery) { |
| | | return roleService.selectPageRoleList(role, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºè§è²ä¿¡æ¯å表 |
| | | */ |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("system:role:export") |
| | | @PostMapping("/export") |
| | | public void export(SysRole role, HttpServletResponse response) { |
| | | List<SysRole> list = roleService.selectRoleList(role); |
| | | ExcelUtil.exportExcel(list, "è§è²æ°æ®", SysRole.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®è§è²ç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param roleId è§è²ID |
| | | */ |
| | | @SaCheckPermission("system:role:query") |
| | | @GetMapping(value = "/{roleId}") |
| | | public R<SysRole> getInfo(@PathVariable Long roleId) { |
| | | roleService.checkRoleDataScope(roleId); |
| | | return R.ok(roleService.selectRoleById(roleId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢è§è² |
| | | */ |
| | | @SaCheckPermission("system:role:add") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysRole role) { |
| | | if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) { |
| | | return R.fail("æ°å¢è§è²'" + role.getRoleName() + "'失败ï¼è§è²åç§°å·²åå¨"); |
| | | } else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) { |
| | | return R.fail("æ°å¢è§è²'" + role.getRoleName() + "'失败ï¼è§è²æéå·²åå¨"); |
| | | } |
| | | return toAjax(roleService.insertRole(role)); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¿åè§è² |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysRole role) { |
| | | roleService.checkRoleAllowed(role); |
| | | roleService.checkRoleDataScope(role.getRoleId()); |
| | | if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) { |
| | | return R.fail("ä¿®æ¹è§è²'" + role.getRoleName() + "'失败ï¼è§è²åç§°å·²åå¨"); |
| | | } else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) { |
| | | return R.fail("ä¿®æ¹è§è²'" + role.getRoleName() + "'失败ï¼è§è²æéå·²åå¨"); |
| | | } |
| | | |
| | | if (roleService.updateRole(role) > 0) { |
| | | // æ´æ°ç¼åç¨æ·æé |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | SysUser sysUser = userService.selectUserById(loginUser.getUserId()); |
| | | if (ObjectUtil.isNotNull(sysUser) && !sysUser.isAdmin()) { |
| | | loginUser.setMenuPermission(permissionService.getMenuPermission(sysUser)); |
| | | LoginHelper.setLoginUser(loginUser); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | return R.fail("ä¿®æ¹è§è²'" + role.getRoleName() + "'失败ï¼è¯·è系管çå"); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä¿åæ°æ®æé |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/dataScope") |
| | | public R<Void> dataScope(@RequestBody SysRole role) { |
| | | roleService.checkRoleAllowed(role); |
| | | roleService.checkRoleDataScope(role.getRoleId()); |
| | | return toAjax(roleService.authDataScope(role)); |
| | | } |
| | | |
| | | /** |
| | | * ç¶æä¿®æ¹ |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/changeStatus") |
| | | public R<Void> changeStatus(@RequestBody SysRole role) { |
| | | roleService.checkRoleAllowed(role); |
| | | roleService.checkRoleDataScope(role.getRoleId()); |
| | | return toAjax(roleService.updateRoleStatus(role)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤è§è² |
| | | * |
| | | * @param roleIds è§è²ID串 |
| | | */ |
| | | @SaCheckPermission("system:role:remove") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{roleIds}") |
| | | public R<Void> remove(@PathVariable Long[] roleIds) { |
| | | return toAjax(roleService.deleteRoleByIds(roleIds)); |
| | | } |
| | | |
| | | /** |
| | | * è·åè§è²éæ©æ¡å表 |
| | | */ |
| | | @SaCheckPermission("system:role:query") |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysRole>> optionselect() { |
| | | return R.ok(roleService.selectRoleAll()); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å·²åé
ç¨æ·è§è²å表 |
| | | */ |
| | | @SaCheckPermission("system:role:list") |
| | | @GetMapping("/authUser/allocatedList") |
| | | public TableDataInfo<SysUser> allocatedList(SysUser user, PageQuery pageQuery) { |
| | | return userService.selectAllocatedList(user, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æªåé
ç¨æ·è§è²å表 |
| | | */ |
| | | @SaCheckPermission("system:role:list") |
| | | @GetMapping("/authUser/unallocatedList") |
| | | public TableDataInfo<SysUser> unallocatedList(SysUser user, PageQuery pageQuery) { |
| | | return userService.selectUnallocatedList(user, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * åæ¶ææç¨æ· |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.GRANT) |
| | | @PutMapping("/authUser/cancel") |
| | | public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) { |
| | | return toAjax(roleService.deleteAuthUser(userRole)); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éåæ¶ææç¨æ· |
| | | * |
| | | * @param roleId è§è²ID |
| | | * @param userIds ç¨æ·ID串 |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.GRANT) |
| | | @PutMapping("/authUser/cancelAll") |
| | | public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) { |
| | | return toAjax(roleService.deleteAuthUsers(roleId, userIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¹ééæ©ç¨æ·ææ |
| | | * |
| | | * @param roleId è§è²ID |
| | | * @param userIds ç¨æ·ID串 |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "è§è²ç®¡ç", businessType = BusinessType.GRANT) |
| | | @PutMapping("/authUser/selectAll") |
| | | public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) { |
| | | roleService.checkRoleDataScope(roleId); |
| | | return toAjax(roleService.insertAuthUsers(roleId, userIds)); |
| | | } |
| | | |
| | | /** |
| | | * è·å对åºè§è²é¨é¨æ å表 |
| | | * |
| | | * @param roleId è§è²ID |
| | | */ |
| | | @SaCheckPermission("system:role:list") |
| | | @GetMapping(value = "/deptTree/{roleId}") |
| | | public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) { |
| | | Map<String, Object> ajax = new HashMap<>(); |
| | | ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); |
| | | ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); |
| | | return R.ok(ajax); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.dev33.satoken.secure.BCrypt; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.lang.tree.Tree; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ruoyi.common.excel.core.ExcelResult; |
| | | import com.ruoyi.common.log.annotation.Log; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.satoken.utils.LoginHelper; |
| | | import com.ruoyi.system.domain.SysDept; |
| | | import com.ruoyi.system.domain.SysRole; |
| | | import com.ruoyi.system.domain.SysUser; |
| | | import com.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import com.ruoyi.common.log.enums.BusinessType; |
| | | import com.ruoyi.common.core.utils.StreamUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.excel.utils.ExcelUtil; |
| | | import com.ruoyi.system.domain.vo.SysUserExportVo; |
| | | import com.ruoyi.system.domain.vo.SysUserImportVo; |
| | | import com.ruoyi.system.listener.SysUserImportListener; |
| | | import com.ruoyi.system.service.ISysDeptService; |
| | | import com.ruoyi.system.service.ISysPostService; |
| | | import com.ruoyi.system.service.ISysRoleService; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ç¨æ·ä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/system/user") |
| | | public class SysUserController extends BaseController { |
| | | |
| | | private final ISysUserService userService; |
| | | private final ISysRoleService roleService; |
| | | private final ISysPostService postService; |
| | | private final ISysDeptService deptService; |
| | | |
| | | /** |
| | | * è·åç¨æ·å表 |
| | | */ |
| | | @SaCheckPermission("system:user:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<SysUser> list(SysUser user, PageQuery pageQuery) { |
| | | return userService.selectPageUserList(user, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºç¨æ·å表 |
| | | */ |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.EXPORT) |
| | | @SaCheckPermission("system:user:export") |
| | | @PostMapping("/export") |
| | | public void export(SysUser user, HttpServletResponse response) { |
| | | List<SysUser> list = userService.selectUserList(user); |
| | | List<SysUserExportVo> listVo = BeanUtil.copyToList(list, SysUserExportVo.class); |
| | | for (int i = 0; i < list.size(); i++) { |
| | | SysDept dept = list.get(i).getDept(); |
| | | SysUserExportVo vo = listVo.get(i); |
| | | if (ObjectUtil.isNotEmpty(dept)) { |
| | | vo.setDeptName(dept.getDeptName()); |
| | | vo.setLeader(dept.getLeader()); |
| | | } |
| | | } |
| | | ExcelUtil.exportExcel(listVo, "ç¨æ·æ°æ®", SysUserExportVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥æ°æ® |
| | | * |
| | | * @param file 导å
¥æä»¶ |
| | | * @param updateSupport æ¯å¦æ´æ°å·²å卿°æ® |
| | | */ |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.IMPORT) |
| | | @SaCheckPermission("system:user:import") |
| | | @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
| | | public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { |
| | | ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); |
| | | return R.ok(result.getAnalysis()); |
| | | } |
| | | |
| | | /** |
| | | * è·å导å
¥æ¨¡æ¿ |
| | | */ |
| | | @PostMapping("/importTemplate") |
| | | public void importTemplate(HttpServletResponse response) { |
| | | ExcelUtil.exportExcel(new ArrayList<>(), "ç¨æ·æ°æ®", SysUserImportVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·ç¼å·è·å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | */ |
| | | @SaCheckPermission("system:user:query") |
| | | @GetMapping(value = {"/", "/{userId}"}) |
| | | public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) { |
| | | userService.checkUserDataScope(userId); |
| | | Map<String, Object> ajax = new HashMap<>(); |
| | | List<SysRole> roles = roleService.selectRoleAll(); |
| | | ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); |
| | | ajax.put("posts", postService.selectPostAll()); |
| | | if (ObjectUtil.isNotNull(userId)) { |
| | | SysUser sysUser = userService.selectUserById(userId); |
| | | ajax.put("user", sysUser); |
| | | ajax.put("postIds", postService.selectPostListByUserId(userId)); |
| | | ajax.put("roleIds", StreamUtils.toList(sysUser.getRoles(), SysRole::getRoleId)); |
| | | } |
| | | return R.ok(ajax); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ç¨æ· |
| | | */ |
| | | @SaCheckPermission("system:user:add") |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysUser user) { |
| | | if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) { |
| | | return R.fail("æ°å¢ç¨æ·'" + user.getUserName() + "'失败ï¼ç»å½è´¦å·å·²åå¨"); |
| | | } else if (StringUtils.isNotEmpty(user.getPhonenumber()) |
| | | && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { |
| | | return R.fail("æ°å¢ç¨æ·'" + user.getUserName() + "'å¤±è´¥ï¼ææºå·ç å·²åå¨"); |
| | | } else if (StringUtils.isNotEmpty(user.getEmail()) |
| | | && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { |
| | | return R.fail("æ°å¢ç¨æ·'" + user.getUserName() + "'失败ï¼é®ç®±è´¦å·å·²åå¨"); |
| | | } |
| | | user.setPassword(BCrypt.hashpw(user.getPassword())); |
| | | return toAjax(userService.insertUser(user)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¨æ· |
| | | */ |
| | | @SaCheckPermission("system:user:edit") |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysUser user) { |
| | | userService.checkUserAllowed(user); |
| | | userService.checkUserDataScope(user.getUserId()); |
| | | if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) { |
| | | return R.fail("ä¿®æ¹ç¨æ·'" + user.getUserName() + "'失败ï¼ç»å½è´¦å·å·²åå¨"); |
| | | } else if (StringUtils.isNotEmpty(user.getPhonenumber()) |
| | | && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { |
| | | return R.fail("ä¿®æ¹ç¨æ·'" + user.getUserName() + "'å¤±è´¥ï¼ææºå·ç å·²åå¨"); |
| | | } else if (StringUtils.isNotEmpty(user.getEmail()) |
| | | && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { |
| | | return R.fail("ä¿®æ¹ç¨æ·'" + user.getUserName() + "'失败ï¼é®ç®±è´¦å·å·²åå¨"); |
| | | } |
| | | return toAjax(userService.updateUser(user)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ç¨æ· |
| | | * |
| | | * @param userIds è§è²ID串 |
| | | */ |
| | | @SaCheckPermission("system:user:remove") |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{userIds}") |
| | | public R<Void> remove(@PathVariable Long[] userIds) { |
| | | if (ArrayUtil.contains(userIds, LoginHelper.getUserId())) { |
| | | return R.fail("å½åç¨æ·ä¸è½å é¤"); |
| | | } |
| | | return toAjax(userService.deleteUserByIds(userIds)); |
| | | } |
| | | |
| | | /** |
| | | * éç½®å¯ç |
| | | */ |
| | | @SaCheckPermission("system:user:resetPwd") |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/resetPwd") |
| | | public R<Void> resetPwd(@RequestBody SysUser user) { |
| | | userService.checkUserAllowed(user); |
| | | userService.checkUserDataScope(user.getUserId()); |
| | | user.setPassword(BCrypt.hashpw(user.getPassword())); |
| | | return toAjax(userService.resetPwd(user)); |
| | | } |
| | | |
| | | /** |
| | | * ç¶æä¿®æ¹ |
| | | */ |
| | | @SaCheckPermission("system:user:edit") |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/changeStatus") |
| | | public R<Void> changeStatus(@RequestBody SysUser user) { |
| | | userService.checkUserAllowed(user); |
| | | userService.checkUserDataScope(user.getUserId()); |
| | | return toAjax(userService.updateUserStatus(user)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·ç¼å·è·åææè§è² |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | */ |
| | | @SaCheckPermission("system:user:query") |
| | | @GetMapping("/authRole/{userId}") |
| | | public R<Map<String, Object>> authRole(@PathVariable Long userId) { |
| | | SysUser user = userService.selectUserById(userId); |
| | | List<SysRole> roles = roleService.selectRolesByUserId(userId); |
| | | Map<String, Object> ajax = new HashMap<>(); |
| | | ajax.put("user", user); |
| | | ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); |
| | | return R.ok(ajax); |
| | | } |
| | | |
| | | /** |
| | | * ç¨æ·ææè§è² |
| | | * |
| | | * @param userId ç¨æ·Id |
| | | * @param roleIds è§è²ID串 |
| | | */ |
| | | @SaCheckPermission("system:user:edit") |
| | | @Log(title = "ç¨æ·ç®¡ç", businessType = BusinessType.GRANT) |
| | | @PutMapping("/authRole") |
| | | public R<Void> insertAuthRole(Long userId, Long[] roleIds) { |
| | | userService.checkUserDataScope(userId); |
| | | userService.insertUserAuth(userId, roleIds); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * è·åé¨é¨æ å表 |
| | | */ |
| | | @SaCheckPermission("system:user:list") |
| | | @GetMapping("/deptTree") |
| | | public R<List<Tree<Long>>> deptTree(SysDept dept) { |
| | | return R.ok(deptService.selectDeptTreeList(dept)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.domain; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * ç¼åä¿¡æ¯ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class SysCache { |
| | | |
| | | /** |
| | | * ç¼ååç§° |
| | | */ |
| | | private String cacheName = ""; |
| | | |
| | | /** |
| | | * ç¼åé®å |
| | | */ |
| | | private String cacheKey = ""; |
| | | |
| | | /** |
| | | * ç¼åå
容 |
| | | */ |
| | | private String cacheValue = ""; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark = ""; |
| | | |
| | | public SysCache(String cacheName, String remark) { |
| | | this.cacheName = cacheName; |
| | | this.remark = remark; |
| | | } |
| | | |
| | | public SysCache(String cacheName, String cacheKey, String cacheValue) { |
| | | this.cacheName = StringUtils.replace(cacheName, ":", ""); |
| | | this.cacheKey = StringUtils.replace(cacheKey, cacheName, ""); |
| | | this.cacheValue = cacheValue; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.domain; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import com.ruoyi.common.excel.annotation.ExcelDictFormat; |
| | | import com.ruoyi.common.excel.convert.ExcelDictConvert; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.Size; |
| | | |
| | | /** |
| | | * åæ°é
置表 sys_config |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("sys_config") |
| | | @ExcelIgnoreUnannotated |
| | | public class SysConfig extends BaseEntity { |
| | | |
| | | /** |
| | | * åæ°ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "忰䏻é®") |
| | | @TableId(value = "config_id") |
| | | private Long configId; |
| | | |
| | | /** |
| | | * åæ°åç§° |
| | | */ |
| | | @ExcelProperty(value = "åæ°åç§°") |
| | | @NotBlank(message = "åæ°åç§°ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 100, message = "åæ°åç§°ä¸è½è¶
è¿{max}个å符") |
| | | private String configName; |
| | | |
| | | /** |
| | | * åæ°é®å |
| | | */ |
| | | @ExcelProperty(value = "åæ°é®å") |
| | | @NotBlank(message = "åæ°é®åé¿åº¦ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 100, message = "åæ°é®åé¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String configKey; |
| | | |
| | | /** |
| | | * åæ°é®å¼ |
| | | */ |
| | | @ExcelProperty(value = "åæ°é®å¼") |
| | | @NotBlank(message = "åæ°é®å¼ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 500, message = "åæ°é®å¼é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String configValue; |
| | | |
| | | /** |
| | | * ç³»ç»å
ç½®ï¼Yæ¯ Nå¦ï¼ |
| | | */ |
| | | @ExcelProperty(value = "ç³»ç»å
ç½®", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(dictType = "sys_yes_no") |
| | | private String configType; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ruoyi.common.core.web.domain.TreeEntity; |
| | | import jakarta.validation.constraints.Email; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import jakarta.validation.constraints.Size; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * é¨é¨è¡¨ sys_dept |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("sys_dept") |
| | | public class SysDept extends TreeEntity<SysDept> { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | @TableId(value = "dept_id") |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * é¨é¨åç§° |
| | | */ |
| | | @NotBlank(message = "é¨é¨åç§°ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 30, message = "é¨é¨åç§°é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String deptName; |
| | | |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | | */ |
| | | @NotNull(message = "æ¾ç¤ºé¡ºåºä¸è½ä¸ºç©º") |
| | | private Integer orderNum; |
| | | |
| | | /** |
| | | * è´è´£äºº |
| | | */ |
| | | private String leader; |
| | | |
| | | /** |
| | | * èç³»çµè¯ |
| | | */ |
| | | @Size(min = 0, max = 11, message = "èç³»çµè¯é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String phone; |
| | | |
| | | /** |
| | | * é®ç®± |
| | | */ |
| | | @Email(message = "é®ç®±æ ¼å¼ä¸æ£ç¡®") |
| | | @Size(min = 0, max = 50, message = "é®ç®±é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String email; |
| | | |
| | | /** |
| | | * é¨é¨ç¶æ:0æ£å¸¸,1åç¨ |
| | | */ |
| | | private String status; |
| | | |
| | | /** |
| | | * å 餿 å¿ï¼0代表åå¨ 2代表å é¤ï¼ |
| | | */ |
| | | @TableLogic |
| | | private String delFlag; |
| | | |
| | | /** |
| | | * ç¥çº§å表 |
| | | */ |
| | | private String ancestors; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.system.domain; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ruoyi.common.core.constant.UserConstants; |
| | | import com.ruoyi.common.core.web.domain.BaseEntity; |
| | | import com.ruoyi.common.excel.annotation.ExcelDictFormat; |
| | | import com.ruoyi.common.excel.convert.ExcelDictConvert; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.Size; |
| | | |
| | | /** |
| | | * åå
¸æ°æ®è¡¨ sys_dict_data |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("sys_dict_data") |
| | | @ExcelIgnoreUnannotated |
| | | public class SysDictData extends BaseEntity { |
| | | |
| | | /** |
| | | * åå
¸ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "åå
¸ç¼ç ") |
| | | @TableId(value = "dict_code") |
| | | private Long dictCode; |
| | | |
| | | /** |
| | | * åå
¸æåº |
| | | */ |
| | | @ExcelProperty(value = "åå
¸æåº") |
| | | private Integer dictSort; |
| | | |
| | | /** |
| | | * åå
¸æ ç¾ |
| | | */ |
| | | @ExcelProperty(value = "åå
¸æ ç¾") |
| | | @NotBlank(message = "åå
¸æ ç¾ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 100, message = "åå
¸æ ç¾é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String dictLabel; |
| | | |
| | | /** |
| | | * åå
¸é®å¼ |
| | | */ |
| | | @ExcelProperty(value = "åå
¸é®å¼") |
| | | @NotBlank(message = "åå
¸é®å¼ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 100, message = "åå
¸é®å¼é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String dictValue; |
| | | |
| | | /** |
| | | * åå
¸ç±»å |
| | | */ |
| | | @ExcelProperty(value = "åå
¸ç±»å") |
| | | @NotBlank(message = "åå
¸ç±»åä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 100, message = "åå
¸ç±»åé¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String dictType; |
| | | |
| | | /** |
| | | * æ ·å¼å±æ§ï¼å
¶ä»æ ·å¼æ©å±ï¼ |
| | | */ |
| | | @Size(min = 0, max = 100, message = "æ ·å¼å±æ§é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String cssClass; |
| | | |
| | | /** |
| | | * è¡¨æ ¼åå
¸æ ·å¼ |
| | | */ |
| | | private String listClass; |
| | | |
| | | /** |
| | | * æ¯å¦é»è®¤ï¼Yæ¯ Nå¦ï¼ |
| | | */ |
| | | @ExcelProperty(value = "æ¯å¦é»è®¤", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(dictType = "sys_yes_no") |
| | | private String isDefault; |
| | | |
| | | /** |
| | | * ç¶æï¼0æ£å¸¸ 1åç¨ï¼ |
| | | */ |
| | | @ExcelProperty(value = "ç¶æ", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(dictType = "sys_normal_disable") |
| | | private String status; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | public boolean getDefault() { |
| | | return UserConstants.YES.equals(this.isDefault); |
| | | } |
| | | |
| | | } |
| ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictType.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOss.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssBo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssVo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserExportVo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssConfigMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDataScopeService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysPermissionService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDataScopeServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/resources/mapper/package-info.md
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssConfigMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
ruoyi-oss/pom.xml (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/core/OssClient.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/entity/UploadResult.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/AccessPolicyType.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/PolicyType.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/exception/OssException.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java (已删除)
ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java (已删除)
ruoyi-sms/pom.xml (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java (已删除)
ruoyi-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java (已删除)
ruoyi-system/pom.xml (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/CacheController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysLogininforController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysOperlogController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysUserOnlineController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysConfigController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDeptController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictDataController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictTypeController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysMenuController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysNoticeController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssConfigController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysPostController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysProfileController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysRoleController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysUserController.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDept.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictData.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictType.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOss.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssBo.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserExportVo.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssConfigMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDataScopeServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java (已删除)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java (已删除) |