chore(build): 更新项目依赖版本并优化代码格式
- 升级 Spring Boot 父项目版本至 3.5.9 - 更新 MySQL 连接器版本至 9.4.0 - 更新 MyBatis-Plus 版本至 3.5.14 - 更新 Fastjson2 版本至 2.0.59 - 更新 Hutool 版本至 5.8.41 - 更新 JJWT 版本至 0.12.6 - 更新 Knife4j 版本至 4.5.0 - 更新 Undertow 版本至 2.3.20.Final - 更新 Oshi 版本至 6.6.5 - 更新 Guava 版本至 33.5.0-jre - 格式化注解文件中的代码缩进 - 移除多余的空行和注释格式调整
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>cutejava</artifactId>
|
||||
<groupId>cn.odboy</groupId>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cutejava-module-system</artifactId>
|
||||
<name>核心模块</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.odboy</groupId>
|
||||
<artifactId>cutejava-framework</artifactId>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.minio/minio -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>8.5.17</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>cutejava</artifactId>
|
||||
<groupId>cn.odboy</groupId>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cutejava-module-system</artifactId>
|
||||
<name>核心模块</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.odboy</groupId>
|
||||
<artifactId>cutejava-framework</artifactId>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.minio/minio -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>8.5.17</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+31
-31
@@ -24,37 +24,37 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SystemCaptchaBizEnum {
|
||||
/* 通过手机号码重置邮箱 */
|
||||
PHONE_RESET_EMAIL_CODE("10000", "phone_reset_email_code_", "SystemEmailCaptchaTemplate.ftl",
|
||||
"通过手机号码重置邮箱"), /* 通过旧邮箱重置邮箱 */
|
||||
EMAIL_RESET_EMAIL_CODE("10001", "email_reset_email_code_", "SystemEmailCaptchaTemplate.ftl", "通过旧邮箱重置邮箱"),
|
||||
/* 通过手机号码重置密码 */
|
||||
PHONE_RESET_PWD_CODE("10002", "phone_reset_pwd_code_", "SystemEmailCaptchaTemplate.ftl", "通过手机号码重置密码"),
|
||||
/* 通过邮箱重置密码 */
|
||||
EMAIL_RESET_PWD_CODE("10003", "email_reset_pwd_code_", "SystemEmailCaptchaTemplate.ftl", "通过邮箱重置密码");
|
||||
/**
|
||||
* 业务编码
|
||||
*/
|
||||
private final String bizCode;
|
||||
/**
|
||||
* redis中的key
|
||||
*/
|
||||
private final String redisKey;
|
||||
/**
|
||||
* resources文件夹,template中的模版名称
|
||||
*/
|
||||
private final String templateName;
|
||||
/**
|
||||
* 业务描述
|
||||
*/
|
||||
private final String description;
|
||||
/* 通过手机号码重置邮箱 */
|
||||
PHONE_RESET_EMAIL_CODE("10000", "phone_reset_email_code_", "SystemEmailCaptchaTemplate.ftl",
|
||||
"通过手机号码重置邮箱"), /* 通过旧邮箱重置邮箱 */
|
||||
EMAIL_RESET_EMAIL_CODE("10001", "email_reset_email_code_", "SystemEmailCaptchaTemplate.ftl", "通过旧邮箱重置邮箱"),
|
||||
/* 通过手机号码重置密码 */
|
||||
PHONE_RESET_PWD_CODE("10002", "phone_reset_pwd_code_", "SystemEmailCaptchaTemplate.ftl", "通过手机号码重置密码"),
|
||||
/* 通过邮箱重置密码 */
|
||||
EMAIL_RESET_PWD_CODE("10003", "email_reset_pwd_code_", "SystemEmailCaptchaTemplate.ftl", "通过邮箱重置密码");
|
||||
/**
|
||||
* 业务编码
|
||||
*/
|
||||
private final String bizCode;
|
||||
/**
|
||||
* redis中的key
|
||||
*/
|
||||
private final String redisKey;
|
||||
/**
|
||||
* resources文件夹,template中的模版名称
|
||||
*/
|
||||
private final String templateName;
|
||||
/**
|
||||
* 业务描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
public static SystemCaptchaBizEnum getByBizCode(String bizCode) {
|
||||
for (SystemCaptchaBizEnum value : SystemCaptchaBizEnum.values()) {
|
||||
if (value.getBizCode().equals(bizCode)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public static SystemCaptchaBizEnum getByBizCode(String bizCode) {
|
||||
for (SystemCaptchaBizEnum value : SystemCaptchaBizEnum.values()) {
|
||||
if (value.getBizCode().equals(bizCode)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -24,19 +24,19 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SystemDataScopeEnum {
|
||||
/* 全部的数据权限 */
|
||||
ALL("全部", "全部的数据权限"), /* 自己部门的数据权限 */
|
||||
THIS_LEVEL("本级", "自己部门的数据权限"), /* 自定义的数据权限 */
|
||||
CUSTOMIZE("自定义", "自定义的数据权限");
|
||||
private final String value;
|
||||
private final String description;
|
||||
/* 全部的数据权限 */
|
||||
ALL("全部", "全部的数据权限"), /* 自己部门的数据权限 */
|
||||
THIS_LEVEL("本级", "自己部门的数据权限"), /* 自定义的数据权限 */
|
||||
CUSTOMIZE("自定义", "自定义的数据权限");
|
||||
private final String value;
|
||||
private final String description;
|
||||
|
||||
public static SystemDataScopeEnum find(String val) {
|
||||
for (SystemDataScopeEnum dataScopeEnum : SystemDataScopeEnum.values()) {
|
||||
if (dataScopeEnum.getValue().equals(val)) {
|
||||
return dataScopeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public static SystemDataScopeEnum find(String val) {
|
||||
for (SystemDataScopeEnum dataScopeEnum : SystemDataScopeEnum.values()) {
|
||||
if (dataScopeEnum.getValue().equals(val)) {
|
||||
return dataScopeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@ package cn.odboy.system.constant;
|
||||
|
||||
public interface TransferProtocolConst {
|
||||
|
||||
String PREFIX_HTTP = "http://";
|
||||
String PREFIX_HTTPS = "https://";
|
||||
String PREFIX_HTTPS_BAD_REQUEST = "外链必须以http://或者https://开头";
|
||||
String PREFIX_HTTP = "http://";
|
||||
String PREFIX_HTTPS = "https://";
|
||||
String PREFIX_HTTPS_BAD_REQUEST = "外链必须以http://或者https://开头";
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,8 +21,8 @@ import cn.odboy.system.dal.model.SystemUserLoginArgs;
|
||||
import cn.odboy.system.service.SystemAuthService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import java.util.Map;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
+1
-1
@@ -24,9 +24,9 @@ import cn.odboy.system.service.SystemDeptService;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
+1
-1
@@ -24,10 +24,10 @@ import cn.odboy.system.service.SystemDictService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
+1
-1
@@ -24,9 +24,9 @@ import cn.odboy.system.service.SystemJobService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
+1
-1
@@ -23,8 +23,8 @@ import cn.odboy.system.service.SystemLocalStorageService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import java.io.IOException;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
-3
@@ -21,7 +21,6 @@ import cn.odboy.framework.exception.BadRequestException;
|
||||
import cn.odboy.system.dal.dataobject.SystemMenuTb;
|
||||
import cn.odboy.system.dal.model.SystemMenuVo;
|
||||
import cn.odboy.system.dal.model.SystemQueryMenuArgs;
|
||||
import cn.odboy.system.dal.mysql.SystemMenuMapper;
|
||||
import cn.odboy.system.service.SystemMenuService;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -47,8 +46,6 @@ public class SystemMenuController {
|
||||
|
||||
@Autowired
|
||||
private SystemMenuService systemMenuService;
|
||||
@Autowired
|
||||
private SystemMenuMapper systemMenuMapper;
|
||||
|
||||
@ApiOperation("导出菜单数据")
|
||||
@GetMapping(value = "/download")
|
||||
|
||||
+1
-1
@@ -23,10 +23,10 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
+1
-1
@@ -24,8 +24,8 @@ import cn.odboy.system.service.SystemOssStorageService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import java.io.IOException;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
+1
-1
@@ -25,9 +25,9 @@ import cn.odboy.system.service.SystemQuartzJobService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
+1
-1
@@ -26,10 +26,10 @@ import cn.odboy.system.service.SystemRoleService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
+1
-7
@@ -23,16 +23,14 @@ import cn.odboy.system.dal.model.SystemQueryUserArgs;
|
||||
import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs;
|
||||
import cn.odboy.system.dal.model.SystemUserVo;
|
||||
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
|
||||
import cn.odboy.system.service.SystemDataService;
|
||||
import cn.odboy.system.service.SystemDeptService;
|
||||
import cn.odboy.system.service.SystemUserService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
@@ -53,10 +51,6 @@ public class SystemUserController {
|
||||
|
||||
@Autowired
|
||||
private SystemUserService systemUserService;
|
||||
@Autowired
|
||||
private SystemDataService systemDataService;
|
||||
@Autowired
|
||||
private SystemDeptService systemDeptService;
|
||||
|
||||
|
||||
@ApiOperation("导出用户数据")
|
||||
|
||||
+50
-36
@@ -35,46 +35,60 @@ import lombok.Setter;
|
||||
@TableName("system_dept")
|
||||
public class SystemDeptTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = Update.class) @TableId(value = "dept_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@TableField(exist = false) @JSONField(serialize = false) @ApiModelProperty(value = "角色") private Set<SystemRoleTb>
|
||||
roles;
|
||||
@TableField(exist = false) @ApiModelProperty(value = "子部门") private List<SystemDeptTb> children;
|
||||
@ApiModelProperty(value = "排序") private Integer deptSort;
|
||||
@NotBlank @ApiModelProperty(value = "部门名称") private String name;
|
||||
@NotNull @ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@ApiModelProperty(value = "上级部门") private Long pid;
|
||||
@ApiModelProperty(value = "子节点数目", hidden = true) private Integer subCount = 0;
|
||||
@NotNull(groups = Update.class)
|
||||
@TableId(value = "dept_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@TableField(exist = false)
|
||||
@JSONField(serialize = false)
|
||||
@ApiModelProperty(value = "角色")
|
||||
private Set<SystemRoleTb>
|
||||
roles;
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "子部门")
|
||||
private List<SystemDeptTb> children;
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer deptSort;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "部门名称")
|
||||
private String name;
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
@ApiModelProperty(value = "上级部门")
|
||||
private Long pid;
|
||||
@ApiModelProperty(value = "子节点数目", hidden = true)
|
||||
private Integer subCount = 0;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemDeptTb dept = (SystemDeptTb)o;
|
||||
return Objects.equals(id, dept.id) && Objects.equals(name, dept.name);
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemDeptTb dept = (SystemDeptTb) o;
|
||||
return Objects.equals(id, dept.id) && Objects.equals(name, dept.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name);
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "是否有子节点")
|
||||
public Boolean getHasChildren() {
|
||||
return subCount > 0;
|
||||
}
|
||||
@ApiModelProperty(value = "是否有子节点")
|
||||
public Boolean getHasChildren() {
|
||||
return subCount > 0;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "是否为叶子")
|
||||
public Boolean getLeaf() {
|
||||
return subCount <= 0;
|
||||
}
|
||||
@ApiModelProperty(value = "是否为叶子")
|
||||
public Boolean getLeaf() {
|
||||
return subCount <= 0;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "标签名称")
|
||||
public String getLabel() {
|
||||
return name;
|
||||
}
|
||||
@ApiModelProperty(value = "标签名称")
|
||||
public String getLabel() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
+13
-6
@@ -30,10 +30,17 @@ import lombok.Setter;
|
||||
@TableName("system_dict_detail")
|
||||
public class SystemDictDetailTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = Update.class) @ApiModelProperty(value = "ID", hidden = true)
|
||||
@TableId(value = "id", type = IdType.AUTO) private Long id;
|
||||
@TableField(value = "dict_id") @ApiModelProperty(hidden = true) private Long dictId;
|
||||
@ApiModelProperty(value = "字典标签") private String label;
|
||||
@ApiModelProperty(value = "字典值") private String value;
|
||||
@ApiModelProperty(value = "排序") private Integer dictSort = 999;
|
||||
@NotNull(groups = Update.class)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
@TableField(value = "dict_id")
|
||||
@ApiModelProperty(hidden = true)
|
||||
private Long dictId;
|
||||
@ApiModelProperty(value = "字典标签")
|
||||
private String label;
|
||||
@ApiModelProperty(value = "字典值")
|
||||
private String value;
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer dictSort = 999;
|
||||
}
|
||||
+10
-4
@@ -32,8 +32,14 @@ import lombok.Setter;
|
||||
@TableName("system_dict")
|
||||
public class SystemDictTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = Update.class) @ApiModelProperty(value = "ID", hidden = true)
|
||||
@TableId(value = "id", type = IdType.AUTO) private Long id;
|
||||
@NotBlank @ApiModelProperty(value = "名称") private String name;
|
||||
@ApiModelProperty(value = "描述") @TableField(updateStrategy = FieldStrategy.ALWAYS) private String description;
|
||||
@NotNull(groups = Update.class)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "名称")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "描述")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String description;
|
||||
}
|
||||
+17
-6
@@ -31,10 +31,21 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemEmailConfigTb extends KitObject {
|
||||
|
||||
@TableId("config_id") private Long id;
|
||||
@NotBlank @ApiModelProperty(value = "邮件服务器SMTP地址") private String host;
|
||||
@NotBlank @ApiModelProperty(value = "邮件服务器 SMTP 端口") private String port;
|
||||
@NotBlank @ApiModelProperty(value = "发件者用户名") private String user;
|
||||
@NotBlank @ApiModelProperty(value = "密码") private String password;
|
||||
@NotBlank @ApiModelProperty(value = "收件人") private String fromUser;
|
||||
@TableId("config_id")
|
||||
private Long id;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "邮件服务器SMTP地址")
|
||||
private String host;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "邮件服务器 SMTP 端口")
|
||||
private String port;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "发件者用户名")
|
||||
private String user;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "收件人")
|
||||
private String fromUser;
|
||||
}
|
||||
|
||||
+27
-19
@@ -31,26 +31,34 @@ import lombok.Setter;
|
||||
@TableName("system_job")
|
||||
public class SystemJobTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = Update.class) @TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@NotBlank @ApiModelProperty(value = "岗位名称") private String name;
|
||||
@NotNull @ApiModelProperty(value = "岗位排序") private Long jobSort;
|
||||
@NotNull @ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@NotNull(groups = Update.class)
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "岗位名称")
|
||||
private String name;
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "岗位排序")
|
||||
private Long jobSort;
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemJobTb job = (SystemJobTb)o;
|
||||
return Objects.equals(id, job.id);
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemJobTb job = (SystemJobTb) o;
|
||||
return Objects.equals(id, job.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
}
|
||||
+20
-11
@@ -30,16 +30,25 @@ import lombok.Setter;
|
||||
@TableName("system_local_storage")
|
||||
public class SystemLocalStorageTb extends KitBaseUserTimeTb {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO) @ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@ApiModelProperty(value = "真实文件名") private String realName;
|
||||
@ApiModelProperty(value = "文件名") private String name;
|
||||
@ApiModelProperty(value = "后缀") private String suffix;
|
||||
@ApiModelProperty(value = "路径") private String path;
|
||||
@ApiModelProperty(value = "类型") private String type;
|
||||
@ApiModelProperty(value = "大小") private String size;
|
||||
@ApiModelProperty(value = "日期分组") private String dateGroup;
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@ApiModelProperty(value = "真实文件名")
|
||||
private String realName;
|
||||
@ApiModelProperty(value = "文件名")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "后缀")
|
||||
private String suffix;
|
||||
@ApiModelProperty(value = "路径")
|
||||
private String path;
|
||||
@ApiModelProperty(value = "类型")
|
||||
private String type;
|
||||
@ApiModelProperty(value = "大小")
|
||||
private String size;
|
||||
@ApiModelProperty(value = "日期分组")
|
||||
private String dateGroup;
|
||||
|
||||
public void copy(SystemLocalStorageTb source) {
|
||||
BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
public void copy(SystemLocalStorageTb source) {
|
||||
BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
}
|
||||
+63
-44
@@ -34,54 +34,73 @@ import lombok.Setter;
|
||||
@TableName("system_menu")
|
||||
public class SystemMenuTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = {Update.class}) @TableId(value = "menu_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@TableField(exist = false) @JSONField(serialize = false) @ApiModelProperty(value = "菜单角色")
|
||||
private Set<SystemRoleTb> roles;
|
||||
@TableField(exist = false) private List<SystemMenuTb> children;
|
||||
@ApiModelProperty(value = "菜单标题") private String title;
|
||||
@TableField(value = "name") @ApiModelProperty(value = "菜单组件名称") private String componentName;
|
||||
@ApiModelProperty(value = "排序") private Integer menuSort = 999;
|
||||
@ApiModelProperty(value = "组件路径") private String component;
|
||||
@ApiModelProperty(value = "路由地址") private String path;
|
||||
@ApiModelProperty(value = "菜单类型,目录、菜单、按钮") private Integer type;
|
||||
@ApiModelProperty(value = "权限标识") private String permission;
|
||||
@ApiModelProperty(value = "菜单图标") private String icon;
|
||||
@ApiModelProperty(value = "缓存") private Boolean cache;
|
||||
@ApiModelProperty(value = "是否隐藏") private Boolean hidden;
|
||||
@ApiModelProperty(value = "上级菜单") private Long pid;
|
||||
@ApiModelProperty(value = "子节点数目", hidden = true) private Integer subCount = 0;
|
||||
@ApiModelProperty(value = "外链菜单") private Boolean iFrame;
|
||||
@NotNull(groups = {Update.class})
|
||||
@TableId(value = "menu_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@TableField(exist = false)
|
||||
@JSONField(serialize = false)
|
||||
@ApiModelProperty(value = "菜单角色")
|
||||
private Set<SystemRoleTb> roles;
|
||||
@TableField(exist = false)
|
||||
private List<SystemMenuTb> children;
|
||||
@ApiModelProperty(value = "菜单标题")
|
||||
private String title;
|
||||
@TableField(value = "name")
|
||||
@ApiModelProperty(value = "菜单组件名称")
|
||||
private String componentName;
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer menuSort = 999;
|
||||
@ApiModelProperty(value = "组件路径")
|
||||
private String component;
|
||||
@ApiModelProperty(value = "路由地址")
|
||||
private String path;
|
||||
@ApiModelProperty(value = "菜单类型,目录、菜单、按钮")
|
||||
private Integer type;
|
||||
@ApiModelProperty(value = "权限标识")
|
||||
private String permission;
|
||||
@ApiModelProperty(value = "菜单图标")
|
||||
private String icon;
|
||||
@ApiModelProperty(value = "缓存")
|
||||
private Boolean cache;
|
||||
@ApiModelProperty(value = "是否隐藏")
|
||||
private Boolean hidden;
|
||||
@ApiModelProperty(value = "上级菜单")
|
||||
private Long pid;
|
||||
@ApiModelProperty(value = "子节点数目", hidden = true)
|
||||
private Integer subCount = 0;
|
||||
@ApiModelProperty(value = "外链菜单")
|
||||
private Boolean iFrame;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemMenuTb menu = (SystemMenuTb)o;
|
||||
return Objects.equals(id, menu.id);
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemMenuTb menu = (SystemMenuTb) o;
|
||||
return Objects.equals(id, menu.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "是否有子节点")
|
||||
public Boolean getHasChildren() {
|
||||
return subCount > 0;
|
||||
}
|
||||
@ApiModelProperty(value = "是否有子节点")
|
||||
public Boolean getHasChildren() {
|
||||
return subCount > 0;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "是否为叶子")
|
||||
public Boolean getLeaf() {
|
||||
return subCount <= 0;
|
||||
}
|
||||
@ApiModelProperty(value = "是否为叶子")
|
||||
public Boolean getLeaf() {
|
||||
return subCount <= 0;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "标签名称")
|
||||
public String getLabel() {
|
||||
return title;
|
||||
}
|
||||
@ApiModelProperty(value = "标签名称")
|
||||
public String getLabel() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
+56
-44
@@ -43,48 +43,60 @@ import lombok.ToString;
|
||||
@ApiModel(value = "SystemOperationLog对象", description = "审计日志")
|
||||
public class SystemOperationLogTb extends KitObject {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@ApiModelProperty("id") @TableId(value = "id", type = IdType.AUTO) private Long id;
|
||||
/**
|
||||
* 业务名称
|
||||
*/
|
||||
@TableField("biz_name") private String bizName;
|
||||
/**
|
||||
* 业务方法
|
||||
*/
|
||||
@TableField("method") private String method;
|
||||
/**
|
||||
* 业务参数
|
||||
*/
|
||||
@TableField("params") private String params;
|
||||
/**
|
||||
* 访问来源IP
|
||||
*/
|
||||
@TableField("request_ip") private String requestIp;
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
@TableField("execute_time") private Long executeTime;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@TableField("username") private String username;
|
||||
/**
|
||||
* 访问来源地址
|
||||
*/
|
||||
@TableField("address") private String address;
|
||||
/**
|
||||
* 浏览器信息
|
||||
*/
|
||||
@TableField("browser_info") private String browserInfo;
|
||||
/**
|
||||
* 异常详情
|
||||
*/
|
||||
@TableField("exception_detail") private String exceptionDetail;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@ApiModelProperty("id")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
/**
|
||||
* 业务名称
|
||||
*/
|
||||
@TableField("biz_name")
|
||||
private String bizName;
|
||||
/**
|
||||
* 业务方法
|
||||
*/
|
||||
@TableField("method")
|
||||
private String method;
|
||||
/**
|
||||
* 业务参数
|
||||
*/
|
||||
@TableField("params")
|
||||
private String params;
|
||||
/**
|
||||
* 访问来源IP
|
||||
*/
|
||||
@TableField("request_ip")
|
||||
private String requestIp;
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
@TableField("execute_time")
|
||||
private Long executeTime;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@TableField("username")
|
||||
private String username;
|
||||
/**
|
||||
* 访问来源地址
|
||||
*/
|
||||
@TableField("address")
|
||||
private String address;
|
||||
/**
|
||||
* 浏览器信息
|
||||
*/
|
||||
@TableField("browser_info")
|
||||
private String browserInfo;
|
||||
/**
|
||||
* 异常详情
|
||||
*/
|
||||
@TableField("exception_detail")
|
||||
private String exceptionDetail;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
}
|
||||
|
||||
+39
-13
@@ -39,17 +39,43 @@ import lombok.Setter;
|
||||
@ApiModel(value = "SystemOssStorage对象", description = "OSS存储")
|
||||
public class SystemOssStorageTb extends KitBaseUserTimeTb {
|
||||
|
||||
@ApiModelProperty("ID") @TableId(value = "id", type = IdType.AUTO) private Long id;
|
||||
@TableField("service_type") @ApiModelProperty("类型,比如minio") private String serviceType;
|
||||
@TableField("endpoint") @ApiModelProperty("服务地址") private String endpoint;
|
||||
@TableField("bucket_name") @ApiModelProperty("存储桶名称") private String bucketName;
|
||||
@TableField("file_name") @ApiModelProperty("完整文件名称") private String fileName;
|
||||
@TableField("file_size") @ApiModelProperty("文件大小, 单位:字节") private Long fileSize;
|
||||
@TableField("file_mime") @ApiModelProperty("文件类型") private String fileMime;
|
||||
@ApiModelProperty("短文件名") @TableField("file_prefix") private String filePrefix;
|
||||
@ApiModelProperty("文件后缀") @TableField("file_suffix") private String fileSuffix;
|
||||
@TableField("file_md5") @ApiModelProperty("文件md5") private String fileMd5;
|
||||
@TableField("file_url") @ApiModelProperty("文件链接") private String fileUrl;
|
||||
@TableField("file_code") @ApiModelProperty("文件编码") private String fileCode;
|
||||
@TableField("object_name") @ApiModelProperty("对象路径") private String objectName;
|
||||
@ApiModelProperty("ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
@TableField("service_type")
|
||||
@ApiModelProperty("类型,比如minio")
|
||||
private String serviceType;
|
||||
@TableField("endpoint")
|
||||
@ApiModelProperty("服务地址")
|
||||
private String endpoint;
|
||||
@TableField("bucket_name")
|
||||
@ApiModelProperty("存储桶名称")
|
||||
private String bucketName;
|
||||
@TableField("file_name")
|
||||
@ApiModelProperty("完整文件名称")
|
||||
private String fileName;
|
||||
@TableField("file_size")
|
||||
@ApiModelProperty("文件大小, 单位:字节")
|
||||
private Long fileSize;
|
||||
@TableField("file_mime")
|
||||
@ApiModelProperty("文件类型")
|
||||
private String fileMime;
|
||||
@ApiModelProperty("短文件名")
|
||||
@TableField("file_prefix")
|
||||
private String filePrefix;
|
||||
@ApiModelProperty("文件后缀")
|
||||
@TableField("file_suffix")
|
||||
private String fileSuffix;
|
||||
@TableField("file_md5")
|
||||
@ApiModelProperty("文件md5")
|
||||
private String fileMd5;
|
||||
@TableField("file_url")
|
||||
@ApiModelProperty("文件链接")
|
||||
private String fileUrl;
|
||||
@TableField("file_code")
|
||||
@ApiModelProperty("文件编码")
|
||||
private String fileCode;
|
||||
@TableField("object_name")
|
||||
@ApiModelProperty("对象路径")
|
||||
private String objectName;
|
||||
}
|
||||
|
||||
+35
-15
@@ -32,19 +32,39 @@ import lombok.Setter;
|
||||
@TableName("system_quartz_job")
|
||||
public class SystemQuartzJobTb extends KitBaseUserTimeTb {
|
||||
|
||||
public static final String JOB_KEY = "JOB_KEY";
|
||||
@TableId(value = "id", type = IdType.AUTO) @NotNull(groups = {Update.class}) private Long id;
|
||||
@TableField(exist = false) @ApiModelProperty(value = "用于子任务唯一标识", hidden = true) private String uuid;
|
||||
@ApiModelProperty(value = "定时器名称") private String jobName;
|
||||
@NotBlank @ApiModelProperty(value = "Bean名称") private String beanName;
|
||||
@NotBlank @ApiModelProperty(value = "方法名称") private String methodName;
|
||||
@ApiModelProperty(value = "参数") private String params;
|
||||
@NotBlank @ApiModelProperty(value = "cron表达式") private String cronExpression;
|
||||
@ApiModelProperty(value = "状态:暂停或启动") private Boolean isPause = false;
|
||||
@ApiModelProperty(value = "负责人") private String personInCharge;
|
||||
@ApiModelProperty(value = "报警邮箱") private String email;
|
||||
@ApiModelProperty(value = "子任务") private String subTask;
|
||||
@ApiModelProperty(value = "失败后暂停") private Boolean pauseAfterFailure;
|
||||
@NotBlank @ApiModelProperty(value = "备注") @TableField(updateStrategy = FieldStrategy.ALWAYS) private String
|
||||
description;
|
||||
public static final String JOB_KEY = "JOB_KEY";
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@NotNull(groups = {Update.class})
|
||||
private Long id;
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "用于子任务唯一标识", hidden = true)
|
||||
private String uuid;
|
||||
@ApiModelProperty(value = "定时器名称")
|
||||
private String jobName;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "Bean名称")
|
||||
private String beanName;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "方法名称")
|
||||
private String methodName;
|
||||
@ApiModelProperty(value = "参数")
|
||||
private String params;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "cron表达式")
|
||||
private String cronExpression;
|
||||
@ApiModelProperty(value = "状态:暂停或启动")
|
||||
private Boolean isPause = false;
|
||||
@ApiModelProperty(value = "负责人")
|
||||
private String personInCharge;
|
||||
@ApiModelProperty(value = "报警邮箱")
|
||||
private String email;
|
||||
@ApiModelProperty(value = "子任务")
|
||||
private String subTask;
|
||||
@ApiModelProperty(value = "失败后暂停")
|
||||
private Boolean pauseAfterFailure;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "备注")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String
|
||||
description;
|
||||
}
|
||||
+22
-10
@@ -31,14 +31,26 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemQuartzLogTb extends KitObject {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO) @ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@ApiModelProperty(value = "任务名称", hidden = true) private String jobName;
|
||||
@ApiModelProperty(value = "bean名称", hidden = true) private String beanName;
|
||||
@ApiModelProperty(value = "方法名称", hidden = true) private String methodName;
|
||||
@ApiModelProperty(value = "参数", hidden = true) private String params;
|
||||
@ApiModelProperty(value = "cron表达式", hidden = true) private String cronExpression;
|
||||
@ApiModelProperty(value = "状态", hidden = true) private Boolean isSuccess;
|
||||
@ApiModelProperty(value = "异常详情", hidden = true) private String exceptionDetail;
|
||||
@ApiModelProperty(value = "执行耗时", hidden = true) private Long time;
|
||||
@TableField(fill = FieldFill.INSERT) @ApiModelProperty(value = "创建时间", hidden = true) private Date createTime;
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@ApiModelProperty(value = "任务名称", hidden = true)
|
||||
private String jobName;
|
||||
@ApiModelProperty(value = "bean名称", hidden = true)
|
||||
private String beanName;
|
||||
@ApiModelProperty(value = "方法名称", hidden = true)
|
||||
private String methodName;
|
||||
@ApiModelProperty(value = "参数", hidden = true)
|
||||
private String params;
|
||||
@ApiModelProperty(value = "cron表达式", hidden = true)
|
||||
private String cronExpression;
|
||||
@ApiModelProperty(value = "状态", hidden = true)
|
||||
private Boolean isSuccess;
|
||||
@ApiModelProperty(value = "异常详情", hidden = true)
|
||||
private String exceptionDetail;
|
||||
@ApiModelProperty(value = "执行耗时", hidden = true)
|
||||
private Long time;
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@ApiModelProperty(value = "创建时间", hidden = true)
|
||||
private Date createTime;
|
||||
}
|
||||
|
||||
+4
-2
@@ -26,6 +26,8 @@ import lombok.Setter;
|
||||
@TableName("system_roles_depts")
|
||||
public class SystemRoleDeptTb extends KitObject {
|
||||
|
||||
@TableField(value = "role_id") private Long roleId;
|
||||
@TableField(value = "dept_id") private Long deptId;
|
||||
@TableField(value = "role_id")
|
||||
private Long roleId;
|
||||
@TableField(value = "dept_id")
|
||||
private Long deptId;
|
||||
}
|
||||
+4
-2
@@ -13,6 +13,8 @@ import lombok.Setter;
|
||||
@TableName("system_roles_menus")
|
||||
public class SystemRoleMenuTb {
|
||||
|
||||
@TableField(value = "role_id") private Long roleId;
|
||||
@TableField(value = "menu_id") private Long menuId;
|
||||
@TableField(value = "role_id")
|
||||
private Long roleId;
|
||||
@TableField(value = "menu_id")
|
||||
private Long menuId;
|
||||
}
|
||||
|
||||
+29
-21
@@ -37,28 +37,36 @@ import lombok.Setter;
|
||||
@TableName("system_role")
|
||||
public class SystemRoleTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = {Update.class}) @TableId(value = "role_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@NotBlank @ApiModelProperty(value = "名称", hidden = true) private String name;
|
||||
@ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义") private String dataScope =
|
||||
SystemDataScopeEnum.THIS_LEVEL.getValue();
|
||||
@ApiModelProperty(value = "级别,数值越小,级别越大") private Integer level = 3;
|
||||
@ApiModelProperty(value = "描述") @TableField(updateStrategy = FieldStrategy.ALWAYS) private String description;
|
||||
@NotNull(groups = {Update.class})
|
||||
@TableId(value = "role_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "名称", hidden = true)
|
||||
private String name;
|
||||
@ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义")
|
||||
private String dataScope =
|
||||
SystemDataScopeEnum.THIS_LEVEL.getValue();
|
||||
@ApiModelProperty(value = "级别,数值越小,级别越大")
|
||||
private Integer level = 3;
|
||||
@ApiModelProperty(value = "描述")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String description;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemRoleTb role = (SystemRoleTb)o;
|
||||
return Objects.equals(id, role.id);
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemRoleTb role = (SystemRoleTb) o;
|
||||
return Objects.equals(id, role.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -13,6 +13,8 @@ import lombok.Setter;
|
||||
@TableName("system_users_jobs")
|
||||
public class SystemUserJobTb {
|
||||
|
||||
@TableField(value = "user_id") private Long userId;
|
||||
@TableField(value = "job_id") private Long jobId;
|
||||
@TableField(value = "user_id")
|
||||
private Long userId;
|
||||
@TableField(value = "job_id")
|
||||
private Long jobId;
|
||||
}
|
||||
|
||||
+4
-2
@@ -26,6 +26,8 @@ import lombok.Setter;
|
||||
@TableName("system_users_roles")
|
||||
public class SystemUserRoleTb extends KitObject {
|
||||
|
||||
@TableField(value = "user_id") private Long userId;
|
||||
@TableField(value = "role_id") private Long roleId;
|
||||
@TableField(value = "user_id")
|
||||
private Long userId;
|
||||
@TableField(value = "role_id")
|
||||
private Long roleId;
|
||||
}
|
||||
+52
-29
@@ -34,36 +34,59 @@ import lombok.Setter;
|
||||
@TableName("system_user")
|
||||
public class SystemUserTb extends KitBaseUserTimeTb {
|
||||
|
||||
@NotNull(groups = Update.class) @TableId(value = "user_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@TableField(value = "dept_id") @ApiModelProperty(hidden = true) private Long deptId;
|
||||
@ApiModelProperty(value = "用户部门") @TableField(exist = false) private SystemDeptTb dept;
|
||||
@NotBlank @ApiModelProperty(value = "用户名称") private String username;
|
||||
@NotBlank @ApiModelProperty(value = "用户昵称") private String nickName;
|
||||
@Email @NotBlank @ApiModelProperty(value = "邮箱") private String email;
|
||||
@NotBlank @ApiModelProperty(value = "电话号码") private String phone;
|
||||
@ApiModelProperty(value = "用户性别") private String gender;
|
||||
@ApiModelProperty(value = "头像真实名称", hidden = true) private String avatarName;
|
||||
@ApiModelProperty(value = "头像存储的路径", hidden = true) private String avatarPath;
|
||||
@ApiModelProperty(value = "密码") private String password;
|
||||
@NotNull @ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@ApiModelProperty(value = "是否为admin账号", hidden = true) private Boolean isAdmin = false;
|
||||
@ApiModelProperty(value = "最后修改密码的时间", hidden = true) private Date pwdResetTime;
|
||||
@NotNull(groups = Update.class)
|
||||
@TableId(value = "user_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@TableField(value = "dept_id")
|
||||
@ApiModelProperty(hidden = true)
|
||||
private Long deptId;
|
||||
@ApiModelProperty(value = "用户部门")
|
||||
@TableField(exist = false)
|
||||
private SystemDeptTb dept;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "用户名称")
|
||||
private String username;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
private String nickName;
|
||||
@Email
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
private String email;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "电话号码")
|
||||
private String phone;
|
||||
@ApiModelProperty(value = "用户性别")
|
||||
private String gender;
|
||||
@ApiModelProperty(value = "头像真实名称", hidden = true)
|
||||
private String avatarName;
|
||||
@ApiModelProperty(value = "头像存储的路径", hidden = true)
|
||||
private String avatarPath;
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
@ApiModelProperty(value = "是否为admin账号", hidden = true)
|
||||
private Boolean isAdmin = false;
|
||||
@ApiModelProperty(value = "最后修改密码的时间", hidden = true)
|
||||
private Date pwdResetTime;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemUserTb user = (SystemUserTb)o;
|
||||
return Objects.equals(id, user.id) && Objects.equals(username, user.username);
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemUserTb user = (SystemUserTb) o;
|
||||
return Objects.equals(id, user.id) && Objects.equals(username, user.username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username);
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -24,7 +24,10 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemCheckEmailCaptchaArgs extends KitObject {
|
||||
|
||||
@NotBlank(message = "邮箱不能为空") private String email;
|
||||
@NotBlank(message = "验证码不能为空") private String code;
|
||||
@NotBlank(message = "验证码业务标识不能为空") private String bizCode;
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
private String email;
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String code;
|
||||
@NotBlank(message = "验证码业务标识不能为空")
|
||||
private String bizCode;
|
||||
}
|
||||
|
||||
+8
-6
@@ -25,10 +25,12 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemCreateDeptArgs extends KitObject {
|
||||
|
||||
@NotBlank(message = "部门名称必填") private String name;
|
||||
@NotNull(message = "部门排序必填") private Integer deptSort;
|
||||
private Boolean enabled;
|
||||
private String isTop;
|
||||
private Long pid;
|
||||
private Integer subCount = 0;
|
||||
@NotBlank(message = "部门名称必填")
|
||||
private String name;
|
||||
@NotNull(message = "部门排序必填")
|
||||
private Integer deptSort;
|
||||
private Boolean enabled;
|
||||
private String isTop;
|
||||
private Long pid;
|
||||
private Integer subCount = 0;
|
||||
}
|
||||
|
||||
+3
-2
@@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemCreateDictArgs extends KitObject {
|
||||
|
||||
@NotBlank(message = "字典名称必填") private String name;
|
||||
private String description;
|
||||
@NotBlank(message = "字典名称必填")
|
||||
private String name;
|
||||
private String description;
|
||||
}
|
||||
|
||||
+8
-4
@@ -26,8 +26,12 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemCreateDictDetailArgs extends KitObject {
|
||||
|
||||
@NotNull(message = "参数dict必填") private SystemDictTb dict;
|
||||
@NotBlank(message = "字典标签必填") private String label;
|
||||
@NotBlank(message = "字典值必填") private String value;
|
||||
@NotNull(message = "字典排序必填") private Integer dictSort;
|
||||
@NotNull(message = "参数dict必填")
|
||||
private SystemDictTb dict;
|
||||
@NotBlank(message = "字典标签必填")
|
||||
private String label;
|
||||
@NotBlank(message = "字典值必填")
|
||||
private String value;
|
||||
@NotNull(message = "字典排序必填")
|
||||
private Integer dictSort;
|
||||
}
|
||||
|
||||
+5
-3
@@ -25,7 +25,9 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemCreateJobArgs extends KitObject {
|
||||
|
||||
@NotBlank(message = "职位名称必填") private String name;
|
||||
@NotNull(message = "职位排序必填") private Integer jobSort;
|
||||
private Boolean enabled;
|
||||
@NotBlank(message = "职位名称必填")
|
||||
private String name;
|
||||
@NotNull(message = "职位排序必填")
|
||||
private Integer jobSort;
|
||||
private Boolean enabled;
|
||||
}
|
||||
|
||||
+12
-9
@@ -27,13 +27,16 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemCreateRoleArgs extends KitObject {
|
||||
|
||||
@NotBlank(message = "角色名称必填") private String name;
|
||||
@NotNull(message = "角色级别必填") private Integer level;
|
||||
@NotBlank(message = "数据范围必填") private String dataScope;
|
||||
private String description;
|
||||
/**
|
||||
* 关联的部门
|
||||
*/
|
||||
private Long id;
|
||||
private Set<SystemDeptTb> depts;
|
||||
@NotBlank(message = "角色名称必填")
|
||||
private String name;
|
||||
@NotNull(message = "角色级别必填")
|
||||
private Integer level;
|
||||
@NotBlank(message = "数据范围必填")
|
||||
private String dataScope;
|
||||
private String description;
|
||||
/**
|
||||
* 关联的部门
|
||||
*/
|
||||
private Long id;
|
||||
private Set<SystemDeptTb> depts;
|
||||
}
|
||||
|
||||
+2
-1
@@ -25,5 +25,6 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemDictDetailVo extends SystemDictDetailTb {
|
||||
|
||||
@ApiModelProperty(value = "字典") private SystemDictTb dict;
|
||||
@ApiModelProperty(value = "字典")
|
||||
private SystemDictTb dict;
|
||||
}
|
||||
+6
-3
@@ -26,7 +26,10 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemMenuMetaVo extends KitObject {
|
||||
|
||||
@ApiModelProperty(value = "菜单标题") private String title;
|
||||
@ApiModelProperty(value = "菜单图标") private String icon;
|
||||
@ApiModelProperty(value = "缓存") private Boolean noCache;
|
||||
@ApiModelProperty(value = "菜单标题")
|
||||
private String title;
|
||||
@ApiModelProperty(value = "菜单图标")
|
||||
private String icon;
|
||||
@ApiModelProperty(value = "缓存")
|
||||
private Boolean noCache;
|
||||
}
|
||||
|
||||
+16
-8
@@ -28,12 +28,20 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemMenuVo extends KitObject {
|
||||
|
||||
@ApiModelProperty(value = "菜单名称") private String name;
|
||||
@ApiModelProperty(value = "路径") private String path;
|
||||
@ApiModelProperty(value = "隐藏状态") private Boolean hidden;
|
||||
@ApiModelProperty(value = "重定向") private String redirect;
|
||||
@ApiModelProperty(value = "组件") private String component;
|
||||
@ApiModelProperty(value = "总是显示") private Boolean alwaysShow;
|
||||
@ApiModelProperty(value = "元数据") private SystemMenuMetaVo meta;
|
||||
@ApiModelProperty(value = "子路由") private List<SystemMenuVo> children;
|
||||
@ApiModelProperty(value = "菜单名称")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "路径")
|
||||
private String path;
|
||||
@ApiModelProperty(value = "隐藏状态")
|
||||
private Boolean hidden;
|
||||
@ApiModelProperty(value = "重定向")
|
||||
private String redirect;
|
||||
@ApiModelProperty(value = "组件")
|
||||
private String component;
|
||||
@ApiModelProperty(value = "总是显示")
|
||||
private Boolean alwaysShow;
|
||||
@ApiModelProperty(value = "元数据")
|
||||
private SystemMenuMetaVo meta;
|
||||
@ApiModelProperty(value = "子路由")
|
||||
private List<SystemMenuVo> children;
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,5 +23,5 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemOssStorageVo extends SystemOssStorageTb {
|
||||
|
||||
private String fileSizeDesc;
|
||||
private String fileSizeDesc;
|
||||
}
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemProductLineTreeVo extends KitObject {
|
||||
|
||||
private String value;
|
||||
private String label;
|
||||
private List<SystemProductLineTreeVo> children;
|
||||
private String value;
|
||||
private String label;
|
||||
private List<SystemProductLineTreeVo> children;
|
||||
}
|
||||
|
||||
+12
-12
@@ -23,16 +23,16 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemProductLineVo extends KitObject {
|
||||
|
||||
/**
|
||||
* 部门ID(select的value)
|
||||
*/
|
||||
private Long value;
|
||||
/**
|
||||
* 产品线,如"研发部/华南分部/devops组"
|
||||
*/
|
||||
private String label;
|
||||
/**
|
||||
* ID路径,如"1-2-3"
|
||||
*/
|
||||
private String idPath;
|
||||
/**
|
||||
* 部门ID(select的value)
|
||||
*/
|
||||
private Long value;
|
||||
/**
|
||||
* 产品线,如"研发部/华南分部/devops组"
|
||||
*/
|
||||
private String label;
|
||||
/**
|
||||
* ID路径,如"1-2-3"
|
||||
*/
|
||||
private String idPath;
|
||||
}
|
||||
|
||||
+12
-6
@@ -23,10 +23,16 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemQueryDeptArgs {
|
||||
|
||||
@ApiModelProperty(value = "部门id集合") private List<Long> ids;
|
||||
@ApiModelProperty(value = "部门名称") private String name;
|
||||
@ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@ApiModelProperty(value = "上级部门") private Long pid;
|
||||
@ApiModelProperty(value = "PID为空查询") private Boolean pidIsNull;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "部门id集合")
|
||||
private List<Long> ids;
|
||||
@ApiModelProperty(value = "部门名称")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
@ApiModelProperty(value = "上级部门")
|
||||
private Long pid;
|
||||
@ApiModelProperty(value = "PID为空查询")
|
||||
private Boolean pidIsNull;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
}
|
||||
|
||||
+6
-3
@@ -21,7 +21,10 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemQueryDictArgs {
|
||||
|
||||
@ApiModelProperty(value = "模糊查询") private String blurry;
|
||||
@ApiModelProperty(value = "页码", example = "1") private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10") private Integer size = 10;
|
||||
@ApiModelProperty(value = "模糊查询")
|
||||
private String blurry;
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
||||
|
||||
+4
-2
@@ -24,6 +24,8 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemQueryDictDetailArgs extends KitObject {
|
||||
|
||||
@ApiModelProperty(value = "标签") private String label;
|
||||
@ApiModelProperty(value = "字典名称") private String dictName;
|
||||
@ApiModelProperty(value = "标签")
|
||||
private String label;
|
||||
@ApiModelProperty(value = "字典名称")
|
||||
private String dictName;
|
||||
}
|
||||
+10
-5
@@ -25,9 +25,14 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
public class SystemQueryJobArgs {
|
||||
|
||||
@ApiModelProperty(value = "岗位名称") private String name;
|
||||
@ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1") private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10") private Integer size = 10;
|
||||
@ApiModelProperty(value = "岗位名称")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
||||
|
||||
+8
-4
@@ -23,8 +23,12 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemQueryMenuArgs {
|
||||
|
||||
@ApiModelProperty(value = "模糊查询") private String blurry;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "PID为空查询") private Boolean pidIsNull;
|
||||
@ApiModelProperty(value = "PID") private Long pid;
|
||||
@ApiModelProperty(value = "模糊查询")
|
||||
private String blurry;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
@ApiModelProperty(value = "PID为空查询")
|
||||
private Boolean pidIsNull;
|
||||
@ApiModelProperty(value = "PID")
|
||||
private Long pid;
|
||||
}
|
||||
|
||||
+10
-5
@@ -23,9 +23,14 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemQueryQuartzJobArgs {
|
||||
|
||||
@ApiModelProperty(value = "定时任务名称") private String jobName;
|
||||
@ApiModelProperty(value = "是否成功") private Boolean isSuccess;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1") private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10") private Integer size = 10;
|
||||
@ApiModelProperty(value = "定时任务名称")
|
||||
private String jobName;
|
||||
@ApiModelProperty(value = "是否成功")
|
||||
private Boolean isSuccess;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
||||
|
||||
+10
-5
@@ -23,9 +23,14 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemQueryRoleArgs {
|
||||
|
||||
@ApiModelProperty(value = "模糊查询") private String blurry;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1") private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10") private Integer size = 10;
|
||||
@ApiModelProperty(value = "偏移量", hidden = true) private long offset;
|
||||
@ApiModelProperty(value = "模糊查询")
|
||||
private String blurry;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
@ApiModelProperty(value = "偏移量", hidden = true)
|
||||
private long offset;
|
||||
}
|
||||
|
||||
+8
-4
@@ -23,8 +23,12 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemQueryStorageArgs {
|
||||
|
||||
@ApiModelProperty(value = "模糊查询") private String blurry;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1") private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10") private Integer size = 10;
|
||||
@ApiModelProperty(value = "模糊查询")
|
||||
private String blurry;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
||||
|
||||
+16
-8
@@ -28,12 +28,20 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemQueryUserArgs extends KitObject {
|
||||
|
||||
@ApiModelProperty(value = "ID") private Long id;
|
||||
@ApiModelProperty(value = "多个ID") private Set<Long> deptIds = new HashSet<>();
|
||||
@ApiModelProperty(value = "模糊查询") private String blurry;
|
||||
@ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@ApiModelProperty(value = "部门ID") private Long deptId;
|
||||
@ApiModelProperty(value = "创建时间") private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1") private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10") private Integer size = 10;
|
||||
@ApiModelProperty(value = "ID")
|
||||
private Long id;
|
||||
@ApiModelProperty(value = "多个ID")
|
||||
private Set<Long> deptIds = new HashSet<>();
|
||||
@ApiModelProperty(value = "模糊查询")
|
||||
private String blurry;
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
@ApiModelProperty(value = "部门ID")
|
||||
private Long deptId;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private List<Date> createTime;
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
||||
|
||||
+2
-1
@@ -29,5 +29,6 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
@AllArgsConstructor
|
||||
public class SystemRoleCodeVo implements GrantedAuthority {
|
||||
|
||||
@ApiModelProperty(value = "角色名") private String authority;
|
||||
@ApiModelProperty(value = "角色名")
|
||||
private String authority;
|
||||
}
|
||||
|
||||
+6
-3
@@ -13,7 +13,10 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemRoleVo extends SystemRoleTb {
|
||||
|
||||
@ApiModelProperty(value = "用户", hidden = true) private Set<SystemUserTb> users;
|
||||
@ApiModelProperty(value = "菜单", hidden = true) private Set<SystemMenuTb> menus;
|
||||
@ApiModelProperty(value = "部门", hidden = true) private Set<SystemDeptTb> depts;
|
||||
@ApiModelProperty(value = "用户", hidden = true)
|
||||
private Set<SystemUserTb> users;
|
||||
@ApiModelProperty(value = "菜单", hidden = true)
|
||||
private Set<SystemMenuTb> menus;
|
||||
@ApiModelProperty(value = "部门", hidden = true)
|
||||
private Set<SystemDeptTb> depts;
|
||||
}
|
||||
|
||||
+9
-3
@@ -31,7 +31,13 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
public class SystemSendEmailArgs {
|
||||
|
||||
@NotEmpty @ApiModelProperty(value = "收件人") private List<String> tos;
|
||||
@NotBlank @ApiModelProperty(value = "主题") private String subject;
|
||||
@NotBlank @ApiModelProperty(value = "内容") private String content;
|
||||
@NotEmpty
|
||||
@ApiModelProperty(value = "收件人")
|
||||
private List<String> tos;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "主题")
|
||||
private String subject;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "内容")
|
||||
private String content;
|
||||
}
|
||||
|
||||
+25
-13
@@ -29,17 +29,29 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemSimpleUserVo extends KitObject {
|
||||
|
||||
@ApiModelProperty(value = "ID", hidden = true) private Long id;
|
||||
@ApiModelProperty(value = "用户角色") private Set<SystemRoleTb> roles;
|
||||
@ApiModelProperty(value = "用户岗位") private Set<SystemJobTb> jobs;
|
||||
private Long deptId;
|
||||
@TableField(exist = false) private SystemDeptTb dept;
|
||||
@ApiModelProperty(value = "用户名称") private String username;
|
||||
@ApiModelProperty(value = "用户昵称") private String nickName;
|
||||
@ApiModelProperty(value = "邮箱") private String email;
|
||||
@ApiModelProperty(value = "电话号码") private String phone;
|
||||
@ApiModelProperty(value = "用户性别") private String gender;
|
||||
@ApiModelProperty(value = "头像真实名称", hidden = true) private String avatarName;
|
||||
@ApiModelProperty(value = "是否启用") private Boolean enabled;
|
||||
@ApiModelProperty(value = "是否为admin账号", hidden = true) private Boolean isAdmin = false;
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@ApiModelProperty(value = "用户角色")
|
||||
private Set<SystemRoleTb> roles;
|
||||
@ApiModelProperty(value = "用户岗位")
|
||||
private Set<SystemJobTb> jobs;
|
||||
private Long deptId;
|
||||
@TableField(exist = false)
|
||||
private SystemDeptTb dept;
|
||||
@ApiModelProperty(value = "用户名称")
|
||||
private String username;
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
private String nickName;
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
private String email;
|
||||
@ApiModelProperty(value = "电话号码")
|
||||
private String phone;
|
||||
@ApiModelProperty(value = "用户性别")
|
||||
private String gender;
|
||||
@ApiModelProperty(value = "头像真实名称", hidden = true)
|
||||
private String avatarName;
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
@ApiModelProperty(value = "是否为admin账号", hidden = true)
|
||||
private Boolean isAdmin = false;
|
||||
}
|
||||
+18
-13
@@ -25,17 +25,22 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemUpdateQuartzJobArgs extends KitObject {
|
||||
|
||||
@NotNull private Long id;
|
||||
private String uuid;
|
||||
private String jobName;
|
||||
@NotBlank private String beanName;
|
||||
@NotBlank private String methodName;
|
||||
private String params;
|
||||
@NotBlank private String cronExpression;
|
||||
private Boolean isPause = false;
|
||||
private String personInCharge;
|
||||
private String email;
|
||||
private String subTask;
|
||||
private Boolean pauseAfterFailure;
|
||||
@NotBlank private String description;
|
||||
@NotNull
|
||||
private Long id;
|
||||
private String uuid;
|
||||
private String jobName;
|
||||
@NotBlank
|
||||
private String beanName;
|
||||
@NotBlank
|
||||
private String methodName;
|
||||
private String params;
|
||||
@NotBlank
|
||||
private String cronExpression;
|
||||
private Boolean isPause = false;
|
||||
private String personInCharge;
|
||||
private String email;
|
||||
private String subTask;
|
||||
private Boolean pauseAfterFailure;
|
||||
@NotBlank
|
||||
private String description;
|
||||
}
|
||||
|
||||
+4
-2
@@ -24,6 +24,8 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemUpdateUserPasswordArgs {
|
||||
|
||||
@ApiModelProperty(value = "旧密码") private String oldPass;
|
||||
@ApiModelProperty(value = "新密码") private String newPass;
|
||||
@ApiModelProperty(value = "旧密码")
|
||||
private String oldPass;
|
||||
@ApiModelProperty(value = "新密码")
|
||||
private String newPass;
|
||||
}
|
||||
|
||||
+6
-6
@@ -26,11 +26,11 @@ import lombok.EqualsAndHashCode;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SystemUserInfoVo extends KitObject {
|
||||
|
||||
private SystemSimpleUserVo user;
|
||||
private List<Long> dataScopes;
|
||||
private List<SystemRoleCodeVo> authorities;
|
||||
private SystemSimpleUserVo user;
|
||||
private List<Long> dataScopes;
|
||||
private List<SystemRoleCodeVo> authorities;
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return authorities.stream().map(SystemRoleCodeVo::getAuthority).collect(Collectors.toSet());
|
||||
}
|
||||
public Set<String> getRoles() {
|
||||
return authorities.stream().map(SystemRoleCodeVo::getAuthority).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
+10
-4
@@ -24,8 +24,14 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemUserLoginArgs {
|
||||
|
||||
@NotBlank @ApiModelProperty(value = "用户名") private String username;
|
||||
@NotBlank @ApiModelProperty(value = "密码") private String password;
|
||||
@ApiModelProperty(value = "验证码") private String code;
|
||||
@ApiModelProperty(value = "验证码的key") private String uuid = "";
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "用户名")
|
||||
private String username;
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
@ApiModelProperty(value = "验证码")
|
||||
private String code;
|
||||
@ApiModelProperty(value = "验证码的key")
|
||||
private String uuid = "";
|
||||
}
|
||||
|
||||
+18
-9
@@ -25,13 +25,22 @@ import lombok.Data;
|
||||
@Data
|
||||
public class SystemUserOnlineVo {
|
||||
|
||||
@ApiModelProperty(value = "Token编号") private String uid;
|
||||
@ApiModelProperty(value = "用户名") private String userName;
|
||||
@ApiModelProperty(value = "昵称") private String nickName;
|
||||
@ApiModelProperty(value = "岗位") private String dept;
|
||||
@ApiModelProperty(value = "浏览器") private String browser;
|
||||
@ApiModelProperty(value = "IP") private String ip;
|
||||
@ApiModelProperty(value = "地址") private String address;
|
||||
@ApiModelProperty(value = "token") private String key;
|
||||
@ApiModelProperty(value = "登录时间") private Date loginTime;
|
||||
@ApiModelProperty(value = "Token编号")
|
||||
private String uid;
|
||||
@ApiModelProperty(value = "用户名")
|
||||
private String userName;
|
||||
@ApiModelProperty(value = "昵称")
|
||||
private String nickName;
|
||||
@ApiModelProperty(value = "岗位")
|
||||
private String dept;
|
||||
@ApiModelProperty(value = "浏览器")
|
||||
private String browser;
|
||||
@ApiModelProperty(value = "IP")
|
||||
private String ip;
|
||||
@ApiModelProperty(value = "地址")
|
||||
private String address;
|
||||
@ApiModelProperty(value = "token")
|
||||
private String key;
|
||||
@ApiModelProperty(value = "登录时间")
|
||||
private Date loginTime;
|
||||
}
|
||||
|
||||
+4
-2
@@ -12,6 +12,8 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class SystemUserVo extends SystemUserTb {
|
||||
|
||||
@ApiModelProperty(value = "用户角色") private Set<SystemRoleTb> roles;
|
||||
@ApiModelProperty(value = "用户岗位") private Set<SystemJobTb> jobs;
|
||||
@ApiModelProperty(value = "用户角色")
|
||||
private Set<SystemRoleTb> roles;
|
||||
@ApiModelProperty(value = "用户岗位")
|
||||
private Set<SystemJobTb> jobs;
|
||||
}
|
||||
|
||||
+2
-2
@@ -13,6 +13,8 @@ import cn.odboy.util.KitFileUtil;
|
||||
import cn.odboy.util.KitIPUtil;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -22,8 +24,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
+21
-20
@@ -35,28 +35,29 @@ import java.util.concurrent.TimeUnit;
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface BizLock {
|
||||
/**
|
||||
* 业务名称
|
||||
*/
|
||||
String bizName() default "";
|
||||
|
||||
/**
|
||||
* 锁key,支持SpEL表达式 示例: #user.id - 获取参数user的id属性 #p0 - 获取第一个参数 #root.methodName - 获取方法名
|
||||
*/
|
||||
String key() default "";
|
||||
/**
|
||||
* 业务名称
|
||||
*/
|
||||
String bizName() default "";
|
||||
|
||||
/**
|
||||
* 锁持有时间(秒),默认60秒。锁的持有时间,超过这个时间锁会自动释放
|
||||
*/
|
||||
long leaseTime() default 60;
|
||||
/**
|
||||
* 锁key,支持SpEL表达式 示例: #user.id - 获取参数user的id属性 #p0 - 获取第一个参数 #root.methodName - 获取方法名
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
/**
|
||||
* 时间单位,默认为秒
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.SECONDS;
|
||||
/**
|
||||
* 锁持有时间(秒),默认60秒。锁的持有时间,超过这个时间锁会自动释放
|
||||
*/
|
||||
long leaseTime() default 60;
|
||||
|
||||
/**
|
||||
* 获取锁失败后的异常信息
|
||||
*/
|
||||
String errorMessage() default "操作太繁忙,请稍后再试";
|
||||
/**
|
||||
* 时间单位,默认为秒
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.SECONDS;
|
||||
|
||||
/**
|
||||
* 获取锁失败后的异常信息
|
||||
*/
|
||||
String errorMessage() default "操作太繁忙,请稍后再试";
|
||||
}
|
||||
|
||||
+52
-51
@@ -32,62 +32,63 @@ import org.springframework.stereotype.Component;
|
||||
@Aspect
|
||||
@Component
|
||||
public class BizLockAspect {
|
||||
private final KitRedisHelper redisHelper;
|
||||
private final ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
public BizLockAspect(KitRedisHelper redisHelper) {
|
||||
this.redisHelper = redisHelper;
|
||||
private final KitRedisHelper redisHelper;
|
||||
private final ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
public BizLockAspect(KitRedisHelper redisHelper) {
|
||||
this.redisHelper = redisHelper;
|
||||
}
|
||||
|
||||
@Around("@annotation(bizLock)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, BizLock bizLock) throws Throwable {
|
||||
// 解析SpEL表达式生成最终的lockKey
|
||||
String lockKey = parseLockKey(joinPoint, bizLock);
|
||||
Boolean success = redisHelper.setIfAbsent(lockKey, lockKey, bizLock.leaseTime(), bizLock.timeUnit());
|
||||
if (success == null || !success) {
|
||||
throw new BadRequestException(bizLock.errorMessage());
|
||||
}
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
redisHelper.del(lockKey);
|
||||
}
|
||||
}
|
||||
|
||||
private String parseLockKey(ProceedingJoinPoint joinPoint, BizLock bizLock) {
|
||||
// 如果key为空,使用默认格式: bizName:方法名
|
||||
if (bizLock.key().isEmpty()) {
|
||||
return String.format("%s:%s", bizLock.bizName(),
|
||||
((MethodSignature) joinPoint.getSignature()).getMethod().getName());
|
||||
}
|
||||
|
||||
@Around("@annotation(bizLock)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, BizLock bizLock) throws Throwable {
|
||||
// 解析SpEL表达式生成最终的lockKey
|
||||
String lockKey = parseLockKey(joinPoint, bizLock);
|
||||
Boolean success = redisHelper.setIfAbsent(lockKey, lockKey, bizLock.leaseTime(), bizLock.timeUnit());
|
||||
if (success == null || !success) {
|
||||
throw new BadRequestException(bizLock.errorMessage());
|
||||
}
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
redisHelper.del(lockKey);
|
||||
}
|
||||
// 解析SpEL表达式
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
// 创建SpEL上下文
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
// 设置方法参数
|
||||
String[] parameterNames = signature.getParameterNames();
|
||||
Object[] args = joinPoint.getArgs();
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
context.setVariable(parameterNames[i], args[i]);
|
||||
// 支持#p0,#p1格式
|
||||
context.setVariable("p" + i, args[i]);
|
||||
}
|
||||
|
||||
private String parseLockKey(ProceedingJoinPoint joinPoint, BizLock bizLock) {
|
||||
// 如果key为空,使用默认格式: bizName:方法名
|
||||
if (bizLock.key().isEmpty()) {
|
||||
return String.format("%s:%s", bizLock.bizName(),
|
||||
((MethodSignature)joinPoint.getSignature()).getMethod().getName());
|
||||
}
|
||||
// 设置方法相关信息
|
||||
context.setVariable("methodName", method.getName());
|
||||
context.setVariable("targetClass", joinPoint.getTarget().getClass().getName());
|
||||
|
||||
// 解析SpEL表达式
|
||||
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
// 解析表达式
|
||||
Expression expression = parser.parseExpression(bizLock.key());
|
||||
String value = expression.getValue(context, String.class);
|
||||
|
||||
// 创建SpEL上下文
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
// 设置方法参数
|
||||
String[] parameterNames = signature.getParameterNames();
|
||||
Object[] args = joinPoint.getArgs();
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
context.setVariable(parameterNames[i], args[i]);
|
||||
// 支持#p0,#p1格式
|
||||
context.setVariable("p" + i, args[i]);
|
||||
}
|
||||
|
||||
// 设置方法相关信息
|
||||
context.setVariable("methodName", method.getName());
|
||||
context.setVariable("targetClass", joinPoint.getTarget().getClass().getName());
|
||||
|
||||
// 解析表达式
|
||||
Expression expression = parser.parseExpression(bizLock.key());
|
||||
String value = expression.getValue(context, String.class);
|
||||
|
||||
// 组合最终的key: bizName:解析后的key
|
||||
return String.format("%s:%s", bizLock.bizName(), value);
|
||||
}
|
||||
// 组合最终的key: bizName:解析后的key
|
||||
return String.format("%s:%s", bizLock.bizName(), value);
|
||||
}
|
||||
}
|
||||
+25
-25
@@ -26,33 +26,33 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class MpMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
DateTime now = DateTime.now();
|
||||
/* 创建时间 */
|
||||
this.strictInsertFill(metaObject, "createTime", Date.class, now);
|
||||
this.strictInsertFill(metaObject, "updateTime", Date.class, now);
|
||||
/* 操作人 */
|
||||
String username = "System";
|
||||
try {
|
||||
username = KitSecurityHelper.getCurrentUsername();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
this.strictInsertFill(metaObject, "createBy", String.class, username);
|
||||
this.strictInsertFill(metaObject, "updateBy", String.class, username);
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
DateTime now = DateTime.now();
|
||||
/* 创建时间 */
|
||||
this.strictInsertFill(metaObject, "createTime", Date.class, now);
|
||||
this.strictInsertFill(metaObject, "updateTime", Date.class, now);
|
||||
/* 操作人 */
|
||||
String username = "System";
|
||||
try {
|
||||
username = KitSecurityHelper.getCurrentUsername();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
this.strictInsertFill(metaObject, "createBy", String.class, username);
|
||||
this.strictInsertFill(metaObject, "updateBy", String.class, username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
/* 更新时间 */
|
||||
this.strictUpdateFill(metaObject, "updateTime", Date.class, DateTime.now());
|
||||
/* 操作人 */
|
||||
String username = "System";
|
||||
try {
|
||||
username = KitSecurityHelper.getCurrentUsername();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
this.strictUpdateFill(metaObject, "updateBy", String.class, username);
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
/* 更新时间 */
|
||||
this.strictUpdateFill(metaObject, "updateTime", Date.class, DateTime.now());
|
||||
/* 操作人 */
|
||||
String username = "System";
|
||||
try {
|
||||
username = KitSecurityHelper.getCurrentUsername();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
this.strictUpdateFill(metaObject, "updateBy", String.class, username);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -34,5 +34,6 @@ import java.lang.annotation.Target;
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface OperationLog {
|
||||
String bizName() default "";
|
||||
|
||||
String bizName() default "";
|
||||
}
|
||||
|
||||
+63
-61
@@ -47,72 +47,74 @@ import org.springframework.stereotype.Component;
|
||||
@Aspect
|
||||
@Component
|
||||
public class OperationLogAspect {
|
||||
@Autowired private SystemOperationLogMapper systemOperationLogMapper;
|
||||
|
||||
@Around("@annotation(operationLog)")
|
||||
public Object operationLogCatch(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
|
||||
return handleLog(joinPoint, operationLog);
|
||||
}
|
||||
@Autowired
|
||||
private SystemOperationLogMapper systemOperationLogMapper;
|
||||
|
||||
private Object handleLog(ProceedingJoinPoint joinPoint, OperationLog annotation) throws Throwable {
|
||||
TimeInterval timeInterval = new TimeInterval();
|
||||
@Around("@annotation(operationLog)")
|
||||
public Object operationLogCatch(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
|
||||
return handleLog(joinPoint, operationLog);
|
||||
}
|
||||
|
||||
private Object handleLog(ProceedingJoinPoint joinPoint, OperationLog annotation) throws Throwable {
|
||||
TimeInterval timeInterval = new TimeInterval();
|
||||
try {
|
||||
Object result = joinPoint.proceed();
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
Object result = joinPoint.proceed();
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} catch (Throwable exception) {
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
record.setExceptionDetail(ExceptionUtil.stacktraceToString(exception));
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
throw exception;
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} catch (Throwable exception) {
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
record.setExceptionDetail(ExceptionUtil.stacktraceToString(exception));
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
private SystemOperationLogTb getOperationLogTb(ProceedingJoinPoint joinPoint, OperationLog annotation,
|
||||
TimeInterval timeInterval) {
|
||||
long executeTime = timeInterval.intervalMs();
|
||||
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
|
||||
String bizName = annotation.bizName();
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
Method method = signature.getMethod();
|
||||
Operation apiOperation = method.getAnnotation(Operation.class);
|
||||
if (apiOperation != null) {
|
||||
bizName = apiOperation.summary();
|
||||
}
|
||||
}
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
bizName = "默认业务";
|
||||
}
|
||||
String method = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||
Object[] args = joinPoint.getArgs();
|
||||
String params = JSON.toJSONString(args);
|
||||
HttpServletRequest request = KitRequestHolder.getHttpServletRequest();
|
||||
String requestIp = KitBrowserUtil.getIp(request);
|
||||
String browserInfo = KitBrowserUtil.getVersion(request);
|
||||
String address = KitIPUtil.getCityInfo(requestIp);
|
||||
String username = KitSecurityHelper.getCurrentUsername();
|
||||
SystemOperationLogTb record = new SystemOperationLogTb();
|
||||
record.setBizName(bizName);
|
||||
record.setMethod(method);
|
||||
record.setParams(params);
|
||||
record.setRequestIp(requestIp);
|
||||
record.setExecuteTime(executeTime);
|
||||
record.setUsername(username);
|
||||
record.setAddress(address);
|
||||
record.setBrowserInfo(browserInfo);
|
||||
return record;
|
||||
private SystemOperationLogTb getOperationLogTb(ProceedingJoinPoint joinPoint, OperationLog annotation,
|
||||
TimeInterval timeInterval) {
|
||||
long executeTime = timeInterval.intervalMs();
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
String bizName = annotation.bizName();
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
Method method = signature.getMethod();
|
||||
Operation apiOperation = method.getAnnotation(Operation.class);
|
||||
if (apiOperation != null) {
|
||||
bizName = apiOperation.summary();
|
||||
}
|
||||
}
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
bizName = "默认业务";
|
||||
}
|
||||
String method = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||
Object[] args = joinPoint.getArgs();
|
||||
String params = JSON.toJSONString(args);
|
||||
HttpServletRequest request = KitRequestHolder.getHttpServletRequest();
|
||||
String requestIp = KitBrowserUtil.getIp(request);
|
||||
String browserInfo = KitBrowserUtil.getVersion(request);
|
||||
String address = KitIPUtil.getCityInfo(requestIp);
|
||||
String username = KitSecurityHelper.getCurrentUsername();
|
||||
SystemOperationLogTb record = new SystemOperationLogTb();
|
||||
record.setBizName(bizName);
|
||||
record.setMethod(method);
|
||||
record.setParams(params);
|
||||
record.setRequestIp(requestIp);
|
||||
record.setExecuteTime(executeTime);
|
||||
record.setUsername(username);
|
||||
record.setAddress(address);
|
||||
record.setBrowserInfo(browserInfo);
|
||||
return record;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -33,5 +33,6 @@ import java.lang.annotation.Target;
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface OperationLog {
|
||||
String bizName() default "";
|
||||
|
||||
String bizName() default "";
|
||||
}
|
||||
|
||||
+65
-63
@@ -47,74 +47,76 @@ import org.springframework.stereotype.Component;
|
||||
@Aspect
|
||||
@Component
|
||||
public class SystemOperationLogAspect {
|
||||
@Autowired private SystemOperationLogMapper systemOperationLogMapper;
|
||||
|
||||
@Around("@annotation(operationLog)")
|
||||
public Object operationLogCatch(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
|
||||
return handleLog(joinPoint, operationLog);
|
||||
}
|
||||
@Autowired
|
||||
private SystemOperationLogMapper systemOperationLogMapper;
|
||||
|
||||
private Object handleLog(ProceedingJoinPoint joinPoint, OperationLog annotation) throws Throwable {
|
||||
TimeInterval timeInterval = new TimeInterval();
|
||||
@Around("@annotation(operationLog)")
|
||||
public Object operationLogCatch(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
|
||||
return handleLog(joinPoint, operationLog);
|
||||
}
|
||||
|
||||
private Object handleLog(ProceedingJoinPoint joinPoint, OperationLog annotation) throws Throwable {
|
||||
TimeInterval timeInterval = new TimeInterval();
|
||||
try {
|
||||
Object result = joinPoint.proceed();
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
Object result = joinPoint.proceed();
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// log.error("保存审计日志失败", e);
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} catch (Throwable exception) {
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
record.setExceptionDetail(ExceptionUtil.stacktraceToString(exception));
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// log.error("保存审计日志失败", e);
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
throw exception;
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// log.error("保存审计日志失败", e);
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} catch (Throwable exception) {
|
||||
SystemOperationLogTb record = getOperationLogTb(joinPoint, annotation, timeInterval);
|
||||
record.setExceptionDetail(ExceptionUtil.stacktraceToString(exception));
|
||||
Thread.startVirtualThread(() -> {
|
||||
try {
|
||||
systemOperationLogMapper.insert(record);
|
||||
} catch (Exception e) {
|
||||
// log.error("保存审计日志失败", e);
|
||||
// 忽略
|
||||
}
|
||||
});
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
private SystemOperationLogTb getOperationLogTb(ProceedingJoinPoint joinPoint, OperationLog annotation,
|
||||
TimeInterval timeInterval) {
|
||||
long executeTime = timeInterval.intervalMs();
|
||||
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
|
||||
String bizName = annotation.bizName();
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
Method method = signature.getMethod();
|
||||
Operation apiOperation = method.getAnnotation(Operation.class);
|
||||
if (apiOperation != null) {
|
||||
bizName = apiOperation.summary();
|
||||
}
|
||||
}
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
bizName = "默认业务";
|
||||
}
|
||||
String method = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||
Object[] args = joinPoint.getArgs();
|
||||
String params = JSON.toJSONString(args);
|
||||
HttpServletRequest request = KitRequestHolder.getHttpServletRequest();
|
||||
String requestIp = KitBrowserUtil.getIp(request);
|
||||
String browserInfo = KitBrowserUtil.getVersion(request);
|
||||
String address = KitIPUtil.getCityInfo(requestIp);
|
||||
String username = KitSecurityHelper.getCurrentUsername();
|
||||
SystemOperationLogTb record = new SystemOperationLogTb();
|
||||
record.setBizName(bizName);
|
||||
record.setMethod(method);
|
||||
record.setParams(params);
|
||||
record.setRequestIp(requestIp);
|
||||
record.setExecuteTime(executeTime);
|
||||
record.setUsername(username);
|
||||
record.setAddress(address);
|
||||
record.setBrowserInfo(browserInfo);
|
||||
return record;
|
||||
private SystemOperationLogTb getOperationLogTb(ProceedingJoinPoint joinPoint, OperationLog annotation,
|
||||
TimeInterval timeInterval) {
|
||||
long executeTime = timeInterval.intervalMs();
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
String bizName = annotation.bizName();
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
Method method = signature.getMethod();
|
||||
Operation apiOperation = method.getAnnotation(Operation.class);
|
||||
if (apiOperation != null) {
|
||||
bizName = apiOperation.summary();
|
||||
}
|
||||
}
|
||||
if (StrUtil.isBlank(bizName)) {
|
||||
bizName = "默认业务";
|
||||
}
|
||||
String method = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||
Object[] args = joinPoint.getArgs();
|
||||
String params = JSON.toJSONString(args);
|
||||
HttpServletRequest request = KitRequestHolder.getHttpServletRequest();
|
||||
String requestIp = KitBrowserUtil.getIp(request);
|
||||
String browserInfo = KitBrowserUtil.getVersion(request);
|
||||
String address = KitIPUtil.getCityInfo(requestIp);
|
||||
String username = KitSecurityHelper.getCurrentUsername();
|
||||
SystemOperationLogTb record = new SystemOperationLogTb();
|
||||
record.setBizName(bizName);
|
||||
record.setMethod(method);
|
||||
record.setParams(params);
|
||||
record.setRequestIp(requestIp);
|
||||
record.setExecuteTime(executeTime);
|
||||
record.setUsername(username);
|
||||
record.setAddress(address);
|
||||
record.setBrowserInfo(browserInfo);
|
||||
return record;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -25,17 +25,17 @@ import org.springframework.stereotype.Service;
|
||||
@Service(value = "el")
|
||||
public class AuthorityConfig {
|
||||
|
||||
/**
|
||||
* 判断接口是否有权限
|
||||
*
|
||||
* @param permissions 权限
|
||||
* @return /
|
||||
*/
|
||||
public Boolean check(String... permissions) {
|
||||
// 获取当前用户的所有权限
|
||||
List<String> roleList =
|
||||
KitSecurityHelper.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).toList();
|
||||
// 判断当前用户的所有权限是否包含接口上定义的权限
|
||||
return roleList.contains("admin") || Arrays.stream(permissions).anyMatch(roleList::contains);
|
||||
}
|
||||
/**
|
||||
* 判断接口是否有权限
|
||||
*
|
||||
* @param permissions 权限
|
||||
* @return /
|
||||
*/
|
||||
public Boolean check(String... permissions) {
|
||||
// 获取当前用户的所有权限
|
||||
List<String> roleList =
|
||||
KitSecurityHelper.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).toList();
|
||||
// 判断当前用户的所有权限是否包含接口上定义的权限
|
||||
return roleList.contains("admin") || Arrays.stream(permissions).anyMatch(roleList::contains);
|
||||
}
|
||||
}
|
||||
|
||||
+75
-68
@@ -45,77 +45,84 @@ import org.springframework.web.filter.CorsFilter;
|
||||
@Configuration
|
||||
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||
public class SpringSecurityConfig {
|
||||
@Autowired private TokenProvider tokenProvider;
|
||||
@Autowired private CorsFilter corsFilter;
|
||||
@Autowired private JwtAuthenticationEntryPoint authenticationErrorHandler;
|
||||
@Autowired private JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
||||
@Autowired private ApplicationContext applicationContext;
|
||||
@Autowired private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
||||
// 去除 ROLE_ 前缀
|
||||
return new GrantedAuthorityDefaults("");
|
||||
}
|
||||
@Autowired
|
||||
private TokenProvider tokenProvider;
|
||||
@Autowired
|
||||
private CorsFilter corsFilter;
|
||||
@Autowired
|
||||
private JwtAuthenticationEntryPoint authenticationErrorHandler;
|
||||
@Autowired
|
||||
private JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Autowired
|
||||
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
// 密码加密方式
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
||||
// 去除 ROLE_ 前缀
|
||||
return new GrantedAuthorityDefaults("");
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||
// 获取匿名标记
|
||||
Map<String, Set<String>> anonymousUrls = KitAnonTagUtil.getAnonymousUrl(applicationContext);
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
// 密码加密方式
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
// 创建TokenFilter实例
|
||||
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoDAO);
|
||||
@Bean
|
||||
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||
// 获取匿名标记
|
||||
Map<String, Set<String>> anonymousUrls = KitAnonTagUtil.getAnonymousUrl(applicationContext);
|
||||
|
||||
return httpSecurity
|
||||
// 禁用 CSRF
|
||||
.csrf(AbstractHttpConfigurer::disable).addFilter(corsFilter)
|
||||
.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
// 授权异常
|
||||
.exceptionHandling(
|
||||
exceptionHandling -> exceptionHandling.authenticationEntryPoint(authenticationErrorHandler)
|
||||
.accessDeniedHandler(jwtAccessDeniedHandler))
|
||||
// 防止iframe 造成跨域
|
||||
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
|
||||
// 不创建会话
|
||||
.sessionManagement(
|
||||
sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
|
||||
// 静态资源等等
|
||||
.requestMatchers(HttpMethod.GET, "*.html", "*.css", "*.js", "/websocket/**").permitAll()
|
||||
// Knife4j 和 OpenAPI 相关路径
|
||||
.requestMatchers("/doc.html", "/webjars/**", "/v3/api-docs", "/v3/api-docs/**", "/swagger-resources",
|
||||
"/swagger-resources/**", "/configuration/ui", "/configuration/security").permitAll()
|
||||
// 文件
|
||||
.requestMatchers("/avatar/**").permitAll().requestMatchers("/file/**").permitAll()
|
||||
// 阿里巴巴 druid
|
||||
.requestMatchers("/druid/**").permitAll()
|
||||
// 放行OPTIONS请求
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
|
||||
// GET
|
||||
.requestMatchers(HttpMethod.GET,
|
||||
anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()
|
||||
// POST
|
||||
.requestMatchers(HttpMethod.POST,
|
||||
anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll()
|
||||
// PUT
|
||||
.requestMatchers(HttpMethod.PUT,
|
||||
anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll()
|
||||
// PATCH
|
||||
.requestMatchers(HttpMethod.PATCH,
|
||||
anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll()
|
||||
// DELETE
|
||||
.requestMatchers(HttpMethod.DELETE,
|
||||
anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll()
|
||||
// 所有类型的接口都放行
|
||||
.requestMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll()
|
||||
// 所有请求都需要认证
|
||||
.anyRequest().authenticated()).build();
|
||||
}
|
||||
// 创建TokenFilter实例
|
||||
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoDAO);
|
||||
|
||||
return httpSecurity
|
||||
// 禁用 CSRF
|
||||
.csrf(AbstractHttpConfigurer::disable).addFilter(corsFilter)
|
||||
.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
// 授权异常
|
||||
.exceptionHandling(
|
||||
exceptionHandling -> exceptionHandling.authenticationEntryPoint(authenticationErrorHandler)
|
||||
.accessDeniedHandler(jwtAccessDeniedHandler))
|
||||
// 防止iframe 造成跨域
|
||||
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
|
||||
// 不创建会话
|
||||
.sessionManagement(
|
||||
sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
|
||||
// 静态资源等等
|
||||
.requestMatchers(HttpMethod.GET, "*.html", "*.css", "*.js", "/websocket/**").permitAll()
|
||||
// Knife4j 和 OpenAPI 相关路径
|
||||
.requestMatchers("/doc.html", "/webjars/**", "/v3/api-docs", "/v3/api-docs/**", "/swagger-resources",
|
||||
"/swagger-resources/**", "/configuration/ui", "/configuration/security").permitAll()
|
||||
// 文件
|
||||
.requestMatchers("/avatar/**").permitAll().requestMatchers("/file/**").permitAll()
|
||||
// 阿里巴巴 druid
|
||||
.requestMatchers("/druid/**").permitAll()
|
||||
// 放行OPTIONS请求
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
|
||||
// GET
|
||||
.requestMatchers(HttpMethod.GET,
|
||||
anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()
|
||||
// POST
|
||||
.requestMatchers(HttpMethod.POST,
|
||||
anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll()
|
||||
// PUT
|
||||
.requestMatchers(HttpMethod.PUT,
|
||||
anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll()
|
||||
// PATCH
|
||||
.requestMatchers(HttpMethod.PATCH,
|
||||
anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll()
|
||||
// DELETE
|
||||
.requestMatchers(HttpMethod.DELETE,
|
||||
anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll()
|
||||
// 所有类型的接口都放行
|
||||
.requestMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll()
|
||||
// 所有请求都需要认证
|
||||
.anyRequest().authenticated()).build();
|
||||
}
|
||||
}
|
||||
+12
-11
@@ -25,17 +25,18 @@ import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||
private final TokenProvider tokenProvider;
|
||||
private final SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||
|
||||
public TokenConfigurer(TokenProvider tokenProvider, SystemUserOnlineInfoDAO systemUserOnlineInfoDAO) {
|
||||
this.tokenProvider = tokenProvider;
|
||||
this.systemUserOnlineInfoDAO = systemUserOnlineInfoDAO;
|
||||
}
|
||||
private final TokenProvider tokenProvider;
|
||||
private final SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoDAO);
|
||||
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
}
|
||||
public TokenConfigurer(TokenProvider tokenProvider, SystemUserOnlineInfoDAO systemUserOnlineInfoDAO) {
|
||||
this.tokenProvider = tokenProvider;
|
||||
this.systemUserOnlineInfoDAO = systemUserOnlineInfoDAO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoDAO);
|
||||
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
}
|
||||
}
|
||||
|
||||
+83
-82
@@ -41,95 +41,96 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class KitSecurityHelper {
|
||||
/**
|
||||
* 获取当前登录的用户
|
||||
*
|
||||
* @return UserDetails
|
||||
*/
|
||||
public static UserDetails getCurrentUser() {
|
||||
UserDetailsService userDetailsService = KitSpringBeanHolder.getBean(UserDetailsService.class);
|
||||
return userDetailsService.loadUserByUsername(getCurrentUsername());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的数据权限
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static List<Long> getCurrentUserDataScope() {
|
||||
UserDetails userDetails = getCurrentUser();
|
||||
// 将 Java 对象转换为 JSONObject 对象
|
||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(userDetails);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("dataScopes");
|
||||
return JSON.parseArray(jsonArray.toJSONString(), Long.class);
|
||||
}
|
||||
/**
|
||||
* 获取当前登录的用户
|
||||
*
|
||||
* @return UserDetails
|
||||
*/
|
||||
public static UserDetails getCurrentUser() {
|
||||
UserDetailsService userDetailsService = KitSpringBeanHolder.getBean(UserDetailsService.class);
|
||||
return userDetailsService.loadUserByUsername(getCurrentUsername());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据权限级别
|
||||
*
|
||||
* @return 级别
|
||||
*/
|
||||
public static String getDataScopeType() {
|
||||
List<Long> dataScopes = getCurrentUserDataScope();
|
||||
if (CollUtil.isEmpty(dataScopes)) {
|
||||
return "";
|
||||
}
|
||||
return SystemDataScopeEnum.ALL.getValue();
|
||||
}
|
||||
/**
|
||||
* 获取当前用户的数据权限
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static List<Long> getCurrentUserDataScope() {
|
||||
UserDetails userDetails = getCurrentUser();
|
||||
// 将 Java 对象转换为 JSONObject 对象
|
||||
JSONObject jsonObject = (JSONObject) JSON.toJSON(userDetails);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("dataScopes");
|
||||
return JSON.parseArray(jsonArray.toJSONString(), Long.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户ID
|
||||
*
|
||||
* @return 系统用户ID
|
||||
*/
|
||||
public static Long getCurrentUserId() {
|
||||
return getCurrentUserId(getToken());
|
||||
/**
|
||||
* 获取数据权限级别
|
||||
*
|
||||
* @return 级别
|
||||
*/
|
||||
public static String getDataScopeType() {
|
||||
List<Long> dataScopes = getCurrentUserDataScope();
|
||||
if (CollUtil.isEmpty(dataScopes)) {
|
||||
return "";
|
||||
}
|
||||
return SystemDataScopeEnum.ALL.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户ID
|
||||
*
|
||||
* @return 系统用户ID
|
||||
*/
|
||||
public static Long getCurrentUserId(String token) {
|
||||
JWT jwt = JWTUtil.parseToken(token);
|
||||
return Long.valueOf(jwt.getPayload("userId").toString());
|
||||
}
|
||||
/**
|
||||
* 获取用户ID
|
||||
*
|
||||
* @return 系统用户ID
|
||||
*/
|
||||
public static Long getCurrentUserId() {
|
||||
return getCurrentUserId(getToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统用户名称
|
||||
*
|
||||
* @return 系统用户名称
|
||||
*/
|
||||
public static String getCurrentUsername() {
|
||||
return getCurrentUsername(getToken());
|
||||
}
|
||||
/**
|
||||
* 获取用户ID
|
||||
*
|
||||
* @return 系统用户ID
|
||||
*/
|
||||
public static Long getCurrentUserId(String token) {
|
||||
JWT jwt = JWTUtil.parseToken(token);
|
||||
return Long.valueOf(jwt.getPayload("userId").toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统用户名称
|
||||
*
|
||||
* @return 系统用户名称
|
||||
*/
|
||||
public static String getCurrentUsername(String token) {
|
||||
JWT jwt = JWTUtil.parseToken(token);
|
||||
return jwt.getPayload("sub").toString();
|
||||
}
|
||||
/**
|
||||
* 获取系统用户名称
|
||||
*
|
||||
* @return 系统用户名称
|
||||
*/
|
||||
public static String getCurrentUsername() {
|
||||
return getCurrentUsername(getToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Token
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static String getToken() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes)Objects.requireNonNull(
|
||||
RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String bearerToken = request.getHeader(SystemConst.HEADER_NAME);
|
||||
if (bearerToken != null && bearerToken.startsWith(SystemConst.TOKEN_PREFIX)) {
|
||||
// 去掉令牌前缀
|
||||
return bearerToken.replace(SystemConst.TOKEN_PREFIX, "");
|
||||
} else {
|
||||
log.debug("非法Token:{}", bearerToken);
|
||||
}
|
||||
return null;
|
||||
/**
|
||||
* 获取系统用户名称
|
||||
*
|
||||
* @return 系统用户名称
|
||||
*/
|
||||
public static String getCurrentUsername(String token) {
|
||||
JWT jwt = JWTUtil.parseToken(token);
|
||||
return jwt.getPayload("sub").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Token
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static String getToken() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(
|
||||
RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String bearerToken = request.getHeader(SystemConst.HEADER_NAME);
|
||||
if (bearerToken != null && bearerToken.startsWith(SystemConst.TOKEN_PREFIX)) {
|
||||
// 去掉令牌前缀
|
||||
return bearerToken.replace(SystemConst.TOKEN_PREFIX, "");
|
||||
} else {
|
||||
log.debug("非法Token:{}", bearerToken);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -29,15 +29,15 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response,
|
||||
AccessDeniedException accessDeniedException) throws IOException {
|
||||
//当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应
|
||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonResponse = objectMapper.writeValueAsString(
|
||||
ApiError.error(HttpStatus.FORBIDDEN.value(), "禁止访问,您没有权限访问此资源"));
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response,
|
||||
AccessDeniedException accessDeniedException) throws IOException {
|
||||
//当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应
|
||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonResponse = objectMapper.writeValueAsString(
|
||||
ApiError.error(HttpStatus.FORBIDDEN.value(), "禁止访问,您没有权限访问此资源"));
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -31,16 +31,16 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
// 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
|
||||
int code = HttpStatus.UNAUTHORIZED.value();
|
||||
response.setStatus(code);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonResponse = objectMapper.writeValueAsString(
|
||||
ApiError.error(HttpStatus.UNAUTHORIZED.value(), "登录状态已过期,请重新登录"));
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
// 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
|
||||
int code = HttpStatus.UNAUTHORIZED.value();
|
||||
response.setStatus(code);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonResponse = objectMapper.writeValueAsString(
|
||||
ApiError.error(HttpStatus.UNAUTHORIZED.value(), "登录状态已过期,请重新登录"));
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
}
|
||||
|
||||
+47
-46
@@ -34,54 +34,55 @@ import org.springframework.web.filter.GenericFilterBean;
|
||||
|
||||
@Slf4j
|
||||
public class TokenFilter extends GenericFilterBean {
|
||||
private final TokenProvider tokenProvider;
|
||||
private final SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||
|
||||
/**
|
||||
* @param tokenProvider Token
|
||||
* @param systemUserOnlineInfoDAO 用户在线
|
||||
*/
|
||||
public TokenFilter(TokenProvider tokenProvider, SystemUserOnlineInfoDAO systemUserOnlineInfoDAO) {
|
||||
this.systemUserOnlineInfoDAO = systemUserOnlineInfoDAO;
|
||||
this.tokenProvider = tokenProvider;
|
||||
}
|
||||
private final TokenProvider tokenProvider;
|
||||
private final SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
|
||||
String token = resolveToken(httpServletRequest);
|
||||
// 对于 Token 为空的不需要去查 Redis
|
||||
if (StrUtil.isNotBlank(token)) {
|
||||
// 获取用户Token的Key
|
||||
String loginKey = tokenProvider.loginKey(token);
|
||||
SystemUserOnlineVo userOnlineVo = systemUserOnlineInfoDAO.queryUserOnlineModelByKey(loginKey);
|
||||
// 判断用户在线信息是否为空
|
||||
if (userOnlineVo != null) {
|
||||
// Token 续期判断
|
||||
tokenProvider.checkRenewal(token);
|
||||
// 获取认证信息,设置上下文
|
||||
Authentication authentication = tokenProvider.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
}
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
/**
|
||||
* @param tokenProvider Token
|
||||
* @param systemUserOnlineInfoDAO 用户在线
|
||||
*/
|
||||
public TokenFilter(TokenProvider tokenProvider, SystemUserOnlineInfoDAO systemUserOnlineInfoDAO) {
|
||||
this.systemUserOnlineInfoDAO = systemUserOnlineInfoDAO;
|
||||
this.tokenProvider = tokenProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初步检测Token
|
||||
*
|
||||
* @param request /
|
||||
* @return /
|
||||
*/
|
||||
private String resolveToken(HttpServletRequest request) {
|
||||
String bearerToken = request.getHeader(SystemConst.HEADER_NAME);
|
||||
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(SystemConst.TOKEN_PREFIX)) {
|
||||
// 去掉令牌前缀
|
||||
return bearerToken.replace(SystemConst.TOKEN_PREFIX + " ", "");
|
||||
} else {
|
||||
log.debug("非法Token:{}", bearerToken);
|
||||
}
|
||||
return null;
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
||||
String token = resolveToken(httpServletRequest);
|
||||
// 对于 Token 为空的不需要去查 Redis
|
||||
if (StrUtil.isNotBlank(token)) {
|
||||
// 获取用户Token的Key
|
||||
String loginKey = tokenProvider.loginKey(token);
|
||||
SystemUserOnlineVo userOnlineVo = systemUserOnlineInfoDAO.queryUserOnlineModelByKey(loginKey);
|
||||
// 判断用户在线信息是否为空
|
||||
if (userOnlineVo != null) {
|
||||
// Token 续期判断
|
||||
tokenProvider.checkRenewal(token);
|
||||
// 获取认证信息,设置上下文
|
||||
Authentication authentication = tokenProvider.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
}
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初步检测Token
|
||||
*
|
||||
* @param request /
|
||||
* @return /
|
||||
*/
|
||||
private String resolveToken(HttpServletRequest request) {
|
||||
String bearerToken = request.getHeader(SystemConst.HEADER_NAME);
|
||||
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(SystemConst.TOKEN_PREFIX)) {
|
||||
// 去掉令牌前缀
|
||||
return bearerToken.replace(SystemConst.TOKEN_PREFIX + " ", "");
|
||||
} else {
|
||||
log.debug("非法Token:{}", bearerToken);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+106
-103
@@ -47,118 +47,121 @@ import org.springframework.stereotype.Component;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TokenProvider implements InitializingBean {
|
||||
public static final String AUTHORITIES_UUID_KEY = "uid";
|
||||
public static final String AUTHORITIES_UID_KEY = "userId";
|
||||
@Autowired private KitRedisHelper redisHelper;
|
||||
@Autowired private AppProperties properties;
|
||||
|
||||
public static final String AUTHORITIES_UUID_KEY = "uid";
|
||||
public static final String AUTHORITIES_UID_KEY = "userId";
|
||||
@Autowired
|
||||
private KitRedisHelper redisHelper;
|
||||
@Autowired
|
||||
private AppProperties properties;
|
||||
// 0.11.x版本
|
||||
// private Key signingKey;
|
||||
// 0.12.x版本
|
||||
private SecretKey signingKey;
|
||||
private JwtParser jwtParser;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
// 解码Base64密钥并创建签名密钥
|
||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getJwt().getBase64Secret());
|
||||
signingKey = Keys.hmacShaKeyFor(keyBytes);
|
||||
// 0.11.x版本
|
||||
// private Key signingKey;
|
||||
// jwtParser = Jwts.parserBuilder()
|
||||
// // 使用预生成的签名密钥
|
||||
// .setSigningKey(signingKey).build();
|
||||
// 0.12.x版本
|
||||
private SecretKey signingKey;
|
||||
private JwtParser jwtParser;
|
||||
jwtParser = Jwts.parser().verifyWith(signingKey).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
// 解码Base64密钥并创建签名密钥
|
||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getJwt().getBase64Secret());
|
||||
signingKey = Keys.hmacShaKeyFor(keyBytes);
|
||||
// 0.11.x版本
|
||||
// jwtParser = Jwts.parserBuilder()
|
||||
// // 使用预生成的签名密钥
|
||||
// .setSigningKey(signingKey).build();
|
||||
// 0.12.x版本
|
||||
jwtParser = Jwts.parser().verifyWith(signingKey).build();
|
||||
}
|
||||
/**
|
||||
* 创建Token 设置永不过期, Token 的时间有效性转到Redis 维护
|
||||
*
|
||||
* @param user /
|
||||
* @return /
|
||||
*/
|
||||
public String createToken(SystemUserJwtVo user) {
|
||||
// 设置参数
|
||||
Map<String, Object> claims = new HashMap<>(6);
|
||||
// 设置用户ID
|
||||
claims.put(AUTHORITIES_UID_KEY, user.getUser().getId());
|
||||
// 设置UUID,确保每次Token不一样
|
||||
claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
|
||||
// 0.11.x版本
|
||||
// 直接调用 Jwts.builder() 创建新实例Add commentMore actions
|
||||
// return Jwts.builder()
|
||||
// // 设置自定义 Claims
|
||||
// .setClaims(claims)
|
||||
// // 设置主题
|
||||
// .setSubject(user.getUsername())
|
||||
// // 使用预生成的签名密钥和算法签名
|
||||
// .signWith(signingKey, SignatureAlgorithm.HS512).compact();
|
||||
// 0.12.x版本
|
||||
return Jwts.builder().claims(claims).subject(user.getUsername()).signWith(signingKey).compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Token 设置永不过期, Token 的时间有效性转到Redis 维护
|
||||
*
|
||||
* @param user /
|
||||
* @return /
|
||||
*/
|
||||
public String createToken(SystemUserJwtVo user) {
|
||||
// 设置参数
|
||||
Map<String, Object> claims = new HashMap<>(6);
|
||||
// 设置用户ID
|
||||
claims.put(AUTHORITIES_UID_KEY, user.getUser().getId());
|
||||
// 设置UUID,确保每次Token不一样
|
||||
claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
|
||||
// 0.11.x版本
|
||||
// 直接调用 Jwts.builder() 创建新实例Add commentMore actions
|
||||
// return Jwts.builder()
|
||||
// // 设置自定义 Claims
|
||||
// .setClaims(claims)
|
||||
// // 设置主题
|
||||
// .setSubject(user.getUsername())
|
||||
// // 使用预生成的签名密钥和算法签名
|
||||
// .signWith(signingKey, SignatureAlgorithm.HS512).compact();
|
||||
// 0.12.x版本
|
||||
return Jwts.builder().claims(claims).subject(user.getUsername()).signWith(signingKey).compact();
|
||||
}
|
||||
/**
|
||||
* 依据Token 获取鉴权信息
|
||||
*
|
||||
* @param token /
|
||||
* @return /
|
||||
*/
|
||||
Authentication getAuthentication(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
|
||||
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* 依据Token 获取鉴权信息
|
||||
*
|
||||
* @param token /
|
||||
* @return /
|
||||
*/
|
||||
Authentication getAuthentication(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
|
||||
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
|
||||
}
|
||||
public Claims getClaims(String token) {
|
||||
// 0.11.x版本
|
||||
// return jwtParser.parseClaimsJws(token).getBody();
|
||||
// 0.12.x版本
|
||||
return jwtParser.parseSignedClaims(token).getPayload();
|
||||
}
|
||||
|
||||
public Claims getClaims(String token) {
|
||||
// 0.11.x版本
|
||||
// return jwtParser.parseClaimsJws(token).getBody();
|
||||
// 0.12.x版本
|
||||
return jwtParser.parseSignedClaims(token).getPayload();
|
||||
/**
|
||||
* @param token 需要检查的token
|
||||
*/
|
||||
public void checkRenewal(String token) {
|
||||
// 判断是否续期token,计算token的过期时间
|
||||
String loginKey = loginKey(token);
|
||||
long time = redisHelper.getExpire(loginKey) * 1000;
|
||||
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
|
||||
// 判断当前时间与过期时间的时间差
|
||||
long differ = expireDate.getTime() - System.currentTimeMillis();
|
||||
// 如果在续期检查的范围内,则续期
|
||||
if (differ <= properties.getJwt().getDetect()) {
|
||||
long renew = time + properties.getJwt().getRenew();
|
||||
redisHelper.expire(loginKey, renew, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token 需要检查的token
|
||||
*/
|
||||
public void checkRenewal(String token) {
|
||||
// 判断是否续期token,计算token的过期时间
|
||||
String loginKey = loginKey(token);
|
||||
long time = redisHelper.getExpire(loginKey) * 1000;
|
||||
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int)time);
|
||||
// 判断当前时间与过期时间的时间差
|
||||
long differ = expireDate.getTime() - System.currentTimeMillis();
|
||||
// 如果在续期检查的范围内,则续期
|
||||
if (differ <= properties.getJwt().getDetect()) {
|
||||
long renew = time + properties.getJwt().getRenew();
|
||||
redisHelper.expire(loginKey, renew, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
public String getToken(HttpServletRequest request) {
|
||||
final String requestHeader = request.getHeader(SystemConst.HEADER_NAME);
|
||||
if (requestHeader != null && requestHeader.startsWith(SystemConst.TOKEN_PREFIX)) {
|
||||
return requestHeader.substring(7);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getToken(HttpServletRequest request) {
|
||||
final String requestHeader = request.getHeader(SystemConst.HEADER_NAME);
|
||||
if (requestHeader != null && requestHeader.startsWith(SystemConst.TOKEN_PREFIX)) {
|
||||
return requestHeader.substring(7);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 获取登录用户RedisKey
|
||||
*
|
||||
* @param token /
|
||||
* @return key
|
||||
*/
|
||||
public String loginKey(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return SystemCacheKey.ONLINE_USER + claims.getSubject() + ":" + getId(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户RedisKey
|
||||
*
|
||||
* @param token /
|
||||
* @return key
|
||||
*/
|
||||
public String loginKey(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return SystemCacheKey.ONLINE_USER + claims.getSubject() + ":" + getId(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话编号
|
||||
*
|
||||
* @param token /
|
||||
* @return /
|
||||
*/
|
||||
public String getId(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return claims.get(AUTHORITIES_UUID_KEY, String.class);
|
||||
}
|
||||
/**
|
||||
* 获取会话编号
|
||||
*
|
||||
* @param token /
|
||||
* @return /
|
||||
*/
|
||||
public String getId(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return claims.get(AUTHORITIES_UUID_KEY, String.class);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-13
@@ -28,18 +28,21 @@ import org.springframework.stereotype.Component;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ActiveJobRegister implements ApplicationRunner {
|
||||
@Autowired private SystemQuartzJobService systemQuartzJobService;
|
||||
@Autowired private QuartzManage quartzManage;
|
||||
|
||||
/**
|
||||
* 项目启动时重新激活启用的定时任务
|
||||
*
|
||||
* @param applicationArguments /
|
||||
*/
|
||||
@Override
|
||||
public void run(ApplicationArguments applicationArguments) {
|
||||
List<SystemQuartzJobTb> quartzJobs = systemQuartzJobService.listEnableQuartzJob();
|
||||
quartzJobs.forEach(quartzManage::addJob);
|
||||
log.info("Timing task injection complete");
|
||||
}
|
||||
@Autowired
|
||||
private SystemQuartzJobService systemQuartzJobService;
|
||||
@Autowired
|
||||
private QuartzManage quartzManage;
|
||||
|
||||
/**
|
||||
* 项目启动时重新激活启用的定时任务
|
||||
*
|
||||
* @param applicationArguments /
|
||||
*/
|
||||
@Override
|
||||
public void run(ApplicationArguments applicationArguments) {
|
||||
List<SystemQuartzJobTb> quartzJobs = systemQuartzJobService.listEnableQuartzJob();
|
||||
quartzJobs.forEach(quartzManage::addJob);
|
||||
log.info("Timing task injection complete");
|
||||
}
|
||||
}
|
||||
|
||||
+82
-81
@@ -43,91 +43,92 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
|
||||
@Slf4j
|
||||
public class ExecutionJobBean extends QuartzJobBean {
|
||||
/**
|
||||
* 此处仅供参考,可根据任务执行情况自定义线程池参数
|
||||
*/
|
||||
private final ThreadPoolTaskExecutor executor = KitSpringBeanHolder.getBean("taskAsync");
|
||||
|
||||
@Override
|
||||
public void executeInternal(JobExecutionContext context) {
|
||||
// 获取任务
|
||||
SystemQuartzJobTb quartzJob = (SystemQuartzJobTb)context.getMergedJobDataMap().get(SystemQuartzJobTb.JOB_KEY);
|
||||
// 获取spring bean
|
||||
SystemQuartzLogMapper quartzLogMapper = KitSpringBeanHolder.getBean(SystemQuartzLogMapper.class);
|
||||
SystemQuartzJobService systemQuartzJobService = KitSpringBeanHolder.getBean(SystemQuartzJobService.class);
|
||||
KitRedisHelper redisHelper = KitSpringBeanHolder.getBean(KitRedisHelper.class);
|
||||
/**
|
||||
* 此处仅供参考,可根据任务执行情况自定义线程池参数
|
||||
*/
|
||||
private final ThreadPoolTaskExecutor executor = KitSpringBeanHolder.getBean("taskAsync");
|
||||
|
||||
String uuid = quartzJob.getUuid();
|
||||
@Override
|
||||
public void executeInternal(JobExecutionContext context) {
|
||||
// 获取任务
|
||||
SystemQuartzJobTb quartzJob = (SystemQuartzJobTb) context.getMergedJobDataMap().get(SystemQuartzJobTb.JOB_KEY);
|
||||
// 获取spring bean
|
||||
SystemQuartzLogMapper quartzLogMapper = KitSpringBeanHolder.getBean(SystemQuartzLogMapper.class);
|
||||
SystemQuartzJobService systemQuartzJobService = KitSpringBeanHolder.getBean(SystemQuartzJobService.class);
|
||||
KitRedisHelper redisHelper = KitSpringBeanHolder.getBean(KitRedisHelper.class);
|
||||
|
||||
SystemQuartzLogTb quartzLog = new SystemQuartzLogTb();
|
||||
quartzLog.setJobName(quartzJob.getJobName());
|
||||
quartzLog.setBeanName(quartzJob.getBeanName());
|
||||
quartzLog.setMethodName(quartzJob.getMethodName());
|
||||
quartzLog.setParams(quartzJob.getParams());
|
||||
long startTime = System.currentTimeMillis();
|
||||
quartzLog.setCronExpression(quartzJob.getCronExpression());
|
||||
try {
|
||||
// 执行任务
|
||||
QuartzRunnable task =
|
||||
new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), quartzJob.getParams());
|
||||
Future<?> future = executor.submit(task);
|
||||
// 忽略任务执行结果
|
||||
future.get();
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
quartzLog.setTime(times);
|
||||
if (StrUtil.isNotBlank(uuid)) {
|
||||
redisHelper.set(uuid, true);
|
||||
}
|
||||
// 任务状态
|
||||
quartzLog.setIsSuccess(true);
|
||||
log.info("任务执行成功,任务名称:{}, 执行时间:{}毫秒", quartzJob.getJobName(), times);
|
||||
// 判断是否存在子任务
|
||||
if (StrUtil.isNotBlank(quartzJob.getSubTask())) {
|
||||
String[] tasks = quartzJob.getSubTask().split("[,,]");
|
||||
// 执行子任务
|
||||
systemQuartzJobService.startSubQuartJob(tasks);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (StrUtil.isNotBlank(uuid)) {
|
||||
redisHelper.set(uuid, false);
|
||||
}
|
||||
log.error("任务执行失败,任务名称:{}", quartzJob.getJobName(), e);
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
quartzLog.setTime(times);
|
||||
// 任务状态 0:成功 1:失败
|
||||
quartzLog.setIsSuccess(false);
|
||||
quartzLog.setExceptionDetail(ExceptionUtil.stacktraceToString(e));
|
||||
// 任务如果失败了则暂停
|
||||
if (quartzJob.getPauseAfterFailure() != null && quartzJob.getPauseAfterFailure()) {
|
||||
quartzJob.setIsPause(false);
|
||||
// 更新状态
|
||||
systemQuartzJobService.switchQuartzJobStatus(quartzJob);
|
||||
}
|
||||
if (quartzJob.getEmail() != null) {
|
||||
SystemEmailService emailService = KitSpringBeanHolder.getBean(SystemEmailService.class);
|
||||
// 邮箱报警
|
||||
if (StrUtil.isNotBlank(quartzJob.getEmail())) {
|
||||
SystemSendEmailArgs sendEmailRequest = taskAlarm(quartzJob, ExceptionUtil.stacktraceToString(e));
|
||||
emailService.sendEmail(sendEmailRequest);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
quartzLogMapper.insert(quartzLog);
|
||||
String uuid = quartzJob.getUuid();
|
||||
|
||||
SystemQuartzLogTb quartzLog = new SystemQuartzLogTb();
|
||||
quartzLog.setJobName(quartzJob.getJobName());
|
||||
quartzLog.setBeanName(quartzJob.getBeanName());
|
||||
quartzLog.setMethodName(quartzJob.getMethodName());
|
||||
quartzLog.setParams(quartzJob.getParams());
|
||||
long startTime = System.currentTimeMillis();
|
||||
quartzLog.setCronExpression(quartzJob.getCronExpression());
|
||||
try {
|
||||
// 执行任务
|
||||
QuartzRunnable task =
|
||||
new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), quartzJob.getParams());
|
||||
Future<?> future = executor.submit(task);
|
||||
// 忽略任务执行结果
|
||||
future.get();
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
quartzLog.setTime(times);
|
||||
if (StrUtil.isNotBlank(uuid)) {
|
||||
redisHelper.set(uuid, true);
|
||||
}
|
||||
// 任务状态
|
||||
quartzLog.setIsSuccess(true);
|
||||
log.info("任务执行成功,任务名称:{}, 执行时间:{}毫秒", quartzJob.getJobName(), times);
|
||||
// 判断是否存在子任务
|
||||
if (StrUtil.isNotBlank(quartzJob.getSubTask())) {
|
||||
String[] tasks = quartzJob.getSubTask().split("[,,]");
|
||||
// 执行子任务
|
||||
systemQuartzJobService.startSubQuartJob(tasks);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (StrUtil.isNotBlank(uuid)) {
|
||||
redisHelper.set(uuid, false);
|
||||
}
|
||||
log.error("任务执行失败,任务名称:{}", quartzJob.getJobName(), e);
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
quartzLog.setTime(times);
|
||||
// 任务状态 0:成功 1:失败
|
||||
quartzLog.setIsSuccess(false);
|
||||
quartzLog.setExceptionDetail(ExceptionUtil.stacktraceToString(e));
|
||||
// 任务如果失败了则暂停
|
||||
if (quartzJob.getPauseAfterFailure() != null && quartzJob.getPauseAfterFailure()) {
|
||||
quartzJob.setIsPause(false);
|
||||
// 更新状态
|
||||
systemQuartzJobService.switchQuartzJobStatus(quartzJob);
|
||||
}
|
||||
if (quartzJob.getEmail() != null) {
|
||||
SystemEmailService emailService = KitSpringBeanHolder.getBean(SystemEmailService.class);
|
||||
// 邮箱报警
|
||||
if (StrUtil.isNotBlank(quartzJob.getEmail())) {
|
||||
SystemSendEmailArgs sendEmailRequest = taskAlarm(quartzJob, ExceptionUtil.stacktraceToString(e));
|
||||
emailService.sendEmail(sendEmailRequest);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
quartzLogMapper.insert(quartzLog);
|
||||
}
|
||||
}
|
||||
|
||||
private SystemSendEmailArgs taskAlarm(SystemQuartzJobTb quartzJob, String msg) {
|
||||
SystemSendEmailArgs sendEmailRequest = new SystemSendEmailArgs();
|
||||
sendEmailRequest.setSubject("定时任务【" + quartzJob.getJobName() + "】执行失败,请尽快处理!");
|
||||
Map<String, Object> data = new HashMap<>(16);
|
||||
data.put("task", quartzJob);
|
||||
data.put("msg", msg);
|
||||
TemplateEngine engine =
|
||||
TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH));
|
||||
Template template = engine.getTemplate("SystemQuartzJobTaskAlarmTemplate.ftl");
|
||||
sendEmailRequest.setContent(template.render(data));
|
||||
List<String> emails = Arrays.asList(quartzJob.getEmail().split("[,,]"));
|
||||
sendEmailRequest.setTos(emails);
|
||||
return sendEmailRequest;
|
||||
}
|
||||
private SystemSendEmailArgs taskAlarm(SystemQuartzJobTb quartzJob, String msg) {
|
||||
SystemSendEmailArgs sendEmailRequest = new SystemSendEmailArgs();
|
||||
sendEmailRequest.setSubject("定时任务【" + quartzJob.getJobName() + "】执行失败,请尽快处理!");
|
||||
Map<String, Object> data = new HashMap<>(16);
|
||||
data.put("task", quartzJob);
|
||||
data.put("msg", msg);
|
||||
TemplateEngine engine =
|
||||
TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH));
|
||||
Template template = engine.getTemplate("SystemQuartzJobTaskAlarmTemplate.ftl");
|
||||
sendEmailRequest.setContent(template.render(data));
|
||||
List<String> emails = Arrays.asList(quartzJob.getEmail().split("[,,]"));
|
||||
sendEmailRequest.setTos(emails);
|
||||
return sendEmailRequest;
|
||||
}
|
||||
}
|
||||
|
||||
+123
-122
@@ -39,145 +39,146 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class QuartzManage {
|
||||
|
||||
private static final String JOB_NAME = "TASK_";
|
||||
private static final String JOB_NAME = "TASK_";
|
||||
|
||||
@Resource private Scheduler scheduler;
|
||||
@Resource
|
||||
private Scheduler scheduler;
|
||||
|
||||
public void addJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
// 构建job信息
|
||||
JobDetail jobDetail =
|
||||
JobBuilder.newJob(ExecutionJobBean.class).withIdentity(JOB_NAME + quartzJob.getId()).build();
|
||||
public void addJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
// 构建job信息
|
||||
JobDetail jobDetail =
|
||||
JobBuilder.newJob(ExecutionJobBean.class).withIdentity(JOB_NAME + quartzJob.getId()).build();
|
||||
|
||||
// 通过触发器名和cron 表达式创建 Trigger
|
||||
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(JOB_NAME + quartzJob.getId()).startNow()
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression())).build();
|
||||
// 通过触发器名和cron 表达式创建 Trigger
|
||||
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(JOB_NAME + quartzJob.getId()).startNow()
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression())).build();
|
||||
|
||||
trigger.getJobDataMap().put(SystemQuartzJobTb.JOB_KEY, quartzJob);
|
||||
trigger.getJobDataMap().put(SystemQuartzJobTb.JOB_KEY, quartzJob);
|
||||
|
||||
// 重置启动时间
|
||||
((CronTriggerImpl)trigger).setStartTime(new Date());
|
||||
// 重置启动时间
|
||||
((CronTriggerImpl) trigger).setStartTime(new Date());
|
||||
|
||||
// 执行定时任务,如果是持久化的,这里会报错,捕获输出
|
||||
try {
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
} catch (ObjectAlreadyExistsException e) {
|
||||
log.warn("定时任务已存在,跳过加载");
|
||||
}
|
||||
// 执行定时任务,如果是持久化的,这里会报错,捕获输出
|
||||
try {
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
} catch (ObjectAlreadyExistsException e) {
|
||||
log.warn("定时任务已存在,跳过加载");
|
||||
}
|
||||
|
||||
// 暂停任务
|
||||
if (quartzJob.getIsPause()) {
|
||||
pauseJob(quartzJob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建定时任务失败", e);
|
||||
throw new BadRequestException("创建定时任务失败");
|
||||
}
|
||||
// 暂停任务
|
||||
if (quartzJob.getIsPause()) {
|
||||
pauseJob(quartzJob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建定时任务失败", e);
|
||||
throw new BadRequestException("创建定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新job cron表达式
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void updateJobCron(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
|
||||
}
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression());
|
||||
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
|
||||
// 重置启动时间
|
||||
((CronTriggerImpl)trigger).setStartTime(new Date());
|
||||
trigger.getJobDataMap().put(SystemQuartzJobTb.JOB_KEY, quartzJob);
|
||||
/**
|
||||
* 更新job cron表达式
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void updateJobCron(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
}
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression());
|
||||
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
|
||||
// 重置启动时间
|
||||
((CronTriggerImpl) trigger).setStartTime(new Date());
|
||||
trigger.getJobDataMap().put(SystemQuartzJobTb.JOB_KEY, quartzJob);
|
||||
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
// 暂停任务
|
||||
if (quartzJob.getIsPause()) {
|
||||
pauseJob(quartzJob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("更新定时任务失败", e);
|
||||
throw new BadRequestException("更新定时任务失败");
|
||||
}
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
// 暂停任务
|
||||
if (quartzJob.getIsPause()) {
|
||||
pauseJob(quartzJob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("更新定时任务失败", e);
|
||||
throw new BadRequestException("更新定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void deleteJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.pauseJob(jobKey);
|
||||
scheduler.deleteJob(jobKey);
|
||||
} catch (Exception e) {
|
||||
log.error("删除定时任务失败", e);
|
||||
throw new BadRequestException("删除定时任务失败");
|
||||
}
|
||||
/**
|
||||
* 删除一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void deleteJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.pauseJob(jobKey);
|
||||
scheduler.deleteJob(jobKey);
|
||||
} catch (Exception e) {
|
||||
log.error("删除定时任务失败", e);
|
||||
throw new BadRequestException("删除定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void resumeJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
}
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.resumeJob(jobKey);
|
||||
} catch (Exception e) {
|
||||
log.error("恢复定时任务失败", e);
|
||||
throw new BadRequestException("恢复定时任务失败");
|
||||
}
|
||||
/**
|
||||
* 恢复一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void resumeJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
}
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.resumeJob(jobKey);
|
||||
} catch (Exception e) {
|
||||
log.error("恢复定时任务失败", e);
|
||||
throw new BadRequestException("恢复定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void runJobNow(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
}
|
||||
JobDataMap dataMap = new JobDataMap();
|
||||
dataMap.put(SystemQuartzJobTb.JOB_KEY, quartzJob);
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.triggerJob(jobKey, dataMap);
|
||||
} catch (Exception e) {
|
||||
log.error("定时任务执行失败", e);
|
||||
throw new BadRequestException("定时任务执行失败");
|
||||
}
|
||||
/**
|
||||
* 立即执行job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void runJobNow(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
}
|
||||
JobDataMap dataMap = new JobDataMap();
|
||||
dataMap.put(SystemQuartzJobTb.JOB_KEY, quartzJob);
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.triggerJob(jobKey, dataMap);
|
||||
} catch (Exception e) {
|
||||
log.error("定时任务执行失败", e);
|
||||
throw new BadRequestException("定时任务执行失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void pauseJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.pauseJob(jobKey);
|
||||
} catch (Exception e) {
|
||||
log.error("定时任务暂停失败", e);
|
||||
throw new BadRequestException("定时任务暂停失败");
|
||||
}
|
||||
/**
|
||||
* 暂停一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
*/
|
||||
public void pauseJob(SystemQuartzJobTb quartzJob) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.pauseJob(jobKey);
|
||||
} catch (Exception e) {
|
||||
log.error("定时任务暂停失败", e);
|
||||
throw new BadRequestException("定时任务暂停失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-11
@@ -28,17 +28,19 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class OssStorageConfiguration {
|
||||
@Autowired private AppProperties properties;
|
||||
|
||||
@Bean
|
||||
public MinioClient minioClient() {
|
||||
try {
|
||||
OSSConfigModel minio = properties.getOss().getMinio();
|
||||
return MinioClient.builder().endpoint(minio.getEndpoint())
|
||||
.credentials(minio.getAccessKey(), minio.getSecretKey()).build();
|
||||
} catch (Exception e) {
|
||||
log.error("创建Minio客户端失败", e);
|
||||
throw new BadRequestException("创建Minio客户端失败");
|
||||
}
|
||||
@Autowired
|
||||
private AppProperties properties;
|
||||
|
||||
@Bean
|
||||
public MinioClient minioClient() {
|
||||
try {
|
||||
OSSConfigModel minio = properties.getOss().getMinio();
|
||||
return MinioClient.builder().endpoint(minio.getEndpoint())
|
||||
.credentials(minio.getAccessKey(), minio.getSecretKey()).build();
|
||||
} catch (Exception e) {
|
||||
log.error("创建Minio客户端失败", e);
|
||||
throw new BadRequestException("创建Minio客户端失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-20
@@ -31,26 +31,29 @@ import org.springframework.util.unit.DataSize;
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class MultipartConfig {
|
||||
@Value("${spring.application.name}") private String name;
|
||||
@Autowired private AppProperties properties;
|
||||
|
||||
/**
|
||||
* 文件上传临时路径
|
||||
*/
|
||||
@Bean
|
||||
public MultipartConfigElement multipartConfigElement() {
|
||||
MultipartConfigFactory factory = new MultipartConfigFactory();
|
||||
factory.setMaxFileSize(DataSize.ofMegabytes(properties.getOss().getMaxSize()));
|
||||
factory.setMaxRequestSize(DataSize.ofMegabytes(properties.getOss().getMaxSize()));
|
||||
String location = System.getProperty("user.home") + "/" + name + "/tmp";
|
||||
File tmpFile = new File(location);
|
||||
if (!tmpFile.exists()) {
|
||||
if (!tmpFile.mkdirs()) {
|
||||
log.error("创建临时文件失败");
|
||||
throw new BadRequestException("创建临时文件失败");
|
||||
}
|
||||
}
|
||||
factory.setLocation(location);
|
||||
return factory.createMultipartConfig();
|
||||
@Value("${spring.application.name}")
|
||||
private String name;
|
||||
@Autowired
|
||||
private AppProperties properties;
|
||||
|
||||
/**
|
||||
* 文件上传临时路径
|
||||
*/
|
||||
@Bean
|
||||
public MultipartConfigElement multipartConfigElement() {
|
||||
MultipartConfigFactory factory = new MultipartConfigFactory();
|
||||
factory.setMaxFileSize(DataSize.ofMegabytes(properties.getOss().getMaxSize()));
|
||||
factory.setMaxRequestSize(DataSize.ofMegabytes(properties.getOss().getMaxSize()));
|
||||
String location = System.getProperty("user.home") + "/" + name + "/tmp";
|
||||
File tmpFile = new File(location);
|
||||
if (!tmpFile.exists()) {
|
||||
if (!tmpFile.mkdirs()) {
|
||||
log.error("创建临时文件失败");
|
||||
throw new BadRequestException("创建临时文件失败");
|
||||
}
|
||||
}
|
||||
factory.setLocation(location);
|
||||
return factory.createMultipartConfig();
|
||||
}
|
||||
}
|
||||
+301
-298
@@ -59,324 +59,327 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MinioRepository {
|
||||
@Autowired private AppProperties properties;
|
||||
@Autowired private MinioClient minioClient;
|
||||
|
||||
/**
|
||||
* 检查存储bucket是否存在
|
||||
*
|
||||
* @param bucketName Bucket 名称
|
||||
* @return boolean 存在返回 true,否则返回 false
|
||||
*/
|
||||
public boolean existsBucket(String bucketName) {
|
||||
try {
|
||||
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
} catch (Exception e) {
|
||||
log.error("检查 bucket 是否存在失败,bucketName: {}, 错误信息", bucketName, e);
|
||||
return false;
|
||||
}
|
||||
@Autowired
|
||||
private AppProperties properties;
|
||||
@Autowired
|
||||
private MinioClient minioClient;
|
||||
|
||||
/**
|
||||
* 检查存储bucket是否存在
|
||||
*
|
||||
* @param bucketName Bucket 名称
|
||||
* @return boolean 存在返回 true,否则返回 false
|
||||
*/
|
||||
public boolean existsBucket(String bucketName) {
|
||||
try {
|
||||
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
} catch (Exception e) {
|
||||
log.error("检查 bucket 是否存在失败,bucketName: {}, 错误信息", bucketName, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建存储bucket
|
||||
*
|
||||
* @param bucketName Bucket 名称
|
||||
* @return boolean 创建成功返回 true,否则返回 false
|
||||
*/
|
||||
public boolean createBucket(String bucketName) {
|
||||
try {
|
||||
if (!existsBucket(bucketName)) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
log.info("Bucket 创建成功,bucketName: {}", bucketName);
|
||||
return true;
|
||||
} else {
|
||||
log.warn("Bucket 已经存在,bucketName: {}", bucketName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建 bucket 失败,bucketName: {}, 错误信息", bucketName, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除存储bucket
|
||||
*
|
||||
* @param bucketName Bucket 名称
|
||||
* @return boolean 删除成功返回 true,否则返回 false
|
||||
*/
|
||||
public boolean removeBucket(String bucketName) {
|
||||
try {
|
||||
if (existsBucket(bucketName)) {
|
||||
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
|
||||
log.info("Bucket 删除成功,bucketName: {}", bucketName);
|
||||
return true;
|
||||
} else {
|
||||
log.warn("Bucket 不存在,bucketName: {}", bucketName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("删除 bucket 失败,bucketName: {}, 错误信息", bucketName, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有 bucket 列表
|
||||
*
|
||||
* @return List<Bucket> 所有的 Bucket 列表
|
||||
*/
|
||||
public List<Bucket> queryAllBuckets() {
|
||||
try {
|
||||
return minioClient.listBuckets();
|
||||
} catch (Exception e) {
|
||||
log.error("获取所有 buckets 失败,错误信息", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param tempFile 文件
|
||||
* @param originalFilename 源文件名
|
||||
* @param fileSize 文件大小
|
||||
* @param contentType 文件类型
|
||||
* @param md5 文件md5
|
||||
* @return String 上传后的文件名,上传失败返回 null
|
||||
*/
|
||||
public SystemOssStorageTb upload(File tempFile, String originalFilename, long fileSize, String contentType,
|
||||
String md5) {
|
||||
StorageOSSModel ossConfig = properties.getOss();
|
||||
OSSConfigModel ossMinioConfig = ossConfig.getMinio();
|
||||
String type = FileTypeUtil.getType(tempFile);
|
||||
String prefix = KitFileUtil.getPrefix(tempFile);
|
||||
String suffix = KitFileUtil.getSuffix(tempFile);
|
||||
|
||||
String fileCode = IdUtil.fastSimpleUUID();
|
||||
String fileName = fileCode + FileUtil.getSuffix(originalFilename);
|
||||
String objectName = KitDateUtil.getNowDateStr() + "/" + fileName;
|
||||
log.info("上传文件,原文件名:{},上传后文件名:{}", originalFilename, fileName);
|
||||
String fileUrl = ossMinioConfig.getEndpoint() + "/" + ossMinioConfig.getBucketName() + "/" + objectName;
|
||||
|
||||
SystemOssStorageTb systemOssStorageTb = new SystemOssStorageTb();
|
||||
systemOssStorageTb.setServiceType("minio");
|
||||
systemOssStorageTb.setEndpoint(ossMinioConfig.getEndpoint());
|
||||
systemOssStorageTb.setBucketName(StrUtil.trim(ossMinioConfig.getBucketName()));
|
||||
systemOssStorageTb.setFileName(originalFilename);
|
||||
systemOssStorageTb.setFileSize(fileSize);
|
||||
systemOssStorageTb.setFileMime(type);
|
||||
systemOssStorageTb.setFilePrefix(prefix);
|
||||
systemOssStorageTb.setFileSuffix(suffix);
|
||||
systemOssStorageTb.setFileMd5(md5);
|
||||
systemOssStorageTb.setFileUrl(fileUrl);
|
||||
systemOssStorageTb.setFileCode(fileCode);
|
||||
systemOssStorageTb.setObjectName(objectName);
|
||||
|
||||
try (InputStream fileInputStream = KitFileUtil.getInputStream(tempFile)) {
|
||||
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(ossMinioConfig.getBucketName()).object(objectName)
|
||||
.stream(fileInputStream, fileSize, -1).contentType(contentType).build();
|
||||
minioClient.putObject(objectArgs);
|
||||
log.info("文件上传成功,并删除临时文件,文件名:{}", originalFilename);
|
||||
return systemOssStorageTb;
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败,文件名:{},错误信息", originalFilename, e);
|
||||
} finally {
|
||||
try {
|
||||
KitFileUtil.del(tempFile);
|
||||
} catch (IORuntimeException e) {
|
||||
// 删除失败忽略
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化文件上传 文件上传:优化版
|
||||
*
|
||||
* @param file
|
||||
* @return {@link String }
|
||||
*/
|
||||
public String optimizedUpload(MultipartFile file) {
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (StrUtil.isBlank(originalFilename)) {
|
||||
throw new BadRequestException("文件名不能为空");
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建存储bucket
|
||||
*
|
||||
* @param bucketName Bucket 名称
|
||||
* @return boolean 创建成功返回 true,否则返回 false
|
||||
*/
|
||||
public boolean createBucket(String bucketName) {
|
||||
try {
|
||||
if (!existsBucket(bucketName)) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
log.info("Bucket 创建成功,bucketName: {}", bucketName);
|
||||
return true;
|
||||
} else {
|
||||
log.warn("Bucket 已经存在,bucketName: {}", bucketName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建 bucket 失败,bucketName: {}, 错误信息", bucketName, e);
|
||||
}
|
||||
return false;
|
||||
long size = file.getSize();
|
||||
KitFileUtil.checkSize(properties.getOss().getMaxSize(), size);
|
||||
|
||||
String fileName = UUID.randomUUID() + FileUtil.getSuffix(originalFilename);
|
||||
// yyyy/MM/dd/fileName.xxx
|
||||
String objectName = KitDateUtil.getNowDateTimeStr() + "/" + fileName;
|
||||
|
||||
log.info("准备上传文件,原文件名:{},上传后文件名:{}", originalFilename, fileName);
|
||||
try (InputStream fileInputStream = file.getInputStream()) {
|
||||
PutObjectArgs objectArgs =
|
||||
PutObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(objectName)
|
||||
.stream(fileInputStream, file.getSize(), -1).contentType(file.getContentType()).build();
|
||||
// 使用重试机制进行上传
|
||||
uploadWithRetry(objectArgs, 3);
|
||||
log.info("文件上传成功,objectName: {}", objectName);
|
||||
return objectName;
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败,文件名:{},错误信息", originalFilename, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除存储bucket
|
||||
*
|
||||
* @param bucketName Bucket 名称
|
||||
* @return boolean 删除成功返回 true,否则返回 false
|
||||
*/
|
||||
public boolean removeBucket(String bucketName) {
|
||||
try {
|
||||
if (existsBucket(bucketName)) {
|
||||
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
|
||||
log.info("Bucket 删除成功,bucketName: {}", bucketName);
|
||||
return true;
|
||||
} else {
|
||||
log.warn("Bucket 不存在,bucketName: {}", bucketName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("删除 bucket 失败,bucketName: {}, 错误信息", bucketName, e);
|
||||
/**
|
||||
* 上传重试机制
|
||||
*
|
||||
* @param objectArgs 对象参数
|
||||
* @param maxRetries 最大重试次数
|
||||
* @throws Exception 例外
|
||||
*/
|
||||
private void uploadWithRetry(PutObjectArgs objectArgs, int maxRetries) throws Exception {
|
||||
int attempt = 0;
|
||||
while (attempt < maxRetries) {
|
||||
try {
|
||||
minioClient.putObject(objectArgs);
|
||||
return; // 上传成功,返回
|
||||
} catch (Exception e) {
|
||||
attempt++;
|
||||
log.warn("上传失败,第 {} 次尝试,错误信息", attempt, e);
|
||||
if (attempt == maxRetries) {
|
||||
throw new BadRequestException("上传失败,已达到最大重试次数");
|
||||
}
|
||||
return false;
|
||||
// 等待一段时间后重试
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有 bucket 列表
|
||||
*
|
||||
* @return List<Bucket> 所有的 Bucket 列表
|
||||
*/
|
||||
public List<Bucket> queryAllBuckets() {
|
||||
try {
|
||||
return minioClient.listBuckets();
|
||||
} catch (Exception e) {
|
||||
log.error("获取所有 buckets 失败,错误信息", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
/**
|
||||
* 生成文件的预签名 URL,用于文件预览
|
||||
*
|
||||
* @param fullFileName 文件完整路径
|
||||
* @return String 预签名 URL
|
||||
*/
|
||||
public String generatePreviewUrl(String fullFileName) {
|
||||
if (StrUtil.isBlank(fullFileName)) {
|
||||
log.warn("文件名为空,无法生成预签名 URL");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param tempFile 文件
|
||||
* @param originalFilename 源文件名
|
||||
* @param fileSize 文件大小
|
||||
* @param contentType 文件类型
|
||||
* @param md5 文件md5
|
||||
* @return String 上传后的文件名,上传失败返回 null
|
||||
*/
|
||||
public SystemOssStorageTb upload(File tempFile, String originalFilename, long fileSize, String contentType,
|
||||
String md5) {
|
||||
StorageOSSModel ossConfig = properties.getOss();
|
||||
OSSConfigModel ossMinioConfig = ossConfig.getMinio();
|
||||
String type = FileTypeUtil.getType(tempFile);
|
||||
String prefix = KitFileUtil.getPrefix(tempFile);
|
||||
String suffix = KitFileUtil.getSuffix(tempFile);
|
||||
|
||||
String fileCode = IdUtil.fastSimpleUUID();
|
||||
String fileName = fileCode + FileUtil.getSuffix(originalFilename);
|
||||
String objectName = KitDateUtil.getNowDateStr() + "/" + fileName;
|
||||
log.info("上传文件,原文件名:{},上传后文件名:{}", originalFilename, fileName);
|
||||
String fileUrl = ossMinioConfig.getEndpoint() + "/" + ossMinioConfig.getBucketName() + "/" + objectName;
|
||||
|
||||
SystemOssStorageTb systemOssStorageTb = new SystemOssStorageTb();
|
||||
systemOssStorageTb.setServiceType("minio");
|
||||
systemOssStorageTb.setEndpoint(ossMinioConfig.getEndpoint());
|
||||
systemOssStorageTb.setBucketName(StrUtil.trim(ossMinioConfig.getBucketName()));
|
||||
systemOssStorageTb.setFileName(originalFilename);
|
||||
systemOssStorageTb.setFileSize(fileSize);
|
||||
systemOssStorageTb.setFileMime(type);
|
||||
systemOssStorageTb.setFilePrefix(prefix);
|
||||
systemOssStorageTb.setFileSuffix(suffix);
|
||||
systemOssStorageTb.setFileMd5(md5);
|
||||
systemOssStorageTb.setFileUrl(fileUrl);
|
||||
systemOssStorageTb.setFileCode(fileCode);
|
||||
systemOssStorageTb.setObjectName(objectName);
|
||||
|
||||
try (InputStream fileInputStream = KitFileUtil.getInputStream(tempFile)) {
|
||||
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(ossMinioConfig.getBucketName()).object(objectName)
|
||||
.stream(fileInputStream, fileSize, -1).contentType(contentType).build();
|
||||
minioClient.putObject(objectArgs);
|
||||
log.info("文件上传成功,并删除临时文件,文件名:{}", originalFilename);
|
||||
return systemOssStorageTb;
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败,文件名:{},错误信息", originalFilename, e);
|
||||
} finally {
|
||||
try {
|
||||
KitFileUtil.del(tempFile);
|
||||
} catch (IORuntimeException e) {
|
||||
// 删除失败忽略
|
||||
}
|
||||
}
|
||||
return null;
|
||||
try {
|
||||
GetPresignedObjectUrlArgs presignedUrlArgs =
|
||||
GetPresignedObjectUrlArgs.builder().bucket(properties.getOss().getMinio().getBucketName())
|
||||
.object(fullFileName).method(Method.GET)
|
||||
// 设置 URL 过期时间为 7 天, 最大 7 天, 别挣扎了
|
||||
.expiry(3600 * 24 * 7).build();
|
||||
String url = minioClient.getPresignedObjectUrl(presignedUrlArgs);
|
||||
log.info("生成预签名 URL 成功,fileName: {}, url: {}", fullFileName, url);
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
log.error("生成预签名 URL 失败,fileName: {}", fullFileName, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化文件上传 文件上传:优化版
|
||||
*
|
||||
* @param file
|
||||
* @return {@link String }
|
||||
*/
|
||||
public String optimizedUpload(MultipartFile file) {
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (StrUtil.isBlank(originalFilename)) {
|
||||
throw new BadRequestException("文件名不能为空");
|
||||
}
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @param res HTTP 响应
|
||||
*/
|
||||
public void download(String fileName, HttpServletResponse res) {
|
||||
GetObjectArgs objectArgs =
|
||||
GetObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fileName).build();
|
||||
|
||||
long size = file.getSize();
|
||||
KitFileUtil.checkSize(properties.getOss().getMaxSize(), size);
|
||||
try (GetObjectResponse response = minioClient.getObject(objectArgs);
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
|
||||
|
||||
String fileName = UUID.randomUUID() + FileUtil.getSuffix(originalFilename);
|
||||
// yyyy/MM/dd/fileName.xxx
|
||||
String objectName = KitDateUtil.getNowDateTimeStr() + "/" + fileName;
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = response.read(buf)) != -1) {
|
||||
os.write(buf, 0, len);
|
||||
}
|
||||
os.flush();
|
||||
|
||||
log.info("准备上传文件,原文件名:{},上传后文件名:{}", originalFilename, fileName);
|
||||
try (InputStream fileInputStream = file.getInputStream()) {
|
||||
PutObjectArgs objectArgs =
|
||||
PutObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(objectName)
|
||||
.stream(fileInputStream, file.getSize(), -1).contentType(file.getContentType()).build();
|
||||
// 使用重试机制进行上传
|
||||
uploadWithRetry(objectArgs, 3);
|
||||
log.info("文件上传成功,objectName: {}", objectName);
|
||||
return objectName;
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败,文件名:{},错误信息", originalFilename, e);
|
||||
}
|
||||
return null;
|
||||
byte[] bytes = os.toByteArray();
|
||||
res.setCharacterEncoding("utf-8");
|
||||
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
try (ServletOutputStream stream = res.getOutputStream()) {
|
||||
stream.write(bytes);
|
||||
stream.flush();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载文件失败,fileName: {}, 错误信息", fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传重试机制
|
||||
*
|
||||
* @param objectArgs 对象参数
|
||||
* @param maxRetries 最大重试次数
|
||||
* @throws Exception 例外
|
||||
*/
|
||||
private void uploadWithRetry(PutObjectArgs objectArgs, int maxRetries) throws Exception {
|
||||
int attempt = 0;
|
||||
while (attempt < maxRetries) {
|
||||
try {
|
||||
minioClient.putObject(objectArgs);
|
||||
return; // 上传成功,返回
|
||||
} catch (Exception e) {
|
||||
attempt++;
|
||||
log.warn("上传失败,第 {} 次尝试,错误信息", attempt, e);
|
||||
if (attempt == maxRetries) {
|
||||
throw new BadRequestException("上传失败,已达到最大重试次数");
|
||||
}
|
||||
// 等待一段时间后重试
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
/**
|
||||
* 文件下载:优化版
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @param res HTTP 响应
|
||||
*/
|
||||
public void downloadOptimizedVersion(String fileName, HttpServletResponse res) {
|
||||
GetObjectArgs objectArgs =
|
||||
GetObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fileName).build();
|
||||
|
||||
try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
|
||||
// 增大缓冲区
|
||||
byte[] buf = new byte[1024 * 4];
|
||||
int len;
|
||||
|
||||
// 分块下载并输出到响应流
|
||||
try (ServletOutputStream stream = res.getOutputStream()) {
|
||||
res.setCharacterEncoding("utf-8");
|
||||
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
res.setHeader("Cache-Control", "no-store");
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
res.setHeader("Expires", "0");
|
||||
|
||||
while ((len = response.read(buf)) != -1) {
|
||||
stream.write(buf, 0, len);
|
||||
// 确保实时写入
|
||||
stream.flush();
|
||||
}
|
||||
log.info("文件下载成功,fileName: {}", fileName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载文件失败,fileName: {}, 错误信息", fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成文件的预签名 URL,用于文件预览
|
||||
*
|
||||
* @param fullFileName 文件完整路径
|
||||
* @return String 预签名 URL
|
||||
*/
|
||||
public String generatePreviewUrl(String fullFileName) {
|
||||
if (StrUtil.isBlank(fullFileName)) {
|
||||
log.warn("文件名为空,无法生成预签名 URL");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
GetPresignedObjectUrlArgs presignedUrlArgs =
|
||||
GetPresignedObjectUrlArgs.builder().bucket(properties.getOss().getMinio().getBucketName())
|
||||
.object(fullFileName).method(Method.GET)
|
||||
// 设置 URL 过期时间为 7 天, 最大 7 天, 别挣扎了
|
||||
.expiry(3600 * 24 * 7).build();
|
||||
String url = minioClient.getPresignedObjectUrl(presignedUrlArgs);
|
||||
log.info("生成预签名 URL 成功,fileName: {}, url: {}", fullFileName, url);
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
log.error("生成预签名 URL 失败,fileName: {}", fullFileName, e);
|
||||
}
|
||||
return null;
|
||||
/**
|
||||
* 查看文件对象列表
|
||||
*
|
||||
* @return List<Item> 文件对象列表
|
||||
*/
|
||||
public List<Item> queryAllObjects() {
|
||||
try {
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).build());
|
||||
List<Item> items = new ArrayList<>();
|
||||
for (Result<Item> result : results) {
|
||||
items.add(result.get());
|
||||
}
|
||||
return items;
|
||||
} catch (Exception e) {
|
||||
log.error("列出文件对象失败,错误信息", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @param res HTTP 响应
|
||||
*/
|
||||
public void download(String fileName, HttpServletResponse res) {
|
||||
GetObjectArgs objectArgs =
|
||||
GetObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fileName).build();
|
||||
|
||||
try (GetObjectResponse response = minioClient.getObject(objectArgs);
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = response.read(buf)) != -1) {
|
||||
os.write(buf, 0, len);
|
||||
}
|
||||
os.flush();
|
||||
|
||||
byte[] bytes = os.toByteArray();
|
||||
res.setCharacterEncoding("utf-8");
|
||||
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
try (ServletOutputStream stream = res.getOutputStream()) {
|
||||
stream.write(bytes);
|
||||
stream.flush();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载文件失败,fileName: {}, 错误信息", fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载:优化版
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @param res HTTP 响应
|
||||
*/
|
||||
public void downloadOptimizedVersion(String fileName, HttpServletResponse res) {
|
||||
GetObjectArgs objectArgs =
|
||||
GetObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fileName).build();
|
||||
|
||||
try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
|
||||
// 增大缓冲区
|
||||
byte[] buf = new byte[1024 * 4];
|
||||
int len;
|
||||
|
||||
// 分块下载并输出到响应流
|
||||
try (ServletOutputStream stream = res.getOutputStream()) {
|
||||
res.setCharacterEncoding("utf-8");
|
||||
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
res.setHeader("Cache-Control", "no-store");
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
res.setHeader("Expires", "0");
|
||||
|
||||
while ((len = response.read(buf)) != -1) {
|
||||
stream.write(buf, 0, len);
|
||||
// 确保实时写入
|
||||
stream.flush();
|
||||
}
|
||||
log.info("文件下载成功,fileName: {}", fileName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载文件失败,fileName: {}, 错误信息", fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看文件对象列表
|
||||
*
|
||||
* @return List<Item> 文件对象列表
|
||||
*/
|
||||
public List<Item> queryAllObjects() {
|
||||
try {
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).build());
|
||||
List<Item> items = new ArrayList<>();
|
||||
for (Result<Item> result : results) {
|
||||
items.add(result.get());
|
||||
}
|
||||
return items;
|
||||
} catch (Exception e) {
|
||||
log.error("列出文件对象失败,错误信息", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return boolean 删除成功返回 true,否则返回 false
|
||||
*/
|
||||
public boolean removeBucketFile(String fileName) {
|
||||
try {
|
||||
minioClient.removeObject(
|
||||
RemoveObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fileName)
|
||||
.build());
|
||||
log.info("删除文件成功,fileName: {}", fileName);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("删除文件失败,fileName: {}, 错误信息", fileName, e);
|
||||
}
|
||||
return false;
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return boolean 删除成功返回 true,否则返回 false
|
||||
*/
|
||||
public boolean removeBucketFile(String fileName) {
|
||||
try {
|
||||
minioClient.removeObject(
|
||||
RemoveObjectArgs.builder().bucket(properties.getOss().getMinio().getBucketName()).object(fileName)
|
||||
.build());
|
||||
log.info("删除文件成功,fileName: {}", fileName);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("删除文件失败,fileName: {}, 错误信息", fileName, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -22,15 +22,15 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class TestTask {
|
||||
|
||||
public void run() {
|
||||
log.info("run 执行成功");
|
||||
}
|
||||
public void run() {
|
||||
log.info("run 执行成功");
|
||||
}
|
||||
|
||||
public void run1(String str) {
|
||||
log.info("run1 执行成功, 参数为: {}", str);
|
||||
}
|
||||
public void run1(String str) {
|
||||
log.info("run1 执行成功, 参数为: {}", str);
|
||||
}
|
||||
|
||||
public void run2() {
|
||||
log.info("run2 执行成功");
|
||||
}
|
||||
public void run2() {
|
||||
log.info("run2 执行成功");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,10 +18,10 @@ import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
||||
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
|
||||
import cn.odboy.util.KitRsaEncryptUtil;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
+1
-1
@@ -33,6 +33,7 @@ import cn.odboy.system.framework.permission.core.KitSecurityHelper;
|
||||
import cn.odboy.util.KitClassUtil;
|
||||
import cn.odboy.util.KitFileUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
@@ -46,7 +47,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+1
-1
@@ -29,13 +29,13 @@ import cn.odboy.util.KitFileUtil;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+1
-1
@@ -28,13 +28,13 @@ import cn.odboy.util.KitFileUtil;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+1
-1
@@ -33,6 +33,7 @@ import cn.odboy.util.KitFileUtil;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -40,7 +41,6 @@ import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+1
-1
@@ -36,6 +36,7 @@ import cn.odboy.util.KitClassUtil;
|
||||
import cn.odboy.util.KitFileUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
@@ -48,7 +49,6 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+1
-1
@@ -21,9 +21,9 @@ import cn.odboy.system.dal.model.SystemOssStorageVo;
|
||||
import cn.odboy.system.dal.model.SystemQueryStorageArgs;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -34,6 +34,7 @@ import cn.odboy.util.KitFileUtil;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -41,7 +42,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.quartz.CronExpression;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
+1
-1
@@ -35,6 +35,7 @@ import cn.odboy.util.KitFileUtil;
|
||||
import cn.odboy.util.KitPageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -44,7 +45,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+1
-1
@@ -50,6 +50,7 @@ import cn.odboy.util.KitRsaEncryptUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -62,7 +63,6 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
+1
-1
@@ -36,13 +36,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
+142
-142
@@ -37,150 +37,150 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public final class KitSqlUtil {
|
||||
|
||||
/**
|
||||
* 获取数据源
|
||||
*
|
||||
* @param jdbcUrl /
|
||||
* @param userName /
|
||||
* @param password /
|
||||
* @return DataSource
|
||||
*/
|
||||
private static DataSource getDataSource(String jdbcUrl, String userName, String password) {
|
||||
HikariDataSource druidDataSource = new HikariDataSource();
|
||||
String className;
|
||||
try {
|
||||
className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();
|
||||
} catch (SQLException e) {
|
||||
throw new BadRequestException("Get class name error: =" + jdbcUrl);
|
||||
/**
|
||||
* 获取数据源
|
||||
*
|
||||
* @param jdbcUrl /
|
||||
* @param userName /
|
||||
* @param password /
|
||||
* @return DataSource
|
||||
*/
|
||||
private static DataSource getDataSource(String jdbcUrl, String userName, String password) {
|
||||
HikariDataSource druidDataSource = new HikariDataSource();
|
||||
String className;
|
||||
try {
|
||||
className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();
|
||||
} catch (SQLException e) {
|
||||
throw new BadRequestException("Get class name error: =" + jdbcUrl);
|
||||
}
|
||||
if (StringUtils.isEmpty(className)) {
|
||||
DataTypeEnum dataTypeEnum = DataTypeEnum.urlOf(jdbcUrl);
|
||||
if (null == dataTypeEnum) {
|
||||
throw new BadRequestException("Not supported data type: jdbcUrl=" + jdbcUrl);
|
||||
}
|
||||
druidDataSource.setDriverClassName(dataTypeEnum.getDriver());
|
||||
} else {
|
||||
druidDataSource.setDriverClassName(className);
|
||||
}
|
||||
druidDataSource.setJdbcUrl(jdbcUrl);
|
||||
druidDataSource.setUsername(userName);
|
||||
druidDataSource.setPassword(password);
|
||||
druidDataSource.setConnectionTimeout(3000);
|
||||
return druidDataSource;
|
||||
}
|
||||
|
||||
private static Connection getConnection(String jdbcUrl, String userName, String password) {
|
||||
DataSource dataSource = getDataSource(jdbcUrl, userName, password);
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = dataSource.getConnection();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
try {
|
||||
int timeOut = 5;
|
||||
if (null == connection || connection.isClosed() || !connection.isValid(timeOut)) {
|
||||
log.info("connection is closed or invalid, retry get connection!");
|
||||
connection = dataSource.getConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("create connection error, jdbcUrl: {}", jdbcUrl);
|
||||
throw new BadRequestException("create connection error, jdbcUrl: " + jdbcUrl);
|
||||
} finally {
|
||||
KitCloseUtil.close(connection);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static void releaseConnection(Connection connection) {
|
||||
if (null != connection) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
log.error("connection close error:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean testConnection(String jdbcUrl, String userName, String password) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection(jdbcUrl, userName, password);
|
||||
if (null != connection) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info("Get connection failed:" + e.getMessage());
|
||||
} finally {
|
||||
releaseConnection(connection);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String executeFile(String jdbcUrl, String username, String password, File sqlFile) {
|
||||
Connection connection = getConnection(jdbcUrl, username, password);
|
||||
try {
|
||||
batchExecute(connection, readSqlList(sqlFile));
|
||||
} catch (Exception e) {
|
||||
log.error("sql脚本执行发生异常:{}", e.getMessage());
|
||||
return e.getMessage();
|
||||
} finally {
|
||||
releaseConnection(connection);
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行sql
|
||||
*
|
||||
* @param connection /
|
||||
* @param sqlList /
|
||||
*/
|
||||
public static void batchExecute(Connection connection, List<String> sqlList) {
|
||||
Statement st = null;
|
||||
try {
|
||||
st = connection.createStatement();
|
||||
for (String sql : sqlList) {
|
||||
if (sql.endsWith(";")) {
|
||||
sql = sql.substring(0, sql.length() - 1);
|
||||
}
|
||||
if (StringUtils.isEmpty(className)) {
|
||||
DataTypeEnum dataTypeEnum = DataTypeEnum.urlOf(jdbcUrl);
|
||||
if (null == dataTypeEnum) {
|
||||
throw new BadRequestException("Not supported data type: jdbcUrl=" + jdbcUrl);
|
||||
}
|
||||
druidDataSource.setDriverClassName(dataTypeEnum.getDriver());
|
||||
st.addBatch(sql);
|
||||
}
|
||||
st.executeBatch();
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
} finally {
|
||||
KitCloseUtil.close(st);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件中的sql语句以;为单位读取到列表中
|
||||
*
|
||||
* @param sqlFile /
|
||||
* @return /
|
||||
* @throws Exception e
|
||||
*/
|
||||
private static List<String> readSqlList(File sqlFile) throws Exception {
|
||||
List<String> sqlList = Lists.newArrayList();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(Files.newInputStream(sqlFile.toPath()), StandardCharsets.UTF_8))) {
|
||||
String tmp;
|
||||
while ((tmp = reader.readLine()) != null) {
|
||||
log.info("line:{}", tmp);
|
||||
if (tmp.endsWith(";")) {
|
||||
sb.append(tmp);
|
||||
sqlList.add(sb.toString());
|
||||
sb.delete(0, sb.length());
|
||||
} else {
|
||||
druidDataSource.setDriverClassName(className);
|
||||
sb.append(tmp);
|
||||
}
|
||||
druidDataSource.setJdbcUrl(jdbcUrl);
|
||||
druidDataSource.setUsername(userName);
|
||||
druidDataSource.setPassword(password);
|
||||
druidDataSource.setConnectionTimeout(3000);
|
||||
return druidDataSource;
|
||||
}
|
||||
|
||||
private static Connection getConnection(String jdbcUrl, String userName, String password) {
|
||||
DataSource dataSource = getDataSource(jdbcUrl, userName, password);
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = dataSource.getConnection();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
try {
|
||||
int timeOut = 5;
|
||||
if (null == connection || connection.isClosed() || !connection.isValid(timeOut)) {
|
||||
log.info("connection is closed or invalid, retry get connection!");
|
||||
connection = dataSource.getConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("create connection error, jdbcUrl: {}", jdbcUrl);
|
||||
throw new BadRequestException("create connection error, jdbcUrl: " + jdbcUrl);
|
||||
} finally {
|
||||
KitCloseUtil.close(connection);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static void releaseConnection(Connection connection) {
|
||||
if (null != connection) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
log.error("connection close error:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean testConnection(String jdbcUrl, String userName, String password) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection(jdbcUrl, userName, password);
|
||||
if (null != connection) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info("Get connection failed:" + e.getMessage());
|
||||
} finally {
|
||||
releaseConnection(connection);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String executeFile(String jdbcUrl, String username, String password, File sqlFile) {
|
||||
Connection connection = getConnection(jdbcUrl, username, password);
|
||||
try {
|
||||
batchExecute(connection, readSqlList(sqlFile));
|
||||
} catch (Exception e) {
|
||||
log.error("sql脚本执行发生异常:{}", e.getMessage());
|
||||
return e.getMessage();
|
||||
} finally {
|
||||
releaseConnection(connection);
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行sql
|
||||
*
|
||||
* @param connection /
|
||||
* @param sqlList /
|
||||
*/
|
||||
public static void batchExecute(Connection connection, List<String> sqlList) {
|
||||
Statement st = null;
|
||||
try {
|
||||
st = connection.createStatement();
|
||||
for (String sql : sqlList) {
|
||||
if (sql.endsWith(";")) {
|
||||
sql = sql.substring(0, sql.length() - 1);
|
||||
}
|
||||
st.addBatch(sql);
|
||||
}
|
||||
st.executeBatch();
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
} finally {
|
||||
KitCloseUtil.close(st);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件中的sql语句以;为单位读取到列表中
|
||||
*
|
||||
* @param sqlFile /
|
||||
* @return /
|
||||
* @throws Exception e
|
||||
*/
|
||||
private static List<String> readSqlList(File sqlFile) throws Exception {
|
||||
List<String> sqlList = Lists.newArrayList();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(Files.newInputStream(sqlFile.toPath()), StandardCharsets.UTF_8))) {
|
||||
String tmp;
|
||||
while ((tmp = reader.readLine()) != null) {
|
||||
log.info("line:{}", tmp);
|
||||
if (tmp.endsWith(";")) {
|
||||
sb.append(tmp);
|
||||
sqlList.add(sb.toString());
|
||||
sb.delete(0, sb.length());
|
||||
} else {
|
||||
sb.append(tmp);
|
||||
}
|
||||
}
|
||||
if (!"".endsWith(sb.toString().trim())) {
|
||||
sqlList.add(sb.toString());
|
||||
}
|
||||
}
|
||||
return sqlList;
|
||||
}
|
||||
if (!"".endsWith(sb.toString().trim())) {
|
||||
sqlList.add(sb.toString());
|
||||
}
|
||||
}
|
||||
return sqlList;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
}
|
||||
@page {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0px;
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
}
|
||||
@page {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0px;
|
||||
|
||||
Reference in New Issue
Block a user