This commit is contained in:
张良(004796)
2024-03-04 18:54:18 +08:00
commit 273ee16e8c
585 changed files with 41565 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
package com.ruoyi.system.domain;
import com.ruoyi.common.utils.StringUtils;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 缓存信息
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
public class SysCache {
/**
* 缓存名称
*/
private String cacheName = "";
/**
* 缓存键名
*/
private String cacheKey = "";
/**
* 缓存内容
*/
private String cacheValue = "";
/**
* 备注
*/
private String remark = "";
public SysCache(String cacheName, String remark) {
this.cacheName = cacheName;
this.remark = remark;
}
public SysCache(String cacheName, String cacheKey, String cacheValue) {
this.cacheName = StringUtils.replace(cacheName, ":", "");
this.cacheKey = StringUtils.replace(cacheKey, cacheName, "");
this.cacheValue = cacheValue;
}
}

View File

@@ -0,0 +1,71 @@
package com.ruoyi.system.domain;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 参数配置表 sys_config
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_config")
@ExcelIgnoreUnannotated
public class SysConfig extends BaseEntity {
/**
* 参数主键
*/
@ExcelProperty(value = "参数主键")
@TableId(value = "config_id")
private Long configId;
/**
* 参数名称
*/
@ExcelProperty(value = "参数名称")
@NotBlank(message = "参数名称不能为空")
@Size(min = 0, max = 100, message = "参数名称不能超过{max}个字符")
private String configName;
/**
* 参数键名
*/
@ExcelProperty(value = "参数键名")
@NotBlank(message = "参数键名长度不能为空")
@Size(min = 0, max = 100, message = "参数键名长度不能超过{max}个字符")
private String configKey;
/**
* 参数键值
*/
@ExcelProperty(value = "参数键值")
@NotBlank(message = "参数键值不能为空")
@Size(min = 0, max = 500, message = "参数键值长度不能超过{max}个字符")
private String configValue;
/**
* 系统内置Y是 N否
*/
@ExcelProperty(value = "系统内置", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_yes_no")
private String configType;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,93 @@
package com.ruoyi.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.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.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;
private String userType;
/**
* 登录状态 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<>();
}

View File

@@ -0,0 +1,58 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 通知公告表 sys_notice
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_notice")
public class SysNotice extends BaseEntity {
/**
* 公告ID
*/
@TableId(value = "notice_id")
private Long noticeId;
/**
* 公告标题
*/
@Xss(message = "公告标题不能包含脚本字符")
@NotBlank(message = "公告标题不能为空")
@Size(min = 0, max = 50, message = "公告标题不能超过{max}个字符")
private String noticeTitle;
/**
* 公告类型1通知 2公告
*/
private String noticeType;
/**
* 公告内容
*/
private String noticeContent;
/**
* 公告状态0正常 1关闭
*/
private String status;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,146 @@
package com.ruoyi.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.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 操作日志记录表 oper_log
*
* @author Lion Li
*/
@Data
@TableName("sys_oper_log")
@ExcelIgnoreUnannotated
public class SysOperLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 日志主键
*/
@ExcelProperty(value = "日志主键")
@TableId(value = "oper_id")
private Long operId;
/**
* 操作模块
*/
@ExcelProperty(value = "操作模块")
private String title;
/**
* 业务类型0其它 1新增 2修改 3删除
*/
@ExcelProperty(value = "业务类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_oper_type")
private Integer businessType;
/**
* 业务类型数组
*/
@TableField(exist = false)
private Integer[] businessTypes;
/**
* 请求方法
*/
@ExcelProperty(value = "请求方法")
private String method;
/**
* 请求方式
*/
@ExcelProperty(value = "请求方式")
private String requestMethod;
/**
* 操作类别0其它 1后台用户 2手机端用户
*/
@ExcelProperty(value = "操作类别", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=其它,1=后台用户,2=手机端用户")
private Integer operatorType;
/**
* 操作人员
*/
@ExcelProperty(value = "操作人员")
private String operName;
// @ExcelProperty(value = "用户类型")
private String userType;
/**
* 部门名称
*/
@ExcelProperty(value = "部门名称")
private String deptName;
/**
* 请求url
*/
@ExcelProperty(value = "请求地址")
private String operUrl;
/**
* 操作地址
*/
@ExcelProperty(value = "操作地址")
private String operIp;
/**
* 操作地点
*/
@ExcelProperty(value = "操作地点")
private String operLocation;
/**
* 请求参数
*/
@ExcelProperty(value = "请求参数")
private String operParam;
/**
* 返回参数
*/
@ExcelProperty(value = "返回参数")
private String jsonResult;
/**
* 操作状态0正常 1异常
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_common_status")
private Integer status;
/**
* 错误消息
*/
@ExcelProperty(value = "错误消息")
private String errorMsg;
/**
* 操作时间
*/
@ExcelProperty(value = "操作时间")
private Date operTime;
/**
* 请求参数
*/
@TableField(exist = false)
private Map<String, Object> params = new HashMap<>();
}

View File

@@ -0,0 +1,50 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.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;
}

View File

@@ -0,0 +1,89 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.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;
/**
* 是否https0否 1是
*/
private String isHttps;
/**
* 域
*/
private String region;
/**
* 是否默认0=是,1=否)
*/
private String status;
/**
* 扩展字段
*/
private String ext1;
/**
* 备注
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@@ -0,0 +1,78 @@
package com.ruoyi.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.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.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;
}

View File

@@ -0,0 +1,29 @@
package com.ruoyi.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;
}

View File

@@ -0,0 +1,29 @@
package com.ruoyi.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_menu
*
* @author Lion Li
*/
@Data
@TableName("sys_role_menu")
public class SysRoleMenu {
/**
* 角色ID
*/
@TableId(type = IdType.INPUT)
private Long roleId;
/**
* 菜单ID
*/
private Long menuId;
}

View File

@@ -0,0 +1,55 @@
package com.ruoyi.system.domain;
import lombok.Data;
/**
* 当前在线会话
*
* @author Lion Li
*/
@Data
public class SysUserOnline {
private String userType;
/**
* 会话编号
*/
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;
}

View File

@@ -0,0 +1,29 @@
package com.ruoyi.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;
}

View File

@@ -0,0 +1,29 @@
package com.ruoyi.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;
}

View File

@@ -0,0 +1,46 @@
package com.ruoyi.system.domain.bo;
import com.ruoyi.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;
}

View File

@@ -0,0 +1,107 @@
package com.ruoyi.system.domain.bo;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.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;
/**
* 是否httpsY=是,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;
}

View File

@@ -0,0 +1,61 @@
package com.ruoyi.system.domain.vo;
import com.ruoyi.common.utils.StringUtils;
import lombok.Data;
/**
* 路由显示信息
*
* @author ruoyi
*/
@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;
}
}
}

View File

@@ -0,0 +1,62 @@
package com.ruoyi.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.List;
/**
* 路由配置信息
*
* @author Lion Li
*/
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class RouterVo {
/**
* 路由名字
*/
private String name;
/**
* 路由地址
*/
private String path;
/**
* 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现
*/
private boolean hidden;
/**
* 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
*/
private String redirect;
/**
* 组件地址
*/
private String component;
/**
* 路由参数:如 {"id": 1, "name": "ry"}
*/
private String query;
/**
* 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面
*/
private Boolean alwaysShow;
/**
* 其他元素
*/
private MetaVo meta;
/**
* 子路由
*/
private List<RouterVo> children;
}

View File

@@ -0,0 +1,90 @@
package com.ruoyi.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;
/**
* 是否httpsY=是,N=否)
*/
private String isHttps;
/**
* 域
*/
private String region;
/**
* 是否默认0=是,1=否)
*/
private String status;
/**
* 扩展字段
*/
private String ext1;
/**
* 备注
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@@ -0,0 +1,58 @@
package com.ruoyi.system.domain.vo;
import lombok.Data;
import java.util.Date;
/**
* OSS对象存储视图对象 sys_oss
*
* @author Lion Li
*/
@Data
public class SysOssVo {
private static final long serialVersionUID = 1L;
/**
* 对象存储主键
*/
private Long ossId;
/**
* 文件名
*/
private String fileName;
/**
* 原名
*/
private String originalName;
/**
* 文件后缀名
*/
private String fileSuffix;
/**
* URL地址
*/
private String url;
/**
* 创建时间
*/
private Date createTime;
/**
* 上传人
*/
private String createBy;
/**
* 服务商
*/
private String service;
}

View File

@@ -0,0 +1,91 @@
package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.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;
}

View File

@@ -0,0 +1,73 @@
package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.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;
}

View File

@@ -0,0 +1,118 @@
package com.ruoyi.system.listener;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.excel.ExcelListener;
import com.ruoyi.common.excel.ExcelResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.ValidatorUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.vo.SysUserImportVo;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 系统用户自定义导入
*
* @author Lion Li
*/
@Slf4j
public class SysUserImportListener extends AnalysisEventListener<SysUserImportVo> implements ExcelListener<SysUserImportVo> {
private final ISysUserService userService;
private final String password;
private final Boolean isUpdateSupport;
private final String operName;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public SysUserImportListener(Boolean isUpdateSupport) {
String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
this.userService = SpringUtils.getBean(ISysUserService.class);
this.password = BCrypt.hashpw(initPassword);
this.isUpdateSupport = isUpdateSupport;
this.operName = LoginHelper.getUsername();
}
@Override
public void invoke(SysUserImportVo userVo, AnalysisContext context) {
SysUser user = this.userService.selectUserByUserName(userVo.getUserName());
try {
// 验证是否存在这个用户
if (ObjectUtil.isNull(user)) {
user = BeanUtil.toBean(userVo, SysUser.class);
ValidatorUtils.validate(user);
user.setPassword(password);
user.setCreateBy(operName);
userService.insertUser(user);
successNum++;
successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 导入成功");
} else if (isUpdateSupport) {
Long userId = user.getUserId();
user = BeanUtil.toBean(userVo, SysUser.class);
user.setUserId(userId);
ValidatorUtils.validate(user);
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(operName);
userService.updateUser(user);
successNum++;
successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 更新成功");
} else {
failureNum++;
failureMsg.append("<br/>").append(failureNum).append("、账号 ").append(user.getUserName()).append(" 已存在");
}
} catch (Exception e) {
failureNum++;
String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
failureMsg.append(msg).append(e.getMessage());
log.error(msg, e);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<SysUserImportVo> getExcelResult() {
return new ExcelResult<SysUserImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<SysUserImportVo> getList() {
return null;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysConfig;
/**
* 参数配置 数据层
*
* @author Lion Li
*/
public interface SysConfigMapper extends BaseMapperPlus<SysConfigMapper, SysConfig, SysConfig> {
}

View File

@@ -0,0 +1,40 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.ruoyi.common.annotation.DataColumn;
import com.ruoyi.common.annotation.DataPermission;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.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);
}

View File

@@ -0,0 +1,24 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.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));
}
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* 字典表 数据层
*
* @author Lion Li
*/
public interface SysDictTypeMapper extends BaseMapperPlus<SysDictTypeMapper, SysDictType, SysDictType> {
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysLogininfor;
/**
* 系统访问日志情况信息 数据层
*
* @author Lion Li
*/
public interface SysLogininforMapper extends BaseMapperPlus<SysLogininforMapper, SysLogininfor, SysLogininfor> {
}

View File

@@ -0,0 +1,82 @@
package com.ruoyi.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.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.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);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysNotice;
/**
* 通知公告表 数据层
*
* @author Lion Li
*/
public interface SysNoticeMapper extends BaseMapperPlus<SysNoticeMapper, SysNotice, SysNotice> {
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysOperLog;
/**
* 操作日志 数据层
*
* @author Lion Li
*/
public interface SysOperLogMapper extends BaseMapperPlus<SysOperLogMapper, SysOperLog, SysOperLog> {
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysOssConfig;
import com.ruoyi.system.domain.vo.SysOssConfigVo;
/**
* 对象存储配置Mapper接口
*
* @author Lion Li
* @author 孤舟烟雨
* @date 2021-08-13
*/
public interface SysOssConfigMapper extends BaseMapperPlus<SysOssConfigMapper, SysOssConfig, SysOssConfigVo> {
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.vo.SysOssVo;
/**
* 文件上传 数据层
*
* @author Lion Li
*/
public interface SysOssMapper extends BaseMapperPlus<SysOssMapper, SysOss, SysOssVo> {
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysPost;
import java.util.List;
/**
* 岗位信息 数据层
*
* @author Lion Li
*/
public interface SysPostMapper extends BaseMapperPlus<SysPostMapper, SysPost, SysPost> {
/**
* 根据用户ID获取岗位选择框列表
*
* @param userId 用户ID
* @return 选中岗位ID列表
*/
List<Long> selectPostListByUserId(Long userId);
/**
* 查询用户所属岗位组
*
* @param userName 用户名
* @return 结果
*/
List<SysPost> selectPostsByUserName(String userName);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysRoleDept;
/**
* 角色与部门关联表 数据层
*
* @author Lion Li
*/
public interface SysRoleDeptMapper extends BaseMapperPlus<SysRoleDeptMapper, SysRoleDept, SysRoleDept> {
}

View File

@@ -0,0 +1,64 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DataColumn;
import com.ruoyi.common.annotation.DataPermission;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 角色表 数据层
*
* @author Lion Li
*/
public interface SysRoleMapper extends BaseMapperPlus<SysRoleMapper, SysRole, SysRole> {
@DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "us.user_id")
})
Page<SysRole> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
/**
* 根据条件分页查询角色数据
*
* @param queryWrapper 查询条件
* @return 角色数据集合信息
*/
@DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "us.user_id")
})
List<SysRole> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
/**
* 根据用户ID查询角色
*
* @param userId 用户ID
* @return 角色列表
*/
List<SysRole> selectRolePermissionByUserId(Long userId);
/**
* 根据用户ID获取角色选择框列表
*
* @param userId 用户ID
* @return 选中角色ID列表
*/
List<Long> selectRoleListByUserId(Long userId);
/**
* 根据用户ID查询角色
*
* @param userName 用户名
* @return 角色列表
*/
List<SysRole> selectRolesByUserName(String userName);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysRoleMenu;
/**
* 角色与菜单关联表 数据层
*
* @author Lion Li
*/
public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenuMapper, SysRoleMenu, SysRoleMenu> {
}

