package com.ruoyi.cai.auth; 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.cai.domain.*; import com.ruoyi.cai.dto.commom.ignoredata.InviteIgnoreData; import com.ruoyi.cai.enums.CodeEnum; import com.ruoyi.cai.enums.GenderEnum; import com.ruoyi.cai.enums.IgnoreDataTypeEnum; import com.ruoyi.cai.enums.SystemConfigEnum; import com.ruoyi.cai.executor.ExecutorConstant; import com.ruoyi.cai.manager.*; import com.ruoyi.cai.service.*; import com.ruoyi.cai.util.RandomSjUtil; 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.common.utils.ip.AddressUtils; import com.ruoyi.system.service.SysLoginService; import com.ruoyi.yunxin.Yunxin; 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.math.BigDecimal; 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 CodeManager codeManager; @Autowired private UserCodeGenService userCodeGenService; @Autowired private UserInfoService userInfoService; @Autowired private SystemConfigManager systemConfigManager; @Autowired private AccountService accountService; @Autowired private UserOnlineService userOnlineService; @Autowired private RedissonClient redissonClient; @Autowired private UserInviteService userInviteService; @Autowired private UnionService unionService; @Autowired private UnionUserService unionUserService; @Resource private ImUserClient imUserClient; @Autowired private UserCountService userCountService; @Autowired private UserForbidManager userForbidManager; @Autowired private AwardManager awardManager; @Autowired private SmsVerifyService smsVerifyService; @Autowired private IgnoreDataService ignoreDataService; 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 register(CaiRegisterUser caiUser) { User user = userService.getByUsername(caiUser.getUsername()); if(user != null){ throw new ServiceException("手机号已存在"); } if(!caiUser.getPassword().equals(caiUser.getPasswordCheck())){ throw new ServiceException("两次输入密码不一致,请检查"); } boolean check = smsVerifyService.check(CodeEnum.REGISTER, caiUser.getUsername(), caiUser.getCode()); if(!check){ throw new ServiceException("验证码错误"); } // 加锁 String lockKey = LockManager.getRegisterLockKey(caiUser.getUsername()); RLock lock = redissonClient.getLock(lockKey); if(lock.isLocked()){ throw new ServiceException("您点击太快了"); } lock.lock(); try { CaiLoginManager bean = SpringUtil.getBean(CaiLoginManager.class); user = bean.registerUser(caiUser); }finally { lock.unlock(); } awardManager.giveRegisterAsync(user.getId()); if(user.getInviteId() != null){ User finalUser = user; ExecutorConstant.COMMON_EXECUTOR.execute(() -> dealInviteId(finalUser,true)); } return login(user); } public void dealInviteId(User user, boolean openIgnore){ Long inviteId = user.getInviteId(); if(inviteId == null){ return; } User inviteUser = userService.getById(inviteId); if(inviteUser == null){ return; } String key = LockManager.getDealInviteLockKey(user.getId()); RLock lock = redissonClient.getLock(key); if(lock.isLocked()){ log.warn("点击太快了,等一等,dealInviteId"); return; } lock.lock(5,TimeUnit.SECONDS); try { if(openIgnore){ Integer inviteBindRate = systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.INVITE_BIND_RATE); boolean sj = RandomSjUtil.rateSj(inviteBindRate); if(!sj){ InviteIgnoreData data = new InviteIgnoreData(); data.setUserId(user.getId()); data.setInviteId(inviteId); ignoreDataService.saveIgnoreData(IgnoreDataTypeEnum.INVITE,inviteUser.getId(),data); return; } } UserInvite check = userInviteService.getByUserId(user.getId()); if(check == null){ UserInvite userInvite = new UserInvite(); userInvite.setUserId(user.getId()); userInvite.setInviteId(user.getInviteId()); userInviteService.save(userInvite); }else{ userInviteService.update(Wrappers.lambdaUpdate(UserInvite.class) .eq(UserInvite::getId,check.getId()) .set(UserInvite::getInviteId,user.getInviteId()) .set(UserInvite::getRewardCoinTotal,0L)); } // 处理工会 Union union = null; // if(inviteUser.getIsUnion() == 1){ union = unionService.getByUserId(inviteUser.getId()); } else { UnionUser unionUser = unionUserService.getByUserId(inviteUser.getId()); if(unionUser != null){ union = unionService.getById(unionUser); } } if(union == null){ log.info("邀请人没有工会,无法入会 inviteId={}",inviteId); return; } UnionUser checkUnionUser = unionUserService.getByUserId(user.getId()); if(checkUnionUser != null){ UnionUser unionUser = new UnionUser(); unionUser.setUnionId(union.getId()); unionUser.setUnionUserId(union.getUserId()); unionUser.setUserId(user.getId()); unionUser.setVideoDivide(systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.DEFAULT_UNION_VIDEO_INCOME_RATE)); unionUser.setGiftDivide(systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.DEFAULT_UNION_VIDEO_INCOME_RATE)); unionUser.setVipDivide(BigDecimal.ZERO); unionUser.setEnableRate(true); unionUserService.save(unionUser); } }finally { lock.unlock(); } } /** * 退出登录 */ 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(CaiRegisterUser user){ String usercode = userCodeGenService.getCodeGen(); User add = new User(); add.setUsercode(usercode); add.setNickname("用户"+usercode); add.setType(0); add.setPassword(BCrypt.hashpw(user.getPassword())); add.setMobile(user.getUsername()); add.setGender(GenderEnum.NONE.getCode()); add.setAvatar(GenderEnum.NONE.getDefaultAvatar()); add.setInviteId(user.getInviteId()); 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(); UserInfo userInfo = new UserInfo(); userInfo.setUserId(add.getId()); userInfo.setVideoIncomeRate(systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.DEFAULT_VIDEO_INCOME_RATE)); userInfo.setGuardIncomeRate(systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.DEFAULT_GUARD_INCOME_RATE)); userInfo.setGiftIncomeRate(systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.DEFAULT_GIFT_INCOME_RATE)); userInfo.setPayIncomeRate(systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.DEFAULT_PAY_INCOME_RATE)); userInfo.setLoginCount(1); userInfo.setLastLoginIp(clientIP); userInfo.setLastLoginTime(LocalDateTime.now()); userInfo.setRegIp(clientIP); userInfo.setRegTime(LocalDateTime.now()); userInfoService.save(userInfo); Account account = new Account(); account.setUserId(add.getId()); accountService.save(account); UserOnline userOnline = new UserOnline(); userOnline.setUserId(add.getId()); userOnlineService.save(userOnline); UserCount userCount = new UserCount(); userCount.setUserId(add.getId()); userCountService.save(userCount); return add; } public void resetPassword(ResetPasswordReq code) { User user = userService.getByUsername(code.getMobile()); if(user == null){ throw new ServiceException("账户不存在"); } boolean check = smsVerifyService.check(CodeEnum.RESET_PASSWORD, code.getMobile(), code.getCode()); if(!check){ throw new ServiceException("验证码错误"); } userService.resetPassword(user.getId(),code.getPassword()); } }