package com.mes.userinfo.service.impl; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.mes.common.config.Const; import com.mes.common.utils.JwtUtil; import com.mes.common.utils.RedisUtil; import com.mes.common.utils.UserInfoUtils; import com.mes.entity.request.GeneralRequest; import com.mes.menu.mapper.SysMenuMapper; import com.mes.role.entity.SysRole; import com.mes.role.entity.SysRoleMenu; import com.mes.role.service.SysRoleService; import com.mes.userinfo.entity.LoginUser; import com.mes.userinfo.entity.SysUser; import com.mes.userinfo.entity.SysUserRole; import com.mes.userinfo.entity.vo.SysUserVO; import com.mes.userinfo.mapper.SysUserMapper; import com.mes.userinfo.service.SysUserRoleService; import com.mes.userinfo.service.SysUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** *

* 用户表 服务实现类 *

* * @author zhoush * @since 2024-04-11 */ @Service @Slf4j public class SysUserServiceImpl extends ServiceImpl implements SysUserService, UserDetailsService { @Autowired private AuthenticationManager authenticationManager; @Autowired private RedisUtil redisUtil; @Resource private SysMenuMapper sysMenuMapper; @Resource private SysUserRoleService sysUserRoleService; @Resource private SysRoleService sysRoleService; @Resource BCryptPasswordEncoder passwordEncoder; @Override public Map login(SysUser user) { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword()); Authentication authenticate = authenticationManager.authenticate(authenticationToken); if (Objects.isNull(authenticate)) { throw new RuntimeException("用户名或密码错误"); } //使用userid生成token LoginUser loginUser = (LoginUser) authenticate.getPrincipal(); String userId = loginUser.getUser().getId().toString(); String jwt = JwtUtil.generateToken(userId); //查询权限信息 // List perms = sysMenuMapper.selectPermsByUserId(userId); //authenticate存入redis redisUtil.setCacheObject("login:" + userId, loginUser); //把token响应给前端 HashMap map = new HashMap<>(); map.put("token", jwt); return map; } @Override public String logout() { log.info("用户退出"); SysUser user = UserInfoUtils.get(); redisUtil.deleteObject("login:" + user.getId()); return "注销成功"; } @Transactional @Override public String saveUser(SysUserVO user) { log.info("保存用户信息"); // 默认密码 String password = passwordEncoder.encode(Const.DEFULT_PASSWORD); user.setPassword(password); SysUser sysUser = new SysUser(); BeanUtils.copyProperties(user, sysUser); this.save(sysUser); saveUserRole(user.getRoleList(), sysUser.getId()); return "success"; } @Transactional @Override public SysUserVO updateUser(SysUserVO user) { log.info("更新用户信息"); SysUser sysUser = new SysUser(); BeanUtils.copyProperties(user, sysUser); this.updateById(sysUser); log.info("删除用户角色信息"); List roleIds = user.getRoleList().stream().map(SysRole::getId).collect(Collectors.toList()); sysUserRoleService.remove(new LambdaQueryWrapper() .eq(SysUserRole::getUserId, sysUser.getId()).in(CollectionUtil.isNotEmpty(roleIds), SysUserRole::getRoleId, roleIds)); log.info("保存用户角色信息"); saveUserRole(user.getRoleList(), sysUser.getId()); return user; } @Override public String resetPassword(Long userId) { log.info("重置密码为{}", Const.DEFULT_PASSWORD); SysUser sysUser = new SysUser(); sysUser.setId(userId); String password = passwordEncoder.encode(Const.DEFULT_PASSWORD); sysUser.setPassword(password); this.updateById(sysUser); return "success"; } @Override public SysUser queryByUserName(String userName) { return baseMapper.selectOne(new LambdaQueryWrapper().eq(SysUser::getUserName, userName)); } @Override public List listByUserName(GeneralRequest request) { MPJLambdaWrapper wrapper = new MPJLambdaWrapper<>(); wrapper.selectAll(SysUser.class) .selectCollection(SysRole.class, SysUserVO::getRoleList) .leftJoin(SysUserRole.class, SysUserRole::getUserId, SysUser::getId) .leftJoin(SysRole.class, SysRole::getId, SysUserRole::getRoleId) .like(StringUtils.hasText(request.getKey()), SysUser::getUserName, request.getKey()); return baseMapper.selectJoinList(SysUserVO.class, wrapper); } @Transactional @Override public String deleteUser(List ids) { this.removeByIds(ids); sysUserRoleService.remove(new QueryWrapper().in("user_id", ids)); return "success"; } @Override public List getUserAuthorityInfo(Long userId) { SysUser sysUser = baseMapper.selectById(userId); // ROLE_admin,ROLE_normal,sys:user:list,.... String authority = ""; if (redisUtil.hasKey("GrantedAuthority:" + sysUser.getUserName())) { authority = redisUtil.getCacheObject("GrantedAuthority:" + sysUser.getUserName()); } else { // 获取角色编码 List roles = sysRoleService.list(new QueryWrapper() .inSql("id", "select role_id from sys_user_role where user_id = " + userId)); if (roles.size() > 0) { String roleCodes = roles.stream().map(r -> "ROLE_" + r.getRoleKey()).collect(Collectors.joining(",")); authority = roleCodes.concat(","); } // 获取菜单操作编码 List perms = sysMenuMapper.selectPermsByUserId(userId); if (perms.size() > 0) { String menuPerms = String.join(",", perms); authority = authority.concat(menuPerms); } redisUtil.setCacheObject("GrantedAuthority:" + sysUser.getUserName(), authority, 60 * 60, TimeUnit.SECONDS); } return Arrays.stream(authority.split(",")).collect(Collectors.toList()); } @Override public void clearUserAuthorityInfo(String userName) { redisUtil.deleteObject("GrantedAuthority:" + userName); } @Override public void clearUserAuthorityInfoByRoleId(Long roleId) { List sysUsers = this.list(new QueryWrapper() .inSql("id", "select user_id from sys_user_role where role_id = " + roleId)); sysUsers.forEach(u -> { this.clearUserAuthorityInfo(u.getUserName()); }); } @Override public void clearUserAuthorityInfoByMenuId(Long menuId) { MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysUser.class).distinct() .leftJoin(SysUser.class, SysUser::getId, SysUserRole::getUserId) .leftJoin(SysRoleMenu.class, SysRoleMenu::getRoleId, SysUserRole::getRoleId) .eq(SysRoleMenu::getMenuId, menuId); List sysUsers = sysUserRoleService.selectJoinList(SysUser.class, wrapper); sysUsers.forEach(u -> { this.clearUserAuthorityInfo(u.getUserName()); }); } /** * 实现UserDetailsService接口,从数据库内获取用户及权限信息 * * @param username * @return * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); lqw.eq(SysUser::getUserName, username); SysUser user = this.baseMapper.selectOne(lqw); //判断是否为空 if (Objects.isNull(user)) { throw new RuntimeException("用户名或密码错误"); } //查询权限信息 List perms = sysMenuMapper.selectPermsByUserId(user.getId()); return new LoginUser(user, perms); } private void saveUserRole(List roles, Long userId) { log.info("保存用户角色信息"); List userRoles = new ArrayList<>(); if (CollectionUtils.isEmpty(roles)) { log.info("保存用户角色信息为空,给默认普通用户角色"); userRoles.add(new SysUserRole(userId, Const.DEFULT_ROLE)); } else { log.info("保存用户角色信息"); userRoles = roles.stream().map(e -> new SysUserRole(userId, e.getId())).collect(Collectors.toList()); } sysUserRoleService.saveBatch(userRoles); } }