View File

@@ -0,0 +1,95 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DataColumn;
import com.ruoyi.common.annotation.DataPermission;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 用户表 数据层
*
* @author Lion Li
*/
public interface SysUserMapper extends BaseMapperPlus<SysUserMapper, SysUser, SysUser> {
@DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.user_id")
})
Page<SysUser> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/**
* 根据条件分页查询用户列表
*
* @param queryWrapper 查询条件
* @return 用户信息集合信息
*/
@DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.user_id")
})
List<SysUser> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/**
* 根据条件分页查询已配用户角色列表
*
* @param queryWrapper 查询条件
* @return 用户信息集合信息
*/
@DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.user_id")
})
Page<SysUser> selectAllocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/**
* 根据条件分页查询未分配用户角色列表
*
* @param queryWrapper 查询条件
* @return 用户信息集合信息
*/
@DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.user_id")
})
Page<SysUser> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
SysUser selectUserByUserName(String userName);
/**
* 通过手机号查询用户
*
* @param phonenumber 手机号
* @return 用户对象信息
*/
SysUser selectUserByPhonenumber(String phonenumber);
/**
* 通过邮箱查询用户
*
* @param email 邮箱
* @return 用户对象信息
*/
SysUser selectUserByEmail(String email);
/**
* 通过用户ID查询用户
*
* @param userId 用户ID
* @return 用户对象信息
*/
SysUser selectUserById(Long userId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysUserPost;
/**
* 用户与岗位关联表 数据层
*
* @author Lion Li
*/
public interface SysUserPostMapper extends BaseMapperPlus<SysUserPostMapper, SysUserPost, SysUserPost> {
}

View File

@@ -0,0 +1,17 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.system.domain.SysUserRole;
import java.util.List;
/**
* 用户与角色关联表 数据层
*
* @author Lion Li
*/
public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRoleMapper, SysUserRole, SysUserRole> {
List<Long> selectUserIdsByRoleId(Long roleId);
}

View File

@@ -0,0 +1,41 @@
package com.ruoyi.system.runner;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.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 RuoYiConfig 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("加载字典缓存数据成功");
}
}

View File

@@ -0,0 +1,96 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysConfig;
import java.util.List;
/**
* 参数配置 服务层
*
* @author Lion Li
*/
public interface ISysConfigService {
TableDataInfo<SysConfig> selectPageConfigList(SysConfig config, PageQuery pageQuery);
/**
* 查询参数配置信息
*
* @param configId 参数配置ID
* @return 参数配置信息
*/
SysConfig selectConfigById(Long configId);
/**
* 根据键名查询参数配置信息
*
* @param configKey 参数键名
* @return 参数键值
*/
String selectConfigByKey(String configKey);
/**
* 获取验证码开关
*
* @return true开启false关闭
*/
boolean selectCaptchaEnabled();
/**
* 查询参数配置列表
*
* @param config 参数配置信息
* @return 参数配置集合
*/
List<SysConfig> selectConfigList(SysConfig config);
/**
* 新增参数配置
*
* @param config 参数配置信息
* @return 结果
*/
String insertConfig(SysConfig config);
/**
* 修改参数配置
*
* @param config 参数配置信息
* @return 结果
*/
String updateConfig(SysConfig config);
/**
* 批量删除参数信息
*
* @param configIds 需要删除的参数ID
*/
void deleteConfigByIds(Long[] configIds);
/**
* 加载参数缓存数据
*/
void loadingConfigCache();
/**
* 清空参数缓存数据
*/
void clearConfigCache();
/**
* 重置参数缓存数据
*/
void resetConfigCache();
/**
* 校验参数键名是否唯一
*
* @param config 参数信息
* @return 结果
*/
boolean checkConfigKeyUnique(SysConfig config);
}

View File

@@ -0,0 +1,26 @@
package com.ruoyi.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);
}

View File

@@ -0,0 +1,116 @@
package com.ruoyi.system.service;
import cn.hutool.core.lang.tree.Tree;
import com.ruoyi.common.core.domain.entity.SysDept;
import java.util.List;
/**
* 部门管理 服务层
*
* @author Lion Li
*/
public interface ISysDeptService {
/**
* 查询部门管理数据
*
* @param dept 部门信息
* @return 部门信息集合
*/
List<SysDept> selectDeptList(SysDept dept);
/**
* 查询部门树结构信息
*
* @param dept 部门信息
* @return 部门树信息集合
*/
List<Tree<Long>> selectDeptTreeList(SysDept dept);
/**
* 构建前端所需要下拉树结构
*
* @param depts 部门列表
* @return 下拉树结构列表
*/
List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts);
/**
* 根据角色ID查询部门树信息
*
* @param roleId 角色ID
* @return 选中部门列表
*/
List<Long> selectDeptListByRoleId(Long roleId);
/**
* 根据部门ID查询信息
*
* @param deptId 部门ID
* @return 部门信息
*/
SysDept selectDeptById(Long deptId);
/**
* 根据ID查询所有子部门数正常状态
*
* @param deptId 部门ID
* @return 子部门数
*/
long selectNormalChildrenDeptById(Long deptId);
/**
* 是否存在部门子节点
*
* @param deptId 部门ID
* @return 结果
*/
boolean hasChildByDeptId(Long deptId);
/**
* 查询部门是否存在用户
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
boolean checkDeptExistUser(Long deptId);
/**
* 校验部门名称是否唯一
*
* @param dept 部门信息
* @return 结果
*/
boolean checkDeptNameUnique(SysDept dept);
/**
* 校验部门是否有数据权限
*
* @param deptId 部门id
*/
void checkDeptDataScope(Long deptId);
/**
* 新增保存部门信息
*
* @param dept 部门信息
* @return 结果
*/
int insertDept(SysDept dept);
/**
* 修改保存部门信息
*
* @param dept 部门信息
* @return 结果
*/
int updateDept(SysDept dept);
/**
* 删除部门管理信息
*
* @param deptId 部门ID
* @return 结果
*/
int deleteDeptById(Long deptId);
}

View File

@@ -0,0 +1,66 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.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);
}

View File

@@ -0,0 +1,104 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import java.util.List;
/**
* 字典 业务层
*
* @author Lion Li
*/
public interface ISysDictTypeService {
TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery);
/**
* 根据条件分页查询字典类型
*
* @param dictType 字典类型信息
* @return 字典类型集合信息
*/
List<SysDictType> selectDictTypeList(SysDictType dictType);
/**
* 根据所有字典类型
*
* @return 字典类型集合信息
*/
List<SysDictType> selectDictTypeAll();
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
List<SysDictData> selectDictDataByType(String dictType);
/**
* 根据字典类型ID查询信息
*
* @param dictId 字典类型ID
* @return 字典类型
*/
SysDictType selectDictTypeById(Long dictId);
/**
* 根据字典类型查询信息
*
* @param dictType 字典类型
* @return 字典类型
*/
SysDictType selectDictTypeByType(String dictType);
/**
* 批量删除字典信息
*
* @param dictIds 需要删除的字典ID
*/
void deleteDictTypeByIds(Long[] dictIds);
/**
* 加载字典缓存数据
*/
void loadingDictCache();
/**
* 清空字典缓存数据
*/
void clearDictCache();
/**
* 重置字典缓存数据
*/
void resetDictCache();
/**
* 新增保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
List<SysDictData> insertDictType(SysDictType dictType);
/**
* 修改保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
List<SysDictData> updateDictType(SysDictType dictType);
/**
* 校验字典类型称是否唯一
*
* @param dictType 字典类型
* @return 结果
*/
boolean checkDictTypeUnique(SysDictType dictType);
}

View File

@@ -0,0 +1,46 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.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();
}

View File

@@ -0,0 +1,137 @@
package com.ruoyi.system.service;
import cn.hutool.core.lang.tree.Tree;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.system.domain.vo.RouterVo;
import java.util.List;
import java.util.Set;
/**
* 菜单 业务层
*
* @author Lion Li
*/
public interface ISysMenuService {
/**
* 根据用户查询系统菜单列表
*
* @param userId 用户ID
* @return 菜单列表
*/
List<SysMenu> selectMenuList(Long userId);
/**
* 根据用户查询系统菜单列表
*
* @param menu 菜单信息
* @param userId 用户ID
* @return 菜单列表
*/
List<SysMenu> selectMenuList(SysMenu menu, Long userId);
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
Set<String> selectMenuPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
Set<String> selectMenuPermsByRoleId(Long roleId);
/**
* 根据用户ID查询菜单树信息
*
* @param userId 用户ID
* @return 菜单列表
*/
List<SysMenu> selectMenuTreeByUserId(Long userId);
/**
* 根据角色ID查询菜单树信息
*
* @param roleId 角色ID
* @return 选中菜单列表
*/
List<Long> selectMenuListByRoleId(Long roleId);
/**
* 构建前端路由所需要的菜单
*
* @param menus 菜单列表
* @return 路由列表
*/
List<RouterVo> buildMenus(List<SysMenu> menus);
/**
* 构建前端所需要下拉树结构
*
* @param menus 菜单列表
* @return 下拉树结构列表
*/
List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus);
/**
* 根据菜单ID查询信息
*
* @param menuId 菜单ID
* @return 菜单信息
*/
SysMenu selectMenuById(Long menuId);
/**
* 是否存在菜单子节点
*
* @param menuId 菜单ID
* @return 结果 true 存在 false 不存在
*/
boolean hasChildByMenuId(Long menuId);
/**
* 查询菜单是否存在角色
*
* @param menuId 菜单ID
* @return 结果 true 存在 false 不存在
*/
boolean checkMenuExistRole(Long menuId);
/**
* 新增保存菜单信息
*
* @param menu 菜单信息
* @return 结果
*/
int insertMenu(SysMenu menu);
/**
* 修改保存菜单信息
*
* @param menu 菜单信息
* @return 结果
*/
int updateMenu(SysMenu menu);
/**
* 删除菜单管理信息
*
* @param menuId 菜单ID
* @return 结果
*/
int deleteMenuById(Long menuId);
/**
* 校验菜单名称是否唯一
*
* @param menu 菜单信息
* @return 结果
*/
boolean checkMenuNameUnique(SysMenu menu);
}

