add common 依赖 spring-boot-properties-migrator ;

add 新增 modules 模块, 包含 demo, generator, job, system 模块 ;
update 更新模块包名 rateLimiter => ratelimiter ;
refactor 重构 ratelimiter 模块, 参考幂等模块加入自动装配相关配置 ;
fix 修正 AsyncConfig 实现接口 ;
fix 修正 SwaggerConfig 注解写法 ;
fix 修正 ruoyi-common-doc pom 描述 ;
delete LogAspect 去掉无用注解 ;
This commit is contained in:
zlyx
2023-01-18 20:23:11 +08:00
parent 71a2a8245d
commit 2ae3681286
208 changed files with 89 additions and 100 deletions

View File

@ -0,0 +1,96 @@
package com.ruoyi.system.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.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 结果
*/
String 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.system.domain.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 结果
*/
String 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.mybatis.core.page.PageQuery;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.common.mybatis.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.mybatis.core.page.PageQuery;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.domain.SysDictType;
import com.ruoyi.common.mybatis.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 结果
*/
String checkDictTypeUnique(SysDictType dictType);
}

View File

@ -0,0 +1,46 @@
package com.ruoyi.system.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.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.system.domain.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 结果
*/
String checkMenuNameUnique(SysMenu menu);
}

View File

@ -0,0 +1,66 @@
package com.ruoyi.system.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.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.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.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.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.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,34 @@
package com.ruoyi.system.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
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);
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.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.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 结果
*/
String checkPostNameUnique(SysPost post);
/**
* 校验岗位编码
*
* @param post 岗位信息
* @return 结果
*/
String 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,179 @@
package com.ruoyi.system.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.common.mybatis.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 结果
*/
String checkRoleNameUnique(SysRole role);
/**
* 校验角色权限是否唯一
*
* @param role 角色信息
* @return 结果
*/
String 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);
}

View File

@ -0,0 +1,211 @@
package com.ruoyi.system.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysUser;
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 结果
*/
String checkUserNameUnique(SysUser user);
/**
* 校验手机号码是否唯一
*
* @param user 用户信息
* @return 结果
*/
String checkPhoneUnique(SysUser user);
/**
* 校验email是否唯一
*
* @param user 用户信息
* @return 结果
*/
String 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,294 @@
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.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.log.event.LogininforEvent;
import com.ruoyi.common.core.domain.dto.RoleDTO;
import com.ruoyi.common.core.enums.DeviceType;
import com.ruoyi.common.core.enums.LoginType;
import com.ruoyi.common.core.enums.UserStatus;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.XcxLoginUser;
import com.ruoyi.common.core.exception.user.CaptchaException;
import com.ruoyi.common.core.exception.user.CaptchaExpireException;
import com.ruoyi.common.core.exception.user.UserException;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.MessageUtils;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.core.utils.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 jakarta.servlet.http.HttpServletRequest;
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) {
HttpServletRequest request = ServletUtils.getRequest();
boolean captchaEnabled = configService.selectCaptchaEnabled();
// 验证码开关
if (captchaEnabled) {
validateCaptcha(username, code, uuid, request);
}
SysUser user = loadUserByUsername(username);
checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
// 此处可根据登录用户的数据不同 自行创建 loginUser
LoginUser loginUser = buildLoginUser(user);
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), username);
return StpUtil.getTokenValue();
}
public String smsLogin(String phonenumber, String smsCode) {
// 通过手机号查找用户
SysUser user = loadUserByPhonenumber(phonenumber);
checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode));
// 此处可根据登录用户的数据不同 自行创建 loginUser
LoginUser loginUser = buildLoginUser(user);
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.APP);
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), user.getUserName());
return StpUtil.getTokenValue();
}
public String xcxLogin(String xcxCode) {
// xcxCode 为 小程序调用 wx.login 授权后获取
// todo 以下自行实现
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
String openid = "";
SysUser user = loadUserByOpenid(openid);
// 此处可根据登录用户的数据不同 自行创建 loginUser
XcxLoginUser loginUser = new XcxLoginUser();
loginUser.setUserId(user.getUserId());
loginUser.setUsername(user.getUserName());
loginUser.setUserType(user.getUserType());
loginUser.setOpenid(openid);
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), user.getUserName());
return StpUtil.getTokenValue();
}
/**
* 退出登录
*/
public void logout() {
try {
LoginUser loginUser = LoginHelper.getLoginUser();
StpUtil.logout();
recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
} catch (NotLoginException ignored) {
}
}
/**
* 记录登录信息
*
* @param username 用户名
* @param status 状态
* @param message 消息内容
* @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);
}
/**
* 校验短信验证码
*/
private boolean validateSmsCode(String phonenumber, String smsCode) {
String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phonenumber);
if (StringUtils.isBlank(code)) {
recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
}
return code.equals(smsCode);
}
/**
* 校验验证码
*
* @param username 用户名
* @param code 验证码
* @param uuid 唯一标识
*/
public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
String captcha = RedisUtils.getCacheObject(verifyKey);
RedisUtils.deleteObject(verifyKey);
if (captcha == null) {
recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha)) {
recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
throw new CaptchaException();
}
}
private SysUser loadUserByUsername(String username) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserName, SysUser::getStatus)
.eq(SysUser::getUserName, username));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", username);
throw new UserException("user.not.exists", username);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", username);
throw new UserException("user.blocked", username);
}
return userMapper.selectUserByUserName(username);
}
private SysUser loadUserByPhonenumber(String phonenumber) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getPhonenumber, SysUser::getStatus)
.eq(SysUser::getPhonenumber, phonenumber));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", phonenumber);
throw new UserException("user.not.exists", phonenumber);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", phonenumber);
throw new UserException("user.blocked", phonenumber);
}
return userMapper.selectUserByPhonenumber(phonenumber);
}
private SysUser 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;
// 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip)
Integer errorNumber = RedisUtils.getCacheObject(errorKey);
// 锁定时间内登录 则踢出
if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(maxRetryCount)) {
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
}
if (supplier.get()) {
// 是否第一次
errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
// 达到规定错误次数 则锁定登录
if (errorNumber.equals(maxRetryCount)) {
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
} else {
// 未达到规定错误次数 则递增
RedisUtils.setCacheObject(errorKey, errorNumber);
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
throw new UserException(loginType.getRetryLimitCount(), errorNumber);
}
}
// 登录成功 清空错误次数
RedisUtils.deleteObject(errorKey);
}
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.system.service;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
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<String>();
// 管理员拥有所有权限
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<String>();
// 管理员拥有所有权限
if (user.isAdmin()) {
perms.add("*:*:*");
} else {
List<SysRole> roles = user.getRoles();
if (!roles.isEmpty() && roles.size() > 1) {
// 多角色设置permissions属性以便数据权限匹配权限
for (SysRole role : roles) {
Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
role.setPermissions(rolePerms);
perms.addAll(rolePerms);
}
} else {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
}
}
return perms;
}
}

