feat(dict): 添加字典明细查询功能并重构系统服务代码结构

This commit is contained in:
2026-01-14 20:20:11 +08:00
parent c008daaaa1
commit cf65b4f5ab
103 changed files with 6109 additions and 5984 deletions
@@ -20,11 +20,11 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Objects;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Objects;
@Getter @Getter
@Setter @Setter
@@ -21,9 +21,9 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotNull;
@Getter @Getter
@Setter @Setter
@@ -22,10 +22,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Getter @Getter
@Setter @Setter
@@ -19,9 +19,9 @@ import cn.odboy.base.KitObject;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
/** /**
* 邮件配置类,数据存覆盖式存入数据存 * 邮件配置类,数据存覆盖式存入数据存
@@ -20,11 +20,11 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Objects;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.Objects;
@Getter @Getter
@Setter @Setter
@@ -21,10 +21,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Objects;
import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotNull;
import java.util.Objects;
@Getter @Getter
@Setter @Setter
@@ -23,10 +23,10 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.util.Date;
/** /**
* <p> * <p>
@@ -22,10 +22,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Getter @Getter
@Setter @Setter
@@ -22,9 +22,9 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.Date;
@Data @Data
@TableName("system_quartz_log") @TableName("system_quartz_log")
@@ -23,11 +23,11 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Objects;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.Objects;
/** /**
* 角色 * 角色
@@ -21,13 +21,13 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Date; import lombok.Getter;
import java.util.Objects; import lombok.Setter;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Getter; import java.util.Date;
import lombok.Setter; import java.util.Objects;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -2,9 +2,9 @@ package cn.odboy.system.dal.model.export;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date;
@Getter @Getter
@Setter @Setter
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotBlank;
@Getter @Getter
@Setter @Setter
@@ -16,10 +16,10 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -17,10 +17,10 @@ package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import cn.odboy.system.dal.dataobject.SystemDictTb; import cn.odboy.system.dal.dataobject.SystemDictTb;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -16,10 +16,10 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -17,11 +17,11 @@ package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import java.util.Set;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.Set;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import lombok.Data;
@Data @Data
public class SystemQueryDeptArgs { public class SystemQueryDeptArgs {
@@ -16,10 +16,10 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import java.util.List;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import lombok.Data;
@Data @Data
public class SystemQueryMenuArgs { public class SystemQueryMenuArgs {
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import lombok.Data;
@Data @Data
public class SystemQueryQuartzJobArgs { public class SystemQueryQuartzJobArgs {
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import lombok.Data;
@Data @Data
public class SystemQueryRoleArgs { public class SystemQueryRoleArgs {
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import lombok.Data;
@Data @Data
public class SystemQueryStorageArgs { public class SystemQueryStorageArgs {
@@ -17,12 +17,12 @@ package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -16,12 +16,12 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.List;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
/** /**
* 发送邮件时,接收参数的类 * 发送邮件时,接收参数的类
@@ -16,10 +16,10 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.request; package cn.odboy.system.dal.model.request;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.validation.constraints.NotBlank;
@Getter @Getter
@Setter @Setter
@@ -3,11 +3,11 @@ package cn.odboy.system.dal.model.response;
import cn.odboy.base.KitBaseUserTimeTb; import cn.odboy.base.KitBaseUserTimeTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import lombok.Getter;
import lombok.Setter;
@Getter @Getter
@Setter @Setter
@@ -17,9 +17,9 @@ package cn.odboy.system.dal.model.response;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.List;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.List;
/** /**
* 构建前端路由时用到 * 构建前端路由时用到
@@ -3,11 +3,11 @@ package cn.odboy.system.dal.model.response;
import cn.odboy.base.KitBaseUserTimeTb; import cn.odboy.base.KitBaseUserTimeTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import lombok.Getter;
import lombok.Setter;
@Getter @Getter
@Setter @Setter
@@ -16,9 +16,9 @@
package cn.odboy.system.dal.model.response; package cn.odboy.system.dal.model.response;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -5,10 +5,10 @@ import cn.odboy.system.constant.SystemDataScopeEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Objects;
import java.util.Set;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Objects;
import java.util.Set;
@Getter @Getter
@Setter @Setter
@@ -20,9 +20,9 @@ import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemJobTb; import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Set;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.Set;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -16,11 +16,11 @@
package cn.odboy.system.dal.model.response; package cn.odboy.system.dal.model.response;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -17,12 +17,12 @@ package cn.odboy.system.dal.model.response;
import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@@ -16,8 +16,8 @@
package cn.odboy.system.dal.model.response; package cn.odboy.system.dal.model.response;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import lombok.Data; import lombok.Data;
import java.util.Date;
/** /**
* 在线用户 * 在线用户
@@ -1,18 +1,18 @@
package cn.odboy.system.dal.model.response; package cn.odboy.system.dal.model.response;
import cn.odboy.base.KitBaseUserTimeTb;
import cn.odboy.system.dal.dataobject.SystemJobTb; import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import lombok.Getter;
import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class SystemUserVo extends SystemUserTb { public class SystemUserVo extends KitBaseUserTimeTb {
@ApiModelProperty(value = "ID", hidden = true) @ApiModelProperty(value = "ID", hidden = true)
private Long id; private Long id;
@@ -17,11 +17,13 @@ package cn.odboy.system.dal.mysql;
import cn.odboy.system.dal.dataobject.SystemDictDetailTb; import cn.odboy.system.dal.dataobject.SystemDictDetailTb;
import cn.odboy.system.dal.model.request.SystemQueryDictDetailArgs; import cn.odboy.system.dal.model.request.SystemQueryDictDetailArgs;
import cn.odboy.system.dal.model.response.SystemDictDetailVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 字典明细 Mapper * 字典明细 Mapper
@@ -31,5 +33,7 @@ import org.apache.ibatis.annotations.Param;
@Mapper @Mapper
public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> { public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> {
IPage<SystemDictDetailTb> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args); IPage<SystemDictDetailVo> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args);
List<SystemDictDetailVo> listDictDetailByName(@Param("name") String name);
} }
@@ -15,9 +15,12 @@
*/ */
package cn.odboy.system.dal.mysql; package cn.odboy.system.dal.mysql;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemRoleDeptTb; import cn.odboy.system.dal.dataobject.SystemRoleDeptTb;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Set;
/** /**
* 角色部门关联 Mapper * 角色部门关联 Mapper
@@ -27,4 +30,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface SystemRoleDeptMapper extends BaseMapper<SystemRoleDeptTb> { public interface SystemRoleDeptMapper extends BaseMapper<SystemRoleDeptTb> {
Set<SystemDeptTb> listUserDeptByRoleId(@Param("roleId") Long roleId);
} }
@@ -15,9 +15,12 @@
*/ */
package cn.odboy.system.dal.mysql; package cn.odboy.system.dal.mysql;
import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemUserJobTb; import cn.odboy.system.dal.dataobject.SystemUserJobTb;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Set;
/** /**
* 用户职位关联 Mapper * 用户职位关联 Mapper
@@ -27,4 +30,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface SystemUserJobMapper extends BaseMapper<SystemUserJobTb> { public interface SystemUserJobMapper extends BaseMapper<SystemUserJobTb> {
Set<SystemJobTb> listUserJobByUserId(@Param("userId") Long userId);
} }
@@ -18,8 +18,8 @@ package cn.odboy.system.dal.mysql;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.Set;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.Set;
/** /**
* 用户 Mapper * 用户 Mapper
@@ -15,11 +15,15 @@
*/ */
package cn.odboy.system.dal.mysql; package cn.odboy.system.dal.mysql;
import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb; import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Set;
@Mapper @Mapper
public interface SystemUserRoleMapper extends BaseMapper<SystemUserRoleTb> { public interface SystemUserRoleMapper extends BaseMapper<SystemUserRoleTb> {
Set<SystemRoleTb> listUserRoleByUserId(@Param("userId") Long userId);
} }
@@ -15,17 +15,17 @@ import cn.odboy.util.KitIPUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; 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;
@Slf4j @Slf4j
@Component @Component
@@ -62,7 +62,7 @@ public class SystemUserOnlineInfoDAO {
userOnlineVo.setKey(KitDesEncryptUtil.desEncrypt(token)); userOnlineVo.setKey(KitDesEncryptUtil.desEncrypt(token));
userOnlineVo.setLoginTime(new Date()); userOnlineVo.setLoginTime(new Date());
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error("保存在线用户信息失败", e);
} }
String loginKey = tokenProvider.loginKey(token); String loginKey = tokenProvider.loginKey(token);
redisHelper.set(loginKey, userOnlineVo, properties.getJwt().getTokenValidityInSeconds(), TimeUnit.MILLISECONDS); redisHelper.set(loginKey, userOnlineVo, properties.getJwt().getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
@@ -22,68 +22,82 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/**
* 用户认证
*/
@Service @Service
public class SystemAuthService { public class SystemAuthService {
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
@Autowired @Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@Autowired @Autowired
private TokenProvider tokenProvider; private TokenProvider tokenProvider;
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Autowired @Autowired
private UserDetailsHandler userDetailsService; private UserDetailsHandler userDetailsService;
@Autowired @Autowired
private SystemCaptchaService systemCaptchaService; private SystemCaptchaService systemCaptchaService;
public SystemAuthVo doLogin(SystemUserLoginArgs loginArgs, HttpServletRequest request) throws Exception { /**
KitValidUtil.notNull(loginArgs); * 登录 -> TestPassed
*/
public SystemAuthVo doLogin(SystemUserLoginArgs loginArgs, HttpServletRequest request) throws Exception {
KitValidUtil.notNull(loginArgs);
// 密码解密 // 密码解密
String password = KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginArgs.getPassword()); String password =
// 校验验证码 KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginArgs.getPassword());
systemCaptchaService.validate(loginArgs.getUuid(), loginArgs.getCode()); // 校验验证码
// 获取用户信息 systemCaptchaService.validate(loginArgs.getUuid(), loginArgs.getCode());
SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginArgs.getUsername()); // 获取用户信息
// 验证用户密码 SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginArgs.getUsername());
if (!passwordEncoder.matches(password, jwtUser.getPassword())) { // 验证用户密码
throw new BadRequestException("登录密码错误"); if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
// 登录验证
Authentication authentication =
new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
SystemAuthVo authInfo = new SystemAuthVo();
authInfo.setToken(String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
/// 这里是为了清空密码
authInfo.setUser(KitBeanUtil.copyToClass(jwtUser, SystemUserInfoVo.class));
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginArgs.getUsername());
}
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return authInfo;
} }
// 登录验证 /**
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities()); * 获取当前登录人信息 -> TestPassed
SecurityContextHolder.getContext().setAuthentication(authentication); */
public SystemUserJwtVo getCurrentUserInfo() {
// 生成令牌 SystemUserJwtVo jwtUser = (SystemUserJwtVo)KitSecurityHelper.getCurrentUser();
String token = tokenProvider.createToken(jwtUser); if (jwtUser.getUser() != null) {
// 返回 token 与 用户信息 jwtUser.getUser().setPassword(null);
SystemAuthVo authInfo = new SystemAuthVo(); }
authInfo.setToken(String.format("%s %s", SystemConst.TOKEN_PREFIX, token)); return jwtUser;
/// 这里是为了清空密码
authInfo.setUser(KitBeanUtil.copyToClass(jwtUser, SystemUserInfoVo.class));
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginArgs.getUsername());
} }
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return authInfo;
}
public SystemUserJwtVo getCurrentUserInfo() { /**
SystemUserJwtVo jwtUser = (SystemUserJwtVo) KitSecurityHelper.getCurrentUser(); * 退出登录 -> TestPassed
if (jwtUser.getUser() != null) { */
jwtUser.getUser().setPassword(null); public void doLogout(HttpServletRequest request) {
String token = tokenProvider.getToken(request);
systemUserOnlineInfoDAO.logoutByToken(token);
} }
return jwtUser;
}
public void doLogout(HttpServletRequest request) {
String token = tokenProvider.getToken(request);
systemUserOnlineInfoDAO.logoutByToken(token);
}
} }
@@ -10,9 +10,9 @@ import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.model.response.SystemCaptchaVo; import cn.odboy.system.dal.model.response.SystemCaptchaVo;
import cn.odboy.system.dal.redis.SystemCacheKey; import cn.odboy.system.dal.redis.SystemCacheKey;
import com.wf.captcha.base.Captcha; import com.wf.captcha.base.Captcha;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/** /**
* 验证码 * 验证码
@@ -20,40 +20,50 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemCaptchaService { public class SystemCaptchaService {
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
public SystemCaptchaVo getLoginCaptcha() { /**
// 获取运算的结果 * 获取登录验证码 -> TestPassed
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha(); */
String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID(); public SystemCaptchaVo getLoginCaptcha() {
//当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型 // 获取运算的结果
String captchaValue = captcha.text(); Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() && String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
captchaValue.contains(SystemConst.SYMBOL_DOT)) { //当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型
captchaValue = captchaValue.split("\\.")[0]; String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() && captchaValue.contains(
SystemConst.SYMBOL_DOT)) {
captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(),
TimeUnit.MINUTES);
// 验证码信息
SystemCaptchaVo captchaVo = new SystemCaptchaVo();
captchaVo.setUuid(uuid);
captchaVo.setImg(captcha.toBase64());
return captchaVo;
} }
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(), TimeUnit.MINUTES);
// 验证码信息
SystemCaptchaVo captchaVo = new SystemCaptchaVo();
captchaVo.setUuid(uuid);
captchaVo.setImg(captcha.toBase64());
return captchaVo;
}
public void validate(String uuid, String inputCode) { /**
// 查询验证码 * 验证验证码 -> TestPassed
String code = redisHelper.get(uuid, String.class); *
if (StrUtil.isBlank(code)) { * @param uuid 验证码uuid
throw new BadRequestException("验证码不存在或已过期"); * @param inputCode 用户输入的验证码
*/
public void validate(String uuid, String inputCode) {
// 查询验证码
String code = redisHelper.get(uuid, String.class);
if (StrUtil.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期");
}
// 清除验证码
redisHelper.del(uuid);
if (StrUtil.isBlank(inputCode) || !code.equalsIgnoreCase(inputCode)) {
throw new BadRequestException("验证码错误");
}
} }
// 清除验证码
redisHelper.del(uuid);
if (StrUtil.isBlank(inputCode) || !code.equalsIgnoreCase(inputCode)) {
throw new BadRequestException("验证码错误");
}
}
} }
@@ -18,74 +18,80 @@ package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.odboy.system.constant.SystemDataScopeEnum; import cn.odboy.system.constant.SystemDataScopeEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.model.response.SystemDeptVo; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.model.response.SystemRoleVo;
import cn.odboy.system.dal.model.response.SystemUserVo; import cn.odboy.system.dal.model.response.SystemUserVo;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* 数据权限 Service * 数据权限
* *
* @author odboy * @author odboy
*/ */
@Service @Service
public class SystemDataService { public class SystemDataService {
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemUserRoleService systemUserRoleService;
@Autowired @Autowired
private SystemDeptService systemDeptService; private SystemDeptService systemDeptService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
/** /**
* 获取数据权限 * 获取数据权限 -> TestPassed
* *
* @param user / * @param user /
* @return / * @return /
*/ */
public List<Long> queryDeptIdByArgs(SystemUserVo user) { public List<Long> queryDeptIdByArgs(SystemUserVo user) {
List<Long> deptIds = new ArrayList<>(); List<Long> deptIds = new ArrayList<>();
// 查询用户角色 // 查询用户角色
List<SystemRoleVo> roleList = systemUserRoleService.queryRoleByUsersId(user.getId()); Set<SystemRoleTb> roleList = systemUserRoleService.listUserRoleByUserId(user.getId());
// 获取对应的部门ID // 获取对应的部门ID
for (SystemRoleVo role : roleList) { for (SystemRoleTb role : roleList) {
SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope()); SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope());
switch (Objects.requireNonNull(dataScopeEnum)) { switch (Objects.requireNonNull(dataScopeEnum)) {
case THIS_LEVEL: case THIS_LEVEL:
deptIds.add(user.getDept().getId()); Long currentDeptId = user.getDept().getId();
break; deptIds.add(currentDeptId);
case CUSTOMIZE: break;
deptIds.addAll(this.queryCustomDataPermissionByArgs(deptIds, role)); case CUSTOMIZE:
break; // 优化 283ms -> 51 ms
default: List<Long> customDeptIds = this.queryCustomDataPermissionByArgs(deptIds, role.getId());
return new ArrayList<>(); deptIds.addAll(customDeptIds);
} break;
default:
return new ArrayList<>();
}
}
return deptIds.stream().distinct().collect(Collectors.toList());
} }
return deptIds.stream().distinct().collect(Collectors.toList());
}
/** /**
* 获取自定义的数据权限 * 获取自定义的数据权限 -> TestPassed
* *
* @param deptIds 部门ID * @param deptIds 部门ID(外部数据)
* @param role 角色 * @param roleId 角色ID
* @return 数据权限ID * @return 数据权限ID(所有部门ID数据)
*/ */
private List<Long> queryCustomDataPermissionByArgs(List<Long> deptIds, SystemRoleVo role) { private List<Long> queryCustomDataPermissionByArgs(List<Long> deptIds, Long roleId) {
List<SystemDeptTb> deptList = systemRoleDeptService.listDeptByRoleId(role.getId()); Set<SystemDeptTb> deptList = systemRoleDeptService.listUserDeptByRoleId(roleId);
for (SystemDeptTb dept : deptList) { Map<Long, List<SystemDeptTb>> deptPidMap =
deptIds.add(dept.getId()); systemDeptService.listPidNonNull().stream().collect(Collectors.groupingBy(SystemDeptTb::getPid));
List<SystemDeptVo> deptChildren = systemDeptService.listDeptByPid(dept.getId()); for (SystemDeptTb dept : deptList) {
if (CollUtil.isNotEmpty(deptChildren)) { deptIds.add(dept.getId());
deptIds.addAll(systemDeptService.queryChildDeptIdByDeptIds(deptChildren)); List<SystemDeptTb> deptChildren = deptPidMap.getOrDefault(dept.getId(), null);
} if (CollUtil.isNotEmpty(deptChildren)) {
deptIds.addAll(systemDeptService.queryChildDeptIdByDeptIds(deptChildren, deptPidMap));
}
}
return deptIds;
} }
return deptIds;
}
} }
@@ -16,7 +16,6 @@
package cn.odboy.system.service; package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
@@ -37,6 +36,10 @@ import cn.odboy.util.KitClassUtil;
import cn.odboy.util.KitValidUtil; import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -48,439 +51,458 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; 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;
@Service @Service
public class SystemDeptService { public class SystemDeptService {
@Autowired @Autowired
private SystemDeptMapper systemDeptMapper; private SystemDeptMapper systemDeptMapper;
@Autowired @Autowired
private SystemUserDeptService systemUserDeptService; private SystemUserDeptService systemUserDeptService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveDept(SystemCreateDeptArgs args) { public void saveDept(SystemCreateDeptArgs args) {
KitValidUtil.notNull(args); KitValidUtil.notNull(args);
systemDeptMapper.insert(KitBeanUtil.copyToClass(args, SystemDeptTb.class));
this.updateDeptSubCnt(args.getPid());
}
/** SystemDeptTb record = KitBeanUtil.copyToClass(args, SystemDeptTb.class);
* 编辑 systemDeptMapper.insert(record);
*
* @param args / this.updateDeptSubCnt(args.getPid());
*/
@Transactional(rollbackFor = Exception.class)
public void updateDeptById(SystemDeptTb args) {
KitValidUtil.notNull(args);
// 旧的父部门
Long oldPid = this.getDeptVoById(args.getId()).getPid();
// 新的父部门
Long newPid = args.getPid();
if (args.getPid() != null && args.getId().equals(args.getPid())) {
throw new BadRequestException("上级不能为自己");
} }
SystemDeptTb dept = systemDeptMapper.selectById(args.getId());
args.setId(dept.getId());
systemDeptMapper.insertOrUpdate(args);
this.updateDeptSubCnt(oldPid);
this.updateDeptSubCnt(newPid);
}
/** /**
* 删除 * 编辑 -> TestPassed
* *
* @param ids / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDeptByIds(Set<Long> ids) { public void updateDeptById(SystemDeptTb args) {
// 获取部门, 和其所有子部门 KitValidUtil.notNull(args);
Set<SystemDeptVo> depts = this.traverseDeptByIdWithPids(ids); // 旧的父部门
// 验证是否被角色或用户关联 Long oldPid = this.getDeptById(args.getId()).getPid();
this.verifyBindRelationByIds(depts); // 新的父部门
for (SystemDeptVo dept : depts) { Long newPid = args.getPid();
systemDeptMapper.deleteById(dept.getId()); if (args.getPid() != null && args.getId().equals(args.getPid())) {
this.updateDeptSubCnt(dept.getPid()); throw new BadRequestException("上级不能为自己");
}
}
/**
* 更新父节点中子节点数目
*
* @param deptId /
*/
@Transactional(rollbackFor = Exception.class)
public void updateDeptSubCnt(Long deptId) {
if (deptId != null) {
long count = this.countDeptByPid(deptId);
systemDeptMapper.updateDeptSubCountById(count, deptId);
}
}
private long countDeptByPid(Long pid) {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getPid, pid);
return systemDeptMapper.selectCount(wrapper);
}
/**
* 筛选出 list 中没有父部门(即 pid 不在其他部门 id 列表中的部门)的部门列表
*/
private List<SystemDeptTb> deduplication(List<SystemDeptTb> list) {
List<SystemDeptTb> deptList = new ArrayList<>();
// 使用 Set 存储所有部门的 id
Set<Long> idSet = list.stream().map(SystemDeptTb::getId).collect(Collectors.toSet());
// 遍历部门列表, 筛选出没有父部门的部门
for (SystemDeptTb dept : list) {
if (!idSet.contains(dept.getPid())) {
deptList.add(dept);
}
}
return deptList;
}
private List<SystemDeptTb> queryDeptByArgs(SystemQueryDeptArgs args) {
KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(CollUtil.isNotEmpty(args.getIds()), SystemDeptTb::getId, args.getIds());
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemDeptTb::getName, args.getName());
wrapper.eq(args.getEnabled() != null, SystemDeptTb::getEnabled, args.getEnabled());
wrapper.eq(args.getPid() != null, SystemDeptTb::getPid, args.getPid());
wrapper.isNull(args.getPidIsNull() != null, SystemDeptTb::getPid);
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemDeptTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
wrapper.orderByAsc(SystemDeptTb::getDeptSort);
return systemDeptMapper.selectList(wrapper);
}
/**
* 查询所有数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemDeptTb> queryAllDeptByArgs(SystemQueryDeptArgs args, Boolean isQuery) throws Exception {
String dataScopeType = KitSecurityHelper.getDataScopeType();
if (isQuery) {
if (dataScopeType.equals(SystemDataScopeEnum.ALL.getValue())) {
args.setPidIsNull(true);
}
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
List<String> fieldNames = new ArrayList<>() {{
add("pidIsNull");
add("enabled");
}};
for (Field field : fields) {
// 设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if (fieldNames.contains(field.getName())) {
continue;
} }
if (ObjectUtil.isNotNull(val)) { SystemDeptTb dept = systemDeptMapper.selectById(args.getId());
args.setPidIsNull(null); args.setId(dept.getId());
break; systemDeptMapper.updateById(args);
this.updateDeptSubCnt(oldPid);
this.updateDeptSubCnt(newPid);
}
/**
* 根据部门id获取部门信息 -> TestPassed
*
* @param id 部门id
* @return /
*/
private SystemDeptTb getDeptById(Long id) {
return systemDeptMapper.selectById(id);
}
/**
* 删除
*
* @param ids /
*/
@Transactional(rollbackFor = Exception.class)
public void deleteDeptByIds(Set<Long> ids) {
// 获取部门, 和其所有子部门
Set<SystemDeptVo> depts = this.traverseDeptByIdWithPids(ids);
// 验证是否被角色或用户关联
this.verifyBindRelationByIds(depts);
for (SystemDeptVo dept : depts) {
systemDeptMapper.deleteById(dept.getId());
this.updateDeptSubCnt(dept.getPid());
} }
}
} }
// 数据权限
args.setIds(KitSecurityHelper.getCurrentUserDataScope());
List<SystemDeptTb> list = this.queryDeptByArgs(args);
// 如果为空, 就代表为自定义权限或者本级权限, 就需要去重, 不理解可以注释掉,看查询结果
if (StrUtil.isBlank(dataScopeType)) {
return this.deduplication(list);
}
return list;
}
/** /**
* 根据ID查询 * 更新父节点中子节点数目 -> TestPassed
* *
* @param id / * @param deptId /
* @return / */
*/ @Transactional(rollbackFor = Exception.class)
public SystemDeptVo getDeptVoById(Long id) { public void updateDeptSubCnt(Long deptId) {
return KitBeanUtil.copyToClass(systemDeptMapper.selectById(id), SystemDeptVo.class); if (deptId != null) {
} long count = this.countDeptByPid(deptId);
systemDeptMapper.updateDeptSubCountById(count, deptId);
/**
* 获取部门下所有关联的部门
*
* @param deptTbList /
* @param depts /
*/
private void queryRelationDeptByArgs(List<SystemDeptVo> deptTbList, Set<SystemDeptVo> depts) {
for (SystemDeptVo dept : deptTbList) {
depts.add(dept);
List<SystemDeptVo> deptList = this.listDeptByPid(dept.getId());
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
}
}
public List<Long> queryChildDeptIdByDeptIds(List<SystemDeptVo> deptList) {
List<Long> list = new ArrayList<>();
for (SystemDeptVo systemDeptTb : deptList) {
if (systemDeptTb != null && systemDeptTb.getEnabled()) {
List<SystemDeptVo> deptList1 = this.listDeptByPid(systemDeptTb.getId());
if (CollUtil.isNotEmpty(deptList1)) {
list.addAll(queryChildDeptIdByDeptIds(deptList1));
} }
list.add(systemDeptTb.getId());
}
} }
return list;
}
/** private long countDeptByPid(Long pid) {
* 根据ID获取同级与上级数据 LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
* wrapper.eq(SystemDeptTb::getPid, pid);
* @param dept / return systemDeptMapper.selectCount(wrapper);
* @param deptList /
* @return /
*/
private List<SystemDeptVo> querySuperiorDeptByPid(SystemDeptVo dept, List<SystemDeptVo> deptList) {
if (dept.getPid() == null) {
deptList.addAll(this.listRootDept());
return deptList;
} }
deptList.addAll(this.listDeptByPid(dept.getPid()));
return querySuperiorDeptByPid(this.getDeptVoById(dept.getPid()), deptList);
}
private List<SystemDeptVo> listRootDept() { /**
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); * 筛选出 list 中没有父部门(即 pid 不在其他部门 id 列表中的部门)的部门列表
wrapper.isNull(SystemDeptTb::getPid); */
return KitBeanUtil.copyToList(systemDeptMapper.selectList(wrapper), SystemDeptVo.class); private List<SystemDeptTb> deduplication(List<SystemDeptTb> list) {
} List<SystemDeptTb> deptList = new ArrayList<>();
// 使用 Set 存储所有部门的 id
/** Set<Long> idSet = list.stream().map(SystemDeptTb::getId).collect(Collectors.toSet());
* 构建树形数据 // 遍历部门列表, 筛选出没有父部门的部门
* for (SystemDeptTb dept : list) {
* @return / if (!idSet.contains(dept.getPid())) {
*/ deptList.add(dept);
public KitPageResult<SystemDeptVo> searchDeptTree(List<Long> ids, Boolean exclude) { }
Set<SystemDeptVo> deptSet1 = new LinkedHashSet<>();
for (Long id : ids) {
// 同级数据
SystemDeptVo dept = this.getDeptVoById(id);
// 上级数据
List<SystemDeptVo> depts = this.querySuperiorDeptByPid(dept, new ArrayList<>());
if (exclude) {
for (SystemDeptVo data : depts) {
if (data.getId().equals(dept.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
} }
// 编辑部门时不显示自己以及自己下级的数据, 避免出现PID数据环形问题 return deptList;
depts = depts.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toList());
}
deptSet1.addAll(depts);
} }
List<SystemDeptVo> deptList = new ArrayList<>(deptSet1);
// 构建部门树 private List<SystemDeptTb> queryDeptByArgs(SystemQueryDeptArgs args) {
Set<SystemDeptVo> trees = new LinkedHashSet<>(); KitValidUtil.notNull(args);
Set<SystemDeptVo> deptSet = new LinkedHashSet<>(); LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
List<String> deptNames = deptList.stream().map(SystemDeptVo::getName).collect(Collectors.toList()); wrapper.in(CollUtil.isNotEmpty(args.getIds()), SystemDeptTb::getId, args.getIds());
boolean isChild; wrapper.like(StrUtil.isNotBlank(args.getName()), SystemDeptTb::getName, args.getName());
for (SystemDeptVo dept : deptList) { wrapper.eq(args.getEnabled() != null, SystemDeptTb::getEnabled, args.getEnabled());
isChild = false; wrapper.eq(args.getPid() != null, SystemDeptTb::getPid, args.getPid());
if (dept.getPid() == null) { wrapper.isNull(args.getPidIsNull() != null, SystemDeptTb::getPid);
trees.add(dept); if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
} wrapper.between(SystemDeptTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
for (SystemDeptVo it : deptList) {
if (it.getPid() != null && dept.getId().equals(it.getPid())) {
isChild = true;
if (dept.getChildren() == null) {
dept.setChildren(new ArrayList<>());
}
dept.getChildren().add(it);
} }
} wrapper.orderByAsc(SystemDeptTb::getDeptSort);
if (isChild) { return systemDeptMapper.selectList(wrapper);
deptSet.add(dept);
} else if (dept.getPid() != null && !deptNames.contains(this.getDeptVoById(dept.getPid()).getName())) {
deptSet.add(dept);
}
} }
if (CollectionUtil.isEmpty(trees)) {
trees = deptSet; /**
* 查询所有数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemDeptTb> queryAllDeptByArgs(SystemQueryDeptArgs args, Boolean isQuery) throws Exception {
String dataScopeType = KitSecurityHelper.getDataScopeType();
if (isQuery) {
if (dataScopeType.equals(SystemDataScopeEnum.ALL.getValue())) {
args.setPidIsNull(true);
}
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
List<String> fieldNames = new ArrayList<>() {{
add("pidIsNull");
add("enabled");
}};
for (Field field : fields) {
// 设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if (fieldNames.contains(field.getName())) {
continue;
}
if (ObjectUtil.isNotNull(val)) {
args.setPidIsNull(null);
break;
}
}
}
// 数据权限
args.setIds(KitSecurityHelper.getCurrentUserDataScope());
List<SystemDeptTb> list = this.queryDeptByArgs(args);
// 如果为空, 就代表为自定义权限或者本级权限, 就需要去重, 不理解可以注释掉,看查询结果
if (StrUtil.isBlank(dataScopeType)) {
return this.deduplication(list);
}
return list;
} }
KitPageResult<SystemDeptVo> baseResult = new KitPageResult<>();
baseResult.setContent(CollectionUtil.isEmpty(trees) ? new ArrayList<>(deptSet) : new ArrayList<>(trees));
baseResult.setTotalElements(deptSet.size());
return baseResult;
}
/** /**
* 验证是否被角色或用户关联 * 根据ID查询
* *
* @param deptSet / * @param id /
*/ * @return /
public void verifyBindRelationByIds(Set<SystemDeptVo> deptSet) { */
Set<Long> deptIds = deptSet.stream().map(SystemDeptVo::getId).collect(Collectors.toSet()); public SystemDeptVo getDeptVoById(Long id) {
if (systemUserDeptService.countUserByDeptIds(deptIds) > 0) { return KitBeanUtil.copyToClass(systemDeptMapper.selectById(id), SystemDeptVo.class);
throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
} }
if (systemRoleDeptService.countRoleByDeptIds(deptIds) > 0) {
throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); /**
* 获取部门下所有关联的部门
*
* @param deptTbList /
* @param depts /
*/
private void queryRelationDeptByArgs(List<SystemDeptVo> deptTbList, Set<SystemDeptVo> depts) {
for (SystemDeptVo dept : deptTbList) {
depts.add(dept);
List<SystemDeptVo> deptList = this.listDeptVoByPid(dept.getId());
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
}
} }
}
private List<SystemDeptTb> listEnabledDepts() { private List<SystemDeptVo> listDeptVoByPid(Long pid) {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); return KitBeanUtil.copyToList(this.listDeptByPid(pid), SystemDeptVo.class);
wrapper.eq(SystemDeptTb::getEnabled, 1);
return systemDeptMapper.selectList(wrapper);
}
/**
* 遍历所有部门和子部门
*
* @param ids /
*/
public Set<SystemDeptVo> traverseDeptByIdWithPids(Set<Long> ids) {
Set<SystemDeptVo> depts = new HashSet<>();
for (Long id : ids) {
// 根部门
depts.add(this.getDeptVoById(id));
// 子部门
List<SystemDeptVo> deptList = this.listDeptByPid(id);
if (CollectionUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
} }
return depts;
}
public List<SystemProductLineVo> listDeptSelectDataSource() { public List<Long> queryChildDeptIdByDeptIds(List<SystemDeptTb> deptList, Map<Long, List<SystemDeptTb>> deptPidMap) {
List<SystemDeptTb> depts = this.listEnabledDepts(); List<Long> list = new ArrayList<>();
return buildDeptSelectOptions(depts); for (SystemDeptTb systemDeptTb : deptList) {
} if (systemDeptTb != null && systemDeptTb.getEnabled()) {
List<SystemDeptTb> deptList1 = deptPidMap.getOrDefault(systemDeptTb.getId(), null);
private List<SystemProductLineVo> buildDeptSelectOptions(List<SystemDeptTb> depts) { if (CollUtil.isNotEmpty(deptList1)) {
// 获取所有部门并按父子关系组织 list.addAll(this.queryChildDeptIdByDeptIds(deptList1, deptPidMap));
Map<Long, SystemDeptTb> deptMap = }
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity())); list.add(systemDeptTb.getId());
List<SystemProductLineVo> options = new ArrayList<>(); }
for (SystemDeptTb dept : depts) { }
// 构建部门ID路径 return list;
List<Long> pathIds = new ArrayList<>();
buildDeptIdPath(dept, deptMap, pathIds);
// 反转路径,从顶级部门到当前部门
Collections.reverse(pathIds);
SystemProductLineVo dto = new SystemProductLineVo();
dto.setValue(dept.getId());
dto.setIdPath(pathIds.stream().map(String::valueOf).collect(Collectors.joining("-")));
// 保留名称路径用于显示
dto.setLabel(buildNamePath(dept, deptMap));
options.add(dto);
} }
// 按部门名称路径排序
options.sort(Comparator.comparing(SystemProductLineVo::getLabel));
return options;
}
private void buildDeptIdPath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<Long> pathIds) { /**
pathIds.add(dept.getId()); * 根据ID获取同级与上级数据
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) { *
buildDeptIdPath(deptMap.get(dept.getPid()), deptMap, pathIds); * @param dept /
* @param deptList /
* @return /
*/
private List<SystemDeptVo> querySuperiorDeptByPid(SystemDeptVo dept, List<SystemDeptVo> deptList) {
if (dept.getPid() == null) {
deptList.addAll(this.listRootDept());
return deptList;
}
deptList.addAll(this.listDeptVoByPid(dept.getPid()));
return querySuperiorDeptByPid(this.getDeptVoById(dept.getPid()), deptList);
} }
}
private String buildNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) { private List<SystemDeptVo> listRootDept() {
List<String> pathNames = new ArrayList<>(); LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
buildDeptNamePath(dept, deptMap, pathNames); wrapper.isNull(SystemDeptTb::getPid);
Collections.reverse(pathNames); return KitBeanUtil.copyToList(systemDeptMapper.selectList(wrapper), SystemDeptVo.class);
return String.join(" / ", pathNames);
}
private void buildDeptNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<String> pathNames) {
pathNames.add(dept.getName());
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) {
buildDeptNamePath(deptMap.get(dept.getPid()), deptMap, pathNames);
} }
}
public List<SystemProductLineTreeVo> listDeptSelectProDataSource() { /**
List<SystemDeptTb> depts = this.listEnabledDepts(); * 构建树形数据
// 获取所有部门并按父子关系组织 *
Map<Long, SystemDeptTb> deptMap = * @return /
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity())); */
List<SystemProductLineTreeVo> options = new ArrayList<>(); public KitPageResult<SystemDeptVo> searchDeptTree(List<Long> ids, Boolean exclude) {
// 构建树形结构 Set<SystemDeptVo> deptSet1 = new LinkedHashSet<>();
for (SystemDeptTb dept : depts) { for (Long id : ids) {
// 只处理顶级部门(pid为null或0的部门) // 同级数据
if (dept.getPid() == null || dept.getPid() == 0) { SystemDeptVo dept = this.getDeptVoById(id);
SystemProductLineTreeVo vo = buildDeptTreePro(dept, deptMap); // 上级数据
options.add(vo); List<SystemDeptVo> depts = this.querySuperiorDeptByPid(dept, new ArrayList<>());
} if (exclude) {
for (SystemDeptVo data : depts) {
if (data.getId().equals(dept.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
// 编辑部门时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
depts = depts.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toList());
}
deptSet1.addAll(depts);
}
List<SystemDeptVo> deptList = new ArrayList<>(deptSet1);
// 构建部门树
Set<SystemDeptVo> trees = new LinkedHashSet<>();
Set<SystemDeptVo> deptSet = new LinkedHashSet<>();
List<String> deptNames = deptList.stream().map(SystemDeptVo::getName).collect(Collectors.toList());
boolean isChild;
for (SystemDeptVo dept : deptList) {
isChild = false;
if (dept.getPid() == null) {
trees.add(dept);
}
for (SystemDeptVo it : deptList) {
if (it.getPid() != null && dept.getId().equals(it.getPid())) {
isChild = true;
if (dept.getChildren() == null) {
dept.setChildren(new ArrayList<>());
}
dept.getChildren().add(it);
}
}
if (isChild) {
deptSet.add(dept);
} else if (dept.getPid() != null && !deptNames.contains(this.getDeptVoById(dept.getPid()).getName())) {
deptSet.add(dept);
}
}
if (CollUtil.isEmpty(trees)) {
trees = deptSet;
}
KitPageResult<SystemDeptVo> baseResult = new KitPageResult<>();
baseResult.setContent(CollUtil.isEmpty(trees) ? new ArrayList<>(deptSet) : new ArrayList<>(trees));
baseResult.setTotalElements(deptSet.size());
return baseResult;
} }
// 按排序字段排序
options.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
return options;
}
/** /**
* 递归构建部门树 * 验证是否被角色或用户关联
* *
* @param dept 当前部门 * @param deptSet /
* @param deptMap 部门映射 */
* @return SystemProductLineTreeVo 树节点 public void verifyBindRelationByIds(Set<SystemDeptVo> deptSet) {
*/ Set<Long> deptIds = deptSet.stream().map(SystemDeptVo::getId).collect(Collectors.toSet());
private SystemProductLineTreeVo buildDeptTreePro(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) { if (systemUserDeptService.countUserByDeptIds(deptIds) > 0) {
SystemProductLineTreeVo vo = new SystemProductLineTreeVo(); throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
vo.setValue(String.valueOf(dept.getId())); }
vo.setLabel(dept.getName()); if (systemRoleDeptService.countRoleByDeptIds(deptIds) > 0) {
// 查找子部门 throw new BadRequestException("所选部门存在角色关联,请解除后再试!");
List<SystemProductLineTreeVo> children = new ArrayList<>(); }
for (SystemDeptTb childDept : deptMap.values()) {
if (dept.getId().equals(childDept.getPid())) {
children.add(buildDeptTreePro(childDept, deptMap));
}
} }
// 子部门按排序字段排序
children.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
vo.setChildren(children);
return vo;
}
public List<SystemDeptVo> listDeptByPid(long pid) { private List<SystemDeptTb> listEnabledDepts() {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getPid, pid); wrapper.eq(SystemDeptTb::getEnabled, 1);
return KitBeanUtil.copyToList(systemDeptMapper.selectList(wrapper), SystemDeptVo.class); return systemDeptMapper.selectList(wrapper);
} }
public void exportDeptXlsx(HttpServletResponse response, SystemQueryDeptArgs args) throws Exception { /**
List<SystemDeptTb> systemDeptTbs = this.queryAllDeptByArgs(args, false); * 遍历所有部门和子部门
List<SystemDeptExportRowVo> rowVos = new ArrayList<>(); *
for (SystemDeptTb dataObject : systemDeptTbs) { * @param ids /
SystemDeptExportRowVo rowVo = new SystemDeptExportRowVo(); */
rowVo.setName(dataObject.getName()); public Set<SystemDeptVo> traverseDeptByIdWithPids(Set<Long> ids) {
rowVo.setEnabled(dataObject.getEnabled() ? SystemZhConst.ENABLE_STR : SystemZhConst.DISABLE_STR); Set<SystemDeptVo> depts = new HashSet<>();
rowVo.setCreateTime(dataObject.getCreateTime()); for (Long id : ids) {
rowVos.add(rowVo); // 根部门
depts.add(this.getDeptVoById(id));
// 子部门
List<SystemDeptVo> deptList = this.listDeptVoByPid(id);
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
}
return depts;
}
public List<SystemProductLineVo> listDeptSelectDataSource() {
List<SystemDeptTb> depts = this.listEnabledDepts();
return buildDeptSelectOptions(depts);
}
private List<SystemProductLineVo> buildDeptSelectOptions(List<SystemDeptTb> depts) {
// 获取所有部门并按父子关系组织
Map<Long, SystemDeptTb> deptMap =
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity()));
List<SystemProductLineVo> options = new ArrayList<>();
for (SystemDeptTb dept : depts) {
// 构建部门ID路径
List<Long> pathIds = new ArrayList<>();
buildDeptIdPath(dept, deptMap, pathIds);
// 反转路径,从顶级部门到当前部门
Collections.reverse(pathIds);
SystemProductLineVo dto = new SystemProductLineVo();
dto.setValue(dept.getId());
dto.setIdPath(pathIds.stream().map(String::valueOf).collect(Collectors.joining("-")));
// 保留名称路径用于显示
dto.setLabel(buildNamePath(dept, deptMap));
options.add(dto);
}
// 按部门名称路径排序
options.sort(Comparator.comparing(SystemProductLineVo::getLabel));
return options;
}
private void buildDeptIdPath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<Long> pathIds) {
pathIds.add(dept.getId());
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) {
buildDeptIdPath(deptMap.get(dept.getPid()), deptMap, pathIds);
}
}
private String buildNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) {
List<String> pathNames = new ArrayList<>();
buildDeptNamePath(dept, deptMap, pathNames);
Collections.reverse(pathNames);
return String.join(" / ", pathNames);
}
private void buildDeptNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<String> pathNames) {
pathNames.add(dept.getName());
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) {
buildDeptNamePath(deptMap.get(dept.getPid()), deptMap, pathNames);
}
}
public List<SystemProductLineTreeVo> listDeptSelectProDataSource() {
List<SystemDeptTb> depts = this.listEnabledDepts();
// 获取所有部门并按父子关系组织
Map<Long, SystemDeptTb> deptMap =
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity()));
List<SystemProductLineTreeVo> options = new ArrayList<>();
// 构建树形结构
for (SystemDeptTb dept : depts) {
// 只处理顶级部门(pid为null或0的部门)
if (dept.getPid() == null || dept.getPid() == 0) {
SystemProductLineTreeVo vo = buildDeptTreePro(dept, deptMap);
options.add(vo);
}
}
// 按排序字段排序
options.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
return options;
}
/**
* 递归构建部门树
*
* @param dept 当前部门
* @param deptMap 部门映射
* @return SystemProductLineTreeVo 树节点
*/
private SystemProductLineTreeVo buildDeptTreePro(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) {
SystemProductLineTreeVo vo = new SystemProductLineTreeVo();
vo.setValue(String.valueOf(dept.getId()));
vo.setLabel(dept.getName());
// 查找子部门
List<SystemProductLineTreeVo> children = new ArrayList<>();
for (SystemDeptTb childDept : deptMap.values()) {
if (dept.getId().equals(childDept.getPid())) {
children.add(buildDeptTreePro(childDept, deptMap));
}
}
// 子部门按排序字段排序
children.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
vo.setChildren(children);
return vo;
}
public List<SystemDeptTb> listDeptByPid(long pid) {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getPid, pid);
return systemDeptMapper.selectList(wrapper);
}
public void exportDeptXlsx(HttpServletResponse response, SystemQueryDeptArgs args) throws Exception {
List<SystemDeptTb> systemDeptTbs = this.queryAllDeptByArgs(args, false);
List<SystemDeptExportRowVo> rowVos = new ArrayList<>();
for (SystemDeptTb dataObject : systemDeptTbs) {
SystemDeptExportRowVo rowVo = new SystemDeptExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setEnabled(dataObject.getEnabled() ? SystemZhConst.ENABLE_STR : SystemZhConst.DISABLE_STR);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "部门数据", SystemDeptExportRowVo.class, rowVos);
}
public List<SystemDeptTb> listPidNonNull() {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getEnabled, 1);
wrapper.isNotNull(SystemDeptTb::getPid);
return systemDeptMapper.selectList(wrapper);
} }
KitExcelExporter.exportSimple(response, "部门数据", SystemDeptExportRowVo.class, rowVos);
}
} }
@@ -31,120 +31,122 @@ import cn.odboy.util.KitValidUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemDictDetailService { public class SystemDictDetailService {
@Autowired @Autowired
private SystemDictDetailMapper systemDictDetailMapper; private SystemDictDetailMapper systemDictDetailMapper;
@Autowired @Autowired
private SystemDictMapper systemDictMapper; private SystemDictMapper systemDictMapper;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveDictDetail(SystemCreateDictDetailArgs args) { public void saveDictDetail(SystemCreateDictDetailArgs args) {
KitValidUtil.notNull(args); KitValidUtil.notNull(args);
KitValidUtil.notNull(args.getDict()); KitValidUtil.notNull(args.getDict());
SystemDictDetailTb dictDetail = KitBeanUtil.copyToClass(args, SystemDictDetailTb.class); SystemDictDetailTb dictDetail = KitBeanUtil.copyToClass(args, SystemDictDetailTb.class);
dictDetail.setDictId(args.getDict().getId()); dictDetail.setDictId(args.getDict().getId());
systemDictDetailMapper.insert(dictDetail); systemDictDetailMapper.insert(dictDetail);
}
/**
* 编辑
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateDictDetailById(SystemDictDetailTb args) {
SystemDictDetailTb dictDetail = systemDictDetailMapper.selectById(args.getId());
args.setId(dictDetail.getId());
systemDictDetailMapper.insertOrUpdate(args);
}
/**
* 删除
*
* @param id /
*/
@Transactional(rollbackFor = Exception.class)
public void deleteDictDetailById(Long id) {
systemDictDetailMapper.deleteById(id);
}
@Transactional(rollbackFor = Exception.class)
public void deleteDictDetailByDictIds(Set<Long> ids) {
if (CollUtil.isNotEmpty(ids)) {
LambdaQueryWrapper<SystemDictDetailTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemDictDetailTb::getDictId, ids);
systemDictDetailMapper.delete(wrapper);
} }
}
private List<SystemDictDetailTb> listDictDetailByDictId(Long dictId) { /**
LambdaQueryWrapper<SystemDictDetailTb> wrapper = new LambdaQueryWrapper<>(); * 编辑 -> TestPassed
wrapper.eq(SystemDictDetailTb::getDictId, dictId); *
return systemDictDetailMapper.selectList(wrapper); * @param args /
} */
@Transactional(rollbackFor = Exception.class)
public void updateDictDetailById(SystemDictDetailTb args) {
SystemDictDetailTb dictDetail = systemDictDetailMapper.selectById(args.getId());
args.setId(dictDetail.getId());
systemDictDetailMapper.insertOrUpdate(args);
}
/** /**
* 分页查询 * 删除 -> TestPassed
* *
* @param args 条件 * @param id /
* @param page 分页参数 */
* @return / @Transactional(rollbackFor = Exception.class)
*/ public void deleteDictDetailById(Long id) {
public KitPageResult<SystemDictDetailVo> searchDictDetail(SystemQueryDictDetailArgs args, Page<SystemDictDetailTb> page) { systemDictDetailMapper.deleteById(id);
IPage<SystemDictDetailVo> iPage = systemDictDetailMapper.selectPageByArgs(page, args).convert(i -> KitBeanUtil.copyToClass(i, SystemDictDetailVo.class));
List<Long> dictIds = iPage.getRecords().stream().map(SystemDictDetailVo::getDictId).collect(Collectors.toList());
Map<Long, SystemDictTb> id2ItemMap = systemDictMapper.selectByIds(dictIds).stream().collect(Collectors.toMap(SystemDictTb::getId, i -> i));
for (SystemDictDetailVo record : iPage.getRecords()) {
record.setDict(id2ItemMap.get(record.getDictId()));
} }
return KitPageUtil.toPage(iPage);
}
/** @Transactional(rollbackFor = Exception.class)
* 根据字典名称获取字典详情 public void deleteDictDetailByDictIds(Set<Long> ids) {
* if (CollUtil.isNotEmpty(ids)) {
* @param name 字典名称 LambdaQueryWrapper<SystemDictDetailTb> wrapper = new LambdaQueryWrapper<>();
* @return / wrapper.in(SystemDictDetailTb::getDictId, ids);
*/ systemDictDetailMapper.delete(wrapper);
public List<SystemDictDetailVo> listDictDetailByName(String name) { }
if (StrUtil.isBlank(name)) {
return new ArrayList<>();
} }
SystemDictTb systemDictTb = systemDictMapper.getByName(name);
if (systemDictTb == null) {
return new ArrayList<>();
}
List<SystemDictDetailTb> detailTbs = this.listDictDetailByDictId(systemDictTb.getId());
List<SystemDictDetailVo> detailVos = KitBeanUtil.copyToList(detailTbs, SystemDictDetailVo.class);
for (SystemDictDetailVo detailVo : detailVos) {
detailVo.setDict(systemDictTb);
}
return detailVos;
}
public Map<String, List<SystemDictDetailVo>> getDictDetailMap(String dictName) { /**
String[] names = dictName.split("[,, ]"); * 分页查询 -> TestPassed
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16); *
for (String name : names) { * @param args 条件
dictMap.put(name, this.listDictDetailByName(name)); * @param page 分页参数
* @return /
*/
public KitPageResult<SystemDictDetailVo> searchDictDetail(SystemQueryDictDetailArgs args,
Page<SystemDictDetailTb> page) {
IPage<SystemDictDetailVo> iPage = systemDictDetailMapper.selectPageByArgs(page, args);
List<Long> dictIds =
iPage.getRecords().stream().map(SystemDictDetailVo::getDictId).collect(Collectors.toList());
if (CollUtil.isNotEmpty(dictIds)) {
Map<Long, SystemDictTb> id2ItemMap =
systemDictMapper.selectByIds(dictIds).stream().collect(Collectors.toMap(SystemDictTb::getId, i -> i));
for (SystemDictDetailVo record : iPage.getRecords()) {
record.setDict(id2ItemMap.get(record.getDictId()));
}
}
return KitPageUtil.toPage(iPage);
}
/**
* 根据字典名称获取字典详情 -> TestPassed
*
* @param name 字典名称
* @return /
*/
public List<SystemDictDetailVo> listDictDetailByName(String name) {
if (StrUtil.isBlank(name)) {
return new ArrayList<>();
}
List<SystemDictDetailVo> detailVos = systemDictDetailMapper.listDictDetailByName(name);
if (CollUtil.isNotEmpty(detailVos)) {
SystemDictDetailVo systemDictDetailVo = detailVos.stream().findFirst().orElse(null);
if (systemDictDetailVo != null) {
SystemDictTb systemDictTb = systemDictMapper.selectById(systemDictDetailVo.getDictId());
if (systemDictTb != null) {
for (SystemDictDetailVo detailVo : detailVos) {
detailVo.setDict(systemDictTb);
}
}
}
}
return detailVos;
}
public Map<String, List<SystemDictDetailVo>> getDictDetailMap(String dictName) {
String[] names = dictName.split("[,, ]");
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, this.listDictDetailByName(name));
}
return dictMap;
} }
return dictMap;
}
} }
@@ -29,111 +29,111 @@ import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemDictService { public class SystemDictService {
@Autowired @Autowired
private SystemDictMapper systemDictMapper; private SystemDictMapper systemDictMapper;
@Autowired @Autowired
private SystemDictDetailService systemDictDetailService; private SystemDictDetailService systemDictDetailService;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveDict(SystemCreateDictArgs args) { public void saveDict(SystemCreateDictArgs args) {
SystemDictTb dictTb = KitBeanUtil.copyToClass(args, SystemDictTb.class); SystemDictTb dictTb = KitBeanUtil.copyToClass(args, SystemDictTb.class);
systemDictMapper.insert(dictTb); systemDictMapper.insert(dictTb);
}
/**
* 编辑
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateDictById(SystemDictTb args) {
SystemDictTb dict = systemDictMapper.selectById(args.getId());
dict.setName(args.getName());
dict.setDescription(args.getDescription());
systemDictMapper.insertOrUpdate(dict);
}
/**
* 删除
*
* @param ids /
*/
@Transactional(rollbackFor = Exception.class)
public void deleteDictByIds(Set<Long> ids) {
// 删除字典
systemDictMapper.deleteByIds(ids);
// 删除字典详情
systemDictDetailService.deleteDictDetailByDictIds(ids);
}
/**
* 分页查询
*
* @param args 条件
* @param page 分页参数
* @return /
*/
public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page) {
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage);
}
private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) {
if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemDictTb::getName, args.getBlurry()).or()
.like(SystemDictTb::getDescription, args.getBlurry()));
} }
}
public List<SystemDictTb> queryDictByArgs(SystemQueryDictArgs args) { /**
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>(); * 编辑 -> TestPassed
this.injectQueryParams(args, wrapper); *
return systemDictMapper.selectList(wrapper); * @param args /
} */
@Transactional(rollbackFor = Exception.class)
public void updateDictById(SystemDictTb args) {
SystemDictTb dict = systemDictMapper.selectById(args.getId());
dict.setName(args.getName());
dict.setDescription(args.getDescription());
systemDictMapper.insertOrUpdate(dict);
}
public void exportDictXlsx(HttpServletResponse response, SystemQueryDictArgs args) { /**
List<SystemDictTb> systemDictTbs = this.queryDictByArgs(args); * 删除 -> TestPassed
List<SystemDictExportRowVo> rowVos = new ArrayList<>(); *
for (SystemDictTb dataObject : systemDictTbs) { * @param ids /
List<SystemDictDetailVo> dictDetails = systemDictDetailService.listDictDetailByName(dataObject.getName()); */
if (CollUtil.isEmpty(dictDetails)) { @Transactional(rollbackFor = Exception.class)
SystemDictExportRowVo rowVo = new SystemDictExportRowVo(); public void deleteDictByIds(Set<Long> ids) {
rowVo.setName(dataObject.getName()); // 删除字典
rowVo.setDescription(dataObject.getDescription()); systemDictMapper.deleteByIds(ids);
rowVo.setCreateTime(dataObject.getCreateTime()); // 删除字典详情
rowVo.setLabel(""); systemDictDetailService.deleteDictDetailByDictIds(ids);
rowVo.setValue(""); }
rowVos.add(rowVo);
continue; /**
} * 分页查询 -> TestPassed
for (SystemDictDetailVo dictDetail : dictDetails) { *
SystemDictExportRowVo rowVo = new SystemDictExportRowVo(); * @param args 条件
rowVo.setName(dataObject.getName()); * @param page 分页参数
rowVo.setDescription(dataObject.getDescription()); * @return /
rowVo.setCreateTime(dataObject.getCreateTime()); */
rowVo.setLabel(dictDetail.getLabel()); public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page) {
rowVo.setValue(dictDetail.getValue()); LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>();
rowVos.add(rowVo); this.injectQueryParams(args, wrapper);
} Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage);
}
private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) {
if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemDictTb::getName, args.getBlurry()).or()
.like(SystemDictTb::getDescription, args.getBlurry()));
}
}
public List<SystemDictTb> queryDictByArgs(SystemQueryDictArgs args) {
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
return systemDictMapper.selectList(wrapper);
}
public void exportDictXlsx(HttpServletResponse response, SystemQueryDictArgs args) {
List<SystemDictTb> systemDictTbs = this.queryDictByArgs(args);
List<SystemDictExportRowVo> rowVos = new ArrayList<>();
for (SystemDictTb dataObject : systemDictTbs) {
List<SystemDictDetailVo> dictDetails = systemDictDetailService.listDictDetailByName(dataObject.getName());
if (CollUtil.isEmpty(dictDetails)) {
SystemDictExportRowVo rowVo = new SystemDictExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVo.setLabel("");
rowVo.setValue("");
rowVos.add(rowVo);
continue;
}
for (SystemDictDetailVo dictDetail : dictDetails) {
SystemDictExportRowVo rowVo = new SystemDictExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVo.setLabel(dictDetail.getLabel());
rowVo.setValue(dictDetail.getValue());
rowVos.add(rowVo);
}
}
KitExcelExporter.exportSimple(response, "字典数据", SystemDictExportRowVo.class, rowVos);
} }
KitExcelExporter.exportSimple(response, "字典数据", SystemDictExportRowVo.class, rowVos);
}
} }
@@ -30,134 +30,134 @@ import cn.odboy.system.dal.model.request.SystemSendEmailArgs;
import cn.odboy.system.dal.mysql.SystemEmailConfigMapper; import cn.odboy.system.dal.mysql.SystemEmailConfigMapper;
import cn.odboy.util.KitDesEncryptUtil; import cn.odboy.util.KitDesEncryptUtil;
import cn.odboy.util.KitResourceTemplateUtil; import cn.odboy.util.KitResourceTemplateUtil;
import java.util.Collections;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
@Slf4j @Slf4j
@Service @Service
public class SystemEmailService { public class SystemEmailService {
@Autowired @Autowired
private SystemEmailConfigMapper systemEmailConfigMapper; private SystemEmailConfigMapper systemEmailConfigMapper;
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
/** /**
* 更新邮件配置 * 更新邮件配置 -> TestPassed
* *
* @param emailConfig 邮箱配置 * @param emailConfig 邮箱配置
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateEmailConfigById(SystemEmailConfigTb emailConfig) throws Exception { public void updateEmailConfigById(SystemEmailConfigTb emailConfig) throws Exception {
SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig(); SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig();
if (!emailConfig.getPassword().equals(systemEmailConfigTb.getPassword())) { if (!emailConfig.getPassword().equals(systemEmailConfigTb.getPassword())) {
// 对称加密 // 对称加密
systemEmailConfigTb.setPassword(KitDesEncryptUtil.desEncrypt(emailConfig.getPassword())); systemEmailConfigTb.setPassword(KitDesEncryptUtil.desEncrypt(emailConfig.getPassword()));
}
systemEmailConfigTb.setId(1L);
systemEmailConfigMapper.insertOrUpdate(systemEmailConfigTb);
} }
systemEmailConfigTb.setId(1L);
systemEmailConfigMapper.insertOrUpdate(systemEmailConfigTb);
}
/** /**
* 发送邮件 * 发送邮件 -> TestPassed
* *
* @param sendEmailRequest 邮件发送的内容 * @param sendEmailRequest 邮件发送的内容
*/ */
public void sendEmail(SystemSendEmailArgs sendEmailRequest) { public void sendEmail(SystemSendEmailArgs sendEmailRequest) {
SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig(); SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig();
if (systemEmailConfigTb.getId() == null) { if (systemEmailConfigTb.getId() == null) {
throw new BadRequestException("请先配置, 再操作"); throw new BadRequestException("请先配置, 再操作");
}
// 封装
MailAccount account = new MailAccount();
// 设置用户
String user = systemEmailConfigTb.getFromUser().split("@")[0];
account.setUser(user);
account.setHost(systemEmailConfigTb.getHost());
account.setPort(Integer.parseInt(systemEmailConfigTb.getPort()));
account.setAuth(true);
try {
// 对称解密
account.setPass(KitDesEncryptUtil.desDecrypt(systemEmailConfigTb.getPassword()));
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
account.setFrom(systemEmailConfigTb.getUser() + "<" + systemEmailConfigTb.getFromUser() + ">");
// ssl方式发送
account.setSslEnable(true);
// 使用STARTTLS安全连接
account.setStarttlsEnable(true);
// 解决jdk8之后默认禁用部分tls协议, 导致邮件发送失败的问题
account.setSslProtocols("TLSv1 TLSv1.1 TLSv1.2");
String content = sendEmailRequest.getContent();
// 发送
try {
int size = sendEmailRequest.getTos().size();
Mail.create(account).setTos(sendEmailRequest.getTos().toArray(new String[size]))
.setTitle(sendEmailRequest.getSubject()).setContent(content).setHtml(true)
// 关闭session
.setUseGlobalSession(false).send();
} catch (Exception e) {
log.error("邮件发送失败", e);
throw new BadRequestException("邮件发送失败");
}
} }
// 封装
MailAccount account = new MailAccount();
// 设置用户
String user = systemEmailConfigTb.getFromUser().split("@")[0];
account.setUser(user);
account.setHost(systemEmailConfigTb.getHost());
account.setPort(Integer.parseInt(systemEmailConfigTb.getPort()));
account.setAuth(true);
try {
// 对称解密
account.setPass(KitDesEncryptUtil.desDecrypt(systemEmailConfigTb.getPassword()));
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
account.setFrom(systemEmailConfigTb.getUser() + "<" + systemEmailConfigTb.getFromUser() + ">");
// ssl方式发送
account.setSslEnable(true);
// 使用STARTTLS安全连接
account.setStarttlsEnable(true);
// 解决jdk8之后默认禁用部分tls协议, 导致邮件发送失败的问题
account.setSslProtocols("TLSv1 TLSv1.1 TLSv1.2");
String content = sendEmailRequest.getContent();
// 发送
try {
int size = sendEmailRequest.getTos().size();
Mail.create(account).setTos(sendEmailRequest.getTos().toArray(new String[size]))
.setTitle(sendEmailRequest.getSubject()).setContent(content).setHtml(true)
// 关闭session
.setUseGlobalSession(false).send();
} catch (Exception e) {
log.error("邮件发送失败", e);
throw new BadRequestException("邮件发送失败");
}
}
/** /**
* 校验邮箱验证码 * 校验邮箱验证码 -> TestPassed
*/ */
public void checkEmailCaptchaV1(SystemCaptchaBizEnum biEnum, String email, String code) { public void checkEmailCaptchaV1(SystemCaptchaBizEnum biEnum, String email, String code) {
String redisKey = biEnum.getRedisKey() + email; String redisKey = biEnum.getRedisKey() + email;
String value = redisHelper.get(redisKey, String.class); String value = redisHelper.get(redisKey, String.class);
if (value == null || !value.equals(code)) { if (value == null || !value.equals(code)) {
throw new BadRequestException("无效验证码"); throw new BadRequestException("无效验证码");
} else { } else {
redisHelper.del(redisKey); redisHelper.del(redisKey);
}
} }
}
/** /**
* 发送给邮箱验证码 * 发送给邮箱验证码
*/ */
public void sendCaptcha(SystemCaptchaBizEnum biEnum, String email) { public void sendCaptcha(SystemCaptchaBizEnum biEnum, String email) {
if (biEnum == null) { if (biEnum == null) {
throw new BadRequestException("biEnum必填"); throw new BadRequestException("biEnum必填");
}
String content;
String redisKey = biEnum.getRedisKey() + email;
String oldCode = redisHelper.get(redisKey, String.class);
if (oldCode == null) {
String code = RandomUtil.randomNumbers(6);
// 存入缓存
if (!redisHelper.set(redisKey, code, properties.getCaptcha().getExpireTime())) {
throw new BadRequestException("服务异常, 请联系网站负责人");
}
// 存在就再次发送原来的验证码
content = KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", code));
} else {
content =
KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", oldCode));
}
SystemSendEmailArgs sendEmailRequest =
new SystemSendEmailArgs(Collections.singletonList(email), SystemConst.CURRENT_APP_TITLE, content);
sendEmail(sendEmailRequest);
} }
String content;
String redisKey = biEnum.getRedisKey() + email;
String oldCode = redisHelper.get(redisKey, String.class);
if (oldCode == null) {
String code = RandomUtil.randomNumbers(6);
// 存入缓存
if (!redisHelper.set(redisKey, code, properties.getCaptcha().getExpireTime())) {
throw new BadRequestException("服务异常, 请联系网站负责人");
}
// 存在就再次发送原来的验证码
content = KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", code));
} else {
content =
KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", oldCode));
}
SystemSendEmailArgs sendEmailRequest =
new SystemSendEmailArgs(Collections.singletonList(email), SystemConst.CURRENT_APP_TITLE, content);
sendEmail(sendEmailRequest);
}
public SystemEmailConfigTb getLastEmailConfig() { public SystemEmailConfigTb getLastEmailConfig() {
SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L); SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L);
return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb; return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb;
} }
public void checkEmailCaptcha(SystemCheckEmailCaptchaArgs args) { public void checkEmailCaptcha(SystemCheckEmailCaptchaArgs args) {
SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode()); SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode());
if (biEnum == null) { if (biEnum == null) {
throw new BadRequestException("不支持的业务"); throw new BadRequestException("不支持的业务");
}
this.checkEmailCaptchaV1(biEnum, args.getEmail(), args.getCode());
} }
this.checkEmailCaptchaV1(biEnum, args.getEmail(), args.getCode());
}
} }
@@ -29,130 +29,129 @@ import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemJobService { public class SystemJobService {
@Autowired @Autowired
private SystemJobMapper systemJobMapper; private SystemJobMapper systemJobMapper;
@Autowired @Autowired
private SystemUserJobService systemUserJobService; private SystemUserJobService systemUserJobService;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveJob(SystemCreateJobArgs args) { public void saveJob(SystemCreateJobArgs args) {
SystemJobTb job = this.getJobByName(args.getName()); SystemJobTb job = this.getJobByName(args.getName());
if (job != null) { if (job != null) {
throw new BadRequestException("职位名称已存在"); throw new BadRequestException("职位名称已存在");
}
SystemJobTb systemJobTb = KitBeanUtil.copyToClass(args, SystemJobTb.class);
systemJobMapper.insert(systemJobTb);
} }
SystemJobTb systemJobTb = KitBeanUtil.copyToClass(args, SystemJobTb.class);
systemJobMapper.insert(systemJobTb);
}
/** /**
* 编辑 * 编辑 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateJobById(SystemJobTb args) { public void updateJobById(SystemJobTb args) {
SystemJobTb job = systemJobMapper.selectById(args.getId()); SystemJobTb job = systemJobMapper.selectById(args.getId());
SystemJobTb old = this.getJobByName(args.getName()); SystemJobTb old = this.getJobByName(args.getName());
if (old != null && !old.getId().equals(args.getId())) { if (old != null && !old.getId().equals(args.getId())) {
throw new BadRequestException("职位名称已存在"); throw new BadRequestException("职位名称已存在");
}
args.setId(job.getId());
systemJobMapper.updateById(args);
} }
args.setId(job.getId());
systemJobMapper.insertOrUpdate(args);
}
/** /**
* 删除 * 删除 -> TestPassed
* *
* @param ids / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Set<Long> ids) { public void deleteJobByIds(Set<Long> ids) {
// 验证是否被用户关联 // 验证是否被用户关联
this.verifyBindRelationByIds(ids); this.verifyBindRelationByIds(ids);
systemJobMapper.deleteByIds(ids); systemJobMapper.deleteByIds(ids);
}
/**
* 分页查询
*
* @param args 条件
* @param page 分页参数
*/
public KitPageResult<SystemJobTb> searchJobByArgs(SystemQueryJobArgs args, Page<SystemJobTb> page) {
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
Page<SystemJobTb> selectPage = systemJobMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage);
}
/**
* 查询全部数据
*/
public List<SystemJobTb> queryJobByArgs(SystemQueryJobArgs args) {
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
return systemJobMapper.selectList(wrapper);
}
/**
* 验证是否被用户关联
*
* @param ids /
*/
public void verifyBindRelationByIds(Set<Long> ids) {
if (systemUserJobService.countUserByJobIds(ids) > 0) {
throw new BadRequestException("所选的岗位中存在用户关联, 请解除关联再试!");
} }
}
public SystemJobTb getJobByName(String name) { /**
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>(); * 分页查询 -> TestPassed
wrapper.eq(SystemJobTb::getName, name); *
return systemJobMapper.selectOne(wrapper); * @param args 条件
} * @param page 分页参数
*/
public void injectQueryParams(SystemQueryJobArgs args, LambdaQueryWrapper<SystemJobTb> wrapper) { public KitPageResult<SystemJobTb> searchJobByArgs(SystemQueryJobArgs args, Page<SystemJobTb> page) {
if (args != null) { LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemJobTb::getName, args.getName()); this.injectQueryParams(args, wrapper);
wrapper.eq(args.getEnabled() != null, SystemJobTb::getEnabled, args.getEnabled()); Page<SystemJobTb> selectPage = systemJobMapper.selectPage(page, wrapper);
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { return KitPageUtil.toPage(selectPage);
wrapper.between(SystemJobTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
} }
wrapper.orderByDesc(SystemJobTb::getJobSort, SystemJobTb::getId);
}
public void exportJobXlsx(HttpServletResponse response, SystemQueryJobArgs args) { /**
List<SystemJobTb> systemJobTbs = this.queryJobByArgs(args); * 查询全部数据 -> TestPassed
List<SystemJobExportRowVo> rowVos = new ArrayList<>(); */
for (SystemJobTb dataObject : systemJobTbs) { public List<SystemJobTb> queryJobByArgs(SystemQueryJobArgs args) {
SystemJobExportRowVo rowVo = new SystemJobExportRowVo(); LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
rowVo.setName(dataObject.getName()); this.injectQueryParams(args, wrapper);
rowVo.setEnabled(dataObject.getEnabled() ? "启用" : "停用"); return systemJobMapper.selectList(wrapper);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
} }
KitExcelExporter.exportSimple(response, "岗位数据", SystemJobExportRowVo.class, rowVos);
}
public List<SystemJobTb> listByIds(Set<Long> jobIds) { /**
return systemJobMapper.selectByIds(jobIds); * 验证是否被用户关联 -> TestPassed
} *
* @param ids /
*/
public void verifyBindRelationByIds(Set<Long> ids) {
if (systemUserJobService.countUserByJobIds(ids) > 0) {
throw new BadRequestException("所选的岗位中存在用户关联, 请解除关联再试!");
}
}
public SystemJobTb getJobByName(String name) {
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemJobTb::getName, name);
return systemJobMapper.selectOne(wrapper);
}
public void injectQueryParams(SystemQueryJobArgs args, LambdaQueryWrapper<SystemJobTb> wrapper) {
if (args != null) {
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemJobTb::getName, args.getName());
wrapper.eq(args.getEnabled() != null, SystemJobTb::getEnabled, args.getEnabled());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemJobTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
}
}
wrapper.orderByDesc(SystemJobTb::getJobSort, SystemJobTb::getId);
}
public void exportJobXlsx(HttpServletResponse response, SystemQueryJobArgs args) {
List<SystemJobTb> systemJobTbs = this.queryJobByArgs(args);
List<SystemJobExportRowVo> rowVos = new ArrayList<>();
for (SystemJobTb dataObject : systemJobTbs) {
SystemJobExportRowVo rowVo = new SystemJobExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setEnabled(dataObject.getEnabled() ? "启用" : "停用");
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "岗位数据", SystemJobExportRowVo.class, rowVos);
}
public List<SystemJobTb> listByIds(Set<Long> jobIds) {
return systemJobMapper.selectByIds(jobIds);
}
} }
@@ -36,142 +36,142 @@ import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.io.File;
import java.util.Date;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.List;
@Service @Service
public class SystemLocalStorageService { public class SystemLocalStorageService {
@Autowired @Autowired
private SystemLocalStorageMapper systemLocalStorageMapper; private SystemLocalStorageMapper systemLocalStorageMapper;
@Autowired @Autowired
private KitFileLocalUploadHelper fileUploadPathHelper; private KitFileLocalUploadHelper fileUploadPathHelper;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
/** /**
* 上传 * 上传 -> TestPassed
* *
* @param name 文件名称 * @param name 文件名称
* @param multipartFile 文件 * @param multipartFile 文件
* @return / * @return /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public SystemLocalStorageTb uploadFile(String name, MultipartFile multipartFile) { public SystemLocalStorageTb uploadFile(String name, MultipartFile multipartFile) {
long size = multipartFile.getSize(); long size = multipartFile.getSize();
KitFileUtil.checkSize(properties.getOss().getMaxSize(), size); KitFileUtil.checkSize(properties.getOss().getMaxSize(), size);
String suffix = KitFileUtil.getSuffix(multipartFile.getOriginalFilename()); String suffix = KitFileUtil.getSuffix(multipartFile.getOriginalFilename());
String type = KitFileUtil.getFileType(suffix); String type = KitFileUtil.getFileType(suffix);
String uploadDateStr = DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT); String uploadDateStr = DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT);
File file = KitFileUtil.upload(multipartFile, fileUploadPathHelper.getPath() + uploadDateStr + File.separator); File file = KitFileUtil.upload(multipartFile, fileUploadPathHelper.getPath() + uploadDateStr + File.separator);
if (file == null) { if (file == null) {
throw new BadRequestException("上传失败"); throw new BadRequestException("上传失败");
}
try {
String formatSize = KitFileUtil.getSize(size);
String prefixName =
StrUtil.isBlank(name) ? KitFileUtil.getPrefix(multipartFile.getOriginalFilename()) : name;
SystemLocalStorageTb localStorage = new SystemLocalStorageTb();
localStorage.setRealName(file.getName());
localStorage.setName(prefixName);
localStorage.setSuffix(suffix);
localStorage.setPath(file.getPath());
localStorage.setType(type);
localStorage.setSize(formatSize);
localStorage.setDateGroup(uploadDateStr);
systemLocalStorageMapper.insert(localStorage);
return localStorage;
} catch (Exception e) {
KitFileUtil.del(file);
throw e;
}
} }
try {
String formatSize = KitFileUtil.getSize(size); /**
String prefixName = * 编辑 -> TestPassed
StrUtil.isBlank(name) ? KitFileUtil.getPrefix(multipartFile.getOriginalFilename()) : name; *
SystemLocalStorageTb localStorage = new SystemLocalStorageTb(); * @param args 文件信息
localStorage.setRealName(file.getName()); */
localStorage.setName(prefixName); @Transactional(rollbackFor = Exception.class)
localStorage.setSuffix(suffix); public void updateLocalStorageById(SystemLocalStorageTb args) {
localStorage.setPath(file.getPath()); SystemLocalStorageTb localStorage = systemLocalStorageMapper.selectById(args.getId());
localStorage.setType(type); localStorage.copy(args);
localStorage.setSize(formatSize); systemLocalStorageMapper.insertOrUpdate(localStorage);
localStorage.setDateGroup(uploadDateStr);
systemLocalStorageMapper.insert(localStorage);
return localStorage;
} catch (Exception e) {
KitFileUtil.del(file);
throw e;
} }
}
/** /**
* 编辑 * 多选删除 -> TestPassed
* *
* @param args 文件信息 * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateLocalStorageById(SystemLocalStorageTb args) { public void deleteFileByIds(Long[] ids) {
SystemLocalStorageTb localStorage = systemLocalStorageMapper.selectById(args.getId()); for (Long id : ids) {
localStorage.copy(args); SystemLocalStorageTb storage = systemLocalStorageMapper.selectById(id);
systemLocalStorageMapper.insertOrUpdate(localStorage); try {
} KitFileUtil.del(storage.getPath());
systemLocalStorageMapper.deleteById(storage);
/** } catch (IORuntimeException e) {
* 多选删除 throw new BadRequestException("删除文件 " + storage.getName() + " 失败");
* }
* @param ids / }
*/
@Transactional(rollbackFor = Exception.class)
public void deleteFileByIds(Long[] ids) {
for (Long id : ids) {
SystemLocalStorageTb storage = systemLocalStorageMapper.selectById(id);
try {
KitFileUtil.del(storage.getPath());
systemLocalStorageMapper.deleteById(storage);
} catch (IORuntimeException e) {
throw new BadRequestException("删除文件 " + storage.getName() + " 失败");
}
} }
}
/** /**
* 分页查询 * 分页查询 -> TestPassed
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @return / * @return /
*/ */
public KitPageResult<SystemLocalStorageTb> searchLocalStorage(SystemQueryStorageArgs args, public KitPageResult<SystemLocalStorageTb> searchLocalStorage(SystemQueryStorageArgs args,
Page<SystemLocalStorageTb> page) { Page<SystemLocalStorageTb> page) {
LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper); this.injectQueryParams(args, wrapper);
Page<SystemLocalStorageTb> selectPage = systemLocalStorageMapper.selectPage(page, wrapper); Page<SystemLocalStorageTb> selectPage = systemLocalStorageMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage); return KitPageUtil.toPage(selectPage);
}
private void injectQueryParams(SystemQueryStorageArgs args, LambdaQueryWrapper<SystemLocalStorageTb> wrapper) {
if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemLocalStorageTb::getName, args.getBlurry()).or()
.like(SystemLocalStorageTb::getSuffix, args.getBlurry()).or()
.like(SystemLocalStorageTb::getType, args.getBlurry()).or()
.like(SystemLocalStorageTb::getCreateBy, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemLocalStorageTb::getUpdateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
} }
wrapper.orderByDesc(SystemLocalStorageTb::getId);
}
public List<SystemLocalStorageTb> queryLocalStorageByArgs(SystemQueryStorageArgs args) { private void injectQueryParams(SystemQueryStorageArgs args, LambdaQueryWrapper<SystemLocalStorageTb> wrapper) {
LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>(); if (args != null) {
this.injectQueryParams(args, wrapper); wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
return systemLocalStorageMapper.selectList(wrapper); c -> c.like(SystemLocalStorageTb::getName, args.getBlurry()).or()
} .like(SystemLocalStorageTb::getSuffix, args.getBlurry()).or()
.like(SystemLocalStorageTb::getType, args.getBlurry()).or()
.like(SystemLocalStorageTb::getCreateBy, args.getBlurry()));
public SystemLocalStorageTb uploadPictureV1(MultipartFile file) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
// 判断文件是否为图片 wrapper.between(SystemLocalStorageTb::getUpdateTime, args.getCreateTime().get(0),
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename()); args.getCreateTime().get(1));
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) { }
throw new BadRequestException("只能上传图片"); }
wrapper.orderByDesc(SystemLocalStorageTb::getId);
} }
return KitSpringBeanHolder.getBean(SystemLocalStorageService.class).uploadFile(null, file);
}
public void exportLocalStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args) { public List<SystemLocalStorageTb> queryLocalStorageByArgs(SystemQueryStorageArgs args) {
List<SystemLocalStorageTb> systemLocalStorageTbs = this.queryLocalStorageByArgs(args); LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>();
List<SystemLocalStorageExportRowVo> rowVos = KitBeanUtil.copyToList(systemLocalStorageTbs, SystemLocalStorageExportRowVo.class); this.injectQueryParams(args, wrapper);
KitExcelExporter.exportSimple(response, "文件上传记录数据", SystemLocalStorageExportRowVo.class, rowVos); return systemLocalStorageMapper.selectList(wrapper);
} }
public SystemLocalStorageTb uploadPictureV1(MultipartFile file) {
// 判断文件是否为图片
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename());
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) {
throw new BadRequestException("只能上传图片");
}
return KitSpringBeanHolder.getBean(SystemLocalStorageService.class).uploadFile(null, file);
}
public void exportLocalStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args) {
List<SystemLocalStorageTb> systemLocalStorageTbs = this.queryLocalStorageByArgs(args);
List<SystemLocalStorageExportRowVo> rowVos =
KitBeanUtil.copyToList(systemLocalStorageTbs, SystemLocalStorageExportRowVo.class);
KitExcelExporter.exportSimple(response, "文件上传记录数据", SystemLocalStorageExportRowVo.class, rowVos);
}
} }
@@ -16,7 +16,6 @@
package cn.odboy.system.service; package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
@@ -37,6 +36,10 @@ import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@@ -46,435 +49,428 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; 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;
@Service @Service
public class SystemMenuService { public class SystemMenuService {
@Autowired
private SystemMenuMapper systemMenuMapper;
@Autowired
private SystemRoleMenuService systemRoleMenuService;
@Autowired
private SystemUserRoleService systemUserRoleService;
@Autowired /**
private SystemMenuMapper systemMenuMapper; * 创建
@Autowired *
private SystemRoleMenuService systemRoleMenuService; * @param args /
@Autowired */
private SystemUserRoleService systemUserRoleService; @Transactional(rollbackFor = Exception.class)
public void saveMenu(SystemMenuTb args) {
/** if (this.getMenuByTitle(args.getTitle()) != null) {
* 创建 throw new BadRequestException("菜单标题已存在");
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void saveMenu(SystemMenuTb args) {
if (this.getMenuByTitle(args.getTitle()) != null) {
throw new BadRequestException("菜单标题已存在");
}
if (StrUtil.isNotBlank(args.getComponentName())) {
if (this.getMenuByComponentName(args.getComponentName()) != null) {
throw new BadRequestException("菜单组件名称已存在");
}
}
if (Long.valueOf(0L).equals(args.getPid())) {
args.setPid(null);
}
if (args.getIFrame()) {
if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) ||
args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
}
}
systemMenuMapper.insert(args);
// 计算子节点数目
args.setSubCount(0);
// 更新父节点菜单数目
this.updateMenuSubCnt(args.getPid());
}
/**
* 编辑
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateMenuById(SystemMenuTb args) {
if (args.getId().equals(args.getPid())) {
throw new BadRequestException("上级不能为自己");
}
SystemMenuTb menu = systemMenuMapper.selectById(args.getId());
if (args.getIFrame()) {
if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) ||
args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
}
}
SystemMenuTb menu1 = this.getMenuByTitle(args.getTitle());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单标题已存在");
}
if (args.getPid().equals(0L)) {
args.setPid(null);
}
// 记录的父节点ID
Long oldPid = menu.getPid();
Long newPid = args.getPid();
if (StrUtil.isNotBlank(args.getComponentName())) {
menu1 = this.getMenuByComponentName(args.getComponentName());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单组件名称已存在");
}
}
menu.setTitle(args.getTitle());
menu.setComponent(args.getComponent());
menu.setPath(args.getPath());
menu.setIcon(args.getIcon());
menu.setIFrame(args.getIFrame());
menu.setPid(args.getPid());
menu.setMenuSort(args.getMenuSort());
menu.setCache(args.getCache());
menu.setHidden(args.getHidden());
menu.setComponentName(args.getComponentName());
menu.setPermission(args.getPermission());
menu.setType(args.getType());
// auto fill
menu.setUpdateBy(null);
menu.setUpdateTime(null);
systemMenuMapper.insertOrUpdate(menu);
// 计算父级菜单节点数目
this.updateMenuSubCnt(oldPid);
this.updateMenuSubCnt(newPid);
}
/**
* 删除
*/
@Transactional(rollbackFor = Exception.class)
public void deleteMenuByIds(Set<Long> ids) {
Set<SystemMenuVo> menuSet = new HashSet<>();
for (Long id : ids) {
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
}
List<Long> menuIds =
menuSet.stream().map(SystemMenuVo::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(menuIds)) {
systemRoleMenuService.deleteRoleMenuByMenuIds(menuIds);
systemMenuMapper.deleteByIds(menuIds);
}
for (SystemMenuVo menu : menuSet) {
this.updateMenuSubCnt(menu.getPid());
}
}
private SystemMenuVo getMenuVoById(Long id) {
return KitBeanUtil.copyToClass(systemMenuMapper.selectById(id), SystemMenuVo.class);
}
@Transactional(rollbackFor = Exception.class)
public void updateMenuSubCnt(Long menuId) {
if (menuId != null) {
long count = this.countMenuByPid(menuId);
LambdaUpdateWrapper<SystemMenuTb> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(SystemMenuTb::getId, menuId);
wrapper.set(SystemMenuTb::getSubCount, count);
systemMenuMapper.update(wrapper);
}
}
/**
* 查询全部数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemMenuTb> queryAllMenu(SystemQueryMenuArgs args, Boolean isQuery) throws Exception {
if (Boolean.TRUE.equals(isQuery)) {
args.setPidIsNull(true);
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
for (Field field : fields) {
//设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if ("pidIsNull".equals(field.getName())) {
continue;
} }
// 如果有查询条件, 则不指定pidIsNull if (StrUtil.isNotBlank(args.getComponentName())) {
if (ObjectUtil.isNotNull(val)) { if (this.getMenuByComponentName(args.getComponentName()) != null) {
args.setPidIsNull(null); throw new BadRequestException("菜单组件名称已存在");
break; }
} }
} if (Long.valueOf(0L).equals(args.getPid())) {
} args.setPid(null);
return this.queryMenuByArgs(args);
}
/**
* 根据当前用户获取菜单
*
* @param currentUserId /
* @return /
*/
public List<SystemMenuVo> listMenuByUserId(Long currentUserId) {
List<SystemRoleVo> roles = systemUserRoleService.queryRoleByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(SystemRoleVo::getId).collect(Collectors.toSet());
return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds));
}
/**
* 获取所有子节点, 包含自身ID
*
* @param menuList /
* @param menuSet /
* @return /
*/
public Set<SystemMenuVo> queryChildMenuByArgs(List<SystemMenuVo> menuList, Set<SystemMenuVo> menuSet) {
for (SystemMenuVo menu : menuList) {
menuSet.add(menu);
List<SystemMenuVo> menus = this.listMenuByPid(menu.getId());
if (CollUtil.isNotEmpty(menus)) {
queryChildMenuByArgs(menus, menuSet);
}
}
return menuSet;
}
/**
* 懒加载菜单数据
*
* @param pid /
* @return /
*/
public List<SystemMenuVo> listMenuByPid(Long pid) {
List<SystemMenuVo> menus;
if (pid != null && !pid.equals(0L)) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getPid, pid);
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
} else {
menus = this.listRootMenu();
}
return menus;
}
/**
* 根据ID获取同级与上级数据
*
* @param menu /
* @param menus /
* @return /
*/
public List<SystemMenuVo> querySuperiorMenuByArgs(SystemMenuVo menu, List<SystemMenuVo> menus) {
if (menu.getPid() == null) {
menus.addAll(this.listRootMenu());
return menus;
}
menus.addAll(this.listMenuByPid(menu.getPid()));
return querySuperiorMenuByArgs(this.getMenuVoById(menu.getPid()), menus);
}
/**
* 构建菜单树
*
* @param menus 原始数据
* @return /
*/
public List<SystemMenuVo> buildMenuTree(List<SystemMenuVo> menus) {
List<SystemMenuVo> trees = new ArrayList<>();
Set<Long> ids = new HashSet<>();
for (SystemMenuVo menu : menus) {
if (menu.getPid() == null) {
trees.add(menu);
}
for (SystemMenuVo it : menus) {
if (menu.getId().equals(it.getPid())) {
if (menu.getChildren() == null) {
menu.setChildren(new ArrayList<>());
}
menu.getChildren().add(it);
ids.add(it.getId());
} }
} if (args.getIFrame()) {
if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) || args.getPath()
.toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
}
}
systemMenuMapper.insert(args);
// 计算子节点数目
args.setSubCount(0);
// 更新父节点菜单数目
this.updateMenuSubCnt(args.getPid());
} }
if (CollUtil.isNotEmpty(trees)) {
trees = menus.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
}
return trees;
}
/** /**
* 构建菜单树 * 编辑
* *
* @param menus / * @param args /
* @return / */
*/ @Transactional(rollbackFor = Exception.class)
public List<SystemMenuRouterVo> buildMenuVo(List<SystemMenuVo> menus) { public void updateMenuById(SystemMenuTb args) {
List<SystemMenuRouterVo> list = new LinkedList<>(); if (args.getId().equals(args.getPid())) {
for (SystemMenuVo menu : menus) { throw new BadRequestException("上级不能为自己");
if (menu != null) { }
List<SystemMenuVo> menuList = menu.getChildren(); SystemMenuTb menu = systemMenuMapper.selectById(args.getId());
SystemMenuRouterVo menuVo = new SystemMenuRouterVo(); if (args.getIFrame()) {
menuVo.setName( if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) || args.getPath()
ObjectUtil.isNotEmpty(menu.getComponentName()) ? menu.getComponentName() : menu.getTitle()); .toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
// 一级目录需要加斜杠, 不然会报警告 throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
menuVo.setPath(menu.getPid() == null ? "/" + menu.getPath() : menu.getPath()); }
menuVo.setHidden(menu.getHidden()); }
// 如果不是外链 SystemMenuTb menu1 = this.getMenuByTitle(args.getTitle());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单标题已存在");
}
if (args.getPid().equals(0L)) {
args.setPid(null);
}
// 记录的父节点ID
Long oldPid = menu.getPid();
Long newPid = args.getPid();
if (StrUtil.isNotBlank(args.getComponentName())) {
menu1 = this.getMenuByComponentName(args.getComponentName());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单组件名称已存在");
}
}
menu.setTitle(args.getTitle());
menu.setComponent(args.getComponent());
menu.setPath(args.getPath());
menu.setIcon(args.getIcon());
menu.setIFrame(args.getIFrame());
menu.setPid(args.getPid());
menu.setMenuSort(args.getMenuSort());
menu.setCache(args.getCache());
menu.setHidden(args.getHidden());
menu.setComponentName(args.getComponentName());
menu.setPermission(args.getPermission());
menu.setType(args.getType());
// auto fill
menu.setUpdateBy(null);
menu.setUpdateTime(null);
systemMenuMapper.insertOrUpdate(menu);
// 计算父级菜单节点数目
this.updateMenuSubCnt(oldPid);
this.updateMenuSubCnt(newPid);
}
/**
* 删除
*/
@Transactional(rollbackFor = Exception.class)
public void deleteMenuByIds(Set<Long> ids) {
Set<SystemMenuVo> menuSet = new HashSet<>();
for (Long id : ids) {
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
}
List<Long> menuIds =
menuSet.stream().map(SystemMenuVo::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(menuIds)) {
systemRoleMenuService.deleteRoleMenuByMenuIds(menuIds);
systemMenuMapper.deleteByIds(menuIds);
}
for (SystemMenuVo menu : menuSet) {
this.updateMenuSubCnt(menu.getPid());
}
}
private SystemMenuVo getMenuVoById(Long id) {
return KitBeanUtil.copyToClass(systemMenuMapper.selectById(id), SystemMenuVo.class);
}
@Transactional(rollbackFor = Exception.class)
public void updateMenuSubCnt(Long menuId) {
if (menuId != null) {
long count = this.countMenuByPid(menuId);
LambdaUpdateWrapper<SystemMenuTb> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(SystemMenuTb::getId, menuId);
wrapper.set(SystemMenuTb::getSubCount, count);
systemMenuMapper.update(wrapper);
}
}
/**
* 查询全部数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemMenuTb> queryAllMenu(SystemQueryMenuArgs args, Boolean isQuery) throws Exception {
if (Boolean.TRUE.equals(isQuery)) {
args.setPidIsNull(true);
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
for (Field field : fields) {
//设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if ("pidIsNull".equals(field.getName())) {
continue;
}
// 如果有查询条件, 则不指定pidIsNull
if (ObjectUtil.isNotNull(val)) {
args.setPidIsNull(null);
break;
}
}
}
return this.queryMenuByArgs(args);
}
/**
* 根据当前用户获取菜单
*
* @param currentUserId /
* @return /
*/
public List<SystemMenuVo> listMenuByUserId(Long currentUserId) {
List<SystemRoleVo> roles = systemUserRoleService.queryRoleVoByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(SystemRoleVo::getId).collect(Collectors.toSet());
return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds));
}
/**
* 获取所有子节点, 包含自身ID
*
* @param menuList /
* @param menuSet /
* @return /
*/
public Set<SystemMenuVo> queryChildMenuByArgs(List<SystemMenuVo> menuList, Set<SystemMenuVo> menuSet) {
for (SystemMenuVo menu : menuList) {
menuSet.add(menu);
List<SystemMenuVo> menus = this.listMenuByPid(menu.getId());
if (CollUtil.isNotEmpty(menus)) {
queryChildMenuByArgs(menus, menuSet);
}
}
return menuSet;
}
/**
* 懒加载菜单数据
*
* @param pid /
* @return /
*/
public List<SystemMenuVo> listMenuByPid(Long pid) {
List<SystemMenuVo> menus;
if (pid != null && !pid.equals(0L)) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getPid, pid);
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
} else {
menus = this.listRootMenu();
}
return menus;
}
/**
* 根据ID获取同级与上级数据
*
* @param menu /
* @param menus /
* @return /
*/
public List<SystemMenuVo> querySuperiorMenuByArgs(SystemMenuVo menu, List<SystemMenuVo> menus) {
if (menu.getPid() == null) {
menus.addAll(this.listRootMenu());
return menus;
}
menus.addAll(this.listMenuByPid(menu.getPid()));
return querySuperiorMenuByArgs(this.getMenuVoById(menu.getPid()), menus);
}
/**
* 构建菜单树
*
* @param menus 原始数据
* @return /
*/
public List<SystemMenuVo> buildMenuTree(List<SystemMenuVo> menus) {
List<SystemMenuVo> trees = new ArrayList<>();
Set<Long> ids = new HashSet<>();
for (SystemMenuVo menu : menus) {
if (menu.getPid() == null) {
trees.add(menu);
}
for (SystemMenuVo it : menus) {
if (menu.getId().equals(it.getPid())) {
if (menu.getChildren() == null) {
menu.setChildren(new ArrayList<>());
}
menu.getChildren().add(it);
ids.add(it.getId());
}
}
}
if (CollUtil.isNotEmpty(trees)) {
trees = menus.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
}
return trees;
}
/**
* 构建菜单树
*
* @param menus /
* @return /
*/
public List<SystemMenuRouterVo> buildMenuVo(List<SystemMenuVo> menus) {
List<SystemMenuRouterVo> list = new LinkedList<>();
for (SystemMenuVo menu : menus) {
if (menu != null) {
List<SystemMenuVo> menuList = menu.getChildren();
SystemMenuRouterVo menuVo = new SystemMenuRouterVo();
menuVo.setName(
ObjectUtil.isNotEmpty(menu.getComponentName()) ? menu.getComponentName() : menu.getTitle());
// 一级目录需要加斜杠, 不然会报警告
menuVo.setPath(menu.getPid() == null ? "/" + menu.getPath() : menu.getPath());
menuVo.setHidden(menu.getHidden());
// 如果不是外链
if (!menu.getIFrame()) {
if (menu.getPid() == null) {
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "Layout" : menu.getComponent());
// 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单
} else if (menu.getType() == 0) {
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "ParentView" : menu.getComponent());
} else if (StrUtil.isNotBlank(menu.getComponent())) {
menuVo.setComponent(menu.getComponent());
}
}
menuVo.setMeta(new SystemMenuMetaVo(menu.getTitle(), menu.getIcon(), !menu.getCache()));
if (CollUtil.isNotEmpty(menuList)) {
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenuVo(menuList));
// 处理是一级菜单并且没有子菜单的情况
} else if (menu.getPid() == null) {
SystemMenuRouterVo menuVo1 = getMenuVo(menu, menuVo);
menuVo.setName(null);
menuVo.setMeta(null);
menuVo.setComponent("Layout");
List<SystemMenuRouterVo> list1 = new ArrayList<>();
list1.add(menuVo1);
menuVo.setChildren(list1);
}
list.add(menuVo);
}
}
return list;
}
/**
* 获取 MenuResponse
*
* @param menu /
* @param menuVo /
* @return /
*/
private SystemMenuRouterVo getMenuVo(SystemMenuVo menu, SystemMenuRouterVo menuVo) {
SystemMenuRouterVo menuVo1 = new SystemMenuRouterVo();
menuVo1.setMeta(menuVo.getMeta());
// 非外链
if (!menu.getIFrame()) { if (!menu.getIFrame()) {
if (menu.getPid() == null) { menuVo1.setPath("index");
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "Layout" : menu.getComponent()); menuVo1.setName(menuVo.getName());
// 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单 menuVo1.setComponent(menuVo.getComponent());
} else if (menu.getType() == 0) { } else {
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "ParentView" : menu.getComponent()); menuVo1.setPath(menu.getPath());
} else if (StrUtil.isNotBlank(menu.getComponent())) {
menuVo.setComponent(menu.getComponent());
}
} }
menuVo.setMeta(new SystemMenuMetaVo(menu.getTitle(), menu.getIcon(), !menu.getCache())); return menuVo1;
if (CollectionUtil.isNotEmpty(menuList)) {
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenuVo(menuList));
// 处理是一级菜单并且没有子菜单的情况
} else if (menu.getPid() == null) {
SystemMenuRouterVo menuVo1 = getMenuVo(menu, menuVo);
menuVo.setName(null);
menuVo.setMeta(null);
menuVo.setComponent("Layout");
List<SystemMenuRouterVo> list1 = new ArrayList<>();
list1.add(menuVo1);
menuVo.setChildren(list1);
}
list.add(menuVo);
}
} }
return list;
}
/** public List<SystemMenuVo> listMenuByIds(List<Long> ids) {
* 获取 MenuResponse return KitBeanUtil.copyToList(systemMenuMapper.selectByIds(ids), SystemMenuVo.class);
*
* @param menu /
* @param menuVo /
* @return /
*/
private SystemMenuRouterVo getMenuVo(SystemMenuVo menu, SystemMenuRouterVo menuVo) {
SystemMenuRouterVo menuVo1 = new SystemMenuRouterVo();
menuVo1.setMeta(menuVo.getMeta());
// 非外链
if (!menu.getIFrame()) {
menuVo1.setPath("index");
menuVo1.setName(menuVo.getName());
menuVo1.setComponent(menuVo.getComponent());
} else {
menuVo1.setPath(menu.getPath());
} }
return menuVo1;
}
public List<SystemMenuVo> listMenuByIds(List<Long> ids) { private SystemMenuTb getMenuByComponentName(String componentName) {
return KitBeanUtil.copyToList(systemMenuMapper.selectByIds(ids), SystemMenuVo.class); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
} wrapper.eq(SystemMenuTb::getComponentName, componentName);
return systemMenuMapper.selectOne(wrapper);
}
private SystemMenuTb getMenuByComponentName(String componentName) { private SystemMenuTb getMenuByTitle(String title) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getComponentName, componentName); wrapper.eq(SystemMenuTb::getTitle, title);
return systemMenuMapper.selectOne(wrapper); return systemMenuMapper.selectOne(wrapper);
} }
private SystemMenuTb getMenuByTitle(String title) { private Long countMenuByPid(Long pid) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getTitle, title); wrapper.eq(SystemMenuTb::getPid, pid);
return systemMenuMapper.selectOne(wrapper); return systemMenuMapper.selectCount(wrapper);
} }
private Long countMenuByPid(Long pid) { private List<SystemMenuTb> queryMenuByArgs(SystemQueryMenuArgs args) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>(); KitValidUtil.notNull(args);
wrapper.eq(SystemMenuTb::getPid, pid); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
return systemMenuMapper.selectCount(wrapper); wrapper.isNull(args.getPidIsNull() != null, SystemMenuTb::getPid);
} wrapper.eq(args.getPid() != null, SystemMenuTb::getPid, args.getPid());
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemMenuTb::getTitle, args.getBlurry()).or()
private List<SystemMenuTb> queryMenuByArgs(SystemQueryMenuArgs args) {
KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(args.getPidIsNull() != null, SystemMenuTb::getPid);
wrapper.eq(args.getPid() != null, SystemMenuTb::getPid, args.getPid());
wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemMenuTb::getTitle, args.getBlurry()).or()
.like(SystemMenuTb::getComponentName, args.getBlurry()).or() .like(SystemMenuTb::getComponentName, args.getBlurry()).or()
.like(SystemMenuTb::getPermission, args.getBlurry())); .like(SystemMenuTb::getPermission, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemMenuTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemMenuTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
args.getCreateTime().get(1));
}
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return systemMenuMapper.selectList(wrapper);
}
private List<SystemMenuVo> listRootMenu() {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(SystemMenuTb::getPid);
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
}
public List<SystemMenuRouterVo> buildFrontMenus() {
List<SystemMenuVo> originMenus = this.listMenuByUserId(KitSecurityHelper.getCurrentUserId());
List<SystemMenuVo> targetMenus = this.buildMenuTree(originMenus);
return this.buildMenuVo(targetMenus);
}
public Set<Long> listChildMenuSetByMenuId(Long id) {
Set<SystemMenuVo> menuSet = new HashSet<>();
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
return menuSet.stream().map(SystemMenuVo::getId).collect(Collectors.toSet());
}
public List<SystemMenuVo> listMenuSuperior(List<Long> ids) {
Set<SystemMenuVo> menus;
List<SystemMenuVo> systemMenuTbs;
if (CollectionUtil.isNotEmpty(ids)) {
menus = new LinkedHashSet<>(this.listMenuByIds(ids));
for (SystemMenuVo menu : menus) {
List<SystemMenuVo> menuList = this.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuVo data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
} }
menus.addAll(menuList); wrapper.orderByAsc(SystemMenuTb::getMenuSort);
} return systemMenuMapper.selectList(wrapper);
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
List<SystemMenuVo> newMenuList = new ArrayList<>(menus);
systemMenuTbs = this.buildMenuTree(newMenuList);
} else {
systemMenuTbs = this.listMenuByPid(null);
} }
return systemMenuTbs;
}
public void exportMenuXlsx(HttpServletResponse response, SystemQueryMenuArgs args) throws Exception { private List<SystemMenuVo> listRootMenu() {
List<SystemMenuTb> systemMenuTbs = this.queryAllMenu(args, false); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
List<SystemMenuExportRowVo> rowVos = new ArrayList<>(); wrapper.isNull(SystemMenuTb::getPid);
for (SystemMenuTb dataObject : systemMenuTbs) { wrapper.orderByAsc(SystemMenuTb::getMenuSort);
SystemMenuExportRowVo rowVo = new SystemMenuExportRowVo(); return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
rowVo.setTitle(dataObject.getTitle()); }
rowVo.setType(dataObject.getType() == null ? "目录" : dataObject.getType() == 1 ? "菜单" : "按钮");
rowVo.setPermission(dataObject.getPermission()); public List<SystemMenuRouterVo> buildFrontMenus() {
rowVo.setIFrame(dataObject.getIFrame() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR); List<SystemMenuVo> originMenus = this.listMenuByUserId(KitSecurityHelper.getCurrentUserId());
rowVo.setHidden(dataObject.getHidden() ? SystemYesOrNoChConst.NO_STR : SystemYesOrNoChConst.YES_STR); List<SystemMenuVo> targetMenus = this.buildMenuTree(originMenus);
rowVo.setCache(dataObject.getCache() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR); return this.buildMenuVo(targetMenus);
rowVo.setCreateTime(dataObject.getCreateTime()); }
rowVos.add(rowVo);
public Set<Long> listChildMenuSetByMenuId(Long id) {
Set<SystemMenuVo> menuSet = new HashSet<>();
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
return menuSet.stream().map(SystemMenuVo::getId).collect(Collectors.toSet());
}
public List<SystemMenuVo> listMenuSuperior(List<Long> ids) {
Set<SystemMenuVo> menus;
List<SystemMenuVo> systemMenuTbs;
if (CollUtil.isNotEmpty(ids)) {
menus = new LinkedHashSet<>(this.listMenuByIds(ids));
for (SystemMenuVo menu : menus) {
List<SystemMenuVo> menuList = this.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuVo data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
menus.addAll(menuList);
}
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
List<SystemMenuVo> newMenuList = new ArrayList<>(menus);
systemMenuTbs = this.buildMenuTree(newMenuList);
} else {
systemMenuTbs = this.listMenuByPid(null);
}
return systemMenuTbs;
}
public void exportMenuXlsx(HttpServletResponse response, SystemQueryMenuArgs args) throws Exception {
List<SystemMenuTb> systemMenuTbs = this.queryAllMenu(args, false);
List<SystemMenuExportRowVo> rowVos = new ArrayList<>();
for (SystemMenuTb dataObject : systemMenuTbs) {
SystemMenuExportRowVo rowVo = new SystemMenuExportRowVo();
rowVo.setTitle(dataObject.getTitle());
rowVo.setType(dataObject.getType() == null ? "目录" : dataObject.getType() == 1 ? "菜单" : "按钮");
rowVo.setPermission(dataObject.getPermission());
rowVo.setIFrame(dataObject.getIFrame() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR);
rowVo.setHidden(dataObject.getHidden() ? SystemYesOrNoChConst.NO_STR : SystemYesOrNoChConst.YES_STR);
rowVo.setCache(dataObject.getCache() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "菜单数据", SystemMenuExportRowVo.class, rowVos);
} }
KitExcelExporter.exportSimple(response, "菜单数据", SystemMenuExportRowVo.class, rowVos);
}
} }
@@ -20,13 +20,6 @@ import cn.hutool.core.date.DateUtil;
import cn.odboy.constant.SystemConst; import cn.odboy.constant.SystemConst;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitIPUtil; import cn.odboy.util.KitIPUtil;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import oshi.SystemInfo; import oshi.SystemInfo;
@@ -39,177 +32,184 @@ import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem; import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil; import oshi.util.FormatUtil;
import oshi.util.Util; import oshi.util.Util;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
@Service @Service
public class SystemMonitorService { public class SystemMonitorService {
private final DecimalFormat df = new DecimalFormat("0.00"); private final DecimalFormat df = new DecimalFormat("0.00");
/** /**
* 查询服务器监控信息 * 查询服务器监控信息 -> TestPassed
* *
* @return Map<String, Object> * @return Map<String, Object>
*/ */
public Map<String, Object> getServerMonitorInfo() { public Map<String, Object> getServerMonitorInfo() {
Map<String, Object> resultMap = new LinkedHashMap<>(8); Map<String, Object> resultMap = new LinkedHashMap<>(8);
try { try {
SystemInfo si = new SystemInfo(); SystemInfo si = new SystemInfo();
OperatingSystem os = si.getOperatingSystem(); OperatingSystem os = si.getOperatingSystem();
HardwareAbstractionLayer hal = si.getHardware(); HardwareAbstractionLayer hal = si.getHardware();
// 系统信息 // 系统信息
resultMap.put("sys", getSystemInfo(os)); resultMap.put("sys", getSystemInfo(os));
// cpu 信息 // cpu 信息
resultMap.put("cpu", getCpuInfo(hal.getProcessor())); resultMap.put("cpu", getCpuInfo(hal.getProcessor()));
// 内存信息 // 内存信息
resultMap.put("memory", getMemoryInfo(hal.getMemory())); resultMap.put("memory", getMemoryInfo(hal.getMemory()));
// 交换区信息 // 交换区信息
resultMap.put("swap", getSwapInfo(hal.getMemory())); resultMap.put("swap", getSwapInfo(hal.getMemory()));
// 磁盘 // 磁盘
resultMap.put("disk", getDiskInfo(os)); resultMap.put("disk", getDiskInfo(os));
resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss")); resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
}
return resultMap;
} }
return resultMap;
}
/** /**
* 获取磁盘信息 * 获取磁盘信息
* *
* @return / * @return /
*/ */
private Map<String, Object> getDiskInfo(OperatingSystem os) { private Map<String, Object> getDiskInfo(OperatingSystem os) {
Map<String, Object> diskInfo = new LinkedHashMap<>(); Map<String, Object> diskInfo = new LinkedHashMap<>();
FileSystem fileSystem = os.getFileSystem(); FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores(); List<OSFileStore> fsArray = fileSystem.getFileStores();
String osName = System.getProperty("os.name"); String osName = System.getProperty("os.name");
long available = 0, total = 0; long available = 0, total = 0;
for (OSFileStore fs : fsArray) { for (OSFileStore fs : fsArray) {
// windows 需要将所有磁盘分区累加, linux 和 mac 直接累加会出现磁盘重复的问题, 待修复 // windows 需要将所有磁盘分区累加, linux 和 mac 直接累加会出现磁盘重复的问题, 待修复
if (osName.toLowerCase().startsWith(SystemConst.WIN)) { if (osName.toLowerCase().startsWith(SystemConst.WIN)) {
available += fs.getUsableSpace(); available += fs.getUsableSpace();
total += fs.getTotalSpace(); total += fs.getTotalSpace();
} else { } else {
available = fs.getUsableSpace(); available = fs.getUsableSpace();
total = fs.getTotalSpace(); total = fs.getTotalSpace();
break; break;
} }
}
long used = total - available;
diskInfo.put("total", total > 0 ? KitFileUtil.getSize(total) : "?");
diskInfo.put("available", KitFileUtil.getSize(available));
diskInfo.put("used", KitFileUtil.getSize(used));
if (total != 0) {
diskInfo.put("usageRate", df.format(used / (double)total * 100));
} else {
diskInfo.put("usageRate", 0);
}
return diskInfo;
} }
long used = total - available;
diskInfo.put("total", total > 0 ? KitFileUtil.getSize(total) : "?"); /**
diskInfo.put("available", KitFileUtil.getSize(available)); * 获取交换区信息
diskInfo.put("used", KitFileUtil.getSize(used)); *
if (total != 0) { * @param memory /
diskInfo.put("usageRate", df.format(used / (double) total * 100)); * @return /
} else { */
diskInfo.put("usageRate", 0); private Map<String, Object> getSwapInfo(GlobalMemory memory) {
Map<String, Object> swapInfo = new LinkedHashMap<>();
VirtualMemory virtualMemory = memory.getVirtualMemory();
long total = virtualMemory.getSwapTotal();
long used = virtualMemory.getSwapUsed();
swapInfo.put("total", FormatUtil.formatBytes(total));
swapInfo.put("used", FormatUtil.formatBytes(used));
swapInfo.put("available", FormatUtil.formatBytes(total - used));
if (used == 0) {
swapInfo.put("usageRate", 0);
} else {
swapInfo.put("usageRate", df.format(used / (double)total * 100));
}
return swapInfo;
} }
return diskInfo;
}
/** /**
* 获取交换区信息 * 获取内存信息
* *
* @param memory / * @param memory /
* @return / * @return /
*/ */
private Map<String, Object> getSwapInfo(GlobalMemory memory) { private Map<String, Object> getMemoryInfo(GlobalMemory memory) {
Map<String, Object> swapInfo = new LinkedHashMap<>(); Map<String, Object> memoryInfo = new LinkedHashMap<>();
VirtualMemory virtualMemory = memory.getVirtualMemory(); memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal()));
long total = virtualMemory.getSwapTotal(); memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable()));
long used = virtualMemory.getSwapUsed(); memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable()));
swapInfo.put("total", FormatUtil.formatBytes(total)); memoryInfo.put("usageRate",
swapInfo.put("used", FormatUtil.formatBytes(used)); df.format((memory.getTotal() - memory.getAvailable()) / (double)memory.getTotal() * 100));
swapInfo.put("available", FormatUtil.formatBytes(total - used)); return memoryInfo;
if (used == 0) {
swapInfo.put("usageRate", 0);
} else {
swapInfo.put("usageRate", df.format(used / (double) total * 100));
} }
return swapInfo;
}
/** /**
* 获取内存信息 * 获取Cpu相关信息
* *
* @param memory / * @param processor /
* @return / * @return /
*/ */
private Map<String, Object> getMemoryInfo(GlobalMemory memory) { private Map<String, Object> getCpuInfo(CentralProcessor processor) {
Map<String, Object> memoryInfo = new LinkedHashMap<>(); Map<String, Object> cpuInfo = new LinkedHashMap<>();
memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal())); cpuInfo.put("name", processor.getProcessorIdentifier().getName());
memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable())); cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU");
memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable())); cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心");
memoryInfo.put("usageRate", cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount());
df.format((memory.getTotal() - memory.getAvailable()) / (double) memory.getTotal() * 100)); cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU");
return memoryInfo; // CPU信息
} long[] prevTicks = processor.getSystemCpuLoadTicks();
// 默认等待300毫秒...
/** long time = 300;
* 获取Cpu相关信息 Util.sleep(time);
* long[] ticks = processor.getSystemCpuLoadTicks();
* @param processor / long minCpuLoadTick = 1000;
* @return / while (Arrays.toString(prevTicks).equals(Arrays.toString(ticks)) && time < minCpuLoadTick) {
*/ time += 25;
private Map<String, Object> getCpuInfo(CentralProcessor processor) { Util.sleep(25);
Map<String, Object> cpuInfo = new LinkedHashMap<>(); ticks = processor.getSystemCpuLoadTicks();
cpuInfo.put("name", processor.getProcessorIdentifier().getName()); }
cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU"); long user =
cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心"); ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount()); long nice =
cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU"); ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
// CPU信息 long sys =
long[] prevTicks = processor.getSystemCpuLoadTicks(); ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
// 默认等待300毫秒... long idle =
long time = 300; ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
Util.sleep(time); long ioWait =
long[] ticks = processor.getSystemCpuLoadTicks(); ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
long minCpuLoadTick = 1000; long irq =
while (Arrays.toString(prevTicks).equals(Arrays.toString(ticks)) && time < minCpuLoadTick) { ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
time += 25; long softIrq =
Util.sleep(25); ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
ticks = processor.getSystemCpuLoadTicks(); long steal =
ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
long totalCpu = user + nice + sys + idle + ioWait + irq + softIrq + steal;
cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu));
cpuInfo.put("idle", df.format(100d * idle / totalCpu));
return cpuInfo;
} }
long user =
ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
long nice =
ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
long sys =
ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
long idle =
ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
long ioWait =
ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
long irq =
ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
long softIrq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] -
prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
long steal =
ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
long totalCpu = user + nice + sys + idle + ioWait + irq + softIrq + steal;
cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu));
cpuInfo.put("idle", df.format(100d * idle / totalCpu));
return cpuInfo;
}
/** /**
* 获取系统相关信息,系统、运行天数、系统IP * 获取系统相关信息,系统、运行天数、系统IP
* *
* @param os / * @param os /
* @return / * @return /
*/ */
private Map<String, Object> getSystemInfo(OperatingSystem os) { private Map<String, Object> getSystemInfo(OperatingSystem os) {
Map<String, Object> systemInfo = new LinkedHashMap<>(); Map<String, Object> systemInfo = new LinkedHashMap<>();
// jvm 运行时间 // jvm 运行时间
long time = ManagementFactory.getRuntimeMXBean().getStartTime(); long time = ManagementFactory.getRuntimeMXBean().getStartTime();
Date date = new Date(time); Date date = new Date(time);
// 计算项目运行时间 // 计算项目运行时间
String formatBetween = DateUtil.formatBetween(date, new Date(), Level.HOUR); String formatBetween = DateUtil.formatBetween(date, new Date(), Level.HOUR);
// 系统信息 // 系统信息
systemInfo.put("os", os.toString()); systemInfo.put("os", os.toString());
systemInfo.put("day", formatBetween); systemInfo.put("day", formatBetween);
systemInfo.put("ip", KitIPUtil.getLocalIp()); systemInfo.put("ip", KitIPUtil.getLocalIp());
return systemInfo; return systemInfo;
} }
} }
@@ -14,13 +14,16 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemOperationLogService { public class SystemOperationLogService {
@Autowired @Autowired
private SystemOperationLogMapper systemOperationLogMapper; private SystemOperationLogMapper systemOperationLogMapper;
public IPage<SystemOperationLogTb> searchUserLog(KitPageArgs<SystemQueryOperationLogArgs> pageArgs) { /**
LambdaQueryWrapper<SystemOperationLogTb> wrapper = new LambdaQueryWrapper<>(); * 查询用户操作日志
wrapper.eq(SystemOperationLogTb::getUsername, KitSecurityHelper.getCurrentUsername()); */
Page<SystemOperationLogTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); public IPage<SystemOperationLogTb> searchUserLog(KitPageArgs<SystemQueryOperationLogArgs> pageArgs) {
return systemOperationLogMapper.selectPage(page, wrapper); LambdaQueryWrapper<SystemOperationLogTb> wrapper = new LambdaQueryWrapper<>();
} wrapper.eq(SystemOperationLogTb::getUsername, KitSecurityHelper.getCurrentUsername());
Page<SystemOperationLogTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return systemOperationLogMapper.selectPage(page, wrapper);
}
} }
@@ -21,9 +21,9 @@ import cn.odboy.system.dal.model.request.SystemQueryStorageArgs;
import cn.odboy.system.dal.model.response.SystemOssStorageVo; import cn.odboy.system.dal.model.response.SystemOssStorageVo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
/** /**
* <p> * <p>
@@ -35,13 +35,13 @@ import org.springframework.web.multipart.MultipartFile;
*/ */
public interface SystemOssStorageService extends IService<SystemOssStorageTb> { public interface SystemOssStorageService extends IService<SystemOssStorageTb> {
KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args, Page<SystemOssStorageTb> page); KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args, Page<SystemOssStorageTb> page);
List<SystemOssStorageVo> queryOssStorage(SystemQueryStorageArgs args); List<SystemOssStorageVo> queryOssStorage(SystemQueryStorageArgs args);
String uploadFile(MultipartFile file); String uploadFile(MultipartFile file);
void deleteFileByIds(Long[] ids); void deleteFileByIds(Long[] ids);
void exportOssStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args); void exportOssStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args);
} }
@@ -38,279 +38,283 @@ import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.quartz.CronExpression; import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemQuartzJobService { public class SystemQuartzJobService {
@Autowired @Autowired
private SystemQuartzJobMapper systemQuartzJobMapper; private SystemQuartzJobMapper systemQuartzJobMapper;
@Autowired @Autowired
private SystemQuartzLogMapper systemQuartzLogMapper; private SystemQuartzLogMapper systemQuartzLogMapper;
@Autowired @Autowired
private QuartzManage quartzManage; private QuartzManage quartzManage;
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
/** /**
* 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义 * 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
* *
* @param beanName Bean名称 * @param beanName Bean名称
*/ */
private void checkBean(String beanName) { private void checkBean(String beanName) {
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类 // 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。 // 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) { if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) {
throw new BadRequestException("非法的 Bean,请重新输入!"); throw new BadRequestException("非法的 Bean,请重新输入!");
}
} }
}
/** /**
* 创建 * 创建
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void createJob(SystemQuartzJobVo args) { public void createJob(SystemQuartzJobVo args) {
if (args.getId() != null) { if (args.getId() != null) {
throw new BadRequestException("无效参数id"); throw new BadRequestException("无效参数id");
}
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误");
}
SystemQuartzJobTb record = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insert(record);
quartzManage.addJob(args);
} }
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName()); /**
if (!CronExpression.isValidExpression(args.getCronExpression())) { * 修改任务并重新调度
throw new BadRequestException("cron表达式格式错误"); *
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误");
}
if (StrUtil.isNotBlank(args.getSubTask())) {
List<String> tasks = Arrays.asList(args.getSubTask().split("[,,]"));
if (tasks.contains(args.getId().toString())) {
throw new BadRequestException("子任务中不能添加当前任务ID");
}
}
SystemQuartzJobTb jobTb = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(jobTb);
SystemQuartzJobVo jobVo = KitBeanUtil.copyToClass(args, SystemQuartzJobVo.class);
quartzManage.updateJobCron(jobVo);
} }
SystemQuartzJobTb record = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insert(record);
quartzManage.addJob(args);
}
/** /**
* 修改任务并重新调度 * 更改定时任务状态
* *
* @param args / * @param quartzJob /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) { public void switchQuartzJobStatus(SystemQuartzJobVo quartzJob) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义 // 置换暂停状态
checkBean(args.getBeanName()); if (quartzJob.getIsPause()) {
if (!CronExpression.isValidExpression(args.getCronExpression())) { quartzManage.resumeJob(quartzJob);
throw new BadRequestException("cron表达式格式错误"); quartzJob.setIsPause(false);
} else {
quartzManage.pauseJob(quartzJob);
quartzJob.setIsPause(true);
}
SystemQuartzJobTb quartzJobTb = KitBeanUtil.copyToClass(quartzJob, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(quartzJobTb);
} }
if (StrUtil.isNotBlank(args.getSubTask())) {
List<String> tasks = Arrays.asList(args.getSubTask().split("[,,]")); /**
if (tasks.contains(args.getId().toString())) { * 立即执行定时任务
throw new BadRequestException("子任务中不能添加当前任务ID"); *
} * @param quartzJob /
*/
public void startQuartzJob(SystemQuartzJobVo quartzJob) {
quartzManage.runJobNow(quartzJob);
} }
SystemQuartzJobTb jobTb = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(jobTb);
SystemQuartzJobVo jobVo = KitBeanUtil.copyToClass(args, SystemQuartzJobVo.class);
quartzManage.updateJobCron(jobVo);
}
/** /**
* 更改定时任务状态 * 删除任务
* *
* @param quartzJob / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void switchQuartzJobStatus(SystemQuartzJobVo quartzJob) { public void deleteJobByIds(Set<Long> ids) {
// 置换暂停状态 for (Long id : ids) {
if (quartzJob.getIsPause()) { SystemQuartzJobTb quartzJob = systemQuartzJobMapper.selectById(id);
quartzManage.resumeJob(quartzJob); quartzManage.deleteJob(quartzJob);
quartzJob.setIsPause(false); systemQuartzJobMapper.deleteById(quartzJob);
} else { }
quartzManage.pauseJob(quartzJob);
quartzJob.setIsPause(true);
} }
SystemQuartzJobTb quartzJobTb = KitBeanUtil.copyToClass(quartzJob, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(quartzJobTb);
}
/** /**
* 立即执行定时任务 * 执行子任务
* *
* @param quartzJob / * @param tasks /
*/ * @throws InterruptedException /
public void startQuartzJob(SystemQuartzJobVo quartzJob) { */
quartzManage.runJobNow(quartzJob); @Transactional(rollbackFor = Exception.class)
} public void startSubQuartJob(String[] tasks) throws InterruptedException {
for (String id : tasks) {
/** if (StrUtil.isBlank(id)) {
* 删除任务 // 如果是手动清除子任务id, 会出现id为空字符串的问题
* continue;
* @param ids / }
*/ SystemQuartzJobVo quartzJob = systemQuartzJobMapper.selectVoById(id);
@Transactional(rollbackFor = Exception.class) if (quartzJob == null) {
public void deleteJobByIds(Set<Long> ids) { // 防止子任务不存在
for (Long id : ids) { continue;
SystemQuartzJobTb quartzJob = systemQuartzJobMapper.selectById(id); }
quartzManage.deleteJob(quartzJob); // 执行任务
systemQuartzJobMapper.deleteById(quartzJob); String uuid = IdUtil.simpleUUID();
quartzJob.setUuid(uuid);
// 执行任务
startQuartzJob(quartzJob);
// 获取执行状态, 如果执行失败则停止后面的子任务执行
Boolean result = redisHelper.get(uuid, Boolean.class);
while (result == null) {
// 休眠5秒, 再次获取子任务执行情况
Thread.sleep(5000);
result = redisHelper.get(uuid, Boolean.class);
}
if (!result) {
redisHelper.del(uuid);
break;
}
}
} }
}
/** /**
* 执行子任务 * 分页查询
* *
* @param tasks / * @param args 条件
* @throws InterruptedException / * @param page 分页参数
*/ * @return /
@Transactional(rollbackFor = Exception.class) */
public void startSubQuartJob(String[] tasks) throws InterruptedException { public KitPageResult<SystemQuartzJobTb> searchQuartzJobByArgs(SystemQueryQuartzJobArgs args,
for (String id : tasks) { Page<SystemQuartzJobTb> page) {
if (StrUtil.isBlank(id)) { LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
// 如果是手动清除子任务id, 会出现id为空字符串的问题 this.injectQuartzJobQueryParams(args, wrapper);
continue; return KitPageUtil.toPage(systemQuartzJobMapper.selectPage(page, wrapper));
}
SystemQuartzJobVo quartzJob = systemQuartzJobMapper.selectVoById(id);
if (quartzJob == null) {
// 防止子任务不存在
continue;
}
// 执行任务
String uuid = IdUtil.simpleUUID();
quartzJob.setUuid(uuid);
// 执行任务
startQuartzJob(quartzJob);
// 获取执行状态, 如果执行失败则停止后面的子任务执行
Boolean result = redisHelper.get(uuid, Boolean.class);
while (result == null) {
// 休眠5秒, 再次获取子任务执行情况
Thread.sleep(5000);
result = redisHelper.get(uuid, Boolean.class);
}
if (!result) {
redisHelper.del(uuid);
break;
}
} }
}
/** private void injectQuartzJobQueryParams(SystemQueryQuartzJobArgs args,
* 分页查询 LambdaQueryWrapper<SystemQuartzJobTb> wrapper) {
* KitValidUtil.notNull(args);
* @param args 条件 wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzJobTb::getJobName, args.getJobName());
* @param page 分页参数 if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
* @return / wrapper.between(SystemQuartzJobTb::getUpdateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
*/ }
public KitPageResult<SystemQuartzJobTb> searchQuartzJobByArgs(SystemQueryQuartzJobArgs args, Page<SystemQuartzJobTb> page) { wrapper.orderByDesc(SystemQuartzJobTb::getId);
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzJobQueryParams(args, wrapper);
return KitPageUtil.toPage(systemQuartzJobMapper.selectPage(page, wrapper));
}
private void injectQuartzJobQueryParams(SystemQueryQuartzJobArgs args, LambdaQueryWrapper<SystemQuartzJobTb> wrapper) {
KitValidUtil.notNull(args);
wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzJobTb::getJobName, args.getJobName());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemQuartzJobTb::getUpdateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
} }
wrapper.orderByDesc(SystemQuartzJobTb::getId);
}
private void injectQuartzLogQueryParams(SystemQueryQuartzJobArgs args, LambdaQueryWrapper<SystemQuartzLogTb> wrapper) { private void injectQuartzLogQueryParams(SystemQueryQuartzJobArgs args,
if (args != null) { LambdaQueryWrapper<SystemQuartzLogTb> wrapper) {
wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzLogTb::getJobName, args.getJobName()); if (args != null) {
wrapper.eq(args.getIsSuccess() != null, SystemQuartzLogTb::getIsSuccess, args.getIsSuccess()); wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzLogTb::getJobName, args.getJobName());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { wrapper.eq(args.getIsSuccess() != null, SystemQuartzLogTb::getIsSuccess, args.getIsSuccess());
wrapper.between(SystemQuartzLogTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
} wrapper.between(SystemQuartzLogTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
}
wrapper.orderByDesc(SystemQuartzLogTb::getId);
} }
wrapper.orderByDesc(SystemQuartzLogTb::getId);
}
/** /**
* 分页查询日志 * 分页查询日志
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @return / * @return /
*/ */
public KitPageResult<SystemQuartzLogTb> searchQuartzLogByArgs(SystemQueryQuartzJobArgs args, public KitPageResult<SystemQuartzLogTb> searchQuartzLogByArgs(SystemQueryQuartzJobArgs args,
Page<SystemQuartzLogTb> page) { Page<SystemQuartzLogTb> page) {
LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzLogQueryParams(args, wrapper); this.injectQuartzLogQueryParams(args, wrapper);
return KitPageUtil.toPage(systemQuartzLogMapper.selectPage(page, wrapper)); return KitPageUtil.toPage(systemQuartzLogMapper.selectPage(page, wrapper));
}
/**
* 查询全部
*
* @param args 条件
* @return /
*/
public List<SystemQuartzJobTb> queryQuartzJobByArgs(SystemQueryQuartzJobArgs args) {
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzJobQueryParams(args, wrapper);
return systemQuartzJobMapper.selectList(wrapper);
}
/**
* 查询全部
*
* @param args 条件
* @return /
*/
public List<SystemQuartzLogTb> queryQuartzLogByArgs(SystemQueryQuartzJobArgs args) {
LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzLogQueryParams(args, wrapper);
return systemQuartzLogMapper.selectList(wrapper);
}
public SystemQuartzJobVo getQuartzJobById(Long id) {
return KitBeanUtil.copyToClass(systemQuartzJobMapper.selectById(id), SystemQuartzJobVo.class);
}
public List<SystemQuartzJobVo> listEnableQuartzJob() {
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemQuartzJobTb::getIsPause, 0);
return KitBeanUtil.copyToList(systemQuartzJobMapper.selectList(wrapper), SystemQuartzJobVo.class);
}
public void exportQuartzJobXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) {
List<SystemQuartzJobTb> systemQuartzJobTbs = this.queryQuartzJobByArgs(args);
List<SystemQuartzJobExportRowVo> rowVos = new ArrayList<>();
for (SystemQuartzJobTb dataObject : systemQuartzJobTbs) {
SystemQuartzJobExportRowVo rowVo = new SystemQuartzJobExportRowVo();
rowVo.setJobName(dataObject.getJobName());
rowVo.setBeanName(dataObject.getBeanName());
rowVo.setMethodName(dataObject.getMethodName());
rowVo.setParams(dataObject.getParams());
rowVo.setCronExpression(dataObject.getCronExpression());
rowVo.setIsPause(dataObject.getIsPause() ? "暂停中" : "运行中");
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
} }
KitExcelExporter.exportSimple(response, "定时任务数据", SystemQuartzJobExportRowVo.class, rowVos);
}
public void exportQuartzLogXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) { /**
List<SystemQuartzLogTb> systemQuartzLogTbs = this.queryQuartzLogByArgs(args); * 查询全部
List<SystemQuartzLogExportRowVo> rowVos = new ArrayList<>(); *
for (SystemQuartzLogTb dataObject : systemQuartzLogTbs) { * @param args 条件
SystemQuartzLogExportRowVo rowVo = new SystemQuartzLogExportRowVo(); * @return /
rowVo.setJobName(dataObject.getJobName()); */
rowVo.setBeanName(dataObject.getBeanName()); public List<SystemQuartzJobTb> queryQuartzJobByArgs(SystemQueryQuartzJobArgs args) {
rowVo.setMethodName(dataObject.getMethodName()); LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
rowVo.setParams(dataObject.getParams()); this.injectQuartzJobQueryParams(args, wrapper);
rowVo.setCronExpression(dataObject.getCronExpression()); return systemQuartzJobMapper.selectList(wrapper);
rowVo.setExceptionDetail(dataObject.getExceptionDetail()); }
rowVo.setTime(dataObject.getTime());
rowVo.setStatus(dataObject.getIsSuccess() ? "成功" : "失败"); /**
rowVo.setCreateTime(dataObject.getCreateTime()); * 查询全部
rowVos.add(rowVo); *
* @param args 条件
* @return /
*/
public List<SystemQuartzLogTb> queryQuartzLogByArgs(SystemQueryQuartzJobArgs args) {
LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzLogQueryParams(args, wrapper);
return systemQuartzLogMapper.selectList(wrapper);
}
public SystemQuartzJobVo getQuartzJobById(Long id) {
return KitBeanUtil.copyToClass(systemQuartzJobMapper.selectById(id), SystemQuartzJobVo.class);
}
public List<SystemQuartzJobVo> listEnableQuartzJob() {
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemQuartzJobTb::getIsPause, 0);
return KitBeanUtil.copyToList(systemQuartzJobMapper.selectList(wrapper), SystemQuartzJobVo.class);
}
public void exportQuartzJobXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) {
List<SystemQuartzJobTb> systemQuartzJobTbs = this.queryQuartzJobByArgs(args);
List<SystemQuartzJobExportRowVo> rowVos = new ArrayList<>();
for (SystemQuartzJobTb dataObject : systemQuartzJobTbs) {
SystemQuartzJobExportRowVo rowVo = new SystemQuartzJobExportRowVo();
rowVo.setJobName(dataObject.getJobName());
rowVo.setBeanName(dataObject.getBeanName());
rowVo.setMethodName(dataObject.getMethodName());
rowVo.setParams(dataObject.getParams());
rowVo.setCronExpression(dataObject.getCronExpression());
rowVo.setIsPause(dataObject.getIsPause() ? "暂停中" : "运行中");
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "定时任务数据", SystemQuartzJobExportRowVo.class, rowVos);
}
public void exportQuartzLogXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) {
List<SystemQuartzLogTb> systemQuartzLogTbs = this.queryQuartzLogByArgs(args);
List<SystemQuartzLogExportRowVo> rowVos = new ArrayList<>();
for (SystemQuartzLogTb dataObject : systemQuartzLogTbs) {
SystemQuartzLogExportRowVo rowVo = new SystemQuartzLogExportRowVo();
rowVo.setJobName(dataObject.getJobName());
rowVo.setBeanName(dataObject.getBeanName());
rowVo.setMethodName(dataObject.getMethodName());
rowVo.setParams(dataObject.getParams());
rowVo.setCronExpression(dataObject.getCronExpression());
rowVo.setExceptionDetail(dataObject.getExceptionDetail());
rowVo.setTime(dataObject.getTime());
rowVo.setStatus(dataObject.getIsSuccess() ? "成功" : "失败");
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "定时任务日志数据", SystemQuartzLogExportRowVo.class, rowVos);
} }
KitExcelExporter.exportSimple(response, "定时任务日志数据", SystemQuartzLogExportRowVo.class, rowVos);
}
} }
@@ -21,75 +21,67 @@ import cn.odboy.system.dal.dataobject.SystemRoleDeptTb;
import cn.odboy.system.dal.mysql.SystemDeptMapper; import cn.odboy.system.dal.mysql.SystemDeptMapper;
import cn.odboy.system.dal.mysql.SystemRoleDeptMapper; import cn.odboy.system.dal.mysql.SystemRoleDeptMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemRoleDeptService { public class SystemRoleDeptService {
@Autowired @Autowired
private SystemRoleDeptMapper systemRoleDeptMapper; private SystemRoleDeptMapper systemRoleDeptMapper;
@Autowired @Autowired
private SystemDeptMapper systemDeptMapper; private SystemDeptMapper systemDeptMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteRoleDept(Set<Long> roleIds) { public void batchDeleteRoleDept(Set<Long> roleIds) {
if (CollUtil.isNotEmpty(roleIds)) { if (CollUtil.isNotEmpty(roleIds)) {
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getRoleId, roleIds); wrapper.in(SystemRoleDeptTb::getRoleId, roleIds);
systemRoleDeptMapper.delete(wrapper); systemRoleDeptMapper.delete(wrapper);
} }
}
@Transactional(rollbackFor = Exception.class)
public void batchInsertRoleDept(Set<SystemDeptTb> depts, Long id) {
if (CollUtil.isNotEmpty(depts)) {
List<SystemRoleDeptTb> records = new ArrayList<>();
for (SystemDeptTb dept : depts) {
SystemRoleDeptTb record = new SystemRoleDeptTb();
record.setRoleId(id);
record.setDeptId(dept.getId());
records.add(record);
}
systemRoleDeptMapper.insert(records);
}
}
/**
* 根据角色id查询
*
* @param roleId /
* @return /
*/
public List<SystemDeptTb> listDeptByRoleId(Long roleId) {
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleDeptTb::getRoleId, roleId);
List<SystemRoleDeptTb> systemRoleDeptTbs = systemRoleDeptMapper.selectList(wrapper);
if (systemRoleDeptTbs.isEmpty()) {
return new ArrayList<>();
}
List<Long> deptIds = systemRoleDeptTbs.stream().map(SystemRoleDeptTb::getDeptId).collect(Collectors.toList());
return systemDeptMapper.selectByIds(deptIds);
}
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
} }
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>(); @Transactional(rollbackFor = Exception.class)
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds); public void batchInsertRoleDept(Set<SystemDeptTb> depts, Long id) {
return systemRoleDeptMapper.selectCount(wrapper); if (CollUtil.isNotEmpty(depts)) {
} List<SystemRoleDeptTb> records = new ArrayList<>();
for (SystemDeptTb dept : depts) {
SystemRoleDeptTb record = new SystemRoleDeptTb();
record.setRoleId(id);
record.setDeptId(dept.getId());
records.add(record);
}
systemRoleDeptMapper.insert(records);
}
}
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
}
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds);
return systemRoleDeptMapper.selectCount(wrapper);
}
/**
* 根据角色id查询部门信息
*
* @param roleId 角色id
* @return /
*/
public Set<SystemDeptTb> listUserDeptByRoleId(Long roleId) {
return systemRoleDeptMapper.listUserDeptByRoleId(roleId);
}
} }
@@ -23,82 +23,82 @@ import cn.odboy.system.dal.mysql.SystemMenuMapper;
import cn.odboy.system.dal.mysql.SystemRoleMenuMapper; import cn.odboy.system.dal.mysql.SystemRoleMenuMapper;
import cn.odboy.util.KitBeanUtil; import cn.odboy.util.KitBeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleMenuService { public class SystemRoleMenuService {
@Autowired @Autowired
private SystemRoleMenuMapper systemRoleMenuMapper; private SystemRoleMenuMapper systemRoleMenuMapper;
@Autowired @Autowired
private SystemMenuMapper systemMenuMapper; private SystemMenuMapper systemMenuMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleMenuByRoleId(Long roleId) { public void deleteRoleMenuByRoleId(Long roleId) {
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleMenuTb::getRoleId, roleId); wrapper.eq(SystemRoleMenuTb::getRoleId, roleId);
systemRoleMenuMapper.delete(wrapper); systemRoleMenuMapper.delete(wrapper);
}
@Transactional(rollbackFor = Exception.class)
public void batchInsertRoleMenu(Set<SystemMenuVo> menus, Long roleId) {
if (CollUtil.isNotEmpty(menus)) {
List<SystemRoleMenuTb> records = new ArrayList<>();
for (SystemMenuVo menu : menus) {
SystemRoleMenuTb record = new SystemRoleMenuTb();
record.setMenuId(menu.getId());
record.setRoleId(roleId);
records.add(record);
}
systemRoleMenuMapper.insert(records);
} }
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteRoleMenu(Set<Long> roleIds) { public void batchInsertRoleMenu(Set<SystemMenuVo> menus, Long roleId) {
if (CollUtil.isNotEmpty(roleIds)) { if (CollUtil.isNotEmpty(menus)) {
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>(); List<SystemRoleMenuTb> records = new ArrayList<>();
wrapper.in(SystemRoleMenuTb::getRoleId, roleIds); for (SystemMenuVo menu : menus) {
systemRoleMenuMapper.delete(wrapper); SystemRoleMenuTb record = new SystemRoleMenuTb();
record.setMenuId(menu.getId());
record.setRoleId(roleId);
records.add(record);
}
systemRoleMenuMapper.insert(records);
}
} }
}
public LinkedHashSet<SystemMenuVo> queryMenuByRoleIds(Set<Long> roleIds) { @Transactional(rollbackFor = Exception.class)
if (CollUtil.isEmpty(roleIds)) { public void batchDeleteRoleMenu(Set<Long> roleIds) {
return new LinkedHashSet<>(); if (CollUtil.isNotEmpty(roleIds)) {
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleMenuTb::getRoleId, roleIds);
systemRoleMenuMapper.delete(wrapper);
}
} }
LambdaQueryWrapper<SystemRoleMenuTb> roleMenuWrapper = new LambdaQueryWrapper<>();
roleMenuWrapper.in(SystemRoleMenuTb::getRoleId, roleIds);
List<Long> menuIds = systemRoleMenuMapper.selectList(roleMenuWrapper).stream().map(SystemRoleMenuTb::getMenuId)
.collect(Collectors.toList());
if (CollUtil.isEmpty(menuIds)) {
return new LinkedHashSet<>();
}
LambdaQueryWrapper<SystemMenuTb> menuWrapper = new LambdaQueryWrapper<>();
menuWrapper.in(SystemMenuTb::getId, menuIds);
// 排除"按钮"
menuWrapper.ne(SystemMenuTb::getType, 2);
menuWrapper.orderByAsc(SystemMenuTb::getMenuSort);
List<SystemMenuTb> systemMenuTbs = systemMenuMapper.selectList(menuWrapper); public LinkedHashSet<SystemMenuVo> queryMenuByRoleIds(Set<Long> roleIds) {
List<SystemMenuVo> systemMenuVos = KitBeanUtil.copyToList(systemMenuTbs, SystemMenuVo.class); if (CollUtil.isEmpty(roleIds)) {
return new LinkedHashSet<>(systemMenuVos); return new LinkedHashSet<>();
} }
LambdaQueryWrapper<SystemRoleMenuTb> roleMenuWrapper = new LambdaQueryWrapper<>();
roleMenuWrapper.in(SystemRoleMenuTb::getRoleId, roleIds);
List<Long> menuIds = systemRoleMenuMapper.selectList(roleMenuWrapper).stream().map(SystemRoleMenuTb::getMenuId)
.collect(Collectors.toList());
if (CollUtil.isEmpty(menuIds)) {
return new LinkedHashSet<>();
}
LambdaQueryWrapper<SystemMenuTb> menuWrapper = new LambdaQueryWrapper<>();
menuWrapper.in(SystemMenuTb::getId, menuIds);
// 排除"按钮"
menuWrapper.ne(SystemMenuTb::getType, 2);
menuWrapper.orderByAsc(SystemMenuTb::getMenuSort);
@Transactional(rollbackFor = Exception.class) List<SystemMenuTb> systemMenuTbs = systemMenuMapper.selectList(menuWrapper);
public void deleteRoleMenuByMenuIds(List<Long> menuIds) { List<SystemMenuVo> systemMenuVos = KitBeanUtil.copyToList(systemMenuTbs, SystemMenuVo.class);
if (CollUtil.isEmpty(menuIds)) { return new LinkedHashSet<>(systemMenuVos);
return; }
@Transactional(rollbackFor = Exception.class)
public void deleteRoleMenuByMenuIds(List<Long> menuIds) {
if (CollUtil.isEmpty(menuIds)) {
return;
}
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleMenuTb::getMenuId, menuIds);
systemRoleMenuMapper.delete(wrapper);
} }
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleMenuTb::getMenuId, menuIds);
systemRoleMenuMapper.delete(wrapper);
}
} }
@@ -16,19 +16,18 @@
package cn.odboy.system.service; package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.export.SystemRoleExportRowVo; import cn.odboy.system.dal.model.export.SystemRoleExportRowVo;
import cn.odboy.system.dal.model.request.SystemCreateRoleArgs; import cn.odboy.system.dal.model.request.SystemCreateRoleArgs;
import cn.odboy.system.dal.model.request.SystemQueryRoleArgs; import cn.odboy.system.dal.model.request.SystemQueryRoleArgs;
import cn.odboy.system.dal.model.response.SystemMenuVo; import cn.odboy.system.dal.model.response.SystemMenuVo;
import cn.odboy.system.dal.model.response.SystemRoleCodeVo; import cn.odboy.system.dal.model.response.SystemRoleCodeVo;
import cn.odboy.system.dal.model.response.SystemRoleVo; import cn.odboy.system.dal.model.response.SystemRoleVo;
import cn.odboy.system.dal.model.response.SystemUserVo;
import cn.odboy.system.dal.mysql.SystemRoleMapper; import cn.odboy.system.dal.mysql.SystemRoleMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitBeanUtil; import cn.odboy.util.KitBeanUtil;
@@ -37,268 +36,264 @@ import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleService { public class SystemRoleService {
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private SystemRoleMapper systemRoleMapper;
@Autowired @Autowired
private SystemRoleMenuService systemRoleMenuService; private SystemRoleMenuService systemRoleMenuService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemUserRoleService systemUserRoleService;
/** /**
* 创建 * 创建
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveRole(SystemCreateRoleArgs args) { public void saveRole(SystemCreateRoleArgs args) {
checkRoleLevels(args.getLevel()); checkRoleLevels(args.getLevel());
if (this.countRoleByName(args.getName()) > 0) { if (this.countRoleByName(args.getName()) > 0) {
throw new BadRequestException("角色名称已存在"); throw new BadRequestException("角色名称已存在");
}
SystemRoleTb roleTb = KitBeanUtil.copyToClass(args, SystemRoleTb.class);
systemRoleMapper.insert(roleTb);
// 判断是否有部门数据, 若有, 则需创建关联
if (CollUtil.isNotEmpty(args.getDepts())) {
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), roleTb.getId());
}
} }
SystemRoleTb roleTb = KitBeanUtil.copyToClass(args, SystemRoleTb.class);
systemRoleMapper.insert(roleTb); private SystemRoleTb getRoleByName(String name) {
// 判断是否有部门数据, 若有, 则需创建关联 LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
if (CollectionUtil.isNotEmpty(args.getDepts())) { wrapper.eq(SystemRoleTb::getName, name);
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), args.getId()); return systemRoleMapper.selectOne(wrapper);
} }
}
private SystemRoleTb getRoleByName(String name) { private long countRoleByName(String name) {
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleTb::getName, name); wrapper.eq(SystemRoleTb::getName, name);
return systemRoleMapper.selectOne(wrapper); return systemRoleMapper.selectCount(wrapper);
}
private long countRoleByName(String name) {
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleTb::getName, name);
return systemRoleMapper.selectCount(wrapper);
}
/**
* 修改
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateRoleById(SystemRoleVo args) {
checkRoleLevels(args.getLevel());
SystemRoleTb role = this.getRoleTbById(args.getId());
SystemRoleTb role1 = this.getRoleByName(args.getName());
if (role1 != null && !role1.getId().equals(role.getId())) {
throw new BadRequestException("角色名称已存在");
} }
role.setName(args.getName());
role.setDescription(args.getDescription()); /**
role.setDataScope(args.getDataScope()); * 修改
role.setLevel(args.getLevel()); *
// 更新 * @param args /
systemRoleMapper.insertOrUpdate(role); */
// 删除关联部门数据 @Transactional(rollbackFor = Exception.class)
systemRoleDeptService.batchDeleteRoleDept(Collections.singleton(args.getId())); public void updateRoleById(SystemRoleVo args) {
// 判断是否有部门数据, 若有, 则需更新关联 checkRoleLevels(args.getLevel());
if (CollectionUtil.isNotEmpty(args.getDepts())) { SystemRoleTb role = this.getRoleTbById(args.getId());
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), args.getId()); SystemRoleTb role1 = this.getRoleByName(args.getName());
if (role1 != null && !role1.getId().equals(role.getId())) {
throw new BadRequestException("角色名称已存在");
}
role.setName(args.getName());
role.setDescription(args.getDescription());
role.setDataScope(args.getDataScope());
role.setLevel(args.getLevel());
// 更新
systemRoleMapper.insertOrUpdate(role);
// 删除关联部门数据
systemRoleDeptService.batchDeleteRoleDept(Collections.singleton(args.getId()));
// 判断是否有部门数据, 若有, 则需更新关联
if (CollUtil.isNotEmpty(args.getDepts())) {
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), args.getId());
}
} }
}
private SystemRoleTb getRoleTbById(Long id) { private SystemRoleTb getRoleTbById(Long id) {
return systemRoleMapper.selectById(id); return systemRoleMapper.selectById(id);
}
/**
* 修改绑定的菜单
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateBindMenuById(SystemRoleVo args) {
SystemRoleTb role = systemRoleMapper.selectById(args.getId());
checkRoleLevels(role.getLevel());
// 更新菜单
systemRoleMenuService.deleteRoleMenuByRoleId(role.getId());
// 判断是否为空
Set<SystemMenuVo> menus = args.getMenus();
if (CollUtil.isNotEmpty(menus)) {
systemRoleMenuService.batchInsertRoleMenu(menus, role.getId());
} }
}
/** /**
* 删除 * 修改绑定的菜单
* *
* @param ids / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleByIds(Set<Long> ids) { public void updateBindMenuById(SystemRoleVo args) {
List<Integer> roleLevels = systemRoleMapper.selectByIds(ids).stream().map(SystemRoleTb::getLevel).distinct().collect(Collectors.toList()); SystemRoleTb role = systemRoleMapper.selectById(args.getId());
for (Integer roleLevel : roleLevels) { checkRoleLevels(role.getLevel());
checkRoleLevels(roleLevel); // 更新菜单
systemRoleMenuService.deleteRoleMenuByRoleId(role.getId());
// 判断是否为空
Set<SystemMenuVo> menus = args.getMenus();
if (CollUtil.isNotEmpty(menus)) {
systemRoleMenuService.batchInsertRoleMenu(menus, role.getId());
}
} }
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
// 删除角色
systemRoleMapper.deleteByIds(ids);
// 删除角色部门关联数据、角色菜单关联数据
systemRoleDeptService.batchDeleteRoleDept(ids);
systemRoleMenuService.batchDeleteRoleMenu(ids);
}
/** /**
* 查询全部角色 * 删除
*/ *
public List<SystemRoleTb> listAllRole() { * @param ids /
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); */
wrapper.orderByAsc(SystemRoleTb::getLevel); @Transactional(rollbackFor = Exception.class)
return systemRoleMapper.selectList(wrapper); public void deleteRoleByIds(Set<Long> ids) {
} List<Integer> roleLevels = systemRoleMapper.selectByIds(ids).stream().map(SystemRoleTb::getLevel).distinct()
.collect(Collectors.toList());
for (Integer roleLevel : roleLevels) {
checkRoleLevels(roleLevel);
}
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
// 删除角色
systemRoleMapper.deleteByIds(ids);
// 删除角色部门关联数据、角色菜单关联数据
systemRoleDeptService.batchDeleteRoleDept(ids);
systemRoleMenuService.batchDeleteRoleMenu(ids);
}
/** /**
* 根据条件查询全部角色 * 查询全部角色
* */
* @param args 条件 public List<SystemRoleTb> listAllRole() {
* @param rolePage 分页参数 LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
* @return / wrapper.orderByAsc(SystemRoleTb::getLevel);
*/ return systemRoleMapper.selectList(wrapper);
public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> rolePage) { }
KitValidUtil.notNull(args);
// 查询角色基本信息 /**
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); * 根据条件查询全部角色
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), *
c -> c.like(SystemRoleTb::getName, args.getBlurry()).or() * @param args 条件
* @param rolePage 分页参数
* @return /
*/
public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> rolePage) {
KitValidUtil.notNull(args);
// 查询角色基本信息
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
.like(SystemRoleTb::getDescription, args.getBlurry())); .like(SystemRoleTb::getDescription, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
args.getCreateTime().get(1)); }
wrapper.orderByAsc(SystemRoleTb::getLevel);
List<SystemRoleTb> roles;
if (rolePage == null) {
roles = systemRoleMapper.selectList(wrapper);
} else {
Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper);
roles = page.getRecords();
}
return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
} }
wrapper.orderByAsc(SystemRoleTb::getLevel);
List<SystemRoleTb> roles; /**
if (rolePage == null) { * 分页查询角色
roles = systemRoleMapper.selectList(wrapper); *
} else { * @param args 条件
Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper); * @param page 分页条件
roles = page.getRecords(); * @return /
*/
public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> page) {
List<SystemRoleVo> roles = this.queryRoleByArgs(args, page);
Long total = this.countRoleByArgs(args);
return KitPageUtil.toPage(roles, total);
} }
return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
}
/** /**
* 分页查询角色 * 获取用户权限信息
* *
* @param args 条件 * @param user 用户信息
* @param page 分页条件 * @return 权限信息
* @return / */
*/ public List<SystemRoleCodeVo> buildUserRolePermissions(SystemUserVo user) {
public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> page) { Set<String> permissions = new HashSet<>();
List<SystemRoleVo> roles = this.queryRoleByArgs(args, page); // 如果是管理员直接返回
Long total = this.countRoleByArgs(args); if (user.getIsAdmin()) {
return KitPageUtil.toPage(roles, total); permissions.add("admin");
} return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
}
List<SystemRoleVo> roles = systemUserRoleService.queryRoleVoByUsersId(user.getId());
/** permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuVo::getPermission)
* 获取用户权限信息 .filter(StrUtil::isNotBlank).collect(Collectors.toSet());
* return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
* @param user 用户信息
* @return 权限信息
*/
public List<SystemRoleCodeVo> buildUserRolePermissions(SystemUserTb user) {
Set<String> permissions = new HashSet<>();
// 如果是管理员直接返回
if (user.getIsAdmin()) {
permissions.add("admin");
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
} }
List<SystemRoleVo> roles = systemUserRoleService.queryRoleByUsersId(user.getId());
permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuVo::getPermission)
.filter(StrUtil::isNotBlank).collect(Collectors.toSet());
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
}
/** /**
* 验证是否被用户关联 * 验证是否被用户关联
* *
* @param ids / * @param ids /
*/ */
public void verifyBindRelationByIds(Set<Long> ids) { public void verifyBindRelationByIds(Set<Long> ids) {
if (systemUserRoleService.countUserByRoleIds(ids) > 0) { if (systemUserRoleService.countUserByRoleIds(ids) > 0) {
throw new BadRequestException("所选角色存在用户关联, 请解除关联再试!"); throw new BadRequestException("所选角色存在用户关联, 请解除关联再试!");
}
} }
}
public Long countRoleByArgs(SystemQueryRoleArgs args) { public Long countRoleByArgs(SystemQueryRoleArgs args) {
KitValidUtil.notNull(args); KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
.like(SystemRoleTb::getDescription, args.getBlurry())); .like(SystemRoleTb::getDescription, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
args.getCreateTime().get(1)); }
return systemRoleMapper.selectCount(wrapper);
} }
return systemRoleMapper.selectCount(wrapper);
}
public SystemRoleVo getRoleById(Long id) { public SystemRoleVo getRoleById(Long id) {
SystemRoleTb roleTb = systemRoleMapper.selectById(id); SystemRoleTb roleTb = systemRoleMapper.selectById(id);
if (roleTb == null) { if (roleTb == null) {
return null; return null;
}
return systemUserRoleService.convertToRoleVo(roleTb);
} }
return systemUserRoleService.convertToRoleVo(roleTb);
}
public Dict getCurrentUserRoleLevel() { public Dict getCurrentUserRoleLevel() {
return Dict.create().set("level", checkRoleLevels(null)); return Dict.create().set("level", checkRoleLevels(null));
}
/**
* 检查用户的角色级别
*
* @return /
*/
private int checkRoleLevels(Integer level) {
List<Integer> levels = systemUserRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleVo::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
} }
return min;
}
public void exportRoleXlsx(HttpServletResponse response, SystemQueryRoleArgs args) { /**
List<SystemRoleVo> systemRoleVos = this.queryRoleByArgs(args, null); * 检查用户的角色级别
List<SystemRoleExportRowVo> rowVos = new ArrayList<>(); *
for (SystemRoleVo dataObject : systemRoleVos) { * @return /
SystemRoleExportRowVo rowVo = new SystemRoleExportRowVo(); */
rowVo.setName(dataObject.getName()); private int checkRoleLevels(Integer level) {
rowVo.setLevel(dataObject.getLevel()); List<Integer> levels = systemUserRoleService.queryRoleVoByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
rowVo.setDescription(dataObject.getDescription()); .map(SystemRoleVo::getLevel).collect(Collectors.toList());
rowVo.setCreateTime(dataObject.getCreateTime()); int min = Collections.min(levels);
rowVos.add(rowVo); if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
}
return min;
} }
KitExcelExporter.exportSimple(response, "部门数据", SystemRoleExportRowVo.class, rowVos);
}
public List<SystemRoleTb> listByIds(Set<Long> roleIds) { public void exportRoleXlsx(HttpServletResponse response, SystemQueryRoleArgs args) {
return systemRoleMapper.selectByIds(roleIds); List<SystemRoleVo> systemRoleVos = this.queryRoleByArgs(args, null);
} List<SystemRoleExportRowVo> rowVos = new ArrayList<>();
for (SystemRoleVo dataObject : systemRoleVos) {
SystemRoleExportRowVo rowVo = new SystemRoleExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setLevel(dataObject.getLevel());
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "部门数据", SystemRoleExportRowVo.class, rowVos);
}
public List<SystemRoleTb> listByIds(Set<Long> roleIds) {
return systemRoleMapper.selectByIds(roleIds);
}
} }
@@ -3,19 +3,19 @@ package cn.odboy.system.service;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.mysql.SystemUserMapper; import cn.odboy.system.dal.mysql.SystemUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Set;
@Service @Service
public class SystemUserDeptService { public class SystemUserDeptService {
@Autowired @Autowired
private SystemUserMapper systemUserMapper; private SystemUserMapper systemUserMapper;
public long countUserByDeptIds(Set<Long> deptIds) { public long countUserByDeptIds(Set<Long> deptIds) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserTb::getDeptId, deptIds); wrapper.in(SystemUserTb::getDeptId, deptIds);
return systemUserMapper.selectCount(wrapper); return systemUserMapper.selectCount(wrapper);
} }
} }
@@ -20,60 +20,58 @@ import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemUserJobTb; import cn.odboy.system.dal.dataobject.SystemUserJobTb;
import cn.odboy.system.dal.mysql.SystemUserJobMapper; import cn.odboy.system.dal.mysql.SystemUserJobMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemUserJobService { public class SystemUserJobService {
@Autowired @Autowired
private SystemUserJobMapper systemUserJobMapper; private SystemUserJobMapper systemUserJobMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserJob(Set<SystemJobTb> jobs, Long userId) { public void batchInsertUserJob(Set<SystemJobTb> jobs, Long userId) {
if (CollUtil.isNotEmpty(jobs)) { if (CollUtil.isNotEmpty(jobs)) {
List<SystemUserJobTb> records = new ArrayList<>(); List<SystemUserJobTb> records = new ArrayList<>();
for (SystemJobTb job : jobs) { for (SystemJobTb job : jobs) {
SystemUserJobTb record = new SystemUserJobTb(); SystemUserJobTb record = new SystemUserJobTb();
record.setUserId(userId); record.setUserId(userId);
record.setJobId(job.getId()); record.setJobId(job.getId());
records.add(record); records.add(record);
} }
systemUserJobMapper.insert(records); systemUserJobMapper.insert(records);
}
} }
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteUserJob(Set<Long> userIds) { public void batchDeleteUserJob(Set<Long> userIds) {
if (CollUtil.isNotEmpty(userIds)) { if (CollUtil.isNotEmpty(userIds)) {
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserJobTb::getUserId, userIds); wrapper.in(SystemUserJobTb::getUserId, userIds);
systemUserJobMapper.delete(wrapper); systemUserJobMapper.delete(wrapper);
}
} }
}
/** /**
* 根据岗位ID统计用户数量 * 根据岗位ID统计用户数量
* *
* @param jobIds 岗位ID集合 * @param jobIds 岗位ID集合
* @return / * @return /
*/ */
public Long countUserByJobIds(Set<Long> jobIds) { public Long countUserByJobIds(Set<Long> jobIds) {
if (CollUtil.isEmpty(jobIds)) { if (CollUtil.isEmpty(jobIds)) {
return 0L; return 0L;
}
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserJobTb::getJobId, jobIds);
return systemUserJobMapper.selectCount(wrapper);
} }
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserJobTb::getJobId, jobIds);
return systemUserJobMapper.selectCount(wrapper);
}
public List<SystemUserJobTb> listUserJobByUserId(Long userId) { public Set<SystemJobTb> listUserJobByUserId(Long userId) {
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>(); return systemUserJobMapper.listUserJobByUserId(userId);
wrapper.eq(SystemUserJobTb::getUserId, userId); }
return systemUserJobMapper.selectList(wrapper);
}
} }
@@ -28,137 +28,135 @@ import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitBeanUtil; import cn.odboy.util.KitBeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Service @Service
public class SystemUserRoleService { public class SystemUserRoleService {
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private SystemRoleMapper systemRoleMapper;
@Autowired @Autowired
private SystemUserRoleMapper systemUserRoleMapper; private SystemUserRoleMapper systemUserRoleMapper;
@Autowired @Autowired
private SystemRoleMenuService systemRoleMenuService; private SystemRoleMenuService systemRoleMenuService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) { public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) {
if (CollUtil.isNotEmpty(roles)) { if (CollUtil.isNotEmpty(roles)) {
List<SystemUserRoleTb> records = new ArrayList<>(); List<SystemUserRoleTb> records = new ArrayList<>();
for (SystemRoleTb role : roles) { for (SystemRoleTb role : roles) {
SystemUserRoleTb record = new SystemUserRoleTb(); SystemUserRoleTb record = new SystemUserRoleTb();
record.setUserId(userId); record.setUserId(userId);
record.setRoleId(role.getId()); record.setRoleId(role.getId());
records.add(record); records.add(record);
} }
systemUserRoleMapper.insert(records); systemUserRoleMapper.insert(records);
}
} }
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteUserRole(Set<Long> userIds) { public void batchDeleteUserRole(Set<Long> userIds) {
if (CollUtil.isNotEmpty(userIds)) { if (CollUtil.isNotEmpty(userIds)) {
LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserRoleTb::getUserId, userIds); wrapper.in(SystemUserRoleTb::getUserId, userIds);
systemUserRoleMapper.delete(wrapper); systemUserRoleMapper.delete(wrapper);
}
} }
}
/** /**
* 转换为SystemRoleVo并关联查询菜单和部门信息 * 转换为SystemRoleVo并关联查询菜单和部门信息
* *
* @param role 角色基本信息 * @param role 角色基本信息
* @return 包含关联信息的SystemRoleVo * @return 包含关联信息的SystemRoleVo
*/ */
public SystemRoleVo convertToRoleVo(SystemRoleTb role) { public SystemRoleVo convertToRoleVo(SystemRoleTb role) {
if (role == null) { if (role == null) {
return null; return null;
}
SystemRoleVo roleVo = KitBeanUtil.copyToClass(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuVo> menus = systemRoleMenuService.queryMenuByRoleIds(Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
Set<SystemDeptTb> depts = systemRoleDeptService.listUserDeptByRoleId(role.getId());
roleVo.setDepts(depts);
return roleVo;
} }
SystemRoleVo roleVo = KitBeanUtil.copyToClass(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuVo> menus = systemRoleMenuService.queryMenuByRoleIds(Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息 /**
List<SystemDeptTb> depts = systemRoleDeptService.listDeptByRoleId(role.getId()); * 根据用户ID查询
roleVo.setDepts(new LinkedHashSet<>(depts)); *
* @param userId 用户ID
return roleVo; * @return /
} */
public List<SystemRoleVo> queryRoleVoByUsersId(Long userId) {
/** Set<SystemRoleTb> roles = this.listUserRoleByUserId(userId);
* 根据用户ID查询 return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
*
* @param userId 用户ID
* @return /
*/
public List<SystemRoleVo> queryRoleByUsersId(Long userId) {
// 查询用户角色关联
LambdaQueryWrapper<SystemUserRoleTb> userRoleWrapper = new LambdaQueryWrapper<>();
userRoleWrapper.eq(SystemUserRoleTb::getUserId, userId);
List<SystemUserRoleTb> userRoles = systemUserRoleMapper.selectList(userRoleWrapper);
if (CollUtil.isEmpty(userRoles)) {
return new ArrayList<>();
} }
Set<Long> roleIds = userRoles.stream().map(SystemUserRoleTb::getRoleId).collect(Collectors.toSet());
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
}
/** /**
* 根据角色查询角色级别 * 根据角色查询角色级别
* *
* @param roles / * @param roles /
* @return / * @return /
*/ */
public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) { public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) {
if (CollUtil.isEmpty(roles)) { if (CollUtil.isEmpty(roles)) {
return Integer.MAX_VALUE; // 最小权限
return Integer.MAX_VALUE;
}
List<Long> roleIds =
roles.stream().map(SystemRoleTb::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(roleIds)) {
// 最小权限
return Integer.MAX_VALUE;
}
List<Integer> roleLevels = systemRoleMapper.selectList(
new LambdaQueryWrapper<SystemRoleTb>().select(SystemRoleTb::getLevel).isNotNull(SystemRoleTb::getLevel)
.in(SystemRoleTb::getId, roleIds)).stream().map(SystemRoleTb::getLevel).distinct()
.collect(Collectors.toList());
if (CollUtil.isEmpty(roleLevels)) {
// 最小权限
return Integer.MAX_VALUE;
}
return Collections.min(roleLevels);
} }
Set<SystemRoleTb> roleSet = new HashSet<>();
for (SystemRoleTb role : roles) {
roleSet.add(systemRoleMapper.selectById(role.getId()));
}
return Collections.min(roleSet.stream().map(SystemRoleTb::getLevel).collect(Collectors.toList()));
}
/** /**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误 * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
* *
* @param args / * @param args /
*/ */
public void checkLevel(SystemUserVo args) { public void checkLevel(SystemUserVo args) {
Integer currentLevel = Collections.min( Integer currentLevel = Collections.min(
this.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream() this.queryRoleVoByUsersId(KitSecurityHelper.getCurrentUserId()).stream().map(SystemRoleVo::getLevel)
.map(SystemRoleVo::getLevel).collect(Collectors.toList())); .collect(Collectors.toList()));
Integer optLevel = this.getDeptLevelByRoles(args.getRoles()); Integer optLevel = this.getDeptLevelByRoles(args.getRoles());
if (currentLevel > optLevel) { if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足"); throw new BadRequestException("角色权限不足");
}
} }
}
public List<SystemUserRoleTb> listUserRoleByUserId(Long userId) { public long countUserByRoleIds(Set<Long> ids) {
LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>(); if (CollUtil.isEmpty(ids)) {
wrapper.eq(SystemUserRoleTb::getUserId, userId); return 0L;
return systemUserRoleMapper.selectList(wrapper); }
} LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserRoleTb::getRoleId, ids);
return systemUserRoleMapper.selectCount(wrapper);
}
public long countUserByRoleIds(Set<Long> ids) { public Set<SystemRoleTb> listUserRoleByUserId(Long userId) {
if (CollUtil.isEmpty(ids)) { return systemUserRoleMapper.listUserRoleByUserId(userId);
return 0L;
} }
LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserRoleTb::getRoleId, ids);
return systemUserRoleMapper.selectCount(wrapper);
}
} }
@@ -16,7 +16,6 @@
package cn.odboy.system.service; package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
@@ -26,15 +25,13 @@ import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.server.core.KitFileLocalUploadHelper; import cn.odboy.framework.server.core.KitFileLocalUploadHelper;
import cn.odboy.system.constant.SystemCaptchaBizEnum; import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.constant.SystemZhConst; import cn.odboy.system.constant.SystemZhConst;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemJobTb; import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserJobTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.export.SystemUserExportRowVo; import cn.odboy.system.dal.model.export.SystemUserExportRowVo;
import cn.odboy.system.dal.model.request.SystemQueryUserArgs; import cn.odboy.system.dal.model.request.SystemQueryUserArgs;
import cn.odboy.system.dal.model.request.SystemUpdateUserPasswordArgs; import cn.odboy.system.dal.model.request.SystemUpdateUserPasswordArgs;
import cn.odboy.system.dal.model.response.SystemDeptVo;
import cn.odboy.system.dal.model.response.SystemRoleVo; import cn.odboy.system.dal.model.response.SystemRoleVo;
import cn.odboy.system.dal.model.response.SystemUserVo; import cn.odboy.system.dal.model.response.SystemUserVo;
import cn.odboy.system.dal.mysql.SystemUserMapper; import cn.odboy.system.dal.mysql.SystemUserMapper;
@@ -50,470 +47,465 @@ import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; 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;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
@Service @Service
public class SystemUserService { public class SystemUserService {
@Autowired @Autowired
private SystemUserMapper systemUserMapper; private SystemUserMapper systemUserMapper;
@Autowired @Autowired
private SystemJobService systemJobService; private SystemDeptService systemDeptService;
@Autowired @Autowired
private SystemRoleService systemRoleService; private SystemUserJobService systemUserJobService;
@Autowired @Autowired
private SystemDeptService systemDeptService; private SystemUserRoleService systemUserRoleService;
@Autowired @Autowired
private SystemUserJobService systemUserJobService; private SystemEmailService systemEmailService;
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemDataService systemDataService;
@Autowired @Autowired
private SystemEmailService systemEmailService; private SystemUserInfoDAO systemUserInfoDAO;
@Autowired @Autowired
private SystemDataService systemDataService; private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@Autowired @Autowired
private SystemUserInfoDAO systemUserInfoDAO; private KitFileLocalUploadHelper fileUploadPathHelper;
@Autowired @Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; private AppProperties properties;
@Autowired @Autowired
private KitFileLocalUploadHelper fileUploadPathHelper; private PasswordEncoder passwordEncoder;
@Autowired
private AppProperties properties;
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 新增用户
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void saveUser(SystemUserVo args) {
systemUserRoleService.checkLevel(args);
SystemUserTb record = KitBeanUtil.copyToClass(args, SystemUserTb.class);
// 默认密码 123456
record.setPassword(passwordEncoder.encode("123456"));
record.setDeptId(args.getDept().getId());
if (this.getUserByUsername(record.getUsername()) != null) {
throw new BadRequestException("用户名已存在");
}
if (this.getUserByEmail(record.getEmail()) != null) {
throw new BadRequestException("邮箱已存在");
}
if (this.getUserByPhone(record.getPhone()) != null) {
throw new BadRequestException("手机号已存在");
}
// 保存用户
systemUserMapper.insert(record);
// 保存用户岗位
systemUserJobService.batchInsertUserJob(args.getJobs(), record.getId());
// 保存用户角色
systemUserRoleService.batchInsertUserRole(args.getRoles(), record.getId());
}
/** /**
* 新增用户 * 编辑用户
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveUser(SystemUserVo args) { public void updateUserById(SystemUserVo args) {
systemUserRoleService.checkLevel(args); systemUserRoleService.checkLevel(args);
// 默认密码 123456 SystemUserTb user = systemUserMapper.selectById(args.getId());
args.setPassword(passwordEncoder.encode("123456")); SystemUserTb user1 = this.getUserByUsername(args.getUsername());
args.setDeptId(args.getDept().getId()); SystemUserTb user2 = this.getUserByEmail(args.getEmail());
if (this.getUserByUsername(args.getUsername()) != null) { SystemUserTb user3 = this.getUserByPhone(args.getPhone());
throw new BadRequestException("用户名已存在"); if (user1 != null && !user.getId().equals(user1.getId())) {
throw new BadRequestException("用户名已存在");
}
if (user2 != null && !user.getId().equals(user2.getId())) {
throw new BadRequestException("邮箱已存在");
}
if (user3 != null && !user.getId().equals(user3.getId())) {
throw new BadRequestException("手机号已存在");
}
// 如果用户被禁用, 则清除用户登录信息
if (!args.getEnabled()) {
systemUserOnlineInfoDAO.kickOutByUsername(args.getUsername());
}
user.setDeptId(args.getDept().getId());
user.setUsername(args.getUsername());
user.setEmail(args.getEmail());
user.setEnabled(args.getEnabled());
user.setPhone(args.getPhone());
user.setNickName(args.getNickName());
user.setGender(args.getGender());
systemUserMapper.updateById(user);
// 清除用户登录缓存
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
// 更新用户岗位
systemUserJobService.batchDeleteUserJob(Collections.singleton(args.getId()));
systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId());
// 更新用户角色
systemUserRoleService.batchDeleteUserRole(Collections.singleton(args.getId()));
systemUserRoleService.batchInsertUserRole(args.getRoles(), args.getId());
} }
if (this.getUserByEmail(args.getEmail()) != null) {
throw new BadRequestException("邮箱已存在");
}
if (this.getUserByPhone(args.getPhone()) != null) {
throw new BadRequestException("手机号已存在");
}
// 保存用户
systemUserMapper.insert(args);
// 保存用户岗位
systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId());
// 保存用户角色
systemUserRoleService.batchInsertUserRole(args.getRoles(), args.getId());
}
/** /**
* 编辑用户 * 用户自助修改资料
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserById(SystemUserVo args) { public void updateUserCenterInfoById(SystemUserTb args) {
systemUserRoleService.checkLevel(args); if (!args.getId().equals(KitSecurityHelper.getCurrentUserId())) {
SystemUserTb user = systemUserMapper.selectById(args.getId()); throw new BadRequestException("不能修改他人资料");
SystemUserTb user1 = this.getUserByUsername(args.getUsername()); }
SystemUserTb user2 = this.getUserByEmail(args.getEmail()); SystemUserTb user = systemUserMapper.selectById(args.getId());
SystemUserTb user3 = this.getUserByPhone(args.getPhone()); SystemUserTb user1 = this.getUserByPhone(args.getPhone());
if (user1 != null && !user.getId().equals(user1.getId())) { if (user1 != null && !user.getId().equals(user1.getId())) {
throw new BadRequestException("用户名已存在"); throw new BadRequestException("手机号已存在");
}
user.setNickName(args.getNickName());
user.setPhone(args.getPhone());
user.setGender(args.getGender());
systemUserMapper.insertOrUpdate(user);
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
} }
if (user2 != null && !user.getId().equals(user2.getId())) {
throw new BadRequestException("邮箱已存在");
}
if (user3 != null && !user.getId().equals(user3.getId())) {
throw new BadRequestException("手机号已存在");
}
// 如果用户被禁用, 则清除用户登录信息
if (!args.getEnabled()) {
systemUserOnlineInfoDAO.kickOutByUsername(args.getUsername());
}
user.setDeptId(args.getDept().getId());
user.setUsername(args.getUsername());
user.setEmail(args.getEmail());
user.setEnabled(args.getEnabled());
user.setPhone(args.getPhone());
user.setNickName(args.getNickName());
user.setGender(args.getGender());
systemUserMapper.insertOrUpdate(user);
// 清除用户登录缓存
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
// 更新用户岗位
systemUserJobService.batchDeleteUserJob(Collections.singleton(args.getId()));
systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId());
// 更新用户角色
systemUserRoleService.batchDeleteUserRole(Collections.singleton(args.getId()));
systemUserRoleService.batchInsertUserRole(args.getRoles(), args.getId());
}
/** /**
* 用户自助修改资料 * 删除用户
* *
* @param args / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserCenterInfoById(SystemUserTb args) { public void deleteUserByIds(Set<Long> ids) {
if (!args.getId().equals(KitSecurityHelper.getCurrentUserId())) { Long currentUserId = KitSecurityHelper.getCurrentUserId();
throw new BadRequestException("不能修改他人资料"); // 校验权限
for (Long id : ids) {
Integer currentLevel = Collections.min(
systemUserRoleService.queryRoleVoByUsersId(currentUserId).stream().map(SystemRoleVo::getLevel)
.collect(Collectors.toList()));
Integer optLevel = Collections.min(
systemUserRoleService.queryRoleVoByUsersId(id).stream().map(SystemRoleVo::getLevel)
.collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足, 不能删除:" + this.getUserById(id).getUsername());
}
}
// 清理缓存
List<String> usernameList = systemUserMapper.selectByIds(ids).stream().map(SystemUserTb::getUsername).distinct()
.collect(Collectors.toList());
for (String username : usernameList) {
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
}
// 删除用户
systemUserMapper.deleteByIds(ids);
// 删除用户岗位
systemUserJobService.batchDeleteUserJob(ids);
// 删除用户角色
systemUserRoleService.batchDeleteUserRole(ids);
} }
SystemUserTb user = systemUserMapper.selectById(args.getId());
SystemUserTb user1 = this.getUserByPhone(args.getPhone());
if (user1 != null && !user.getId().equals(user1.getId())) {
throw new BadRequestException("手机号已存在");
}
user.setNickName(args.getNickName());
user.setPhone(args.getPhone());
user.setGender(args.getGender());
systemUserMapper.insertOrUpdate(user);
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
}
/** /**
* 删除用户 * 修改密码
* *
* @param ids / * @param username 用户名
*/ * @param args 参数
@Transactional(rollbackFor = Exception.class) */
public void deleteUserByIds(Set<Long> ids) { @Transactional(rollbackFor = Exception.class)
Long currentUserId = KitSecurityHelper.getCurrentUserId(); public void updateUserPasswordByUsername(String username, SystemUpdateUserPasswordArgs args) throws Exception {
// 校验权限 String oldPass = KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getOldPass());
for (Long id : ids) { String newPass = KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getNewPass());
Integer currentLevel = Collections.min( SystemUserTb user = this.getUserByUsername(username);
systemUserRoleService.queryRoleByUsersId(currentUserId).stream() if (!passwordEncoder.matches(oldPass, user.getPassword())) {
.map(SystemRoleVo::getLevel).collect(Collectors.toList())); throw new BadRequestException("修改失败,旧密码错误");
Integer optLevel = Collections.min( }
systemUserRoleService.queryRoleByUsersId(id).stream().map(SystemRoleVo::getLevel) if (passwordEncoder.matches(newPass, user.getPassword())) {
.collect(Collectors.toList())); throw new BadRequestException("新密码不能与旧密码相同");
if (currentLevel > optLevel) { }
throw new BadRequestException( String encryptPassword = passwordEncoder.encode(newPass);
"角色权限不足, 不能删除:" + this.getUserById(id).getUsername()); systemUserMapper.updateUserPasswordByUsername(username, encryptPassword);
} systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
} }
// 清理缓存
List<String> usernameList = systemUserMapper.selectByIds(ids).stream().map(SystemUserTb::getUsername).distinct().collect(Collectors.toList());
for (String username : usernameList) {
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
}
// 删除用户
systemUserMapper.deleteByIds(ids);
// 删除用户岗位
systemUserJobService.batchDeleteUserJob(ids);
// 删除用户角色
systemUserRoleService.batchDeleteUserRole(ids);
}
/** /**
* 修改密码 * 重置密码
* *
* @param username 用户名 * @param ids 用户id
* @param args 参数 */
*/ @Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class) public void resetUserPasswordByIds(Set<Long> ids) {
public void updateUserPasswordByUsername(String username, SystemUpdateUserPasswordArgs args) throws Exception { String defaultPwd = passwordEncoder.encode("123456");
String oldPass = List<SystemUserTb> users = systemUserMapper.selectByIds(ids);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getOldPass()); // 清除缓存
String newPass = for (SystemUserTb user : users) {
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getNewPass()); // 清除缓存
SystemUserTb user = this.getUserByUsername(username); systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
if (!passwordEncoder.matches(oldPass, user.getPassword())) { // 强制退出
throw new BadRequestException("修改失败,旧密码错误"); systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername());
}
// 重置密码
systemUserMapper.updateUserPasswordByUserIds(defaultPwd, ids);
} }
if (passwordEncoder.matches(newPass, user.getPassword())) {
throw new BadRequestException("新密码不能与旧密码相同");
}
String encryptPassword = passwordEncoder.encode(newPass);
systemUserMapper.updateUserPasswordByUsername(username, encryptPassword);
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
}
/** /**
* 重置密码 * 修改头像
* *
* @param ids 用户id * @param multipartFile 文件
*/ * @return /
@Transactional(rollbackFor = Exception.class) */
public void resetUserPasswordByIds(Set<Long> ids) { @Transactional(rollbackFor = Exception.class)
String defaultPwd = passwordEncoder.encode("123456"); public Map<String, String> updateUserAvatar(MultipartFile multipartFile) {
List<SystemUserTb> users = systemUserMapper.selectByIds(ids); SystemUserTb user = this.getUserByUsername(KitSecurityHelper.getCurrentUsername());
// 清除缓存 String username = user.getUsername();
for (SystemUserTb user : users) { if (StrUtil.isBlank(username)) {
// 清除缓存 throw new BadRequestException("异常用户数据, 请联系管理员处理");
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername()); }
// 强制退出 // 文件大小验证
systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername()); KitFileUtil.checkSize(fileUploadPathHelper.getAvatarMaxSize(), multipartFile.getSize());
// 验证文件上传的格式
String image = "gif jpg png jpeg";
String fileType = KitFileUtil.getSuffix(multipartFile.getOriginalFilename());
if (fileType != null && !image.contains(fileType)) {
throw new BadRequestException("文件格式错误!, 仅支持 " + image + " 格式");
}
String oldPath = user.getAvatarPath();
File file = KitFileUtil.upload(multipartFile, fileUploadPathHelper.getPath());
user.setAvatarPath(Objects.requireNonNull(file).getPath());
user.setAvatarName(file.getName());
systemUserMapper.insertOrUpdate(user);
if (StrUtil.isNotBlank(oldPath)) {
KitFileUtil.del(oldPath);
}
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
return new HashMap<>(1) {{
put("avatar", file.getName());
}};
} }
// 重置密码
systemUserMapper.updateUserPasswordByUserIds(defaultPwd, ids);
}
/** /**
* 修改头像 * 修改邮箱
* *
* @param multipartFile 文件 * @param username 用户名
* @return / * @param args 参数
*/ * @param code 验证码
@Transactional(rollbackFor = Exception.class) */
public Map<String, String> updateUserAvatar(MultipartFile multipartFile) { @Transactional(rollbackFor = Exception.class)
SystemUserTb user = this.getUserByUsername(KitSecurityHelper.getCurrentUsername()); public void updateUserEmailByUsername(String username, SystemUserTb args, String code) throws Exception {
String username = user.getUsername(); String password =
if (StrUtil.isBlank(username)) { KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getPassword());
throw new BadRequestException("异常用户数据, 请联系管理员处理"); SystemUserTb user = this.getUserByUsername(username);
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new BadRequestException("密码错误");
}
systemEmailService.checkEmailCaptchaV1(SystemCaptchaBizEnum.EMAIL_RESET_EMAIL_CODE, args.getEmail(), code);
systemUserMapper.updateUserEmailByUsername(username, args.getEmail());
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
} }
// 文件大小验证
KitFileUtil.checkSize(fileUploadPathHelper.getAvatarMaxSize(), multipartFile.getSize());
// 验证文件上传的格式
String image = "gif jpg png jpeg";
String fileType = KitFileUtil.getSuffix(multipartFile.getOriginalFilename());
if (fileType != null && !image.contains(fileType)) {
throw new BadRequestException("文件格式错误!, 仅支持 " + image + " 格式");
}
String oldPath = user.getAvatarPath();
File file = KitFileUtil.upload(multipartFile, fileUploadPathHelper.getPath());
user.setAvatarPath(Objects.requireNonNull(file).getPath());
user.setAvatarName(file.getName());
systemUserMapper.insertOrUpdate(user);
if (StrUtil.isNotBlank(oldPath)) {
KitFileUtil.del(oldPath);
}
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
return new HashMap<>(1) {{
put("avatar", file.getName());
}};
}
/** /**
* 修改邮箱 * 查询全部
* *
* @param username 用户名 * @param args 条件
* @param args 参数 * @param page 分页参数
* @param code 验证码 * @return /
*/ */
@Transactional(rollbackFor = Exception.class) public KitPageResult<SystemUserVo> searchUserByArgs(SystemQueryUserArgs args, Page<SystemUserTb> page) {
public void updateUserEmailByUsername(String username, SystemUserTb args, String code) throws Exception { // 查询用户基本信息
String password = LambdaQueryWrapper<SystemUserTb> wrapper = this.buildUserQueryWrapper(args);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getPassword()); IPage<SystemUserTb> userPage = systemUserMapper.selectPage(page, wrapper);
SystemUserTb user = this.getUserByUsername(username); List<SystemUserTb> users = userPage.getRecords();
if (!passwordEncoder.matches(password, user.getPassword())) { // 转换为SystemUserVo并关联查询
throw new BadRequestException("密码错误"); List<SystemUserVo> userVos =
users.stream().map(m -> this.convertToUserVo(m, false)).collect(Collectors.toList());
return KitPageUtil.toPage(userVos, userPage.getTotal());
} }
systemEmailService.checkEmailCaptchaV1(SystemCaptchaBizEnum.EMAIL_RESET_EMAIL_CODE, args.getEmail(), code);
systemUserMapper.updateUserEmailByUsername(username, args.getEmail());
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
}
/** public long countUserByArgs(SystemQueryUserArgs args) {
* 查询全部 LambdaQueryWrapper<SystemUserTb> wrapper = this.buildUserQueryWrapper(args);
* return systemUserMapper.selectCount(wrapper);
* @param args 条件
* @param page 分页参数
* @return /
*/
public KitPageResult<SystemUserVo> searchUserByArgs(SystemQueryUserArgs args, Page<SystemUserTb> page) {
// 查询用户基本信息
LambdaQueryWrapper<SystemUserTb> wrapper = buildUserQueryWrapper(args);
IPage<SystemUserTb> userPage = systemUserMapper.selectPage(page, wrapper);
List<SystemUserTb> users = userPage.getRecords();
// 转换为SystemUserVo并关联查询
List<SystemUserVo> userVos = users.stream().map(this::convertToUserVo).collect(Collectors.toList());
return KitPageUtil.toPage(userVos, userPage.getTotal());
}
public long countUserByArgs(SystemQueryUserArgs args) {
LambdaQueryWrapper<SystemUserTb> wrapper = buildUserQueryWrapper(args);
return systemUserMapper.selectCount(wrapper);
}
/**
* 根据ID查询
*
* @param id ID
* @return /
*/
public SystemUserTb getUserById(long id) {
return systemUserMapper.selectById(id);
}
public List<KitSelectOptionVo> queryUserMetadataOptions(KitPageArgs<SystemQueryUserArgs> pageArgs) {
SystemQueryUserArgs args = pageArgs.getArgs();
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.select(SystemUserTb::getId, SystemUserTb::getDeptId, SystemUserTb::getEmail, SystemUserTb::getPhone);
wrapper.and(c -> {
c.eq(SystemUserTb::getPhone, args.getBlurry());
c.or();
c.eq(SystemUserTb::getEmail, args.getBlurry());
c.or();
c.like(SystemUserTb::getUsername, args.getBlurry());
c.or();
c.like(SystemUserTb::getNickName, args.getBlurry());
});
return systemUserMapper.selectPage(new Page<>(pageArgs.getPage(), 50), wrapper).getRecords().stream().map(m -> {
Map<String, Object> ext = new HashMap<>(1);
ext.put("id", m.getId());
ext.put("deptId", m.getDeptId());
ext.put("email", m.getEmail());
ext.put("phone", m.getPhone());
return KitSelectOptionVo.builder().label(m.getNickName()).value(String.valueOf(m.getId())).ext(ext).build();
}).collect(Collectors.toList());
}
/**
* 构建用户查询条件
*
* @param args 查询条件
* @return /
*/
private LambdaQueryWrapper<SystemUserTb> buildUserQueryWrapper(SystemQueryUserArgs args) {
KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
if (args.getId() != null) {
wrapper.eq(SystemUserTb::getId, args.getId());
} }
if (args.getEnabled() != null) {
wrapper.eq(SystemUserTb::getEnabled, args.getEnabled());
}
if (CollUtil.isNotEmpty(args.getDeptIds())) {
wrapper.in(SystemUserTb::getDeptId, args.getDeptIds());
}
if (StrUtil.isNotBlank(args.getBlurry())) {
wrapper.and(w -> w.like(SystemUserTb::getUsername, args.getBlurry())
.or().like(SystemUserTb::getNickName, args.getBlurry())
.or().like(SystemUserTb::getEmail, args.getBlurry()));
}
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemUserTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
wrapper.orderByDesc(SystemUserTb::getCreateTime);
return wrapper;
}
/** /**
* 转换为SystemUserVo并关联查询部门、角色、岗位信息 * 根据ID查询
* *
* @param user 用户基本信息 * @param id ID
* @return 包含关联信息的SystemUserVo * @return /
*/ */
private SystemUserVo convertToUserVo(SystemUserTb user) { public SystemUserTb getUserById(long id) {
if (user == null) { return systemUserMapper.selectById(id);
return null;
} }
SystemUserVo userVo = KitBeanUtil.copyToClass(user, SystemUserVo.class);
// 查询关联的部门信息 public List<KitSelectOptionVo> queryUserMetadataOptions(KitPageArgs<SystemQueryUserArgs> pageArgs) {
if (user.getDeptId() != null) { SystemQueryUserArgs args = pageArgs.getArgs();
SystemDeptVo dept = systemDeptService.getDeptVoById(user.getDeptId()); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
userVo.setDept(dept); wrapper.select(SystemUserTb::getId, SystemUserTb::getDeptId, SystemUserTb::getEmail, SystemUserTb::getPhone);
wrapper.and(c -> {
c.eq(SystemUserTb::getPhone, args.getBlurry());
c.or();
c.eq(SystemUserTb::getEmail, args.getBlurry());
c.or();
c.like(SystemUserTb::getUsername, args.getBlurry());
c.or();
c.like(SystemUserTb::getNickName, args.getBlurry());
});
return systemUserMapper.selectPage(new Page<>(pageArgs.getPage(), 50), wrapper).getRecords().stream().map(m -> {
Map<String, Object> ext = new HashMap<>(1);
ext.put("id", m.getId());
ext.put("deptId", m.getDeptId());
ext.put("email", m.getEmail());
ext.put("phone", m.getPhone());
return KitSelectOptionVo.builder().label(m.getNickName()).value(String.valueOf(m.getId())).ext(ext).build();
}).collect(Collectors.toList());
} }
// 查询关联的岗位信息
List<SystemUserJobTb> userJobs = systemUserJobService.listUserJobByUserId(user.getId()); /**
if (CollUtil.isNotEmpty(userJobs)) { * 构建用户查询条件
Set<Long> jobIds = userJobs.stream().map(SystemUserJobTb::getJobId).collect(Collectors.toSet()); *
List<SystemJobTb> jobs = systemJobService.listByIds(jobIds); * @param args 查询条件
userVo.setJobs(new LinkedHashSet<>(jobs)); * @return /
*/
private LambdaQueryWrapper<SystemUserTb> buildUserQueryWrapper(SystemQueryUserArgs args) {
KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
if (args.getId() != null) {
wrapper.eq(SystemUserTb::getId, args.getId());
}
if (args.getEnabled() != null) {
wrapper.eq(SystemUserTb::getEnabled, args.getEnabled());
}
if (CollUtil.isNotEmpty(args.getDeptIds())) {
wrapper.in(SystemUserTb::getDeptId, args.getDeptIds());
}
if (StrUtil.isNotBlank(args.getBlurry())) {
wrapper.and(w -> w.like(SystemUserTb::getUsername, args.getBlurry()).or()
.like(SystemUserTb::getNickName, args.getBlurry()).or().like(SystemUserTb::getEmail, args.getBlurry()));
}
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemUserTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
}
wrapper.orderByDesc(SystemUserTb::getCreateTime);
return wrapper;
} }
// 查询关联的角色信息
List<SystemUserRoleTb> userRoles = systemUserRoleService.listUserRoleByUserId(user.getId()); /**
if (CollUtil.isNotEmpty(userRoles)) { * 转换为SystemUserVo并关联查询部门、角色、岗位信息
Set<Long> roleIds = userRoles.stream().map(SystemUserRoleTb::getRoleId).collect(Collectors.toSet()); *
List<SystemRoleTb> roles = systemRoleService.listByIds(roleIds); * @param user 用户基本信息
userVo.setRoles(new LinkedHashSet<>(roles)); * @param includePassword 是否包含用户密码
* @return 包含关联信息的SystemUserVo
*/
private SystemUserVo convertToUserVo(SystemUserTb user, boolean includePassword) {
if (user == null) {
return null;
}
if (!includePassword) {
// 查询用户时,清空密码
user.setPassword(null);
}
SystemUserVo userVo = KitBeanUtil.copyToClass(user, SystemUserVo.class);
// 查询关联的部门信息
if (user.getDeptId() != null) {
userVo.setDept(systemDeptService.getDeptVoById(user.getDeptId()));
}
// 查询关联的岗位信息
userVo.setJobs(systemUserJobService.listUserJobByUserId(user.getId()));
// 查询关联的角色信息
userVo.setRoles(systemUserRoleService.listUserRoleByUserId(user.getId()));
return userVo;
} }
return userVo;
}
public SystemUserTb getUserByUsername(String username) { public SystemUserTb getUserByUsername(String username) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemUserTb::getUsername, username); wrapper.eq(SystemUserTb::getUsername, username);
wrapper.eq(SystemUserTb::getEnabled, 1); wrapper.eq(SystemUserTb::getEnabled, 1);
return systemUserMapper.selectOne(wrapper); return systemUserMapper.selectOne(wrapper);
}
public SystemUserVo getUserVoByUsername(String username) {
return this.convertToUserVo(this.getUserByUsername(username));
}
public SystemUserTb getUserByEmail(String email) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemUserTb::getEmail, email);
wrapper.eq(SystemUserTb::getEnabled, 1);
return systemUserMapper.selectOne(wrapper);
}
public SystemUserTb getUserByPhone(String phone) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemUserTb::getPhone, phone);
wrapper.eq(SystemUserTb::getEnabled, 1);
return systemUserMapper.selectOne(wrapper);
}
public KitPageResult<SystemUserVo> aggregationSearchUserByArgs(Page<SystemUserTb> page, SystemQueryUserArgs args, String currentUsername) {
if (!ObjectUtils.isEmpty(args.getDeptId())) {
args.getDeptIds().add(args.getDeptId());
// 先查找是否存在子节点
List<SystemDeptVo> data = systemDeptService.listDeptByPid(args.getDeptId());
// 然后把子节点的ID都加入到集合中
args.getDeptIds().addAll(systemDeptService.queryChildDeptIdByDeptIds(data));
} }
// 数据权限
List<Long> dataScopes = systemDataService.queryDeptIdByArgs(this.getUserVoByUsername(currentUsername));
// args.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(args.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)) {
// 取交集
args.getDeptIds().retainAll(dataScopes);
if (!CollectionUtil.isEmpty(args.getDeptIds())) {
return this.searchUserByArgs(args, page);
}
} else {
// 否则取并集
args.getDeptIds().addAll(dataScopes);
return this.searchUserByArgs(args, page);
}
return KitPageUtil.emptyData();
}
public void exportUserXlsx(HttpServletResponse response, SystemQueryUserArgs args) { public SystemUserVo getUserVoWithPasswordByUsername(String username) {
long totalCount = this.countUserByArgs(args); return this.convertToUserVo(this.getUserByUsername(username), true);
KitExcelExporter.exportByPage(response, "用户数据", SystemUserExportRowVo.class, totalCount, (long pageNum, long pageSize) -> { }
KitPageResult<SystemUserVo> pageResult = this.searchUserByArgs(args, new Page<>(pageNum, pageSize));
List<SystemUserExportRowVo> rowVos = new ArrayList<>(); public SystemUserVo getUserVoByUsername(String username) {
for (SystemUserVo dataObject : pageResult.getContent()) { return this.convertToUserVo(this.getUserByUsername(username), false);
SystemUserExportRowVo rowVo = new SystemUserExportRowVo(); }
rowVo.setUsername(dataObject.getUsername());
rowVo.setRoles(dataObject.getRoles().stream().map(SystemRoleTb::getName).collect(Collectors.joining(","))); public SystemUserTb getUserByEmail(String email) {
rowVo.setDept(dataObject.getDept().getName()); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
rowVo.setJobs(dataObject.getJobs().stream().map(SystemJobTb::getName).collect(Collectors.joining(","))); wrapper.eq(SystemUserTb::getEmail, email);
rowVo.setEmail(dataObject.getEmail()); wrapper.eq(SystemUserTb::getEnabled, 1);
rowVo.setStatus(dataObject.getEnabled() ? SystemZhConst.ENABLE_STR : SystemZhConst.DISABLE_STR); return systemUserMapper.selectOne(wrapper);
rowVo.setMobile(dataObject.getPhone()); }
rowVo.setUpdatePwdTime(dataObject.getPwdResetTime());
rowVo.setCreateTime(dataObject.getCreateTime()); public SystemUserTb getUserByPhone(String phone) {
rowVos.add(rowVo); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
} wrapper.eq(SystemUserTb::getPhone, phone);
return rowVos; wrapper.eq(SystemUserTb::getEnabled, 1);
}); return systemUserMapper.selectOne(wrapper);
} }
public KitPageResult<SystemUserVo> aggregationSearchUserByArgs(Page<SystemUserTb> page, SystemQueryUserArgs args,
String currentUsername) {
if (!ObjectUtils.isEmpty(args.getDeptId())) {
args.getDeptIds().add(args.getDeptId());
// 先查找是否存在子节点
List<SystemDeptTb> data = systemDeptService.listDeptByPid(args.getDeptId());
Map<Long, List<SystemDeptTb>> deptPidMap =
systemDeptService.listPidNonNull().stream().collect(Collectors.groupingBy(SystemDeptTb::getPid));
// 然后把子节点的ID都加入到集合中
args.getDeptIds().addAll(systemDeptService.queryChildDeptIdByDeptIds(data, deptPidMap));
}
// 数据权限
List<Long> dataScopes = systemDataService.queryDeptIdByArgs(this.getUserVoByUsername(currentUsername));
// args.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollUtil.isEmpty(args.getDeptIds()) && !CollUtil.isEmpty(dataScopes)) {
// 取交集
args.getDeptIds().retainAll(dataScopes);
if (!CollUtil.isEmpty(args.getDeptIds())) {
return this.searchUserByArgs(args, page);
}
} else {
// 否则取并集
args.getDeptIds().addAll(dataScopes);
return this.searchUserByArgs(args, page);
}
return KitPageUtil.emptyData();
}
public void exportUserXlsx(HttpServletResponse response, SystemQueryUserArgs args) {
long totalCount = this.countUserByArgs(args);
KitExcelExporter.exportByPage(response, "用户数据", SystemUserExportRowVo.class, totalCount,
(long pageNum, long pageSize) -> {
KitPageResult<SystemUserVo> pageResult = this.searchUserByArgs(args, new Page<>(pageNum, pageSize));
List<SystemUserExportRowVo> rowVos = new ArrayList<>();
for (SystemUserVo dataObject : pageResult.getContent()) {
SystemUserExportRowVo rowVo = new SystemUserExportRowVo();
rowVo.setUsername(dataObject.getUsername());
rowVo.setRoles(
dataObject.getRoles().stream().map(SystemRoleTb::getName).collect(Collectors.joining(",")));
rowVo.setDept(dataObject.getDept().getName());
rowVo.setJobs(
dataObject.getJobs().stream().map(SystemJobTb::getName).collect(Collectors.joining(",")));
rowVo.setEmail(dataObject.getEmail());
rowVo.setStatus(dataObject.getEnabled() ? SystemZhConst.ENABLE_STR : SystemZhConst.DISABLE_STR);
rowVo.setMobile(dataObject.getPhone());
rowVo.setUpdatePwdTime(dataObject.getPwdResetTime());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
return rowVos;
});
}
} }
@@ -39,13 +39,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.io.File;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.List;
/** /**
* <p> * <p>
@@ -59,105 +59,110 @@ import org.springframework.web.multipart.MultipartFile;
public class SystemMinioStorageServiceImpl extends ServiceImpl<SystemOssStorageMapper, SystemOssStorageTb> public class SystemMinioStorageServiceImpl extends ServiceImpl<SystemOssStorageMapper, SystemOssStorageTb>
implements SystemOssStorageService { implements SystemOssStorageService {
@Autowired @Autowired
private MinioRepository minioRepository; private MinioRepository minioRepository;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
@Autowired @Autowired
private KitFileLocalUploadHelper fileLocalUploadHelper; private KitFileLocalUploadHelper fileLocalUploadHelper;
@Autowired @Autowired
private SystemOssStorageMapper systemOssStorageMapper; private SystemOssStorageMapper systemOssStorageMapper;
@Override @Override
public KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args, Page<SystemOssStorageTb> page) { public KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args,
IPage<SystemOssStorageVo> ossStorageTbs = this.selectOssStorageByArgs(args, page); Page<SystemOssStorageTb> page) {
for (SystemOssStorageVo storageVo : ossStorageTbs.getRecords()) { IPage<SystemOssStorageVo> ossStorageTbs = this.selectOssStorageByArgs(args, page);
storageVo.setFileSizeDesc(KitFileUtil.getSize(storageVo.getFileSize())); for (SystemOssStorageVo storageVo : ossStorageTbs.getRecords()) {
storageVo.setFileSizeDesc(KitFileUtil.getSize(storageVo.getFileSize()));
}
return KitPageUtil.toPage(ossStorageTbs);
} }
return KitPageUtil.toPage(ossStorageTbs);
}
private IPage<SystemOssStorageVo> selectOssStorageByArgs(SystemQueryStorageArgs args, Page<SystemOssStorageTb> page) { private IPage<SystemOssStorageVo> selectOssStorageByArgs(SystemQueryStorageArgs args,
KitValidUtil.notNull(args); Page<SystemOssStorageTb> page) {
LambdaQueryWrapper<SystemOssStorageTb> wrapper = new LambdaQueryWrapper<>(); KitValidUtil.notNull(args);
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), LambdaQueryWrapper<SystemOssStorageTb> wrapper = new LambdaQueryWrapper<>();
c -> c.like(SystemOssStorageTb::getFileName, args.getBlurry()).or() wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
.like(SystemOssStorageTb::getFilePrefix, args.getBlurry()).or() c -> c.like(SystemOssStorageTb::getFileName, args.getBlurry()).or()
.like(SystemOssStorageTb::getFileMime, args.getBlurry()).or() .like(SystemOssStorageTb::getFilePrefix, args.getBlurry()).or()
.like(SystemOssStorageTb::getFileMd5, args.getBlurry())); .like(SystemOssStorageTb::getFileMime, args.getBlurry()).or()
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { .like(SystemOssStorageTb::getFileMd5, args.getBlurry()));
wrapper.between(SystemOssStorageTb::getUpdateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemOssStorageTb::getUpdateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
wrapper.orderByAsc(SystemOssStorageTb::getId);
return systemOssStorageMapper.selectPage(page, wrapper)
.convert(i -> KitBeanUtil.copyToClass(i, SystemOssStorageVo.class));
} }
wrapper.orderByAsc(SystemOssStorageTb::getId);
return systemOssStorageMapper.selectPage(page, wrapper).convert(i -> KitBeanUtil.copyToClass(i, SystemOssStorageVo.class));
}
@Override @Override
public List<SystemOssStorageVo> queryOssStorage(SystemQueryStorageArgs args) { public List<SystemOssStorageVo> queryOssStorage(SystemQueryStorageArgs args) {
// 防止刷数据 // 防止刷数据
Page<SystemOssStorageTb> page = new Page<>(1, 500); Page<SystemOssStorageTb> page = new Page<>(1, 500);
return searchOssStorage(args, page).getContent(); return searchOssStorage(args, page).getContent();
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String uploadFile(MultipartFile file) { public String uploadFile(MultipartFile file) {
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
if (StrUtil.isBlank(originalFilename)) { if (StrUtil.isBlank(originalFilename)) {
throw new BadRequestException("文件名不能为空"); throw new BadRequestException("文件名不能为空");
}
StorageOSSModel ossConfig = properties.getOss();
long fileSize = file.getSize();
String contentType = file.getContentType();
KitFileUtil.checkSize(ossConfig.getMaxSize(), fileSize);
// 按天分组
String nowDateStr = KitDateUtil.getNowDateStr();
// 上传到本地临时目录
File tempFile = KitFileUtil.upload(file, fileLocalUploadHelper.getPath() + nowDateStr + File.separator);
if (tempFile == null) {
throw new BadRequestException("上传失败");
}
// 校验文件md5, 看是否已存在云端(不确定, 可能云端已经删除, 但是正常来说云端是不允许私自删除的, 所以这里忽略云端不存在的情况)
String md5 = KitFileUtil.getMd5(tempFile);
SystemOssStorageTb systemOssStorageTb = this.getOssStorageByMd5(md5);
if (systemOssStorageTb != null) {
// 重新生成7天链接
return minioRepository.generatePreviewUrl(systemOssStorageTb.getObjectName());
}
// 上传到OSS
SystemOssStorageTb storageTb = minioRepository.upload(tempFile, originalFilename, fileSize, contentType, md5);
if (storageTb == null) {
throw new BadRequestException("文件上传失败");
}
save(storageTb);
return minioRepository.generatePreviewUrl(storageTb.getObjectName());
} }
StorageOSSModel ossConfig = properties.getOss();
long fileSize = file.getSize();
String contentType = file.getContentType();
KitFileUtil.checkSize(ossConfig.getMaxSize(), fileSize);
// 按天分组
String nowDateStr = KitDateUtil.getNowDateStr();
// 上传到本地临时目录
File tempFile = KitFileUtil.upload(file, fileLocalUploadHelper.getPath() + nowDateStr + File.separator);
if (tempFile == null) {
throw new BadRequestException("上传失败");
}
// 校验文件md5, 看是否已存在云端(不确定, 可能云端已经删除, 但是正常来说云端是不允许私自删除的, 所以这里忽略云端不存在的情况)
String md5 = KitFileUtil.getMd5(tempFile);
SystemOssStorageTb systemOssStorageTb = this.getOssStorageByMd5(md5);
if (systemOssStorageTb != null) {
// 重新生成7天链接
return minioRepository.generatePreviewUrl(systemOssStorageTb.getObjectName());
}
// 上传到OSS
SystemOssStorageTb storageTb = minioRepository.upload(tempFile, originalFilename, fileSize, contentType, md5);
if (storageTb == null) {
throw new BadRequestException("文件上传失败");
}
save(storageTb);
return minioRepository.generatePreviewUrl(storageTb.getObjectName());
}
/** /**
* 多选删除 * 多选删除
* *
* @param ids / * @param ids /
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteFileByIds(Long[] ids) { public void deleteFileByIds(Long[] ids) {
for (Long id : ids) { for (Long id : ids) {
SystemOssStorageTb storage = getById(id); SystemOssStorageTb storage = getById(id);
minioRepository.removeBucketFile(storage.getObjectName()); minioRepository.removeBucketFile(storage.getObjectName());
removeById(storage); removeById(storage);
}
} }
}
@Override @Override
public void exportOssStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args) { public void exportOssStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args) {
List<SystemOssStorageVo> systemOssStorageVos = this.queryOssStorage(args); List<SystemOssStorageVo> systemOssStorageVos = this.queryOssStorage(args);
// KitXlsxExportUtil.exportFile(response, "OSS文件上传记录数据", systemOssStorageVos, SystemOssStorageExportRowVo.class, // KitXlsxExportUtil.exportFile(response, "OSS文件上传记录数据", systemOssStorageVos, SystemOssStorageExportRowVo.class,
// (dataObject) -> CollUtil.newArrayList(KitBeanUtil.copyProperties(dataObject, SystemOssStorageExportRowVo.class))); // (dataObject) -> CollUtil.newArrayList(KitBeanUtil.copyProperties(dataObject, SystemOssStorageExportRowVo.class)));
List<SystemOssStorageExportRowVo> rowVos = KitBeanUtil.copyToList(systemOssStorageVos, SystemOssStorageExportRowVo.class); List<SystemOssStorageExportRowVo> rowVos =
KitExcelExporter.exportSimple(response, "OSS文件上传记录数据", SystemOssStorageExportRowVo.class, rowVos); KitBeanUtil.copyToList(systemOssStorageVos, SystemOssStorageExportRowVo.class);
} KitExcelExporter.exportSimple(response, "OSS文件上传记录数据", SystemOssStorageExportRowVo.class, rowVos);
}
private SystemOssStorageTb getOssStorageByMd5(String md5) { private SystemOssStorageTb getOssStorageByMd5(String md5) {
return lambdaQuery().eq(SystemOssStorageTb::getFileMd5, md5).one(); return lambdaQuery().eq(SystemOssStorageTb::getFileMd5, md5).one();
} }
} }
@@ -1,18 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.odboy.system.dal.mysql.SystemDictDetailMapper"> <mapper namespace="cn.odboy.system.dal.mysql.SystemDictDetailMapper">
<select id="selectPageByArgs" resultType="cn.odboy.system.dal.dataobject.SystemDictDetailTb"> <select id="selectPageByArgs" resultType="cn.odboy.system.dal.model.response.SystemDictDetailVo">
SELECT SELECT
t1.* t1.*
FROM system_dict_detail t1 LEFT JOIN system_dict t2 ON t1.dict_id = t2.id FROM system_dict_detail t1 LEFT JOIN system_dict t2 ON t1.dict_id = t2.id
<where> <where>
<if test="args.dictName != null and args.dictName != ''"> <if test="args.dictName != null and args.dictName != ''">
AND t2.name = #{args.dictName} AND t2.name = #{args.dictName}
</if> </if>
<if test="args.label != null and args.label != ''"> <if test="args.label != null and args.label != ''">
AND t1.label = #{args.label} AND t1.label = #{args.label}
</if> </if>
</where> </where>
ORDER BY t1.dict_sort ORDER BY t1.dict_sort
</select> </select>
<select id="listDictDetailByName" resultType="cn.odboy.system.dal.model.response.SystemDictDetailVo">
SELECT t1.*
FROM system_dict_detail t1
LEFT JOIN system_dict t2 ON t1.dict_id = t2.id
<where>
<if test="name != null and name != ''">
AND t2.name = #{name}
</if>
</where>
ORDER BY t1.dict_sort
</select>
</mapper> </mapper>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.odboy.system.dal.mysql.SystemRoleDeptMapper">
<select id="listUserDeptByRoleId" resultType="cn.odboy.system.dal.dataobject.SystemDeptTb">
SELECT DISTINCT t1.*, t1.dept_id as id
FROM system_dept t1
LEFT JOIN system_roles_depts t2 ON t1.dept_id = t2.dept_id
WHERE t2.role_id = #{roleId}
</select>
</mapper>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.odboy.system.dal.mysql.SystemUserJobMapper">
<select id="listUserJobByUserId" resultType="cn.odboy.system.dal.dataobject.SystemJobTb">
SELECT DISTINCT t1.*
FROM system_job t1
LEFT JOIN system_users_jobs t2 ON t1.id = t2.job_id
WHERE t1.enabled = 1
AND t2.user_id = #{userId}
</select>
</mapper>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.odboy.system.dal.mysql.SystemUserRoleMapper">
<select id="listUserRoleByUserId" resultType="cn.odboy.system.dal.dataobject.SystemRoleTb">
SELECT DISTINCT t1.*, t1.role_id as id
FROM system_role t1
LEFT JOIN system_users_roles t2 ON t1.role_id = t2.role_id
WHERE t2.user_id = #{userId}
</select>
</mapper>
@@ -17,11 +17,13 @@ package cn.odboy.system.dal.mysql;
import cn.odboy.system.dal.dataobject.SystemDictDetailTb; import cn.odboy.system.dal.dataobject.SystemDictDetailTb;
import cn.odboy.system.dal.model.request.SystemQueryDictDetailArgs; import cn.odboy.system.dal.model.request.SystemQueryDictDetailArgs;
import cn.odboy.system.dal.model.response.SystemDictDetailVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 字典明细 Mapper * 字典明细 Mapper
@@ -31,5 +33,7 @@ import org.apache.ibatis.annotations.Param;
@Mapper @Mapper
public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> { public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> {
IPage<SystemDictDetailTb> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args); IPage<SystemDictDetailVo> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args);
List<SystemDictDetailVo> listDictDetailByName(@Param("name") String name);
} }
@@ -14,13 +14,13 @@ import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
import cn.odboy.util.KitBeanUtil; import cn.odboy.util.KitBeanUtil;
import cn.odboy.util.KitRsaEncryptUtil; import cn.odboy.util.KitRsaEncryptUtil;
import cn.odboy.util.KitValidUtil; import cn.odboy.util.KitValidUtil;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
/** /**
* 用户认证 * 用户认证
@@ -28,74 +28,76 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemAuthService { public class SystemAuthService {
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
@Autowired @Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@Autowired @Autowired
private TokenProvider tokenProvider; private TokenProvider tokenProvider;
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Autowired @Autowired
private UserDetailsHandler userDetailsService; private UserDetailsHandler userDetailsService;
@Autowired @Autowired
private SystemCaptchaService systemCaptchaService; private SystemCaptchaService systemCaptchaService;
/** /**
* 登录 * 登录 -> TestPassed
*/ */
public SystemAuthVo doLogin(SystemUserLoginArgs loginArgs, HttpServletRequest request) throws Exception { public SystemAuthVo doLogin(SystemUserLoginArgs loginArgs, HttpServletRequest request) throws Exception {
KitValidUtil.notNull(loginArgs); KitValidUtil.notNull(loginArgs);
// 密码解密 // 密码解密
String password = KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginArgs.getPassword()); String password =
// 校验验证码 KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginArgs.getPassword());
systemCaptchaService.validate(loginArgs.getUuid(), loginArgs.getCode()); // 校验验证码
// 获取用户信息 systemCaptchaService.validate(loginArgs.getUuid(), loginArgs.getCode());
SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginArgs.getUsername()); // 获取用户信息
// 验证用户密码 SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginArgs.getUsername());
if (!passwordEncoder.matches(password, jwtUser.getPassword())) { // 验证用户密码
throw new BadRequestException("登录密码错误"); if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
// 登录验证
Authentication authentication =
new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
SystemAuthVo authInfo = new SystemAuthVo();
authInfo.setToken(String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
/// 这里是为了清空密码
authInfo.setUser(KitBeanUtil.copyToClass(jwtUser, SystemUserInfoVo.class));
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginArgs.getUsername());
}
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return authInfo;
} }
// 登录验证 /**
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities()); * 获取当前登录人信息 -> TestPassed
SecurityContextHolder.getContext().setAuthentication(authentication); */
public SystemUserJwtVo getCurrentUserInfo() {
// 生成令牌 SystemUserJwtVo jwtUser = (SystemUserJwtVo)KitSecurityHelper.getCurrentUser();
String token = tokenProvider.createToken(jwtUser); if (jwtUser.getUser() != null) {
// 返回 token 与 用户信息 jwtUser.getUser().setPassword(null);
SystemAuthVo authInfo = new SystemAuthVo(); }
authInfo.setToken(String.format("%s %s", SystemConst.TOKEN_PREFIX, token)); return jwtUser;
/// 这里是为了清空密码
authInfo.setUser(KitBeanUtil.copyToClass(jwtUser, SystemUserInfoVo.class));
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginArgs.getUsername());
} }
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return authInfo;
}
/** /**
* 获取当前登录人信息 * 退出登录 -> TestPassed
*/ */
public SystemUserJwtVo getCurrentUserInfo() { public void doLogout(HttpServletRequest request) {
SystemUserJwtVo jwtUser = (SystemUserJwtVo) KitSecurityHelper.getCurrentUser(); String token = tokenProvider.getToken(request);
if (jwtUser.getUser() != null) { systemUserOnlineInfoDAO.logoutByToken(token);
jwtUser.getUser().setPassword(null);
} }
return jwtUser;
}
/**
* 退出登录
*/
public void doLogout(HttpServletRequest request) {
String token = tokenProvider.getToken(request);
systemUserOnlineInfoDAO.logoutByToken(token);
}
} }
@@ -10,9 +10,9 @@ import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.model.response.SystemCaptchaVo; import cn.odboy.system.dal.model.response.SystemCaptchaVo;
import cn.odboy.system.dal.redis.SystemCacheKey; import cn.odboy.system.dal.redis.SystemCacheKey;
import com.wf.captcha.base.Captcha; import com.wf.captcha.base.Captcha;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/** /**
* 验证码 * 验证码
@@ -20,49 +20,50 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemCaptchaService { public class SystemCaptchaService {
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
/** /**
* 获取登录验证码 * 获取登录验证码 -> TestPassed
*/ */
public SystemCaptchaVo getLoginCaptcha() { public SystemCaptchaVo getLoginCaptcha() {
// 获取运算的结果 // 获取运算的结果
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha(); Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID(); String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
//当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型 //当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型
String captchaValue = captcha.text(); String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() && if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() && captchaValue.contains(
captchaValue.contains(SystemConst.SYMBOL_DOT)) { SystemConst.SYMBOL_DOT)) {
captchaValue = captchaValue.split("\\.")[0]; captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(),
TimeUnit.MINUTES);
// 验证码信息
SystemCaptchaVo captchaVo = new SystemCaptchaVo();
captchaVo.setUuid(uuid);
captchaVo.setImg(captcha.toBase64());
return captchaVo;
} }
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(), TimeUnit.MINUTES);
// 验证码信息
SystemCaptchaVo captchaVo = new SystemCaptchaVo();
captchaVo.setUuid(uuid);
captchaVo.setImg(captcha.toBase64());
return captchaVo;
}
/** /**
* 验证验证码 * 验证验证码 -> TestPassed
* *
* @param uuid 验证码uuid * @param uuid 验证码uuid
* @param inputCode 用户输入的验证码 * @param inputCode 用户输入的验证码
*/ */
public void validate(String uuid, String inputCode) { public void validate(String uuid, String inputCode) {
// 查询验证码 // 查询验证码
String code = redisHelper.get(uuid, String.class); String code = redisHelper.get(uuid, String.class);
if (StrUtil.isBlank(code)) { if (StrUtil.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期"); throw new BadRequestException("验证码不存在或已过期");
}
// 清除验证码
redisHelper.del(uuid);
if (StrUtil.isBlank(inputCode) || !code.equalsIgnoreCase(inputCode)) {
throw new BadRequestException("验证码错误");
}
} }
// 清除验证码
redisHelper.del(uuid);
if (StrUtil.isBlank(inputCode) || !code.equalsIgnoreCase(inputCode)) {
throw new BadRequestException("验证码错误");
}
}
} }
@@ -20,14 +20,14 @@ import cn.odboy.system.constant.SystemDataScopeEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.model.response.SystemUserVo; import cn.odboy.system.dal.model.response.SystemUserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/** /**
* 数据权限 * 数据权限
@@ -37,61 +37,61 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemDataService { public class SystemDataService {
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemUserRoleService systemUserRoleService;
@Autowired @Autowired
private SystemDeptService systemDeptService; private SystemDeptService systemDeptService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
/** /**
* 获取数据权限 * 获取数据权限 -> TestPassed
* *
* @param user / * @param user /
* @return / * @return /
*/ */
public List<Long> queryDeptIdByArgs(SystemUserVo user) { public List<Long> queryDeptIdByArgs(SystemUserVo user) {
List<Long> deptIds = new ArrayList<>(); List<Long> deptIds = new ArrayList<>();
// 查询用户角色 // 查询用户角色
Set<SystemRoleTb> roleList = systemUserRoleService.listUserRoleByUserId(user.getId()); Set<SystemRoleTb> roleList = systemUserRoleService.listUserRoleByUserId(user.getId());
// 获取对应的部门ID // 获取对应的部门ID
for (SystemRoleTb role : roleList) { for (SystemRoleTb role : roleList) {
SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope()); SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope());
switch (Objects.requireNonNull(dataScopeEnum)) { switch (Objects.requireNonNull(dataScopeEnum)) {
case THIS_LEVEL: case THIS_LEVEL:
Long currentDeptId = user.getDept().getId(); Long currentDeptId = user.getDept().getId();
deptIds.add(currentDeptId); deptIds.add(currentDeptId);
break; break;
case CUSTOMIZE: case CUSTOMIZE:
// 优化 283ms -> 51 ms // 优化 283ms -> 51 ms
List<Long> customDeptIds = this.queryCustomDataPermissionV2ByArgs(deptIds, role.getId()); List<Long> customDeptIds = this.queryCustomDataPermissionByArgs(deptIds, role.getId());
deptIds.addAll(customDeptIds); deptIds.addAll(customDeptIds);
break; break;
default: default:
return new ArrayList<>(); return new ArrayList<>();
} }
}
return deptIds.stream().distinct().collect(Collectors.toList());
} }
return deptIds.stream().distinct().collect(Collectors.toList());
}
/** /**
* 获取自定义的数据权限 * 获取自定义的数据权限 -> TestPassed
* *
* @param deptIds 部门ID(外部数据) * @param deptIds 部门ID(外部数据)
* @param roleId 角色ID * @param roleId 角色ID
* @return 数据权限ID(所有部门ID数据) * @return 数据权限ID(所有部门ID数据)
*/ */
private List<Long> queryCustomDataPermissionV2ByArgs(List<Long> deptIds, Long roleId) { private List<Long> queryCustomDataPermissionByArgs(List<Long> deptIds, Long roleId) {
Set<SystemDeptTb> deptList = systemRoleDeptService.listUserDeptByRoleId(roleId); Set<SystemDeptTb> deptList = systemRoleDeptService.listUserDeptByRoleId(roleId);
Map<Long, List<SystemDeptTb>> deptPidMap = systemDeptService.listPidNonNull().stream() Map<Long, List<SystemDeptTb>> deptPidMap =
.collect(Collectors.groupingBy(SystemDeptTb::getPid)); systemDeptService.listPidNonNull().stream().collect(Collectors.groupingBy(SystemDeptTb::getPid));
for (SystemDeptTb dept : deptList) { for (SystemDeptTb dept : deptList) {
deptIds.add(dept.getId()); deptIds.add(dept.getId());
List<SystemDeptTb> deptChildren = deptPidMap.getOrDefault(dept.getId(), null); List<SystemDeptTb> deptChildren = deptPidMap.getOrDefault(dept.getId(), null);
if (CollUtil.isNotEmpty(deptChildren)) { if (CollUtil.isNotEmpty(deptChildren)) {
deptIds.addAll(systemDeptService.queryChildDeptIdByDeptIds(deptChildren, deptPidMap)); deptIds.addAll(systemDeptService.queryChildDeptIdByDeptIds(deptChildren, deptPidMap));
} }
}
return deptIds;
} }
return deptIds;
}
} }
@@ -36,6 +36,10 @@ import cn.odboy.util.KitClassUtil;
import cn.odboy.util.KitValidUtil; import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -47,454 +51,458 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemDeptService { public class SystemDeptService {
@Autowired @Autowired
private SystemDeptMapper systemDeptMapper; private SystemDeptMapper systemDeptMapper;
@Autowired @Autowired
private SystemUserDeptService systemUserDeptService; private SystemUserDeptService systemUserDeptService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveDept(SystemCreateDeptArgs args) { public void saveDept(SystemCreateDeptArgs args) {
KitValidUtil.notNull(args); KitValidUtil.notNull(args);
systemDeptMapper.insert(KitBeanUtil.copyToClass(args, SystemDeptTb.class));
this.updateDeptSubCnt(args.getPid());
}
/** SystemDeptTb record = KitBeanUtil.copyToClass(args, SystemDeptTb.class);
* 编辑 systemDeptMapper.insert(record);
*
* @param args / this.updateDeptSubCnt(args.getPid());
*/
@Transactional(rollbackFor = Exception.class)
public void updateDeptById(SystemDeptTb args) {
KitValidUtil.notNull(args);
// 旧的父部门
Long oldPid = this.getDeptById(args.getId()).getPid();
// 新的父部门
Long newPid = args.getPid();
if (args.getPid() != null && args.getId().equals(args.getPid())) {
throw new BadRequestException("上级不能为自己");
} }
SystemDeptTb dept = systemDeptMapper.selectById(args.getId());
args.setId(dept.getId());
systemDeptMapper.insertOrUpdate(args);
this.updateDeptSubCnt(oldPid);
this.updateDeptSubCnt(newPid);
}
private SystemDeptTb getDeptById(Long id) { /**
return systemDeptMapper.selectById(id); * 编辑 -> TestPassed
} *
* @param args /
/** */
* 删除 @Transactional(rollbackFor = Exception.class)
* public void updateDeptById(SystemDeptTb args) {
* @param ids / KitValidUtil.notNull(args);
*/ // 旧的父部门
@Transactional(rollbackFor = Exception.class) Long oldPid = this.getDeptById(args.getId()).getPid();
public void deleteDeptByIds(Set<Long> ids) { // 新的父部门
// 获取部门, 和其所有子部门 Long newPid = args.getPid();
Set<SystemDeptVo> depts = this.traverseDeptByIdWithPids(ids); if (args.getPid() != null && args.getId().equals(args.getPid())) {
// 验证是否被角色或用户关联 throw new BadRequestException("上级不能为自己");
this.verifyBindRelationByIds(depts);
for (SystemDeptVo dept : depts) {
systemDeptMapper.deleteById(dept.getId());
this.updateDeptSubCnt(dept.getPid());
}
}
/**
* 更新父节点中子节点数目
*
* @param deptId /
*/
@Transactional(rollbackFor = Exception.class)
public void updateDeptSubCnt(Long deptId) {
if (deptId != null) {
long count = this.countDeptByPid(deptId);
systemDeptMapper.updateDeptSubCountById(count, deptId);
}
}
private long countDeptByPid(Long pid) {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getPid, pid);
return systemDeptMapper.selectCount(wrapper);
}
/**
* 筛选出 list 中没有父部门(即 pid 不在其他部门 id 列表中的部门)的部门列表
*/
private List<SystemDeptTb> deduplication(List<SystemDeptTb> list) {
List<SystemDeptTb> deptList = new ArrayList<>();
// 使用 Set 存储所有部门的 id
Set<Long> idSet = list.stream().map(SystemDeptTb::getId).collect(Collectors.toSet());
// 遍历部门列表, 筛选出没有父部门的部门
for (SystemDeptTb dept : list) {
if (!idSet.contains(dept.getPid())) {
deptList.add(dept);
}
}
return deptList;
}
private List<SystemDeptTb> queryDeptByArgs(SystemQueryDeptArgs args) {
KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(CollUtil.isNotEmpty(args.getIds()), SystemDeptTb::getId, args.getIds());
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemDeptTb::getName, args.getName());
wrapper.eq(args.getEnabled() != null, SystemDeptTb::getEnabled, args.getEnabled());
wrapper.eq(args.getPid() != null, SystemDeptTb::getPid, args.getPid());
wrapper.isNull(args.getPidIsNull() != null, SystemDeptTb::getPid);
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemDeptTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
wrapper.orderByAsc(SystemDeptTb::getDeptSort);
return systemDeptMapper.selectList(wrapper);
}
/**
* 查询所有数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemDeptTb> queryAllDeptByArgs(SystemQueryDeptArgs args, Boolean isQuery) throws Exception {
String dataScopeType = KitSecurityHelper.getDataScopeType();
if (isQuery) {
if (dataScopeType.equals(SystemDataScopeEnum.ALL.getValue())) {
args.setPidIsNull(true);
}
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
List<String> fieldNames = new ArrayList<>() {{
add("pidIsNull");
add("enabled");
}};
for (Field field : fields) {
// 设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if (fieldNames.contains(field.getName())) {
continue;
} }
if (ObjectUtil.isNotNull(val)) { SystemDeptTb dept = systemDeptMapper.selectById(args.getId());
args.setPidIsNull(null); args.setId(dept.getId());
break; systemDeptMapper.updateById(args);
this.updateDeptSubCnt(oldPid);
this.updateDeptSubCnt(newPid);
}
/**
* 根据部门id获取部门信息 -> TestPassed
*
* @param id 部门id
* @return /
*/
private SystemDeptTb getDeptById(Long id) {
return systemDeptMapper.selectById(id);
}
/**
* 删除
*
* @param ids /
*/
@Transactional(rollbackFor = Exception.class)
public void deleteDeptByIds(Set<Long> ids) {
// 获取部门, 和其所有子部门
Set<SystemDeptVo> depts = this.traverseDeptByIdWithPids(ids);
// 验证是否被角色或用户关联
this.verifyBindRelationByIds(depts);
for (SystemDeptVo dept : depts) {
systemDeptMapper.deleteById(dept.getId());
this.updateDeptSubCnt(dept.getPid());
} }
}
} }
// 数据权限
args.setIds(KitSecurityHelper.getCurrentUserDataScope());
List<SystemDeptTb> list = this.queryDeptByArgs(args);
// 如果为空, 就代表为自定义权限或者本级权限, 就需要去重, 不理解可以注释掉,看查询结果
if (StrUtil.isBlank(dataScopeType)) {
return this.deduplication(list);
}
return list;
}
/** /**
* 根据ID查询 * 更新父节点中子节点数目 -> TestPassed
* *
* @param id / * @param deptId /
* @return / */
*/ @Transactional(rollbackFor = Exception.class)
public SystemDeptVo getDeptVoById(Long id) { public void updateDeptSubCnt(Long deptId) {
return KitBeanUtil.copyToClass(systemDeptMapper.selectById(id), SystemDeptVo.class); if (deptId != null) {
} long count = this.countDeptByPid(deptId);
systemDeptMapper.updateDeptSubCountById(count, deptId);
/**
* 获取部门下所有关联的部门
*
* @param deptTbList /
* @param depts /
*/
private void queryRelationDeptByArgs(List<SystemDeptVo> deptTbList, Set<SystemDeptVo> depts) {
for (SystemDeptVo dept : deptTbList) {
depts.add(dept);
List<SystemDeptVo> deptList = this.listDeptVoByPid(dept.getId());
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
}
}
private List<SystemDeptVo> listDeptVoByPid(Long pid) {
return KitBeanUtil.copyToList(this.listDeptByPid(pid), SystemDeptVo.class);
}
public List<Long> queryChildDeptIdByDeptIds(List<SystemDeptTb> deptList, Map<Long, List<SystemDeptTb>> deptPidMap) {
List<Long> list = new ArrayList<>();
for (SystemDeptTb systemDeptTb : deptList) {
if (systemDeptTb != null && systemDeptTb.getEnabled()) {
List<SystemDeptTb> deptList1 = deptPidMap.getOrDefault(systemDeptTb.getId(), null);
if (CollUtil.isNotEmpty(deptList1)) {
list.addAll(this.queryChildDeptIdByDeptIds(deptList1, deptPidMap));
} }
list.add(systemDeptTb.getId());
}
} }
return list;
}
/** private long countDeptByPid(Long pid) {
* 根据ID获取同级与上级数据 LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
* wrapper.eq(SystemDeptTb::getPid, pid);
* @param dept / return systemDeptMapper.selectCount(wrapper);
* @param deptList /
* @return /
*/
private List<SystemDeptVo> querySuperiorDeptByPid(SystemDeptVo dept, List<SystemDeptVo> deptList) {
if (dept.getPid() == null) {
deptList.addAll(this.listRootDept());
return deptList;
} }
deptList.addAll(this.listDeptVoByPid(dept.getPid()));
return querySuperiorDeptByPid(this.getDeptVoById(dept.getPid()), deptList);
}
private List<SystemDeptVo> listRootDept() { /**
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); * 筛选出 list 中没有父部门(即 pid 不在其他部门 id 列表中的部门)的部门列表
wrapper.isNull(SystemDeptTb::getPid); */
return KitBeanUtil.copyToList(systemDeptMapper.selectList(wrapper), SystemDeptVo.class); private List<SystemDeptTb> deduplication(List<SystemDeptTb> list) {
} List<SystemDeptTb> deptList = new ArrayList<>();
// 使用 Set 存储所有部门的 id
/** Set<Long> idSet = list.stream().map(SystemDeptTb::getId).collect(Collectors.toSet());
* 构建树形数据 // 遍历部门列表, 筛选出没有父部门的部门
* for (SystemDeptTb dept : list) {
* @return / if (!idSet.contains(dept.getPid())) {
*/ deptList.add(dept);
public KitPageResult<SystemDeptVo> searchDeptTree(List<Long> ids, Boolean exclude) { }
Set<SystemDeptVo> deptSet1 = new LinkedHashSet<>();
for (Long id : ids) {
// 同级数据
SystemDeptVo dept = this.getDeptVoById(id);
// 上级数据
List<SystemDeptVo> depts = this.querySuperiorDeptByPid(dept, new ArrayList<>());
if (exclude) {
for (SystemDeptVo data : depts) {
if (data.getId().equals(dept.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
} }
// 编辑部门时不显示自己以及自己下级的数据, 避免出现PID数据环形问题 return deptList;
depts = depts.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toList());
}
deptSet1.addAll(depts);
} }
List<SystemDeptVo> deptList = new ArrayList<>(deptSet1);
// 构建部门树 private List<SystemDeptTb> queryDeptByArgs(SystemQueryDeptArgs args) {
Set<SystemDeptVo> trees = new LinkedHashSet<>(); KitValidUtil.notNull(args);
Set<SystemDeptVo> deptSet = new LinkedHashSet<>(); LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
List<String> deptNames = deptList.stream().map(SystemDeptVo::getName).collect(Collectors.toList()); wrapper.in(CollUtil.isNotEmpty(args.getIds()), SystemDeptTb::getId, args.getIds());
boolean isChild; wrapper.like(StrUtil.isNotBlank(args.getName()), SystemDeptTb::getName, args.getName());
for (SystemDeptVo dept : deptList) { wrapper.eq(args.getEnabled() != null, SystemDeptTb::getEnabled, args.getEnabled());
isChild = false; wrapper.eq(args.getPid() != null, SystemDeptTb::getPid, args.getPid());
if (dept.getPid() == null) { wrapper.isNull(args.getPidIsNull() != null, SystemDeptTb::getPid);
trees.add(dept); if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
} wrapper.between(SystemDeptTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
for (SystemDeptVo it : deptList) {
if (it.getPid() != null && dept.getId().equals(it.getPid())) {
isChild = true;
if (dept.getChildren() == null) {
dept.setChildren(new ArrayList<>());
}
dept.getChildren().add(it);
} }
} wrapper.orderByAsc(SystemDeptTb::getDeptSort);
if (isChild) { return systemDeptMapper.selectList(wrapper);
deptSet.add(dept);
} else if (dept.getPid() != null && !deptNames.contains(this.getDeptVoById(dept.getPid()).getName())) {
deptSet.add(dept);
}
} }
if (CollUtil.isEmpty(trees)) {
trees = deptSet; /**
* 查询所有数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemDeptTb> queryAllDeptByArgs(SystemQueryDeptArgs args, Boolean isQuery) throws Exception {
String dataScopeType = KitSecurityHelper.getDataScopeType();
if (isQuery) {
if (dataScopeType.equals(SystemDataScopeEnum.ALL.getValue())) {
args.setPidIsNull(true);
}
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
List<String> fieldNames = new ArrayList<>() {{
add("pidIsNull");
add("enabled");
}};
for (Field field : fields) {
// 设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if (fieldNames.contains(field.getName())) {
continue;
}
if (ObjectUtil.isNotNull(val)) {
args.setPidIsNull(null);
break;
}
}
}
// 数据权限
args.setIds(KitSecurityHelper.getCurrentUserDataScope());
List<SystemDeptTb> list = this.queryDeptByArgs(args);
// 如果为空, 就代表为自定义权限或者本级权限, 就需要去重, 不理解可以注释掉,看查询结果
if (StrUtil.isBlank(dataScopeType)) {
return this.deduplication(list);
}
return list;
} }
KitPageResult<SystemDeptVo> baseResult = new KitPageResult<>();
baseResult.setContent(CollUtil.isEmpty(trees) ? new ArrayList<>(deptSet) : new ArrayList<>(trees));
baseResult.setTotalElements(deptSet.size());
return baseResult;
}
/** /**
* 验证是否被角色或用户关联 * 根据ID查询
* *
* @param deptSet / * @param id /
*/ * @return /
public void verifyBindRelationByIds(Set<SystemDeptVo> deptSet) { */
Set<Long> deptIds = deptSet.stream().map(SystemDeptVo::getId).collect(Collectors.toSet()); public SystemDeptVo getDeptVoById(Long id) {
if (systemUserDeptService.countUserByDeptIds(deptIds) > 0) { return KitBeanUtil.copyToClass(systemDeptMapper.selectById(id), SystemDeptVo.class);
throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
} }
if (systemRoleDeptService.countRoleByDeptIds(deptIds) > 0) {
throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); /**
* 获取部门下所有关联的部门
*
* @param deptTbList /
* @param depts /
*/
private void queryRelationDeptByArgs(List<SystemDeptVo> deptTbList, Set<SystemDeptVo> depts) {
for (SystemDeptVo dept : deptTbList) {
depts.add(dept);
List<SystemDeptVo> deptList = this.listDeptVoByPid(dept.getId());
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
}
} }
}
private List<SystemDeptTb> listEnabledDepts() { private List<SystemDeptVo> listDeptVoByPid(Long pid) {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); return KitBeanUtil.copyToList(this.listDeptByPid(pid), SystemDeptVo.class);
wrapper.eq(SystemDeptTb::getEnabled, 1);
return systemDeptMapper.selectList(wrapper);
}
/**
* 遍历所有部门和子部门
*
* @param ids /
*/
public Set<SystemDeptVo> traverseDeptByIdWithPids(Set<Long> ids) {
Set<SystemDeptVo> depts = new HashSet<>();
for (Long id : ids) {
// 根部门
depts.add(this.getDeptVoById(id));
// 子部门
List<SystemDeptVo> deptList = this.listDeptVoByPid(id);
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
} }
return depts;
}
public List<SystemProductLineVo> listDeptSelectDataSource() { public List<Long> queryChildDeptIdByDeptIds(List<SystemDeptTb> deptList, Map<Long, List<SystemDeptTb>> deptPidMap) {
List<SystemDeptTb> depts = this.listEnabledDepts(); List<Long> list = new ArrayList<>();
return buildDeptSelectOptions(depts); for (SystemDeptTb systemDeptTb : deptList) {
} if (systemDeptTb != null && systemDeptTb.getEnabled()) {
List<SystemDeptTb> deptList1 = deptPidMap.getOrDefault(systemDeptTb.getId(), null);
private List<SystemProductLineVo> buildDeptSelectOptions(List<SystemDeptTb> depts) { if (CollUtil.isNotEmpty(deptList1)) {
// 获取所有部门并按父子关系组织 list.addAll(this.queryChildDeptIdByDeptIds(deptList1, deptPidMap));
Map<Long, SystemDeptTb> deptMap = }
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity())); list.add(systemDeptTb.getId());
List<SystemProductLineVo> options = new ArrayList<>(); }
for (SystemDeptTb dept : depts) { }
// 构建部门ID路径 return list;
List<Long> pathIds = new ArrayList<>();
buildDeptIdPath(dept, deptMap, pathIds);
// 反转路径,从顶级部门到当前部门
Collections.reverse(pathIds);
SystemProductLineVo dto = new SystemProductLineVo();
dto.setValue(dept.getId());
dto.setIdPath(pathIds.stream().map(String::valueOf).collect(Collectors.joining("-")));
// 保留名称路径用于显示
dto.setLabel(buildNamePath(dept, deptMap));
options.add(dto);
} }
// 按部门名称路径排序
options.sort(Comparator.comparing(SystemProductLineVo::getLabel));
return options;
}
private void buildDeptIdPath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<Long> pathIds) { /**
pathIds.add(dept.getId()); * 根据ID获取同级与上级数据
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) { *
buildDeptIdPath(deptMap.get(dept.getPid()), deptMap, pathIds); * @param dept /
* @param deptList /
* @return /
*/
private List<SystemDeptVo> querySuperiorDeptByPid(SystemDeptVo dept, List<SystemDeptVo> deptList) {
if (dept.getPid() == null) {
deptList.addAll(this.listRootDept());
return deptList;
}
deptList.addAll(this.listDeptVoByPid(dept.getPid()));
return querySuperiorDeptByPid(this.getDeptVoById(dept.getPid()), deptList);
} }
}
private String buildNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) { private List<SystemDeptVo> listRootDept() {
List<String> pathNames = new ArrayList<>(); LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
buildDeptNamePath(dept, deptMap, pathNames); wrapper.isNull(SystemDeptTb::getPid);
Collections.reverse(pathNames); return KitBeanUtil.copyToList(systemDeptMapper.selectList(wrapper), SystemDeptVo.class);
return String.join(" / ", pathNames);
}
private void buildDeptNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<String> pathNames) {
pathNames.add(dept.getName());
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) {
buildDeptNamePath(deptMap.get(dept.getPid()), deptMap, pathNames);
} }
}
public List<SystemProductLineTreeVo> listDeptSelectProDataSource() { /**
List<SystemDeptTb> depts = this.listEnabledDepts(); * 构建树形数据
// 获取所有部门并按父子关系组织 *
Map<Long, SystemDeptTb> deptMap = * @return /
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity())); */
List<SystemProductLineTreeVo> options = new ArrayList<>(); public KitPageResult<SystemDeptVo> searchDeptTree(List<Long> ids, Boolean exclude) {
// 构建树形结构 Set<SystemDeptVo> deptSet1 = new LinkedHashSet<>();
for (SystemDeptTb dept : depts) { for (Long id : ids) {
// 只处理顶级部门(pid为null或0的部门) // 同级数据
if (dept.getPid() == null || dept.getPid() == 0) { SystemDeptVo dept = this.getDeptVoById(id);
SystemProductLineTreeVo vo = buildDeptTreePro(dept, deptMap); // 上级数据
options.add(vo); List<SystemDeptVo> depts = this.querySuperiorDeptByPid(dept, new ArrayList<>());
} if (exclude) {
for (SystemDeptVo data : depts) {
if (data.getId().equals(dept.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
// 编辑部门时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
depts = depts.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toList());
}
deptSet1.addAll(depts);
}
List<SystemDeptVo> deptList = new ArrayList<>(deptSet1);
// 构建部门树
Set<SystemDeptVo> trees = new LinkedHashSet<>();
Set<SystemDeptVo> deptSet = new LinkedHashSet<>();
List<String> deptNames = deptList.stream().map(SystemDeptVo::getName).collect(Collectors.toList());
boolean isChild;
for (SystemDeptVo dept : deptList) {
isChild = false;
if (dept.getPid() == null) {
trees.add(dept);
}
for (SystemDeptVo it : deptList) {
if (it.getPid() != null && dept.getId().equals(it.getPid())) {
isChild = true;
if (dept.getChildren() == null) {
dept.setChildren(new ArrayList<>());
}
dept.getChildren().add(it);
}
}
if (isChild) {
deptSet.add(dept);
} else if (dept.getPid() != null && !deptNames.contains(this.getDeptVoById(dept.getPid()).getName())) {
deptSet.add(dept);
}
}
if (CollUtil.isEmpty(trees)) {
trees = deptSet;
}
KitPageResult<SystemDeptVo> baseResult = new KitPageResult<>();
baseResult.setContent(CollUtil.isEmpty(trees) ? new ArrayList<>(deptSet) : new ArrayList<>(trees));
baseResult.setTotalElements(deptSet.size());
return baseResult;
} }
// 按排序字段排序
options.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
return options;
}
/** /**
* 递归构建部门树 * 验证是否被角色或用户关联
* *
* @param dept 当前部门 * @param deptSet /
* @param deptMap 部门映射 */
* @return SystemProductLineTreeVo 树节点 public void verifyBindRelationByIds(Set<SystemDeptVo> deptSet) {
*/ Set<Long> deptIds = deptSet.stream().map(SystemDeptVo::getId).collect(Collectors.toSet());
private SystemProductLineTreeVo buildDeptTreePro(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) { if (systemUserDeptService.countUserByDeptIds(deptIds) > 0) {
SystemProductLineTreeVo vo = new SystemProductLineTreeVo(); throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
vo.setValue(String.valueOf(dept.getId())); }
vo.setLabel(dept.getName()); if (systemRoleDeptService.countRoleByDeptIds(deptIds) > 0) {
// 查找子部门 throw new BadRequestException("所选部门存在角色关联,请解除后再试!");
List<SystemProductLineTreeVo> children = new ArrayList<>(); }
for (SystemDeptTb childDept : deptMap.values()) {
if (dept.getId().equals(childDept.getPid())) {
children.add(buildDeptTreePro(childDept, deptMap));
}
} }
// 子部门按排序字段排序
children.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
vo.setChildren(children);
return vo;
}
public List<SystemDeptTb> listDeptByPid(long pid) { private List<SystemDeptTb> listEnabledDepts() {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getPid, pid); wrapper.eq(SystemDeptTb::getEnabled, 1);
return systemDeptMapper.selectList(wrapper); return systemDeptMapper.selectList(wrapper);
}
public void exportDeptXlsx(HttpServletResponse response, SystemQueryDeptArgs args) throws Exception {
List<SystemDeptTb> systemDeptTbs = this.queryAllDeptByArgs(args, false);
List<SystemDeptExportRowVo> rowVos = new ArrayList<>();
for (SystemDeptTb dataObject : systemDeptTbs) {
SystemDeptExportRowVo rowVo = new SystemDeptExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setEnabled(dataObject.getEnabled() ? SystemZhConst.ENABLE_STR : SystemZhConst.DISABLE_STR);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
} }
KitExcelExporter.exportSimple(response, "部门数据", SystemDeptExportRowVo.class, rowVos);
}
public List<SystemDeptTb> listPidNonNull() { /**
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>(); * 遍历所有部门和子部门
wrapper.eq(SystemDeptTb::getEnabled, 1); *
wrapper.isNotNull(SystemDeptTb::getPid); * @param ids /
return systemDeptMapper.selectList(wrapper); */
} public Set<SystemDeptVo> traverseDeptByIdWithPids(Set<Long> ids) {
Set<SystemDeptVo> depts = new HashSet<>();
for (Long id : ids) {
// 根部门
depts.add(this.getDeptVoById(id));
// 子部门
List<SystemDeptVo> deptList = this.listDeptVoByPid(id);
if (CollUtil.isNotEmpty(deptList)) {
queryRelationDeptByArgs(deptList, depts);
}
}
return depts;
}
public List<SystemProductLineVo> listDeptSelectDataSource() {
List<SystemDeptTb> depts = this.listEnabledDepts();
return buildDeptSelectOptions(depts);
}
private List<SystemProductLineVo> buildDeptSelectOptions(List<SystemDeptTb> depts) {
// 获取所有部门并按父子关系组织
Map<Long, SystemDeptTb> deptMap =
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity()));
List<SystemProductLineVo> options = new ArrayList<>();
for (SystemDeptTb dept : depts) {
// 构建部门ID路径
List<Long> pathIds = new ArrayList<>();
buildDeptIdPath(dept, deptMap, pathIds);
// 反转路径,从顶级部门到当前部门
Collections.reverse(pathIds);
SystemProductLineVo dto = new SystemProductLineVo();
dto.setValue(dept.getId());
dto.setIdPath(pathIds.stream().map(String::valueOf).collect(Collectors.joining("-")));
// 保留名称路径用于显示
dto.setLabel(buildNamePath(dept, deptMap));
options.add(dto);
}
// 按部门名称路径排序
options.sort(Comparator.comparing(SystemProductLineVo::getLabel));
return options;
}
private void buildDeptIdPath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<Long> pathIds) {
pathIds.add(dept.getId());
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) {
buildDeptIdPath(deptMap.get(dept.getPid()), deptMap, pathIds);
}
}
private String buildNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) {
List<String> pathNames = new ArrayList<>();
buildDeptNamePath(dept, deptMap, pathNames);
Collections.reverse(pathNames);
return String.join(" / ", pathNames);
}
private void buildDeptNamePath(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap, List<String> pathNames) {
pathNames.add(dept.getName());
if (dept.getPid() != null && dept.getPid() != 0 && deptMap.containsKey(dept.getPid())) {
buildDeptNamePath(deptMap.get(dept.getPid()), deptMap, pathNames);
}
}
public List<SystemProductLineTreeVo> listDeptSelectProDataSource() {
List<SystemDeptTb> depts = this.listEnabledDepts();
// 获取所有部门并按父子关系组织
Map<Long, SystemDeptTb> deptMap =
depts.stream().collect(Collectors.toMap(SystemDeptTb::getId, Function.identity()));
List<SystemProductLineTreeVo> options = new ArrayList<>();
// 构建树形结构
for (SystemDeptTb dept : depts) {
// 只处理顶级部门(pid为null或0的部门)
if (dept.getPid() == null || dept.getPid() == 0) {
SystemProductLineTreeVo vo = buildDeptTreePro(dept, deptMap);
options.add(vo);
}
}
// 按排序字段排序
options.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
return options;
}
/**
* 递归构建部门树
*
* @param dept 当前部门
* @param deptMap 部门映射
* @return SystemProductLineTreeVo 树节点
*/
private SystemProductLineTreeVo buildDeptTreePro(SystemDeptTb dept, Map<Long, SystemDeptTb> deptMap) {
SystemProductLineTreeVo vo = new SystemProductLineTreeVo();
vo.setValue(String.valueOf(dept.getId()));
vo.setLabel(dept.getName());
// 查找子部门
List<SystemProductLineTreeVo> children = new ArrayList<>();
for (SystemDeptTb childDept : deptMap.values()) {
if (dept.getId().equals(childDept.getPid())) {
children.add(buildDeptTreePro(childDept, deptMap));
}
}
// 子部门按排序字段排序
children.sort(Comparator.comparingInt(o -> {
Long id = Long.valueOf(o.getValue());
return deptMap.get(id) != null ? deptMap.get(id).getDeptSort() : 0;
}));
vo.setChildren(children);
return vo;
}
public List<SystemDeptTb> listDeptByPid(long pid) {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getPid, pid);
return systemDeptMapper.selectList(wrapper);
}
public void exportDeptXlsx(HttpServletResponse response, SystemQueryDeptArgs args) throws Exception {
List<SystemDeptTb> systemDeptTbs = this.queryAllDeptByArgs(args, false);
List<SystemDeptExportRowVo> rowVos = new ArrayList<>();
for (SystemDeptTb dataObject : systemDeptTbs) {
SystemDeptExportRowVo rowVo = new SystemDeptExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setEnabled(dataObject.getEnabled() ? SystemZhConst.ENABLE_STR : SystemZhConst.DISABLE_STR);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "部门数据", SystemDeptExportRowVo.class, rowVos);
}
public List<SystemDeptTb> listPidNonNull() {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getEnabled, 1);
wrapper.isNotNull(SystemDeptTb::getPid);
return systemDeptMapper.selectList(wrapper);
}
} }
@@ -31,120 +31,122 @@ import cn.odboy.util.KitValidUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemDictDetailService { public class SystemDictDetailService {
@Autowired @Autowired
private SystemDictDetailMapper systemDictDetailMapper; private SystemDictDetailMapper systemDictDetailMapper;
@Autowired @Autowired
private SystemDictMapper systemDictMapper; private SystemDictMapper systemDictMapper;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveDictDetail(SystemCreateDictDetailArgs args) { public void saveDictDetail(SystemCreateDictDetailArgs args) {
KitValidUtil.notNull(args); KitValidUtil.notNull(args);
KitValidUtil.notNull(args.getDict()); KitValidUtil.notNull(args.getDict());
SystemDictDetailTb dictDetail = KitBeanUtil.copyToClass(args, SystemDictDetailTb.class); SystemDictDetailTb dictDetail = KitBeanUtil.copyToClass(args, SystemDictDetailTb.class);
dictDetail.setDictId(args.getDict().getId()); dictDetail.setDictId(args.getDict().getId());
systemDictDetailMapper.insert(dictDetail); systemDictDetailMapper.insert(dictDetail);
}
/**
* 编辑
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateDictDetailById(SystemDictDetailTb args) {
SystemDictDetailTb dictDetail = systemDictDetailMapper.selectById(args.getId());
args.setId(dictDetail.getId());
systemDictDetailMapper.insertOrUpdate(args);
}
/**
* 删除
*
* @param id /
*/
@Transactional(rollbackFor = Exception.class)
public void deleteDictDetailById(Long id) {
systemDictDetailMapper.deleteById(id);
}
@Transactional(rollbackFor = Exception.class)
public void deleteDictDetailByDictIds(Set<Long> ids) {
if (CollUtil.isNotEmpty(ids)) {
LambdaQueryWrapper<SystemDictDetailTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemDictDetailTb::getDictId, ids);
systemDictDetailMapper.delete(wrapper);
} }
}
private List<SystemDictDetailTb> listDictDetailByDictId(Long dictId) { /**
LambdaQueryWrapper<SystemDictDetailTb> wrapper = new LambdaQueryWrapper<>(); * 编辑 -> TestPassed
wrapper.eq(SystemDictDetailTb::getDictId, dictId); *
return systemDictDetailMapper.selectList(wrapper); * @param args /
} */
@Transactional(rollbackFor = Exception.class)
public void updateDictDetailById(SystemDictDetailTb args) {
SystemDictDetailTb dictDetail = systemDictDetailMapper.selectById(args.getId());
args.setId(dictDetail.getId());
systemDictDetailMapper.insertOrUpdate(args);
}
/** /**
* 分页查询 * 删除 -> TestPassed
* *
* @param args 条件 * @param id /
* @param page 分页参数 */
* @return / @Transactional(rollbackFor = Exception.class)
*/ public void deleteDictDetailById(Long id) {
public KitPageResult<SystemDictDetailVo> searchDictDetail(SystemQueryDictDetailArgs args, Page<SystemDictDetailTb> page) { systemDictDetailMapper.deleteById(id);
IPage<SystemDictDetailVo> iPage = systemDictDetailMapper.selectPageByArgs(page, args).convert(i -> KitBeanUtil.copyToClass(i, SystemDictDetailVo.class));
List<Long> dictIds = iPage.getRecords().stream().map(SystemDictDetailVo::getDictId).collect(Collectors.toList());
Map<Long, SystemDictTb> id2ItemMap = systemDictMapper.selectByIds(dictIds).stream().collect(Collectors.toMap(SystemDictTb::getId, i -> i));
for (SystemDictDetailVo record : iPage.getRecords()) {
record.setDict(id2ItemMap.get(record.getDictId()));
} }
return KitPageUtil.toPage(iPage);
}
/** @Transactional(rollbackFor = Exception.class)
* 根据字典名称获取字典详情 public void deleteDictDetailByDictIds(Set<Long> ids) {
* if (CollUtil.isNotEmpty(ids)) {
* @param name 字典名称 LambdaQueryWrapper<SystemDictDetailTb> wrapper = new LambdaQueryWrapper<>();
* @return / wrapper.in(SystemDictDetailTb::getDictId, ids);
*/ systemDictDetailMapper.delete(wrapper);
public List<SystemDictDetailVo> listDictDetailByName(String name) { }
if (StrUtil.isBlank(name)) {
return new ArrayList<>();
} }
SystemDictTb systemDictTb = systemDictMapper.getByName(name);
if (systemDictTb == null) {
return new ArrayList<>();
}
List<SystemDictDetailTb> detailTbs = this.listDictDetailByDictId(systemDictTb.getId());
List<SystemDictDetailVo> detailVos = KitBeanUtil.copyToList(detailTbs, SystemDictDetailVo.class);
for (SystemDictDetailVo detailVo : detailVos) {
detailVo.setDict(systemDictTb);
}
return detailVos;
}
public Map<String, List<SystemDictDetailVo>> getDictDetailMap(String dictName) { /**
String[] names = dictName.split("[,, ]"); * 分页查询 -> TestPassed
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16); *
for (String name : names) { * @param args 条件
dictMap.put(name, this.listDictDetailByName(name)); * @param page 分页参数
* @return /
*/
public KitPageResult<SystemDictDetailVo> searchDictDetail(SystemQueryDictDetailArgs args,
Page<SystemDictDetailTb> page) {
IPage<SystemDictDetailVo> iPage = systemDictDetailMapper.selectPageByArgs(page, args);
List<Long> dictIds =
iPage.getRecords().stream().map(SystemDictDetailVo::getDictId).collect(Collectors.toList());
if (CollUtil.isNotEmpty(dictIds)) {
Map<Long, SystemDictTb> id2ItemMap =
systemDictMapper.selectByIds(dictIds).stream().collect(Collectors.toMap(SystemDictTb::getId, i -> i));
for (SystemDictDetailVo record : iPage.getRecords()) {
record.setDict(id2ItemMap.get(record.getDictId()));
}
}
return KitPageUtil.toPage(iPage);
}
/**
* 根据字典名称获取字典详情 -> TestPassed
*
* @param name 字典名称
* @return /
*/
public List<SystemDictDetailVo> listDictDetailByName(String name) {
if (StrUtil.isBlank(name)) {
return new ArrayList<>();
}
List<SystemDictDetailVo> detailVos = systemDictDetailMapper.listDictDetailByName(name);
if (CollUtil.isNotEmpty(detailVos)) {
SystemDictDetailVo systemDictDetailVo = detailVos.stream().findFirst().orElse(null);
if (systemDictDetailVo != null) {
SystemDictTb systemDictTb = systemDictMapper.selectById(systemDictDetailVo.getDictId());
if (systemDictTb != null) {
for (SystemDictDetailVo detailVo : detailVos) {
detailVo.setDict(systemDictTb);
}
}
}
}
return detailVos;
}
public Map<String, List<SystemDictDetailVo>> getDictDetailMap(String dictName) {
String[] names = dictName.split("[,, ]");
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, this.listDictDetailByName(name));
}
return dictMap;
} }
return dictMap;
}
} }
@@ -29,111 +29,111 @@ import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemDictService { public class SystemDictService {
@Autowired @Autowired
private SystemDictMapper systemDictMapper; private SystemDictMapper systemDictMapper;
@Autowired @Autowired
private SystemDictDetailService systemDictDetailService; private SystemDictDetailService systemDictDetailService;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveDict(SystemCreateDictArgs args) { public void saveDict(SystemCreateDictArgs args) {
SystemDictTb dictTb = KitBeanUtil.copyToClass(args, SystemDictTb.class); SystemDictTb dictTb = KitBeanUtil.copyToClass(args, SystemDictTb.class);
systemDictMapper.insert(dictTb); systemDictMapper.insert(dictTb);
}
/**
* 编辑
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateDictById(SystemDictTb args) {
SystemDictTb dict = systemDictMapper.selectById(args.getId());
dict.setName(args.getName());
dict.setDescription(args.getDescription());
systemDictMapper.insertOrUpdate(dict);
}
/**
* 删除
*
* @param ids /
*/
@Transactional(rollbackFor = Exception.class)
public void deleteDictByIds(Set<Long> ids) {
// 删除字典
systemDictMapper.deleteByIds(ids);
// 删除字典详情
systemDictDetailService.deleteDictDetailByDictIds(ids);
}
/**
* 分页查询
*
* @param args 条件
* @param page 分页参数
* @return /
*/
public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page) {
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage);
}
private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) {
if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemDictTb::getName, args.getBlurry()).or()
.like(SystemDictTb::getDescription, args.getBlurry()));
} }
}
public List<SystemDictTb> queryDictByArgs(SystemQueryDictArgs args) { /**
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>(); * 编辑 -> TestPassed
this.injectQueryParams(args, wrapper); *
return systemDictMapper.selectList(wrapper); * @param args /
} */
@Transactional(rollbackFor = Exception.class)
public void updateDictById(SystemDictTb args) {
SystemDictTb dict = systemDictMapper.selectById(args.getId());
dict.setName(args.getName());
dict.setDescription(args.getDescription());
systemDictMapper.insertOrUpdate(dict);
}
public void exportDictXlsx(HttpServletResponse response, SystemQueryDictArgs args) { /**
List<SystemDictTb> systemDictTbs = this.queryDictByArgs(args); * 删除 -> TestPassed
List<SystemDictExportRowVo> rowVos = new ArrayList<>(); *
for (SystemDictTb dataObject : systemDictTbs) { * @param ids /
List<SystemDictDetailVo> dictDetails = systemDictDetailService.listDictDetailByName(dataObject.getName()); */
if (CollUtil.isEmpty(dictDetails)) { @Transactional(rollbackFor = Exception.class)
SystemDictExportRowVo rowVo = new SystemDictExportRowVo(); public void deleteDictByIds(Set<Long> ids) {
rowVo.setName(dataObject.getName()); // 删除字典
rowVo.setDescription(dataObject.getDescription()); systemDictMapper.deleteByIds(ids);
rowVo.setCreateTime(dataObject.getCreateTime()); // 删除字典详情
rowVo.setLabel(""); systemDictDetailService.deleteDictDetailByDictIds(ids);
rowVo.setValue(""); }
rowVos.add(rowVo);
continue; /**
} * 分页查询 -> TestPassed
for (SystemDictDetailVo dictDetail : dictDetails) { *
SystemDictExportRowVo rowVo = new SystemDictExportRowVo(); * @param args 条件
rowVo.setName(dataObject.getName()); * @param page 分页参数
rowVo.setDescription(dataObject.getDescription()); * @return /
rowVo.setCreateTime(dataObject.getCreateTime()); */
rowVo.setLabel(dictDetail.getLabel()); public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page) {
rowVo.setValue(dictDetail.getValue()); LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>();
rowVos.add(rowVo); this.injectQueryParams(args, wrapper);
} Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage);
}
private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) {
if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemDictTb::getName, args.getBlurry()).or()
.like(SystemDictTb::getDescription, args.getBlurry()));
}
}
public List<SystemDictTb> queryDictByArgs(SystemQueryDictArgs args) {
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
return systemDictMapper.selectList(wrapper);
}
public void exportDictXlsx(HttpServletResponse response, SystemQueryDictArgs args) {
List<SystemDictTb> systemDictTbs = this.queryDictByArgs(args);
List<SystemDictExportRowVo> rowVos = new ArrayList<>();
for (SystemDictTb dataObject : systemDictTbs) {
List<SystemDictDetailVo> dictDetails = systemDictDetailService.listDictDetailByName(dataObject.getName());
if (CollUtil.isEmpty(dictDetails)) {
SystemDictExportRowVo rowVo = new SystemDictExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVo.setLabel("");
rowVo.setValue("");
rowVos.add(rowVo);
continue;
}
for (SystemDictDetailVo dictDetail : dictDetails) {
SystemDictExportRowVo rowVo = new SystemDictExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVo.setLabel(dictDetail.getLabel());
rowVo.setValue(dictDetail.getValue());
rowVos.add(rowVo);
}
}
KitExcelExporter.exportSimple(response, "字典数据", SystemDictExportRowVo.class, rowVos);
} }
KitExcelExporter.exportSimple(response, "字典数据", SystemDictExportRowVo.class, rowVos);
}
} }
@@ -30,134 +30,134 @@ import cn.odboy.system.dal.model.request.SystemSendEmailArgs;
import cn.odboy.system.dal.mysql.SystemEmailConfigMapper; import cn.odboy.system.dal.mysql.SystemEmailConfigMapper;
import cn.odboy.util.KitDesEncryptUtil; import cn.odboy.util.KitDesEncryptUtil;
import cn.odboy.util.KitResourceTemplateUtil; import cn.odboy.util.KitResourceTemplateUtil;
import java.util.Collections;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
@Slf4j @Slf4j
@Service @Service
public class SystemEmailService { public class SystemEmailService {
@Autowired @Autowired
private SystemEmailConfigMapper systemEmailConfigMapper; private SystemEmailConfigMapper systemEmailConfigMapper;
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
/** /**
* 更新邮件配置 * 更新邮件配置 -> TestPassed
* *
* @param emailConfig 邮箱配置 * @param emailConfig 邮箱配置
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateEmailConfigById(SystemEmailConfigTb emailConfig) throws Exception { public void updateEmailConfigById(SystemEmailConfigTb emailConfig) throws Exception {
SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig(); SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig();
if (!emailConfig.getPassword().equals(systemEmailConfigTb.getPassword())) { if (!emailConfig.getPassword().equals(systemEmailConfigTb.getPassword())) {
// 对称加密 // 对称加密
systemEmailConfigTb.setPassword(KitDesEncryptUtil.desEncrypt(emailConfig.getPassword())); systemEmailConfigTb.setPassword(KitDesEncryptUtil.desEncrypt(emailConfig.getPassword()));
}
systemEmailConfigTb.setId(1L);
systemEmailConfigMapper.insertOrUpdate(systemEmailConfigTb);
} }
systemEmailConfigTb.setId(1L);
systemEmailConfigMapper.insertOrUpdate(systemEmailConfigTb);
}
/** /**
* 发送邮件 * 发送邮件 -> TestPassed
* *
* @param sendEmailRequest 邮件发送的内容 * @param sendEmailRequest 邮件发送的内容
*/ */
public void sendEmail(SystemSendEmailArgs sendEmailRequest) { public void sendEmail(SystemSendEmailArgs sendEmailRequest) {
SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig(); SystemEmailConfigTb systemEmailConfigTb = getLastEmailConfig();
if (systemEmailConfigTb.getId() == null) { if (systemEmailConfigTb.getId() == null) {
throw new BadRequestException("请先配置, 再操作"); throw new BadRequestException("请先配置, 再操作");
}
// 封装
MailAccount account = new MailAccount();
// 设置用户
String user = systemEmailConfigTb.getFromUser().split("@")[0];
account.setUser(user);
account.setHost(systemEmailConfigTb.getHost());
account.setPort(Integer.parseInt(systemEmailConfigTb.getPort()));
account.setAuth(true);
try {
// 对称解密
account.setPass(KitDesEncryptUtil.desDecrypt(systemEmailConfigTb.getPassword()));
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
account.setFrom(systemEmailConfigTb.getUser() + "<" + systemEmailConfigTb.getFromUser() + ">");
// ssl方式发送
account.setSslEnable(true);
// 使用STARTTLS安全连接
account.setStarttlsEnable(true);
// 解决jdk8之后默认禁用部分tls协议, 导致邮件发送失败的问题
account.setSslProtocols("TLSv1 TLSv1.1 TLSv1.2");
String content = sendEmailRequest.getContent();
// 发送
try {
int size = sendEmailRequest.getTos().size();
Mail.create(account).setTos(sendEmailRequest.getTos().toArray(new String[size]))
.setTitle(sendEmailRequest.getSubject()).setContent(content).setHtml(true)
// 关闭session
.setUseGlobalSession(false).send();
} catch (Exception e) {
log.error("邮件发送失败", e);
throw new BadRequestException("邮件发送失败");
}
} }
// 封装
MailAccount account = new MailAccount();
// 设置用户
String user = systemEmailConfigTb.getFromUser().split("@")[0];
account.setUser(user);
account.setHost(systemEmailConfigTb.getHost());
account.setPort(Integer.parseInt(systemEmailConfigTb.getPort()));
account.setAuth(true);
try {
// 对称解密
account.setPass(KitDesEncryptUtil.desDecrypt(systemEmailConfigTb.getPassword()));
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
account.setFrom(systemEmailConfigTb.getUser() + "<" + systemEmailConfigTb.getFromUser() + ">");
// ssl方式发送
account.setSslEnable(true);
// 使用STARTTLS安全连接
account.setStarttlsEnable(true);
// 解决jdk8之后默认禁用部分tls协议, 导致邮件发送失败的问题
account.setSslProtocols("TLSv1 TLSv1.1 TLSv1.2");
String content = sendEmailRequest.getContent();
// 发送
try {
int size = sendEmailRequest.getTos().size();
Mail.create(account).setTos(sendEmailRequest.getTos().toArray(new String[size]))
.setTitle(sendEmailRequest.getSubject()).setContent(content).setHtml(true)
// 关闭session
.setUseGlobalSession(false).send();
} catch (Exception e) {
log.error("邮件发送失败", e);
throw new BadRequestException("邮件发送失败");
}
}
/** /**
* 校验邮箱验证码 * 校验邮箱验证码 -> TestPassed
*/ */
public void checkEmailCaptchaV1(SystemCaptchaBizEnum biEnum, String email, String code) { public void checkEmailCaptchaV1(SystemCaptchaBizEnum biEnum, String email, String code) {
String redisKey = biEnum.getRedisKey() + email; String redisKey = biEnum.getRedisKey() + email;
String value = redisHelper.get(redisKey, String.class); String value = redisHelper.get(redisKey, String.class);
if (value == null || !value.equals(code)) { if (value == null || !value.equals(code)) {
throw new BadRequestException("无效验证码"); throw new BadRequestException("无效验证码");
} else { } else {
redisHelper.del(redisKey); redisHelper.del(redisKey);
}
} }
}
/** /**
* 发送给邮箱验证码 * 发送给邮箱验证码
*/ */
public void sendCaptcha(SystemCaptchaBizEnum biEnum, String email) { public void sendCaptcha(SystemCaptchaBizEnum biEnum, String email) {
if (biEnum == null) { if (biEnum == null) {
throw new BadRequestException("biEnum必填"); throw new BadRequestException("biEnum必填");
}
String content;
String redisKey = biEnum.getRedisKey() + email;
String oldCode = redisHelper.get(redisKey, String.class);
if (oldCode == null) {
String code = RandomUtil.randomNumbers(6);
// 存入缓存
if (!redisHelper.set(redisKey, code, properties.getCaptcha().getExpireTime())) {
throw new BadRequestException("服务异常, 请联系网站负责人");
}
// 存在就再次发送原来的验证码
content = KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", code));
} else {
content =
KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", oldCode));
}
SystemSendEmailArgs sendEmailRequest =
new SystemSendEmailArgs(Collections.singletonList(email), SystemConst.CURRENT_APP_TITLE, content);
sendEmail(sendEmailRequest);
} }
String content;
String redisKey = biEnum.getRedisKey() + email;
String oldCode = redisHelper.get(redisKey, String.class);
if (oldCode == null) {
String code = RandomUtil.randomNumbers(6);
// 存入缓存
if (!redisHelper.set(redisKey, code, properties.getCaptcha().getExpireTime())) {
throw new BadRequestException("服务异常, 请联系网站负责人");
}
// 存在就再次发送原来的验证码
content = KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", code));
} else {
content =
KitResourceTemplateUtil.render(null, biEnum.getTemplateName(), Dict.create().set("code", oldCode));
}
SystemSendEmailArgs sendEmailRequest =
new SystemSendEmailArgs(Collections.singletonList(email), SystemConst.CURRENT_APP_TITLE, content);
sendEmail(sendEmailRequest);
}
public SystemEmailConfigTb getLastEmailConfig() { public SystemEmailConfigTb getLastEmailConfig() {
SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L); SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L);
return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb; return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb;
} }
public void checkEmailCaptcha(SystemCheckEmailCaptchaArgs args) { public void checkEmailCaptcha(SystemCheckEmailCaptchaArgs args) {
SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode()); SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode());
if (biEnum == null) { if (biEnum == null) {
throw new BadRequestException("不支持的业务"); throw new BadRequestException("不支持的业务");
}
this.checkEmailCaptchaV1(biEnum, args.getEmail(), args.getCode());
} }
this.checkEmailCaptchaV1(biEnum, args.getEmail(), args.getCode());
}
} }
@@ -29,130 +29,129 @@ import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemJobService { public class SystemJobService {
@Autowired @Autowired
private SystemJobMapper systemJobMapper; private SystemJobMapper systemJobMapper;
@Autowired @Autowired
private SystemUserJobService systemUserJobService; private SystemUserJobService systemUserJobService;
/** /**
* 创建 * 创建 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveJob(SystemCreateJobArgs args) { public void saveJob(SystemCreateJobArgs args) {
SystemJobTb job = this.getJobByName(args.getName()); SystemJobTb job = this.getJobByName(args.getName());
if (job != null) { if (job != null) {
throw new BadRequestException("职位名称已存在"); throw new BadRequestException("职位名称已存在");
}
SystemJobTb systemJobTb = KitBeanUtil.copyToClass(args, SystemJobTb.class);
systemJobMapper.insert(systemJobTb);
} }
SystemJobTb systemJobTb = KitBeanUtil.copyToClass(args, SystemJobTb.class);
systemJobMapper.insert(systemJobTb);
}
/** /**
* 编辑 * 编辑 -> TestPassed
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateJobById(SystemJobTb args) { public void updateJobById(SystemJobTb args) {
SystemJobTb job = systemJobMapper.selectById(args.getId()); SystemJobTb job = systemJobMapper.selectById(args.getId());
SystemJobTb old = this.getJobByName(args.getName()); SystemJobTb old = this.getJobByName(args.getName());
if (old != null && !old.getId().equals(args.getId())) { if (old != null && !old.getId().equals(args.getId())) {
throw new BadRequestException("职位名称已存在"); throw new BadRequestException("职位名称已存在");
}
args.setId(job.getId());
systemJobMapper.updateById(args);
} }
args.setId(job.getId());
systemJobMapper.insertOrUpdate(args);
}
/** /**
* 删除 * 删除 -> TestPassed
* *
* @param ids / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Set<Long> ids) { public void deleteJobByIds(Set<Long> ids) {
// 验证是否被用户关联 // 验证是否被用户关联
this.verifyBindRelationByIds(ids); this.verifyBindRelationByIds(ids);
systemJobMapper.deleteByIds(ids); systemJobMapper.deleteByIds(ids);
}
/**
* 分页查询
*
* @param args 条件
* @param page 分页参数
*/
public KitPageResult<SystemJobTb> searchJobByArgs(SystemQueryJobArgs args, Page<SystemJobTb> page) {
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
Page<SystemJobTb> selectPage = systemJobMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage);
}
/**
* 查询全部数据
*/
public List<SystemJobTb> queryJobByArgs(SystemQueryJobArgs args) {
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper);
return systemJobMapper.selectList(wrapper);
}
/**
* 验证是否被用户关联
*
* @param ids /
*/
public void verifyBindRelationByIds(Set<Long> ids) {
if (systemUserJobService.countUserByJobIds(ids) > 0) {
throw new BadRequestException("所选的岗位中存在用户关联, 请解除关联再试!");
} }
}
public SystemJobTb getJobByName(String name) { /**
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>(); * 分页查询 -> TestPassed
wrapper.eq(SystemJobTb::getName, name); *
return systemJobMapper.selectOne(wrapper); * @param args 条件
} * @param page 分页参数
*/
public void injectQueryParams(SystemQueryJobArgs args, LambdaQueryWrapper<SystemJobTb> wrapper) { public KitPageResult<SystemJobTb> searchJobByArgs(SystemQueryJobArgs args, Page<SystemJobTb> page) {
if (args != null) { LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemJobTb::getName, args.getName()); this.injectQueryParams(args, wrapper);
wrapper.eq(args.getEnabled() != null, SystemJobTb::getEnabled, args.getEnabled()); Page<SystemJobTb> selectPage = systemJobMapper.selectPage(page, wrapper);
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { return KitPageUtil.toPage(selectPage);
wrapper.between(SystemJobTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
} }
wrapper.orderByDesc(SystemJobTb::getJobSort, SystemJobTb::getId);
}
public void exportJobXlsx(HttpServletResponse response, SystemQueryJobArgs args) { /**
List<SystemJobTb> systemJobTbs = this.queryJobByArgs(args); * 查询全部数据 -> TestPassed
List<SystemJobExportRowVo> rowVos = new ArrayList<>(); */
for (SystemJobTb dataObject : systemJobTbs) { public List<SystemJobTb> queryJobByArgs(SystemQueryJobArgs args) {
SystemJobExportRowVo rowVo = new SystemJobExportRowVo(); LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
rowVo.setName(dataObject.getName()); this.injectQueryParams(args, wrapper);
rowVo.setEnabled(dataObject.getEnabled() ? "启用" : "停用"); return systemJobMapper.selectList(wrapper);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
} }
KitExcelExporter.exportSimple(response, "岗位数据", SystemJobExportRowVo.class, rowVos);
}
public List<SystemJobTb> listByIds(Set<Long> jobIds) { /**
return systemJobMapper.selectByIds(jobIds); * 验证是否被用户关联 -> TestPassed
} *
* @param ids /
*/
public void verifyBindRelationByIds(Set<Long> ids) {
if (systemUserJobService.countUserByJobIds(ids) > 0) {
throw new BadRequestException("所选的岗位中存在用户关联, 请解除关联再试!");
}
}
public SystemJobTb getJobByName(String name) {
LambdaQueryWrapper<SystemJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemJobTb::getName, name);
return systemJobMapper.selectOne(wrapper);
}
public void injectQueryParams(SystemQueryJobArgs args, LambdaQueryWrapper<SystemJobTb> wrapper) {
if (args != null) {
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemJobTb::getName, args.getName());
wrapper.eq(args.getEnabled() != null, SystemJobTb::getEnabled, args.getEnabled());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemJobTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
}
}
wrapper.orderByDesc(SystemJobTb::getJobSort, SystemJobTb::getId);
}
public void exportJobXlsx(HttpServletResponse response, SystemQueryJobArgs args) {
List<SystemJobTb> systemJobTbs = this.queryJobByArgs(args);
List<SystemJobExportRowVo> rowVos = new ArrayList<>();
for (SystemJobTb dataObject : systemJobTbs) {
SystemJobExportRowVo rowVo = new SystemJobExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setEnabled(dataObject.getEnabled() ? "启用" : "停用");
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "岗位数据", SystemJobExportRowVo.class, rowVos);
}
public List<SystemJobTb> listByIds(Set<Long> jobIds) {
return systemJobMapper.selectByIds(jobIds);
}
} }
@@ -36,142 +36,142 @@ import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.io.File;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.List;
@Service @Service
public class SystemLocalStorageService { public class SystemLocalStorageService {
@Autowired @Autowired
private SystemLocalStorageMapper systemLocalStorageMapper; private SystemLocalStorageMapper systemLocalStorageMapper;
@Autowired @Autowired
private KitFileLocalUploadHelper fileUploadPathHelper; private KitFileLocalUploadHelper fileUploadPathHelper;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
/** /**
* 上传 * 上传 -> TestPassed
* *
* @param name 文件名称 * @param name 文件名称
* @param multipartFile 文件 * @param multipartFile 文件
* @return / * @return /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public SystemLocalStorageTb uploadFile(String name, MultipartFile multipartFile) { public SystemLocalStorageTb uploadFile(String name, MultipartFile multipartFile) {
long size = multipartFile.getSize(); long size = multipartFile.getSize();
KitFileUtil.checkSize(properties.getOss().getMaxSize(), size); KitFileUtil.checkSize(properties.getOss().getMaxSize(), size);
String suffix = KitFileUtil.getSuffix(multipartFile.getOriginalFilename()); String suffix = KitFileUtil.getSuffix(multipartFile.getOriginalFilename());
String type = KitFileUtil.getFileType(suffix); String type = KitFileUtil.getFileType(suffix);
String uploadDateStr = DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT); String uploadDateStr = DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT);
File file = KitFileUtil.upload(multipartFile, fileUploadPathHelper.getPath() + uploadDateStr + File.separator); File file = KitFileUtil.upload(multipartFile, fileUploadPathHelper.getPath() + uploadDateStr + File.separator);
if (file == null) { if (file == null) {
throw new BadRequestException("上传失败"); throw new BadRequestException("上传失败");
}
try {
String formatSize = KitFileUtil.getSize(size);
String prefixName =
StrUtil.isBlank(name) ? KitFileUtil.getPrefix(multipartFile.getOriginalFilename()) : name;
SystemLocalStorageTb localStorage = new SystemLocalStorageTb();
localStorage.setRealName(file.getName());
localStorage.setName(prefixName);
localStorage.setSuffix(suffix);
localStorage.setPath(file.getPath());
localStorage.setType(type);
localStorage.setSize(formatSize);
localStorage.setDateGroup(uploadDateStr);
systemLocalStorageMapper.insert(localStorage);
return localStorage;
} catch (Exception e) {
KitFileUtil.del(file);
throw e;
}
} }
try {
String formatSize = KitFileUtil.getSize(size); /**
String prefixName = * 编辑 -> TestPassed
StrUtil.isBlank(name) ? KitFileUtil.getPrefix(multipartFile.getOriginalFilename()) : name; *
SystemLocalStorageTb localStorage = new SystemLocalStorageTb(); * @param args 文件信息
localStorage.setRealName(file.getName()); */
localStorage.setName(prefixName); @Transactional(rollbackFor = Exception.class)
localStorage.setSuffix(suffix); public void updateLocalStorageById(SystemLocalStorageTb args) {
localStorage.setPath(file.getPath()); SystemLocalStorageTb localStorage = systemLocalStorageMapper.selectById(args.getId());
localStorage.setType(type); localStorage.copy(args);
localStorage.setSize(formatSize); systemLocalStorageMapper.insertOrUpdate(localStorage);
localStorage.setDateGroup(uploadDateStr);
systemLocalStorageMapper.insert(localStorage);
return localStorage;
} catch (Exception e) {
KitFileUtil.del(file);
throw e;
} }
}
/** /**
* 编辑 * 多选删除 -> TestPassed
* *
* @param args 文件信息 * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateLocalStorageById(SystemLocalStorageTb args) { public void deleteFileByIds(Long[] ids) {
SystemLocalStorageTb localStorage = systemLocalStorageMapper.selectById(args.getId()); for (Long id : ids) {
localStorage.copy(args); SystemLocalStorageTb storage = systemLocalStorageMapper.selectById(id);
systemLocalStorageMapper.insertOrUpdate(localStorage); try {
} KitFileUtil.del(storage.getPath());
systemLocalStorageMapper.deleteById(storage);
/** } catch (IORuntimeException e) {
* 多选删除 throw new BadRequestException("删除文件 " + storage.getName() + " 失败");
* }
* @param ids / }
*/
@Transactional(rollbackFor = Exception.class)
public void deleteFileByIds(Long[] ids) {
for (Long id : ids) {
SystemLocalStorageTb storage = systemLocalStorageMapper.selectById(id);
try {
KitFileUtil.del(storage.getPath());
systemLocalStorageMapper.deleteById(storage);
} catch (IORuntimeException e) {
throw new BadRequestException("删除文件 " + storage.getName() + " 失败");
}
} }
}
/** /**
* 分页查询 * 分页查询 -> TestPassed
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @return / * @return /
*/ */
public KitPageResult<SystemLocalStorageTb> searchLocalStorage(SystemQueryStorageArgs args, public KitPageResult<SystemLocalStorageTb> searchLocalStorage(SystemQueryStorageArgs args,
Page<SystemLocalStorageTb> page) { Page<SystemLocalStorageTb> page) {
LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>();
this.injectQueryParams(args, wrapper); this.injectQueryParams(args, wrapper);
Page<SystemLocalStorageTb> selectPage = systemLocalStorageMapper.selectPage(page, wrapper); Page<SystemLocalStorageTb> selectPage = systemLocalStorageMapper.selectPage(page, wrapper);
return KitPageUtil.toPage(selectPage); return KitPageUtil.toPage(selectPage);
}
private void injectQueryParams(SystemQueryStorageArgs args, LambdaQueryWrapper<SystemLocalStorageTb> wrapper) {
if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemLocalStorageTb::getName, args.getBlurry()).or()
.like(SystemLocalStorageTb::getSuffix, args.getBlurry()).or()
.like(SystemLocalStorageTb::getType, args.getBlurry()).or()
.like(SystemLocalStorageTb::getCreateBy, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemLocalStorageTb::getUpdateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
} }
wrapper.orderByDesc(SystemLocalStorageTb::getId);
}
public List<SystemLocalStorageTb> queryLocalStorageByArgs(SystemQueryStorageArgs args) { private void injectQueryParams(SystemQueryStorageArgs args, LambdaQueryWrapper<SystemLocalStorageTb> wrapper) {
LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>(); if (args != null) {
this.injectQueryParams(args, wrapper); wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
return systemLocalStorageMapper.selectList(wrapper); c -> c.like(SystemLocalStorageTb::getName, args.getBlurry()).or()
} .like(SystemLocalStorageTb::getSuffix, args.getBlurry()).or()
.like(SystemLocalStorageTb::getType, args.getBlurry()).or()
.like(SystemLocalStorageTb::getCreateBy, args.getBlurry()));
public SystemLocalStorageTb uploadPictureV1(MultipartFile file) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
// 判断文件是否为图片 wrapper.between(SystemLocalStorageTb::getUpdateTime, args.getCreateTime().get(0),
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename()); args.getCreateTime().get(1));
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) { }
throw new BadRequestException("只能上传图片"); }
wrapper.orderByDesc(SystemLocalStorageTb::getId);
} }
return KitSpringBeanHolder.getBean(SystemLocalStorageService.class).uploadFile(null, file);
}
public void exportLocalStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args) { public List<SystemLocalStorageTb> queryLocalStorageByArgs(SystemQueryStorageArgs args) {
List<SystemLocalStorageTb> systemLocalStorageTbs = this.queryLocalStorageByArgs(args); LambdaQueryWrapper<SystemLocalStorageTb> wrapper = new LambdaQueryWrapper<>();
List<SystemLocalStorageExportRowVo> rowVos = KitBeanUtil.copyToList(systemLocalStorageTbs, SystemLocalStorageExportRowVo.class); this.injectQueryParams(args, wrapper);
KitExcelExporter.exportSimple(response, "文件上传记录数据", SystemLocalStorageExportRowVo.class, rowVos); return systemLocalStorageMapper.selectList(wrapper);
} }
public SystemLocalStorageTb uploadPictureV1(MultipartFile file) {
// 判断文件是否为图片
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename());
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) {
throw new BadRequestException("只能上传图片");
}
return KitSpringBeanHolder.getBean(SystemLocalStorageService.class).uploadFile(null, file);
}
public void exportLocalStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args) {
List<SystemLocalStorageTb> systemLocalStorageTbs = this.queryLocalStorageByArgs(args);
List<SystemLocalStorageExportRowVo> rowVos =
KitBeanUtil.copyToList(systemLocalStorageTbs, SystemLocalStorageExportRowVo.class);
KitExcelExporter.exportSimple(response, "文件上传记录数据", SystemLocalStorageExportRowVo.class, rowVos);
}
} }
@@ -36,6 +36,10 @@ import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@@ -45,435 +49,428 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemMenuService { public class SystemMenuService {
@Autowired
private SystemMenuMapper systemMenuMapper;
@Autowired
private SystemRoleMenuService systemRoleMenuService;
@Autowired
private SystemUserRoleService systemUserRoleService;
@Autowired /**
private SystemMenuMapper systemMenuMapper; * 创建
@Autowired *
private SystemRoleMenuService systemRoleMenuService; * @param args /
@Autowired */
private SystemUserRoleService systemUserRoleService; @Transactional(rollbackFor = Exception.class)
public void saveMenu(SystemMenuTb args) {
/** if (this.getMenuByTitle(args.getTitle()) != null) {
* 创建 throw new BadRequestException("菜单标题已存在");
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void saveMenu(SystemMenuTb args) {
if (this.getMenuByTitle(args.getTitle()) != null) {
throw new BadRequestException("菜单标题已存在");
}
if (StrUtil.isNotBlank(args.getComponentName())) {
if (this.getMenuByComponentName(args.getComponentName()) != null) {
throw new BadRequestException("菜单组件名称已存在");
}
}
if (Long.valueOf(0L).equals(args.getPid())) {
args.setPid(null);
}
if (args.getIFrame()) {
if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) ||
args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
}
}
systemMenuMapper.insert(args);
// 计算子节点数目
args.setSubCount(0);
// 更新父节点菜单数目
this.updateMenuSubCnt(args.getPid());
}
/**
* 编辑
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateMenuById(SystemMenuTb args) {
if (args.getId().equals(args.getPid())) {
throw new BadRequestException("上级不能为自己");
}
SystemMenuTb menu = systemMenuMapper.selectById(args.getId());
if (args.getIFrame()) {
if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) ||
args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
}
}
SystemMenuTb menu1 = this.getMenuByTitle(args.getTitle());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单标题已存在");
}
if (args.getPid().equals(0L)) {
args.setPid(null);
}
// 记录的父节点ID
Long oldPid = menu.getPid();
Long newPid = args.getPid();
if (StrUtil.isNotBlank(args.getComponentName())) {
menu1 = this.getMenuByComponentName(args.getComponentName());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单组件名称已存在");
}
}
menu.setTitle(args.getTitle());
menu.setComponent(args.getComponent());
menu.setPath(args.getPath());
menu.setIcon(args.getIcon());
menu.setIFrame(args.getIFrame());
menu.setPid(args.getPid());
menu.setMenuSort(args.getMenuSort());
menu.setCache(args.getCache());
menu.setHidden(args.getHidden());
menu.setComponentName(args.getComponentName());
menu.setPermission(args.getPermission());
menu.setType(args.getType());
// auto fill
menu.setUpdateBy(null);
menu.setUpdateTime(null);
systemMenuMapper.insertOrUpdate(menu);
// 计算父级菜单节点数目
this.updateMenuSubCnt(oldPid);
this.updateMenuSubCnt(newPid);
}
/**
* 删除
*/
@Transactional(rollbackFor = Exception.class)
public void deleteMenuByIds(Set<Long> ids) {
Set<SystemMenuVo> menuSet = new HashSet<>();
for (Long id : ids) {
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
}
List<Long> menuIds =
menuSet.stream().map(SystemMenuVo::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(menuIds)) {
systemRoleMenuService.deleteRoleMenuByMenuIds(menuIds);
systemMenuMapper.deleteByIds(menuIds);
}
for (SystemMenuVo menu : menuSet) {
this.updateMenuSubCnt(menu.getPid());
}
}
private SystemMenuVo getMenuVoById(Long id) {
return KitBeanUtil.copyToClass(systemMenuMapper.selectById(id), SystemMenuVo.class);
}
@Transactional(rollbackFor = Exception.class)
public void updateMenuSubCnt(Long menuId) {
if (menuId != null) {
long count = this.countMenuByPid(menuId);
LambdaUpdateWrapper<SystemMenuTb> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(SystemMenuTb::getId, menuId);
wrapper.set(SystemMenuTb::getSubCount, count);
systemMenuMapper.update(wrapper);
}
}
/**
* 查询全部数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemMenuTb> queryAllMenu(SystemQueryMenuArgs args, Boolean isQuery) throws Exception {
if (Boolean.TRUE.equals(isQuery)) {
args.setPidIsNull(true);
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
for (Field field : fields) {
//设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if ("pidIsNull".equals(field.getName())) {
continue;
} }
// 如果有查询条件, 则不指定pidIsNull if (StrUtil.isNotBlank(args.getComponentName())) {
if (ObjectUtil.isNotNull(val)) { if (this.getMenuByComponentName(args.getComponentName()) != null) {
args.setPidIsNull(null); throw new BadRequestException("菜单组件名称已存在");
break; }
} }
} if (Long.valueOf(0L).equals(args.getPid())) {
} args.setPid(null);
return this.queryMenuByArgs(args);
}
/**
* 根据当前用户获取菜单
*
* @param currentUserId /
* @return /
*/
public List<SystemMenuVo> listMenuByUserId(Long currentUserId) {
List<SystemRoleVo> roles = systemUserRoleService.queryRoleVoByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(SystemRoleVo::getId).collect(Collectors.toSet());
return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds));
}
/**
* 获取所有子节点, 包含自身ID
*
* @param menuList /
* @param menuSet /
* @return /
*/
public Set<SystemMenuVo> queryChildMenuByArgs(List<SystemMenuVo> menuList, Set<SystemMenuVo> menuSet) {
for (SystemMenuVo menu : menuList) {
menuSet.add(menu);
List<SystemMenuVo> menus = this.listMenuByPid(menu.getId());
if (CollUtil.isNotEmpty(menus)) {
queryChildMenuByArgs(menus, menuSet);
}
}
return menuSet;
}
/**
* 懒加载菜单数据
*
* @param pid /
* @return /
*/
public List<SystemMenuVo> listMenuByPid(Long pid) {
List<SystemMenuVo> menus;
if (pid != null && !pid.equals(0L)) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getPid, pid);
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
} else {
menus = this.listRootMenu();
}
return menus;
}
/**
* 根据ID获取同级与上级数据
*
* @param menu /
* @param menus /
* @return /
*/
public List<SystemMenuVo> querySuperiorMenuByArgs(SystemMenuVo menu, List<SystemMenuVo> menus) {
if (menu.getPid() == null) {
menus.addAll(this.listRootMenu());
return menus;
}
menus.addAll(this.listMenuByPid(menu.getPid()));
return querySuperiorMenuByArgs(this.getMenuVoById(menu.getPid()), menus);
}
/**
* 构建菜单树
*
* @param menus 原始数据
* @return /
*/
public List<SystemMenuVo> buildMenuTree(List<SystemMenuVo> menus) {
List<SystemMenuVo> trees = new ArrayList<>();
Set<Long> ids = new HashSet<>();
for (SystemMenuVo menu : menus) {
if (menu.getPid() == null) {
trees.add(menu);
}
for (SystemMenuVo it : menus) {
if (menu.getId().equals(it.getPid())) {
if (menu.getChildren() == null) {
menu.setChildren(new ArrayList<>());
}
menu.getChildren().add(it);
ids.add(it.getId());
} }
} if (args.getIFrame()) {
if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) || args.getPath()
.toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
}
}
systemMenuMapper.insert(args);
// 计算子节点数目
args.setSubCount(0);
// 更新父节点菜单数目
this.updateMenuSubCnt(args.getPid());
} }
if (CollUtil.isNotEmpty(trees)) {
trees = menus.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
}
return trees;
}
/** /**
* 构建菜单树 * 编辑
* *
* @param menus / * @param args /
* @return / */
*/ @Transactional(rollbackFor = Exception.class)
public List<SystemMenuRouterVo> buildMenuVo(List<SystemMenuVo> menus) { public void updateMenuById(SystemMenuTb args) {
List<SystemMenuRouterVo> list = new LinkedList<>(); if (args.getId().equals(args.getPid())) {
for (SystemMenuVo menu : menus) { throw new BadRequestException("上级不能为自己");
if (menu != null) { }
List<SystemMenuVo> menuList = menu.getChildren(); SystemMenuTb menu = systemMenuMapper.selectById(args.getId());
SystemMenuRouterVo menuVo = new SystemMenuRouterVo(); if (args.getIFrame()) {
menuVo.setName( if (!(args.getPath().toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTP) || args.getPath()
ObjectUtil.isNotEmpty(menu.getComponentName()) ? menu.getComponentName() : menu.getTitle()); .toLowerCase().startsWith(SystemTransferProtocolConst.PREFIX_HTTPS))) {
// 一级目录需要加斜杠, 不然会报警告 throw new BadRequestException(SystemTransferProtocolConst.PREFIX_HTTPS_BAD_REQUEST);
menuVo.setPath(menu.getPid() == null ? "/" + menu.getPath() : menu.getPath()); }
menuVo.setHidden(menu.getHidden()); }
// 如果不是外链 SystemMenuTb menu1 = this.getMenuByTitle(args.getTitle());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单标题已存在");
}
if (args.getPid().equals(0L)) {
args.setPid(null);
}
// 记录的父节点ID
Long oldPid = menu.getPid();
Long newPid = args.getPid();
if (StrUtil.isNotBlank(args.getComponentName())) {
menu1 = this.getMenuByComponentName(args.getComponentName());
if (menu1 != null && !menu1.getId().equals(menu.getId())) {
throw new BadRequestException("菜单组件名称已存在");
}
}
menu.setTitle(args.getTitle());
menu.setComponent(args.getComponent());
menu.setPath(args.getPath());
menu.setIcon(args.getIcon());
menu.setIFrame(args.getIFrame());
menu.setPid(args.getPid());
menu.setMenuSort(args.getMenuSort());
menu.setCache(args.getCache());
menu.setHidden(args.getHidden());
menu.setComponentName(args.getComponentName());
menu.setPermission(args.getPermission());
menu.setType(args.getType());
// auto fill
menu.setUpdateBy(null);
menu.setUpdateTime(null);
systemMenuMapper.insertOrUpdate(menu);
// 计算父级菜单节点数目
this.updateMenuSubCnt(oldPid);
this.updateMenuSubCnt(newPid);
}
/**
* 删除
*/
@Transactional(rollbackFor = Exception.class)
public void deleteMenuByIds(Set<Long> ids) {
Set<SystemMenuVo> menuSet = new HashSet<>();
for (Long id : ids) {
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
}
List<Long> menuIds =
menuSet.stream().map(SystemMenuVo::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(menuIds)) {
systemRoleMenuService.deleteRoleMenuByMenuIds(menuIds);
systemMenuMapper.deleteByIds(menuIds);
}
for (SystemMenuVo menu : menuSet) {
this.updateMenuSubCnt(menu.getPid());
}
}
private SystemMenuVo getMenuVoById(Long id) {
return KitBeanUtil.copyToClass(systemMenuMapper.selectById(id), SystemMenuVo.class);
}
@Transactional(rollbackFor = Exception.class)
public void updateMenuSubCnt(Long menuId) {
if (menuId != null) {
long count = this.countMenuByPid(menuId);
LambdaUpdateWrapper<SystemMenuTb> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(SystemMenuTb::getId, menuId);
wrapper.set(SystemMenuTb::getSubCount, count);
systemMenuMapper.update(wrapper);
}
}
/**
* 查询全部数据
*
* @param args 条件
* @param isQuery /
* @return /
* @throws Exception /
*/
public List<SystemMenuTb> queryAllMenu(SystemQueryMenuArgs args, Boolean isQuery) throws Exception {
if (Boolean.TRUE.equals(isQuery)) {
args.setPidIsNull(true);
List<Field> fields = KitClassUtil.getAllFields(args.getClass(), new ArrayList<>());
for (Field field : fields) {
//设置对象的访问权限, 保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(args);
if ("pidIsNull".equals(field.getName())) {
continue;
}
// 如果有查询条件, 则不指定pidIsNull
if (ObjectUtil.isNotNull(val)) {
args.setPidIsNull(null);
break;
}
}
}
return this.queryMenuByArgs(args);
}
/**
* 根据当前用户获取菜单
*
* @param currentUserId /
* @return /
*/
public List<SystemMenuVo> listMenuByUserId(Long currentUserId) {
List<SystemRoleVo> roles = systemUserRoleService.queryRoleVoByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(SystemRoleVo::getId).collect(Collectors.toSet());
return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds));
}
/**
* 获取所有子节点, 包含自身ID
*
* @param menuList /
* @param menuSet /
* @return /
*/
public Set<SystemMenuVo> queryChildMenuByArgs(List<SystemMenuVo> menuList, Set<SystemMenuVo> menuSet) {
for (SystemMenuVo menu : menuList) {
menuSet.add(menu);
List<SystemMenuVo> menus = this.listMenuByPid(menu.getId());
if (CollUtil.isNotEmpty(menus)) {
queryChildMenuByArgs(menus, menuSet);
}
}
return menuSet;
}
/**
* 懒加载菜单数据
*
* @param pid /
* @return /
*/
public List<SystemMenuVo> listMenuByPid(Long pid) {
List<SystemMenuVo> menus;
if (pid != null && !pid.equals(0L)) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getPid, pid);
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
} else {
menus = this.listRootMenu();
}
return menus;
}
/**
* 根据ID获取同级与上级数据
*
* @param menu /
* @param menus /
* @return /
*/
public List<SystemMenuVo> querySuperiorMenuByArgs(SystemMenuVo menu, List<SystemMenuVo> menus) {
if (menu.getPid() == null) {
menus.addAll(this.listRootMenu());
return menus;
}
menus.addAll(this.listMenuByPid(menu.getPid()));
return querySuperiorMenuByArgs(this.getMenuVoById(menu.getPid()), menus);
}
/**
* 构建菜单树
*
* @param menus 原始数据
* @return /
*/
public List<SystemMenuVo> buildMenuTree(List<SystemMenuVo> menus) {
List<SystemMenuVo> trees = new ArrayList<>();
Set<Long> ids = new HashSet<>();
for (SystemMenuVo menu : menus) {
if (menu.getPid() == null) {
trees.add(menu);
}
for (SystemMenuVo it : menus) {
if (menu.getId().equals(it.getPid())) {
if (menu.getChildren() == null) {
menu.setChildren(new ArrayList<>());
}
menu.getChildren().add(it);
ids.add(it.getId());
}
}
}
if (CollUtil.isNotEmpty(trees)) {
trees = menus.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
}
return trees;
}
/**
* 构建菜单树
*
* @param menus /
* @return /
*/
public List<SystemMenuRouterVo> buildMenuVo(List<SystemMenuVo> menus) {
List<SystemMenuRouterVo> list = new LinkedList<>();
for (SystemMenuVo menu : menus) {
if (menu != null) {
List<SystemMenuVo> menuList = menu.getChildren();
SystemMenuRouterVo menuVo = new SystemMenuRouterVo();
menuVo.setName(
ObjectUtil.isNotEmpty(menu.getComponentName()) ? menu.getComponentName() : menu.getTitle());
// 一级目录需要加斜杠, 不然会报警告
menuVo.setPath(menu.getPid() == null ? "/" + menu.getPath() : menu.getPath());
menuVo.setHidden(menu.getHidden());
// 如果不是外链
if (!menu.getIFrame()) {
if (menu.getPid() == null) {
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "Layout" : menu.getComponent());
// 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单
} else if (menu.getType() == 0) {
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "ParentView" : menu.getComponent());
} else if (StrUtil.isNotBlank(menu.getComponent())) {
menuVo.setComponent(menu.getComponent());
}
}
menuVo.setMeta(new SystemMenuMetaVo(menu.getTitle(), menu.getIcon(), !menu.getCache()));
if (CollUtil.isNotEmpty(menuList)) {
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenuVo(menuList));
// 处理是一级菜单并且没有子菜单的情况
} else if (menu.getPid() == null) {
SystemMenuRouterVo menuVo1 = getMenuVo(menu, menuVo);
menuVo.setName(null);
menuVo.setMeta(null);
menuVo.setComponent("Layout");
List<SystemMenuRouterVo> list1 = new ArrayList<>();
list1.add(menuVo1);
menuVo.setChildren(list1);
}
list.add(menuVo);
}
}
return list;
}
/**
* 获取 MenuResponse
*
* @param menu /
* @param menuVo /
* @return /
*/
private SystemMenuRouterVo getMenuVo(SystemMenuVo menu, SystemMenuRouterVo menuVo) {
SystemMenuRouterVo menuVo1 = new SystemMenuRouterVo();
menuVo1.setMeta(menuVo.getMeta());
// 非外链
if (!menu.getIFrame()) { if (!menu.getIFrame()) {
if (menu.getPid() == null) { menuVo1.setPath("index");
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "Layout" : menu.getComponent()); menuVo1.setName(menuVo.getName());
// 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单 menuVo1.setComponent(menuVo.getComponent());
} else if (menu.getType() == 0) { } else {
menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "ParentView" : menu.getComponent()); menuVo1.setPath(menu.getPath());
} else if (StrUtil.isNotBlank(menu.getComponent())) {
menuVo.setComponent(menu.getComponent());
}
} }
menuVo.setMeta(new SystemMenuMetaVo(menu.getTitle(), menu.getIcon(), !menu.getCache())); return menuVo1;
if (CollUtil.isNotEmpty(menuList)) {
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenuVo(menuList));
// 处理是一级菜单并且没有子菜单的情况
} else if (menu.getPid() == null) {
SystemMenuRouterVo menuVo1 = getMenuVo(menu, menuVo);
menuVo.setName(null);
menuVo.setMeta(null);
menuVo.setComponent("Layout");
List<SystemMenuRouterVo> list1 = new ArrayList<>();
list1.add(menuVo1);
menuVo.setChildren(list1);
}
list.add(menuVo);
}
} }
return list;
}
/** public List<SystemMenuVo> listMenuByIds(List<Long> ids) {
* 获取 MenuResponse return KitBeanUtil.copyToList(systemMenuMapper.selectByIds(ids), SystemMenuVo.class);
*
* @param menu /
* @param menuVo /
* @return /
*/
private SystemMenuRouterVo getMenuVo(SystemMenuVo menu, SystemMenuRouterVo menuVo) {
SystemMenuRouterVo menuVo1 = new SystemMenuRouterVo();
menuVo1.setMeta(menuVo.getMeta());
// 非外链
if (!menu.getIFrame()) {
menuVo1.setPath("index");
menuVo1.setName(menuVo.getName());
menuVo1.setComponent(menuVo.getComponent());
} else {
menuVo1.setPath(menu.getPath());
} }
return menuVo1;
}
public List<SystemMenuVo> listMenuByIds(List<Long> ids) { private SystemMenuTb getMenuByComponentName(String componentName) {
return KitBeanUtil.copyToList(systemMenuMapper.selectByIds(ids), SystemMenuVo.class); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
} wrapper.eq(SystemMenuTb::getComponentName, componentName);
return systemMenuMapper.selectOne(wrapper);
}
private SystemMenuTb getMenuByComponentName(String componentName) { private SystemMenuTb getMenuByTitle(String title) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getComponentName, componentName); wrapper.eq(SystemMenuTb::getTitle, title);
return systemMenuMapper.selectOne(wrapper); return systemMenuMapper.selectOne(wrapper);
} }
private SystemMenuTb getMenuByTitle(String title) { private Long countMenuByPid(Long pid) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemMenuTb::getTitle, title); wrapper.eq(SystemMenuTb::getPid, pid);
return systemMenuMapper.selectOne(wrapper); return systemMenuMapper.selectCount(wrapper);
} }
private Long countMenuByPid(Long pid) { private List<SystemMenuTb> queryMenuByArgs(SystemQueryMenuArgs args) {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>(); KitValidUtil.notNull(args);
wrapper.eq(SystemMenuTb::getPid, pid); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
return systemMenuMapper.selectCount(wrapper); wrapper.isNull(args.getPidIsNull() != null, SystemMenuTb::getPid);
} wrapper.eq(args.getPid() != null, SystemMenuTb::getPid, args.getPid());
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemMenuTb::getTitle, args.getBlurry()).or()
private List<SystemMenuTb> queryMenuByArgs(SystemQueryMenuArgs args) {
KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(args.getPidIsNull() != null, SystemMenuTb::getPid);
wrapper.eq(args.getPid() != null, SystemMenuTb::getPid, args.getPid());
wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemMenuTb::getTitle, args.getBlurry()).or()
.like(SystemMenuTb::getComponentName, args.getBlurry()).or() .like(SystemMenuTb::getComponentName, args.getBlurry()).or()
.like(SystemMenuTb::getPermission, args.getBlurry())); .like(SystemMenuTb::getPermission, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemMenuTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemMenuTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
args.getCreateTime().get(1));
}
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return systemMenuMapper.selectList(wrapper);
}
private List<SystemMenuVo> listRootMenu() {
LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(SystemMenuTb::getPid);
wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
}
public List<SystemMenuRouterVo> buildFrontMenus() {
List<SystemMenuVo> originMenus = this.listMenuByUserId(KitSecurityHelper.getCurrentUserId());
List<SystemMenuVo> targetMenus = this.buildMenuTree(originMenus);
return this.buildMenuVo(targetMenus);
}
public Set<Long> listChildMenuSetByMenuId(Long id) {
Set<SystemMenuVo> menuSet = new HashSet<>();
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
return menuSet.stream().map(SystemMenuVo::getId).collect(Collectors.toSet());
}
public List<SystemMenuVo> listMenuSuperior(List<Long> ids) {
Set<SystemMenuVo> menus;
List<SystemMenuVo> systemMenuTbs;
if (CollUtil.isNotEmpty(ids)) {
menus = new LinkedHashSet<>(this.listMenuByIds(ids));
for (SystemMenuVo menu : menus) {
List<SystemMenuVo> menuList = this.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuVo data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
} }
menus.addAll(menuList); wrapper.orderByAsc(SystemMenuTb::getMenuSort);
} return systemMenuMapper.selectList(wrapper);
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
List<SystemMenuVo> newMenuList = new ArrayList<>(menus);
systemMenuTbs = this.buildMenuTree(newMenuList);
} else {
systemMenuTbs = this.listMenuByPid(null);
} }
return systemMenuTbs;
}
public void exportMenuXlsx(HttpServletResponse response, SystemQueryMenuArgs args) throws Exception { private List<SystemMenuVo> listRootMenu() {
List<SystemMenuTb> systemMenuTbs = this.queryAllMenu(args, false); LambdaQueryWrapper<SystemMenuTb> wrapper = new LambdaQueryWrapper<>();
List<SystemMenuExportRowVo> rowVos = new ArrayList<>(); wrapper.isNull(SystemMenuTb::getPid);
for (SystemMenuTb dataObject : systemMenuTbs) { wrapper.orderByAsc(SystemMenuTb::getMenuSort);
SystemMenuExportRowVo rowVo = new SystemMenuExportRowVo(); return KitBeanUtil.copyToList(systemMenuMapper.selectList(wrapper), SystemMenuVo.class);
rowVo.setTitle(dataObject.getTitle()); }
rowVo.setType(dataObject.getType() == null ? "目录" : dataObject.getType() == 1 ? "菜单" : "按钮");
rowVo.setPermission(dataObject.getPermission()); public List<SystemMenuRouterVo> buildFrontMenus() {
rowVo.setIFrame(dataObject.getIFrame() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR); List<SystemMenuVo> originMenus = this.listMenuByUserId(KitSecurityHelper.getCurrentUserId());
rowVo.setHidden(dataObject.getHidden() ? SystemYesOrNoChConst.NO_STR : SystemYesOrNoChConst.YES_STR); List<SystemMenuVo> targetMenus = this.buildMenuTree(originMenus);
rowVo.setCache(dataObject.getCache() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR); return this.buildMenuVo(targetMenus);
rowVo.setCreateTime(dataObject.getCreateTime()); }
rowVos.add(rowVo);
public Set<Long> listChildMenuSetByMenuId(Long id) {
Set<SystemMenuVo> menuSet = new HashSet<>();
List<SystemMenuVo> menuList = this.listMenuByPid(id);
menuSet.add(this.getMenuVoById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
return menuSet.stream().map(SystemMenuVo::getId).collect(Collectors.toSet());
}
public List<SystemMenuVo> listMenuSuperior(List<Long> ids) {
Set<SystemMenuVo> menus;
List<SystemMenuVo> systemMenuTbs;
if (CollUtil.isNotEmpty(ids)) {
menus = new LinkedHashSet<>(this.listMenuByIds(ids));
for (SystemMenuVo menu : menus) {
List<SystemMenuVo> menuList = this.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuVo data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
menus.addAll(menuList);
}
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
List<SystemMenuVo> newMenuList = new ArrayList<>(menus);
systemMenuTbs = this.buildMenuTree(newMenuList);
} else {
systemMenuTbs = this.listMenuByPid(null);
}
return systemMenuTbs;
}
public void exportMenuXlsx(HttpServletResponse response, SystemQueryMenuArgs args) throws Exception {
List<SystemMenuTb> systemMenuTbs = this.queryAllMenu(args, false);
List<SystemMenuExportRowVo> rowVos = new ArrayList<>();
for (SystemMenuTb dataObject : systemMenuTbs) {
SystemMenuExportRowVo rowVo = new SystemMenuExportRowVo();
rowVo.setTitle(dataObject.getTitle());
rowVo.setType(dataObject.getType() == null ? "目录" : dataObject.getType() == 1 ? "菜单" : "按钮");
rowVo.setPermission(dataObject.getPermission());
rowVo.setIFrame(dataObject.getIFrame() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR);
rowVo.setHidden(dataObject.getHidden() ? SystemYesOrNoChConst.NO_STR : SystemYesOrNoChConst.YES_STR);
rowVo.setCache(dataObject.getCache() ? SystemYesOrNoChConst.YES_STR : SystemYesOrNoChConst.NO_STR);
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "菜单数据", SystemMenuExportRowVo.class, rowVos);
} }
KitExcelExporter.exportSimple(response, "菜单数据", SystemMenuExportRowVo.class, rowVos);
}
} }
@@ -20,13 +20,6 @@ import cn.hutool.core.date.DateUtil;
import cn.odboy.constant.SystemConst; import cn.odboy.constant.SystemConst;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitIPUtil; import cn.odboy.util.KitIPUtil;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import oshi.SystemInfo; import oshi.SystemInfo;
@@ -39,177 +32,184 @@ import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem; import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil; import oshi.util.FormatUtil;
import oshi.util.Util; import oshi.util.Util;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
@Service @Service
public class SystemMonitorService { public class SystemMonitorService {
private final DecimalFormat df = new DecimalFormat("0.00"); private final DecimalFormat df = new DecimalFormat("0.00");
/** /**
* 查询服务器监控信息 * 查询服务器监控信息 -> TestPassed
* *
* @return Map<String, Object> * @return Map<String, Object>
*/ */
public Map<String, Object> getServerMonitorInfo() { public Map<String, Object> getServerMonitorInfo() {
Map<String, Object> resultMap = new LinkedHashMap<>(8); Map<String, Object> resultMap = new LinkedHashMap<>(8);
try { try {
SystemInfo si = new SystemInfo(); SystemInfo si = new SystemInfo();
OperatingSystem os = si.getOperatingSystem(); OperatingSystem os = si.getOperatingSystem();
HardwareAbstractionLayer hal = si.getHardware(); HardwareAbstractionLayer hal = si.getHardware();
// 系统信息 // 系统信息
resultMap.put("sys", getSystemInfo(os)); resultMap.put("sys", getSystemInfo(os));
// cpu 信息 // cpu 信息
resultMap.put("cpu", getCpuInfo(hal.getProcessor())); resultMap.put("cpu", getCpuInfo(hal.getProcessor()));
// 内存信息 // 内存信息
resultMap.put("memory", getMemoryInfo(hal.getMemory())); resultMap.put("memory", getMemoryInfo(hal.getMemory()));
// 交换区信息 // 交换区信息
resultMap.put("swap", getSwapInfo(hal.getMemory())); resultMap.put("swap", getSwapInfo(hal.getMemory()));
// 磁盘 // 磁盘
resultMap.put("disk", getDiskInfo(os)); resultMap.put("disk", getDiskInfo(os));
resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss")); resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
}
return resultMap;
} }
return resultMap;
}
/** /**
* 获取磁盘信息 * 获取磁盘信息
* *
* @return / * @return /
*/ */
private Map<String, Object> getDiskInfo(OperatingSystem os) { private Map<String, Object> getDiskInfo(OperatingSystem os) {
Map<String, Object> diskInfo = new LinkedHashMap<>(); Map<String, Object> diskInfo = new LinkedHashMap<>();
FileSystem fileSystem = os.getFileSystem(); FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores(); List<OSFileStore> fsArray = fileSystem.getFileStores();
String osName = System.getProperty("os.name"); String osName = System.getProperty("os.name");
long available = 0, total = 0; long available = 0, total = 0;
for (OSFileStore fs : fsArray) { for (OSFileStore fs : fsArray) {
// windows 需要将所有磁盘分区累加, linux 和 mac 直接累加会出现磁盘重复的问题, 待修复 // windows 需要将所有磁盘分区累加, linux 和 mac 直接累加会出现磁盘重复的问题, 待修复
if (osName.toLowerCase().startsWith(SystemConst.WIN)) { if (osName.toLowerCase().startsWith(SystemConst.WIN)) {
available += fs.getUsableSpace(); available += fs.getUsableSpace();
total += fs.getTotalSpace(); total += fs.getTotalSpace();
} else { } else {
available = fs.getUsableSpace(); available = fs.getUsableSpace();
total = fs.getTotalSpace(); total = fs.getTotalSpace();
break; break;
} }
}
long used = total - available;
diskInfo.put("total", total > 0 ? KitFileUtil.getSize(total) : "?");
diskInfo.put("available", KitFileUtil.getSize(available));
diskInfo.put("used", KitFileUtil.getSize(used));
if (total != 0) {
diskInfo.put("usageRate", df.format(used / (double)total * 100));
} else {
diskInfo.put("usageRate", 0);
}
return diskInfo;
} }
long used = total - available;
diskInfo.put("total", total > 0 ? KitFileUtil.getSize(total) : "?"); /**
diskInfo.put("available", KitFileUtil.getSize(available)); * 获取交换区信息
diskInfo.put("used", KitFileUtil.getSize(used)); *
if (total != 0) { * @param memory /
diskInfo.put("usageRate", df.format(used / (double) total * 100)); * @return /
} else { */
diskInfo.put("usageRate", 0); private Map<String, Object> getSwapInfo(GlobalMemory memory) {
Map<String, Object> swapInfo = new LinkedHashMap<>();
VirtualMemory virtualMemory = memory.getVirtualMemory();
long total = virtualMemory.getSwapTotal();
long used = virtualMemory.getSwapUsed();
swapInfo.put("total", FormatUtil.formatBytes(total));
swapInfo.put("used", FormatUtil.formatBytes(used));
swapInfo.put("available", FormatUtil.formatBytes(total - used));
if (used == 0) {
swapInfo.put("usageRate", 0);
} else {
swapInfo.put("usageRate", df.format(used / (double)total * 100));
}
return swapInfo;
} }
return diskInfo;
}
/** /**
* 获取交换区信息 * 获取内存信息
* *
* @param memory / * @param memory /
* @return / * @return /
*/ */
private Map<String, Object> getSwapInfo(GlobalMemory memory) { private Map<String, Object> getMemoryInfo(GlobalMemory memory) {
Map<String, Object> swapInfo = new LinkedHashMap<>(); Map<String, Object> memoryInfo = new LinkedHashMap<>();
VirtualMemory virtualMemory = memory.getVirtualMemory(); memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal()));
long total = virtualMemory.getSwapTotal(); memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable()));
long used = virtualMemory.getSwapUsed(); memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable()));
swapInfo.put("total", FormatUtil.formatBytes(total)); memoryInfo.put("usageRate",
swapInfo.put("used", FormatUtil.formatBytes(used)); df.format((memory.getTotal() - memory.getAvailable()) / (double)memory.getTotal() * 100));
swapInfo.put("available", FormatUtil.formatBytes(total - used)); return memoryInfo;
if (used == 0) {
swapInfo.put("usageRate", 0);
} else {
swapInfo.put("usageRate", df.format(used / (double) total * 100));
} }
return swapInfo;
}
/** /**
* 获取内存信息 * 获取Cpu相关信息
* *
* @param memory / * @param processor /
* @return / * @return /
*/ */
private Map<String, Object> getMemoryInfo(GlobalMemory memory) { private Map<String, Object> getCpuInfo(CentralProcessor processor) {
Map<String, Object> memoryInfo = new LinkedHashMap<>(); Map<String, Object> cpuInfo = new LinkedHashMap<>();
memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal())); cpuInfo.put("name", processor.getProcessorIdentifier().getName());
memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable())); cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU");
memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable())); cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心");
memoryInfo.put("usageRate", cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount());
df.format((memory.getTotal() - memory.getAvailable()) / (double) memory.getTotal() * 100)); cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU");
return memoryInfo; // CPU信息
} long[] prevTicks = processor.getSystemCpuLoadTicks();
// 默认等待300毫秒...
/** long time = 300;
* 获取Cpu相关信息 Util.sleep(time);
* long[] ticks = processor.getSystemCpuLoadTicks();
* @param processor / long minCpuLoadTick = 1000;
* @return / while (Arrays.toString(prevTicks).equals(Arrays.toString(ticks)) && time < minCpuLoadTick) {
*/ time += 25;
private Map<String, Object> getCpuInfo(CentralProcessor processor) { Util.sleep(25);
Map<String, Object> cpuInfo = new LinkedHashMap<>(); ticks = processor.getSystemCpuLoadTicks();
cpuInfo.put("name", processor.getProcessorIdentifier().getName()); }
cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU"); long user =
cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心"); ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount()); long nice =
cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU"); ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
// CPU信息 long sys =
long[] prevTicks = processor.getSystemCpuLoadTicks(); ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
// 默认等待300毫秒... long idle =
long time = 300; ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
Util.sleep(time); long ioWait =
long[] ticks = processor.getSystemCpuLoadTicks(); ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
long minCpuLoadTick = 1000; long irq =
while (Arrays.toString(prevTicks).equals(Arrays.toString(ticks)) && time < minCpuLoadTick) { ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
time += 25; long softIrq =
Util.sleep(25); ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
ticks = processor.getSystemCpuLoadTicks(); long steal =
ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
long totalCpu = user + nice + sys + idle + ioWait + irq + softIrq + steal;
cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu));
cpuInfo.put("idle", df.format(100d * idle / totalCpu));
return cpuInfo;
} }
long user =
ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
long nice =
ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
long sys =
ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
long idle =
ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
long ioWait =
ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
long irq =
ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
long softIrq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] -
prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
long steal =
ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
long totalCpu = user + nice + sys + idle + ioWait + irq + softIrq + steal;
cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu));
cpuInfo.put("idle", df.format(100d * idle / totalCpu));
return cpuInfo;
}
/** /**
* 获取系统相关信息,系统、运行天数、系统IP * 获取系统相关信息,系统、运行天数、系统IP
* *
* @param os / * @param os /
* @return / * @return /
*/ */
private Map<String, Object> getSystemInfo(OperatingSystem os) { private Map<String, Object> getSystemInfo(OperatingSystem os) {
Map<String, Object> systemInfo = new LinkedHashMap<>(); Map<String, Object> systemInfo = new LinkedHashMap<>();
// jvm 运行时间 // jvm 运行时间
long time = ManagementFactory.getRuntimeMXBean().getStartTime(); long time = ManagementFactory.getRuntimeMXBean().getStartTime();
Date date = new Date(time); Date date = new Date(time);
// 计算项目运行时间 // 计算项目运行时间
String formatBetween = DateUtil.formatBetween(date, new Date(), Level.HOUR); String formatBetween = DateUtil.formatBetween(date, new Date(), Level.HOUR);
// 系统信息 // 系统信息
systemInfo.put("os", os.toString()); systemInfo.put("os", os.toString());
systemInfo.put("day", formatBetween); systemInfo.put("day", formatBetween);
systemInfo.put("ip", KitIPUtil.getLocalIp()); systemInfo.put("ip", KitIPUtil.getLocalIp());
return systemInfo; return systemInfo;
} }
} }
@@ -14,13 +14,16 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemOperationLogService { public class SystemOperationLogService {
@Autowired @Autowired
private SystemOperationLogMapper systemOperationLogMapper; private SystemOperationLogMapper systemOperationLogMapper;
public IPage<SystemOperationLogTb> searchUserLog(KitPageArgs<SystemQueryOperationLogArgs> pageArgs) { /**
LambdaQueryWrapper<SystemOperationLogTb> wrapper = new LambdaQueryWrapper<>(); * 查询用户操作日志
wrapper.eq(SystemOperationLogTb::getUsername, KitSecurityHelper.getCurrentUsername()); */
Page<SystemOperationLogTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); public IPage<SystemOperationLogTb> searchUserLog(KitPageArgs<SystemQueryOperationLogArgs> pageArgs) {
return systemOperationLogMapper.selectPage(page, wrapper); LambdaQueryWrapper<SystemOperationLogTb> wrapper = new LambdaQueryWrapper<>();
} wrapper.eq(SystemOperationLogTb::getUsername, KitSecurityHelper.getCurrentUsername());
Page<SystemOperationLogTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return systemOperationLogMapper.selectPage(page, wrapper);
}
} }
@@ -21,9 +21,9 @@ import cn.odboy.system.dal.model.request.SystemQueryStorageArgs;
import cn.odboy.system.dal.model.response.SystemOssStorageVo; import cn.odboy.system.dal.model.response.SystemOssStorageVo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/** /**
* <p> * <p>
@@ -35,13 +35,13 @@ import org.springframework.web.multipart.MultipartFile;
*/ */
public interface SystemOssStorageService extends IService<SystemOssStorageTb> { public interface SystemOssStorageService extends IService<SystemOssStorageTb> {
KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args, Page<SystemOssStorageTb> page); KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args, Page<SystemOssStorageTb> page);
List<SystemOssStorageVo> queryOssStorage(SystemQueryStorageArgs args); List<SystemOssStorageVo> queryOssStorage(SystemQueryStorageArgs args);
String uploadFile(MultipartFile file); String uploadFile(MultipartFile file);
void deleteFileByIds(Long[] ids); void deleteFileByIds(Long[] ids);
void exportOssStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args); void exportOssStorageXlsx(HttpServletResponse response, SystemQueryStorageArgs args);
} }
@@ -38,279 +38,283 @@ import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.quartz.CronExpression; import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemQuartzJobService { public class SystemQuartzJobService {
@Autowired @Autowired
private SystemQuartzJobMapper systemQuartzJobMapper; private SystemQuartzJobMapper systemQuartzJobMapper;
@Autowired @Autowired
private SystemQuartzLogMapper systemQuartzLogMapper; private SystemQuartzLogMapper systemQuartzLogMapper;
@Autowired @Autowired
private QuartzManage quartzManage; private QuartzManage quartzManage;
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
/** /**
* 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义 * 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
* *
* @param beanName Bean名称 * @param beanName Bean名称
*/ */
private void checkBean(String beanName) { private void checkBean(String beanName) {
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类 // 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。 // 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) { if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) {
throw new BadRequestException("非法的 Bean,请重新输入!"); throw new BadRequestException("非法的 Bean,请重新输入!");
}
} }
}
/** /**
* 创建 * 创建
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void createJob(SystemQuartzJobVo args) { public void createJob(SystemQuartzJobVo args) {
if (args.getId() != null) { if (args.getId() != null) {
throw new BadRequestException("无效参数id"); throw new BadRequestException("无效参数id");
}
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误");
}
SystemQuartzJobTb record = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insert(record);
quartzManage.addJob(args);
} }
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName()); /**
if (!CronExpression.isValidExpression(args.getCronExpression())) { * 修改任务并重新调度
throw new BadRequestException("cron表达式格式错误"); *
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误");
}
if (StrUtil.isNotBlank(args.getSubTask())) {
List<String> tasks = Arrays.asList(args.getSubTask().split("[,,]"));
if (tasks.contains(args.getId().toString())) {
throw new BadRequestException("子任务中不能添加当前任务ID");
}
}
SystemQuartzJobTb jobTb = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(jobTb);
SystemQuartzJobVo jobVo = KitBeanUtil.copyToClass(args, SystemQuartzJobVo.class);
quartzManage.updateJobCron(jobVo);
} }
SystemQuartzJobTb record = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insert(record);
quartzManage.addJob(args);
}
/** /**
* 修改任务并重新调度 * 更改定时任务状态
* *
* @param args / * @param quartzJob /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) { public void switchQuartzJobStatus(SystemQuartzJobVo quartzJob) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义 // 置换暂停状态
checkBean(args.getBeanName()); if (quartzJob.getIsPause()) {
if (!CronExpression.isValidExpression(args.getCronExpression())) { quartzManage.resumeJob(quartzJob);
throw new BadRequestException("cron表达式格式错误"); quartzJob.setIsPause(false);
} else {
quartzManage.pauseJob(quartzJob);
quartzJob.setIsPause(true);
}
SystemQuartzJobTb quartzJobTb = KitBeanUtil.copyToClass(quartzJob, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(quartzJobTb);
} }
if (StrUtil.isNotBlank(args.getSubTask())) {
List<String> tasks = Arrays.asList(args.getSubTask().split("[,,]")); /**
if (tasks.contains(args.getId().toString())) { * 立即执行定时任务
throw new BadRequestException("子任务中不能添加当前任务ID"); *
} * @param quartzJob /
*/
public void startQuartzJob(SystemQuartzJobVo quartzJob) {
quartzManage.runJobNow(quartzJob);
} }
SystemQuartzJobTb jobTb = KitBeanUtil.copyToClass(args, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(jobTb);
SystemQuartzJobVo jobVo = KitBeanUtil.copyToClass(args, SystemQuartzJobVo.class);
quartzManage.updateJobCron(jobVo);
}
/** /**
* 更改定时任务状态 * 删除任务
* *
* @param quartzJob / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void switchQuartzJobStatus(SystemQuartzJobVo quartzJob) { public void deleteJobByIds(Set<Long> ids) {
// 置换暂停状态 for (Long id : ids) {
if (quartzJob.getIsPause()) { SystemQuartzJobTb quartzJob = systemQuartzJobMapper.selectById(id);
quartzManage.resumeJob(quartzJob); quartzManage.deleteJob(quartzJob);
quartzJob.setIsPause(false); systemQuartzJobMapper.deleteById(quartzJob);
} else { }
quartzManage.pauseJob(quartzJob);
quartzJob.setIsPause(true);
} }
SystemQuartzJobTb quartzJobTb = KitBeanUtil.copyToClass(quartzJob, SystemQuartzJobTb.class);
systemQuartzJobMapper.insertOrUpdate(quartzJobTb);
}
/** /**
* 立即执行定时任务 * 执行子任务
* *
* @param quartzJob / * @param tasks /
*/ * @throws InterruptedException /
public void startQuartzJob(SystemQuartzJobVo quartzJob) { */
quartzManage.runJobNow(quartzJob); @Transactional(rollbackFor = Exception.class)
} public void startSubQuartJob(String[] tasks) throws InterruptedException {
for (String id : tasks) {
/** if (StrUtil.isBlank(id)) {
* 删除任务 // 如果是手动清除子任务id, 会出现id为空字符串的问题
* continue;
* @param ids / }
*/ SystemQuartzJobVo quartzJob = systemQuartzJobMapper.selectVoById(id);
@Transactional(rollbackFor = Exception.class) if (quartzJob == null) {
public void deleteJobByIds(Set<Long> ids) { // 防止子任务不存在
for (Long id : ids) { continue;
SystemQuartzJobTb quartzJob = systemQuartzJobMapper.selectById(id); }
quartzManage.deleteJob(quartzJob); // 执行任务
systemQuartzJobMapper.deleteById(quartzJob); String uuid = IdUtil.simpleUUID();
quartzJob.setUuid(uuid);
// 执行任务
startQuartzJob(quartzJob);
// 获取执行状态, 如果执行失败则停止后面的子任务执行
Boolean result = redisHelper.get(uuid, Boolean.class);
while (result == null) {
// 休眠5秒, 再次获取子任务执行情况
Thread.sleep(5000);
result = redisHelper.get(uuid, Boolean.class);
}
if (!result) {
redisHelper.del(uuid);
break;
}
}
} }
}
/** /**
* 执行子任务 * 分页查询
* *
* @param tasks / * @param args 条件
* @throws InterruptedException / * @param page 分页参数
*/ * @return /
@Transactional(rollbackFor = Exception.class) */
public void startSubQuartJob(String[] tasks) throws InterruptedException { public KitPageResult<SystemQuartzJobTb> searchQuartzJobByArgs(SystemQueryQuartzJobArgs args,
for (String id : tasks) { Page<SystemQuartzJobTb> page) {
if (StrUtil.isBlank(id)) { LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
// 如果是手动清除子任务id, 会出现id为空字符串的问题 this.injectQuartzJobQueryParams(args, wrapper);
continue; return KitPageUtil.toPage(systemQuartzJobMapper.selectPage(page, wrapper));
}
SystemQuartzJobVo quartzJob = systemQuartzJobMapper.selectVoById(id);
if (quartzJob == null) {
// 防止子任务不存在
continue;
}
// 执行任务
String uuid = IdUtil.simpleUUID();
quartzJob.setUuid(uuid);
// 执行任务
startQuartzJob(quartzJob);
// 获取执行状态, 如果执行失败则停止后面的子任务执行
Boolean result = redisHelper.get(uuid, Boolean.class);
while (result == null) {
// 休眠5秒, 再次获取子任务执行情况
Thread.sleep(5000);
result = redisHelper.get(uuid, Boolean.class);
}
if (!result) {
redisHelper.del(uuid);
break;
}
} }
}
/** private void injectQuartzJobQueryParams(SystemQueryQuartzJobArgs args,
* 分页查询 LambdaQueryWrapper<SystemQuartzJobTb> wrapper) {
* KitValidUtil.notNull(args);
* @param args 条件 wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzJobTb::getJobName, args.getJobName());
* @param page 分页参数 if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
* @return / wrapper.between(SystemQuartzJobTb::getUpdateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
*/ }
public KitPageResult<SystemQuartzJobTb> searchQuartzJobByArgs(SystemQueryQuartzJobArgs args, Page<SystemQuartzJobTb> page) { wrapper.orderByDesc(SystemQuartzJobTb::getId);
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzJobQueryParams(args, wrapper);
return KitPageUtil.toPage(systemQuartzJobMapper.selectPage(page, wrapper));
}
private void injectQuartzJobQueryParams(SystemQueryQuartzJobArgs args, LambdaQueryWrapper<SystemQuartzJobTb> wrapper) {
KitValidUtil.notNull(args);
wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzJobTb::getJobName, args.getJobName());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemQuartzJobTb::getUpdateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
} }
wrapper.orderByDesc(SystemQuartzJobTb::getId);
}
private void injectQuartzLogQueryParams(SystemQueryQuartzJobArgs args, LambdaQueryWrapper<SystemQuartzLogTb> wrapper) { private void injectQuartzLogQueryParams(SystemQueryQuartzJobArgs args,
if (args != null) { LambdaQueryWrapper<SystemQuartzLogTb> wrapper) {
wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzLogTb::getJobName, args.getJobName()); if (args != null) {
wrapper.eq(args.getIsSuccess() != null, SystemQuartzLogTb::getIsSuccess, args.getIsSuccess()); wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzLogTb::getJobName, args.getJobName());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { wrapper.eq(args.getIsSuccess() != null, SystemQuartzLogTb::getIsSuccess, args.getIsSuccess());
wrapper.between(SystemQuartzLogTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
} wrapper.between(SystemQuartzLogTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
}
}
wrapper.orderByDesc(SystemQuartzLogTb::getId);
} }
wrapper.orderByDesc(SystemQuartzLogTb::getId);
}
/** /**
* 分页查询日志 * 分页查询日志
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @return / * @return /
*/ */
public KitPageResult<SystemQuartzLogTb> searchQuartzLogByArgs(SystemQueryQuartzJobArgs args, public KitPageResult<SystemQuartzLogTb> searchQuartzLogByArgs(SystemQueryQuartzJobArgs args,
Page<SystemQuartzLogTb> page) { Page<SystemQuartzLogTb> page) {
LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzLogQueryParams(args, wrapper); this.injectQuartzLogQueryParams(args, wrapper);
return KitPageUtil.toPage(systemQuartzLogMapper.selectPage(page, wrapper)); return KitPageUtil.toPage(systemQuartzLogMapper.selectPage(page, wrapper));
}
/**
* 查询全部
*
* @param args 条件
* @return /
*/
public List<SystemQuartzJobTb> queryQuartzJobByArgs(SystemQueryQuartzJobArgs args) {
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzJobQueryParams(args, wrapper);
return systemQuartzJobMapper.selectList(wrapper);
}
/**
* 查询全部
*
* @param args 条件
* @return /
*/
public List<SystemQuartzLogTb> queryQuartzLogByArgs(SystemQueryQuartzJobArgs args) {
LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzLogQueryParams(args, wrapper);
return systemQuartzLogMapper.selectList(wrapper);
}
public SystemQuartzJobVo getQuartzJobById(Long id) {
return KitBeanUtil.copyToClass(systemQuartzJobMapper.selectById(id), SystemQuartzJobVo.class);
}
public List<SystemQuartzJobVo> listEnableQuartzJob() {
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemQuartzJobTb::getIsPause, 0);
return KitBeanUtil.copyToList(systemQuartzJobMapper.selectList(wrapper), SystemQuartzJobVo.class);
}
public void exportQuartzJobXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) {
List<SystemQuartzJobTb> systemQuartzJobTbs = this.queryQuartzJobByArgs(args);
List<SystemQuartzJobExportRowVo> rowVos = new ArrayList<>();
for (SystemQuartzJobTb dataObject : systemQuartzJobTbs) {
SystemQuartzJobExportRowVo rowVo = new SystemQuartzJobExportRowVo();
rowVo.setJobName(dataObject.getJobName());
rowVo.setBeanName(dataObject.getBeanName());
rowVo.setMethodName(dataObject.getMethodName());
rowVo.setParams(dataObject.getParams());
rowVo.setCronExpression(dataObject.getCronExpression());
rowVo.setIsPause(dataObject.getIsPause() ? "暂停中" : "运行中");
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
} }
KitExcelExporter.exportSimple(response, "定时任务数据", SystemQuartzJobExportRowVo.class, rowVos);
}
public void exportQuartzLogXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) { /**
List<SystemQuartzLogTb> systemQuartzLogTbs = this.queryQuartzLogByArgs(args); * 查询全部
List<SystemQuartzLogExportRowVo> rowVos = new ArrayList<>(); *
for (SystemQuartzLogTb dataObject : systemQuartzLogTbs) { * @param args 条件
SystemQuartzLogExportRowVo rowVo = new SystemQuartzLogExportRowVo(); * @return /
rowVo.setJobName(dataObject.getJobName()); */
rowVo.setBeanName(dataObject.getBeanName()); public List<SystemQuartzJobTb> queryQuartzJobByArgs(SystemQueryQuartzJobArgs args) {
rowVo.setMethodName(dataObject.getMethodName()); LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
rowVo.setParams(dataObject.getParams()); this.injectQuartzJobQueryParams(args, wrapper);
rowVo.setCronExpression(dataObject.getCronExpression()); return systemQuartzJobMapper.selectList(wrapper);
rowVo.setExceptionDetail(dataObject.getExceptionDetail()); }
rowVo.setTime(dataObject.getTime());
rowVo.setStatus(dataObject.getIsSuccess() ? "成功" : "失败"); /**
rowVo.setCreateTime(dataObject.getCreateTime()); * 查询全部
rowVos.add(rowVo); *
* @param args 条件
* @return /
*/
public List<SystemQuartzLogTb> queryQuartzLogByArgs(SystemQueryQuartzJobArgs args) {
LambdaQueryWrapper<SystemQuartzLogTb> wrapper = new LambdaQueryWrapper<>();
this.injectQuartzLogQueryParams(args, wrapper);
return systemQuartzLogMapper.selectList(wrapper);
}
public SystemQuartzJobVo getQuartzJobById(Long id) {
return KitBeanUtil.copyToClass(systemQuartzJobMapper.selectById(id), SystemQuartzJobVo.class);
}
public List<SystemQuartzJobVo> listEnableQuartzJob() {
LambdaQueryWrapper<SystemQuartzJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemQuartzJobTb::getIsPause, 0);
return KitBeanUtil.copyToList(systemQuartzJobMapper.selectList(wrapper), SystemQuartzJobVo.class);
}
public void exportQuartzJobXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) {
List<SystemQuartzJobTb> systemQuartzJobTbs = this.queryQuartzJobByArgs(args);
List<SystemQuartzJobExportRowVo> rowVos = new ArrayList<>();
for (SystemQuartzJobTb dataObject : systemQuartzJobTbs) {
SystemQuartzJobExportRowVo rowVo = new SystemQuartzJobExportRowVo();
rowVo.setJobName(dataObject.getJobName());
rowVo.setBeanName(dataObject.getBeanName());
rowVo.setMethodName(dataObject.getMethodName());
rowVo.setParams(dataObject.getParams());
rowVo.setCronExpression(dataObject.getCronExpression());
rowVo.setIsPause(dataObject.getIsPause() ? "暂停中" : "运行中");
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "定时任务数据", SystemQuartzJobExportRowVo.class, rowVos);
}
public void exportQuartzLogXlsx(HttpServletResponse response, SystemQueryQuartzJobArgs args) {
List<SystemQuartzLogTb> systemQuartzLogTbs = this.queryQuartzLogByArgs(args);
List<SystemQuartzLogExportRowVo> rowVos = new ArrayList<>();
for (SystemQuartzLogTb dataObject : systemQuartzLogTbs) {
SystemQuartzLogExportRowVo rowVo = new SystemQuartzLogExportRowVo();
rowVo.setJobName(dataObject.getJobName());
rowVo.setBeanName(dataObject.getBeanName());
rowVo.setMethodName(dataObject.getMethodName());
rowVo.setParams(dataObject.getParams());
rowVo.setCronExpression(dataObject.getCronExpression());
rowVo.setExceptionDetail(dataObject.getExceptionDetail());
rowVo.setTime(dataObject.getTime());
rowVo.setStatus(dataObject.getIsSuccess() ? "成功" : "失败");
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "定时任务日志数据", SystemQuartzLogExportRowVo.class, rowVos);
} }
KitExcelExporter.exportSimple(response, "定时任务日志数据", SystemQuartzLogExportRowVo.class, rowVos);
}
} }
@@ -21,67 +21,67 @@ import cn.odboy.system.dal.dataobject.SystemRoleDeptTb;
import cn.odboy.system.dal.mysql.SystemDeptMapper; import cn.odboy.system.dal.mysql.SystemDeptMapper;
import cn.odboy.system.dal.mysql.SystemRoleDeptMapper; import cn.odboy.system.dal.mysql.SystemRoleDeptMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemRoleDeptService { public class SystemRoleDeptService {
@Autowired @Autowired
private SystemRoleDeptMapper systemRoleDeptMapper; private SystemRoleDeptMapper systemRoleDeptMapper;
@Autowired @Autowired
private SystemDeptMapper systemDeptMapper; private SystemDeptMapper systemDeptMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteRoleDept(Set<Long> roleIds) { public void batchDeleteRoleDept(Set<Long> roleIds) {
if (CollUtil.isNotEmpty(roleIds)) { if (CollUtil.isNotEmpty(roleIds)) {
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getRoleId, roleIds); wrapper.in(SystemRoleDeptTb::getRoleId, roleIds);
systemRoleDeptMapper.delete(wrapper); systemRoleDeptMapper.delete(wrapper);
} }
}
@Transactional(rollbackFor = Exception.class)
public void batchInsertRoleDept(Set<SystemDeptTb> depts, Long id) {
if (CollUtil.isNotEmpty(depts)) {
List<SystemRoleDeptTb> records = new ArrayList<>();
for (SystemDeptTb dept : depts) {
SystemRoleDeptTb record = new SystemRoleDeptTb();
record.setRoleId(id);
record.setDeptId(dept.getId());
records.add(record);
}
systemRoleDeptMapper.insert(records);
}
}
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
} }
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>(); @Transactional(rollbackFor = Exception.class)
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds); public void batchInsertRoleDept(Set<SystemDeptTb> depts, Long id) {
return systemRoleDeptMapper.selectCount(wrapper); if (CollUtil.isNotEmpty(depts)) {
} List<SystemRoleDeptTb> records = new ArrayList<>();
for (SystemDeptTb dept : depts) {
SystemRoleDeptTb record = new SystemRoleDeptTb();
record.setRoleId(id);
record.setDeptId(dept.getId());
records.add(record);
}
systemRoleDeptMapper.insert(records);
}
}
/** /**
* 根据角色id查询部门信息 * 根据部门ID统计角色数量
* *
* @param roleId 角色id * @param deptIds 部门ID集合
* @return / * @return /
*/ */
public Set<SystemDeptTb> listUserDeptByRoleId(Long roleId) { public Long countRoleByDeptIds(Set<Long> deptIds) {
return systemRoleDeptMapper.listUserDeptByRoleId(roleId); if (CollUtil.isEmpty(deptIds)) {
} return 0L;
}
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds);
return systemRoleDeptMapper.selectCount(wrapper);
}
/**
* 根据角色id查询部门信息
*
* @param roleId 角色id
* @return /
*/
public Set<SystemDeptTb> listUserDeptByRoleId(Long roleId) {
return systemRoleDeptMapper.listUserDeptByRoleId(roleId);
}
} }
@@ -23,82 +23,82 @@ import cn.odboy.system.dal.mysql.SystemMenuMapper;
import cn.odboy.system.dal.mysql.SystemRoleMenuMapper; import cn.odboy.system.dal.mysql.SystemRoleMenuMapper;
import cn.odboy.util.KitBeanUtil; import cn.odboy.util.KitBeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleMenuService { public class SystemRoleMenuService {
@Autowired @Autowired
private SystemRoleMenuMapper systemRoleMenuMapper; private SystemRoleMenuMapper systemRoleMenuMapper;
@Autowired @Autowired
private SystemMenuMapper systemMenuMapper; private SystemMenuMapper systemMenuMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleMenuByRoleId(Long roleId) { public void deleteRoleMenuByRoleId(Long roleId) {
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleMenuTb::getRoleId, roleId); wrapper.eq(SystemRoleMenuTb::getRoleId, roleId);
systemRoleMenuMapper.delete(wrapper); systemRoleMenuMapper.delete(wrapper);
}
@Transactional(rollbackFor = Exception.class)
public void batchInsertRoleMenu(Set<SystemMenuVo> menus, Long roleId) {
if (CollUtil.isNotEmpty(menus)) {
List<SystemRoleMenuTb> records = new ArrayList<>();
for (SystemMenuVo menu : menus) {
SystemRoleMenuTb record = new SystemRoleMenuTb();
record.setMenuId(menu.getId());
record.setRoleId(roleId);
records.add(record);
}
systemRoleMenuMapper.insert(records);
} }
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteRoleMenu(Set<Long> roleIds) { public void batchInsertRoleMenu(Set<SystemMenuVo> menus, Long roleId) {
if (CollUtil.isNotEmpty(roleIds)) { if (CollUtil.isNotEmpty(menus)) {
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>(); List<SystemRoleMenuTb> records = new ArrayList<>();
wrapper.in(SystemRoleMenuTb::getRoleId, roleIds); for (SystemMenuVo menu : menus) {
systemRoleMenuMapper.delete(wrapper); SystemRoleMenuTb record = new SystemRoleMenuTb();
record.setMenuId(menu.getId());
record.setRoleId(roleId);
records.add(record);
}
systemRoleMenuMapper.insert(records);
}
} }
}
public LinkedHashSet<SystemMenuVo> queryMenuByRoleIds(Set<Long> roleIds) { @Transactional(rollbackFor = Exception.class)
if (CollUtil.isEmpty(roleIds)) { public void batchDeleteRoleMenu(Set<Long> roleIds) {
return new LinkedHashSet<>(); if (CollUtil.isNotEmpty(roleIds)) {
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleMenuTb::getRoleId, roleIds);
systemRoleMenuMapper.delete(wrapper);
}
} }
LambdaQueryWrapper<SystemRoleMenuTb> roleMenuWrapper = new LambdaQueryWrapper<>();
roleMenuWrapper.in(SystemRoleMenuTb::getRoleId, roleIds);
List<Long> menuIds = systemRoleMenuMapper.selectList(roleMenuWrapper).stream().map(SystemRoleMenuTb::getMenuId)
.collect(Collectors.toList());
if (CollUtil.isEmpty(menuIds)) {
return new LinkedHashSet<>();
}
LambdaQueryWrapper<SystemMenuTb> menuWrapper = new LambdaQueryWrapper<>();
menuWrapper.in(SystemMenuTb::getId, menuIds);
// 排除"按钮"
menuWrapper.ne(SystemMenuTb::getType, 2);
menuWrapper.orderByAsc(SystemMenuTb::getMenuSort);
List<SystemMenuTb> systemMenuTbs = systemMenuMapper.selectList(menuWrapper); public LinkedHashSet<SystemMenuVo> queryMenuByRoleIds(Set<Long> roleIds) {
List<SystemMenuVo> systemMenuVos = KitBeanUtil.copyToList(systemMenuTbs, SystemMenuVo.class); if (CollUtil.isEmpty(roleIds)) {
return new LinkedHashSet<>(systemMenuVos); return new LinkedHashSet<>();
} }
LambdaQueryWrapper<SystemRoleMenuTb> roleMenuWrapper = new LambdaQueryWrapper<>();
roleMenuWrapper.in(SystemRoleMenuTb::getRoleId, roleIds);
List<Long> menuIds = systemRoleMenuMapper.selectList(roleMenuWrapper).stream().map(SystemRoleMenuTb::getMenuId)
.collect(Collectors.toList());
if (CollUtil.isEmpty(menuIds)) {
return new LinkedHashSet<>();
}
LambdaQueryWrapper<SystemMenuTb> menuWrapper = new LambdaQueryWrapper<>();
menuWrapper.in(SystemMenuTb::getId, menuIds);
// 排除"按钮"
menuWrapper.ne(SystemMenuTb::getType, 2);
menuWrapper.orderByAsc(SystemMenuTb::getMenuSort);
@Transactional(rollbackFor = Exception.class) List<SystemMenuTb> systemMenuTbs = systemMenuMapper.selectList(menuWrapper);
public void deleteRoleMenuByMenuIds(List<Long> menuIds) { List<SystemMenuVo> systemMenuVos = KitBeanUtil.copyToList(systemMenuTbs, SystemMenuVo.class);
if (CollUtil.isEmpty(menuIds)) { return new LinkedHashSet<>(systemMenuVos);
return; }
@Transactional(rollbackFor = Exception.class)
public void deleteRoleMenuByMenuIds(List<Long> menuIds) {
if (CollUtil.isEmpty(menuIds)) {
return;
}
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleMenuTb::getMenuId, menuIds);
systemRoleMenuMapper.delete(wrapper);
} }
LambdaQueryWrapper<SystemRoleMenuTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleMenuTb::getMenuId, menuIds);
systemRoleMenuMapper.delete(wrapper);
}
} }
@@ -36,268 +36,264 @@ import cn.odboy.util.KitValidUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleService { public class SystemRoleService {
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private SystemRoleMapper systemRoleMapper;
@Autowired @Autowired
private SystemRoleMenuService systemRoleMenuService; private SystemRoleMenuService systemRoleMenuService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemUserRoleService systemUserRoleService;
/** /**
* 创建 * 创建
* *
* @param args / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveRole(SystemCreateRoleArgs args) { public void saveRole(SystemCreateRoleArgs args) {
checkRoleLevels(args.getLevel()); checkRoleLevels(args.getLevel());
if (this.countRoleByName(args.getName()) > 0) { if (this.countRoleByName(args.getName()) > 0) {
throw new BadRequestException("角色名称已存在"); throw new BadRequestException("角色名称已存在");
}
SystemRoleTb roleTb = KitBeanUtil.copyToClass(args, SystemRoleTb.class);
systemRoleMapper.insert(roleTb);
// 判断是否有部门数据, 若有, 则需创建关联
if (CollUtil.isNotEmpty(args.getDepts())) {
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), roleTb.getId());
}
} }
SystemRoleTb roleTb = KitBeanUtil.copyToClass(args, SystemRoleTb.class);
systemRoleMapper.insert(roleTb); private SystemRoleTb getRoleByName(String name) {
// 判断是否有部门数据, 若有, 则需创建关联 LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
if (CollUtil.isNotEmpty(args.getDepts())) { wrapper.eq(SystemRoleTb::getName, name);
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), roleTb.getId()); return systemRoleMapper.selectOne(wrapper);
} }
}
private SystemRoleTb getRoleByName(String name) { private long countRoleByName(String name) {
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleTb::getName, name); wrapper.eq(SystemRoleTb::getName, name);
return systemRoleMapper.selectOne(wrapper); return systemRoleMapper.selectCount(wrapper);
}
private long countRoleByName(String name) {
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemRoleTb::getName, name);
return systemRoleMapper.selectCount(wrapper);
}
/**
* 修改
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateRoleById(SystemRoleVo args) {
checkRoleLevels(args.getLevel());
SystemRoleTb role = this.getRoleTbById(args.getId());
SystemRoleTb role1 = this.getRoleByName(args.getName());
if (role1 != null && !role1.getId().equals(role.getId())) {
throw new BadRequestException("角色名称已存在");
} }
role.setName(args.getName());
role.setDescription(args.getDescription()); /**
role.setDataScope(args.getDataScope()); * 修改
role.setLevel(args.getLevel()); *
// 更新 * @param args /
systemRoleMapper.insertOrUpdate(role); */
// 删除关联部门数据 @Transactional(rollbackFor = Exception.class)
systemRoleDeptService.batchDeleteRoleDept(Collections.singleton(args.getId())); public void updateRoleById(SystemRoleVo args) {
// 判断是否有部门数据, 若有, 则需更新关联 checkRoleLevels(args.getLevel());
if (CollUtil.isNotEmpty(args.getDepts())) { SystemRoleTb role = this.getRoleTbById(args.getId());
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), args.getId()); SystemRoleTb role1 = this.getRoleByName(args.getName());
if (role1 != null && !role1.getId().equals(role.getId())) {
throw new BadRequestException("角色名称已存在");
}
role.setName(args.getName());
role.setDescription(args.getDescription());
role.setDataScope(args.getDataScope());
role.setLevel(args.getLevel());
// 更新
systemRoleMapper.insertOrUpdate(role);
// 删除关联部门数据
systemRoleDeptService.batchDeleteRoleDept(Collections.singleton(args.getId()));
// 判断是否有部门数据, 若有, 则需更新关联
if (CollUtil.isNotEmpty(args.getDepts())) {
systemRoleDeptService.batchInsertRoleDept(args.getDepts(), args.getId());
}
} }
}
private SystemRoleTb getRoleTbById(Long id) { private SystemRoleTb getRoleTbById(Long id) {
return systemRoleMapper.selectById(id); return systemRoleMapper.selectById(id);
}
/**
* 修改绑定的菜单
*
* @param args /
*/
@Transactional(rollbackFor = Exception.class)
public void updateBindMenuById(SystemRoleVo args) {
SystemRoleTb role = systemRoleMapper.selectById(args.getId());
checkRoleLevels(role.getLevel());
// 更新菜单
systemRoleMenuService.deleteRoleMenuByRoleId(role.getId());
// 判断是否为空
Set<SystemMenuVo> menus = args.getMenus();
if (CollUtil.isNotEmpty(menus)) {
systemRoleMenuService.batchInsertRoleMenu(menus, role.getId());
} }
}
/** /**
* 删除 * 修改绑定的菜单
* *
* @param ids / * @param args /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleByIds(Set<Long> ids) { public void updateBindMenuById(SystemRoleVo args) {
List<Integer> roleLevels = systemRoleMapper.selectByIds(ids).stream().map(SystemRoleTb::getLevel).distinct().collect(Collectors.toList()); SystemRoleTb role = systemRoleMapper.selectById(args.getId());
for (Integer roleLevel : roleLevels) { checkRoleLevels(role.getLevel());
checkRoleLevels(roleLevel); // 更新菜单
systemRoleMenuService.deleteRoleMenuByRoleId(role.getId());
// 判断是否为空
Set<SystemMenuVo> menus = args.getMenus();
if (CollUtil.isNotEmpty(menus)) {
systemRoleMenuService.batchInsertRoleMenu(menus, role.getId());
}
} }
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
// 删除角色
systemRoleMapper.deleteByIds(ids);
// 删除角色部门关联数据、角色菜单关联数据
systemRoleDeptService.batchDeleteRoleDept(ids);
systemRoleMenuService.batchDeleteRoleMenu(ids);
}
/** /**
* 查询全部角色 * 删除
*/ *
public List<SystemRoleTb> listAllRole() { * @param ids /
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); */
wrapper.orderByAsc(SystemRoleTb::getLevel); @Transactional(rollbackFor = Exception.class)
return systemRoleMapper.selectList(wrapper); public void deleteRoleByIds(Set<Long> ids) {
} List<Integer> roleLevels = systemRoleMapper.selectByIds(ids).stream().map(SystemRoleTb::getLevel).distinct()
.collect(Collectors.toList());
for (Integer roleLevel : roleLevels) {
checkRoleLevels(roleLevel);
}
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
// 删除角色
systemRoleMapper.deleteByIds(ids);
// 删除角色部门关联数据、角色菜单关联数据
systemRoleDeptService.batchDeleteRoleDept(ids);
systemRoleMenuService.batchDeleteRoleMenu(ids);
}
/** /**
* 根据条件查询全部角色 * 查询全部角色
* */
* @param args 条件 public List<SystemRoleTb> listAllRole() {
* @param rolePage 分页参数 LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
* @return / wrapper.orderByAsc(SystemRoleTb::getLevel);
*/ return systemRoleMapper.selectList(wrapper);
public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> rolePage) { }
KitValidUtil.notNull(args);
// 查询角色基本信息 /**
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); * 根据条件查询全部角色
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), *
c -> c.like(SystemRoleTb::getName, args.getBlurry()).or() * @param args 条件
* @param rolePage 分页参数
* @return /
*/
public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> rolePage) {
KitValidUtil.notNull(args);
// 查询角色基本信息
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
.like(SystemRoleTb::getDescription, args.getBlurry())); .like(SystemRoleTb::getDescription, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
args.getCreateTime().get(1)); }
wrapper.orderByAsc(SystemRoleTb::getLevel);
List<SystemRoleTb> roles;
if (rolePage == null) {
roles = systemRoleMapper.selectList(wrapper);
} else {
Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper);
roles = page.getRecords();
}
return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
} }
wrapper.orderByAsc(SystemRoleTb::getLevel);
List<SystemRoleTb> roles; /**
if (rolePage == null) { * 分页查询角色
roles = systemRoleMapper.selectList(wrapper); *
} else { * @param args 条件
Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper); * @param page 分页条件
roles = page.getRecords(); * @return /
*/
public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> page) {
List<SystemRoleVo> roles = this.queryRoleByArgs(args, page);
Long total = this.countRoleByArgs(args);
return KitPageUtil.toPage(roles, total);
} }
return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
}
/** /**
* 分页查询角色 * 获取用户权限信息
* *
* @param args 条件 * @param user 用户信息
* @param page 分页条件 * @return 权限信息
* @return / */
*/ public List<SystemRoleCodeVo> buildUserRolePermissions(SystemUserVo user) {
public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<SystemRoleTb> page) { Set<String> permissions = new HashSet<>();
List<SystemRoleVo> roles = this.queryRoleByArgs(args, page); // 如果是管理员直接返回
Long total = this.countRoleByArgs(args); if (user.getIsAdmin()) {
return KitPageUtil.toPage(roles, total); permissions.add("admin");
} return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
}
List<SystemRoleVo> roles = systemUserRoleService.queryRoleVoByUsersId(user.getId());
/** permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuVo::getPermission)
* 获取用户权限信息 .filter(StrUtil::isNotBlank).collect(Collectors.toSet());
* return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
* @param user 用户信息
* @return 权限信息
*/
public List<SystemRoleCodeVo> buildUserRolePermissions(SystemUserVo user) {
Set<String> permissions = new HashSet<>();
// 如果是管理员直接返回
if (user.getIsAdmin()) {
permissions.add("admin");
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
} }
List<SystemRoleVo> roles = systemUserRoleService.queryRoleVoByUsersId(user.getId());
permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuVo::getPermission)
.filter(StrUtil::isNotBlank).collect(Collectors.toSet());
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
}
/** /**
* 验证是否被用户关联 * 验证是否被用户关联
* *
* @param ids / * @param ids /
*/ */
public void verifyBindRelationByIds(Set<Long> ids) { public void verifyBindRelationByIds(Set<Long> ids) {
if (systemUserRoleService.countUserByRoleIds(ids) > 0) { if (systemUserRoleService.countUserByRoleIds(ids) > 0) {
throw new BadRequestException("所选角色存在用户关联, 请解除关联再试!"); throw new BadRequestException("所选角色存在用户关联, 请解除关联再试!");
}
} }
}
public Long countRoleByArgs(SystemQueryRoleArgs args) { public Long countRoleByArgs(SystemQueryRoleArgs args) {
KitValidUtil.notNull(args); KitValidUtil.notNull(args);
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
.like(SystemRoleTb::getDescription, args.getBlurry())); .like(SystemRoleTb::getDescription, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1));
args.getCreateTime().get(1)); }
return systemRoleMapper.selectCount(wrapper);
} }
return systemRoleMapper.selectCount(wrapper);
}
public SystemRoleVo getRoleById(Long id) { public SystemRoleVo getRoleById(Long id) {
SystemRoleTb roleTb = systemRoleMapper.selectById(id); SystemRoleTb roleTb = systemRoleMapper.selectById(id);
if (roleTb == null) { if (roleTb == null) {
return null; return null;
}
return systemUserRoleService.convertToRoleVo(roleTb);
} }
return systemUserRoleService.convertToRoleVo(roleTb);
}
public Dict getCurrentUserRoleLevel() { public Dict getCurrentUserRoleLevel() {
return Dict.create().set("level", checkRoleLevels(null)); return Dict.create().set("level", checkRoleLevels(null));
}
/**
* 检查用户的角色级别
*
* @return /
*/
private int checkRoleLevels(Integer level) {
List<Integer> levels = systemUserRoleService.queryRoleVoByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleVo::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
} }
return min;
}
public void exportRoleXlsx(HttpServletResponse response, SystemQueryRoleArgs args) { /**
List<SystemRoleVo> systemRoleVos = this.queryRoleByArgs(args, null); * 检查用户的角色级别
List<SystemRoleExportRowVo> rowVos = new ArrayList<>(); *
for (SystemRoleVo dataObject : systemRoleVos) { * @return /
SystemRoleExportRowVo rowVo = new SystemRoleExportRowVo(); */
rowVo.setName(dataObject.getName()); private int checkRoleLevels(Integer level) {
rowVo.setLevel(dataObject.getLevel()); List<Integer> levels = systemUserRoleService.queryRoleVoByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
rowVo.setDescription(dataObject.getDescription()); .map(SystemRoleVo::getLevel).collect(Collectors.toList());
rowVo.setCreateTime(dataObject.getCreateTime()); int min = Collections.min(levels);
rowVos.add(rowVo); if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
}
return min;
} }
KitExcelExporter.exportSimple(response, "部门数据", SystemRoleExportRowVo.class, rowVos);
}
public List<SystemRoleTb> listByIds(Set<Long> roleIds) { public void exportRoleXlsx(HttpServletResponse response, SystemQueryRoleArgs args) {
return systemRoleMapper.selectByIds(roleIds); List<SystemRoleVo> systemRoleVos = this.queryRoleByArgs(args, null);
} List<SystemRoleExportRowVo> rowVos = new ArrayList<>();
for (SystemRoleVo dataObject : systemRoleVos) {
SystemRoleExportRowVo rowVo = new SystemRoleExportRowVo();
rowVo.setName(dataObject.getName());
rowVo.setLevel(dataObject.getLevel());
rowVo.setDescription(dataObject.getDescription());
rowVo.setCreateTime(dataObject.getCreateTime());
rowVos.add(rowVo);
}
KitExcelExporter.exportSimple(response, "部门数据", SystemRoleExportRowVo.class, rowVos);
}
public List<SystemRoleTb> listByIds(Set<Long> roleIds) {
return systemRoleMapper.selectByIds(roleIds);
}
} }
@@ -3,19 +3,19 @@ package cn.odboy.system.service;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.mysql.SystemUserMapper; import cn.odboy.system.dal.mysql.SystemUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Set;
@Service @Service
public class SystemUserDeptService { public class SystemUserDeptService {
@Autowired @Autowired
private SystemUserMapper systemUserMapper; private SystemUserMapper systemUserMapper;
public long countUserByDeptIds(Set<Long> deptIds) { public long countUserByDeptIds(Set<Long> deptIds) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserTb::getDeptId, deptIds); wrapper.in(SystemUserTb::getDeptId, deptIds);
return systemUserMapper.selectCount(wrapper); return systemUserMapper.selectCount(wrapper);
} }
} }
@@ -20,58 +20,58 @@ import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemUserJobTb; import cn.odboy.system.dal.dataobject.SystemUserJobTb;
import cn.odboy.system.dal.mysql.SystemUserJobMapper; import cn.odboy.system.dal.mysql.SystemUserJobMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service @Service
public class SystemUserJobService { public class SystemUserJobService {
@Autowired @Autowired
private SystemUserJobMapper systemUserJobMapper; private SystemUserJobMapper systemUserJobMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserJob(Set<SystemJobTb> jobs, Long userId) { public void batchInsertUserJob(Set<SystemJobTb> jobs, Long userId) {
if (CollUtil.isNotEmpty(jobs)) { if (CollUtil.isNotEmpty(jobs)) {
List<SystemUserJobTb> records = new ArrayList<>(); List<SystemUserJobTb> records = new ArrayList<>();
for (SystemJobTb job : jobs) { for (SystemJobTb job : jobs) {
SystemUserJobTb record = new SystemUserJobTb(); SystemUserJobTb record = new SystemUserJobTb();
record.setUserId(userId); record.setUserId(userId);
record.setJobId(job.getId()); record.setJobId(job.getId());
records.add(record); records.add(record);
} }
systemUserJobMapper.insert(records); systemUserJobMapper.insert(records);
}
} }
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteUserJob(Set<Long> userIds) { public void batchDeleteUserJob(Set<Long> userIds) {
if (CollUtil.isNotEmpty(userIds)) { if (CollUtil.isNotEmpty(userIds)) {
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserJobTb::getUserId, userIds); wrapper.in(SystemUserJobTb::getUserId, userIds);
systemUserJobMapper.delete(wrapper); systemUserJobMapper.delete(wrapper);
}
} }
}
/** /**
* 根据岗位ID统计用户数量 * 根据岗位ID统计用户数量
* *
* @param jobIds 岗位ID集合 * @param jobIds 岗位ID集合
* @return / * @return /
*/ */
public Long countUserByJobIds(Set<Long> jobIds) { public Long countUserByJobIds(Set<Long> jobIds) {
if (CollUtil.isEmpty(jobIds)) { if (CollUtil.isEmpty(jobIds)) {
return 0L; return 0L;
}
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserJobTb::getJobId, jobIds);
return systemUserJobMapper.selectCount(wrapper);
} }
LambdaQueryWrapper<SystemUserJobTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserJobTb::getJobId, jobIds);
return systemUserJobMapper.selectCount(wrapper);
}
public Set<SystemJobTb> listUserJobByUserId(Long userId) { public Set<SystemJobTb> listUserJobByUserId(Long userId) {
return systemUserJobMapper.listUserJobByUserId(userId); return systemUserJobMapper.listUserJobByUserId(userId);
} }
} }
@@ -28,136 +28,135 @@ import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitBeanUtil; import cn.odboy.util.KitBeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemUserRoleService { public class SystemUserRoleService {
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private SystemRoleMapper systemRoleMapper;
@Autowired @Autowired
private SystemUserRoleMapper systemUserRoleMapper; private SystemUserRoleMapper systemUserRoleMapper;
@Autowired @Autowired
private SystemRoleMenuService systemRoleMenuService; private SystemRoleMenuService systemRoleMenuService;
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) { public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) {
if (CollUtil.isNotEmpty(roles)) { if (CollUtil.isNotEmpty(roles)) {
List<SystemUserRoleTb> records = new ArrayList<>(); List<SystemUserRoleTb> records = new ArrayList<>();
for (SystemRoleTb role : roles) { for (SystemRoleTb role : roles) {
SystemUserRoleTb record = new SystemUserRoleTb(); SystemUserRoleTb record = new SystemUserRoleTb();
record.setUserId(userId); record.setUserId(userId);
record.setRoleId(role.getId()); record.setRoleId(role.getId());
records.add(record); records.add(record);
} }
systemUserRoleMapper.insert(records); systemUserRoleMapper.insert(records);
}
} }
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteUserRole(Set<Long> userIds) { public void batchDeleteUserRole(Set<Long> userIds) {
if (CollUtil.isNotEmpty(userIds)) { if (CollUtil.isNotEmpty(userIds)) {
LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserRoleTb::getUserId, userIds); wrapper.in(SystemUserRoleTb::getUserId, userIds);
systemUserRoleMapper.delete(wrapper); systemUserRoleMapper.delete(wrapper);
}
} }
}
/** /**
* 转换为SystemRoleVo并关联查询菜单和部门信息 * 转换为SystemRoleVo并关联查询菜单和部门信息
* *
* @param role 角色基本信息 * @param role 角色基本信息
* @return 包含关联信息的SystemRoleVo * @return 包含关联信息的SystemRoleVo
*/ */
public SystemRoleVo convertToRoleVo(SystemRoleTb role) { public SystemRoleVo convertToRoleVo(SystemRoleTb role) {
if (role == null) { if (role == null) {
return null; return null;
}
SystemRoleVo roleVo = KitBeanUtil.copyToClass(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuVo> menus = systemRoleMenuService.queryMenuByRoleIds(Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
Set<SystemDeptTb> depts = systemRoleDeptService.listUserDeptByRoleId(role.getId());
roleVo.setDepts(depts);
return roleVo;
} }
SystemRoleVo roleVo = KitBeanUtil.copyToClass(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuVo> menus = systemRoleMenuService.queryMenuByRoleIds(Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
Set<SystemDeptTb> depts = systemRoleDeptService.listUserDeptByRoleId(role.getId());
roleVo.setDepts(depts);
return roleVo;
}
/** /**
* 根据用户ID查询 * 根据用户ID查询
* *
* @param userId 用户ID * @param userId 用户ID
* @return / * @return /
*/ */
public List<SystemRoleVo> queryRoleVoByUsersId(Long userId) { public List<SystemRoleVo> queryRoleVoByUsersId(Long userId) {
Set<SystemRoleTb> roles = this.listUserRoleByUserId(userId); Set<SystemRoleTb> roles = this.listUserRoleByUserId(userId);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList()); return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
} }
/** /**
* 根据角色查询角色级别 * 根据角色查询角色级别
* *
* @param roles / * @param roles /
* @return / * @return /
*/ */
public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) { public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) {
if (CollUtil.isEmpty(roles)) { if (CollUtil.isEmpty(roles)) {
// 最小权限 // 最小权限
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
}
List<Long> roleIds =
roles.stream().map(SystemRoleTb::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(roleIds)) {
// 最小权限
return Integer.MAX_VALUE;
}
List<Integer> roleLevels = systemRoleMapper.selectList(
new LambdaQueryWrapper<SystemRoleTb>().select(SystemRoleTb::getLevel).isNotNull(SystemRoleTb::getLevel)
.in(SystemRoleTb::getId, roleIds)).stream().map(SystemRoleTb::getLevel).distinct()
.collect(Collectors.toList());
if (CollUtil.isEmpty(roleLevels)) {
// 最小权限
return Integer.MAX_VALUE;
}
return Collections.min(roleLevels);
} }
List<Long> roleIds = roles.stream().map(SystemRoleTb::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(roleIds)) {
// 最小权限
return Integer.MAX_VALUE;
}
List<Integer> roleLevels = systemRoleMapper.selectList(new LambdaQueryWrapper<SystemRoleTb>()
.select(SystemRoleTb::getLevel)
.isNotNull(SystemRoleTb::getLevel)
.in(SystemRoleTb::getId, roleIds)
).stream().map(SystemRoleTb::getLevel).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(roleLevels)) {
// 最小权限
return Integer.MAX_VALUE;
}
return Collections.min(roleLevels);
}
/** /**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误 * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
* *
* @param args / * @param args /
*/ */
public void checkLevel(SystemUserVo args) { public void checkLevel(SystemUserVo args) {
Integer currentLevel = Collections.min( Integer currentLevel = Collections.min(
this.queryRoleVoByUsersId(KitSecurityHelper.getCurrentUserId()).stream() this.queryRoleVoByUsersId(KitSecurityHelper.getCurrentUserId()).stream().map(SystemRoleVo::getLevel)
.map(SystemRoleVo::getLevel).collect(Collectors.toList())); .collect(Collectors.toList()));
Integer optLevel = this.getDeptLevelByRoles(args.getRoles()); Integer optLevel = this.getDeptLevelByRoles(args.getRoles());
if (currentLevel > optLevel) { if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足"); throw new BadRequestException("角色权限不足");
}
} }
}
public long countUserByRoleIds(Set<Long> ids) { public long countUserByRoleIds(Set<Long> ids) {
if (CollUtil.isEmpty(ids)) { if (CollUtil.isEmpty(ids)) {
return 0L; return 0L;
}
LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserRoleTb::getRoleId, ids);
return systemUserRoleMapper.selectCount(wrapper);
} }
LambdaQueryWrapper<SystemUserRoleTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserRoleTb::getRoleId, ids);
return systemUserRoleMapper.selectCount(wrapper);
}
public Set<SystemRoleTb> listUserRoleByUserId(Long userId) { public Set<SystemRoleTb> listUserRoleByUserId(Long userId) {
return systemUserRoleMapper.listUserRoleByUserId(userId); return systemUserRoleMapper.listUserRoleByUserId(userId);
} }
} }

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