View File

@@ -0,0 +1,66 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.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);
}

View File

@@ -0,0 +1,53 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysOperLog;
import java.util.List;
/**
* 操作日志 服务层
*
* @author Lion Li
*/
public interface ISysOperLogService {
TableDataInfo<SysOperLog> selectPageOperLogList(SysOperLog operLog, PageQuery pageQuery);
/**
* 新增操作日志
*
* @param operLog 操作日志对象
*/
void insertOperlog(SysOperLog operLog);
/**
* 查询系统操作日志集合
*
* @param operLog 操作日志对象
* @return 操作日志集合
*/
List<SysOperLog> selectOperLogList(SysOperLog operLog);
/**
* 批量删除系统操作日志
*
* @param operIds 需要删除的操作日志ID
* @return 结果
*/
int deleteOperLogByIds(Long[] operIds);
/**
* 查询操作日志详细
*
* @param operId 操作ID
* @return 操作日志对象
*/
SysOperLog selectOperLogById(Long operId);
/**
* 清空操作日志
*/
void cleanOperLog();
}

View File

@@ -0,0 +1,65 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.bo.SysOssConfigBo;
import com.ruoyi.system.domain.vo.SysOssConfigVo;
import java.util.Collection;
/**
* 对象存储配置Service接口
*
* @author Lion Li
* @author 孤舟烟雨
* @date 2021-08-13
*/
public interface ISysOssConfigService {
/**
* 初始化OSS配置
*/
void init();
/**
* 查询单个
*/
SysOssConfigVo queryById(Long ossConfigId);
/**
* 查询列表
*/
TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery);
/**
* 根据新增业务对象插入对象存储配置
*
* @param bo 对象存储配置新增业务对象
* @return
*/
Boolean insertByBo(SysOssConfigBo bo);
/**
* 根据编辑业务对象修改对象存储配置
*
* @param bo 对象存储配置编辑业务对象
* @return
*/
Boolean updateByBo(SysOssConfigBo bo);
/**
* 校验并删除数据
*
* @param ids 主键集合
* @param isValid 是否校验,true-删除前校验,false-不校验
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 启用停用状态
*/
int updateOssConfigStatus(SysOssConfigBo bo);
}

View File

@@ -0,0 +1,36 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
/**
* 文件上传 服务层
*
* @author Lion Li
*/
public interface ISysOssService {
TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery);
List<SysOssVo> listByIds(Collection<Long> ossIds);
SysOssVo getById(Long ossId);
SysOssVo upload(MultipartFile file);
SysOssVo upload(File file);
void download(Long ossId, HttpServletResponse response) throws IOException;
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,105 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysPost;
import java.util.List;
/**
* 岗位信息 服务层
*
* @author Lion Li
*/
public interface ISysPostService {
TableDataInfo<SysPost> selectPagePostList(SysPost post, PageQuery pageQuery);
/**
* 查询岗位信息集合
*
* @param post 岗位信息
* @return 岗位列表
*/
List<SysPost> selectPostList(SysPost post);
/**
* 查询所有岗位
*
* @return 岗位列表
*/
List<SysPost> selectPostAll();
/**
* 通过岗位ID查询岗位信息
*
* @param postId 岗位ID
* @return 角色对象信息
*/
SysPost selectPostById(Long postId);
/**
* 根据用户ID获取岗位选择框列表
*
* @param userId 用户ID
* @return 选中岗位ID列表
*/
List<Long> selectPostListByUserId(Long userId);
/**
* 校验岗位名称
*
* @param post 岗位信息
* @return 结果
*/
boolean checkPostNameUnique(SysPost post);
/**
* 校验岗位编码
*
* @param post 岗位信息
* @return 结果
*/
boolean checkPostCodeUnique(SysPost post);
/**
* 通过岗位ID查询岗位使用数量
*
* @param postId 岗位ID
* @return 结果
*/
long countUserPostById(Long postId);
/**
* 删除岗位信息
*
* @param postId 岗位ID
* @return 结果
*/
int deletePostById(Long postId);
/**
* 批量删除岗位信息
*
* @param postIds 需要删除的岗位ID
* @return 结果
*/
int deletePostByIds(Long[] postIds);
/**
* 新增保存岗位信息
*
* @param post 岗位信息
* @return 结果
*/
int insertPost(SysPost post);
/**
* 修改保存岗位信息
*
* @param post 岗位信息
* @return 结果
*/
int updatePost(SysPost post);
}

View File

@@ -0,0 +1,181 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysUserRole;
import java.util.List;
import java.util.Set;
/**
* 角色业务层
*
* @author Lion Li
*/
public interface ISysRoleService {
TableDataInfo<SysRole> selectPageRoleList(SysRole role, PageQuery pageQuery);
/**
* 根据条件分页查询角色数据
*
* @param role 角色信息
* @return 角色数据集合信息
*/
List<SysRole> selectRoleList(SysRole role);
/**
* 根据用户ID查询角色列表
*
* @param userId 用户ID
* @return 角色列表
*/
List<SysRole> selectRolesByUserId(Long userId);
/**
* 根据用户ID查询角色权限
*
* @param userId 用户ID
* @return 权限列表
*/
Set<String> selectRolePermissionByUserId(Long userId);
/**
* 查询所有角色
*
* @return 角色列表
*/
List<SysRole> selectRoleAll();
/**
* 根据用户ID获取角色选择框列表
*
* @param userId 用户ID
* @return 选中角色ID列表
*/
List<Long> selectRoleListByUserId(Long userId);
/**
* 通过角色ID查询角色
*
* @param roleId 角色ID
* @return 角色对象信息
*/
SysRole selectRoleById(Long roleId);
/**
* 校验角色名称是否唯一
*
* @param role 角色信息
* @return 结果
*/
boolean checkRoleNameUnique(SysRole role);
/**
* 校验角色权限是否唯一
*
* @param role 角色信息
* @return 结果
*/
boolean checkRoleKeyUnique(SysRole role);
/**
* 校验角色是否允许操作
*
* @param role 角色信息
*/
void checkRoleAllowed(SysRole role);
/**
* 校验角色是否有数据权限
*
* @param roleId 角色id
*/
void checkRoleDataScope(Long roleId);
/**
* 通过角色ID查询角色使用数量
*
* @param roleId 角色ID
* @return 结果
*/
long countUserRoleByRoleId(Long roleId);
/**
* 新增保存角色信息
*
* @param role 角色信息
* @return 结果
*/
int insertRole(SysRole role);
/**
* 修改保存角色信息
*
* @param role 角色信息
* @return 结果
*/
int updateRole(SysRole role);
/**
* 修改角色状态
*
* @param role 角色信息
* @return 结果
*/
int updateRoleStatus(SysRole role);
/**
* 修改数据权限信息
*
* @param role 角色信息
* @return 结果
*/
int authDataScope(SysRole role);
/**
* 通过角色ID删除角色
*
* @param roleId 角色ID
* @return 结果
*/
int deleteRoleById(Long roleId);
/**
* 批量删除角色信息
*
* @param roleIds 需要删除的角色ID
* @return 结果
*/
int deleteRoleByIds(Long[] roleIds);
/**
* 取消授权用户角色
*
* @param userRole 用户和角色关联信息
* @return 结果
*/
int deleteAuthUser(SysUserRole userRole);
/**
* 批量取消授权用户角色
*
* @param roleId 角色ID
* @param userIds 需要取消授权的用户数据ID
* @return 结果
*/
int deleteAuthUsers(Long roleId, Long[] userIds);
/**
* 批量选择授权用户角色
*
* @param roleId 角色ID
* @param userIds 需要删除的用户数据ID
* @return 结果
*/
int insertAuthUsers(Long roleId, Long[] userIds);
void cleanOnlineUserByRole(Long roleId);
}

View File

@@ -0,0 +1,211 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.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);
}

View File

@@ -0,0 +1,339 @@
package com.ruoyi.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.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.dto.RoleDTO;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.event.LogininforEvent;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.XcxLoginUser;
import com.ruoyi.common.enums.DeviceType;
import com.ruoyi.common.enums.LoginType;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.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, UserType.SYS_USER.getUserType(), code, uuid);
}
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
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,loginUser.getUserType(), 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(),UserType.SYS_USER.getUserType(), 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(),UserType.SYS_USER.getUserType(), 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 = "";
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
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(), UserType.SYS_USER.getUserType(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), user.getUserName());
return StpUtil.getTokenValue();
}
/**
* 退出登录
*/
public void logout() {
try {
LoginUser loginUser = LoginHelper.getLoginUser();
recordLogininfor(loginUser.getUsername(), loginUser.getUserType(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
} catch (NotLoginException ignored) {
} finally {
try {
StpUtil.logout();
} catch (NotLoginException ignored) {
}
}
}
/**
* 记录登录信息
*
* @param username 用户名
* @param status 状态
* @param message 消息内容
*/
public void recordLogininfor(String username, String userType, String status, String message) {
LogininforEvent logininforEvent = new LogininforEvent();
logininforEvent.setUsername(username);
logininforEvent.setUserType(userType);
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, UserType.SYS_USER.getUserType(), 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, UserType.SYS_USER.getUserType(), 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 userType, 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, userType, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha)) {
recordLogininfor(username, userType, 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.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;
// 获取用户登录错误次数默认为0 (可自定义限制策略 例如: key + username + ip)
int errorNumber = ObjectUtil.defaultIfNull(RedisUtils.getCacheObject(errorKey), 0);
// 锁定时间内登录 则踢出
if (errorNumber >= maxRetryCount) {
recordLogininfor(username, loginFail, UserType.SYS_USER.getUserType(), MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
}
if (supplier.get()) {
// 错误次数递增
errorNumber++;
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
// 达到规定错误次数 则锁定登录
if (errorNumber >= maxRetryCount) {
recordLogininfor(username, UserType.SYS_USER.getUserType(), loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
} else {
// 未达到规定错误次数
recordLogininfor(username, UserType.SYS_USER.getUserType(), loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
throw new UserException(loginType.getRetryLimitCount(), errorNumber);
}
}
// 登录成功 清空错误次数
RedisUtils.deleteObject(errorKey);
}
}

View File

@@ -0,0 +1,55 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
/**
* 用户权限处理
*
* @author ruoyi
*/
@RequiredArgsConstructor
@Service
public class SysPermissionService {
private final ISysRoleService roleService;
private final ISysMenuService menuService;
/**
* 获取角色数据权限
*
* @param user 用户信息
* @return 角色权限信息
*/
public Set<String> getRolePermission(SysUser user) {
Set<String> roles = new HashSet<>();
// 管理员拥有所有权限
if (user.isAdmin()) {
roles.add("admin");
} else {
roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
}
return roles;
}
/**
* 获取菜单数据权限
*
* @param user 用户信息
* @return 菜单权限信息
*/
public Set<String> getMenuPermission(SysUser user) {
Set<String> perms = new HashSet<>();
// 管理员拥有所有权限
if (user.isAdmin()) {
perms.add("*:*:*");
} else {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
}
return perms;
}
}

View File

@@ -0,0 +1,101 @@
package com.ruoyi.system.service;
import cn.dev33.satoken.secure.BCrypt;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.event.LogininforEvent;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.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);
}
}

View File

@@ -0,0 +1,227 @@
package com.ruoyi.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.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.ConfigService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.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);
}
}

View File

@@ -0,0 +1,58 @@
package com.ruoyi.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.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.helper.DataBaseHelper;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.system.domain.SysRoleDept;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysRoleDeptMapper;
import com.ruoyi.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);
if (CollUtil.isNotEmpty(ids)) {
return StreamUtils.join(ids, Convert::toStr);
}
return null;
}
}

