SysUserV2ServiceImpl.java 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. package com.backendsys.modules.system.service.impl;
  2. import cn.hutool.core.convert.Convert;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.backendsys.exception.CustException;
  5. import com.backendsys.modules.common.config.redis.utils.RedisUtil;
  6. import com.backendsys.modules.common.utils.MybatisUtil;
  7. import com.backendsys.modules.system.dao.*;
  8. import com.backendsys.modules.system.entity.SysUser.*;
  9. import com.backendsys.modules.system.service.SysUserV2Service;
  10. import com.backendsys.utils.response.PageEntity;
  11. import com.backendsys.utils.response.PageInfoResult;
  12. import com.backendsys.utils.response.Result;
  13. import com.backendsys.utils.response.ResultEnum;
  14. import com.backendsys.utils.v2.PageUtils;
  15. import com.baomidou.mybatisplus.core.conditions.Wrapper;
  16. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  17. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  18. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  19. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  20. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  21. import org.redisson.api.RLock;
  22. import org.redisson.api.RedissonClient;
  23. import org.springframework.beans.BeanUtils;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.context.annotation.Lazy;
  26. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  27. import org.springframework.stereotype.Service;
  28. import org.springframework.transaction.annotation.Transactional;
  29. import java.util.*;
  30. import java.util.concurrent.TimeUnit;
  31. import java.util.stream.Collectors;
  32. @Service
  33. public class SysUserV2ServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements SysUserV2Service {
  34. @Lazy
  35. @Autowired
  36. RedissonClient redissonClient;
  37. @Autowired
  38. private RedisUtil redisUtil;
  39. @Autowired
  40. private SysUserDao sysUserDao;
  41. @Autowired
  42. private SysUserInfoDao sysUserInfoDao;
  43. @Autowired
  44. private SysUserRoleDao sysUserRoleDao;
  45. @Autowired
  46. private SysUserRoleRelationDao sysUserRoleRelationDao;
  47. @Autowired
  48. private SysUserRoleModuleRelationDao sysUserRoleModuleRelationDao;
  49. /**
  50. * 获得系统用户列表
  51. */
  52. @Override
  53. public PageEntity selectUserList(SysUserDTO sysUserDTO) {
  54. // 分页
  55. PageUtils.startPage();
  56. List<SysUserInfo> list = sysUserInfoDao.selectUserList(sysUserDTO);
  57. return new PageInfoResult(list).toEntity();
  58. }
  59. /**
  60. * 获得系统用户列表 (在线的)
  61. */
  62. @Override
  63. public PageEntity selectUserOnlineList(SysUserDTO sysUserDTO) {
  64. // 分页
  65. PageUtils.startPage();
  66. // 获得 用户最后登录的 tokenUUID
  67. Collection<String> redisKeys = redisUtil.keys("token:*");
  68. List<String> last_login_uuids = redisKeys.stream().map(e -> String.valueOf(e).replace("token:id:", "")).collect(Collectors.toList());
  69. List<SysUserInfo> list = sysUserInfoDao.selectUserByLastLoginUuids(last_login_uuids);
  70. return new PageInfoResult(list).toEntity();
  71. }
  72. /**
  73. * 获得系统用户详情
  74. */
  75. @Override
  76. public SysUserInfo selectUserInfo(Long user_id) {
  77. // 获得 用户账号信息
  78. SysUser sysUser = sysUserDao.selectOne(new QueryWrapper<SysUser>().eq("id", user_id));
  79. Objects.requireNonNull(sysUser, "用户不存在");
  80. // 获得 用户基本信息
  81. SysUserInfo sysUserInfo = sysUserInfoDao.selectOne(new QueryWrapper<SysUserInfo>().eq("user_id", user_id));
  82. Objects.requireNonNull(sysUserInfo, "用户不存在");
  83. // 用户账号信息 赋值到 用户基本信息
  84. BeanUtils.copyProperties(sysUser, sysUserInfo);
  85. // 获得 用户角色(绑定关系)
  86. List<Map<String, Object>> roles = sysUserRoleDao.selectRoleByUserId(user_id);
  87. sysUserInfo.setRoles(roles);
  88. // List<Long> role_ids = roles.stream().map(SysUserRole::getRole_id).collect(Collectors.toList());
  89. List<Long> role_ids = roles.stream().map(m -> Convert.toLong(m.get("role_id"))).collect(Collectors.toList());
  90. sysUserInfo.setRole_id(role_ids);
  91. List<String> modules = sysUserRoleModuleRelationDao.selectUserRoleModuleIdsByRoleIds(role_ids);
  92. sysUserInfo.setModules(modules);
  93. return sysUserInfo;
  94. }
  95. /**
  96. * 获得系统用户权限
  97. */
  98. @Override
  99. public List<String> selectUserModule(Long user_id) {
  100. // 获得当前角色关系(集合)
  101. List<Long> userRoleIds = sysUserRoleRelationDao.selectUserRoleIds(user_id);
  102. // 获得当前角色关系(集合) 所对应的权限(集合)
  103. List<String> roleModuleIds = new ArrayList<>();
  104. if (userRoleIds.size() > 0) {
  105. roleModuleIds = sysUserRoleModuleRelationDao.selectUserRoleModuleIdsByRoleIds(userRoleIds);
  106. roleModuleIds = roleModuleIds.stream().distinct().collect(Collectors.toList());
  107. }
  108. return roleModuleIds;
  109. }
  110. /**
  111. * 创建系统用户
  112. */
  113. @Override
  114. @Transactional
  115. public Map<String, Object> insertUser(SysUserDTO sysUserDTO) {
  116. RLock lock = redissonClient.getLock("insertUser");
  117. try { lock.tryLock(3, TimeUnit.SECONDS);
  118. // 密码二次加密
  119. String password = sysUserDTO.getPassword();
  120. BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
  121. String encodedPassword = encoder.encode(password);
  122. sysUserDTO.setPassword(encodedPassword);
  123. sysUserDao.insertUser(sysUserDTO);
  124. return Map.of("user_id", sysUserDTO.getId());
  125. } catch (InterruptedException e) { throw new RuntimeException(e);
  126. } finally { lock.unlock(); }
  127. }
  128. /**
  129. * 编辑系统用户信息
  130. */
  131. @Override
  132. @Transactional
  133. public Map<String, Object> updateUserInfo(SysUserDTO sysUserDTO) {
  134. RLock lock = redissonClient.getLock("updateUserInfo");
  135. try { lock.tryLock(3, TimeUnit.SECONDS);
  136. // 判断记录是否存在
  137. MybatisUtil.checkExists(sysUserDao, "id", sysUserDTO.getUser_id(), "用户不存在");
  138. // 当 status 状态为 -1(禁用) 时,同时清除登录状态
  139. Integer status = sysUserDTO.getStatus();
  140. if (status != null && status == -1) {
  141. String last_login_uuid = sysUserDTO.getLast_login_uuid();
  142. redisUtil.delete("token:id:" + last_login_uuid);
  143. sysUserDTO.setLast_login_uuid("");
  144. }
  145. sysUserDao.updateUserInfo(sysUserDTO);
  146. return Map.of("user_id", sysUserDTO.getUser_id());
  147. } catch (InterruptedException e) { throw new RuntimeException(e);
  148. } finally { lock.unlock(); }
  149. }
  150. /**
  151. * 编辑系统用户密码
  152. */
  153. @Override
  154. @Transactional
  155. public Map<String, Object> updateUserPassword(SysUserDTO sysUserDTO) {
  156. RLock lock = redissonClient.getLock("updateUserPassword");
  157. try { lock.tryLock(3, TimeUnit.SECONDS);
  158. // 查询用户
  159. SysUser sysUser = sysUserDao.selectOne(new QueryWrapper<SysUser>().eq("id", sysUserDTO.getUser_id()));
  160. if (sysUser == null) throw new CustException("原密码不正确");
  161. BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
  162. // [判断] 原密码是否正确
  163. String old_password_request = sysUserDTO.getOld_password();
  164. String old_password = sysUser.getPassword();
  165. if (!encoder.matches(old_password_request, old_password)) {
  166. throw new CustException("原密码不正确");
  167. }
  168. // 密码二次加密
  169. SysUser entity = new SysUser();
  170. entity.setId(sysUserDTO.getUser_id());
  171. entity.setPassword(encoder.encode(sysUserDTO.getPassword()));
  172. System.out.println(entity);
  173. sysUserDao.updateById(entity);
  174. return Map.of("user_id", sysUserDTO.getUser_id());
  175. } catch (InterruptedException e) { throw new RuntimeException(e);
  176. } finally { lock.unlock(); }
  177. }
  178. /**
  179. * 删除系统用户 (以及部分关联表)
  180. */
  181. @Override
  182. @Transactional
  183. public Map<String, Object> deleteUser(List<Long> user_ids) {
  184. RLock lock = redissonClient.getLock("deleteUser");
  185. try { lock.tryLock(3, TimeUnit.SECONDS);
  186. sysUserDao.delete(new QueryWrapper<SysUser>().in("id", user_ids));
  187. sysUserInfoDao.delete(new QueryWrapper<SysUserInfo>().in("user_id", user_ids));
  188. sysUserRoleRelationDao.delete(new QueryWrapper<SysUserRoleRelation>().in("user_id", user_ids));
  189. return Map.of("user_ids", user_ids);
  190. } catch (InterruptedException e) { throw new RuntimeException(e);
  191. } finally { lock.unlock(); }
  192. }
  193. /**
  194. * 踢出系统用户
  195. */
  196. @Override
  197. public Map<String, Object> kickUser(Long user_id) {
  198. RLock lock = redissonClient.getLock("kickUser");
  199. try { lock.tryLock(3, TimeUnit.SECONDS);
  200. // 查询用户信息
  201. Wrapper queryWrapper = new QueryWrapper<SysUserInfo>().lambda().eq(SysUserInfo::getUser_id, user_id);
  202. SysUserInfo sysUserInfo = sysUserInfoDao.selectOne(queryWrapper);
  203. if (sysUserInfo != null) {
  204. // 清除缓存
  205. String last_login_uuid = Convert.toStr(sysUserInfo.getLast_login_uuid());
  206. if (StrUtil.isNotEmpty(last_login_uuid)) redisUtil.delete("token:id:" + last_login_uuid);
  207. // 更新用户信息 (查询最后登录uuid,并清除)
  208. Wrapper updateWrapper = new UpdateWrapper<SysUserInfo>().lambda().set(SysUserInfo::getLast_login_uuid, "").eq(SysUserInfo::getUser_id, user_id);
  209. sysUserInfoDao.update(null, updateWrapper);
  210. }
  211. return Map.of("user_id", user_id);
  212. } catch (InterruptedException e) { throw new RuntimeException(e);
  213. } finally { lock.unlock(); }
  214. }
  215. }