copyProcess(WfCopyBo copyBo, PageQuery pageQuery) {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfTaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfTaskController.java
index 660269e4..9f19665e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfTaskController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfTaskController.java
@@ -5,11 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.workflow.domain.bo.WfTaskBo;
import com.ruoyi.workflow.domain.dto.WfNextDto;
-import com.ruoyi.workflow.domain.vo.WfTaskVo;
import com.ruoyi.workflow.service.IWfTaskService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@@ -28,7 +24,6 @@ import java.io.OutputStream;
* @createTime 2022/3/10 00:12
*/
@Slf4j
-@Api(tags = "工作流流程任务管理")
@RequiredArgsConstructor
@RestController
@RequestMapping("/workflow/task")
@@ -36,7 +31,9 @@ public class WfTaskController {
private final IWfTaskService flowTaskService;
- @ApiOperation(value = "取消申请", response = WfTaskVo.class)
+ /**
+ * 取消申请
+ */
@PostMapping(value = "/stopProcess")
@SaCheckPermission("workflow:process:cancel")
public R stopProcess(@RequestBody WfTaskBo bo) {
@@ -44,7 +41,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "撤回流程", response = WfTaskVo.class)
+ /**
+ * 撤回流程
+ */
@PostMapping(value = "/revokeProcess")
@SaCheckPermission("workflow:process:revoke")
public R revokeProcess(@RequestBody WfTaskBo bo) {
@@ -52,14 +51,19 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "获取流程变量", response = WfTaskVo.class)
+ /**
+ * 获取流程变量
+ * @param taskId 流程任务Id
+ */
@GetMapping(value = "/processVariables/{taskId}")
@SaCheckPermission("workflow:process:query")
- public R processVariables(@ApiParam(value = "流程任务Id") @PathVariable(value = "taskId") String taskId) {
+ public R processVariables(@PathVariable(value = "taskId") String taskId) {
return R.ok(flowTaskService.getProcessVariables(taskId));
}
- @ApiOperation(value = "审批任务")
+ /**
+ * 审批任务
+ */
@PostMapping(value = "/complete")
@SaCheckPermission("workflow:process:approval")
public R complete(@RequestBody WfTaskBo bo) {
@@ -67,8 +71,9 @@ public class WfTaskController {
return R.ok();
}
-
- @ApiOperation(value = "驳回任务")
+ /**
+ * 驳回任务
+ */
@PostMapping(value = "/reject")
@SaCheckPermission("workflow:process:approval")
public R taskReject(@RequestBody WfTaskBo bo) {
@@ -76,7 +81,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "退回任务")
+ /**
+ * 退回任务
+ */
@PostMapping(value = "/return")
@SaCheckPermission("workflow:process:approval")
public R taskReturn(@RequestBody WfTaskBo bo) {
@@ -84,14 +91,18 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "获取所有可回退的节点")
+ /**
+ * 获取所有可回退的节点
+ */
@PostMapping(value = "/returnList")
@SaCheckPermission("workflow:process:query")
public R findReturnTaskList(@RequestBody WfTaskBo bo) {
return R.ok(flowTaskService.findReturnTaskList(bo));
}
- @ApiOperation(value = "删除任务")
+ /**
+ * 删除任务
+ */
@DeleteMapping(value = "/delete")
@SaCheckPermission("workflow:process:approval")
public R delete(@RequestBody WfTaskBo bo) {
@@ -99,7 +110,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "认领/签收任务")
+ /**
+ * 认领/签收任务
+ */
@PostMapping(value = "/claim")
@SaCheckPermission("workflow:process:claim")
public R claim(@RequestBody WfTaskBo bo) {
@@ -107,7 +120,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "取消认领/签收任务")
+ /**
+ * 取消认领/签收任务
+ */
@PostMapping(value = "/unClaim")
@SaCheckPermission("workflow:process:claim")
public R unClaim(@RequestBody WfTaskBo bo) {
@@ -115,7 +130,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "委派任务")
+ /**
+ * 委派任务
+ */
@PostMapping(value = "/delegate")
@SaCheckPermission("workflow:process:approval")
public R delegate(@RequestBody WfTaskBo bo) {
@@ -126,7 +143,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "转办任务")
+ /**
+ * 转办任务
+ */
@PostMapping(value = "/transfer")
@SaCheckPermission("workflow:process:approval")
public R transfer(@RequestBody WfTaskBo bo) {
@@ -137,7 +156,9 @@ public class WfTaskController {
return R.ok();
}
- @ApiOperation(value = "获取下一节点")
+ /**
+ * 获取下一节点
+ */
@PostMapping(value = "/nextFlowNode")
@SaCheckPermission("workflow:process:query")
public R getNextFlowNode(@RequestBody WfTaskBo bo) {
diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index 5ce9cd5f..5844a242 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -138,6 +138,8 @@ spring:
ssl: false
redisson:
+ # redis key前缀
+ keyPrefix:
# 线程池数量
threads: 4
# Netty线程池数量
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index def5f166..0987874f 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -5,7 +5,7 @@ spring.servlet.multipart.location: /ruoyi/server/temp
spring.boot.admin.client:
# 增加客户端开关
enabled: true
- url: http://172.30.0.90:9090/admin
+ url: http://localhost:9090/admin
instance:
service-host-type: IP
username: ruoyi
@@ -16,7 +16,7 @@ xxl.job:
# 执行器开关
enabled: true
# 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。
- admin-addresses: http://172.30.0.92:9100/xxl-job-admin
+ admin-addresses: http://localhost:9100/xxl-job-admin
# 执行器通讯TOKEN:非空时启用
access-token: xxl-job
executor:
@@ -51,7 +51,7 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
- url: jdbc:mysql://172.30.0.36:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
+ url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: root
password: root
# 从库数据源
@@ -63,19 +63,19 @@ spring:
password:
# oracle:
# driverClassName: oracle.jdbc.OracleDriver
-# url: jdbc:oracle:thin:@//172.30.0.36:1521/XE
+# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# druid:
# validationQuery: SELECT 1 FROM DUAL
# postgres:
# driverClassName: org.postgresql.Driver
-# url: jdbc:postgresql://172.30.0.36:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
+# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root
# password: root
# sqlserver:
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
-# url: jdbc:sqlserver://172.30.0.36:1433;DatabaseName=tempdb;SelectMethod=cursor;rewriteBatchedStatements=true
+# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;rewriteBatchedStatements=true
# username: SA
# password: root
druid:
@@ -128,7 +128,7 @@ spring.datasource.druid:
spring:
redis:
# 地址
- host: 172.30.0.48
+ host: localhost
# 端口,默认为6379
port: 6379
# 数据库索引
@@ -141,6 +141,8 @@ spring:
ssl: false
redisson:
+ # redis key前缀
+ keyPrefix:
# 线程池数量
threads: 16
# Netty线程池数量
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index a2a9f157..cfaccef2 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -53,6 +53,14 @@ logging:
org.springframework: warn
config: classpath:logback.xml
+# 用户配置
+user:
+ password:
+ # 密码最大错误次数
+ maxRetryCount: 5
+ # 密码锁定时间(默认10分钟)
+ lockTime: 10
+
# Spring配置
spring:
application:
@@ -75,10 +83,6 @@ spring:
restart:
# 热部署开关
enabled: true
- mvc:
- pathmatch:
- # 适配 boot 2.6 路由与 springfox 兼容
- matching-strategy: ANT_PATH_MATCHER
jackson:
# 日期格式化
date-format: yyyy-MM-dd HH:mm:ss
@@ -125,10 +129,8 @@ security:
- /**/*.js
# swagger 文档配置
- /favicon.ico
- - /doc.html
- - /swagger-resources/**
- - /webjars/**
- /*/api-docs
+ - /*/api-docs/**
# druid 监控配置
- /druid/**
# actuator 监控配置
@@ -183,46 +185,35 @@ mybatis-plus:
swagger:
# 是否开启swagger
enabled: true
- # 请求前缀
- pathMapping: /dev-api
- # 标题
- title: '标题:${ruoyi.name}后台管理系统_接口文档'
- # 描述
- description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
- # 版本
- version: '版本号: ${ruoyi-flowable-plus.version}'
- # 作者信息
- contact:
- name: Lion Li
- email: crazylionli@163.com
- url: https://gitee.com/JavaLionLi/RuoYi-Vue-Plus
- groups:
- - name: 1.演示案例
- basePackage: com.ruoyi.demo
- - name: 2.系统模块
- basePackage: com.ruoyi.web
- - name: 3.代码生成模块
- basePackage: com.ruoyi.generator
+ info:
+ # 标题
+ title: '标题:${ruoyi.name}后台管理系统_接口文档'
+ # 描述
+ description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
+ # 版本
+ version: '版本号: ${ruoyi-flowable-plus.version}'
+ # 作者信息
+ contact:
+ name: KonBAI
+ email: 1527468660@qq.com
+ url: https://gitee.com/KonBAI-Q/ruoyi-flowable-plus
+ components:
+ # 鉴权方式配置
+ security-schemes:
+ apiKey:
+ type: APIKEY
+ in: HEADER
+ name: ${sa-token.token-name}
-knife4j:
- # 是否开启Knife4j增强模式
- enable: true
- # 是否开启生产环境保护策略
- production: @knife4j.production@
- basic:
- enable: true
- username: ruoyi
- password: 123456
- # 前端Ui的个性化配置属性
- setting:
- # 默认语言
- language: zh-CN
- # 是否显示Footer
- enableFooter: false
- # 是否开启动态参数调试功能
- enableDynamicParameter: true
- # 是否在每个Debug调试栏后显示刷新变量按钮
- enableReloadCacheParameter: true
+springdoc:
+ #这里定义了两个分组,可定义多个,也可以不定义
+ group-configs:
+ - group: 1.演示模块
+ packages-to-scan: com.ruoyi.demo
+ - group: 2.系统模块
+ packages-to-scan: com.ruoyi.web
+ - group: 3.代码生成模块
+ packages-to-scan: com.ruoyi.generator
# 防止XSS攻击
xss:
@@ -242,26 +233,11 @@ thread-pool:
# 线程池维护线程所允许的空闲时间
keepAliveSeconds: 300
---- # redisson 缓存配置
-redisson:
- cacheGroup:
- # 用例: @Cacheable(cacheNames="groupId", key="#XXX") 方可使用缓存组配置
- - groupId: redissonCacheMap
- # 组过期时间(脚本监控)
- ttl: 60000
- # 组最大空闲时间(脚本监控)
- maxIdleTime: 60000
- # 组最大长度
- maxSize: 0
- - groupId: testCache
- ttl: 1000
- maxIdleTime: 500
-
--- # 分布式锁 lock4j 全局配置
lock4j:
# 获取分布式锁超时时间,默认为 3000 毫秒
acquire-timeout: 3000
- # 分布式锁的超时时间,默认为 30 毫秒
+ # 分布式锁的超时时间,默认为 30 秒
expire: 30000
--- # Actuator 监控端点的配置项
@@ -269,10 +245,10 @@ management:
endpoints:
web:
exposure:
- # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
- # 生产环境不建议放开所有 根据项目需求放开即可
- include: @endpoints.include@
+ include: '*'
endpoint:
+ health:
+ show-details: ALWAYS
logfile:
external-file: ./logs/sys-console.log
diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties
index ac1d8c23..e1423a8f 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages.properties
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
-user.password.retry.limit.exceed=密码错误次数过多,帐户锁定{0}分钟
+user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=角色已封禁,请联系管理员
@@ -41,5 +41,5 @@ repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=短信验证码输入错误{0}次
-sms.code.retry.limit.exceed=短信验证码错误次数过多,帐户锁定{0}分钟
+sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{0}分钟
xcx.code.not.blank=小程序code不能为空
diff --git a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
index 9076f79f..04a4aa37 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
@@ -5,7 +5,7 @@ user.jcaptcha.expire=Captcha invalid
user.not.exists=Sorry, your account: {0} does not exist
user.password.not.match=User does not exist/Password error
user.password.retry.limit.count=Password input error {0} times
-user.password.retry.limit.exceed=Too many password errors, account locked for {0} minutes
+user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes
user.password.delete=Sorry, your account:{0} has been deleted
user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator
role.blocked=Role disabled,please contact administrators
@@ -41,5 +41,5 @@ repeat.submit.message=Repeat submit is not allowed, please try again later
rate.limiter.message=Visit too frequently, please try again later
sms.code.not.blank=Sms code cannot be blank
sms.code.retry.limit.count=Sms code input error {0} times
-sms.code.retry.limit.exceed=Too many sms code errors, account locked for {0} minutes
+sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {0} minutes
xcx.code.not.blank=Mini program code cannot be blank
diff --git a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
index ac1d8c23..e1423a8f 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
-user.password.retry.limit.exceed=密码错误次数过多,帐户锁定{0}分钟
+user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=角色已封禁,请联系管理员
@@ -41,5 +41,5 @@ repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=短信验证码输入错误{0}次
-sms.code.retry.limit.exceed=短信验证码错误次数过多,帐户锁定{0}分钟
+sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{0}分钟
xcx.code.not.blank=小程序code不能为空
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 9fbde810..7028965c 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -5,7 +5,7 @@
ruoyi-flowable-plus
com.ruoyi
- 4.2.0
+ 4.3.0
4.0.0
@@ -126,13 +126,13 @@
- com.github.xiaoymin
- knife4j-spring-boot-starter
+ org.springdoc
+ springdoc-openapi-webmvc-core
- io.swagger
- swagger-annotations
+ org.springdoc
+ springdoc-openapi-javadoc
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java
index bd2ddece..df416edc 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java
@@ -5,6 +5,8 @@ import java.lang.annotation.*;
/**
* 数据权限
*
+ * 一个注解只能对应一个模板
+ *
* @author Lion Li
* @version 3.5.0
*/
@@ -16,11 +18,11 @@ public @interface DataColumn {
/**
* 占位符关键字
*/
- String key() default "deptName";
+ String[] key() default "deptName";
/**
* 占位符替换值
*/
- String value() default "dept_id";
+ String[] value() default "dept_id";
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java
index 23ca336f..2e3ff7a8 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java
@@ -1,6 +1,6 @@
package com.ruoyi.common.annotation;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.enums.LimitType;
import java.lang.annotation.*;
@@ -17,7 +17,7 @@ public @interface RateLimiter {
/**
* 限流key
*/
- String key() default Constants.RATE_LIMIT_KEY;
+ String key() default CacheConstants.RATE_LIMIT_KEY;
/**
* 限流时间,单位秒
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
new file mode 100644
index 00000000..1cdf07ee
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
@@ -0,0 +1,49 @@
+package com.ruoyi.common.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:";
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java
new file mode 100644
index 00000000..591ca254
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java
@@ -0,0 +1,48 @@
+package com.ruoyi.common.constant;
+
+/**
+ * 缓存组名称常量
+ *
+ * key 格式为 cacheNames#ttl#maxIdleTime#maxSize
+ *
+ * ttl 过期时间 如果设置为0则不过期 默认为0
+ * maxIdleTime 最大空闲时间 根据LRU算法清理空闲数据 如果设置为0则不检测 默认为0
+ * maxSize 组最大长度 根据LRU算法清理溢出数据 如果设置为0则无限长 默认为0
+ *
+ * 例子: 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";
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index e2ffebdc..e634ed29 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -17,6 +17,11 @@ public interface Constants {
*/
String GBK = "GBK";
+ /**
+ * www主域
+ */
+ String WWW = "www.";
+
/**
* http请求
*/
@@ -57,70 +62,15 @@ public interface Constants {
*/
String LOGIN_FAIL = "Error";
- /**
- * 验证码 redis key
- */
- String CAPTCHA_CODE_KEY = "captcha_codes:";
-
- /**
- * 登录用户 redis key
- */
- String LOGIN_TOKEN_KEY = "Authorization:login:token:";
-
- /**
- * 在线用户 redis key
- */
- String ONLINE_TOKEN_KEY = "online_tokens:";
-
- /**
- * 防重提交 redis key
- */
- String REPEAT_SUBMIT_KEY = "repeat_submit:";
-
- /**
- * 限流 redis key
- */
- String RATE_LIMIT_KEY = "rate_limit:";
-
/**
* 验证码有效期(分钟)
*/
Integer CAPTCHA_EXPIRATION = 2;
- /**
- * 登陆错误 redis key
- */
- String LOGIN_ERROR = "login_error:";
-
- /**
- * 登录错误次数
- */
- Integer LOGIN_ERROR_NUMBER = 5;
-
- /**
- * 登录错误限制时间(分钟)
- */
- Integer LOGIN_ERROR_LIMIT_TIME = 10;
-
/**
* 令牌
*/
String TOKEN = "token";
- /**
- * 令牌前缀
- */
- String LOGIN_USER_KEY = "login_user_key";
-
- /**
- * 参数管理 cache key
- */
- String SYS_CONFIG_KEY = "sys_config:";
-
- /**
- * 字典管理 cache key
- */
- String SYS_DICT_KEY = "sys_dict:";
-
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
index d1ad296f..5a20f9d0 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
@@ -2,7 +2,6 @@ package com.ruoyi.common.core.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -24,42 +23,36 @@ public class BaseEntity implements Serializable {
/**
* 搜索值
*/
- @ApiModelProperty(value = "搜索值")
@TableField(exist = false)
private String searchValue;
/**
* 创建者
*/
- @ApiModelProperty(value = "创建者")
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
- @ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新者
*/
- @ApiModelProperty(value = "更新者")
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 更新时间
*/
- @ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 请求参数
*/
- @ApiModelProperty(value = "请求参数")
@TableField(exist = false)
private Map params = new HashMap<>();
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/PageQuery.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/PageQuery.java
index 7a61237c..f3e2c4a5 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/PageQuery.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/PageQuery.java
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -24,25 +23,21 @@ public class PageQuery implements Serializable {
/**
* 分页大小
*/
- @ApiModelProperty("分页大小")
private Integer pageSize;
/**
* 当前页数
*/
- @ApiModelProperty("当前页数")
private Integer pageNum;
/**
* 排序列
*/
- @ApiModelProperty("排序列")
private String orderByColumn;
/**
* 排序的方向desc或者asc
*/
- @ApiModelProperty(value = "排序的方向", example = "asc,desc")
private String isAsc;
/**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java
index 7a242023..12dc16cb 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java
@@ -1,7 +1,5 @@
package com.ruoyi.common.core.domain;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -14,7 +12,6 @@ import java.io.Serializable;
*/
@Data
@NoArgsConstructor
-@ApiModel("请求响应对象")
public class R implements Serializable {
private static final long serialVersionUID = 1L;
@@ -28,13 +25,10 @@ public class R implements Serializable {
*/
public static final int FAIL = 500;
- @ApiModelProperty("消息状态码")
private int code;
- @ApiModelProperty("消息内容")
private String msg;
- @ApiModelProperty("数据对象")
private T data;
public static R ok() {
@@ -81,4 +75,11 @@ public class R implements Serializable {
return r;
}
+ public Boolean isError() {
+ return !isSuccess();
+ }
+
+ public Boolean isSuccess() {
+ return R.SUCCESS == getCode();
+ }
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java
index f44eacd4..c7bb9b4f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java
@@ -1,7 +1,6 @@
package com.ruoyi.common.core.domain;
import com.baomidou.mybatisplus.annotation.TableField;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -24,20 +23,17 @@ public class TreeEntity extends BaseEntity {
* 父菜单名称
*/
@TableField(exist = false)
- @ApiModelProperty(value = "父菜单名称")
private String parentName;
/**
* 父菜单ID
*/
- @ApiModelProperty(value = "父菜单ID")
private Long parentId;
/**
* 子部门
*/
@TableField(exist = false)
- @ApiModelProperty(value = "子部门")
private List children = new ArrayList<>();
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java
index 2dc3bdc4..857f9b8d 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java
@@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.TreeEntity;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -23,21 +21,18 @@ import javax.validation.constraints.Size;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_dept")
-@ApiModel("部门业务对象")
public class SysDept extends TreeEntity {
private static final long serialVersionUID = 1L;
/**
* 部门ID
*/
- @ApiModelProperty(value = "部门id")
@TableId(value = "dept_id")
private Long deptId;
/**
* 部门名称
*/
- @ApiModelProperty(value = "部门名称")
@NotBlank(message = "部门名称不能为空")
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
private String deptName;
@@ -45,27 +40,23 @@ public class SysDept extends TreeEntity {
/**
* 显示顺序
*/
- @ApiModelProperty(value = "显示顺序")
@NotNull(message = "显示顺序不能为空")
private Integer orderNum;
/**
* 负责人
*/
- @ApiModelProperty(value = "负责人")
private String leader;
/**
* 联系电话
*/
- @ApiModelProperty(value = "联系电话")
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
private String phone;
/**
* 邮箱
*/
- @ApiModelProperty(value = "邮箱")
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
private String email;
@@ -73,20 +64,17 @@ public class SysDept extends TreeEntity {
/**
* 部门状态:0正常,1停用
*/
- @ApiModelProperty(value = "部门状态:0正常,1停用")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
- @ApiModelProperty(value = "删除标志(0代表存在 2代表删除)")
@TableLogic
private String delFlag;
/**
* 祖级列表
*/
- @ApiModelProperty(value = "祖级列表")
private String ancestors;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
index c61c9172..e20f96aa 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
@@ -8,8 +8,6 @@ import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.common.core.domain.BaseEntity;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -26,13 +24,11 @@ import javax.validation.constraints.Size;
@EqualsAndHashCode(callSuper = true)
@TableName("sys_dict_data")
@ExcelIgnoreUnannotated
-@ApiModel("字典数据业务对象")
public class SysDictData extends BaseEntity {
/**
* 字典编码
*/
- @ApiModelProperty(value = "字典编码")
@ExcelProperty(value = "字典编码")
@TableId(value = "dict_code")
private Long dictCode;
@@ -40,14 +36,12 @@ public class SysDictData extends BaseEntity {
/**
* 字典排序
*/
- @ApiModelProperty(value = "字典排序")
@ExcelProperty(value = "字典排序")
private Integer dictSort;
/**
* 字典标签
*/
- @ApiModelProperty(value = "字典标签")
@ExcelProperty(value = "字典标签")
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
@@ -56,7 +50,6 @@ public class SysDictData extends BaseEntity {
/**
* 字典键值
*/
- @ApiModelProperty(value = "字典键值")
@ExcelProperty(value = "字典键值")
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
@@ -65,7 +58,6 @@ public class SysDictData extends BaseEntity {
/**
* 字典类型
*/
- @ApiModelProperty(value = "字典类型")
@ExcelProperty(value = "字典类型")
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
@@ -74,20 +66,17 @@ public class SysDictData extends BaseEntity {
/**
* 样式属性(其他样式扩展)
*/
- @ApiModelProperty(value = "样式属性(其他样式扩展)")
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
private String cssClass;
/**
* 表格字典样式
*/
- @ApiModelProperty(value = "表格字典样式")
private String listClass;
/**
* 是否默认(Y是 N否)
*/
- @ApiModelProperty(value = "是否默认(Y是 N否)")
@ExcelProperty(value = "是否默认", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_yes_no")
private String isDefault;
@@ -95,7 +84,6 @@ public class SysDictData extends BaseEntity {
/**
* 状态(0正常 1停用)
*/
- @ApiModelProperty(value = "状态(0正常 1停用)")
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
@@ -103,7 +91,6 @@ public class SysDictData extends BaseEntity {
/**
* 备注
*/
- @ApiModelProperty(value = "备注")
private String remark;
public boolean getDefault() {
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
index 942c2f97..36e38a97 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
@@ -7,11 +7,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.common.core.domain.BaseEntity;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@@ -27,13 +24,11 @@ import javax.validation.constraints.Size;
@EqualsAndHashCode(callSuper = true)
@TableName("sys_dict_type")
@ExcelIgnoreUnannotated
-@ApiModel("字典类型业务对象")
public class SysDictType extends BaseEntity {
/**
* 字典主键
*/
- @ApiModelProperty(value = "字典主键")
@ExcelProperty(value = "字典主键")
@TableId(value = "dict_id")
private Long dictId;
@@ -41,7 +36,6 @@ public class SysDictType extends BaseEntity {
/**
* 字典名称
*/
- @ApiModelProperty(value = "字典名称")
@ExcelProperty(value = "字典名称")
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
@@ -50,7 +44,6 @@ public class SysDictType extends BaseEntity {
/**
* 字典类型
*/
- @ApiModelProperty(value = "字典类型")
@ExcelProperty(value = "字典类型")
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@@ -60,7 +53,6 @@ public class SysDictType extends BaseEntity {
/**
* 状态(0正常 1停用)
*/
- @ApiModelProperty(value = "状态(0正常 1停用)")
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
@@ -68,7 +60,6 @@ public class SysDictType extends BaseEntity {
/**
* 备注
*/
- @ApiModelProperty(value = "备注")
private String remark;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
index cf337fbe..201605f9 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
@@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.ruoyi.common.core.domain.TreeEntity;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -22,20 +20,17 @@ import javax.validation.constraints.Size;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_menu")
-@ApiModel("菜单权限业务对象")
public class SysMenu extends TreeEntity {
/**
* 菜单ID
*/
- @ApiModelProperty(value = "菜单ID")
@TableId(value = "menu_id")
private Long menuId;
/**
* 菜单名称
*/
- @ApiModelProperty(value = "菜单名称")
@NotBlank(message = "菜单名称不能为空")
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
private String menuName;
@@ -43,65 +38,55 @@ public class SysMenu extends TreeEntity {
/**
* 显示顺序
*/
- @ApiModelProperty(value = "显示顺序")
@NotNull(message = "显示顺序不能为空")
private Integer orderNum;
/**
* 路由地址
*/
- @ApiModelProperty(value = "路由地址")
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
private String path;
/**
* 组件路径
*/
- @ApiModelProperty(value = "组件路径")
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
private String component;
/**
* 路由参数
*/
- @ApiModelProperty(value = "路由参数")
private String queryParam;
/**
* 是否为外链(0是 1否)
*/
- @ApiModelProperty(value = "是否为外链(0是 1否)")
private String isFrame;
/**
* 是否缓存(0缓存 1不缓存)
*/
- @ApiModelProperty(value = "是否缓存(0缓存 1不缓存)")
private String isCache;
/**
* 类型(M目录 C菜单 F按钮)
*/
- @ApiModelProperty(value = "类型(M目录 C菜单 F按钮)")
@NotBlank(message = "菜单类型不能为空")
private String menuType;
/**
* 显示状态(0显示 1隐藏)
*/
- @ApiModelProperty(value = "显示状态(0显示 1隐藏)")
private String visible;
/**
- * 菜单状态(0显示 1隐藏)
+ * 菜单状态(0正常 1停用)
*/
- @ApiModelProperty(value = "菜单状态(0显示 1隐藏)")
private String status;
/**
* 权限字符串
*/
- @ApiModelProperty(value = "权限字符串")
@JsonInclude(JsonInclude.Include.NON_NULL)
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
private String perms;
@@ -109,13 +94,11 @@ public class SysMenu extends TreeEntity {
/**
* 菜单图标
*/
- @ApiModelProperty(value = "菜单图标")
private String icon;
/**
* 备注
*/
- @ApiModelProperty(value = "备注")
private String remark;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
index 80481573..52682894 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
@@ -10,7 +10,6 @@ import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.common.core.domain.BaseEntity;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@@ -18,6 +17,7 @@ import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
+import java.util.Set;
/**
* 角色表 sys_role
@@ -35,7 +35,6 @@ public class SysRole extends BaseEntity {
/**
* 角色ID
*/
- @ApiModelProperty(value = "角色ID")
@ExcelProperty(value = "角色序号")
@TableId(value = "role_id")
private Long roleId;
@@ -43,7 +42,6 @@ public class SysRole extends BaseEntity {
/**
* 角色名称
*/
- @ApiModelProperty(value = "角色名称")
@ExcelProperty(value = "角色名称")
@NotBlank(message = "角色名称不能为空")
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
@@ -52,7 +50,6 @@ public class SysRole extends BaseEntity {
/**
* 角色权限
*/
- @ApiModelProperty(value = "角色权限")
@ExcelProperty(value = "角色权限")
@NotBlank(message = "权限字符不能为空")
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
@@ -61,7 +58,6 @@ public class SysRole extends BaseEntity {
/**
* 角色排序
*/
- @ApiModelProperty(value = "角色排序")
@ExcelProperty(value = "角色排序")
@NotNull(message = "显示顺序不能为空")
private Integer roleSort;
@@ -69,7 +65,6 @@ public class SysRole extends BaseEntity {
/**
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
*/
- @ApiModelProperty(value = "数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)")
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
private String dataScope;
@@ -77,62 +72,59 @@ public class SysRole extends BaseEntity {
/**
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)
*/
- @ApiModelProperty(value = "菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)")
private Boolean menuCheckStrictly;
/**
* 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 )
*/
- @ApiModelProperty(value = "部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 )")
private Boolean deptCheckStrictly;
/**
* 角色状态(0正常 1停用)
*/
- @ApiModelProperty(value = "角色状态(0正常 1停用)")
@ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class)
- @ExcelDictFormat(dictType = "sys_common_status")
+ @ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
- @ApiModelProperty(value = "删除标志(0代表存在 2代表删除)")
@TableLogic
private String delFlag;
/**
* 备注
*/
- @ApiModelProperty(value = "备注")
private String remark;
/**
* 用户是否存在此角色标识 默认不存在
*/
- @ApiModelProperty(value = "用户是否存在此角色标识 默认不存在")
@TableField(exist = false)
private boolean flag = false;
/**
* 菜单组
*/
- @ApiModelProperty(value = "菜单组")
@TableField(exist = false)
private Long[] menuIds;
/**
* 部门组(数据权限)
*/
- @ApiModelProperty(value = "部门组(数据权限)")
@TableField(exist = false)
private Long[] deptIds;
+ /**
+ * 角色菜单权限
+ */
+ @TableField(exist = false)
+ private Set permissions;
+
public SysRole(Long roleId) {
this.roleId = roleId;
}
- @ApiModelProperty(value = "是否管理员")
public boolean isAdmin() {
return UserConstants.ADMIN_ID.equals(this.roleId);
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
index 9aa75f7a..f2d961b7 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
@@ -1,15 +1,11 @@
package com.ruoyi.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.*;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.annotation.Sensitive;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.enums.SensitiveStrategy;
import com.ruoyi.common.xss.Xss;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@@ -30,26 +26,22 @@ import java.util.List;
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
-@ApiModel("用户信息业务对象")
public class SysUser extends BaseEntity {
/**
* 用户ID
*/
- @ApiModelProperty(value = "用户ID")
@TableId(value = "user_id")
private Long userId;
/**
* 部门ID
*/
- @ApiModelProperty(value = "部门ID")
private Long deptId;
/**
* 用户账号
*/
- @ApiModelProperty(value = "用户账号")
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
@@ -58,7 +50,6 @@ public class SysUser extends BaseEntity {
/**
* 用户昵称
*/
- @ApiModelProperty(value = "用户昵称")
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
private String nickName;
@@ -66,14 +57,12 @@ public class SysUser extends BaseEntity {
/**
* 用户类型(sys_user系统用户)
*/
- @ApiModelProperty(value = "用户类型")
private String userType;
/**
* 用户邮箱
*/
@Sensitive(strategy = SensitiveStrategy.EMAIL)
- @ApiModelProperty(value = "用户邮箱")
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
private String email;
@@ -82,25 +71,21 @@ public class SysUser extends BaseEntity {
* 手机号码
*/
@Sensitive(strategy = SensitiveStrategy.PHONE)
- @ApiModelProperty(value = "手机号码")
private String phonenumber;
/**
* 用户性别
*/
- @ApiModelProperty(value = "用户性别")
private String sex;
/**
* 用户头像
*/
- @ApiModelProperty(value = "用户头像")
private String avatar;
/**
* 密码
*/
- @ApiModelProperty(value = "密码")
@TableField(
insertStrategy = FieldStrategy.NOT_EMPTY,
updateStrategy = FieldStrategy.NOT_EMPTY,
@@ -111,66 +96,56 @@ public class SysUser extends BaseEntity {
/**
* 帐号状态(0正常 1停用)
*/
- @ApiModelProperty(value = "帐号状态(0正常 1停用)")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
- @ApiModelProperty(value = "删除标志(0代表存在 2代表删除)")
@TableLogic
private String delFlag;
/**
* 最后登录IP
*/
- @ApiModelProperty(value = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
- @ApiModelProperty(value = "最后登录时间")
private Date loginDate;
/**
* 备注
*/
- @ApiModelProperty(value = "备注")
private String remark;
/**
* 部门对象
*/
- @ApiModelProperty(value = "部门对象")
@TableField(exist = false)
private SysDept dept;
/**
* 角色对象
*/
- @ApiModelProperty(value = "角色对象")
@TableField(exist = false)
private List roles;
/**
* 角色组
*/
- @ApiModelProperty(value = "角色组")
@TableField(exist = false)
private Long[] roleIds;
/**
* 岗位组
*/
- @ApiModelProperty(value = "岗位组")
@TableField(exist = false)
private Long[] postIds;
/**
* 数据权限 当前角色ID
*/
- @ApiModelProperty(value = "角色ID")
@TableField(exist = false)
private Long roleId;
@@ -178,7 +153,6 @@ public class SysUser extends BaseEntity {
this.userId = userId;
}
- @ApiModelProperty(value = "是否管理员")
public boolean isAdmin() {
return UserConstants.ADMIN_ID.equals(this.userId);
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
index f13de971..4a4cfb51 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
@@ -1,8 +1,6 @@
package com.ruoyi.common.core.domain.model;
import com.ruoyi.common.constant.UserConstants;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
@@ -15,7 +13,6 @@ import javax.validation.constraints.NotBlank;
*/
@Data
-@ApiModel("用户登录对象")
public class LoginBody {
/**
@@ -23,7 +20,6 @@ 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}")
- @ApiModelProperty(value = "用户名")
private String username;
/**
@@ -31,19 +27,16 @@ public class LoginBody {
*/
@NotBlank(message = "{user.password.not.blank}")
@Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
- @ApiModelProperty(value = "用户密码")
private String password;
/**
* 验证码
*/
- @ApiModelProperty(value = "验证码")
private String code;
/**
* 唯一标识
*/
- @ApiModelProperty(value = "唯一标识")
private String uuid;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
index cad4f168..0b667861 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
@@ -110,6 +110,12 @@ public class LoginUser implements Serializable {
* 获取登录id
*/
public String getLoginId() {
+ if (userType == null) {
+ throw new IllegalArgumentException("用户类型不能为空");
+ }
+ if (userId == null) {
+ throw new IllegalArgumentException("用户ID不能为空");
+ }
return userType + LoginHelper.JOIN_CODE + userId;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java
index bd9b84cc..88367e7b 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java
@@ -1,7 +1,5 @@
package com.ruoyi.common.core.domain.model;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -12,10 +10,8 @@ import lombok.EqualsAndHashCode;
*/
@Data
@EqualsAndHashCode(callSuper = true)
-@ApiModel("用户注册对象")
public class RegisterBody extends LoginBody {
- @ApiModelProperty(value = "用户类型")
private String userType;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java
index f3ef445c..ce774ac7 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java
@@ -1,7 +1,5 @@
package com.ruoyi.common.core.domain.model;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@@ -13,21 +11,18 @@ import javax.validation.constraints.NotBlank;
*/
@Data
-@ApiModel("短信登录对象")
public class SmsLoginBody {
/**
* 用户名
*/
@NotBlank(message = "{user.phonenumber.not.blank}")
- @ApiModelProperty(value = "用户手机号")
private String phonenumber;
/**
* 用户密码
*/
@NotBlank(message = "{sms.code.not.blank}")
- @ApiModelProperty(value = "短信验证码")
private String smsCode;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mapper/BaseMapperPlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mapper/BaseMapperPlus.java
index 1ff35792..862887d1 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mapper/BaseMapperPlus.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mapper/BaseMapperPlus.java
@@ -149,7 +149,7 @@ public interface BaseMapperPlus extends BaseMapper {
return BeanCopyUtils.copy(obj, voClass);
}
- default List selectVoById(Collection extends Serializable> idList) {
+ default List selectVoBatchIds(Collection extends Serializable> idList) {
return selectVoBatchIds(idList, this.currentVoClass());
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java
index 48353e3e..5f3f2d1a 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java
@@ -2,11 +2,8 @@ package com.ruoyi.common.core.page;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.metadata.IPage;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
@@ -19,32 +16,27 @@ import java.util.List;
@Data
@NoArgsConstructor
-@ApiModel("分页响应对象")
public class TableDataInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
- @ApiModelProperty("总记录数")
private long total;
/**
* 列表数据
*/
- @ApiModelProperty("列表数据")
private List rows;
/**
* 消息状态码
*/
- @ApiModelProperty("消息状态码")
private int code;
/**
* 消息内容
*/
- @ApiModelProperty("消息内容")
private String msg;
/**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java
index 9936f676..6cd6d281 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java
@@ -6,6 +6,7 @@ import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.ValidatorUtils;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -14,7 +15,6 @@ import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* Excel 导入监听
@@ -69,9 +69,7 @@ public class DefaultExcelListener extends AnalysisEventListener implements
if (exception instanceof ConstraintViolationException) {
ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception;
Set> constraintViolations = constraintViolationException.getConstraintViolations();
- String constraintViolationsMsg = constraintViolations.stream()
- .map(ConstraintViolation::getMessage)
- .collect(Collectors.joining(", "));
+ String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", ");
errMsg = StrUtil.format("第{}行数据校验异常: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg);
if (log.isDebugEnabled()) {
log.error(errMsg);
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java
new file mode 100644
index 00000000..3d2b640e
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java
@@ -0,0 +1,16 @@
+package com.ruoyi.common.exception.user;
+
+/**
+ * 用户错误最大次数异常类
+ *
+ * @author ruoyi
+ */
+public class UserPasswordRetryLimitExceedException extends UserException {
+
+ private static final long serialVersionUID = 1L;
+
+ public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) {
+ super("user.password.retry.limit.exceed", retryLimitCount, lockTime);
+ }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
index b6fd0b65..ca76e76c 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
@@ -1,6 +1,7 @@
package com.ruoyi.common.filter;
import cn.hutool.core.io.IoUtil;
+import com.ruoyi.common.constant.Constants;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
@@ -23,8 +24,8 @@ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
super(request);
- request.setCharacterEncoding("UTF-8");
- response.setCharacterEncoding("UTF-8");
+ request.setCharacterEncoding(Constants.UTF8);
+ response.setCharacterEncoding(Constants.UTF8);
body = IoUtil.readUtf8(request.getInputStream()).getBytes(StandardCharsets.UTF_8);
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
index 72a8f274..5a087947 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
@@ -1,5 +1,6 @@
package com.ruoyi.common.filter;
+import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.utils.StringUtils;
import javax.servlet.*;
@@ -48,7 +49,7 @@ public class XssFilter implements Filter {
String url = request.getServletPath();
String method = request.getMethod();
// GET DELETE 不过滤
- if (method == null || method.matches("GET") || method.matches("DELETE")) {
+ if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) {
return true;
}
return StringUtils.matches(url, excludes);
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
index a8ffd66c..f1b51315 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
@@ -89,10 +89,9 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
/**
* 是否是Json请求
*
- * @param request
*/
public boolean isJsonRequest() {
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
}
-}
\ No newline at end of file
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java b/ruoyi-common/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java
index 404f393f..41e57816 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java
@@ -1,5 +1,6 @@
package com.ruoyi.common.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;
@@ -10,6 +11,8 @@ import com.ruoyi.common.annotation.Sensitive;
import com.ruoyi.common.core.service.SensitiveService;
import com.ruoyi.common.enums.SensitiveStrategy;
import com.ruoyi.common.utils.spring.SpringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
import java.io.IOException;
import java.util.Objects;
@@ -19,19 +22,24 @@ import java.util.Objects;
*
* @author Yjoioooo
*/
+@Slf4j
public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer {
private SensitiveStrategy strategy;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
- SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
- if (sensitiveService.isSensitive()) {
- gen.writeString(strategy.desensitizer().apply(value));
- } else {
+ 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
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java
index 93906046..88161daa 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java
@@ -14,7 +14,6 @@ import org.springframework.cglib.core.Converter;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
/**
* bean深拷贝工具(基于 cglib 性能优异)
@@ -79,11 +78,11 @@ public class BeanCopyUtils {
if (CollUtil.isEmpty(sourceList)) {
return CollUtil.newArrayList();
}
- return sourceList.stream().map(source -> {
+ return StreamUtils.toList(sourceList, source -> {
V target = ReflectUtil.newInstanceIfPossible(desc);
copy(source, target);
return target;
- }).collect(Collectors.toList());
+ });
}
/**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
index 446bf1b0..e5c471e5 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
@@ -6,6 +6,7 @@ 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 com.ruoyi.common.utils.spring.SpringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@@ -78,6 +79,9 @@ public class JsonUtils {
}
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);
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
index 6408c894..7012a01f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
@@ -3,6 +3,7 @@ package com.ruoyi.common.utils;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpStatus;
+import com.ruoyi.common.constant.Constants;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.http.MediaType;
@@ -14,6 +15,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
@@ -117,7 +121,7 @@ public class ServletUtils extends ServletUtil {
public static boolean isAjaxRequest(HttpServletRequest request) {
String accept = request.getHeader("accept");
- if (accept != null && accept.contains("application/json")) {
+ if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
return true;
}
@@ -139,4 +143,32 @@ public class ServletUtils extends ServletUtil {
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;
+ }
+ }
+
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/StreamUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StreamUtils.java
new file mode 100644
index 00000000..fccd9e3d
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StreamUtils.java
@@ -0,0 +1,251 @@
+package com.ruoyi.common.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 List filter(Collection collection, Predicate 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 String join(Collection collection, Function function) {
+ return join(collection, function, ",");
+ }
+
+ /**
+ * 将collection拼接
+ *
+ * @param collection 需要转化的集合
+ * @param function 拼接方法
+ * @param delimiter 拼接符
+ * @return 拼接后的list
+ */
+ public static String join(Collection collection, Function 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 List sorted(Collection collection, Comparator comparing) {
+ if (CollUtil.isEmpty(collection)) {
+ return CollUtil.newArrayList();
+ }
+ return collection.stream().sorted(comparing).collect(Collectors.toList());
+ }
+
+ /**
+ * 将collection转化为类型不变的map
+ * {@code Collection ----> Map}
+ *
+ * @param collection 需要转化的集合
+ * @param key V类型转化为K类型的lambda方法
+ * @param collection中的泛型
+ * @param map中的key类型
+ * @return 转化后的map
+ */
+ public static Map toIdentityMap(Collection collection, Function key) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
+ }
+
+ /**
+ * 将Collection转化为map(value类型与collection的泛型不同)
+ * {@code Collection -----> Map }
+ *
+ * @param collection 需要转化的集合
+ * @param key E类型转化为K类型的lambda方法
+ * @param value E类型转化为V类型的lambda方法
+ * @param collection中的泛型
+ * @param map中的key类型
+ * @param map中的value类型
+ * @return 转化后的map
+ */
+ public static Map toMap(Collection collection, Function key, Function value) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
+ }
+
+ /**
+ * 将collection按照规则(比如有相同的班级id)分类成map
+ * {@code Collection -------> Map> }
+ *
+ * @param collection 需要分类的集合
+ * @param key 分类的规则
+ * @param collection中的泛型
+ * @param map中的key类型
+ * @return 分类后的map
+ */
+ public static Map> groupByKey(Collection collection, Function key) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection
+ .stream()
+ .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
+ }
+
+ /**
+ * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
+ * {@code Collection ---> Map>> }
+ *
+ * @param collection 需要分类的集合
+ * @param key1 第一个分类的规则
+ * @param key2 第二个分类的规则
+ * @param 集合元素类型
+ * @param 第一个map中的key类型
+ * @param 第二个map中的key类型
+ * @return 分类后的map
+ */
+ public static Map>> groupBy2Key(Collection collection, Function key1, Function