View File

@@ -0,0 +1,309 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.service.DeptService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.DataBaseHelper;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.TreeBuildUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysDeptService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 部门管理 服务实现
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysDeptServiceImpl implements ISysDeptService, DeptService {
private final SysDeptMapper baseMapper;
private final SysRoleMapper roleMapper;
private final SysUserMapper userMapper;
/**
* 查询部门管理数据
*
* @param dept 部门信息
* @return 部门信息集合
*/
@Override
public List<SysDept> selectDeptList(SysDept dept) {
LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>();
lqw.eq(SysDept::getDelFlag, "0")
.eq(ObjectUtil.isNotNull(dept.getDeptId()), SysDept::getDeptId, dept.getDeptId())
.eq(ObjectUtil.isNotNull(dept.getParentId()), SysDept::getParentId, dept.getParentId())
.like(StringUtils.isNotBlank(dept.getDeptName()), SysDept::getDeptName, dept.getDeptName())
.eq(StringUtils.isNotBlank(dept.getStatus()), SysDept::getStatus, dept.getStatus())
.orderByAsc(SysDept::getParentId)
.orderByAsc(SysDept::getOrderNum);
return baseMapper.selectDeptList(lqw);
}
/**
* 查询部门树结构信息
*
* @param dept 部门信息
* @return 部门树信息集合
*/
@Override
public List<Tree<Long>> selectDeptTreeList(SysDept dept) {
// 只查询未禁用部门
dept.setStatus(UserConstants.DEPT_NORMAL);
List<SysDept> depts = this.selectDeptList(dept);
return buildDeptTreeSelect(depts);
}
/**
* 构建前端所需要下拉树结构
*
* @param depts 部门列表
* @return 下拉树结构列表
*/
@Override
public List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts) {
if (CollUtil.isEmpty(depts)) {
return CollUtil.newArrayList();
}
return TreeBuildUtils.build(depts, (dept, tree) ->
tree.setId(dept.getDeptId())
.setParentId(dept.getParentId())
.setName(dept.getDeptName())
.setWeight(dept.getOrderNum()));
}
/**
* 根据角色ID查询部门树信息
*
* @param roleId 角色ID
* @return 选中部门列表
*/
@Override
public List<Long> selectDeptListByRoleId(Long roleId) {
SysRole role = roleMapper.selectById(roleId);
return baseMapper.selectDeptListByRoleId(roleId, role.getDeptCheckStrictly());
}
/**
* 根据部门ID查询信息
*
* @param deptId 部门ID
* @return 部门信息
*/
@Cacheable(cacheNames = CacheNames.SYS_DEPT, key = "#deptId")
@Override
public SysDept selectDeptById(Long deptId) {
SysDept dept = baseMapper.selectById(deptId);
if (ObjectUtil.isNull(dept)) {
return null;
}
SysDept parentDept = baseMapper.selectOne(new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId()));
dept.setParentName(ObjectUtil.isNotNull(parentDept) ? parentDept.getDeptName() : null);
return dept;
}
/**
* 通过部门ID查询部门名称
*
* @param deptIds 部门ID串逗号分隔
* @return 部门名称串逗号分隔
*/
@Override
public String selectDeptNameByIds(String deptIds) {
List<String> list = new ArrayList<>();
for (Long id : StringUtils.splitTo(deptIds, Convert::toLong)) {
SysDept dept = SpringUtils.getAopProxy(this).selectDeptById(id);
if (ObjectUtil.isNotNull(dept)) {
list.add(dept.getDeptName());
}
}
return String.join(StringUtils.SEPARATOR, list);
}
/**
* 根据ID查询所有子部门数正常状态
*
* @param deptId 部门ID
* @return 子部门数
*/
@Override
public long selectNormalChildrenDeptById(Long deptId) {
return baseMapper.selectCount(new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getStatus, UserConstants.DEPT_NORMAL)
.apply(DataBaseHelper.findInSet(deptId, "ancestors")));
}
/**
* 是否存在子节点
*
* @param deptId 部门ID
* @return 结果
*/
@Override
public boolean hasChildByDeptId(Long deptId) {
return baseMapper.exists(new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getParentId, deptId));
}
/**
* 查询部门是否存在用户
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
@Override
public boolean checkDeptExistUser(Long deptId) {
return userMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getDeptId, deptId));
}
/**
* 校验部门名称是否唯一
*
* @param dept 部门信息
* @return 结果
*/
@Override
public boolean checkDeptNameUnique(SysDept dept) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getDeptName, dept.getDeptName())
.eq(SysDept::getParentId, dept.getParentId())
.ne(ObjectUtil.isNotNull(dept.getDeptId()), SysDept::getDeptId, dept.getDeptId()));
return !exist;
}
/**
* 校验部门是否有数据权限
*
* @param deptId 部门id
*/
@Override
public void checkDeptDataScope(Long deptId) {
if (!LoginHelper.isAdmin()) {
SysDept dept = new SysDept();
dept.setDeptId(deptId);
List<SysDept> depts = this.selectDeptList(dept);
if (CollUtil.isEmpty(depts)) {
throw new ServiceException("没有权限访问部门数据!");
}
}
}
/**
* 新增保存部门信息
*
* @param dept 部门信息
* @return 结果
*/
@Override
public int insertDept(SysDept dept) {
SysDept info = baseMapper.selectById(dept.getParentId());
// 如果父节点不为正常状态,则不允许新增子节点
if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
throw new ServiceException("部门停用,不允许新增");
}
dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId());
return baseMapper.insert(dept);
}
/**
* 修改保存部门信息
*
* @param dept 部门信息
* @return 结果
*/
@CacheEvict(cacheNames = CacheNames.SYS_DEPT, key = "#dept.deptId")
@Override
public int updateDept(SysDept dept) {
SysDept newParentDept = baseMapper.selectById(dept.getParentId());
SysDept oldDept = baseMapper.selectById(dept.getDeptId());
if (ObjectUtil.isNotNull(newParentDept) && ObjectUtil.isNotNull(oldDept)) {
String newAncestors = newParentDept.getAncestors() + StringUtils.SEPARATOR + newParentDept.getDeptId();
String oldAncestors = oldDept.getAncestors();
dept.setAncestors(newAncestors);
updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
}
int result = baseMapper.updateById(dept);
if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
&& !StringUtils.equals(UserConstants.DEPT_NORMAL, dept.getAncestors())) {
// 如果该部门是启用状态,则启用该部门的所有上级部门
updateParentDeptStatusNormal(dept);
}
return result;
}
/**
* 修改该部门的父级部门状态
*
* @param dept 当前部门
*/
private void updateParentDeptStatusNormal(SysDept dept) {
String ancestors = dept.getAncestors();
Long[] deptIds = Convert.toLongArray(ancestors);
baseMapper.update(null, new LambdaUpdateWrapper<SysDept>()
.set(SysDept::getStatus, UserConstants.DEPT_NORMAL)
.in(SysDept::getDeptId, Arrays.asList(deptIds)));
}
/**
* 修改子元素关系
*
* @param deptId 被修改的部门ID
* @param newAncestors 新的父ID集合
* @param oldAncestors 旧的父ID集合
*/
public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
List<SysDept> children = baseMapper.selectList(new LambdaQueryWrapper<SysDept>()
.apply(DataBaseHelper.findInSet(deptId, "ancestors")));
List<SysDept> list = new ArrayList<>();
for (SysDept child : children) {
SysDept dept = new SysDept();
dept.setDeptId(child.getDeptId());
dept.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
list.add(dept);
}
if (CollUtil.isNotEmpty(list)) {
if (baseMapper.updateBatchById(list)) {
list.forEach(dept -> CacheUtils.evict(CacheNames.SYS_DEPT, dept.getDeptId()));
}
}
}
/**
* 删除部门管理信息
*
* @param deptId 部门ID
* @return 结果
*/
@CacheEvict(cacheNames = CacheNames.SYS_DEPT, key = "#deptId")
@Override
public int deleteDeptById(Long deptId) {
return baseMapper.deleteById(deptId);
}
}

View File

@@ -0,0 +1,130 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 字典 业务层处理
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysDictDataServiceImpl implements ISysDictDataService {
private final SysDictDataMapper baseMapper;
@Override
public TableDataInfo<SysDictData> selectPageDictDataList(SysDictData dictData, PageQuery pageQuery) {
LambdaQueryWrapper<SysDictData> lqw = new LambdaQueryWrapper<SysDictData>()
.eq(StringUtils.isNotBlank(dictData.getDictType()), SysDictData::getDictType, dictData.getDictType())
.like(StringUtils.isNotBlank(dictData.getDictLabel()), SysDictData::getDictLabel, dictData.getDictLabel())
.eq(StringUtils.isNotBlank(dictData.getStatus()), SysDictData::getStatus, dictData.getStatus())
.orderByAsc(SysDictData::getDictSort);
Page<SysDictData> page = baseMapper.selectPage(pageQuery.build(), lqw);
return TableDataInfo.build(page);
}
/**
* 根据条件分页查询字典数据
*
* @param dictData 字典数据信息
* @return 字典数据集合信息
*/
@Override
public List<SysDictData> selectDictDataList(SysDictData dictData) {
return baseMapper.selectList(new LambdaQueryWrapper<SysDictData>()
.eq(StringUtils.isNotBlank(dictData.getDictType()), SysDictData::getDictType, dictData.getDictType())
.like(StringUtils.isNotBlank(dictData.getDictLabel()), SysDictData::getDictLabel, dictData.getDictLabel())
.eq(StringUtils.isNotBlank(dictData.getStatus()), SysDictData::getStatus, dictData.getStatus())
.orderByAsc(SysDictData::getDictSort));
}
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType 字典类型
* @param dictValue 字典键值
* @return 字典标签
*/
@Override
public String selectDictLabel(String dictType, String dictValue) {
return baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
.select(SysDictData::getDictLabel)
.eq(SysDictData::getDictType, dictType)
.eq(SysDictData::getDictValue, dictValue))
.getDictLabel();
}
/**
* 根据字典数据ID查询信息
*
* @param dictCode 字典数据ID
* @return 字典数据
*/
@Override
public SysDictData selectDictDataById(Long dictCode) {
return baseMapper.selectById(dictCode);
}
/**
* 批量删除字典数据信息
*
* @param dictCodes 需要删除的字典数据ID
*/
@Override
public void deleteDictDataByIds(Long[] dictCodes) {
for (Long dictCode : dictCodes) {
SysDictData data = selectDictDataById(dictCode);
baseMapper.deleteById(dictCode);
CacheUtils.evict(CacheNames.SYS_DICT, data.getDictType());
}
}
/**
* 新增保存字典数据信息
*
* @param data 字典数据信息
* @return 结果
*/
@CachePut(cacheNames = CacheNames.SYS_DICT, key = "#data.dictType")
@Override
public List<SysDictData> insertDictData(SysDictData data) {
int row = baseMapper.insert(data);
if (row > 0) {
return baseMapper.selectDictDataByType(data.getDictType());
}
throw new ServiceException("操作失败");
}
/**
* 修改保存字典数据信息
*
* @param data 字典数据信息
* @return 结果
*/
@CachePut(cacheNames = CacheNames.SYS_DICT, key = "#data.dictType")
@Override
public List<SysDictData> updateDictData(SysDictData data) {
int row = baseMapper.updateById(data);
if (row > 0) {
return baseMapper.selectDictDataByType(data.getDictType());
}
throw new ServiceException("操作失败");
}
}

View File

@@ -0,0 +1,287 @@
package com.ruoyi.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.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.DictService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.mapper.SysDictTypeMapper;
import com.ruoyi.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 字典类型
*/
@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) {
// 新增 type 下无 data 数据 返回空防止缓存穿透
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);
}
}
@Override
public Map<String, String> getAllDictByDictType(String dictType) {
List<SysDictData> list = selectDictDataByType(dictType);
return StreamUtils.toMap(list, SysDictData::getDictValue, SysDictData::getDictLabel);
}
}

