package com.simuwang.manage.service; import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; import com.simuwang.base.common.exception.APIException; import com.simuwang.base.common.util.ServletUtils; import com.simuwang.base.common.util.TreeUtil; import com.simuwang.base.components.UserAuthService; import com.simuwang.base.config.DaqProperties; import com.simuwang.base.pojo.dos.sys.SysMenuDO; import com.simuwang.base.pojo.dos.sys.SysRoleDO; import com.simuwang.base.pojo.dos.sys.SysUserDO; import com.simuwang.base.pojo.dto.sys.UserUpdatePwdCmd; import com.simuwang.manage.dto.LoginUser; import com.simuwang.manage.dto.MenuTreeDTO; import com.simuwang.manage.dto.UserInfoVO; import com.simuwang.manage.dto.UserRoleDTO; import com.simuwang.shiro.core.ShiroToken; import com.simuwang.shiro.core.ShiroUser; import com.simuwang.shiro.core.jwt.JwtContext; import com.simuwang.shiro.utils.UserUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * @author wangzaijun * @date 2024/9/12 20:28 * @description 系统管理服务 */ @Service public class LoginService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final JwtContext jwtContext; private final DaqProperties properties; private final UserAuthService userAuthService; public LoginService(JwtContext jwtContext, DaqProperties properties, UserAuthService userAuthService) { this.jwtContext = jwtContext; this.properties = properties; this.userAuthService = userAuthService; } public String getRsaPublicKey() { return this.properties.getSecurityRsa().getPublicKey(); } /** * 登录业务 * * @param loginUser 登录用户密码 * @return / */ public String login(LoginUser loginUser) { ShiroToken shiroToken = new ShiroToken(loginUser.getUsername(), loginUser.getPassword()); Subject subject = SecurityUtils.getSubject(); subject.login(shiroToken); String requestIp = ServletUtils.getIpAddr(); return this.jwtContext.generateToken(loginUser.getUsername(), requestIp); } /** * 登出 * * @return / */ public boolean logout() { Subject subject = SecurityUtils.getSubject(); ShiroUser shiroUser = UserUtils.getLoginUser(); String requestIp = ServletUtils.getIpAddr(); this.jwtContext.cleanUserCache(shiroUser.getUsername(), requestIp); subject.logout(); return true; } /** * 获取当前用户的权限角色信息 * * @return / */ public UserInfoVO getUserInfo() { ShiroUser shiroUser = UserUtils.getLoginUser(); Integer userId = shiroUser.getUserId(); String username = shiroUser.getUsername(); SysUserDO userInfo = this.userAuthService.getUserInfoByUsername(username); // 用户角色信息转换 List roleList = this.userAuthService.listUserRoleByUserId(userId); List roles = roleList.stream() .map(e -> new UserRoleDTO(e.getRoleId(), e.getRoleName(), e.getRoleKey())) .distinct().collect(Collectors.toList()); // 用户权限处理 List menuList = this.userAuthService.listUserMenuByUserId(userId, 1); // 过滤按钮 List tempList = menuList.stream() .map(MenuTreeDTO::new).collect(Collectors.toList()); // 菜单列表转树结构 List trees = TreeUtil.list2Tree(tempList, MenuTreeDTO::getId, MenuTreeDTO::getPid, MenuTreeDTO::getChildren, MenuTreeDTO::setChildren, 0, MenuTreeDTO::getSort); MenuTreeDTO root = new MenuTreeDTO(0, "全部菜单", trees); // 返回的数据结构构建 UserInfoVO vo = new UserInfoVO(userId, username, roles, root); vo.setEmail(userInfo.getEmail()); vo.setPhonenumber(userInfo.getPhonenumber()); return vo; } /** * 修改密码 * * @param command / */ public void updatePwd(UserUpdatePwdCmd command) { ShiroUser loginUser = UserUtils.getLoginUser(); Integer userId = loginUser.getUserId(); String oldPwd = this.decryptPwd(command.getOldPassword()); String newPwd = this.decryptPwd(command.getNewPassword()); String confirmPwd = this.decryptPwd(command.getConfirmPassword()); if (!StrUtil.isAllNotBlank(oldPwd, newPwd, confirmPwd)) { throw new APIException("前端密码加密错误"); } if (Objects.equals(oldPwd, newPwd)) { throw new APIException("新密码不能和旧密码一样"); } if (!Objects.equals(newPwd, confirmPwd)) { throw new APIException("确认密码和新密码不相等"); } SysUserDO entity = command.toEntity(); entity.setUserId(userId); entity.setPassword(newPwd); this.userAuthService.updatePwd(entity); } private String decryptPwd(String pwd) { DaqProperties.SecurityRsa securityRsa = this.properties.getSecurityRsa(); String privateKey = securityRsa.getPrivateKey(); try { return new RSA(privateKey, null).decryptStr(pwd, KeyType.PrivateKey); } catch (Exception e) { this.logger.error("密码rsa解密错误\n{}", ExceptionUtil.stacktraceToString(e)); } return null; } }