package com.doumee.service.system.impl; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.api.R; import com.doumee.config.shiro.ShiroToken; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.utils.Constants; import com.doumee.core.utils.Utils; import com.doumee.core.wx.WxMiniConfig; import com.doumee.dao.business.SmsEmailMapper; import com.doumee.dao.system.SystemUserMapper; import com.doumee.dao.system.dto.LoginDTO; import com.doumee.dao.system.dto.LoginPhoneDTO; import com.doumee.dao.system.dto.WxMiniLoginDTO; import com.doumee.dao.system.model.SystemLoginLog; import com.doumee.dao.system.model.SystemUser; import com.doumee.service.business.impl.SmsEmailServiceImpl; import com.doumee.service.common.CaptchaService; import com.doumee.service.system.SystemLoginLogService; import com.doumee.service.system.SystemLoginService; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.Date; import java.util.Objects; @Slf4j @Service public class SystemLoginServiceImpl implements SystemLoginService { @Value("${project.version}") private String systemVersion; @Value("${debug_model}") private Boolean debugModel; @Autowired private SmsEmailMapper smsEmailMapper; @Autowired private CaptchaService captchaService; @Autowired private SystemLoginLogService systemLoginLogService; @Autowired private SystemUserMapper systemUserMapper; /** * 微信授权(登录后) * @param code */ @Override public String wxEmpower(String code,Integer userId){ try { //获取微信敏感数据 WxMaJscode2SessionResult session = WxMiniConfig.wxMaService.getUserService().getSessionInfo(code); String openId = session.getOpenid(); if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(openId)) { throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"获取openid失败!请联系管理员"); } if(Objects.nonNull(userId)){ systemUserMapper.update(null,new UpdateWrapper() .lambda().set(SystemUser::getOpenid,null) .eq(SystemUser::getOpenid,openId) .ne(SystemUser::getId,userId)); systemUserMapper.update(null,new UpdateWrapper() .lambda() .set(SystemUser::getOpenid,openId) .eq(SystemUser::getId,userId)); } return openId; } catch (WxErrorException e) { throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"微信登录异常!请联系管理员"); } } @Override public String loginByWxMini (WxMiniLoginDTO wxMiniLoginDTO, HttpServletRequest request){ if(StringUtils.isNotBlank(wxMiniLoginDTO.getCode())){ try{ WxMaJscode2SessionResult session = WxMiniConfig.wxMaService.getUserService().getSessionInfo(wxMiniLoginDTO.getCode()); String openId = session.getOpenid(); if (StringUtils.isNotBlank(openId)&&StringUtils.isBlank(wxMiniLoginDTO.getUsername())) { SystemUser systemUser = systemUserMapper.selectOne(new QueryWrapper() .lambda().eq(SystemUser::getOpenid,openId) .eq(SystemUser::getDeleted,Constants.ZERO) .eq(SystemUser::getType,Constants.UserType.COMPANY.getKey()) .orderByDesc(SystemUser::getCreateTime) .last(" limit 1") ); if(Objects.nonNull(systemUser)){ LoginPhoneDTO dto = new LoginPhoneDTO(); dto.setPhone(systemUser.getMobile()); return this.loginByPhone(dto,Constants.ZERO,false,request); } } } catch (WxErrorException e) { throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"微信登录异常!请联系管理员"); } } if(StringUtils.isBlank(wxMiniLoginDTO.getUsername()) || StringUtils.isBlank(wxMiniLoginDTO.getPassword())){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } LoginDTO dto = new LoginDTO(); dto.setUsername(wxMiniLoginDTO.getUsername()); dto.setPassword(wxMiniLoginDTO.getPassword()); return this.loginByPassword(dto,Constants.ONE,false,request); } @Override public String loginByPassword(LoginDTO dto, int type,Boolean checkCaptcha,HttpServletRequest request) { SystemLoginLog loginLog = new SystemLoginLog(); loginLog.setLoginUsername(dto.getUsername()); loginLog.setLoginTime(new Date()); loginLog.setSystemVersion(systemVersion); loginLog.setIp(Utils.User_Client.getIP(request)); loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp())); loginLog.setPlatform(Utils.User_Client.getPlatform(request)); loginLog.setClientInfo(Utils.User_Client.getBrowser(request)); loginLog.setOsInfo(Utils.User_Client.getOS(request)); loginLog.setServerIp(Utils.Server.getIP()); // 校验验证码 try { if(!debugModel&&checkCaptcha){ captchaService.check(dto.getUuid(), dto.getCode()); } } catch (Exception e) { log.error(e.getMessage(), e); loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage()); loginLog.setSuccess(Boolean.FALSE); systemLoginLogService.create(loginLog); throw e; } // 校验用户名和密码 Subject subject = SecurityUtils.getSubject(); ShiroToken token = new ShiroToken(dto.getUsername(), dto.getPassword(),true,type); try { subject.login(token); loginLog.setUserId(((LoginUserInfo)subject.getPrincipal()).getId()); loginLog.setSuccess(Boolean.TRUE); systemLoginLogService.create(loginLog); return (String)subject.getSession().getId(); } catch (AuthenticationException e) { log.error(ResponseStatus.ACCOUNT_INCORRECT.getMessage(), e); loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage()); loginLog.setSuccess(Boolean.FALSE); systemLoginLogService.create(loginLog); throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT.getCode(), Objects.isNull(e.getCause())?ResponseStatus.ACCOUNT_INCORRECT.getMessage():e.getCause().getMessage()); } } @Override public String loginByPhone (LoginPhoneDTO dto, int type,Boolean checkSmsCode, HttpServletRequest request) { SystemLoginLog loginLog = new SystemLoginLog(); loginLog.setLoginUsername(dto.getPhone()); loginLog.setLoginTime(new Date()); loginLog.setSystemVersion(systemVersion); loginLog.setIp(Utils.User_Client.getIP(request)); loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp())); loginLog.setPlatform(Utils.User_Client.getPlatform(request)); loginLog.setClientInfo(Utils.User_Client.getBrowser(request)); loginLog.setOsInfo(Utils.User_Client.getOS(request)); loginLog.setServerIp(Utils.Server.getIP()); // 校验验证码 if(type!= Constants.TWO){ try { if(!debugModel&& checkSmsCode){ SmsEmailServiceImpl.isCaptcheValide(smsEmailMapper,dto.getPhone(), dto.getCode()); } } catch (Exception e) { log.error(e.getMessage(), e); loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage()); loginLog.setSuccess(Boolean.FALSE); systemLoginLogService.create(loginLog); throw e; } } // 校验用户名和密码 Subject subject = SecurityUtils.getSubject(); ShiroToken token = new ShiroToken(dto.getPhone(), null,false,type); try { subject.login(token); loginLog.setUserId(((LoginUserInfo)subject.getPrincipal()).getId()); loginLog.setSuccess(Boolean.TRUE); systemLoginLogService.create(loginLog); return (String)subject.getSession().getId(); } catch (AuthenticationException e) { log.error(ResponseStatus.ACCOUNT_INCORRECT.getMessage(), e); loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage()); loginLog.setSuccess(Boolean.FALSE); systemLoginLogService.create(loginLog); throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT.getCode(), Objects.isNull(e.getCause())?ResponseStatus.ACCOUNT_INCORRECT.getMessage():e.getCause().getMessage()); } } }