View File

@@ -0,0 +1,157 @@
package com.ruoyi.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.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.event.LogininforEvent;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.mapper.SysLogininforMapper;
import com.ruoyi.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.setUserType(logininforEvent.getUserType());
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>()
.eq(StringUtils.isNotBlank(logininfor.getUserType()),SysLogininfor::getUserType,logininfor.getUserType())
.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<>());
}
}

View File

@@ -0,0 +1,443 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
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.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.TreeBuildUtils;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.vo.MetaVo;
import com.ruoyi.system.domain.vo.RouterVo;
import com.ruoyi.system.mapper.SysMenuMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysRoleMenuMapper;
import com.ruoyi.system.service.ISysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 菜单 业务层处理
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysMenuServiceImpl implements ISysMenuService {
private final SysMenuMapper baseMapper;
private final SysRoleMapper roleMapper;
private final SysRoleMenuMapper roleMenuMapper;
/**
* 根据用户查询系统菜单列表
*
* @param userId 用户ID
* @return 菜单列表
*/
@Override
public List<SysMenu> selectMenuList(Long userId) {
return selectMenuList(new SysMenu(), userId);
}
/**
* 查询系统菜单列表
*
* @param menu 菜单信息
* @return 菜单列表
*/
@Override
public List<SysMenu> selectMenuList(SysMenu menu, Long userId) {
List<SysMenu> menuList = null;
// 管理员显示所有菜单信息
if (LoginHelper.isAdmin(userId)) {
menuList = baseMapper.selectList(new LambdaQueryWrapper<SysMenu>()
.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
.orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum));
} else {
QueryWrapper<SysMenu> wrapper = Wrappers.query();
wrapper.eq("sur.user_id", userId)
.like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
.orderByAsc("m.parent_id")
.orderByAsc("m.order_num");
menuList = baseMapper.selectMenuListByUserId(wrapper);
}
return menuList;
}
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
@Override
public Set<String> selectMenuPermsByUserId(Long userId) {
List<String> perms = baseMapper.selectMenuPermsByUserId(userId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(StringUtils.splitList(perm.trim()));
}
}
return permsSet;
}
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
@Override
public Set<String> selectMenuPermsByRoleId(Long roleId) {
List<String> perms = baseMapper.selectMenuPermsByRoleId(roleId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(StringUtils.splitList(perm.trim()));
}
}
return permsSet;
}
/**
* 根据用户ID查询菜单
*
* @param userId 用户名称
* @return 菜单列表
*/
@Override
public List<SysMenu> selectMenuTreeByUserId(Long userId) {
List<SysMenu> menus = null;
if (LoginHelper.isAdmin(userId)) {
menus = baseMapper.selectMenuTreeAll();
} else {
menus = baseMapper.selectMenuTreeByUserId(userId);
}
return getChildPerms(menus, 0);
}
/**
* 根据角色ID查询菜单树信息
*
* @param roleId 角色ID
* @return 选中菜单列表
*/
@Override
public List<Long> selectMenuListByRoleId(Long roleId) {
SysRole role = roleMapper.selectById(roleId);
return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly());
}
/**
* 构建前端路由所需要的菜单
*
* @param menus 菜单列表
* @return 路由列表
*/
@Override
public List<RouterVo> buildMenus(List<SysMenu> menus) {
List<RouterVo> routers = new LinkedList<>();
for (SysMenu menu : menus) {
RouterVo router = new RouterVo();
router.setHidden("1".equals(menu.getVisible()));
router.setName(getRouteName(menu));
router.setPath(getRouterPath(menu));
router.setComponent(getComponent(menu));
router.setQuery(menu.getQueryParam());
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
List<SysMenu> cMenus = menu.getChildren();
if (CollUtil.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
router.setAlwaysShow(true);
router.setRedirect("noRedirect");
router.setChildren(buildMenus(cMenus));
} else if (isMenuFrame(menu)) {
router.setMeta(null);
List<RouterVo> childrenList = new ArrayList<>();
RouterVo children = new RouterVo();
children.setPath(menu.getPath());
children.setComponent(menu.getComponent());
children.setName(StringUtils.capitalize(menu.getPath()));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
children.setQuery(menu.getQueryParam());
childrenList.add(children);
router.setChildren(childrenList);
} else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) {
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/");
List<RouterVo> childrenList = new ArrayList<>();
RouterVo children = new RouterVo();
String routerPath = innerLinkReplaceEach(menu.getPath());
children.setPath(routerPath);
children.setComponent(UserConstants.INNER_LINK);
children.setName(StringUtils.capitalize(routerPath));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
childrenList.add(children);
router.setChildren(childrenList);
}
routers.add(router);
}
return routers;
}
/**
* 构建前端所需要下拉树结构
*
* @param menus 菜单列表
* @return 下拉树结构列表
*/
@Override
public List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
if (CollUtil.isEmpty(menus)) {
return CollUtil.newArrayList();
}
return TreeBuildUtils.build(menus, (menu, tree) ->
tree.setId(menu.getMenuId())
.setParentId(menu.getParentId())
.setName(menu.getMenuName())
.setWeight(menu.getOrderNum()));
}
/**
* 根据菜单ID查询信息
*
* @param menuId 菜单ID
* @return 菜单信息
*/
@Override
public SysMenu selectMenuById(Long menuId) {
return baseMapper.selectById(menuId);
}
/**
* 是否存在菜单子节点
*
* @param menuId 菜单ID
* @return 结果
*/
@Override
public boolean hasChildByMenuId(Long menuId) {
return baseMapper.exists(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
}
/**
* 查询菜单使用数量
*
* @param menuId 菜单ID
* @return 结果
*/
@Override
public boolean checkMenuExistRole(Long menuId) {
return roleMenuMapper.exists(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId, menuId));
}
/**
* 新增保存菜单信息
*
* @param menu 菜单信息
* @return 结果
*/
@Override
public int insertMenu(SysMenu menu) {
return baseMapper.insert(menu);
}
/**
* 修改保存菜单信息
*
* @param menu 菜单信息
* @return 结果
*/
@Override
public int updateMenu(SysMenu menu) {
return baseMapper.updateById(menu);
}
/**
* 删除菜单管理信息
*
* @param menuId 菜单ID
* @return 结果
*/
@Override
public int deleteMenuById(Long menuId) {
return baseMapper.deleteById(menuId);
}
/**
* 校验菜单名称是否唯一
*
* @param menu 菜单信息
* @return 结果
*/
@Override
public boolean checkMenuNameUnique(SysMenu menu) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysMenu>()
.eq(SysMenu::getMenuName, menu.getMenuName())
.eq(SysMenu::getParentId, menu.getParentId())
.ne(ObjectUtil.isNotNull(menu.getMenuId()), SysMenu::getMenuId, menu.getMenuId()));
return !exist;
}
/**
* 获取路由名称
*
* @param menu 菜单信息
* @return 路由名称
*/
public String getRouteName(SysMenu menu) {
String routerName = StringUtils.capitalize(menu.getPath());
// 非外链并且是一级目录(类型为目录)
if (isMenuFrame(menu)) {
routerName = StringUtils.EMPTY;
}
return routerName;
}
/**
* 获取路由地址
*
* @param menu 菜单信息
* @return 路由地址
*/
public String getRouterPath(SysMenu menu) {
String routerPath = menu.getPath();
// 内链打开外网方式
if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
routerPath = innerLinkReplaceEach(routerPath);
}
// 非外链并且是一级目录(类型为目录)
if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
&& UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
routerPath = "/" + menu.getPath();
}
// 非外链并且是一级目录(类型为菜单)
else if (isMenuFrame(menu)) {
routerPath = "/";
}
return routerPath;
}
/**
* 获取组件信息
*
* @param menu 菜单信息
* @return 组件信息
*/
public String getComponent(SysMenu menu) {
String component = UserConstants.LAYOUT;
if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) {
component = menu.getComponent();
} else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
component = UserConstants.INNER_LINK;
} else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) {
component = UserConstants.PARENT_VIEW;
}
return component;
}
/**
* 是否为菜单内部跳转
*
* @param menu 菜单信息
* @return 结果
*/
public boolean isMenuFrame(SysMenu menu) {
return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
}
/**
* 是否为内链组件
*
* @param menu 菜单信息
* @return 结果
*/
public boolean isInnerLink(SysMenu menu) {
return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
}
/**
* 是否为parent_view组件
*
* @param menu 菜单信息
* @return 结果
*/
public boolean isParentView(SysMenu menu) {
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
}
/**
* 根据父节点的ID获取所有子节点
*
* @param list 分类表
* @param parentId 传入的父节点ID
* @return String
*/
public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
List<SysMenu> returnList = new ArrayList<>();
for (SysMenu t : list) {
// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
if (t.getParentId() == parentId) {
recursionFn(list, t);
returnList.add(t);
}
}
return returnList;
}
/**
* 递归列表
*
* @param list
* @param t
*/
private void recursionFn(List<SysMenu> list, SysMenu t) {
// 得到子节点列表
List<SysMenu> childList = getChildList(list, t);
t.setChildren(childList);
for (SysMenu tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
* 得到子节点列表
*/
private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
return StreamUtils.filter(list, n -> n.getParentId().equals(t.getMenuId()));
}
/**
* 判断是否有子节点
*/
private boolean hasChild(List<SysMenu> list, SysMenu t) {
return CollUtil.isNotEmpty(getChildList(list, t));
}
/**
* 内链域名特殊字符替换
*/
public String innerLinkReplaceEach(String path) {
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":"},
new String[]{"", "", "", "/", "/"});
}
}

View File

@@ -0,0 +1,106 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.mapper.SysNoticeMapper;
import com.ruoyi.system.service.ISysNoticeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
* 公告 服务层实现
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysNoticeServiceImpl implements ISysNoticeService {
private final SysNoticeMapper baseMapper;
@Override
public TableDataInfo<SysNotice> selectPageNoticeList(SysNotice notice, PageQuery pageQuery) {
LambdaQueryWrapper<SysNotice> lqw = new LambdaQueryWrapper<SysNotice>()
.like(StringUtils.isNotBlank(notice.getNoticeTitle()), SysNotice::getNoticeTitle, notice.getNoticeTitle())
.eq(StringUtils.isNotBlank(notice.getNoticeType()), SysNotice::getNoticeType, notice.getNoticeType())
.like(StringUtils.isNotBlank(notice.getCreateBy()), SysNotice::getCreateBy, notice.getCreateBy());
Page<SysNotice> page = baseMapper.selectPage(pageQuery.build(), lqw);
return TableDataInfo.build(page);
}
/**
* 查询公告信息
*
* @param noticeId 公告ID
* @return 公告信息
*/
@Override
public SysNotice selectNoticeById(Long noticeId) {
return baseMapper.selectById(noticeId);
}
/**
* 查询公告列表
*
* @param notice 公告信息
* @return 公告集合
*/
@Override
public List<SysNotice> selectNoticeList(SysNotice notice) {
return baseMapper.selectList(new LambdaQueryWrapper<SysNotice>()
.like(StringUtils.isNotBlank(notice.getNoticeTitle()), SysNotice::getNoticeTitle, notice.getNoticeTitle())
.eq(StringUtils.isNotBlank(notice.getNoticeType()), SysNotice::getNoticeType, notice.getNoticeType())
.like(StringUtils.isNotBlank(notice.getCreateBy()), SysNotice::getCreateBy, notice.getCreateBy()));
}
/**
* 新增公告
*
* @param notice 公告信息
* @return 结果
*/
@Override
public int insertNotice(SysNotice notice) {
return baseMapper.insert(notice);
}
/**
* 修改公告
*
* @param notice 公告信息
* @return 结果
*/
@Override
public int updateNotice(SysNotice notice) {
return baseMapper.updateById(notice);
}
/**
* 删除公告对象
*
* @param noticeId 公告ID
* @return 结果
*/
@Override
public int deleteNoticeById(Long noticeId) {
return baseMapper.deleteById(noticeId);
}
/**
* 批量删除公告信息
*
* @param noticeIds 需要删除的公告ID
* @return 结果
*/
@Override
public int deleteNoticeByIds(Long[] noticeIds) {
return baseMapper.deleteBatchIds(Arrays.asList(noticeIds));
}
}