View File

@ -0,0 +1,106 @@
package com.ruoyi.system.service;
import cn.dev33.satoken.secure.BCrypt;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.log.event.LogininforEvent;
import com.ruoyi.common.core.enums.UserType;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.exception.user.CaptchaException;
import com.ruoyi.common.core.exception.user.CaptchaExpireException;
import com.ruoyi.common.core.exception.user.UserException;
import com.ruoyi.common.core.utils.MessageUtils;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.core.utils.SpringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import jakarta.servlet.http.HttpServletRequest;
/**
* 注册校验方法
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysRegisterService {
private final ISysUserService userService;
private final ISysConfigService configService;
/**
* 注册
*/
public void register(RegisterBody registerBody) {
HttpServletRequest request = ServletUtils.getRequest();
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(), request);
}
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setPassword(BCrypt.hashpw(password));
sysUser.setUserType(userType);
if (UserConstants.NOT_UNIQUE.equals(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 唯一标识
* @return 结果
*/
public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) {
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.core.constant.CacheNames;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.service.ConfigService;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.utils.CacheUtils;
import com.ruoyi.common.core.utils.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 String 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().longValue() != configId.longValue()) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 根据参数 key 获取参数值
*
* @param configKey 参数 key
* @return 参数值
*/
@Override
public String getConfigValue(String configKey) {
return SpringUtils.getAopProxy(this).selectConfigByKey(configKey);
}
}

View File

@ -0,0 +1,61 @@
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.system.domain.SysDept;
import com.ruoyi.common.mybatis.helper.DataBaseHelper;
import com.ruoyi.common.core.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);
List<SysDept> list = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptId)
.in(SysDept::getDeptId, ids));
if (CollUtil.isNotEmpty(list)) {
return StreamUtils.join(list, d -> Convert.toStr(d.getDeptId()));
}
return null;
}
}

View File

