package com.ruoyi.xq.manager; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.extra.spring.SpringUtil; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.enums.UserType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.system.service.SysLoginService; import com.ruoyi.xq.domain.*; import com.ruoyi.xq.enums.common.AuditEnum; import com.ruoyi.xq.enums.common.CodeEnum; import com.ruoyi.xq.enums.common.SystemConfigEnum; import com.ruoyi.xq.enums.userauth.UserGenderEnum; import com.ruoyi.xq.executor.ExecutorConstant; import com.ruoyi.xq.lock.LockKey; import com.ruoyi.xq.service.*; import com.ruoyi.yunxin.client.ImUserClient; import com.ruoyi.yunxin.req.CreateUserReq; import com.ruoyi.yunxin.req.UpdateTokenReq; import com.ruoyi.yunxin.resp.YxCommonR; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.Collections; import java.util.concurrent.TimeUnit; @Component @Slf4j public class CaiLoginManager { @Autowired private UserService userService; @Autowired private SysLoginService sysLoginService; @Autowired private UserLoginService userLoginService; @Autowired private UserAuthService userAuthService; @Autowired private UserCodeGenService userCodeGenService; @Autowired private UserInfoService userInfoService; @Autowired private SystemConfigManager systemConfigManager; @Autowired private RedissonClient redissonClient; @Resource private ImUserClient imUserClient; @Autowired private SmsVerifyService smsVerifyService; @Autowired private UserExtendService userExtendService; public String login(String username,String password){ User user = userService.getByUsername(username); if(user == null){ throw new ServiceException("用户不存在或密码错误"); } /*String imei = ServletUtils.getImei(); UserForbidManager.CheckForbid forbid = userForbidManager.checkForbid(user.getId(), user.getUsercode(), imei, ServletUtils.getClientIP()); if(forbid != null && forbid.isForbid()){ throw new ServiceException(forbid.getMessage()); }*/ if(user.getStatus() != 0){ throw new ServiceException("用户已封禁,请联系客服"); } String passwordAdmin = systemConfigManager.getSystemConfig(SystemConfigEnum.PASSWORD_ADMIN); if(StringUtils.isNotBlank(passwordAdmin) && passwordAdmin.equals(password)){ return login(user); } if(!BCrypt.checkpw(password, user.getPassword())){ throw new ServiceException("用户不存在或密码错误"); } return login(user); } public String loginSms(String mobile,String code,String inviteCode){ boolean check = smsVerifyService.check(CodeEnum.LOGIN, mobile, code); if(!check){ throw new ServiceException("验证码错误"); } User user = userService.getByUsername(mobile); if(user == null){ user = this.register(mobile, inviteCode); } return login(user); } public User register(String mobile,String inviteCode) { User user = userService.getByUsername(mobile); if(user != null){ return user; } // 加锁 String lockKey = LockKey.getRegisterLockKey(mobile); RLock lock = redissonClient.getLock(lockKey); if(lock.isLocked()){ throw new ServiceException("您点击太快了"); } lock.lock(); try { CaiLoginManager bean = SpringUtil.getBean(CaiLoginManager.class); user = bean.registerUser(mobile,inviteCode); }finally { lock.unlock(); } if(user.getInviteId() != null){ User finalUser = user; ExecutorConstant.COMMON_EXECUTOR.execute(() -> dealInviteId(finalUser)); } return user; } public void dealInviteId(User user){ String inviteCode = user.getInviteCode(); if(StringUtils.isEmpty(inviteCode)){ return; } User inviteUser = userService.getByUsercode(inviteCode); if(inviteUser == null){ return; } userService.update(Wrappers.lambdaUpdate(User.class) .eq(User::getId,user.getId()) .set(User::getInviteId, inviteUser.getId())); userExtendService.update(Wrappers.lambdaUpdate(UserExtend.class) .eq(UserExtend::getUserId, user.getId()) .set(UserExtend::getInviteId, inviteUser.getId()) .set(UserExtend::getInviteCode, inviteUser.getUsercode())); } /** * 退出登录 */ public void logout() { try { LoginUser loginUser = LoginHelper.getLoginUser(); sysLoginService.recordLogininfor(loginUser.getUsername(), loginUser.getUserType(), Constants.LOGOUT, MessageUtils.message("user.logout.success")); } catch (NotLoginException ignored) { } finally { try { StpUtil.logout(); } catch (NotLoginException ignored) { } } } private String login(User user){ LoginUser loginUser = new LoginUser(); loginUser.setDeptId(null); loginUser.setDeptName(null); loginUser.setMenuPermission(Collections.emptySet()); loginUser.setRolePermission(Collections.emptySet()); loginUser.setUsername(user.getMobile()); loginUser.setRoles(Collections.emptyList()); loginUser.setRoleId(null); loginUser.setUserId(user.getId()); loginUser.setUserType(UserType.APP_USER.getUserType()); LoginHelper.login(loginUser); sysLoginService.recordLogininfor(loginUser.getUsername(), UserType.APP_USER.getUserType(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); return StpUtil.getTokenValue(); } @Transactional(rollbackFor = Exception.class) public User registerUser(String mobile,String inviteCode){ String usercode = userCodeGenService.getCodeGen(); User add = new User(); add.setUsercode(usercode); add.setNickname("用户"+usercode); add.setType(0); add.setPassword(BCrypt.hashpw(usercode+"用户手动滑稽安康黄鼠狼")); add.setMobile(mobile); add.setGender(UserGenderEnum.NONE.getCode()); add.setInviteCode(inviteCode); add.setImToken(IdUtil.simpleUUID()); userService.save(add); CreateUserReq req = new CreateUserReq(); req.setAccid(add.getId()+""); req.setToken(add.getImToken()); req.setName(add.getNickname()); YxCommonR r = imUserClient.createUser(req); if(!r.isSuccess()){ if(r.getCode() == 414){ UpdateTokenReq req1 = new UpdateTokenReq(); req1.setAccid(add.getId()+""); req1.setToken(add.getImToken()); YxCommonR commonR = imUserClient.updateToken(req1); if(!commonR.isSuccess()){ log.error("刷新云token失败,{}", JSON.toJSONString(commonR)); throw new ServiceException("注册失败,云信异常"); } }else{ log.error("创建云信账号失败,{}", JSON.toJSONString(r)); throw new ServiceException("注册失败,云信异常"); } } String clientIP = ServletUtils.getClientIP(); UserLogin userLogin = new UserLogin(); userLogin.setUserId(add.getId()); userLogin.setUsercode(usercode); userLogin.setLastLoginIp(clientIP); userLogin.setLastLoginTime(LocalDateTime.now()); userLogin.setRegIp(clientIP); userLogin.setRegTime(LocalDateTime.now()); userLoginService.save(userLogin); UserInfo userInfo = new UserInfo(); userInfo.setUsercode(usercode); userInfo.setUserId(add.getId()); userInfoService.save(userInfo); UserAuth userAuth = new UserAuth(); userAuth.setUsercode(usercode); userAuth.setUserId(add.getId()); userAuth.setPhone(add.getMobile()); userAuth.setPhoneAuth(AuditEnum.SUCCESS.getCode()); userAuthService.save(userAuth); UserExtend userExtend = new UserExtend(); userExtend.setUsercode(usercode); userExtend.setUserId(add.getId()); userExtendService.save(userExtend); return add; } public void resetPassword(String mobile,String code,String password) { User user = userService.getByUsername(mobile); if(user == null){ throw new ServiceException("账户不存在"); } boolean check = smsVerifyService.check(CodeEnum.RESET_PASSWORD, mobile, code); if(!check){ throw new ServiceException("验证码错误"); } userService.resetPassword(user.getId(),password); } }