View File

@@ -0,0 +1,144 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.event.OperLogEvent;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.mapper.SysOperLogMapper;
import com.ruoyi.system.service.ISysOperLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 操作日志 服务层处理
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysOperLogServiceImpl implements ISysOperLogService {
private final SysOperLogMapper baseMapper;
/**
* 操作日志记录
*
* @param operLogEvent 操作日志事件
*/
@Async
@EventListener
public void recordOper(OperLogEvent operLogEvent) {
SysOperLog operLog = BeanUtil.toBean(operLogEvent, SysOperLog.class);
// 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
insertOperlog(operLog);
}
@Override
public TableDataInfo<SysOperLog> selectPageOperLogList(SysOperLog operLog, PageQuery pageQuery) {
Map<String, Object> params = operLog.getParams();
LambdaQueryWrapper<SysOperLog> lqw = new LambdaQueryWrapper<SysOperLog>()
.like(StringUtils.isNotBlank(operLog.getOperIp()), SysOperLog::getOperIp, operLog.getOperIp())
.like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
.eq(StringUtils.isNotBlank(operLog.getUserType()),SysOperLog::getUserType,operLog.getUserType())
.eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
SysOperLog::getBusinessType, operLog.getBusinessType())
.func(f -> {
if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
}
})
.eq(operLog.getStatus() != null,
SysOperLog::getStatus, operLog.getStatus())
.like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName())
.between(params.get("beginTime") != null && params.get("endTime") != null,
SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"));
if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
pageQuery.setOrderByColumn("oper_id");
pageQuery.setIsAsc("desc");
}
Page<SysOperLog> page = baseMapper.selectPage(pageQuery.build(), lqw);
return TableDataInfo.build(page);
}
/**
* 新增操作日志
*
* @param operLog 操作日志对象
*/
@Override
public void insertOperlog(SysOperLog operLog) {
operLog.setOperTime(new Date());
baseMapper.insert(operLog);
}
/**
* 查询系统操作日志集合
*
* @param operLog 操作日志对象
* @return 操作日志集合
*/
@Override
public List<SysOperLog> selectOperLogList(SysOperLog operLog) {
Map<String, Object> params = operLog.getParams();
return baseMapper.selectList(new LambdaQueryWrapper<SysOperLog>()
.like(StringUtils.isNotBlank(operLog.getOperIp()), SysOperLog::getOperIp, operLog.getOperIp())
.like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
.eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
SysOperLog::getBusinessType, operLog.getBusinessType())
.func(f -> {
if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
}
})
.eq(operLog.getStatus() != null && operLog.getStatus() > 0,
SysOperLog::getStatus, operLog.getStatus())
.like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName())
.between(params.get("beginTime") != null && params.get("endTime") != null,
SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"))
.orderByDesc(SysOperLog::getOperId));
}
/**
* 批量删除系统操作日志
*
* @param operIds 需要删除的操作日志ID
* @return 结果
*/
@Override
public int deleteOperLogByIds(Long[] operIds) {
return baseMapper.deleteBatchIds(Arrays.asList(operIds));
}
/**
* 查询操作日志详细
*
* @param operId 操作ID
* @return 操作日志对象
*/
@Override
public SysOperLog selectOperLogById(Long operId) {
return baseMapper.selectById(operId);
}
/**
* 清空操作日志
*/
@Override
public void cleanOperLog() {
baseMapper.delete(new LambdaQueryWrapper<>());
}
}

View File

@@ -0,0 +1,170 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
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.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.oss.constant.OssConstant;
import com.ruoyi.system.domain.SysOssConfig;
import com.ruoyi.system.domain.bo.SysOssConfigBo;
import com.ruoyi.system.domain.vo.SysOssConfigVo;
import com.ruoyi.system.mapper.SysOssConfigMapper;
import com.ruoyi.system.service.ISysOssConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
/**
* 对象存储配置Service业务层处理
*
* @author Lion Li
* @author 孤舟烟雨
* @date 2021-08-13
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SysOssConfigServiceImpl implements ISysOssConfigService {
private final SysOssConfigMapper baseMapper;
/**
* 项目启动时,初始化参数到缓存,加载配置类
*/
@Override
public void init() {
List<SysOssConfig> list = baseMapper.selectList();
// 加载OSS初始化配置
for (SysOssConfig config : list) {
String configKey = config.getConfigKey();
if ("0".equals(config.getStatus())) {
RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
}
CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
}
}
@Override
public SysOssConfigVo queryById(Long ossConfigId) {
return baseMapper.selectVoById(ossConfigId);
}
@Override
public TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOssConfig> lqw = buildQueryWrapper(bo);
Page<SysOssConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
private LambdaQueryWrapper<SysOssConfig> buildQueryWrapper(SysOssConfigBo bo) {
LambdaQueryWrapper<SysOssConfig> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getConfigKey()), SysOssConfig::getConfigKey, bo.getConfigKey());
lqw.like(StringUtils.isNotBlank(bo.getBucketName()), SysOssConfig::getBucketName, bo.getBucketName());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysOssConfig::getStatus, bo.getStatus());
return lqw;
}
@Override
public Boolean insertByBo(SysOssConfigBo bo) {
SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
validEntityBeforeSave(config);
boolean flag = baseMapper.insert(config) > 0;
if (flag) {
CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
}
return flag;
}
@Override
public Boolean updateByBo(SysOssConfigBo bo) {
SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
validEntityBeforeSave(config);
LambdaUpdateWrapper<SysOssConfig> luw = new LambdaUpdateWrapper<>();
luw.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, "");
luw.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, "");
luw.set(ObjectUtil.isNull(config.getExt1()), SysOssConfig::getExt1, "");
luw.set(ObjectUtil.isNull(config.getRemark()), SysOssConfig::getRemark, "");
luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId());
boolean flag = baseMapper.update(config, luw) > 0;
if (flag) {
CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
}
return flag;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysOssConfig entity) {
if (StringUtils.isNotEmpty(entity.getConfigKey()) && !checkConfigKeyUnique(entity)) {
throw new ServiceException("操作配置'" + entity.getConfigKey() + "'失败, 配置key已存在!");
}
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
if (CollUtil.containsAny(ids, OssConstant.SYSTEM_DATA_IDS)) {
throw new ServiceException("系统内置, 不可删除!");
}
}
List<SysOssConfig> list = CollUtil.newArrayList();
for (Long configId : ids) {
SysOssConfig config = baseMapper.selectById(configId);
list.add(config);
}
boolean flag = baseMapper.deleteBatchIds(ids) > 0;
if (flag) {
list.forEach(sysOssConfig ->
CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, sysOssConfig.getConfigKey()));
}
return flag;
}
/**
* 判断configKey是否唯一
*/
private boolean checkConfigKeyUnique(SysOssConfig sysOssConfig) {
long ossConfigId = ObjectUtil.isNull(sysOssConfig.getOssConfigId()) ? -1L : sysOssConfig.getOssConfigId();
SysOssConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysOssConfig>()
.select(SysOssConfig::getOssConfigId, SysOssConfig::getConfigKey)
.eq(SysOssConfig::getConfigKey, sysOssConfig.getConfigKey()));
if (ObjectUtil.isNotNull(info) && info.getOssConfigId() != ossConfigId) {
return false;
}
return true;
}
/**
* 启用禁用状态
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateOssConfigStatus(SysOssConfigBo bo) {
SysOssConfig sysOssConfig = BeanUtil.toBean(bo, SysOssConfig.class);
int row = baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>()
.set(SysOssConfig::getStatus, "1"));
row += baseMapper.updateById(sysOssConfig);
if (row > 0) {
RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, sysOssConfig.getConfigKey());
}
return row;
}
}

View File

@@ -0,0 +1,198 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
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.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.OssService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.oss.core.OssClient;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.enumd.AccessPolicyType;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
import com.ruoyi.system.mapper.SysOssMapper;
import com.ruoyi.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 文件上传 服务层实现
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysOssServiceImpl implements ISysOssService, OssService {
private final SysOssMapper baseMapper;
@Override
public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
List<SysOssVo> filterResult = result.getRecords().stream().map(this::matchingUrl).collect(Collectors.toList());
result.setRecords(filterResult);
return TableDataInfo.build(result);
}
@Override
public List<SysOssVo> listByIds(Collection<Long> ossIds) {
List<SysOssVo> list = new ArrayList<>();
for (Long id : ossIds) {
SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
if (ObjectUtil.isNotNull(vo)) {
try {
list.add(this.matchingUrl(vo));
} catch (Exception ignored) {
// 如果oss异常无法连接则将数据直接返回
list.add(vo);
} }
}
return list;
}
@Override
public String selectUrlByIds(String ossIds) {
List<String> list = new ArrayList<>();
for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) {
SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
if (ObjectUtil.isNotNull(vo)) {
try {
list.add(this.matchingUrl(vo).getUrl());
} catch (Exception ignored) {
// 如果oss异常无法连接则将数据直接返回
list.add(vo.getUrl());
}
}
}
return String.join(StringUtils.SEPARATOR, list);
}
private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName());
lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName());
lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix());
lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl());
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy());
lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService());
return lqw;
}
@Cacheable(cacheNames = CacheNames.SYS_OSS, key = "#ossId")
@Override
public SysOssVo getById(Long ossId) {
return baseMapper.selectVoById(ossId);
}
@Override
public void download(Long ossId, HttpServletResponse response) throws IOException {
SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId);
if (ObjectUtil.isNull(sysOss)) {
throw new ServiceException("文件数据不存在!");
}
FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
OssClient storage = OssFactory.instance(sysOss.getService());
try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) {
int available = inputStream.available();
IoUtil.copy(inputStream, response.getOutputStream(), available);
response.setContentLength(available);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
@Override
public SysOssVo upload(MultipartFile file) {
String originalfileName = file.getOriginalFilename();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance();
UploadResult uploadResult;
try {
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
} catch (IOException e) {
throw new ServiceException(e.getMessage());
}
// 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult);
}
@Override
public SysOssVo upload(File file) {
String originalfileName = file.getName();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance();
UploadResult uploadResult = storage.uploadSuffix(file, suffix);
// 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult);
}
private SysOssVo buildResultEntity(String originalfileName, String suffix, String configKey, UploadResult uploadResult) {
SysOss oss = new SysOss();
oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalfileName);
oss.setService(configKey);
baseMapper.insert(oss);
SysOssVo sysOssVo = BeanUtil.toBean(oss, SysOssVo.class);
return this.matchingUrl(sysOssVo);
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// 做一些业务上的校验,判断是否需要校验
}
List<SysOss> list = baseMapper.selectBatchIds(ids);
for (SysOss sysOss : list) {
OssClient storage = OssFactory.instance(sysOss.getService());
storage.delete(sysOss.getUrl());
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 匹配Url
*
* @param oss OSS对象
* @return oss 匹配Url的OSS对象
*/
private SysOssVo matchingUrl(SysOssVo oss) {
OssClient storage = OssFactory.instance(oss.getService());
// 仅修改桶类型为 private 的URL临时URL时长为120s
if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120));
}
return oss;
}
}

View File

@@ -0,0 +1,177 @@
package com.ruoyi.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.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.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);
}
}

View File