@ -0,0 +1,278 @@
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.core.constant.UserConstants;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.mybatis.helper.DataBaseHelper;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.TreeBuildUtils;
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.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 部门管理 服务实现
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysDeptServiceImpl implements ISysDeptService {
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) {
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 部门信息
*/
@Override
public SysDept selectDeptById(Long deptId) {
SysDept dept = baseMapper.selectById(deptId);
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 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 String 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()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验部门是否有数据权限
*
* @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() + "," + dept.getParentId());
return baseMapper.insert(dept);
}
/**
* 修改保存部门信息
*
* @param dept 部门信息
* @return 结果
*/
@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() + "," + 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 (list.size() > 0) {
baseMapper.updateBatchById(list);
}
}
/**
* 删除部门管理信息
*
* @param deptId 部门ID
* @return 结果
*/
@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.core.constant.CacheNames;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.utils.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,285 @@
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.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.CacheNames;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.core.service.DictService;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.domain.SysDictType;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StreamUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.utils.CacheUtils;
import com.ruoyi.common.core.utils.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 字典类型
*/
@Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
@Override
public SysDictType selectDictTypeByType(String dictType) {
return baseMapper.selectById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
}
/**
* 批量删除字典类型信息
*
* @param dictIds 需要删除的字典ID
*/
@Override
public void deleteDictTypeByIds(Long[] dictIds) {
for (Long dictId : dictIds) {
SysDictType dictType = selectDictTypeById(dictId);
if (dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictType, dictType.getDictType()))) {
throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
}
CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
}
baseMapper.deleteBatchIds(Arrays.asList(dictIds));
}
/**
* 加载字典缓存数据
*/
@Override
public void loadingDictCache() {
List<SysDictData> dictDataList = dictDataMapper.selectList(
new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getStatus, UserConstants.DICT_NORMAL));
Map<String, List<SysDictData>> dictDataMap = StreamUtils.groupByKey(dictDataList, SysDictData::getDictType);
dictDataMap.forEach((k,v) -> {
List<SysDictData> dictList = StreamUtils.sorted(v, Comparator.comparing(SysDictData::getDictSort));
CacheUtils.put(CacheNames.SYS_DICT, k, dictList);
});
}
/**
* 清空字典缓存数据
*/
@Override
public void clearDictCache() {
CacheUtils.clear(CacheNames.SYS_DICT);
}
/**
* 重置字典缓存数据
*/
@Override
public void resetDictCache() {
clearDictCache();
loadingDictCache();
}
/**
* 新增保存字典类型信息
*
* @param dict 字典类型信息
* @return 结果
*/
@CachePut(cacheNames = CacheNames.SYS_DICT, key = "#dict.dictType")
@Override
public List<SysDictData> insertDictType(SysDictType dict) {
int row = baseMapper.insert(dict);
if (row > 0) {
return new ArrayList<>();
}
throw new ServiceException("操作失败");
}
/**
* 修改保存字典类型信息
*
* @param dict 字典类型信息
* @return 结果
*/
@CachePut(cacheNames = CacheNames.SYS_DICT, key = "#dict.dictType")
@Override
@Transactional(rollbackFor = Exception.class)
public List<SysDictData> updateDictType(SysDictType dict) {
SysDictType oldDict = baseMapper.selectById(dict.getDictId());
dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
.set(SysDictData::getDictType, dict.getDictType())
.eq(SysDictData::getDictType, oldDict.getDictType()));
int row = baseMapper.updateById(dict);
if (row > 0) {
CacheUtils.evict(CacheNames.SYS_DICT, oldDict.getDictType());
return dictDataMapper.selectDictDataByType(dict.getDictType());
}
throw new ServiceException("操作失败");
}
/**
* 校验字典类型称是否唯一
*
* @param dict 字典类型
* @return 结果
*/
@Override
public String checkDictTypeUnique(SysDictType dict) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDictType>()
.eq(SysDictType::getDictType, dict.getDictType())
.ne(ObjectUtil.isNotNull(dict.getDictId()), SysDictType::getDictId, dict.getDictId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 根据字典类型和字典值获取字典标签
*
* @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);
}
}
}

View File

