package com.xinquan.auth.service; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; import com.xinquan.auth.form.AppChangePwdBody; import com.xinquan.auth.form.AppLoginBody; import com.xinquan.auth.form.AppRegisterBody; import com.xinquan.auth.form.VerifyResultVO; import com.xinquan.auth.util.HWSendSms; import com.xinquan.auth.util.HuaWeiSMSUtil; import com.xinquan.common.core.constant.CacheConstants; import com.xinquan.common.core.constant.Constants; import com.xinquan.common.core.constant.SecurityConstants; import com.xinquan.common.core.constant.UserConstants; import com.xinquan.common.core.domain.R; import com.xinquan.common.core.enums.AppUserStatusEnum; import com.xinquan.common.core.enums.UserStatus; import com.xinquan.common.core.exception.ServiceException; import com.xinquan.common.core.text.Convert; import com.xinquan.common.core.utils.StringUtils; import com.xinquan.common.core.utils.ip.IpUtils; import com.xinquan.common.redis.service.RedisService; import com.xinquan.common.security.utils.SecurityUtils; import com.xinquan.system.api.RemoteUserService; import com.xinquan.system.api.domain.SysUser; import com.xinquan.system.api.feignClient.SysUserClient; import com.xinquan.system.api.model.AppCaptchaBody; import com.xinquan.system.api.model.AppLoginUser; import com.xinquan.system.api.model.AppVerifyCellPhoneBody; import com.xinquan.system.api.model.AppWXLoginBody; import com.xinquan.system.api.model.LoginUser; import com.xinquan.system.api.domain.AppUser; import com.xinquan.user.api.domain.dto.AppUserDTO; import com.xinquan.user.api.feign.RemoteAppUserService; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; /** * 登录校验方法 * * @author ruoyi */ @Slf4j @Component public class SysLoginService { @Autowired private RemoteUserService remoteUserService; @Autowired private SysPasswordService passwordService; @Autowired private SysRecordLogService recordLogService; @Autowired private RedisService redisService; @Autowired private RemoteAppUserService remoteAppUserService; @Autowired private SysUserClient sysUserClient; /** * 登录 */ public LoginUser login(String username, String password) { // 用户名或密码为空 错误 if (StringUtils.isAnyBlank(username, password)) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写"); throw new ServiceException("用户/密码必须填写"); } // 密码如果不在指定范围内 错误 if (password.length() < UserConstants.PASSWORD_MIN_LENGTH || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围"); throw new ServiceException("用户密码不在指定范围"); } // 用户名不在指定范围内 错误 if (username.length() < UserConstants.USERNAME_MIN_LENGTH || username.length() > UserConstants.USERNAME_MAX_LENGTH) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); throw new ServiceException("用户名不在指定范围"); } // IP黑名单校验 String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); } // 查询用户信息 R userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); throw new ServiceException("登录用户:" + username + " 不存在"); } if (R.FAIL == userResult.getCode()) { throw new ServiceException(userResult.getMsg()); } LoginUser userInfo = userResult.getData(); SysUser user = userResult.getData().getSysUser(); if (user.getStatus().equals("1")){ throw new ServiceException("对不起,您的账号:" + username + " 已被冻结,请联系管理员"); } if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); } if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); throw new ServiceException("对不起,您的账号:" + username + " 已停用"); } passwordService.validate(user, password); recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); return userInfo; } public void logout(String loginName) { recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功"); } /** * 注册 */ public void register(String username, String password) { // 用户名或密码为空 错误 if (StringUtils.isAnyBlank(username, password)) { throw new ServiceException("用户/密码必须填写"); } if (username.length() < UserConstants.USERNAME_MIN_LENGTH || username.length() > UserConstants.USERNAME_MAX_LENGTH) { throw new ServiceException("账户长度必须在2到20个字符之间"); } if (password.length() < UserConstants.PASSWORD_MIN_LENGTH || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { throw new ServiceException("密码长度必须在5到20个字符之间"); } // 注册用户信息 SysUser sysUser = new SysUser(); sysUser.setUserName(username); sysUser.setNickName(username); sysUser.setPassword(SecurityUtils.encryptPassword(password)); R registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); if (R.FAIL == registerResult.getCode()) { throw new ServiceException(registerResult.getMsg()); } recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功"); } public static void main(String[] args) { String s = SecurityUtils.encryptPassword("E10ADC3949BA59ABBE56E057F20F883E"); System.out.println(s); } /** * 注册 */ public AppLoginUser appRegister(AppRegisterBody appRegisterBody) { String cellPhone = appRegisterBody.getCellPhone(); String password = appRegisterBody.getPassword(); //验证码校验 if (!verifyCaptcha(cellPhone, appRegisterBody.getCaptcha(), CacheConstants.APP_REGISTER_CAPTCHA_CODE_PREFIX)) { throw new ServiceException("验证码错误"); } //调用远程服务查询用户信息 AppUser appUser = remoteAppUserService.getUserByCondition1( AppUserDTO.builder().cellPhone(cellPhone).build(), SecurityConstants.INNER).getData(); if (Objects.nonNull(appUser)) { throw new ServiceException("该手机号已注册"); } String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6); // 注册用户信息 SysUser sysUser = new SysUser(); sysUser.setUserName(cellPhone); sysUser.setUserType("01"); sysUser.setNickName(nickname); sysUser.setPassword(SecurityUtils.encryptPassword(password)); R registerResult = remoteUserService.registerAppUserInfo(sysUser, SecurityConstants.INNER); if (R.FAIL == registerResult.getCode()) { throw new ServiceException(registerResult.getMsg()); } sysUser = registerResult.getData(); recordLogService.recordLogininfor(cellPhone, Constants.REGISTER, "注册成功"); //TODO 默认头像待完善 AppUserDTO appUserDTO = AppUserDTO.builder().userId(sysUser.getUserId()).cellPhone(cellPhone) .avatar("https://xqgwzh.obs.cn-south-1.myhuaweicloud.com/Logo%E7%A1%AE%E8%AE%A4%E7%89%88%281%29.jpg").nickname( nickname).userStatus(1).sanskritFlag(2).balance(BigDecimal.ZERO).inviteUserId(appRegisterBody.getInviteUserId()) .income(BigDecimal.ZERO).totalEnergyValue(0).registerTime( LocalDateTime.now()).levelSettingId(1).build(); if (appRegisterBody.getInviteUserId()!=null){ appUserDTO.setInviteUserTime(LocalDateTime.now()); } R result = remoteAppUserService.registerAppUser(appUserDTO, SecurityConstants.INNER); if (R.FAIL == result.getCode()) { throw new ServiceException(result.getMsg()); } // 构建AppLoginUser SysUser sysUserInfo = registerResult.getData(); AppUser appUserInfo = result.getData(); AppLoginUser appLoginUser = new AppLoginUser(); appLoginUser.setUserid(sysUserInfo.getUserId()); appLoginUser.setUsername(appUserInfo.getNickname()); appLoginUser.setCellPhone(cellPhone); appLoginUser.setAppUserId(appUserInfo.getId()); appLoginUser.setSysUser(sysUser); return appLoginUser; } /** * 校验验证码 * @param cellPhone 手机号 * @param captcha 验证码 * @return true/false */ private boolean verifyCaptcha(String cellPhone, String captcha, String keyPrefix) { if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(captcha)) { String key = keyPrefix + cellPhone; String key1 = CacheConstants.APP_PASSWORD_CAPTCHA_CODE_PREFIX + cellPhone; String code = redisService.getCacheObject(key); String code1 = redisService.getCacheObject(key1); // 万能验证码 if (captcha.equals("220125") || (StringUtils.isNotBlank(code) && code.equals( captcha))||(StringUtils.isNotBlank(code1) && code1.equals( captcha))) { redisService.deleteObject(key); return true; } } return false; } /** * 根据类型获取对象的验证码key * * @param type * @return */ private String getCaptchaCodeByTypePrefix(Integer type) { switch (type) { case 1: return CacheConstants.APP_REGISTER_CAPTCHA_CODE_PREFIX; case 2: return CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX; case 3: return CacheConstants.APP_PASSWORD_CAPTCHA_CODE_PREFIX; case 4: return CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX; case 5: return CacheConstants.APP_CHANGE_PHONE_CODE_PREFIX; case 6: return CacheConstants.ADD_CARD_PHONE_CODE_PREFIX; case 7: return CacheConstants.MANAGEMENT_PASSWORD_SECRET_PREFIX; default: return ""; } } @Autowired private HWSendSms hwSendSms; /** * 发送验证码 * * @param cellPhone 手机号码 * @param type */ public void sendCaptchaCode(String cellPhone, Integer type) { String key = getCaptchaCodeByTypePrefix(type); String code = RandomUtil.randomNumbers(6); try { // 将验证码放入redis redisService.setCacheObject(key + cellPhone, code, 5L, TimeUnit.MINUTES); log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone, code); // TODO 修改sender参数及templateId HuaWeiSMSUtil.sendSms("[\"" + code + "\"]", cellPhone, "8825010822864", "c1df549e89724e3db05b018524728d41"); // hwSendSms.sendSms(code, cellPhone); } catch (Exception e) { log.error("发送短信失败", e); throw new ServiceException("验证码发送失败"); } } /** * APP账号密码登录 * * @param body * @return */ public AppLoginUser appLogin(AppLoginBody body) { // IP黑名单校验 String blackStr = Convert.toStr( redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); } // 查询用户信息 AppUser appUser = remoteAppUserService.getUserByCondition( AppUserDTO.builder().cellPhone(body.getCellPhone()).build(), SecurityConstants.INNER).getData(); if (StringUtils.isNull(appUser)) { recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, "登录用户不存在"); throw new ServiceException("登录用户:" + body.getCellPhone() + " 不存在",500); } // 1:正常 2:冻结 3:注销 if (appUser.getUserStatus().equals(AppUserStatusEnum.FROZEN.getCode())) { recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, "账号已冻结"); throw new ServiceException("账号已冻结",500); } if (appUser.getUserStatus().equals(AppUserStatusEnum.LOGOUT.getCode())) { recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, "账号已注销"); throw new ServiceException("账号已注销",500); } // 查询系统用户信息 SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); if (StringUtils.isNull(sysUser)) { recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, "登录用户不存在"); throw new ServiceException("登录用户:" + body.getCellPhone() + " 不存在",500); } passwordService.validate(sysUser, body.getPassword()); // if (!sysUser.getPassword().equals(body.getPassword())){ // throw new ServiceException("密码错误"); // } AppLoginUser appLoginUser = new AppLoginUser(); appLoginUser.setAppUserId(appUser.getId()); appLoginUser.setCellPhone(appUser.getCellPhone()); appLoginUser.setUsername(sysUser.getNickName()); appLoginUser.setSysUser(sysUser); recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, "登录成功"); return appLoginUser; } /** * APP微信登录 * * @param body * @return */ public AppLoginUser wxLogin(AppWXLoginBody body) { // 通过wxOpenId查询APP用户信息 R userResult = remoteAppUserService.wxLogin(body, SecurityConstants.INNER); AppLoginUser data = userResult.getData(); SysUser sysUser = data.getSysUser(); if (R.FAIL == userResult.getCode()) { recordLogService.recordLogininfor(body.getNickname(), Constants.LOGIN_FAIL, userResult.getMsg()); throw new ServiceException(userResult.getMsg()); } if (StringUtils.isNull(sysUser)) { recordLogService.recordLogininfor(data.getCellPhone(), Constants.LOGIN_FAIL, "登录用户不存在"); throw new ServiceException("登录用户:" + data.getCellPhone() + " 不存在"); } // IP黑名单校验 String blackStr = Convert.toStr( redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); } recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, "登录成功"); return data; } /** * 苹果登录 * * @param appleId 苹果id * @return */ public AppLoginUser appleLogin(String appleId,String device) { R userResult = remoteAppUserService.appleLogin(appleId,device, SecurityConstants.INNER); if (R.FAIL == userResult.getCode()) { throw new ServiceException(userResult.getMsg()); } AppLoginUser data = userResult.getData(); SysUser sysUser = data.getSysUser(); if (StringUtils.isNull(sysUser)) { recordLogService.recordLogininfor(data.getCellPhone(), Constants.LOGIN_FAIL, "登录用户不存在"); throw new ServiceException("登录用户:" + data.getCellPhone() + " 不存在"); } // IP黑名单校验 String blackStr = Convert.toStr( redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); } recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, "登录成功"); return data; } /** * 验证手机号 * * @param body * @return */ public VerifyResultVO verifyPhone(AppCaptchaBody body) { VerifyResultVO verifyResultVO = new VerifyResultVO(); boolean b = verifyCaptcha(body.getCellPhone(), body.getCaptcha(), CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX); verifyResultVO.setSuccessFlag(b); if (b) { // 验证成功,删除验证码 redisService.deleteObject( CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone()); verifyResultVO.setSecret(IdUtil.randomUUID()); redisService.setCacheObject( CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone(), verifyResultVO.getSecret(), 10L, TimeUnit.MINUTES); } return verifyResultVO; } public void changePassword(AppChangePwdBody body) { Object baseSecret = redisService.getCacheObject( CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone()); if (Objects.isNull(baseSecret)) { throw new ServiceException("密码修改秘钥已失效,请重新校验手机号获取"); } if (!body.getSecret().equals(baseSecret.toString())) { throw new ServiceException("密码修改秘钥不正确"); } // 根据手机号查询用户 AppUser appUser = remoteAppUserService.getUserByCondition( AppUserDTO.builder().cellPhone(body.getCellPhone()).build(), SecurityConstants.INNER).getData(); if (Objects.isNull(appUser)) { throw new ServiceException("用户不存在或已注销"); } // 查询系统用户 SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); if (Objects.isNull(sysUser)) { throw new ServiceException("用户不存在或已注销"); } // 修改密码 sysUser.setPassword(SecurityUtils.encryptPassword(body.getPassword())); sysUserClient.updateUser(sysUser); redisService.deleteObject(CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone()); } /** * 验证码登录 * * @param body * @return */ public AppLoginUser appCaptchaLogin(AppCaptchaBody body) { // 校验验证码 if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(), CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) { throw new ServiceException("验证码不正确"); } R loginUserR = remoteAppUserService.appCaptchaLogin(body, SecurityConstants.INNER); if (R.FAIL == loginUserR.getCode()) { throw new ServiceException(loginUserR.getMsg()); } return loginUserR.getData(); } public AppLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) { if (!body.getCaptcha().equals("220125")){ Boolean res = redisService.hasKey( CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone()); if (!res) { throw new ServiceException("验证码已失效,请重新获取"); } // 校验验证码 if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(), CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX)) { throw new ServiceException("验证码不正确"); } } // 更新用户系统用户信息 R result = remoteAppUserService.verifyCellPhone(body, SecurityConstants.INNER); if (R.FAIL == result.getCode()) { throw new ServiceException(result.getMsg()); } return result.getData(); } }