@@ -0,0 +1,468 @@
package com.ruoyi.system.service.impl;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysRoleDept;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysRoleDeptMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysRoleMenuMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* 角色 业务层处理
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysRoleServiceImpl implements ISysRoleService {
private final SysRoleMapper baseMapper;
private final SysRoleMenuMapper roleMenuMapper;
private final SysUserRoleMapper userRoleMapper;
private final SysRoleDeptMapper roleDeptMapper;
@Override
public TableDataInfo<SysRole> selectPageRoleList(SysRole role, PageQuery pageQuery) {
Page<SysRole> page = baseMapper.selectPageRoleList(pageQuery.build(), this.buildQueryWrapper(role));
return TableDataInfo.build(page);
}
/**
* 根据条件分页查询角色数据
*
* @param role 角色信息
* @return 角色数据集合信息
*/
@Override
public List<SysRole> selectRoleList(SysRole role) {
return baseMapper.selectRoleList(this.buildQueryWrapper(role));
}
private Wrapper<SysRole> buildQueryWrapper(SysRole role) {
Map<String, Object> params = role.getParams();
QueryWrapper<SysRole> wrapper = Wrappers.query();
wrapper.eq("r.del_flag", UserConstants.ROLE_NORMAL)
.eq(ObjectUtil.isNotNull(role.getRoleId()), "r.role_id", role.getRoleId())
.like(StringUtils.isNotBlank(role.getRoleName()), "r.role_name", role.getRoleName())
.eq(StringUtils.isNotBlank(role.getStatus()), "r.status", role.getStatus())
.like(StringUtils.isNotBlank(role.getRoleKey()), "r.role_key", role.getRoleKey())
.between(params.get("beginTime") != null && params.get("endTime") != null,
"r.create_time", params.get("beginTime"), params.get("endTime"))
.orderByAsc("r.role_sort").orderByAsc("r.create_time");
return wrapper;
}
/**
* 根据用户ID查询角色
*
* @param userId 用户ID
* @return 角色列表
*/
@Override
public List<SysRole> selectRolesByUserId(Long userId) {
List<SysRole> userRoles = baseMapper.selectRolePermissionByUserId(userId);
List<SysRole> roles = selectRoleAll();
for (SysRole role : roles) {
for (SysRole userRole : userRoles) {
if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) {
role.setFlag(true);
break;
}
}
}
return roles;
}
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
@Override
public Set<String> selectRolePermissionByUserId(Long userId) {
List<SysRole> perms = baseMapper.selectRolePermissionByUserId(userId);
Set<String> permsSet = new HashSet<>();
for (SysRole perm : perms) {
if (ObjectUtil.isNotNull(perm)) {
permsSet.addAll(StringUtils.splitList(perm.getRoleKey().trim()));
}
}
return permsSet;
}
/**
* 查询所有角色
*
* @return 角色列表
*/
@Override
public List<SysRole> selectRoleAll() {
return this.selectRoleList(new SysRole());
}
/**
* 根据用户ID获取角色选择框列表
*
* @param userId 用户ID
* @return 选中角色ID列表
*/
@Override
public List<Long> selectRoleListByUserId(Long userId) {
return baseMapper.selectRoleListByUserId(userId);
}
/**
* 通过角色ID查询角色
*
* @param roleId 角色ID
* @return 角色对象信息
*/
@Override
public SysRole selectRoleById(Long roleId) {
return baseMapper.selectById(roleId);
}
/**
* 校验角色名称是否唯一
*
* @param role 角色信息
* @return 结果
*/
@Override
public boolean checkRoleNameUnique(SysRole role) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
.eq(SysRole::getRoleName, role.getRoleName())
.ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
return !exist;
}
/**
* 校验角色权限是否唯一
*
* @param role 角色信息
* @return 结果
*/
@Override
public boolean checkRoleKeyUnique(SysRole role) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
.eq(SysRole::getRoleKey, role.getRoleKey())
.ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
return !exist;
}
/**
* 校验角色是否允许操作
*
* @param role 角色信息
*/
@Override
public void checkRoleAllowed(SysRole role) {
if (ObjectUtil.isNotNull(role.getRoleId()) && role.isAdmin()) {
throw new ServiceException("不允许操作超级管理员角色");
}
// 新增不允许使用 管理员标识符
if (ObjectUtil.isNull(role.getRoleId())
&& StringUtils.equals(role.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
}
// 修改不允许修改 管理员标识符
if (ObjectUtil.isNotNull(role.getRoleId())) {
SysRole sysRole = baseMapper.selectById(role.getRoleId());
// 如果标识符不相等 判断为修改了管理员标识符
if (!StringUtils.equals(sysRole.getRoleKey(), role.getRoleKey())) {
if (StringUtils.equals(sysRole.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
throw new ServiceException("不允许修改系统内置管理员角色标识符!");
} else if (StringUtils.equals(role.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
}
}
}
}
/**
* 校验角色是否有数据权限
*
* @param roleId 角色id
*/
@Override
public void checkRoleDataScope(Long roleId) {
if (!LoginHelper.isAdmin()) {
SysRole role = new SysRole();
role.setRoleId(roleId);
List<SysRole> roles = this.selectRoleList(role);
if (CollUtil.isEmpty(roles)) {
throw new ServiceException("没有权限访问角色数据!");
}
}
}
/**
* 通过角色ID查询角色使用数量
*
* @param roleId 角色ID
* @return 结果
*/
@Override
public long countUserRoleByRoleId(Long roleId) {
return userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
}
/**
* 新增保存角色信息
*
* @param role 角色信息
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int insertRole(SysRole role) {
// 新增角色信息
baseMapper.insert(role);
return insertRoleMenu(role);
}
/**
* 修改保存角色信息
*
* @param role 角色信息
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateRole(SysRole role) {
// 修改角色信息
baseMapper.updateById(role);
// 删除角色与菜单关联
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getRoleId()));
return insertRoleMenu(role);
}
/**
* 修改角色状态
*
* @param role 角色信息
* @return 结果
*/
@Override
public int updateRoleStatus(SysRole role) {
if (UserConstants.ROLE_DISABLE.equals(role.getStatus()) && this.countUserRoleByRoleId(role.getRoleId()) > 0) {
throw new ServiceException("角色已分配,不能禁用!");
}
return baseMapper.updateById(role);
}
/**
* 修改数据权限信息
*
* @param role 角色信息
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int authDataScope(SysRole role) {
// 修改角色信息
baseMapper.updateById(role);
// 删除角色与部门关联
roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, role.getRoleId()));
// 新增角色和部门信息(数据权限)
return insertRoleDept(role);
}
/**
* 新增角色菜单信息
*
* @param role 角色对象
*/
public int insertRoleMenu(SysRole role) {
int rows = 1;
// 新增用户与角色管理
List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
for (Long menuId : role.getMenuIds()) {
SysRoleMenu rm = new SysRoleMenu();
rm.setRoleId(role.getRoleId());
rm.setMenuId(menuId);
list.add(rm);
}
if (list.size() > 0) {
rows = roleMenuMapper.insertBatch(list) ? list.size() : 0;
}
return rows;
}
/**
* 新增角色部门信息(数据权限)
*
* @param role 角色对象
*/
public int insertRoleDept(SysRole role) {
int rows = 1;
// 新增角色与部门(数据权限)管理
List<SysRoleDept> list = new ArrayList<SysRoleDept>();
for (Long deptId : role.getDeptIds()) {
SysRoleDept rd = new SysRoleDept();
rd.setRoleId(role.getRoleId());
rd.setDeptId(deptId);
list.add(rd);
}
if (list.size() > 0) {
rows = roleDeptMapper.insertBatch(list) ? list.size() : 0;
}
return rows;
}
/**
* 通过角色ID删除角色
*
* @param roleId 角色ID
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteRoleById(Long roleId) {
// 删除角色与菜单关联
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
// 删除角色与部门关联
roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, roleId));
return baseMapper.deleteById(roleId);
}
/**
* 批量删除角色信息
*
* @param roleIds 需要删除的角色ID
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteRoleByIds(Long[] roleIds) {
for (Long roleId : roleIds) {
SysRole role = selectRoleById(roleId);
checkRoleAllowed(role);
checkRoleDataScope(roleId);
if (countUserRoleByRoleId(roleId) > 0) {
throw new ServiceException(String.format("%1$s已分配不能删除!", role.getRoleName()));
}
}
List<Long> ids = Arrays.asList(roleIds);
// 删除角色与菜单关联
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids));
// 删除角色与部门关联
roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, ids));
return baseMapper.deleteBatchIds(ids);
}
/**
* 取消授权用户角色
*
* @param userRole 用户和角色关联信息
* @return 结果
*/
@Override
public int deleteAuthUser(SysUserRole userRole) {
int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, userRole.getRoleId())
.eq(SysUserRole::getUserId, userRole.getUserId()));
if (rows > 0) {
cleanOnlineUserByRole(userRole.getRoleId());
}
return rows;
}
/**
* 批量取消授权用户角色
*
* @param roleId 角色ID
* @param userIds 需要取消授权的用户数据ID
* @return 结果
*/
@Override
public int deleteAuthUsers(Long roleId, Long[] userIds) {
int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, roleId)
.in(SysUserRole::getUserId, Arrays.asList(userIds)));
if (rows > 0) {
cleanOnlineUserByRole(roleId);
}
return rows;
}
/**
* 批量选择授权用户角色
*
* @param roleId 角色ID
* @param userIds 需要授权的用户数据ID
* @return 结果
*/
@Override
public int insertAuthUsers(Long roleId, Long[] userIds) {
// 新增用户与角色管理
int rows = 1;
List<SysUserRole> list = StreamUtils.toList(Arrays.asList(userIds), userId -> {
SysUserRole ur = new SysUserRole();
ur.setUserId(userId);
ur.setRoleId(roleId);
return ur;
});
if (CollUtil.isNotEmpty(list)) {
rows = userRoleMapper.insertBatch(list) ? list.size() : 0;
}
if (rows > 0) {
cleanOnlineUserByRole(roleId);
}
return rows;
}
@Override
public void cleanOnlineUserByRole(Long roleId) {
// 如果角色未绑定用户 直接返回
Long num = userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
if (num == 0) {
return;
}
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
if (CollUtil.isEmpty(keys)) {
return;
}
// 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作
keys.parallelStream().forEach(key -> {
String token = StringUtils.substringAfterLast(key, ":");
// 如果已经过期则跳过
if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
return;
}
LoginUser loginUser = LoginHelper.getLoginUser(token);
if (ObjectUtil.isNotNull(loginUser) && loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) {
try {
StpUtil.logoutByTokenValue(token);
} catch (NotLoginException ignored) {
}
}
});
}
}

View File

@@ -0,0 +1,36 @@
package com.ruoyi.system.service.impl;
import com.ruoyi.common.core.service.SensitiveService;
import com.ruoyi.common.helper.LoginHelper;
import org.springframework.stereotype.Service;
/**
* 脱敏服务
* 默认管理员不过滤
* 需自行根据业务重写实现
*
* @author Lion Li
* @version 3.6.0
*/
@Service
public class SysSensitiveServiceImpl implements SensitiveService {
private static volatile boolean SENSITIVE = false;
@Override
public void setSensitive(boolean sensitive){
SENSITIVE = sensitive;
}
/**
* 是否脱敏
*/
@Override
public boolean isSensitive() {
if(LoginHelper.isAdmin()){
return false;
}
return SENSITIVE;
}
}

View File

@@ -0,0 +1,485 @@
package com.ruoyi.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.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.UserService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.DataBaseHelper;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.*;
import com.ruoyi.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();
}
}

View File