@ -0,0 +1,155 @@
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.core.constant.Constants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.log.event.LogininforEvent;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.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 jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 系统访问日志情况信息 服务层处理
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Slf4j
@Service
public class SysLogininforServiceImpl implements ISysLogininforService {
private final SysLogininforMapper baseMapper;
/**
* 记录登录信息
*
* @param logininforEvent 登录事件
*/
@Async
@EventListener
public void recordLogininfor(LogininforEvent logininforEvent) {
HttpServletRequest request = logininforEvent.getRequest();
final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
final String ip = ServletUtils.getClientIP(request);
String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder();
s.append(getBlock(ip));
s.append(address);
s.append(getBlock(logininforEvent.getUsername()));
s.append(getBlock(logininforEvent.getStatus()));
s.append(getBlock(logininforEvent.getMessage()));
// 打印信息到日志
log.info(s.toString(), logininforEvent.getArgs());
// 获取客户端操作系统
String os = userAgent.getOs().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
// 封装对象
SysLogininfor logininfor = new SysLogininfor();
logininfor.setUserName(logininforEvent.getUsername());
logininfor.setIpaddr(ip);
logininfor.setLoginLocation(address);
logininfor.setBrowser(browser);
logininfor.setOs(os);
logininfor.setMsg(logininforEvent.getMessage());
// 日志状态
if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
logininfor.setStatus(Constants.SUCCESS);
} else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
logininfor.setStatus(Constants.FAIL);
}
// 插入数据
insertLogininfor(logininfor);
}
private String getBlock(Object msg) {
if (msg == null) {
msg = "";
}
return "[" + msg.toString() + "]";
}
@Override
public TableDataInfo<SysLogininfor> selectPageLogininforList(SysLogininfor logininfor, PageQuery pageQuery) {
Map<String, Object> params = logininfor.getParams();
LambdaQueryWrapper<SysLogininfor> lqw = new LambdaQueryWrapper<SysLogininfor>()
.like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
.eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
.like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
.between(params.get("beginTime") != null && params.get("endTime") != null,
SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"));
if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
pageQuery.setOrderByColumn("info_id");
pageQuery.setIsAsc("desc");
}
Page<SysLogininfor> page = baseMapper.selectPage(pageQuery.build(), lqw);
return TableDataInfo.build(page);
}
/**
* 新增系统登录日志
*
* @param logininfor 访问日志对象
*/
@Override
public void insertLogininfor(SysLogininfor logininfor) {
logininfor.setLoginTime(new Date());
baseMapper.insert(logininfor);
}
/**
* 查询系统登录日志集合
*
* @param logininfor 访问日志对象
* @return 登录记录集合
*/
@Override
public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor) {
Map<String, Object> params = logininfor.getParams();
return baseMapper.selectList(new LambdaQueryWrapper<SysLogininfor>()
.like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
.eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
.like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
.between(params.get("beginTime") != null && params.get("endTime") != null,
SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"))
.orderByDesc(SysLogininfor::getInfoId));
}
/**
* 批量删除系统登录日志
*
* @param infoIds 需要删除的登录日志ID
* @return 结果
*/
@Override
public int deleteLogininforByIds(Long[] infoIds) {
return baseMapper.deleteBatchIds(Arrays.asList(infoIds));
}
/**
* 清空系统登录日志
*/
@Override
public void cleanLogininfor() {
baseMapper.delete(new LambdaQueryWrapper<>());
}
}

View File

