1
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统访问记录表 sys_logininfor
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@TableName("sys_logininfor")
|
||||
@ExcelIgnoreUnannotated
|
||||
public class SysLogininfor implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@ExcelProperty(value = "序号")
|
||||
@TableId(value = "info_id")
|
||||
private Long infoId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@ExcelProperty(value = "用户账号")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 登录状态 0成功 1失败
|
||||
*/
|
||||
@ExcelProperty(value = "登录状态", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "sys_common_status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 登录IP地址
|
||||
*/
|
||||
@ExcelProperty(value = "登录地址")
|
||||
private String ipaddr;
|
||||
|
||||
/**
|
||||
* 登录地点
|
||||
*/
|
||||
@ExcelProperty(value = "登录地点")
|
||||
private String loginLocation;
|
||||
|
||||
/**
|
||||
* 浏览器类型
|
||||
*/
|
||||
@ExcelProperty(value = "浏览器")
|
||||
private String browser;
|
||||
|
||||
/**
|
||||
* 操作系统
|
||||
*/
|
||||
@ExcelProperty(value = "操作系统")
|
||||
private String os;
|
||||
|
||||
/**
|
||||
* 提示消息
|
||||
*/
|
||||
@ExcelProperty(value = "提示消息")
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 访问时间
|
||||
*/
|
||||
@ExcelProperty(value = "访问时间")
|
||||
private Date loginTime;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* OSS对象存储对象
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_oss")
|
||||
public class SysOss extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 对象存储主键
|
||||
*/
|
||||
@TableId(value = "oss_id")
|
||||
private Long ossId;
|
||||
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 原名
|
||||
*/
|
||||
private String originalName;
|
||||
|
||||
/**
|
||||
* 文件后缀名
|
||||
*/
|
||||
private String fileSuffix;
|
||||
|
||||
/**
|
||||
* URL地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 服务商
|
||||
*/
|
||||
private String service;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 对象存储配置对象 sys_oss_config
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_oss_config")
|
||||
public class SysOssConfig extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主建
|
||||
*/
|
||||
@TableId(value = "oss_config_id")
|
||||
private Long ossConfigId;
|
||||
|
||||
/**
|
||||
* 配置key
|
||||
*/
|
||||
private String configKey;
|
||||
|
||||
/**
|
||||
* accessKey
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* 秘钥
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
private String prefix;
|
||||
|
||||
/**
|
||||
* 访问站点
|
||||
*/
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 是否https(0否 1是)
|
||||
*/
|
||||
private String isHttps;
|
||||
|
||||
/**
|
||||
* 域
|
||||
*/
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* 是否默认(0=是,1=否)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private String ext1;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 桶权限类型(0private 1public 2custom)
|
||||
*/
|
||||
private String accessPolicy;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 岗位表 sys_post
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_post")
|
||||
@ExcelIgnoreUnannotated
|
||||
public class SysPost extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 岗位序号
|
||||
*/
|
||||
@ExcelProperty(value = "岗位序号")
|
||||
@TableId(value = "post_id")
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 岗位编码
|
||||
*/
|
||||
@ExcelProperty(value = "岗位编码")
|
||||
@NotBlank(message = "岗位编码不能为空")
|
||||
@Size(min = 0, max = 64, message = "岗位编码长度不能超过{max}个字符")
|
||||
private String postCode;
|
||||
|
||||
/**
|
||||
* 岗位名称
|
||||
*/
|
||||
@ExcelProperty(value = "岗位名称")
|
||||
@NotBlank(message = "岗位名称不能为空")
|
||||
@Size(min = 0, max = 50, message = "岗位名称长度不能超过{max}个字符")
|
||||
private String postName;
|
||||
|
||||
/**
|
||||
* 岗位排序
|
||||
*/
|
||||
@ExcelProperty(value = "岗位排序")
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
private Integer postSort;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "sys_normal_disable")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 用户是否存在此岗位标识 默认不存在
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private boolean flag = false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 角色和部门关联 sys_role_dept
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@TableName("sys_role_dept")
|
||||
public class SysRoleDept {
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@TableId(type = IdType.INPUT)
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 当前在线会话
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class SysUserOnline {
|
||||
|
||||
/**
|
||||
* 会话编号
|
||||
*/
|
||||
private String tokenId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 登录IP地址
|
||||
*/
|
||||
private String ipaddr;
|
||||
|
||||
/**
|
||||
* 登录地址
|
||||
*/
|
||||
private String loginLocation;
|
||||
|
||||
/**
|
||||
* 浏览器类型
|
||||
*/
|
||||
private String browser;
|
||||
|
||||
/**
|
||||
* 操作系统
|
||||
*/
|
||||
private String os;
|
||||
|
||||
/**
|
||||
* 登录时间
|
||||
*/
|
||||
private Long loginTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户和岗位关联 sys_user_post
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@TableName("sys_user_post")
|
||||
public class SysUserPost {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId(type = IdType.INPUT)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 岗位ID
|
||||
*/
|
||||
private Long postId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.klp.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户和角色关联 sys_user_role
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@TableName("sys_user_role")
|
||||
public class SysUserRole {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId(type = IdType.INPUT)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.klp.system.domain.bo;
|
||||
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* OSS对象存储分页查询对象 sys_oss
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysOssBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* ossId
|
||||
*/
|
||||
private Long ossId;
|
||||
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 原名
|
||||
*/
|
||||
private String originalName;
|
||||
|
||||
/**
|
||||
* 文件后缀名
|
||||
*/
|
||||
private String fileSuffix;
|
||||
|
||||
/**
|
||||
* URL地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 服务商
|
||||
*/
|
||||
private String service;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.klp.system.domain.bo;
|
||||
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 对象存储配置业务对象 sys_oss_config
|
||||
*
|
||||
* @author Lion Li
|
||||
* @author 孤舟烟雨
|
||||
* @date 2021-08-13
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysOssConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主建
|
||||
*/
|
||||
@NotNull(message = "主建不能为空", groups = {EditGroup.class})
|
||||
private Long ossConfigId;
|
||||
|
||||
/**
|
||||
* 配置key
|
||||
*/
|
||||
@NotBlank(message = "配置key不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Size(min = 2, max = 100, message = "configKey长度必须介于{min}和{max} 之间")
|
||||
private String configKey;
|
||||
|
||||
/**
|
||||
* accessKey
|
||||
*/
|
||||
@NotBlank(message = "accessKey不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Size(min = 2, max = 100, message = "accessKey长度必须介于{min}和{max} 之间")
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* 秘钥
|
||||
*/
|
||||
@NotBlank(message = "secretKey不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Size(min = 2, max = 100, message = "secretKey长度必须介于{min}和{max} 之间")
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
@NotBlank(message = "桶名称不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Size(min = 2, max = 100, message = "bucketName长度必须介于{min}和{max}之间")
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
private String prefix;
|
||||
|
||||
/**
|
||||
* 访问站点
|
||||
*/
|
||||
@NotBlank(message = "访问站点不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Size(min = 2, max = 100, message = "endpoint长度必须介于{min}和{max}之间")
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 是否https(Y=是,N=否)
|
||||
*/
|
||||
private String isHttps;
|
||||
|
||||
/**
|
||||
* 是否默认(0=是,1=否)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 域
|
||||
*/
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private String ext1;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 桶权限类型(0private 1public 2custom)
|
||||
*/
|
||||
@NotBlank(message = "桶权限类型不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String accessPolicy;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.klp.system.domain.vo;
|
||||
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 路由显示信息
|
||||
*
|
||||
* @author klp
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class MetaVo {
|
||||
|
||||
/**
|
||||
* 设置该路由在侧边栏和面包屑中展示的名字
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 设置该路由的图标,对应路径src/assets/icons/svg
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 设置为true,则不会被 <keep-alive>缓存
|
||||
*/
|
||||
private boolean noCache;
|
||||
|
||||
/**
|
||||
* 内链地址(http(s)://开头)
|
||||
*/
|
||||
private String link;
|
||||
|
||||
public MetaVo(String title, String icon) {
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public MetaVo(String title, String icon, boolean noCache) {
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.noCache = noCache;
|
||||
}
|
||||
|
||||
public MetaVo(String title, String icon, String link) {
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public MetaVo(String title, String icon, boolean noCache, String link) {
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.noCache = noCache;
|
||||
if (StringUtils.ishttp(link)) {
|
||||
this.link = link;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.klp.system.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 对象存储配置视图对象 sys_oss_config
|
||||
*
|
||||
* @author Lion Li
|
||||
* @author 孤舟烟雨
|
||||
* @date 2021-08-13
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class SysOssConfigVo {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主建
|
||||
*/
|
||||
private Long ossConfigId;
|
||||
|
||||
/**
|
||||
* 配置key
|
||||
*/
|
||||
private String configKey;
|
||||
|
||||
/**
|
||||
* accessKey
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* 秘钥
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
private String prefix;
|
||||
|
||||
/**
|
||||
* 访问站点
|
||||
*/
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 是否https(Y=是,N=否)
|
||||
*/
|
||||
private String isHttps;
|
||||
|
||||
/**
|
||||
* 域
|
||||
*/
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* 是否默认(0=是,1=否)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private String ext1;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 桶权限类型(0private 1public 2custom)
|
||||
*/
|
||||
private String accessPolicy;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.klp.system.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户对象导出VO
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class SysUserExportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@ExcelProperty(value = "用户序号")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@ExcelProperty(value = "登录名称")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
@ExcelProperty(value = "用户名称")
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 用户邮箱
|
||||
*/
|
||||
@ExcelProperty(value = "用户邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 手机号码
|
||||
*/
|
||||
@ExcelProperty(value = "手机号码")
|
||||
private String phonenumber;
|
||||
|
||||
/**
|
||||
* 用户性别
|
||||
*/
|
||||
@ExcelProperty(value = "用户性别", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "sys_user_sex")
|
||||
private String sex;
|
||||
|
||||
/**
|
||||
* 帐号状态(0正常 1停用)
|
||||
*/
|
||||
@ExcelProperty(value = "帐号状态", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "sys_normal_disable")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 最后登录IP
|
||||
*/
|
||||
@ExcelProperty(value = "最后登录IP")
|
||||
private String loginIp;
|
||||
|
||||
/**
|
||||
* 最后登录时间
|
||||
*/
|
||||
@ExcelProperty(value = "最后登录时间")
|
||||
private Date loginDate;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
@ExcelProperty(value = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
@ExcelProperty(value = "部门负责人")
|
||||
private String leader;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.klp.system.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户对象导入VO
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
// @Accessors(chain = true) // 导入不允许使用 会找不到set方法
|
||||
public class SysUserImportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@ExcelProperty(value = "用户序号")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
@ExcelProperty(value = "部门编号")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@ExcelProperty(value = "登录名称")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
@ExcelProperty(value = "用户名称")
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 用户邮箱
|
||||
*/
|
||||
@ExcelProperty(value = "用户邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 手机号码
|
||||
*/
|
||||
@ExcelProperty(value = "手机号码")
|
||||
private String phonenumber;
|
||||
|
||||
/**
|
||||
* 用户性别
|
||||
*/
|
||||
@ExcelProperty(value = "用户性别", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "sys_user_sex")
|
||||
private String sex;
|
||||
|
||||
/**
|
||||
* 帐号状态(0正常 1停用)
|
||||
*/
|
||||
@ExcelProperty(value = "帐号状态", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "sys_normal_disable")
|
||||
private String status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysConfig;
|
||||
|
||||
/**
|
||||
* 参数配置 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysConfigMapper extends BaseMapperPlus<SysConfigMapper, SysConfig, SysConfig> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.klp.common.annotation.DataColumn;
|
||||
import com.klp.common.annotation.DataPermission;
|
||||
import com.klp.common.core.domain.entity.SysDept;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门管理 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysDeptMapper extends BaseMapperPlus<SysDeptMapper, SysDept, SysDept> {
|
||||
|
||||
/**
|
||||
* 查询部门管理数据
|
||||
*
|
||||
* @param queryWrapper 查询条件
|
||||
* @return 部门信息集合
|
||||
*/
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id")
|
||||
})
|
||||
List<SysDept> selectDeptList(@Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询部门树信息
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @param deptCheckStrictly 部门树选择项是否关联显示
|
||||
* @return 选中部门列表
|
||||
*/
|
||||
List<Long> selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.klp.common.constant.UserConstants;
|
||||
import com.klp.common.core.domain.entity.SysDictData;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典表 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysDictDataMapper extends BaseMapperPlus<SysDictDataMapper, SysDictData, SysDictData> {
|
||||
|
||||
default List<SysDictData> selectDictDataByType(String dictType) {
|
||||
return selectList(
|
||||
new LambdaQueryWrapper<SysDictData>()
|
||||
.eq(SysDictData::getStatus, UserConstants.DICT_NORMAL)
|
||||
.eq(SysDictData::getDictType, dictType)
|
||||
.orderByAsc(SysDictData::getDictSort));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.klp.common.constant.UserConstants;
|
||||
import com.klp.common.core.domain.entity.SysMenu;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单表 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysMenuMapper extends BaseMapperPlus<SysMenuMapper, SysMenu, SysMenu> {
|
||||
|
||||
/**
|
||||
* 根据用户所有权限
|
||||
*
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<String> selectMenuPerms();
|
||||
|
||||
/**
|
||||
* 根据用户查询系统菜单列表
|
||||
*
|
||||
* @param queryWrapper 查询条件
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<SysMenu> selectMenuListByUserId(@Param(Constants.WRAPPER) Wrapper<SysMenu> queryWrapper);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询权限
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<String> selectMenuPermsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询权限
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<String> selectMenuPermsByRoleId(Long roleId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询菜单
|
||||
*
|
||||
* @return 菜单列表
|
||||
*/
|
||||
default List<SysMenu> selectMenuTreeAll() {
|
||||
LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<SysMenu>()
|
||||
.in(SysMenu::getMenuType, UserConstants.TYPE_DIR, UserConstants.TYPE_MENU)
|
||||
.eq(SysMenu::getStatus, UserConstants.MENU_NORMAL)
|
||||
.orderByAsc(SysMenu::getParentId)
|
||||
.orderByAsc(SysMenu::getOrderNum);
|
||||
return this.selectList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID查询菜单
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<SysMenu> selectMenuTreeByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询菜单树信息
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @param menuCheckStrictly 菜单树选择项是否关联显示
|
||||
* @return 选中菜单列表
|
||||
*/
|
||||
List<Long> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysNotice;
|
||||
|
||||
/**
|
||||
* 通知公告表 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysNoticeMapper extends BaseMapperPlus<SysNoticeMapper, SysNotice, SysNotice> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysOperLog;
|
||||
|
||||
/**
|
||||
* 操作日志 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysOperLogMapper extends BaseMapperPlus<SysOperLogMapper, SysOperLog, SysOperLog> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysOssConfig;
|
||||
import com.klp.system.domain.vo.SysOssConfigVo;
|
||||
|
||||
/**
|
||||
* 对象存储配置Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @author 孤舟烟雨
|
||||
* @date 2021-08-13
|
||||
*/
|
||||
public interface SysOssConfigMapper extends BaseMapperPlus<SysOssConfigMapper, SysOssConfig, SysOssConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysOss;
|
||||
import com.klp.system.domain.vo.SysOssVo;
|
||||
|
||||
/**
|
||||
* 文件上传 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysOssMapper extends BaseMapperPlus<SysOssMapper, SysOss, SysOssVo> {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysRoleMenu;
|
||||
|
||||
/**
|
||||
* 角色与菜单关联表 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenuMapper, SysRoleMenu, SysRoleMenu> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.klp.system.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.system.domain.SysUserPost;
|
||||
|
||||
/**
|
||||
* 用户与岗位关联表 数据层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysUserPostMapper extends BaseMapperPlus<SysUserPostMapper, SysUserPost, SysUserPost> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.klp.system.runner;
|
||||
|
||||
import com.klp.common.config.KLPConfig;
|
||||
import com.klp.system.service.ISysConfigService;
|
||||
import com.klp.system.service.ISysDictTypeService;
|
||||
import com.klp.system.service.ISysOssConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 初始化 system 模块对应业务数据
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class SystemApplicationRunner implements ApplicationRunner {
|
||||
|
||||
private final KLPConfig ruoyiConfig;
|
||||
private final ISysConfigService configService;
|
||||
private final ISysDictTypeService dictTypeService;
|
||||
private final ISysOssConfigService ossConfigService;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
ossConfigService.init();
|
||||
log.info("初始化OSS配置成功");
|
||||
if (ruoyiConfig.isCacheLazy()) {
|
||||
return;
|
||||
}
|
||||
configService.loadingConfigCache();
|
||||
log.info("加载参数缓存数据成功");
|
||||
dictTypeService.loadingDictCache();
|
||||
log.info("加载字典缓存数据成功");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
/**
|
||||
* 通用 数据权限 服务
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface ISysDataScopeService {
|
||||
|
||||
/**
|
||||
* 获取角色自定义权限
|
||||
*
|
||||
* @param roleId 角色id
|
||||
* @return 部门id组
|
||||
*/
|
||||
String getRoleCustom(Long roleId);
|
||||
|
||||
/**
|
||||
* 获取部门及以下权限
|
||||
*
|
||||
* @param deptId 部门id
|
||||
* @return 部门id组
|
||||
*/
|
||||
String getDeptAndChild(Long deptId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.entity.SysDictData;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典 业务层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface ISysDictDataService {
|
||||
|
||||
|
||||
TableDataInfo<SysDictData> selectPageDictDataList(SysDictData dictData, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 根据条件分页查询字典数据
|
||||
*
|
||||
* @param dictData 字典数据信息
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
List<SysDictData> selectDictDataList(SysDictData dictData);
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典键值查询字典数据信息
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典键值
|
||||
* @return 字典标签
|
||||
*/
|
||||
String selectDictLabel(String dictType, String dictValue);
|
||||
|
||||
/**
|
||||
* 根据字典数据ID查询信息
|
||||
*
|
||||
* @param dictCode 字典数据ID
|
||||
* @return 字典数据
|
||||
*/
|
||||
SysDictData selectDictDataById(Long dictCode);
|
||||
|
||||
/**
|
||||
* 批量删除字典数据信息
|
||||
*
|
||||
* @param dictCodes 需要删除的字典数据ID
|
||||
*/
|
||||
void deleteDictDataByIds(Long[] dictCodes);
|
||||
|
||||
/**
|
||||
* 新增保存字典数据信息
|
||||
*
|
||||
* @param dictData 字典数据信息
|
||||
* @return 结果
|
||||
*/
|
||||
List<SysDictData> insertDictData(SysDictData dictData);
|
||||
|
||||
/**
|
||||
* 修改保存字典数据信息
|
||||
*
|
||||
* @param dictData 字典数据信息
|
||||
* @return 结果
|
||||
*/
|
||||
List<SysDictData> updateDictData(SysDictData dictData);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.system.domain.SysLogininfor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统访问日志情况信息 服务层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface ISysLogininforService {
|
||||
|
||||
|
||||
TableDataInfo<SysLogininfor> selectPageLogininforList(SysLogininfor logininfor, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 新增系统登录日志
|
||||
*
|
||||
* @param logininfor 访问日志对象
|
||||
*/
|
||||
void insertLogininfor(SysLogininfor logininfor);
|
||||
|
||||
/**
|
||||
* 查询系统登录日志集合
|
||||
*
|
||||
* @param logininfor 访问日志对象
|
||||
* @return 登录记录集合
|
||||
*/
|
||||
List<SysLogininfor> selectLogininforList(SysLogininfor logininfor);
|
||||
|
||||
/**
|
||||
* 批量删除系统登录日志
|
||||
*
|
||||
* @param infoIds 需要删除的登录日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteLogininforByIds(Long[] infoIds);
|
||||
|
||||
/**
|
||||
* 清空系统登录日志
|
||||
*/
|
||||
void cleanLogininfor();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.system.domain.SysNotice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 公告 服务层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface ISysNoticeService {
|
||||
|
||||
|
||||
TableDataInfo<SysNotice> selectPageNoticeList(SysNotice notice, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询公告信息
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 公告信息
|
||||
*/
|
||||
SysNotice selectNoticeById(Long noticeId);
|
||||
|
||||
/**
|
||||
* 查询公告列表
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 公告集合
|
||||
*/
|
||||
List<SysNotice> selectNoticeList(SysNotice notice);
|
||||
|
||||
/**
|
||||
* 新增公告
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
int insertNotice(SysNotice notice);
|
||||
|
||||
/**
|
||||
* 修改公告
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateNotice(SysNotice notice);
|
||||
|
||||
/**
|
||||
* 删除公告信息
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteNoticeById(Long noticeId);
|
||||
|
||||
/**
|
||||
* 批量删除公告信息
|
||||
*
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteNoticeByIds(Long[] noticeIds);
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.entity.SysUser;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户 业务层
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface ISysUserService {
|
||||
|
||||
|
||||
TableDataInfo<SysUser> selectPageUserList(SysUser user, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 根据条件分页查询用户列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
*/
|
||||
List<SysUser> selectUserList(SysUser user);
|
||||
|
||||
/**
|
||||
* 根据条件分页查询已分配用户角色列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
*/
|
||||
TableDataInfo<SysUser> selectAllocatedList(SysUser user, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 根据条件分页查询未分配用户角色列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
*/
|
||||
TableDataInfo<SysUser> selectUnallocatedList(SysUser user, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
SysUser selectUserByUserName(String userName);
|
||||
|
||||
/**
|
||||
* 通过手机号查询用户
|
||||
*
|
||||
* @param phonenumber 手机号
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
SysUser selectUserByPhonenumber(String phonenumber);
|
||||
|
||||
/**
|
||||
* 通过用户ID查询用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
SysUser selectUserById(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询用户所属角色组
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 结果
|
||||
*/
|
||||
String selectUserRoleGroup(String userName);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询用户所属岗位组
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 结果
|
||||
*/
|
||||
String selectUserPostGroup(String userName);
|
||||
|
||||
/**
|
||||
* 校验用户名称是否唯一
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
boolean checkUserNameUnique(SysUser user);
|
||||
|
||||
/**
|
||||
* 校验手机号码是否唯一
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
boolean checkPhoneUnique(SysUser user);
|
||||
|
||||
/**
|
||||
* 校验email是否唯一
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
boolean checkEmailUnique(SysUser user);
|
||||
|
||||
/**
|
||||
* 校验用户是否允许操作
|
||||
*
|
||||
* @param user 用户信息
|
||||
*/
|
||||
void checkUserAllowed(SysUser user);
|
||||
|
||||
/**
|
||||
* 校验用户是否有数据权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
*/
|
||||
void checkUserDataScope(Long userId);
|
||||
|
||||
/**
|
||||
* 新增用户信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
int insertUser(SysUser user);
|
||||
|
||||
/**
|
||||
* 注册用户信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
boolean registerUser(SysUser user);
|
||||
|
||||
/**
|
||||
* 修改用户信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateUser(SysUser user);
|
||||
|
||||
/**
|
||||
* 用户授权角色
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleIds 角色组
|
||||
*/
|
||||
void insertUserAuth(Long userId, Long[] roleIds);
|
||||
|
||||
/**
|
||||
* 修改用户状态
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateUserStatus(SysUser user);
|
||||
|
||||
/**
|
||||
* 修改用户基本信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateUserProfile(SysUser user);
|
||||
|
||||
/**
|
||||
* 修改用户头像
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @param avatar 头像地址
|
||||
* @return 结果
|
||||
*/
|
||||
boolean updateUserAvatar(String userName, String avatar);
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
int resetPwd(SysUser user);
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @param password 密码
|
||||
* @return 结果
|
||||
*/
|
||||
int resetUserPwd(String userName, String password);
|
||||
|
||||
/**
|
||||
* 通过用户ID删除用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteUserById(Long userId);
|
||||
|
||||
/**
|
||||
* 批量删除用户信息
|
||||
*
|
||||
* @param userIds 需要删除的用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteUserByIds(Long[] userIds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.klp.common.constant.CacheConstants;
|
||||
import com.klp.common.constant.Constants;
|
||||
import com.klp.common.core.domain.event.LogininforEvent;
|
||||
import com.klp.common.core.domain.dto.RoleDTO;
|
||||
import com.klp.common.core.domain.entity.SysUser;
|
||||
import com.klp.common.core.domain.model.LoginUser;
|
||||
import com.klp.common.core.domain.model.XcxLoginUser;
|
||||
import com.klp.common.enums.DeviceType;
|
||||
import com.klp.common.enums.LoginType;
|
||||
import com.klp.common.enums.UserStatus;
|
||||
import com.klp.common.exception.user.CaptchaException;
|
||||
import com.klp.common.exception.user.CaptchaExpireException;
|
||||
import com.klp.common.exception.user.UserException;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import com.klp.common.utils.DateUtils;
|
||||
import com.klp.common.utils.MessageUtils;
|
||||
import com.klp.common.utils.ServletUtils;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.common.utils.redis.RedisUtils;
|
||||
import com.klp.common.utils.spring.SpringUtils;
|
||||
import com.klp.system.mapper.SysUserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SysLoginService {
|
||||
|
||||
private final SysUserMapper userMapper;
|
||||
private final ISysConfigService configService;
|
||||
private final SysPermissionService permissionService;
|
||||
|
||||
@Value("${user.password.maxRetryCount}")
|
||||
private Integer maxRetryCount;
|
||||
|
||||
@Value("${user.password.lockTime}")
|
||||
private Integer lockTime;
|
||||
|
||||
/**
|
||||
* 登录验证
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(String username, String password, String code, String uuid) {
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
// 验证码开关
|
||||
if (captchaEnabled) {
|
||||
validateCaptcha(username, code, uuid);
|
||||
}
|
||||
SysUser user = loadUserByUsername(username);
|
||||
checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
|
||||
|
||||
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId(), username);
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String smsLogin(String phonenumber, String smsCode) {
|
||||
// 通过手机号查找用户
|
||||
SysUser user = loadUserByPhonenumber(phonenumber);
|
||||
|
||||
checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.APP);
|
||||
|
||||
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId(), user.getUserName());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String emailLogin(String email, String emailCode) {
|
||||
// 通过手机号查找用户
|
||||
SysUser user = loadUserByEmail(email);
|
||||
|
||||
checkLogin(LoginType.EMAIL, user.getUserName(), () -> !validateEmailCode(email, emailCode));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.APP);
|
||||
|
||||
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId(), user.getUserName());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String xcxLogin(String xcxCode) {
|
||||
// xcxCode 为 小程序调用 wx.login 授权后获取
|
||||
// todo 以下自行实现
|
||||
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
|
||||
String openid = "";
|
||||
SysUser user = loadUserByOpenid(openid);
|
||||
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
XcxLoginUser loginUser = new XcxLoginUser();
|
||||
loginUser.setUserId(user.getUserId());
|
||||
loginUser.setUsername(user.getUserName());
|
||||
loginUser.setUserType(user.getUserType());
|
||||
loginUser.setOpenid(openid);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
|
||||
|
||||
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId(), user.getUserName());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
public void logout() {
|
||||
try {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
StpUtil.logout();
|
||||
recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
|
||||
} catch (NotLoginException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息内容
|
||||
*/
|
||||
private void recordLogininfor(String username, String status, String message) {
|
||||
LogininforEvent logininforEvent = new LogininforEvent();
|
||||
logininforEvent.setUsername(username);
|
||||
logininforEvent.setStatus(status);
|
||||
logininforEvent.setMessage(message);
|
||||
logininforEvent.setRequest(ServletUtils.getRequest());
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验短信验证码
|
||||
*/
|
||||
private boolean validateSmsCode(String phonenumber, String smsCode) {
|
||||
String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phonenumber);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
return code.equals(smsCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验邮箱验证码
|
||||
*/
|
||||
private boolean validateEmailCode(String email, String emailCode) {
|
||||
String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + email);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
recordLogininfor(email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
return code.equals(emailCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
*/
|
||||
public void validateCaptcha(String username, String code, String uuid) {
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
if (captcha == null) {
|
||||
recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
if (!code.equalsIgnoreCase(captcha)) {
|
||||
recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
}
|
||||
|
||||
private SysUser loadUserByUsername(String username) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getUserName, SysUser::getStatus)
|
||||
.eq(SysUser::getUserName, username));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", username);
|
||||
throw new UserException("user.not.exists", username);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", username);
|
||||
throw new UserException("user.blocked", username);
|
||||
}
|
||||
return userMapper.selectUserByUserName(username);
|
||||
}
|
||||
|
||||
private SysUser loadUserByPhonenumber(String phonenumber) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getPhonenumber, SysUser::getStatus)
|
||||
.eq(SysUser::getPhonenumber, phonenumber));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", phonenumber);
|
||||
throw new UserException("user.not.exists", phonenumber);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", phonenumber);
|
||||
throw new UserException("user.blocked", phonenumber);
|
||||
}
|
||||
return userMapper.selectUserByPhonenumber(phonenumber);
|
||||
}
|
||||
|
||||
private SysUser loadUserByEmail(String email) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getPhonenumber, SysUser::getStatus)
|
||||
.eq(SysUser::getEmail, email));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", email);
|
||||
throw new UserException("user.not.exists", email);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", email);
|
||||
throw new UserException("user.blocked", email);
|
||||
}
|
||||
return userMapper.selectUserByEmail(email);
|
||||
}
|
||||
|
||||
private SysUser loadUserByOpenid(String openid) {
|
||||
// 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户
|
||||
// todo 自行实现 userService.selectUserByOpenid(openid);
|
||||
SysUser user = new SysUser();
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", openid);
|
||||
// todo 用户不存在 业务逻辑自行实现
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", openid);
|
||||
// todo 用户已被停用 业务逻辑自行实现
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建登录用户
|
||||
*/
|
||||
private LoginUser buildLoginUser(SysUser user) {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
loginUser.setUserId(user.getUserId());
|
||||
loginUser.setDeptId(user.getDeptId());
|
||||
loginUser.setUsername(user.getUserName());
|
||||
loginUser.setNickName(user.getNickName());
|
||||
loginUser.setUserType(user.getUserType());
|
||||
loginUser.setMenuPermission(permissionService.getMenuPermission(user));
|
||||
loginUser.setRolePermission(permissionService.getRolePermission(user));
|
||||
loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
|
||||
List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
|
||||
loginUser.setRoles(roles);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
public void recordLoginInfo(Long userId, String username) {
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserId(userId);
|
||||
sysUser.setLoginIp(ServletUtils.getClientIP());
|
||||
sysUser.setLoginDate(DateUtils.getNowDate());
|
||||
sysUser.setUpdateBy(username);
|
||||
userMapper.updateById(sysUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录校验
|
||||
*/
|
||||
private void checkLogin(LoginType loginType, String username, Supplier<Boolean> supplier) {
|
||||
String errorKey = CacheConstants.PWD_ERR_CNT_KEY + username;
|
||||
String loginFail = Constants.LOGIN_FAIL;
|
||||
|
||||
// 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip)
|
||||
Integer errorNumber = RedisUtils.getCacheObject(errorKey);
|
||||
// 锁定时间内登录 则踢出
|
||||
if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(maxRetryCount)) {
|
||||
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
|
||||
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
|
||||
}
|
||||
|
||||
if (supplier.get()) {
|
||||
// 是否第一次
|
||||
errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
|
||||
// 达到规定错误次数 则锁定登录
|
||||
if (errorNumber.equals(maxRetryCount)) {
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
|
||||
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
|
||||
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
|
||||
} else {
|
||||
// 未达到规定错误次数 则递增
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber);
|
||||
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
|
||||
throw new UserException(loginType.getRetryLimitCount(), errorNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// 登录成功 清空错误次数
|
||||
RedisUtils.deleteObject(errorKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.klp.system.service;
|
||||
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import com.klp.common.constant.CacheConstants;
|
||||
import com.klp.common.constant.Constants;
|
||||
import com.klp.common.core.domain.event.LogininforEvent;
|
||||
import com.klp.common.core.domain.entity.SysUser;
|
||||
import com.klp.common.core.domain.model.RegisterBody;
|
||||
import com.klp.common.enums.UserType;
|
||||
import com.klp.common.exception.user.CaptchaException;
|
||||
import com.klp.common.exception.user.CaptchaExpireException;
|
||||
import com.klp.common.exception.user.UserException;
|
||||
import com.klp.common.utils.MessageUtils;
|
||||
import com.klp.common.utils.ServletUtils;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.common.utils.redis.RedisUtils;
|
||||
import com.klp.common.utils.spring.SpringUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 注册校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysRegisterService {
|
||||
|
||||
private final ISysUserService userService;
|
||||
private final ISysConfigService configService;
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
public void register(RegisterBody registerBody) {
|
||||
String username = registerBody.getUsername();
|
||||
String password = registerBody.getPassword();
|
||||
// 校验用户类型是否存在
|
||||
String userType = UserType.getUserType(registerBody.getUserType()).getUserType();
|
||||
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
// 验证码开关
|
||||
if (captchaEnabled) {
|
||||
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
|
||||
}
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserName(username);
|
||||
sysUser.setNickName(username);
|
||||
sysUser.setPassword(BCrypt.hashpw(password));
|
||||
sysUser.setUserType(userType);
|
||||
|
||||
if (!userService.checkUserNameUnique(sysUser)) {
|
||||
throw new UserException("user.register.save.error", username);
|
||||
}
|
||||
boolean regFlag = userService.registerUser(sysUser);
|
||||
if (!regFlag) {
|
||||
throw new UserException("user.register.error");
|
||||
}
|
||||
recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
*/
|
||||
public void validateCaptcha(String username, String code, String uuid) {
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
if (captcha == null) {
|
||||
recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
if (!code.equalsIgnoreCase(captcha)) {
|
||||
recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息内容
|
||||
* @return
|
||||
*/
|
||||
private void recordLogininfor(String username, String status, String message) {
|
||||
LogininforEvent logininforEvent = new LogininforEvent();
|
||||
logininforEvent.setUsername(username);
|
||||
logininforEvent.setStatus(status);
|
||||
logininforEvent.setMessage(message);
|
||||
logininforEvent.setRequest(ServletUtils.getRequest());
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.constant.CacheNames;
|
||||
import com.klp.common.constant.UserConstants;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.service.ConfigService;
|
||||
import com.klp.common.exception.ServiceException;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.common.utils.redis.CacheUtils;
|
||||
import com.klp.common.utils.spring.SpringUtils;
|
||||
import com.klp.system.domain.SysConfig;
|
||||
import com.klp.system.mapper.SysConfigMapper;
|
||||
import com.klp.system.service.ISysConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 参数配置 服务层实现
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
|
||||
|
||||
private final SysConfigMapper baseMapper;
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysConfig> selectPageConfigList(SysConfig config, PageQuery pageQuery) {
|
||||
Map<String, Object> params = config.getParams();
|
||||
LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
|
||||
.like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
|
||||
.eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
|
||||
.like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime"));
|
||||
Page<SysConfig> page = baseMapper.selectPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询参数配置信息
|
||||
*
|
||||
* @param configId 参数配置ID
|
||||
* @return 参数配置信息
|
||||
*/
|
||||
@Override
|
||||
@DS("master")
|
||||
public SysConfig selectConfigById(Long configId) {
|
||||
return baseMapper.selectById(configId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据键名查询参数配置信息
|
||||
*
|
||||
* @param configKey 参数key
|
||||
* @return 参数键值
|
||||
*/
|
||||
@Cacheable(cacheNames = CacheNames.SYS_CONFIG, key = "#configKey")
|
||||
@Override
|
||||
public String selectConfigByKey(String configKey) {
|
||||
SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
|
||||
.eq(SysConfig::getConfigKey, configKey));
|
||||
if (ObjectUtil.isNotNull(retConfig)) {
|
||||
return retConfig.getConfigValue();
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码开关
|
||||
*
|
||||
* @return true开启,false关闭
|
||||
*/
|
||||
@Override
|
||||
public boolean selectCaptchaEnabled() {
|
||||
String captchaEnabled = SpringUtils.getAopProxy(this).selectConfigByKey("sys.account.captchaEnabled");
|
||||
if (StringUtils.isEmpty(captchaEnabled)) {
|
||||
return true;
|
||||
}
|
||||
return Convert.toBool(captchaEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询参数配置列表
|
||||
*
|
||||
* @param config 参数配置信息
|
||||
* @return 参数配置集合
|
||||
*/
|
||||
@Override
|
||||
public List<SysConfig> selectConfigList(SysConfig config) {
|
||||
Map<String, Object> params = config.getParams();
|
||||
LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
|
||||
.like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
|
||||
.eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
|
||||
.like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime"));
|
||||
return baseMapper.selectList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增参数配置
|
||||
*
|
||||
* @param config 参数配置信息
|
||||
* @return 结果
|
||||
*/
|
||||
@CachePut(cacheNames = CacheNames.SYS_CONFIG, key = "#config.configKey")
|
||||
@Override
|
||||
public String insertConfig(SysConfig config) {
|
||||
int row = baseMapper.insert(config);
|
||||
if (row > 0) {
|
||||
return config.getConfigValue();
|
||||
}
|
||||
throw new ServiceException("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改参数配置
|
||||
*
|
||||
* @param config 参数配置信息
|
||||
* @return 结果
|
||||
*/
|
||||
@CachePut(cacheNames = CacheNames.SYS_CONFIG, key = "#config.configKey")
|
||||
@Override
|
||||
public String updateConfig(SysConfig config) {
|
||||
int row = 0;
|
||||
if (config.getConfigId() != null) {
|
||||
SysConfig temp = baseMapper.selectById(config.getConfigId());
|
||||
if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) {
|
||||
CacheUtils.evict(CacheNames.SYS_CONFIG, temp.getConfigKey());
|
||||
}
|
||||
row = baseMapper.updateById(config);
|
||||
} else {
|
||||
row = baseMapper.update(config, new LambdaQueryWrapper<SysConfig>()
|
||||
.eq(SysConfig::getConfigKey, config.getConfigKey()));
|
||||
}
|
||||
if (row > 0) {
|
||||
return config.getConfigValue();
|
||||
}
|
||||
throw new ServiceException("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除参数信息
|
||||
*
|
||||
* @param configIds 需要删除的参数ID
|
||||
*/
|
||||
@Override
|
||||
public void deleteConfigByIds(Long[] configIds) {
|
||||
for (Long configId : configIds) {
|
||||
SysConfig config = selectConfigById(configId);
|
||||
if (StringUtils.equals(UserConstants.YES, config.getConfigType())) {
|
||||
throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
|
||||
}
|
||||
CacheUtils.evict(CacheNames.SYS_CONFIG, config.getConfigKey());
|
||||
}
|
||||
baseMapper.deleteBatchIds(Arrays.asList(configIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载参数缓存数据
|
||||
*/
|
||||
@Override
|
||||
public void loadingConfigCache() {
|
||||
List<SysConfig> configsList = selectConfigList(new SysConfig());
|
||||
configsList.forEach(config ->
|
||||
CacheUtils.put(CacheNames.SYS_CONFIG, config.getConfigKey(), config.getConfigValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空参数缓存数据
|
||||
*/
|
||||
@Override
|
||||
public void clearConfigCache() {
|
||||
CacheUtils.clear(CacheNames.SYS_CONFIG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置参数缓存数据
|
||||
*/
|
||||
@Override
|
||||
public void resetConfigCache() {
|
||||
clearConfigCache();
|
||||
loadingConfigCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验参数键名是否唯一
|
||||
*
|
||||
* @param config 参数配置信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkConfigKeyUnique(SysConfig config) {
|
||||
long configId = ObjectUtil.isNull(config.getConfigId()) ? -1L : config.getConfigId();
|
||||
SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
|
||||
if (ObjectUtil.isNotNull(info) && info.getConfigId() != configId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取参数值
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return 参数值
|
||||
*/
|
||||
@Override
|
||||
public String getConfigValue(String configKey) {
|
||||
return SpringUtils.getAopProxy(this).selectConfigByKey(configKey);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.klp.common.core.domain.entity.SysDept;
|
||||
import com.klp.common.helper.DataBaseHelper;
|
||||
import com.klp.common.utils.StreamUtils;
|
||||
import com.klp.system.domain.SysRoleDept;
|
||||
import com.klp.system.mapper.SysDeptMapper;
|
||||
import com.klp.system.mapper.SysRoleDeptMapper;
|
||||
import com.klp.system.service.ISysDataScopeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据权限 实现
|
||||
* <p>
|
||||
* 注意: 此Service内不允许调用标注`数据权限`注解的方法
|
||||
* 例如: deptMapper.selectList 此 selectList 方法标注了`数据权限`注解 会出现循环解析的问题
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service("sdss")
|
||||
public class SysDataScopeServiceImpl implements ISysDataScopeService {
|
||||
|
||||
private final SysRoleDeptMapper roleDeptMapper;
|
||||
private final SysDeptMapper deptMapper;
|
||||
|
||||
@Override
|
||||
public String getRoleCustom(Long roleId) {
|
||||
List<SysRoleDept> list = roleDeptMapper.selectList(
|
||||
new LambdaQueryWrapper<SysRoleDept>()
|
||||
.select(SysRoleDept::getDeptId)
|
||||
.eq(SysRoleDept::getRoleId, roleId));
|
||||
if (CollUtil.isNotEmpty(list)) {
|
||||
return StreamUtils.join(list, rd -> Convert.toStr(rd.getDeptId()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeptAndChild(Long deptId) {
|
||||
List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
|
||||
.select(SysDept::getDeptId)
|
||||
.apply(DataBaseHelper.findInSet(deptId, "ancestors")));
|
||||
List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
|
||||
ids.add(deptId);
|
||||
List<SysDept> list = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
|
||||
.select(SysDept::getDeptId)
|
||||
.in(SysDept::getDeptId, ids));
|
||||
if (CollUtil.isNotEmpty(list)) {
|
||||
return StreamUtils.join(list, d -> Convert.toStr(d.getDeptId()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.constant.CacheConstants;
|
||||
import com.klp.common.constant.CacheNames;
|
||||
import com.klp.common.constant.UserConstants;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.entity.SysDictData;
|
||||
import com.klp.common.core.domain.entity.SysDictType;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.service.DictService;
|
||||
import com.klp.common.exception.ServiceException;
|
||||
import com.klp.common.utils.StreamUtils;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.common.utils.redis.CacheUtils;
|
||||
import com.klp.common.utils.spring.SpringUtils;
|
||||
import com.klp.system.mapper.SysDictDataMapper;
|
||||
import com.klp.system.mapper.SysDictTypeMapper;
|
||||
import com.klp.system.service.ISysDictTypeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 字典 业务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService {
|
||||
|
||||
private final SysDictTypeMapper baseMapper;
|
||||
private final SysDictDataMapper dictDataMapper;
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery) {
|
||||
Map<String, Object> params = dictType.getParams();
|
||||
LambdaQueryWrapper<SysDictType> lqw = new LambdaQueryWrapper<SysDictType>()
|
||||
.like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
|
||||
.eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
|
||||
.like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime"));
|
||||
Page<SysDictType> page = baseMapper.selectPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件分页查询字典类型
|
||||
*
|
||||
* @param dictType 字典类型信息
|
||||
* @return 字典类型集合信息
|
||||
*/
|
||||
@Override
|
||||
public List<SysDictType> selectDictTypeList(SysDictType dictType) {
|
||||
Map<String, Object> params = dictType.getParams();
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<SysDictType>()
|
||||
.like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
|
||||
.eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
|
||||
.like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime")));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据所有字典类型
|
||||
*
|
||||
* @return 字典类型集合信息
|
||||
*/
|
||||
@Override
|
||||
public List<SysDictType> selectDictTypeAll() {
|
||||
return baseMapper.selectList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
@Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
|
||||
@Override
|
||||
public List<SysDictData> selectDictDataByType(String dictType) {
|
||||
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType);
|
||||
if (CollUtil.isNotEmpty(dictDatas)) {
|
||||
return dictDatas;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型ID查询信息
|
||||
*
|
||||
* @param dictId 字典类型ID
|
||||
* @return 字典类型
|
||||
*/
|
||||
@Override
|
||||
public SysDictType selectDictTypeById(Long dictId) {
|
||||
return baseMapper.selectById(dictId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询信息
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典类型
|
||||
*/
|
||||
@Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
|
||||
@Override
|
||||
public SysDictType selectDictTypeByType(String dictType) {
|
||||
return baseMapper.selectById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除字典类型信息
|
||||
*
|
||||
* @param dictIds 需要删除的字典ID
|
||||
*/
|
||||
@Override
|
||||
public void deleteDictTypeByIds(Long[] dictIds) {
|
||||
for (Long dictId : dictIds) {
|
||||
SysDictType dictType = selectDictTypeById(dictId);
|
||||
if (dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
|
||||
.eq(SysDictData::getDictType, dictType.getDictType()))) {
|
||||
throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
|
||||
}
|
||||
CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
|
||||
}
|
||||
baseMapper.deleteBatchIds(Arrays.asList(dictIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载字典缓存数据
|
||||
*/
|
||||
@Override
|
||||
public void loadingDictCache() {
|
||||
List<SysDictData> dictDataList = dictDataMapper.selectList(
|
||||
new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getStatus, UserConstants.DICT_NORMAL));
|
||||
Map<String, List<SysDictData>> dictDataMap = StreamUtils.groupByKey(dictDataList, SysDictData::getDictType);
|
||||
dictDataMap.forEach((k,v) -> {
|
||||
List<SysDictData> dictList = StreamUtils.sorted(v, Comparator.comparing(SysDictData::getDictSort));
|
||||
CacheUtils.put(CacheNames.SYS_DICT, k, dictList);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空字典缓存数据
|
||||
*/
|
||||
@Override
|
||||
public void clearDictCache() {
|
||||
CacheUtils.clear(CacheNames.SYS_DICT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置字典缓存数据
|
||||
*/
|
||||
@Override
|
||||
public void resetDictCache() {
|
||||
clearDictCache();
|
||||
loadingDictCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存字典类型信息
|
||||
*
|
||||
* @param dict 字典类型信息
|
||||
* @return 结果
|
||||
*/
|
||||
@CachePut(cacheNames = CacheNames.SYS_DICT, key = "#dict.dictType")
|
||||
@Override
|
||||
public List<SysDictData> insertDictType(SysDictType dict) {
|
||||
int row = baseMapper.insert(dict);
|
||||
if (row > 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
throw new ServiceException("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存字典类型信息
|
||||
*
|
||||
* @param dict 字典类型信息
|
||||
* @return 结果
|
||||
*/
|
||||
@CachePut(cacheNames = CacheNames.SYS_DICT, key = "#dict.dictType")
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<SysDictData> updateDictType(SysDictType dict) {
|
||||
SysDictType oldDict = baseMapper.selectById(dict.getDictId());
|
||||
dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
|
||||
.set(SysDictData::getDictType, dict.getDictType())
|
||||
.eq(SysDictData::getDictType, oldDict.getDictType()));
|
||||
int row = baseMapper.updateById(dict);
|
||||
if (row > 0) {
|
||||
CacheUtils.evict(CacheNames.SYS_DICT, oldDict.getDictType());
|
||||
return dictDataMapper.selectDictDataByType(dict.getDictType());
|
||||
}
|
||||
throw new ServiceException("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验字典类型称是否唯一
|
||||
*
|
||||
* @param dict 字典类型
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkDictTypeUnique(SysDictType dict) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDictType>()
|
||||
.eq(SysDictType::getDictType, dict.getDictType())
|
||||
.ne(ObjectUtil.isNotNull(dict.getDictId()), SysDictType::getDictId, dict.getDictId()));
|
||||
return !exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @param separator 分隔符
|
||||
* @return 字典标签
|
||||
*/
|
||||
@SuppressWarnings("unchecked cast")
|
||||
@Override
|
||||
public String getDictLabel(String dictType, String dictValue, String separator) {
|
||||
// 优先从本地缓存获取
|
||||
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
|
||||
if (ObjectUtil.isNull(datas)) {
|
||||
datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
|
||||
SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
|
||||
}
|
||||
|
||||
Map<String, String> map = StreamUtils.toMap(datas, SysDictData::getDictValue, SysDictData::getDictLabel);
|
||||
if (StringUtils.containsAny(dictValue, separator)) {
|
||||
return Arrays.stream(dictValue.split(separator))
|
||||
.map(v -> map.getOrDefault(v, StringUtils.EMPTY))
|
||||
.collect(Collectors.joining(separator));
|
||||
} else {
|
||||
return map.getOrDefault(dictValue, StringUtils.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @param separator 分隔符
|
||||
* @return 字典值
|
||||
*/
|
||||
@SuppressWarnings("unchecked cast")
|
||||
@Override
|
||||
public String getDictValue(String dictType, String dictLabel, String separator) {
|
||||
// 优先从本地缓存获取
|
||||
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
|
||||
if (ObjectUtil.isNull(datas)) {
|
||||
datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
|
||||
SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
|
||||
}
|
||||
|
||||
Map<String, String> map = StreamUtils.toMap(datas, SysDictData::getDictLabel, SysDictData::getDictValue);
|
||||
if (StringUtils.containsAny(dictLabel, separator)) {
|
||||
return Arrays.stream(dictLabel.split(separator))
|
||||
.map(l -> map.getOrDefault(l, StringUtils.EMPTY))
|
||||
.collect(Collectors.joining(separator));
|
||||
} else {
|
||||
return map.getOrDefault(dictLabel, StringUtils.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.constant.Constants;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.event.LogininforEvent;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.utils.ServletUtils;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.common.utils.ip.AddressUtils;
|
||||
import com.klp.system.domain.SysLogininfor;
|
||||
import com.klp.system.mapper.SysLogininforMapper;
|
||||
import com.klp.system.service.ISysLogininforService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统访问日志情况信息 服务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SysLogininforServiceImpl implements ISysLogininforService {
|
||||
|
||||
private final SysLogininforMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param logininforEvent 登录事件
|
||||
*/
|
||||
@Async
|
||||
@EventListener
|
||||
public void recordLogininfor(LogininforEvent logininforEvent) {
|
||||
HttpServletRequest request = logininforEvent.getRequest();
|
||||
final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
|
||||
final String ip = ServletUtils.getClientIP(request);
|
||||
|
||||
String address = AddressUtils.getRealAddressByIP(ip);
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(getBlock(ip));
|
||||
s.append(address);
|
||||
s.append(getBlock(logininforEvent.getUsername()));
|
||||
s.append(getBlock(logininforEvent.getStatus()));
|
||||
s.append(getBlock(logininforEvent.getMessage()));
|
||||
// 打印信息到日志
|
||||
log.info(s.toString(), logininforEvent.getArgs());
|
||||
// 获取客户端操作系统
|
||||
String os = userAgent.getOs().getName();
|
||||
// 获取客户端浏览器
|
||||
String browser = userAgent.getBrowser().getName();
|
||||
// 封装对象
|
||||
SysLogininfor logininfor = new SysLogininfor();
|
||||
logininfor.setUserName(logininforEvent.getUsername());
|
||||
logininfor.setIpaddr(ip);
|
||||
logininfor.setLoginLocation(address);
|
||||
logininfor.setBrowser(browser);
|
||||
logininfor.setOs(os);
|
||||
logininfor.setMsg(logininforEvent.getMessage());
|
||||
// 日志状态
|
||||
if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
|
||||
logininfor.setStatus(Constants.SUCCESS);
|
||||
} else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
|
||||
logininfor.setStatus(Constants.FAIL);
|
||||
}
|
||||
// 插入数据
|
||||
insertLogininfor(logininfor);
|
||||
}
|
||||
|
||||
private String getBlock(Object msg) {
|
||||
if (msg == null) {
|
||||
msg = "";
|
||||
}
|
||||
return "[" + msg.toString() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysLogininfor> selectPageLogininforList(SysLogininfor logininfor, PageQuery pageQuery) {
|
||||
Map<String, Object> params = logininfor.getParams();
|
||||
LambdaQueryWrapper<SysLogininfor> lqw = new LambdaQueryWrapper<SysLogininfor>()
|
||||
.like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
|
||||
.eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
|
||||
.like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"));
|
||||
if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
|
||||
pageQuery.setOrderByColumn("info_id");
|
||||
pageQuery.setIsAsc("desc");
|
||||
}
|
||||
Page<SysLogininfor> page = baseMapper.selectPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增系统登录日志
|
||||
*
|
||||
* @param logininfor 访问日志对象
|
||||
*/
|
||||
@Override
|
||||
public void insertLogininfor(SysLogininfor logininfor) {
|
||||
logininfor.setLoginTime(new Date());
|
||||
baseMapper.insert(logininfor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询系统登录日志集合
|
||||
*
|
||||
* @param logininfor 访问日志对象
|
||||
* @return 登录记录集合
|
||||
*/
|
||||
@Override
|
||||
public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor) {
|
||||
Map<String, Object> params = logininfor.getParams();
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<SysLogininfor>()
|
||||
.like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
|
||||
.eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
|
||||
.like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"))
|
||||
.orderByDesc(SysLogininfor::getInfoId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除系统登录日志
|
||||
*
|
||||
* @param infoIds 需要删除的登录日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteLogininforByIds(Long[] infoIds) {
|
||||
return baseMapper.deleteBatchIds(Arrays.asList(infoIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空系统登录日志
|
||||
*/
|
||||
@Override
|
||||
public void cleanLogininfor() {
|
||||
baseMapper.delete(new LambdaQueryWrapper<>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.exception.ServiceException;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.system.domain.SysPost;
|
||||
import com.klp.system.domain.SysUserPost;
|
||||
import com.klp.system.mapper.SysPostMapper;
|
||||
import com.klp.system.mapper.SysUserPostMapper;
|
||||
import com.klp.system.service.ISysPostService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 岗位信息 服务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysPostServiceImpl implements ISysPostService {
|
||||
|
||||
private final SysPostMapper baseMapper;
|
||||
private final SysUserPostMapper userPostMapper;
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysPost> selectPagePostList(SysPost post, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<SysPost> lqw = new LambdaQueryWrapper<SysPost>()
|
||||
.like(StringUtils.isNotBlank(post.getPostCode()), SysPost::getPostCode, post.getPostCode())
|
||||
.eq(StringUtils.isNotBlank(post.getStatus()), SysPost::getStatus, post.getStatus())
|
||||
.like(StringUtils.isNotBlank(post.getPostName()), SysPost::getPostName, post.getPostName());
|
||||
Page<SysPost> page = baseMapper.selectPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询岗位信息集合
|
||||
*
|
||||
* @param post 岗位信息
|
||||
* @return 岗位信息集合
|
||||
*/
|
||||
@Override
|
||||
public List<SysPost> selectPostList(SysPost post) {
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<SysPost>()
|
||||
.like(StringUtils.isNotBlank(post.getPostCode()), SysPost::getPostCode, post.getPostCode())
|
||||
.eq(StringUtils.isNotBlank(post.getStatus()), SysPost::getStatus, post.getStatus())
|
||||
.like(StringUtils.isNotBlank(post.getPostName()), SysPost::getPostName, post.getPostName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有岗位
|
||||
*
|
||||
* @return 岗位列表
|
||||
*/
|
||||
@Override
|
||||
public List<SysPost> selectPostAll() {
|
||||
return baseMapper.selectList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过岗位ID查询岗位信息
|
||||
*
|
||||
* @param postId 岗位ID
|
||||
* @return 角色对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysPost selectPostById(Long postId) {
|
||||
return baseMapper.selectById(postId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取岗位选择框列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 选中岗位ID列表
|
||||
*/
|
||||
@Override
|
||||
public List<Long> selectPostListByUserId(Long userId) {
|
||||
return baseMapper.selectPostListByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验岗位名称是否唯一
|
||||
*
|
||||
* @param post 岗位信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkPostNameUnique(SysPost post) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
|
||||
.eq(SysPost::getPostName, post.getPostName())
|
||||
.ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
|
||||
return !exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验岗位编码是否唯一
|
||||
*
|
||||
* @param post 岗位信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkPostCodeUnique(SysPost post) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
|
||||
.eq(SysPost::getPostCode, post.getPostCode())
|
||||
.ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
|
||||
return !exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过岗位ID查询岗位使用数量
|
||||
*
|
||||
* @param postId 岗位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public long countUserPostById(Long postId) {
|
||||
return userPostMapper.selectCount(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getPostId, postId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除岗位信息
|
||||
*
|
||||
* @param postId 岗位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deletePostById(Long postId) {
|
||||
return baseMapper.deleteById(postId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除岗位信息
|
||||
*
|
||||
* @param postIds 需要删除的岗位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deletePostByIds(Long[] postIds) {
|
||||
for (Long postId : postIds) {
|
||||
SysPost post = selectPostById(postId);
|
||||
if (countUserPostById(postId) > 0) {
|
||||
throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName()));
|
||||
}
|
||||
}
|
||||
return baseMapper.deleteBatchIds(Arrays.asList(postIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存岗位信息
|
||||
*
|
||||
* @param post 岗位信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertPost(SysPost post) {
|
||||
return baseMapper.insert(post);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存岗位信息
|
||||
*
|
||||
* @param post 岗位信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updatePost(SysPost post) {
|
||||
return baseMapper.updateById(post);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import com.klp.common.core.service.SensitiveService;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 脱敏服务
|
||||
* 默认管理员不过滤
|
||||
* 需自行根据业务重写实现
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
*/
|
||||
@Service
|
||||
public class SysSensitiveServiceImpl implements SensitiveService {
|
||||
|
||||
/**
|
||||
* 是否脱敏
|
||||
*/
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return !LoginHelper.isAdmin();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
package com.klp.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.constant.CacheNames;
|
||||
import com.klp.common.constant.UserConstants;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.entity.SysDept;
|
||||
import com.klp.common.core.domain.entity.SysRole;
|
||||
import com.klp.common.core.domain.entity.SysUser;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.service.UserService;
|
||||
import com.klp.common.exception.ServiceException;
|
||||
import com.klp.common.helper.DataBaseHelper;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import com.klp.common.utils.StreamUtils;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.system.domain.SysPost;
|
||||
import com.klp.system.domain.SysUserPost;
|
||||
import com.klp.system.domain.SysUserRole;
|
||||
import com.klp.system.mapper.*;
|
||||
import com.klp.system.service.ISysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户 业务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysUserServiceImpl implements ISysUserService, UserService {
|
||||
|
||||
private final SysUserMapper baseMapper;
|
||||
private final SysDeptMapper deptMapper;
|
||||
private final SysRoleMapper roleMapper;
|
||||
private final SysPostMapper postMapper;
|
||||
private final SysUserRoleMapper userRoleMapper;
|
||||
private final SysUserPostMapper userPostMapper;
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysUser> selectPageUserList(SysUser user, PageQuery pageQuery) {
|
||||
Page<SysUser> page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user));
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件分页查询用户列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
*/
|
||||
@Override
|
||||
public List<SysUser> selectUserList(SysUser user) {
|
||||
return baseMapper.selectUserList(this.buildQueryWrapper(user));
|
||||
}
|
||||
|
||||
private Wrapper<SysUser> buildQueryWrapper(SysUser user) {
|
||||
Map<String, Object> params = user.getParams();
|
||||
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
||||
wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
|
||||
.eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
|
||||
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
|
||||
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
|
||||
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
"u.create_time", params.get("beginTime"), params.get("endTime"))
|
||||
.and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
|
||||
List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
|
||||
.select(SysDept::getDeptId)
|
||||
.apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors")));
|
||||
List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
|
||||
ids.add(user.getDeptId());
|
||||
w.in("u.dept_id", ids);
|
||||
});
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件分页查询已分配用户角色列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<SysUser> selectAllocatedList(SysUser user, PageQuery pageQuery) {
|
||||
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
||||
wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
|
||||
.eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId())
|
||||
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
|
||||
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
|
||||
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
|
||||
Page<SysUser> page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件分页查询未分配用户角色列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<SysUser> selectUnallocatedList(SysUser user, PageQuery pageQuery) {
|
||||
List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
|
||||
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
||||
wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
|
||||
.and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id"))
|
||||
.notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds)
|
||||
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
|
||||
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
|
||||
Page<SysUser> page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysUser selectUserByUserName(String userName) {
|
||||
return baseMapper.selectUserByUserName(userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过手机号查询用户
|
||||
*
|
||||
* @param phonenumber 手机号
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysUser selectUserByPhonenumber(String phonenumber) {
|
||||
return baseMapper.selectUserByPhonenumber(phonenumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户ID查询用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysUser selectUserById(Long userId) {
|
||||
return baseMapper.selectUserById(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户所属角色组
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public String selectUserRoleGroup(String userName) {
|
||||
List<SysRole> list = roleMapper.selectRolesByUserName(userName);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return StreamUtils.join(list, SysRole::getRoleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户所属岗位组
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public String selectUserPostGroup(String userName) {
|
||||
List<SysPost> list = postMapper.selectPostsByUserName(userName);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return StreamUtils.join(list, SysPost::getPostName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验用户名称是否唯一
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkUserNameUnique(SysUser user) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getUserName, user.getUserName())
|
||||
.ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
|
||||
return !exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验手机号码是否唯一
|
||||
*
|
||||
* @param user 用户信息
|
||||
*/
|
||||
@Override
|
||||
public boolean checkPhoneUnique(SysUser user) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getPhonenumber, user.getPhonenumber())
|
||||
.ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
|
||||
return !exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验email是否唯一
|
||||
*
|
||||
* @param user 用户信息
|
||||
*/
|
||||
@Override
|
||||
public boolean checkEmailUnique(SysUser user) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getEmail, user.getEmail())
|
||||
.ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
|
||||
return !exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验用户是否允许操作
|
||||
*
|
||||
* @param user 用户信息
|
||||
*/
|
||||
@Override
|
||||
public void checkUserAllowed(SysUser user) {
|
||||
if (ObjectUtil.isNotNull(user.getUserId()) && user.isAdmin()) {
|
||||
throw new ServiceException("不允许操作超级管理员用户");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验用户是否有数据权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
*/
|
||||
@Override
|
||||
public void checkUserDataScope(Long userId) {
|
||||
if (!LoginHelper.isAdmin()) {
|
||||
SysUser user = new SysUser();
|
||||
user.setUserId(userId);
|
||||
List<SysUser> users = this.selectUserList(user);
|
||||
if (CollUtil.isEmpty(users)) {
|
||||
throw new ServiceException("没有权限访问用户数据!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存用户信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertUser(SysUser user) {
|
||||
// 新增用户信息
|
||||
int rows = baseMapper.insert(user);
|
||||
// 新增用户岗位关联
|
||||
insertUserPost(user);
|
||||
// 新增用户与角色管理
|
||||
insertUserRole(user);
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册用户信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean registerUser(SysUser user) {
|
||||
user.setCreateBy(user.getUserName());
|
||||
user.setUpdateBy(user.getUserName());
|
||||
return baseMapper.insert(user) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存用户信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int updateUser(SysUser user) {
|
||||
Long userId = user.getUserId();
|
||||
// 删除用户与角色关联
|
||||
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
|
||||
// 新增用户与角色管理
|
||||
insertUserRole(user);
|
||||
// 删除用户与岗位关联
|
||||
userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId));
|
||||
// 新增用户与岗位管理
|
||||
insertUserPost(user);
|
||||
return baseMapper.updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户授权角色
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleIds 角色组
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void insertUserAuth(Long userId, Long[] roleIds) {
|
||||
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
|
||||
.eq(SysUserRole::getUserId, userId));
|
||||
insertUserRole(userId, roleIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户状态
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateUserStatus(SysUser user) {
|
||||
return baseMapper.updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户基本信息
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateUserProfile(SysUser user) {
|
||||
return baseMapper.updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户头像
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @param avatar 头像地址
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean updateUserAvatar(String userName, String avatar) {
|
||||
return baseMapper.update(null,
|
||||
new LambdaUpdateWrapper<SysUser>()
|
||||
.set(SysUser::getAvatar, avatar)
|
||||
.eq(SysUser::getUserName, userName)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int resetPwd(SysUser user) {
|
||||
return baseMapper.updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @param password 密码
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int resetUserPwd(String userName, String password) {
|
||||
return baseMapper.update(null,
|
||||
new LambdaUpdateWrapper<SysUser>()
|
||||
.set(SysUser::getPassword, password)
|
||||
.eq(SysUser::getUserName, userName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户角色信息
|
||||
*
|
||||
* @param user 用户对象
|
||||
*/
|
||||
public void insertUserRole(SysUser user) {
|
||||
this.insertUserRole(user.getUserId(), user.getRoleIds());
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户岗位信息
|
||||
*
|
||||
* @param user 用户对象
|
||||
*/
|
||||
public void insertUserPost(SysUser user) {
|
||||
Long[] posts = user.getPostIds();
|
||||
if (ArrayUtil.isNotEmpty(posts)) {
|
||||
// 新增用户与岗位管理
|
||||
List<SysUserPost> list = StreamUtils.toList(Arrays.asList(posts), postId -> {
|
||||
SysUserPost up = new SysUserPost();
|
||||
up.setUserId(user.getUserId());
|
||||
up.setPostId(postId);
|
||||
return up;
|
||||
});
|
||||
userPostMapper.insertBatch(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户角色信息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleIds 角色组
|
||||
*/
|
||||
public void insertUserRole(Long userId, Long[] roleIds) {
|
||||
if (ArrayUtil.isNotEmpty(roleIds)) {
|
||||
// 新增用户与角色管理
|
||||
List<SysUserRole> list = StreamUtils.toList(Arrays.asList(roleIds), roleId -> {
|
||||
SysUserRole ur = new SysUserRole();
|
||||
ur.setUserId(userId);
|
||||
ur.setRoleId(roleId);
|
||||
return ur;
|
||||
});
|
||||
userRoleMapper.insertBatch(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户ID删除用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteUserById(Long userId) {
|
||||
// 删除用户与角色关联
|
||||
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
|
||||
// 删除用户与岗位表
|
||||
userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId));
|
||||
return baseMapper.deleteById(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用户信息
|
||||
*
|
||||
* @param userIds 需要删除的用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteUserByIds(Long[] userIds) {
|
||||
for (Long userId : userIds) {
|
||||
checkUserAllowed(new SysUser(userId));
|
||||
checkUserDataScope(userId);
|
||||
}
|
||||
List<Long> ids = Arrays.asList(userIds);
|
||||
// 删除用户与角色关联
|
||||
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
|
||||
// 删除用户与岗位表
|
||||
userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getUserId, ids));
|
||||
return baseMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
|
||||
@Override
|
||||
public String selectUserNameById(Long userId) {
|
||||
SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getUserName).eq(SysUser::getUserId, userId));
|
||||
return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName();
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = CacheNames.SYS_NICK_NAME, key = "#userId")
|
||||
@Override
|
||||
public String selectNickNameById(Long userId) {
|
||||
SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getNickName).eq(SysUser::getUserId, userId));
|
||||
return ObjectUtil.isNull(sysUser) ? null : sysUser.getNickName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.klp.workflow.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 流程抄送对象 wf_copy
|
||||
*
|
||||
* @author KonBAI
|
||||
* @date 2022-05-19
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("wf_copy")
|
||||
public class WfCopy extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 抄送主键
|
||||
*/
|
||||
@TableId(value = "copy_id")
|
||||
private Long copyId;
|
||||
/**
|
||||
* 抄送标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 流程主键
|
||||
*/
|
||||
private String processId;
|
||||
/**
|
||||
* 流程名称
|
||||
*/
|
||||
private String processName;
|
||||
/**
|
||||
* 流程分类主键
|
||||
*/
|
||||
private String categoryId;
|
||||
/**
|
||||
* 部署主键
|
||||
*/
|
||||
private String deploymentId;
|
||||
/**
|
||||
* 流程实例主键
|
||||
*/
|
||||
private String instanceId;
|
||||
/**
|
||||
* 任务主键
|
||||
*/
|
||||
private String taskId;
|
||||
/**
|
||||
* 用户主键
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 发起人Id
|
||||
*/
|
||||
private Long originatorId;
|
||||
/**
|
||||
* 发起人名称
|
||||
*/
|
||||
private String originatorName;
|
||||
/**
|
||||
* 删除标志(0代表存在 2代表删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.klp.workflow.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 流程实例关联表单对象 sys_instance_form
|
||||
*
|
||||
* @author KonBAI
|
||||
* @createTime 2022/3/7 22:07
|
||||
*/
|
||||
@Data
|
||||
@TableName("wf_deploy_form")
|
||||
public class WfDeployForm {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 流程部署主键
|
||||
*/
|
||||
private String deployId;
|
||||
|
||||
/**
|
||||
* 表单Key
|
||||
*/
|
||||
private String formKey;
|
||||
|
||||
/**
|
||||
* 节点Key
|
||||
*/
|
||||
private String nodeKey;
|
||||
|
||||
/**
|
||||
* 表单名称
|
||||
*/
|
||||
private String formName;
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private String nodeName;
|
||||
|
||||
/**
|
||||
* 表单内容
|
||||
*/
|
||||
private String content;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.klp.workflow.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 待签流程对象导出VO
|
||||
*
|
||||
* @author konbai
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WfClaimTaskExportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 任务编号
|
||||
*/
|
||||
@ExcelProperty(value = "任务编号")
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 流程名称
|
||||
*/
|
||||
@ExcelProperty(value = "流程名称")
|
||||
private String procDefName;
|
||||
|
||||
/**
|
||||
* 任务节点
|
||||
*/
|
||||
@ExcelProperty(value = "任务节点")
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
* 流程版本
|
||||
*/
|
||||
@ExcelProperty(value = "流程版本")
|
||||
private int procDefVersion;
|
||||
|
||||
/**
|
||||
* 流程发起人名称
|
||||
*/
|
||||
@ExcelProperty(value = "流程发起人")
|
||||
private String startUserName;
|
||||
|
||||
/**
|
||||
* 接收时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ExcelProperty(value = "接收时间")
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.klp.workflow.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 流程模型对象导出VO
|
||||
*
|
||||
* @author konbai
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WfModelExportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 模型ID
|
||||
*/
|
||||
@ExcelProperty(value = "模型ID")
|
||||
private String modelId;
|
||||
/**
|
||||
* 模型Key
|
||||
*/
|
||||
@ExcelProperty(value = "模型Key")
|
||||
private String modelKey;
|
||||
/**
|
||||
* 模型名称
|
||||
*/
|
||||
@ExcelProperty(value = "模型名称")
|
||||
private String modelName;
|
||||
/**
|
||||
* 分类编码
|
||||
*/
|
||||
@ExcelProperty(value = "分类编码")
|
||||
private String category;
|
||||
/**
|
||||
* 流程分类
|
||||
*/
|
||||
@ExcelProperty(value = "流程分类")
|
||||
private String categoryName;
|
||||
/**
|
||||
* 模型版本
|
||||
*/
|
||||
@ExcelProperty(value = "模型版本")
|
||||
private Integer version;
|
||||
/**
|
||||
* 模型描述
|
||||
*/
|
||||
@ExcelProperty(value = "模型描述")
|
||||
private String description;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.klp.workflow.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 我拥有流程对象导出VO
|
||||
*
|
||||
* @author konbai
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WfOwnTaskExportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 流程实例ID
|
||||
*/
|
||||
@ExcelProperty(value = "流程编号")
|
||||
private String procInsId;
|
||||
|
||||
/**
|
||||
* 流程名称
|
||||
*/
|
||||
@ExcelProperty(value = "流程名称")
|
||||
private String procDefName;
|
||||
|
||||
/**
|
||||
* 流程类别
|
||||
*/
|
||||
@ExcelProperty(value = "流程类别")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 流程版本
|
||||
*/
|
||||
@ExcelProperty(value = "流程版本")
|
||||
private int procDefVersion;
|
||||
|
||||
/**
|
||||
* 提交时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ExcelProperty(value = "提交时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 流程状态
|
||||
*/
|
||||
@ExcelProperty(value = "流程状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 任务耗时
|
||||
*/
|
||||
@ExcelProperty(value = "任务耗时")
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* 当前节点
|
||||
*/
|
||||
@ExcelProperty(value = "当前节点")
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
* 任务完成时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date finishTime;
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.klp.workflow.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.klp.workflow.domain.dto.WfCommentDto;
|
||||
import lombok.Data;
|
||||
import org.flowable.engine.task.Comment;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 工作流任务视图对象
|
||||
*
|
||||
* @author KonBAI
|
||||
* @createTime 2022/3/10 00:12
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WfTaskVo implements Serializable {
|
||||
/**
|
||||
* 任务编号
|
||||
*/
|
||||
private String taskId;
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
private String taskName;
|
||||
/**
|
||||
* 任务Key
|
||||
*/
|
||||
private String taskDefKey;
|
||||
/**
|
||||
* 任务执行人Id
|
||||
*/
|
||||
private Long assigneeId;
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
@Deprecated
|
||||
private String deptName;
|
||||
/**
|
||||
* 流程发起人部门名称
|
||||
*/
|
||||
@Deprecated
|
||||
private String startDeptName;
|
||||
/**
|
||||
* 任务执行人名称
|
||||
*/
|
||||
private String assigneeName;
|
||||
/**
|
||||
* 流程发起人Id
|
||||
*/
|
||||
private Long startUserId;
|
||||
/**
|
||||
* 流程发起人名称
|
||||
*/
|
||||
private String startUserName;
|
||||
/**
|
||||
* 流程类型
|
||||
*/
|
||||
private String category;
|
||||
/**
|
||||
* 流程变量信息
|
||||
*/
|
||||
private Object procVars;
|
||||
/**
|
||||
* 局部变量信息
|
||||
*/
|
||||
private Object taskLocalVars;
|
||||
/**
|
||||
* 流程部署编号
|
||||
*/
|
||||
private String deployId;
|
||||
/**
|
||||
* 流程ID
|
||||
*/
|
||||
private String procDefId;
|
||||
/**
|
||||
* 流程key
|
||||
*/
|
||||
private String procDefKey;
|
||||
/**
|
||||
* 流程定义名称
|
||||
*/
|
||||
private String procDefName;
|
||||
/**
|
||||
* 流程定义内置使用版本
|
||||
*/
|
||||
private int procDefVersion;
|
||||
/**
|
||||
* 流程实例ID
|
||||
*/
|
||||
private String procInsId;
|
||||
/**
|
||||
* 历史流程实例ID
|
||||
*/
|
||||
private String hisProcInsId;
|
||||
/**
|
||||
* 任务耗时
|
||||
*/
|
||||
private String duration;
|
||||
/**
|
||||
* 任务意见
|
||||
*/
|
||||
private WfCommentDto comment;
|
||||
/**
|
||||
* 任务意见
|
||||
*/
|
||||
private List<Comment> commentList;
|
||||
/**
|
||||
* 候选执行人
|
||||
*/
|
||||
private String candidate;
|
||||
/**
|
||||
* 任务创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
/**
|
||||
* 任务完成时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date finishTime;
|
||||
|
||||
/**
|
||||
* 流程状态
|
||||
*/
|
||||
private String processStatus;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.klp.workflow.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.workflow.domain.WfCopy;
|
||||
import com.klp.workflow.domain.vo.WfCopyVo;
|
||||
|
||||
/**
|
||||
* 流程抄送Mapper接口
|
||||
*
|
||||
* @author KonBAI
|
||||
* @date 2022-05-19
|
||||
*/
|
||||
public interface WfCopyMapper extends BaseMapperPlus<WfCopyMapper, WfCopy, WfCopyVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.klp.workflow.service;
|
||||
|
||||
import com.klp.workflow.domain.bo.WfTaskBo;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author KonBAI
|
||||
* @createTime 2022/3/10 00:12
|
||||
*/
|
||||
public interface IWfTaskService {
|
||||
|
||||
/**
|
||||
* 审批任务
|
||||
*
|
||||
* @param task 请求实体参数
|
||||
*/
|
||||
void complete(WfTaskBo task);
|
||||
|
||||
/**
|
||||
* 拒绝任务
|
||||
*
|
||||
* @param taskBo
|
||||
*/
|
||||
void taskReject(WfTaskBo taskBo);
|
||||
|
||||
|
||||
/**
|
||||
* 退回任务
|
||||
*
|
||||
* @param bo 请求实体参数
|
||||
*/
|
||||
void taskReturn(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 获取所有可回退的节点
|
||||
*
|
||||
* @param bo
|
||||
* @return
|
||||
*/
|
||||
List<FlowElement> findReturnTaskList(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*
|
||||
* @param bo 请求实体参数
|
||||
*/
|
||||
void deleteTask(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 认领/签收任务
|
||||
*
|
||||
* @param bo 请求实体参数
|
||||
*/
|
||||
void claim(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 取消认领/签收任务
|
||||
*
|
||||
* @param bo 请求实体参数
|
||||
*/
|
||||
void unClaim(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 委派任务
|
||||
*
|
||||
* @param bo 请求实体参数
|
||||
*/
|
||||
void delegateTask(WfTaskBo bo);
|
||||
|
||||
|
||||
/**
|
||||
* 转办任务
|
||||
*
|
||||
* @param bo 请求实体参数
|
||||
*/
|
||||
void transferTask(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 取消申请
|
||||
* @param bo
|
||||
* @return
|
||||
*/
|
||||
void stopProcess(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 撤回流程
|
||||
* @param bo
|
||||
* @return
|
||||
*/
|
||||
void revokeProcess(WfTaskBo bo);
|
||||
|
||||
/**
|
||||
* 获取流程过程图
|
||||
* @param processId
|
||||
* @return
|
||||
*/
|
||||
InputStream diagram(String processId);
|
||||
|
||||
/**
|
||||
* 获取流程变量
|
||||
* @param taskId 任务ID
|
||||
* @return 流程变量
|
||||
*/
|
||||
Map<String, Object> getProcessVariables(String taskId);
|
||||
|
||||
/**
|
||||
* 启动第一个任务
|
||||
* @param processInstance 流程实例
|
||||
* @param variables 流程参数
|
||||
*/
|
||||
void startFirstTask(ProcessInstance processInstance, Map<String, Object> variables);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.klp.workflow.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.workflow.domain.WfCategory;
|
||||
import com.klp.workflow.domain.vo.WfCategoryVo;
|
||||
import com.klp.workflow.mapper.WfCategoryMapper;
|
||||
import com.klp.workflow.service.IWfCategoryService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程分类Service业务层处理
|
||||
*
|
||||
* @author KonBAI
|
||||
* @date 2022-01-15
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class WfCategoryServiceImpl implements IWfCategoryService {
|
||||
|
||||
private final WfCategoryMapper baseMapper;
|
||||
|
||||
@Override
|
||||
public WfCategoryVo queryById(Long categoryId){
|
||||
return baseMapper.selectVoById(categoryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<WfCategoryVo> queryPageList(WfCategory category, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<WfCategory> lqw = buildQueryWrapper(category);
|
||||
Page<WfCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WfCategoryVo> queryList(WfCategory category) {
|
||||
LambdaQueryWrapper<WfCategory> lqw = buildQueryWrapper(category);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<WfCategory> buildQueryWrapper(WfCategory category) {
|
||||
Map<String, Object> params = category.getParams();
|
||||
LambdaQueryWrapper<WfCategory> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(category.getCategoryName()), WfCategory::getCategoryName, category.getCategoryName());
|
||||
lqw.eq(StringUtils.isNotBlank(category.getCode()), WfCategory::getCode, category.getCode());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertCategory(WfCategory categoryBo) {
|
||||
WfCategory add = BeanUtil.toBean(categoryBo, WfCategory.class);
|
||||
return baseMapper.insert(add);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateCategory(WfCategory categoryBo) {
|
||||
WfCategory update = BeanUtil.toBean(categoryBo, WfCategory.class);
|
||||
return baseMapper.updateById(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验分类编码是否唯一
|
||||
*
|
||||
* @param category 流程分类
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkCategoryCodeUnique(WfCategory category) {
|
||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<WfCategory>()
|
||||
.eq(WfCategory::getCode, category.getCode())
|
||||
.ne(ObjectUtil.isNotNull(category.getCategoryId()), WfCategory::getCategoryId, category.getCategoryId()));
|
||||
return !exist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.klp.workflow.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.workflow.domain.WfCopy;
|
||||
import com.klp.workflow.domain.bo.WfCopyBo;
|
||||
import com.klp.workflow.domain.bo.WfTaskBo;
|
||||
import com.klp.workflow.domain.vo.WfCopyVo;
|
||||
import com.klp.workflow.mapper.WfCopyMapper;
|
||||
import com.klp.workflow.service.IWfCopyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程抄送Service业务层处理
|
||||
*
|
||||
* @author KonBAI
|
||||
* @date 2022-05-19
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class WfCopyServiceImpl implements IWfCopyService {
|
||||
|
||||
private final WfCopyMapper baseMapper;
|
||||
|
||||
private final HistoryService historyService;
|
||||
|
||||
/**
|
||||
* 查询流程抄送
|
||||
*
|
||||
* @param copyId 流程抄送主键
|
||||
* @return 流程抄送
|
||||
*/
|
||||
@Override
|
||||
public WfCopyVo queryById(Long copyId){
|
||||
return baseMapper.selectVoById(copyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程抄送列表
|
||||
*
|
||||
* @param bo 流程抄送
|
||||
* @return 流程抄送
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<WfCopyVo> selectPageList(WfCopyBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<WfCopy> lqw = buildQueryWrapper(bo);
|
||||
lqw.orderByDesc(WfCopy::getCreateTime);
|
||||
Page<WfCopyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程抄送列表
|
||||
*
|
||||
* @param bo 流程抄送
|
||||
* @return 流程抄送
|
||||
*/
|
||||
@Override
|
||||
public List<WfCopyVo> selectList(WfCopyBo bo) {
|
||||
LambdaQueryWrapper<WfCopy> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<WfCopy> buildQueryWrapper(WfCopyBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<WfCopy> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getUserId() != null, WfCopy::getUserId, bo.getUserId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getProcessName()), WfCopy::getProcessName, bo.getProcessName());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getOriginatorName()), WfCopy::getOriginatorName, bo.getOriginatorName());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean makeCopy(WfTaskBo taskBo) {
|
||||
if (StringUtils.isBlank(taskBo.getCopyUserIds())) {
|
||||
// 若抄送用户为空,则不需要处理,返回成功
|
||||
return true;
|
||||
}
|
||||
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(taskBo.getProcInsId()).singleResult();
|
||||
String[] ids = taskBo.getCopyUserIds().split(",");
|
||||
List<WfCopy> copyList = new ArrayList<>(ids.length);
|
||||
Long originatorId = LoginHelper.getUserId();
|
||||
String originatorName = LoginHelper.getNickName();
|
||||
String title = historicProcessInstance.getProcessDefinitionName() + "-" + taskBo.getTaskName();
|
||||
for (String id : ids) {
|
||||
Long userId = Long.valueOf(id);
|
||||
WfCopy copy = new WfCopy();
|
||||
copy.setTitle(title);
|
||||
copy.setProcessId(historicProcessInstance.getProcessDefinitionId());
|
||||
copy.setProcessName(historicProcessInstance.getProcessDefinitionName());
|
||||
copy.setDeploymentId(historicProcessInstance.getDeploymentId());
|
||||
copy.setInstanceId(taskBo.getProcInsId());
|
||||
copy.setTaskId(taskBo.getTaskId());
|
||||
copy.setUserId(userId);
|
||||
copy.setOriginatorId(originatorId);
|
||||
copy.setOriginatorName(originatorName);
|
||||
copyList.add(copy);
|
||||
}
|
||||
return baseMapper.insertBatch(copyList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.klp.workflow.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.exception.ServiceException;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.flowable.utils.ModelUtils;
|
||||
import com.klp.workflow.domain.WfDeployForm;
|
||||
import com.klp.workflow.domain.WfForm;
|
||||
import com.klp.workflow.domain.vo.WfFormVo;
|
||||
import com.klp.workflow.mapper.WfDeployFormMapper;
|
||||
import com.klp.workflow.mapper.WfFormMapper;
|
||||
import com.klp.workflow.service.IWfDeployFormService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowNode;
|
||||
import org.flowable.bpmn.model.StartEvent;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 流程实例关联表单Service业务层处理
|
||||
*
|
||||
* @author KonBAI
|
||||
* @createTime 2022/3/7 22:07
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class WfDeployFormServiceImpl implements IWfDeployFormService {
|
||||
|
||||
private final WfDeployFormMapper baseMapper;
|
||||
|
||||
private final WfFormMapper formMapper;
|
||||
|
||||
/**
|
||||
* 新增流程实例关联表单
|
||||
*
|
||||
* @param deployForm 流程实例关联表单
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertWfDeployForm(WfDeployForm deployForm) {
|
||||
// 删除部署流程和表单的关联关系
|
||||
baseMapper.delete(new LambdaQueryWrapper<WfDeployForm>().eq(WfDeployForm::getDeployId, deployForm.getDeployId()));
|
||||
// 新增部署流程和表单关系
|
||||
return baseMapper.insert(deployForm);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean saveInternalDeployForm(String deployId, BpmnModel bpmnModel) {
|
||||
List<WfDeployForm> deployFormList = new ArrayList<>();
|
||||
// 获取开始节点
|
||||
StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel);
|
||||
if (ObjectUtil.isNull(startEvent)) {
|
||||
throw new RuntimeException("开始节点不存在,请检查流程设计是否有误!");
|
||||
}
|
||||
// 保存开始节点表单信息
|
||||
WfDeployForm startDeployForm = buildDeployForm(deployId, startEvent);
|
||||
if (ObjectUtil.isNotNull(startDeployForm)) {
|
||||
deployFormList.add(startDeployForm);
|
||||
}
|
||||
// 保存用户节点表单信息
|
||||
Collection<UserTask> userTasks = ModelUtils.getAllUserTaskEvent(bpmnModel);
|
||||
if (CollUtil.isNotEmpty(userTasks)) {
|
||||
for (UserTask userTask : userTasks) {
|
||||
WfDeployForm userTaskDeployForm = buildDeployForm(deployId, userTask);
|
||||
if (ObjectUtil.isNotNull(userTaskDeployForm)) {
|
||||
deployFormList.add(userTaskDeployForm);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 批量新增部署流程和表单关联信息
|
||||
return baseMapper.insertBatch(deployFormList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程挂着的表单
|
||||
*
|
||||
* @param deployId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public WfFormVo selectDeployFormByDeployId(String deployId) {
|
||||
QueryWrapper<WfForm> wrapper = Wrappers.query();
|
||||
wrapper.eq("t2.deploy_id", deployId);
|
||||
List<WfFormVo> list = formMapper.selectFormVoList(wrapper);
|
||||
if (ObjectUtil.isNotEmpty(list)) {
|
||||
if (list.size() != 1) {
|
||||
throw new ServiceException("表单信息查询错误");
|
||||
} else {
|
||||
return list.get(0);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建部署表单关联信息对象
|
||||
* @param deployId 部署ID
|
||||
* @param node 节点信息
|
||||
* @return 部署表单关联对象。若无表单信息(formKey),则返回null
|
||||
*/
|
||||
private WfDeployForm buildDeployForm(String deployId, FlowNode node) {
|
||||
String formKey = ModelUtils.getFormKey(node);
|
||||
if (StringUtils.isEmpty(formKey)) {
|
||||
return null;
|
||||
}
|
||||
Long formId = Convert.toLong(StringUtils.substringAfter(formKey, "key_"));
|
||||
WfForm wfForm = formMapper.selectById(formId);
|
||||
if (ObjectUtil.isNull(wfForm)) {
|
||||
throw new ServiceException("表单信息查询错误");
|
||||
}
|
||||
WfDeployForm deployForm = new WfDeployForm();
|
||||
deployForm.setDeployId(deployId);
|
||||
deployForm.setFormKey(formKey);
|
||||
deployForm.setNodeKey(node.getId());
|
||||
deployForm.setFormName(wfForm.getFormName());
|
||||
deployForm.setNodeName(node.getName());
|
||||
deployForm.setContent(wfForm.getContent());
|
||||
return deployForm;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.klp.workflow.service.impl;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.flowable.core.domain.ProcessQuery;
|
||||
import com.klp.flowable.utils.ProcessUtils;
|
||||
import com.klp.workflow.domain.WfDeployForm;
|
||||
import com.klp.workflow.domain.vo.WfDeployVo;
|
||||
import com.klp.workflow.mapper.WfDeployFormMapper;
|
||||
import com.klp.workflow.service.IWfDeployService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.flowable.common.engine.impl.db.SuspensionState;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.repository.Deployment;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.repository.ProcessDefinitionQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author KonBAI
|
||||
* @createTime 2022/6/30 9:04
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class WfDeployServiceImpl implements IWfDeployService {
|
||||
|
||||
private final RepositoryService repositoryService;
|
||||
private final WfDeployFormMapper deployFormMapper;
|
||||
|
||||
@Override
|
||||
public TableDataInfo<WfDeployVo> queryPageList(ProcessQuery processQuery, PageQuery pageQuery) {
|
||||
// 流程定义列表数据查询
|
||||
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery()
|
||||
.latestVersion()
|
||||
.orderByProcessDefinitionKey()
|
||||
.asc();
|
||||
// 构建搜索条件
|
||||
ProcessUtils.buildProcessSearch(processDefinitionQuery, processQuery);
|
||||
long pageTotal = processDefinitionQuery.count();
|
||||
if (pageTotal <= 0) {
|
||||
return TableDataInfo.build();
|
||||
}
|
||||
int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1);
|
||||
List<ProcessDefinition> definitionList = processDefinitionQuery.listPage(offset, pageQuery.getPageSize());
|
||||
|
||||
List<WfDeployVo> deployVoList = new ArrayList<>(definitionList.size());
|
||||
for (ProcessDefinition processDefinition : definitionList) {
|
||||
String deploymentId = processDefinition.getDeploymentId();
|
||||
Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
|
||||
WfDeployVo vo = new WfDeployVo();
|
||||
vo.setDefinitionId(processDefinition.getId());
|
||||
vo.setProcessKey(processDefinition.getKey());
|
||||
vo.setProcessName(processDefinition.getName());
|
||||
vo.setVersion(processDefinition.getVersion());
|
||||
vo.setCategory(processDefinition.getCategory());
|
||||
vo.setDeploymentId(processDefinition.getDeploymentId());
|
||||
vo.setSuspended(processDefinition.isSuspended());
|
||||
// 流程部署信息
|
||||
vo.setCategory(deployment.getCategory());
|
||||
vo.setDeploymentTime(deployment.getDeploymentTime());
|
||||
deployVoList.add(vo);
|
||||
}
|
||||
Page<WfDeployVo> page = new Page<>();
|
||||
page.setRecords(deployVoList);
|
||||
page.setTotal(pageTotal);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<WfDeployVo> queryPublishList(String processKey, PageQuery pageQuery) {
|
||||
// 创建查询条件
|
||||
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery()
|
||||
.processDefinitionKey(processKey)
|
||||
.orderByProcessDefinitionVersion()
|
||||
.desc();
|
||||
long pageTotal = processDefinitionQuery.count();
|
||||
if (pageTotal <= 0) {
|
||||
return TableDataInfo.build();
|
||||
}
|
||||
// 根据查询条件,查询所有版本
|
||||
int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1);
|
||||
List<ProcessDefinition> processDefinitionList = processDefinitionQuery
|
||||
.listPage(offset, pageQuery.getPageSize());
|
||||
List<WfDeployVo> deployVoList = processDefinitionList.stream().map(item -> {
|
||||
WfDeployVo vo = new WfDeployVo();
|
||||
vo.setDefinitionId(item.getId());
|
||||
vo.setProcessKey(item.getKey());
|
||||
vo.setProcessName(item.getName());
|
||||
vo.setVersion(item.getVersion());
|
||||
vo.setCategory(item.getCategory());
|
||||
vo.setDeploymentId(item.getDeploymentId());
|
||||
vo.setSuspended(item.isSuspended());
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
Page<WfDeployVo> page = new Page<>();
|
||||
page.setRecords(deployVoList);
|
||||
page.setTotal(pageTotal);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活或挂起流程
|
||||
*
|
||||
* @param state 状态
|
||||
* @param definitionId 流程定义ID
|
||||
*/
|
||||
@Override
|
||||
public void updateState(String definitionId, String state) {
|
||||
if (SuspensionState.ACTIVE.toString().equals(state)) {
|
||||
// 激活
|
||||
repositoryService.activateProcessDefinitionById(definitionId, true, null);
|
||||
} else if (SuspensionState.SUSPENDED.toString().equals(state)) {
|
||||
// 挂起
|
||||
repositoryService.suspendProcessDefinitionById(definitionId, true, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryBpmnXmlById(String definitionId) {
|
||||
InputStream inputStream = repositoryService.getProcessModel(definitionId);
|
||||
try {
|
||||
return IoUtil.readUtf8(inputStream);
|
||||
} catch (IORuntimeException exception) {
|
||||
throw new RuntimeException("加载xml文件异常");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByIds(List<String> deployIds) {
|
||||
for (String deployId : deployIds) {
|
||||
repositoryService.deleteDeployment(deployId, true);
|
||||
deployFormMapper.delete(new LambdaQueryWrapper<WfDeployForm>().eq(WfDeployForm::getDeployId, deployId));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user