package com.doumee.service.system.impl; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse; import com.doumee.config.shiro.ShiroToken; import com.doumee.core.constants.Constants; import com.doumee.core.dingTalk.DingTalk; import com.doumee.core.exception.BusinessException; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.utils.Utils; import com.doumee.dao.system.SystemUserMapper; import com.doumee.dao.system.dto.DingLoginDTO; import com.doumee.dao.system.dto.DingTalkLoginDTO; import com.doumee.dao.system.dto.LoginDTO; import com.doumee.dao.system.model.SystemLoginLog; import com.doumee.dao.system.model.SystemUser; import com.doumee.service.common.CaptchaService; import com.doumee.service.system.SystemLoginLogService; import com.doumee.service.system.SystemLoginService; import com.taobao.api.ApiException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; 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.HashMap; import java.util.Map; import java.util.Objects; @Slf4j @Service public class SystemLoginServiceImpl implements SystemLoginService { @Value("${project.version}") private String systemVersion; /** * # 环境,生产环境production,开发环境development */ @Value("${project.env}") private String projectEnv; @Autowired private CaptchaService captchaService; @Autowired private SystemLoginLogService systemLoginLogService; @Autowired private DingTalk dingTalk ; @Autowired private SystemUserMapper systemUserMapper; @Override public String loginByPassword(LoginDTO dto, HttpServletRequest request) { log.error("登录入参:"+ JSONObject.toJSONString(dto)); 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()); if(!StringUtils.equals(projectEnv,"development")){ // 校验验证码 try { 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(null,dto.getUsername(), dto.getPassword(),false); try { subject.login(token); loginLog.setUserId(((LoginUserInfo)subject.getPrincipal()).getId()); loginLog.setSuccess(Boolean.TRUE); systemLoginLogService.create(loginLog); if(StringUtils.isNotBlank(dto.getUnionId())){ //更新用户的unionID this.dealDDUnionIdBiz(loginLog.getUserId(), dto.getUnionId()); } 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); } } private void dealDDUnionIdBiz(Integer userId, String ddUnionId) { if(StringUtils.isNotBlank(ddUnionId)){ //如果openId不为空,绑定该用户openid systemUserMapper.update(null,new UpdateWrapper().lambda() .set(SystemUser::getUnionId,null) .eq(SystemUser::getUnionId,ddUnionId) ); systemUserMapper.update(null,new UpdateWrapper().lambda() .set(SystemUser::getUnionId,ddUnionId) .eq(SystemUser::getId,userId)); } } @Override public Map loginByDingTalk(DingLoginDTO dingLoginDTO, HttpServletRequest request) throws ApiException { log.error("授权钉钉登录入参:"+ JSONObject.toJSONString(dingLoginDTO)); Map map = new HashMap<>(); OapiV2UserGetuserinfoResponse.UserGetByCodeResponse response = dingTalk.getDDUserByCode(dingLoginDTO); if(Objects.nonNull(response)){ String unionId = response.getUnionid(); map.put("unionId",unionId); map.put("loginStatus",false); SystemUser systemUser = systemUserMapper.selectOne(new QueryWrapper().lambda().eq(SystemUser::getUnionId,unionId) .last("limit 1") ); if(Objects.nonNull(systemUser)&&!systemUser.getDeleted()){ loginByDingTalkCode(systemUser,unionId,request); map.put("loginStatus",true); } } log.error("授权钉钉登录出参:"+ JSONObject.toJSONString(map)); return map; } public String loginByDingTalkCode(SystemUser systemUser,String unionId, HttpServletRequest request) { SystemLoginLog loginLog = new SystemLoginLog(); loginLog.setLoginUsername(systemUser.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()); // 校验用户名和密码 Subject subject = SecurityUtils.getSubject(); ShiroToken token = new ShiroToken(unionId,systemUser.getUsername(), null,true); 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); } } }