@ -0,0 +1,446 @@
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.core.constant.Constants;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.common.core.utils.StreamUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.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(Arrays.asList(perm.trim().split(",")));
}
}
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(Arrays.asList(perm.trim().split(",")));
}
}
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<RouterVo>();
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 (!cMenus.isEmpty() && 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>();
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>();
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 String 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()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 获取路由名称
*
* @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<SysMenu>();
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 getChildList(list, t).size() > 0;
}
/**
* 内链域名特殊字符替换
*/
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.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.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,141 @@
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.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ip.AddressUtils;
import com.ruoyi.common.log.event.OperLogEvent;
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.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,
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.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,189 @@
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.core.constant.CacheNames;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.JsonUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.oss.constant.OssConstant;
import com.ruoyi.common.oss.factory.OssFactory;
import com.ruoyi.common.redis.utils.CacheUtils;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.core.utils.SpringUtils;
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.context.event.EventListener;
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);
}
SpringUtils.context().publishEvent(config);
}
// 初始化OSS工厂
OssFactory.init();
}
@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) {
SpringUtils.context().publishEvent(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) {
SpringUtils.context().publishEvent(config);
}
return flag;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysOssConfig entity) {
if (StringUtils.isNotEmpty(entity.getConfigKey())
&& UserConstants.NOT_UNIQUE.equals(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 String 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 UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 启用禁用状态
*/
@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;
}
/**
* 更新配置缓存
*
* @param config 配置
*/
@EventListener
public void updateConfigCache(SysOssConfig config) {
CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
RedisUtils.publish(OssConstant.DEFAULT_CONFIG_KEY, config.getConfigKey(), msg -> {
log.info("发布刷新OSS配置 => " + msg);
});
}
}

View File

@ -0,0 +1,161 @@
package com.ruoyi.system.service.impl;
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.core.constant.CacheNames;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.BeanCopyUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.oss.core.OssClient;
import com.ruoyi.common.oss.entity.UploadResult;
import com.ruoyi.common.oss.enumd.AccessPolicyType;
import com.ruoyi.common.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 jakarta.servlet.http.HttpServletResponse;
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 {
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)) {
list.add(this.matchingUrl(vo));
}
}
return 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();
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());
}
// 保存文件信息
SysOss oss = new SysOss();
oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalfileName);
oss.setService(storage.getConfigKey());
baseMapper.insert(oss);
SysOssVo sysOssVo = new SysOssVo();
BeanCopyUtils.copy(oss, sysOssVo);
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,184 @@
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.constant.UserConstants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.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 String checkPostNameUnique(SysPost post) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
.eq(SysPost::getPostName, post.getPostName())
.ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验岗位编码是否唯一
*
* @param post 岗位信息
* @return 结果
*/
@Override
public String checkPostCodeUnique(SysPost post) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
.eq(SysPost::getPostCode, post.getPostCode())
.ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 通过岗位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,412 @@
package com.ruoyi.system.service.impl;
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.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.satoken.utils.LoginHelper;
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");
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(Arrays.asList(perm.getRoleKey().trim().split(",")));
}
}
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 String checkRoleNameUnique(SysRole role) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
.eq(SysRole::getRoleName, role.getRoleName())
.ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验角色权限是否唯一
*
* @param role 角色信息
* @return 结果
*/
@Override
public String checkRoleKeyUnique(SysRole role) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
.eq(SysRole::getRoleKey, role.getRoleKey())
.ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验角色是否允许操作
*
* @param role 角色信息
*/
@Override
public void checkRoleAllowed(SysRole role) {
if (ObjectUtil.isNotNull(role.getRoleId()) && role.isAdmin()) {
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) {
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) {
checkRoleAllowed(new SysRole(roleId));
checkRoleDataScope(roleId);
SysRole role = selectRoleById(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) {
return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, userRole.getRoleId())
.eq(SysUserRole::getUserId, userRole.getUserId()));
}
/**
* 批量取消授权用户角色
*
* @param roleId 角色ID
* @param userIds 需要取消授权的用户数据ID
* @return 结果
*/
@Override
public int deleteAuthUsers(Long roleId, Long[] userIds) {
return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, roleId)
.in(SysUserRole::getUserId, Arrays.asList(userIds)));
}
/**
* 批量选择授权用户角色
*
* @param roleId 角色ID
* @param userIds 需要授权的用户数据ID
* @return 结果
*/
@Override
public int insertAuthUsers(Long roleId, Long[] userIds) {
// 新增用户与角色管理
int rows = 1;
List<SysUserRole> list = new ArrayList<SysUserRole>();
for (Long userId : userIds) {
SysUserRole ur = new SysUserRole();
ur.setUserId(userId);
ur.setRoleId(roleId);
list.add(ur);
}
if (list.size() > 0) {
rows = userRoleMapper.insertBatch(list) ? list.size() : 0;
}
return rows;
}
}

View File

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

View File

@ -0,0 +1,488 @@
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.core.constant.UserConstants;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.mybatis.helper.DataBaseHelper;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.common.core.utils.StreamUtils;
import com.ruoyi.common.core.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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 用户 业务层处理
*
* @author Lion Li
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl implements ISysUserService {
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 String checkUserNameUnique(SysUser user) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUserName, user.getUserName())
.ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验手机号码是否唯一
*
* @param user 用户信息
* @return
*/
@Override
public String checkPhoneUnique(SysUser user) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, user.getPhonenumber())
.ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验email是否唯一
*
* @param user 用户信息
* @return
*/
@Override
public String checkEmailUnique(SysUser user) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getEmail, user.getEmail())
.ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
if (exist) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验用户是否允许操作
*
* @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 = new ArrayList<>(posts.length);
for (Long postId : posts) {
SysUserPost up = new SysUserPost();
up.setUserId(user.getUserId());
up.setPostId(postId);
list.add(up);
}
userPostMapper.insertBatch(list);
}
}
/**
* 新增用户角色信息
*
* @param userId 用户ID
* @param roleIds 角色组
*/
public void insertUserRole(Long userId, Long[] roleIds) {
if (ArrayUtil.isNotEmpty(roleIds)) {
// 新增用户与角色管理
List<SysUserRole> list = new ArrayList<>(roleIds.length);
for (Long roleId : roleIds) {
SysUserRole ur = new SysUserRole();
ur.setUserId(userId);
ur.setRoleId(roleId);
list.add(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);
}
}