@@ -0,0 +1,3 @@
java包使用 `.` 分割 resource 目录使用 `/` 分割
<br>
此文件目的 防止文件夹粘连找不到 `xml` 文件

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysConfigMapper">
<resultMap type="SysConfig" id="SysConfigResult">
<id property="configId" column="config_id"/>
<result property="configName" column="config_name"/>
<result property="configKey" column="config_key"/>
<result property="configValue" column="config_value"/>
<result property="configType" column="config_type"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysDeptMapper">
<resultMap type="SysDept" id="SysDeptResult">
<id property="deptId" column="dept_id"/>
<result property="parentId" column="parent_id"/>
<result property="ancestors" column="ancestors"/>
<result property="deptName" column="dept_name"/>
<result property="orderNum" column="order_num"/>
<result property="leader" column="leader"/>
<result property="phone" column="phone"/>
<result property="email" column="email"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="parentName" column="parent_name"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectDeptList" resultMap="SysDeptResult">
select * from sys_dept ${ew.getCustomSqlSegment}
</select>
<select id="selectDeptListByRoleId" resultType="Long">
select d.dept_id
from sys_dept d
left join sys_role_dept rd on d.dept_id = rd.dept_id
where rd.role_id = #{roleId}
<if test="deptCheckStrictly">
and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = #{roleId})
</if>
order by d.parent_id, d.order_num
</select>
</mapper>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysDictDataMapper">
<resultMap type="SysDictData" id="SysDictDataResult">
<id property="dictCode" column="dict_code"/>
<result property="dictSort" column="dict_sort"/>
<result property="dictLabel" column="dict_label"/>
<result property="dictValue" column="dict_value"/>
<result property="dictType" column="dict_type"/>
<result property="cssClass" column="css_class"/>
<result property="listClass" column="list_class"/>
<result property="isDefault" column="is_default"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysDictTypeMapper">
<resultMap type="SysDictType" id="SysDictTypeResult">
<id property="dictId" column="dict_id"/>
<result property="dictName" column="dict_name"/>
<result property="dictType" column="dict_type"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysLogininforMapper">
<resultMap type="SysLogininfor" id="SysLogininforResult">
<id property="infoId" column="info_id"/>
<result property="userName" column="user_name"/>
<result property="status" column="status"/>
<result property="ipaddr" column="ipaddr"/>
<result property="loginLocation" column="login_location"/>
<result property="browser" column="browser"/>
<result property="os" column="os"/>
<result property="msg" column="msg"/>
<result property="loginTime" column="login_time"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysMenuMapper">
<resultMap type="SysMenu" id="SysMenuResult">
<id property="menuId" column="menu_id"/>
<result property="menuName" column="menu_name"/>
<result property="parentName" column="parent_name"/>
<result property="parentId" column="parent_id"/>
<result property="orderNum" column="order_num"/>
<result property="path" column="path"/>
<result property="component" column="component"/>
<result property="queryParam" column="query_param"/>
<result property="isFrame" column="is_frame"/>
<result property="isCache" column="is_cache"/>
<result property="menuType" column="menu_type"/>
<result property="visible" column="visible"/>
<result property="status" column="status"/>
<result property="perms" column="perms"/>
<result property="icon" column="icon"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult">
select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.query_param, m.visible, m.status,
m.perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role sur on rm.role_id = sur.role_id
left join sys_role ro on sur.role_id = ro.role_id
${ew.getCustomSqlSegment}
</select>
<select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult">
select distinct m.menu_id,
m.parent_id,
m.menu_name,
m.path,
m.component,
m.query_param,
m.visible,
m.status,
m.perms,
m.is_frame,
m.is_cache,
m.menu_type,
m.icon,
m.order_num,
m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role sur on rm.role_id = sur.role_id
left join sys_role ro on sur.role_id = ro.role_id
left join sys_user u on sur.user_id = u.user_id
where u.user_id = #{userId}
and m.menu_type in ('M', 'C')
and m.status = '0'
and ro.status = '0'
order by m.parent_id, m.order_num
</select>
<select id="selectMenuListByRoleId" resultType="Long">
select m.menu_id
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where rm.role_id = #{roleId}
<if test="menuCheckStrictly">
and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id =
rm.menu_id and rm.role_id = #{roleId})
</if>
order by m.parent_id, m.order_num
</select>
<select id="selectMenuPerms" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role sur on rm.role_id = sur.role_id
</select>
<select id="selectMenuPermsByUserId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role sur on rm.role_id = sur.role_id
left join sys_role r on r.role_id = sur.role_id
where m.status = '0'
and r.status = '0'
and sur.user_id = #{userId}
</select>
<select id="selectMenuPermsByRoleId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where m.status = '0' and rm.role_id = #{roleId}
</select>
</mapper>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysNoticeMapper">
<resultMap type="SysNotice" id="SysNoticeResult">
<result property="noticeId" column="notice_id"/>
<result property="noticeTitle" column="notice_title"/>
<result property="noticeType" column="notice_type"/>
<result property="noticeContent" column="notice_content"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysOperLogMapper">
<resultMap type="SysOperLog" id="SysOperLogResult">
<id property="operId" column="oper_id"/>
<result property="title" column="title"/>
<result property="businessType" column="business_type"/>
<result property="method" column="method"/>
<result property="requestMethod" column="request_method"/>
<result property="operatorType" column="operator_type"/>
<result property="operName" column="oper_name"/>
<result property="deptName" column="dept_name"/>
<result property="operUrl" column="oper_url"/>
<result property="operIp" column="oper_ip"/>
<result property="operLocation" column="oper_location"/>
<result property="operParam" column="oper_param"/>
<result property="jsonResult" column="json_result"/>
<result property="status" column="status"/>
<result property="errorMsg" column="error_msg"/>
<result property="operTime" column="oper_time"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysOssConfigMapper">
<resultMap type="com.ruoyi.system.domain.SysOssConfig" id="SysOssConfigResult">
<result property="ossConfigId" column="oss_config_id"/>
<result property="configKey" column="config_key"/>
<result property="accessKey" column="access_key"/>
<result property="secretKey" column="secret_key"/>
<result property="bucketName" column="bucket_name"/>
<result property="prefix" column="prefix"/>
<result property="endpoint" column="endpoint"/>
<result property="isHttps" column="is_https"/>
<result property="region" column="region"/>
<result property="status" column="status"/>
<result property="ext1" column="ext1"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysOssMapper">
<resultMap type="com.ruoyi.system.domain.SysOss" id="SysOssResult">
<result property="ossId" column="oss_id"/>
<result property="fileName" column="file_name"/>
<result property="fileSuffix" column="file_suffix"/>
<result property="url" column="url"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
<result property="service" column="service"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysPostMapper">
<resultMap type="SysPost" id="SysPostResult">
<id property="postId" column="post_id"/>
<result property="postCode" column="post_code"/>
<result property="postName" column="post_name"/>
<result property="postSort" column="post_sort"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectPostListByUserId" parameterType="Long" resultType="Long">
select p.post_id
from sys_post p
left join sys_user_post up on up.post_id = p.post_id
left join sys_user u on u.user_id = up.user_id
where u.user_id = #{userId}
</select>
<select id="selectPostsByUserName" parameterType="String" resultMap="SysPostResult">
select p.post_id, p.post_name, p.post_code
from sys_post p
left join sys_user_post up on up.post_id = p.post_id
left join sys_user u on u.user_id = up.user_id
where u.user_name = #{userName}
</select>
</mapper>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysRoleDeptMapper">
<resultMap type="SysRoleDept" id="SysRoleDeptResult">
<result property="roleId" column="role_id"/>
<result property="deptId" column="dept_id"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysRoleMapper">
<resultMap type="SysRole" id="SysRoleResult">
<id property="roleId" column="role_id"/>
<result property="roleName" column="role_name"/>
<result property="roleKey" column="role_key"/>
<result property="roleSort" column="role_sort"/>
<result property="dataScope" column="data_scope"/>
<result property="menuCheckStrictly" column="menu_check_strictly"/>
<result property="deptCheckStrictly" column="dept_check_strictly"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="selectRoleVo">
select distinct r.role_id,
r.role_name,
r.role_key,
r.role_sort,
r.data_scope,
r.menu_check_strictly,
r.dept_check_strictly,
r.status,
r.del_flag,
r.create_time,
r.remark
from sys_role r
left join sys_user_role sur on sur.role_id = r.role_id
left join sys_user u on u.user_id = sur.user_id
left join sys_user us on us.user_name = r.create_by
left join sys_dept d on u.dept_id = d.dept_id
</sql>
<select id="selectPageRoleList" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
${ew.getCustomSqlSegment}
</select>
<select id="selectRoleList" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
${ew.getCustomSqlSegment}
</select>
<select id="selectRolePermissionByUserId" parameterType="Long" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
WHERE r.del_flag = '0' and sur.user_id = #{userId}
</select>
<select id="selectRoleListByUserId" parameterType="Long" resultType="Long">
select r.role_id
from sys_role r
left join sys_user_role sur on sur.role_id = r.role_id
left join sys_user u on u.user_id = sur.user_id
where u.user_id = #{userId}
</select>
<select id="selectRolesByUserName" parameterType="String" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
WHERE r.del_flag = '0' and u.user_name = #{userName}
</select>
</mapper>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysRoleMenuMapper">
<resultMap type="SysRoleMenu" id="SysRoleMenuResult">
<result property="roleId" column="role_id"/>
<result property="menuId" column="menu_id"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysUserMapper">
<resultMap type="SysUser" id="SysUserResult">
<id property="userId" column="user_id"/>
<result property="deptId" column="dept_id"/>
<result property="userName" column="user_name"/>
<result property="nickName" column="nick_name"/>
<result property="userType" column="user_type"/>
<result property="email" column="email"/>
<result property="phonenumber" column="phonenumber"/>
<result property="sex" column="sex"/>
<result property="avatar" column="avatar"/>
<result property="password" column="password"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="loginIp" column="login_ip"/>
<result property="loginDate" column="login_date"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult"/>
<collection property="roles" javaType="java.util.List" resultMap="RoleResult"/>
</resultMap>
<resultMap id="deptResult" type="SysDept">
<id property="deptId" column="dept_id"/>
<result property="parentId" column="parent_id"/>
<result property="deptName" column="dept_name"/>
<result property="ancestors" column="ancestors"/>
<result property="orderNum" column="order_num"/>
<result property="leader" column="leader"/>
<result property="status" column="dept_status"/>
</resultMap>
<resultMap id="RoleResult" type="SysRole">
<id property="roleId" column="role_id"/>
<result property="roleName" column="role_name"/>
<result property="roleKey" column="role_key"/>
<result property="roleSort" column="role_sort"/>
<result property="dataScope" column="data_scope"/>
<result property="status" column="role_status"/>
</resultMap>
<sql id="selectUserVo">
select u.user_id,
u.dept_id,
u.user_name,
u.nick_name,
u.user_type,
u.email,
u.avatar,
u.phonenumber,
u.password,
u.sex,
u.status,
u.del_flag,
u.login_ip,
u.login_date,
u.create_by,
u.create_time,
u.remark,
d.dept_id,
d.parent_id,
d.ancestors,
d.dept_name,
d.order_num,
d.leader,
d.status as dept_status,
r.role_id,
r.role_name,
r.role_key,
r.role_sort,
r.data_scope,
r.status as role_status
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role sur on u.user_id = sur.user_id
left join sys_role r on r.role_id = sur.role_id
</sql>
<select id="selectPageUserList" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
${ew.getCustomSqlSegment}
</select>
<select id="selectUserList" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
${ew.getCustomSqlSegment}
</select>
<select id="selectAllocatedList" resultMap="SysUserResult">
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role sur on u.user_id = sur.user_id
left join sys_role r on r.role_id = sur.role_id
${ew.getCustomSqlSegment}
</select>
<select id="selectUnallocatedList" resultMap="SysUserResult">
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role sur on u.user_id = sur.user_id
left join sys_role r on r.role_id = sur.role_id
${ew.getCustomSqlSegment}
</select>
<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.del_flag = '0' and u.user_name = #{userName}
</select>
<select id="selectUserByPhonenumber" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.del_flag = '0' and u.phonenumber = #{phonenumber}
</select>
<select id="selectUserByEmail" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.del_flag = '0' and u.email = #{email}
</select>
<select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.del_flag = '0' and u.user_id = #{userId}
</select>
</mapper>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysUserPostMapper">
<resultMap type="SysUserPost" id="SysUserPostResult">
<result property="userId" column="user_id"/>
<result property="postId" column="post_id"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysUserRoleMapper">
<resultMap type="SysUserRole" id="SysUserRoleResult">
<result property="userId" column="user_id"/>
<result property="roleId" column="role_id"/>
</resultMap>
<select id="selectUserIdsByRoleId" resultType="Long">
select u.user_id from sys_user u
inner join sys_user_role sur
on u.user_id = sur.user_id and sur.role_id = #{roleId}
</select>
</mapper>