package com.epmet.service.impl; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.epmet.auth.constants.AuthOperationConstants; import com.epmet.common.token.constant.LoginConstant; import com.epmet.commons.rocketmq.messages.LoginMQMsg; import com.epmet.commons.tools.constant.AppClientConstant; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.EpmetException; import com.epmet.commons.tools.exception.ExceptionUtils; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.feign.ResultDataResolver; import com.epmet.commons.tools.redis.RedisKeys; import com.epmet.commons.tools.redis.RedisUtils; import com.epmet.commons.tools.security.dto.GovTokenDto; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.security.password.PasswordUtils; import com.epmet.commons.tools.security.user.LoginUserUtil; import com.epmet.commons.tools.utils.*; import com.epmet.commons.tools.validator.PhoneValidatorUtils; import com.epmet.constant.AuthHttpUrlConstant; import com.epmet.constant.SmsTemplateConstant; import com.epmet.dto.*; import com.epmet.dto.form.*; import com.epmet.dto.result.*; import com.epmet.feign.EpmetMessageOpenFeignClient; import com.epmet.feign.EpmetUserOpenFeignClient; import com.epmet.feign.GovOrgOpenFeignClient; import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; import com.epmet.redis.CaptchaRedis; import com.epmet.service.ThirdLoginService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.stream.Collectors; /** * @author sun * @Description 第三方-居民端、政府端登陆服务 */ @Slf4j @Service public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResolver { private static final Logger logger = LoggerFactory.getLogger(ThirdLoginServiceImpl.class); @Autowired private JwtTokenUtils jwtTokenUtils; @Autowired private CaptchaRedis captchaRedis; @Autowired private JwtTokenProperties jwtTokenProperties; @Autowired private CpUserDetailRedis cpUserDetailRedis; @Autowired private EpmetUserOpenFeignClient epmetUserOpenFeignClient; @Autowired private GovOrgOpenFeignClient govOrgOpenFeignClient; @Autowired private EpmetMessageOpenFeignClient epmetMessageOpenFeignClient; @Autowired private EpmetMessageOpenFeignClient messageOpenFeignClient; @Autowired private LoginUserUtil loginUserUtil; @Autowired private RedisUtils redisUtils; /** * @param formDTO * @return * @Author sun * @Description 单客户-居民端微信小程序登录 **/ @Override public UserTokenResultDTO resiLogin(LoginFormDTO formDTO) { //1.调用epmet_third服务,校验appId是否有效以及是否授权,校验通过的调用微信API获取用户基本信息 WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); UserWechatDTO userWechatDTO = this.getUserWeChat(resiLoginFormDTO); //2.调用epmet-user服务,新增用户信息(先判断用户是否存在,不存在则新增存在则更新) WxUserFormDTO wxUserFormDTO = new WxUserFormDTO(); wxUserFormDTO.setWechatDTO(userWechatDTO); wxUserFormDTO.setApp(formDTO.getApp()); Result userResult = epmetUserOpenFeignClient.saveWxUser(wxUserFormDTO); if (!userResult.success()) { throw new RenException(userResult.getCode()); } UserDTO userDTO = userResult.getData(); //3.生成业务token String userId = userDTO.getId(); String token = this.generateToken(formDTO, userId); //4.存放Redis this.saveTokenDto(formDTO, userId, userWechatDTO, token, userWechatDTO.getCustomerId()); //5.接口返参 UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); return userTokenResultDTO; } /** * @Description 居民端登陆生成业务token的key **/ private String generateToken(LoginCommonFormDTO formDTO, String userId) { Map map = new HashMap<>(); map.put("app", formDTO.getApp()); map.put("client", formDTO.getClient()); map.put("userId", userId); String token = jwtTokenUtils.createToken(map); logger.info("app:" + formDTO.getApp() + ";client:" + formDTO.getClient() + ";userId:" + userId + ";生成token[" + token + "]"); return token; } /** * @Description 将token存入redis **/ private String saveTokenDto(LoginCommonFormDTO formDTO, String userId, UserWechatDTO userWechatDTO, String token, String customerId) { int expire = jwtTokenProperties.getExpire(); TokenDto tokenDto = new TokenDto(); tokenDto.setCustomerId(customerId); tokenDto.setApp(formDTO.getApp()); tokenDto.setClient(formDTO.getClient()); tokenDto.setUserId(userId); tokenDto.setOpenId(userWechatDTO.getWxOpenId()); tokenDto.setSessionKey(userWechatDTO.getSessionKey()); tokenDto.setUnionId(userWechatDTO.getUnionId()); tokenDto.setToken(token); tokenDto.setUpdateTime(System.currentTimeMillis()); tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); cpUserDetailRedis.set(tokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); return token; } /** * @param formDTO * @return * @Author sun * @Description 单客户-政府端微信小程序登录 **/ @Override public UserTokenResultDTO workLogin(LoginFormDTO formDTO) { //1.调用epmet_third服务,校验appId是否有效以及是否授权,校验通过的调用微信API获取用户基本信息 WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); UserWechatDTO userWechatDTO = this.getUserWeChat(resiLoginFormDTO); //2.根据openid查询用户是否存在历史登陆信息 Result latestStaffWechat = epmetUserOpenFeignClient.getLatestStaffWechatLoginRecord(userWechatDTO.getWxOpenId()); if (!latestStaffWechat.success() || null == latestStaffWechat.getData()) { logger.warn(String.format("没有获取到用户最近一次登录账户信息,code[%s],msg[%s]", EpmetErrorCode.PLEASE_LOGIN.getCode(), EpmetErrorCode.PLEASE_LOGIN.getMsg())); throw new RenException(EpmetErrorCode.PLEASE_LOGIN.getCode()); } StaffLatestAgencyResultDTO staffLatestAgencyResultDTO = latestStaffWechat.getData(); //3.记录staff_wechat this.savestaffwechat(staffLatestAgencyResultDTO.getStaffId(), userWechatDTO.getWxOpenId(), staffLatestAgencyResultDTO.getCustomerId()); //4.记录登录日志 this.saveStaffLoginRecord(staffLatestAgencyResultDTO); //5.获取用户token String token = this.generateGovWxmpToken(staffLatestAgencyResultDTO.getStaffId()); //6.保存到redis this.saveLatestGovTokenDto(staffLatestAgencyResultDTO, userWechatDTO, token); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); //7.发送登录事件 try { sendLoginEvent(staffLatestAgencyResultDTO.getStaffId(), formDTO.getAppId(), AppClientConstant.APP_GOV, AppClientConstant.CLIENT_WXMP); } catch (RenException e) { log.error(e.getInternalMsg()); } catch (Exception e) { log.error("【工作端workLogin登录】发送登录事件失败,程序继续执行。"); } return userTokenResultDTO; } /** * @param userId openid * @return * @Author sun * @Description 保存微信和当前登录用户关系 **/ private Result savestaffwechat(String userId, String openid, String customerId) { StaffWechatFormDTO staffWechatFormDTO = new StaffWechatFormDTO(); staffWechatFormDTO.setUserId(userId); staffWechatFormDTO.setWxOpenId(openid); staffWechatFormDTO.setCustomerId(customerId); return epmetUserOpenFeignClient.saveStaffWechat(staffWechatFormDTO); } /** * @param latestStaffWechatLoginDTO * @return * @Author sun * @Description 保存登录日志 **/ private Result saveStaffLoginRecord(StaffLatestAgencyResultDTO latestStaffWechatLoginDTO) { StaffLoginAgencyRecordFormDTO staffLoginAgencyRecordFormDTO = new StaffLoginAgencyRecordFormDTO(); staffLoginAgencyRecordFormDTO.setCustomerId(latestStaffWechatLoginDTO.getCustomerId()); staffLoginAgencyRecordFormDTO.setStaffId(latestStaffWechatLoginDTO.getStaffId()); staffLoginAgencyRecordFormDTO.setWxOpenId(latestStaffWechatLoginDTO.getWxOpenId()); staffLoginAgencyRecordFormDTO.setMobile(latestStaffWechatLoginDTO.getMobile()); staffLoginAgencyRecordFormDTO.setAgencyId(latestStaffWechatLoginDTO.getAgencyId()); Result staffLoginRecordResult = epmetUserOpenFeignClient.saveStaffLoginRecord(staffLoginAgencyRecordFormDTO); return staffLoginRecordResult; } /** * @Description 生成政府端小程序业务token Key * @Author sun **/ private String generateGovWxmpToken(String staffId) { Map map = new HashMap<>(); map.put("app", LoginConstant.APP_GOV); map.put("client", LoginConstant.CLIENT_WXMP); map.put("userId", staffId); String token = jwtTokenUtils.createToken(map); logger.info("app:" + LoginConstant.APP_GOV + ";client:" + LoginConstant.CLIENT_WXMP + ";userId:" + staffId + ";生成token[" + token + "]"); return token; } /** * @Description 保存tokenDto到redis * @Author sun **/ private void saveLatestGovTokenDto(StaffLatestAgencyResultDTO staffLatestAgency, UserWechatDTO userWechatDTO, String token) { int expire = jwtTokenProperties.getExpire(); GovTokenDto govTokenDto = new GovTokenDto(); govTokenDto.setApp(LoginConstant.APP_GOV); govTokenDto.setClient(LoginConstant.CLIENT_WXMP); govTokenDto.setUserId(staffLatestAgency.getStaffId()); govTokenDto.setOpenId(userWechatDTO.getWxOpenId()); govTokenDto.setSessionKey(userWechatDTO.getSessionKey()); govTokenDto.setUnionId(userWechatDTO.getUnionId()); govTokenDto.setToken(token); govTokenDto.setUpdateTime(System.currentTimeMillis()); govTokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); govTokenDto.setRootAgencyId(staffLatestAgency.getAgencyId()); govTokenDto.setCustomerId(staffLatestAgency.getCustomerId()); //设置部门,网格,角色列表 govTokenDto.setDeptIdList(getDeptartmentIdList(staffLatestAgency.getStaffId())); govTokenDto.setGridIdList(getGridIdList(staffLatestAgency.getStaffId())); CustomerAgencyDTO agency = getAgencyByStaffId(staffLatestAgency.getStaffId()); if (agency != null) { govTokenDto.setAgencyId(agency.getId()); govTokenDto.setRoleList(queryGovStaffRoles(staffLatestAgency.getStaffId(), agency.getId())); } govTokenDto.setOrgIdPath(getOrgIdPath(staffLatestAgency.getStaffId())); cpUserDetailRedis.set(govTokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); } public Set getDeptartmentIdList(String staffId) { try { Result> deptListResult = govOrgOpenFeignClient.getDepartmentListByStaffId(staffId); if (deptListResult.success()) { if (!CollectionUtils.isEmpty(deptListResult.getData())) { Set deptIdLists = deptListResult.getData().stream().map(dept -> dept.getDepartmentId()).collect(Collectors.toSet()); return deptIdLists; } } else { logger.error("登录:查询部门列表,远程调用返回错误:{}", deptListResult.getMsg()); } } catch (Exception e) { String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); logger.error("登录:查询部门列表异常:{}", errorStackTrace); } return new HashSet<>(); } /** * 根据工作人员ID查询网格ID列表 * * @param staffId * @return */ public Set getGridIdList(String staffId) { Result> result = govOrgOpenFeignClient.listGridsbystaffid(staffId); if (!result.success()) { logger.error("登录:查询网格列表,远程调用返回错误:{}", result.getMsg()); return null; } else { List grids = result.getData(); return grids.stream().map(grid -> grid.getGridId()).collect(Collectors.toSet()); } } /** * 根据staffId查询所属的组织机构 * * @param staffId */ public CustomerAgencyDTO getAgencyByStaffId(String staffId) { Result result = govOrgOpenFeignClient.getAgencyByStaff(staffId); if (!result.success()) { logger.error("登录:查询登录人所属的机关OrgIdPath失败:{}", result.getMsg()); return null; } return result.getData(); } /** * 查询人员在某机关单位下的角色列表 * * @param staffId orgId */ public List queryGovStaffRoles(String staffId, String orgId) { StaffRoleFormDTO formDTO = new StaffRoleFormDTO(); formDTO.setStaffId(staffId); formDTO.setOrgId(orgId); Result> gridResult = epmetUserOpenFeignClient.getRolesOfStaff(formDTO); if (!CollectionUtils.isEmpty(gridResult.getData())) { //return gridResult.getData().stream().map(role -> role.getId()).collect(Collectors.toSet()); return ConvertUtils.sourceToTarget(gridResult.getData(), GovTokenDto.Role.class); } return null; } /** * 查询工作人员的OrgIdPath * * @param staffId * @return */ public String getOrgIdPath(String staffId) { Result result = govOrgOpenFeignClient.getAgencyByStaff(staffId); if (!result.success()) { logger.error("登录:查询登录人所属的机关OrgIdPath失败:{}", result.getMsg()); return null; } CustomerAgencyDTO agency = result.getData(); if (agency != null) { if ("0".equals(agency.getPid())) { // 顶级 return agency.getId(); } else { return agency.getPids().concat(":").concat(agency.getId()); } } return null; } /** * @param formDTO * @return * @Author sun * @Description 单客户-选择组织,进入首页 **/ @Override public UserTokenResultDTO enterOrg(ThirdWxmpEnteOrgFormDTO formDTO) { //1、需要校验要登录的客户,是否被禁用 CustomerStaffFormDTO customerStaffFormDTO = new CustomerStaffFormDTO(); customerStaffFormDTO.setCustomerId(formDTO.getCustomerId()); customerStaffFormDTO.setMobile(formDTO.getMobile()); Result customerStaffDTOResult = epmetUserOpenFeignClient.getCustomerStaffInfo(customerStaffFormDTO); if (!customerStaffDTOResult.success() || null == customerStaffDTOResult.getData()) { logger.error(String.format("获取工作人员信息失败,手机号[%s],客户id:[%s],code[%s],msg[%s]", formDTO.getMobile(), formDTO.getCustomerId(), customerStaffDTOResult.getCode(), customerStaffDTOResult.getMsg())); throw new RenException(customerStaffDTOResult.getCode()); } CustomerStaffDTO customerStaff = customerStaffDTOResult.getData(); //2020.7.24 获取微信信息接口调整,改调用微信api的方式 sun start //2.调用epmet_third服务,校验appId是否有效以及是否授权,校验通过的调用微信API获取用户基本信息 WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); UserWechatDTO userWechatDTO = this.getUserWeChat(resiLoginFormDTO); WxMaJscode2SessionResult wxMaJscode2SessionResult = new WxMaJscode2SessionResult(); wxMaJscode2SessionResult.setOpenid(userWechatDTO.getWxOpenId()); wxMaJscode2SessionResult.setSessionKey(userWechatDTO.getSessionKey()); wxMaJscode2SessionResult.setUnionid(""); // end //3、记录staff_wechat,并记录用户激活状态,激活时间 this.savestaffwechat(customerStaff.getUserId(), userWechatDTO.getWxOpenId(), formDTO.getCustomerId()); //4、记录登录日志 StaffLatestAgencyResultDTO staffLatestAgencyResultDTO = new StaffLatestAgencyResultDTO(); staffLatestAgencyResultDTO.setCustomerId(formDTO.getCustomerId()); staffLatestAgencyResultDTO.setStaffId(customerStaff.getUserId()); staffLatestAgencyResultDTO.setWxOpenId(userWechatDTO.getWxOpenId()); staffLatestAgencyResultDTO.setMobile(formDTO.getMobile()); staffLatestAgencyResultDTO.setAgencyId(formDTO.getRootAgencyId()); this.saveStaffLoginRecord(staffLatestAgencyResultDTO); //5.1、获取用户token String token = this.generateGovWxmpToken(customerStaff.getUserId()); //5.2、保存到redis StaffLatestAgencyResultDTO staffLatestAgency = new StaffLatestAgencyResultDTO(); staffLatestAgency.setAgencyId(formDTO.getRootAgencyId()); staffLatestAgency.setCustomerId(formDTO.getCustomerId()); staffLatestAgency.setStaffId(customerStaff.getUserId()); this.saveLatestGovTokenDto(staffLatestAgency, userWechatDTO, token); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); //6.发送登录事件 try { sendLoginEvent(customerStaff.getUserId(), formDTO.getAppId(), AppClientConstant.APP_GOV, AppClientConstant.CLIENT_WXMP); } catch (RenException e) { log.error(e.getInternalMsg()); } catch (Exception e) { log.error("【工作端enterOrg登录】发送登录事件失败,程序继续执行。错误信息"); } return userTokenResultDTO; } /** * @param formDTO * @return * @Author sun * @Description 单客户-选择组织,进入首页 **/ @Override public UserTokenResultDTO enterOrgByAccount(ThirdWxmpEnteOrgByAccountFormDTO formDTO) { //1、需要校验要登录的客户,是否被禁用 CustomerStaffByAccountFormDTO customerStaffFormDTO = new CustomerStaffByAccountFormDTO(); customerStaffFormDTO.setCustomerId(formDTO.getCustomerId()); customerStaffFormDTO.setUserAccount(formDTO.getUserAccount()); Result customerStaffDTOResult = epmetUserOpenFeignClient.getCustomerStaffInfoByAccount(customerStaffFormDTO); if (!customerStaffDTOResult.success() || null == customerStaffDTOResult.getData()) { logger.error(String.format("获取工作人员信息失败,账户[%s],客户id:[%s],code[%s],msg[%s]", formDTO.getUserAccount(), formDTO.getCustomerId(), customerStaffDTOResult.getCode(), customerStaffDTOResult.getMsg())); throw new RenException(customerStaffDTOResult.getCode()); } CustomerStaffDTO customerStaff = customerStaffDTOResult.getData(); //2020.7.24 获取微信信息接口调整,改调用微信api的方式 sun start //2.调用epmet_third服务,校验appId是否有效以及是否授权,校验通过的调用微信API获取用户基本信息 WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); UserWechatDTO userWechatDTO = this.getUserWeChat(resiLoginFormDTO); WxMaJscode2SessionResult wxMaJscode2SessionResult = new WxMaJscode2SessionResult(); wxMaJscode2SessionResult.setOpenid(userWechatDTO.getWxOpenId()); wxMaJscode2SessionResult.setSessionKey(userWechatDTO.getSessionKey()); wxMaJscode2SessionResult.setUnionid(""); // end //3、记录staff_wechat,并记录用户激活状态,激活时间 this.savestaffwechat(customerStaff.getUserId(), userWechatDTO.getWxOpenId(), formDTO.getCustomerId()); //4、记录登录日志 StaffLatestAgencyResultDTO staffLatestAgencyResultDTO = new StaffLatestAgencyResultDTO(); staffLatestAgencyResultDTO.setCustomerId(formDTO.getCustomerId()); staffLatestAgencyResultDTO.setStaffId(customerStaff.getUserId()); staffLatestAgencyResultDTO.setWxOpenId(userWechatDTO.getWxOpenId()); staffLatestAgencyResultDTO.setMobile(customerStaff.getMobile()); staffLatestAgencyResultDTO.setAgencyId(formDTO.getRootAgencyId()); this.saveStaffLoginRecord(staffLatestAgencyResultDTO); //5.1、获取用户token String token = this.generateGovWxmpToken(customerStaff.getUserId()); //5.2、保存到redis StaffLatestAgencyResultDTO staffLatestAgency = new StaffLatestAgencyResultDTO(); staffLatestAgency.setAgencyId(formDTO.getRootAgencyId()); staffLatestAgency.setCustomerId(formDTO.getCustomerId()); staffLatestAgency.setStaffId(customerStaff.getUserId()); this.saveLatestGovTokenDto(staffLatestAgency, userWechatDTO, token); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); //6.发送登录事件 try { sendLoginEvent(customerStaff.getUserId(), formDTO.getAppId(), AppClientConstant.APP_GOV, AppClientConstant.CLIENT_WXMP); } catch (RenException e) { log.error(e.getInternalMsg()); } catch (Exception e) { log.error("【工作端enterOrg登录】发送登录事件失败,程序继续执行。错误信息"); } return userTokenResultDTO; } /** * @param formDTO * @return * @Author sun * @Description 单客户-手机验证码获取组织 **/ @Override public List getMyOrg(ThirdStaffOrgsFormDTO formDTO) { //0、验证码是否正确 String rightSmsCode = captchaRedis.getSmsCode(formDTO.getMobile()); if (!formDTO.getSmsCode().equals(rightSmsCode)) { logger.warn(String.format("验证码错误code[%s],msg[%s]",EpmetErrorCode.MOBILE_CODE_ERROR.getCode(),EpmetErrorCode.MOBILE_CODE_ERROR.getMsg())); throw new RenException(EpmetErrorCode.MOBILE_CODE_ERROR.getCode()); } //1.根据appId查询对应客户Id PaCustomerDTO customer = this.getCustomerInfo(formDTO.getAppId()); //7.28 根据appId只能存在一个客户Id,后边的批量操作逻辑 //2.根据手机号查询到用户信息 ThirdCustomerStaffFormDTO dto = new ThirdCustomerStaffFormDTO(); dto.setCustomerId(customer.getId()); dto.setMobile(formDTO.getMobile()); Result> customerStaffResult = epmetUserOpenFeignClient.getCustsomerStaffByIdAndPhone(dto); if (!customerStaffResult.success()) { logger.error(String.format("手机验证码登录异常,手机号[%s],code[%s],msg[%s]", formDTO.getMobile(), customerStaffResult.getCode(), customerStaffResult.getMsg())); throw new RenException(customerStaffResult.getCode()); } //3、查询用户所有的组织信息 List customerIdList = new ArrayList<>(); for (CustomerStaffDTO customerStaffDTO : customerStaffResult.getData()) { customerIdList.add(customerStaffDTO.getCustomerId()); } StaffOrgFormDTO staffOrgFormDTO = new StaffOrgFormDTO(); staffOrgFormDTO.setCustomerIdList(customerIdList); Result> result = govOrgOpenFeignClient.getStaffOrgList(staffOrgFormDTO); if(result.success()&&null!=result.getData()){ return result.getData(); } logger.error(String .format("手机验证码获取组织,调用%s服务失败,入参手机号%s,验证码%s,返回错误码%s,错误提示信息%s", ServiceConstant.GOV_ORG_SERVER,formDTO.getMobile(),formDTO.getSmsCode(),result.getCode(),result.getMsg())); return new ArrayList<>(); } /** * @param formDTO * @return * @author sun * @description 单客户-手机号密码获取组织 **/ @Override public List getMyOrgByPassword(ThirdStaffOrgsFormDTO formDTO) { //0.根据appId查询对应客户Id // Result resultDTO = epmetThirdFeignClient.getCustomerMsg(formDTO.getAppId()); PaCustomerDTO customer = this.getCustomerInfo(formDTO.getAppId()); //7.28 上边根据appId只能锁定一条客户id,后边的批量循环操作暂不做调整,还是使用之前的代码 sun //1、根据手机号查询到用户信息 ThirdCustomerStaffFormDTO dto = new ThirdCustomerStaffFormDTO(); dto.setCustomerId(customer.getId()); dto.setMobile(formDTO.getMobile()); Result> customerStaffResult = epmetUserOpenFeignClient.getCustsomerStaffByIdAndPhone(dto); if (!customerStaffResult.success()) { logger.warn(String.format("手机密码登录异常,手机号[%s],code[%s],msg[%s]", formDTO.getMobile(), customerStaffResult.getCode(), customerStaffResult.getMsg())); throw new RenException(customerStaffResult.getCode()); } //2、密码是否正确 List customerStaffList=customerStaffResult.getData(); //3、查询用户所有的组织信息 List customerIdList = new ArrayList<>(); //是否设置过密码 boolean havePasswordFlag=false; //密码是否正确 boolean passwordRightFlag=false; for (CustomerStaffDTO customerStaffDTO : customerStaffList) { if(StringUtils.isNotBlank(customerStaffDTO.getPassword())){ havePasswordFlag=true; }else{ logger.warn(String.format("当前用户:手机号%s,客户Id%s下未设置密码.",formDTO.getMobile(),customerStaffDTO.getCustomerId())); continue; } if (!PasswordUtils.matches(formDTO.getPassword(), customerStaffDTO.getPassword())) { logger.warn(String.format("当前用户:手机号%s,客户Id%s密码匹配错误.",formDTO.getMobile(),customerStaffDTO.getCustomerId())); }else{ logger.warn(String.format("当前用户:手机号%s,客户Id%s密码匹配正确.",formDTO.getMobile(),customerStaffDTO.getCustomerId())); passwordRightFlag=true; customerIdList.add(customerStaffDTO.getCustomerId()); } } //根据手机号查出来所有用户,密码都为空,表明用户未激活账户,未设置密码 if(!havePasswordFlag){ logger.warn(String.format("当前手机号(%s)下所有账户都未设置密码,请先使用验证码登录激活账户",formDTO.getMobile())); throw new RenException(EpmetErrorCode.PASSWORD_ERROR.getCode()); } //密码错误 if(!passwordRightFlag){ logger.warn(String.format("根据当前手机号(%s)密码未找到所属组织,密码错误",formDTO.getMobile())); throw new RenException(EpmetErrorCode.PASSWORD_ERROR.getCode()); } StaffOrgFormDTO staffOrgFormDTO = new StaffOrgFormDTO(); staffOrgFormDTO.setCustomerIdList(customerIdList); Result> result = govOrgOpenFeignClient.getStaffOrgList(staffOrgFormDTO); if(result.success()&&null!=result.getData()){ return result.getData(); } logger.warn(String .format("手机验证码获取组织,调用%s服务失败,入参手机号%s,密码%s,返回错误码%s,错误提示信息%s", ServiceConstant.GOV_ORG_SERVER, formDTO.getMobile(), formDTO.getPassword(), result.getCode(), result.getMsg())); return new ArrayList<>(); } @Override public List getMyOrgByAccount(ThirdStaffOrgByAccountFormDTO formDTO) { //{"isNovice":false,"mobile":"","userAccount":"18700011111","password":"Py011111","appId":"wx2b75d556ba867750"} String appId = formDTO.getAppId(); String userAccount = formDTO.getUserAccount(); String password = formDTO.getPassword(); logger.info("getMyOrgByAccount start at:{}",System.currentTimeMillis()); //0.根据appId查询对应客户Id PaCustomerDTO customer = this.getCustomerInfo(formDTO.getAppId()); logger.info("getMyOrgByAccount getCustomerInfo cost:{}",System.currentTimeMillis()); //7.28 上边根据appId只能锁定一条客户id,后边的批量循环操作暂不做调整,还是使用之前的代码 sun //1、根据手机号查询到用户信息 ThirdCustomerStaffByAccountFormDTO dto = new ThirdCustomerStaffByAccountFormDTO(); dto.setCustomerId(customer.getId()); dto.setUserAccount(formDTO.getUserAccount()); Result> customerStaffResult = epmetUserOpenFeignClient.getCustsomerStaffByIdAndAccount(dto); if (!customerStaffResult.success()) { logger.warn(String.format("账户密码登录异常,账户[%s],code[%s],msg[%s]", formDTO.getUserAccount(), customerStaffResult.getCode(), customerStaffResult.getMsg())); throw new RenException(customerStaffResult.getCode()); } logger.info("getMyOrgByAccount getCustsomerStaffByIdAndAccount cost:{}",System.currentTimeMillis()); //2、密码是否正确 List customerStaffList=customerStaffResult.getData(); if (CollectionUtils.isEmpty(customerStaffList)){ throw new EpmetException(EpmetErrorCode.GOV_STAFF_ACCOUNT_NOT_EXISTS.getCode()); } //3、查询用户所有的组织信息 List customerIdList = new ArrayList<>(); //是否设置过密码 boolean havePasswordFlag=false; //密码是否正确 boolean passwordRightFlag=false; for (CustomerStaffDTO customerStaffDTO : customerStaffList) { if(StringUtils.isNotBlank(customerStaffDTO.getPassword())){ havePasswordFlag=true; }else{ logger.warn(String.format("当前用户:账户%s,客户Id%s下未设置密码.",formDTO.getUserAccount(),customerStaffDTO.getCustomerId())); continue; } if (!PasswordUtils.matches(formDTO.getPassword(), customerStaffDTO.getPassword())) { logger.warn(String.format("当前用户:账户%s,客户Id%s密码匹配错误.",formDTO.getUserAccount(),customerStaffDTO.getCustomerId())); }else{ logger.warn(String.format("当前用户:账户%s,客户Id%s密码匹配正确.",formDTO.getUserAccount(),customerStaffDTO.getCustomerId())); passwordRightFlag=true; customerIdList.add(customerStaffDTO.getCustomerId()); } } //根据手机号查出来所有用户,密码都为空,表明用户未激活账户,未设置密码 if(!havePasswordFlag){ logger.warn(String.format("当前账户(%s)下所有账户都未设置密码,请先使用验证码登录激活账户",formDTO.getUserAccount())); throw new RenException(EpmetErrorCode.PASSWORD_ERROR.getCode()); } //密码错误 if(!passwordRightFlag){ logger.warn(String.format("根据当前账户(%s)密码未找到所属组织,密码错误",formDTO.getUserAccount())); throw new RenException(EpmetErrorCode.PASSWORD_ERROR.getCode()); } logger.info("getMyOrgByAccount checkpassword cost:{}",System.currentTimeMillis()); CustomerStaffDTO customerStaffDTO = customerStaffList.get(0); String tempKey = RedisKeys.getCustomerStaffTempKey(customerStaffDTO.getUserId()); List redisTemp = (List)redisUtils.get(tempKey); if (redisTemp != null){ return redisTemp; } logger.info("getMyOrgByAccount getCustomerStaffTempKey cost:{}",System.currentTimeMillis()); StaffOrgFormDTO staffOrgFormDTO = new StaffOrgFormDTO(); staffOrgFormDTO.setCustomerIdList(customerIdList); Result> result = govOrgOpenFeignClient.getStaffOrgList(staffOrgFormDTO); if(result.success()&&null!=result.getData()){ List data = result.getData(); logger.info("getMyOrgByAccount getStaffOrgList from db cost:{}",System.currentTimeMillis()); redisUtils.set(tempKey,data); logger.info("getMyOrgByAccount getCustomerStaffTempKey set redis cost:{}",System.currentTimeMillis()); return data; } logger.warn(String .format("手机验证码获取组织,调用%s服务失败,入参账户%s,密码%s,返回错误码%s,错误提示信息%s", ServiceConstant.GOV_ORG_SERVER, formDTO.getUserAccount(), formDTO.getPassword(), result.getCode(), result.getMsg())); return new ArrayList<>(); } /** * @Description 获取客户信息 * @param appId * @author zxc */ public PaCustomerDTO getCustomerInfo(String appId){ String redisKey = RedisKeys.getThirdCustomerInfoByAppId(appId); PaCustomerDTO customer = (PaCustomerDTO) redisUtils.get(redisKey); if (customer != null && StringUtils.isNotBlank(customer.getId())){ return customer; } JSONObject jsonObject = new JSONObject(); String data = HttpClientManager.getInstance().sendPostByJSON(AuthHttpUrlConstant.CUSTOMER_MSG_URL + appId, JSON.toJSONString(jsonObject)).getData(); logger.info("ThirdLoginServiceImpl.getCustomerInfo:httpclient->url:"+AuthHttpUrlConstant.CUSTOMER_MSG_URL+",结果->"+data); JSONObject toResult = JSON.parseObject(data); Result mapToResult = ConvertUtils.mapToEntity(toResult, Result.class); if (null != toResult.get("code")) { mapToResult.setCode(((Integer) toResult.get("code")).intValue()); } if (!mapToResult.success()) { logger.error(String.format("根据appId查询客户Id失败,对应appId->" + appId)); throw new RenException(mapToResult.getMsg()); } Object PublicCustomerResultDTO = mapToResult.getData(); JSONObject json = JSON.parseObject(PublicCustomerResultDTO.toString()); Map map = (Map)json.get("customer"); customer = ConvertUtils.mapToEntity(map, PaCustomerDTO.class); logger.info("小程序登陆third服务获取客户用户信息PaCustomerDTO->"+customer); redisUtils.set(redisKey,customer); return customer; } /** * @Description 获取UserWechatDTO * @param resiLoginFormDTO * @author zxc */ public UserWechatDTO getUserWeChat(WxLoginFormDTO resiLoginFormDTO){ String data = HttpClientManager.getInstance().sendPostByJSON(AuthHttpUrlConstant.RESI_AND_WORK_LOGIN_URL, JSON.toJSONString(resiLoginFormDTO)).getData(); logger.info("ThirdLoginServiceImpl.getUserWeChat:httpclient->url:"+AuthHttpUrlConstant.RESI_AND_WORK_LOGIN_URL+",结果->"+data); JSONObject toResult = JSON.parseObject(data); Result mapToResult = ConvertUtils.mapToEntity(toResult, Result.class); if (null != toResult.get("code")) { mapToResult.setCode(((Integer) toResult.get("code")).intValue()); } if (!mapToResult.success()) { logger.error("居民端小程序登陆,调用epmet_third服务获取数据失败"); throw new RenException(mapToResult.getCode()); } Object UserWeChatDTO = mapToResult.getData(); JSONObject json = JSON.parseObject(UserWeChatDTO.toString()); UserWechatDTO userWechatDTO = ConvertUtils.mapToEntity(json, UserWechatDTO.class); logger.info("小程序登陆third服务获取微信用户信息userWechatDTO->"+userWechatDTO); return userWechatDTO; } /** * @param formDTO * @return * @author sun * @description 单客户-获取微信用户手机号 * 【此接口只适配第三方客户,对于党群e事通客户还是走原接口】 **/ @Override public String getResiWxPhone(GetResiWxPhoneFormDTO formDTO) { String phone = ""; try { //1.根据wxcode获取sessionKey WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); //此方法会校验appId是否授权,然后在判断客户是否存在,之后才是获取sessionKey,如果只想获取sessionKey需要写新接口 UserWechatDTO userWechatDTO = this.getUserWeChat(resiLoginFormDTO); if (null == userWechatDTO || null == userWechatDTO.getSessionKey()) { logger.error(String.format("调用生成third服务wxcode获取sessionKey失败,对应appId->" + formDTO.getAppId())); throw new RenException("获取本机号码失败"); } //2.使用sessionKey解密获取手机号 WxMaPhoneNumberInfo phoneNoInfo = WxMaPhoneNumberInfo.fromJson(WxMaCryptUtils.decrypt(userWechatDTO.getSessionKey(), formDTO.getEncryptedData(), formDTO.getIv())); if (null != phoneNoInfo) { phone = phoneNoInfo.getPurePhoneNumber(); } } catch (Exception e) { log.error("method exception", e); log.error(String.format("获取用户微信绑定的手机号接口异常%s", e.getMessage())); } return phone; } /** * @param formDTO * @author sun * @description 单客户-工作端微信小程序登录-发送验证码 **/ @Override public void sendSmsCode(ThirdSendSmsCodeFormDTO formDTO) { String str = "发送短信验证码异常,手机号[%s],code[%s],msg[%s]"; //1.校验手机号是否符合规范 if (!PhoneValidatorUtils.isMobile(formDTO.getMobile())) { logger.warn(String.format(str, formDTO.getMobile(), EpmetErrorCode.ERROR_PHONE.getCode(), EpmetErrorCode.ERROR_PHONE.getMsg())); throw new RenException(EpmetErrorCode.ERROR_PHONE.getCode()); } //2.根据手机号校验用户是否存在 //2-1.根据appId查询对应客户Id PaCustomerDTO customer = this.getCustomerInfo(formDTO.getAppId()); //2-2.根据手机号查询到用户信息 ThirdCustomerStaffFormDTO dto = new ThirdCustomerStaffFormDTO(); dto.setCustomerId(customer.getId()); dto.setMobile(formDTO.getMobile()); Result> customerStaffResult = epmetUserOpenFeignClient.getCustsomerStaffByIdAndPhone(dto); if (!customerStaffResult.success()) { logger.warn(String.format(str, formDTO.getMobile(), customerStaffResult.getCode(), customerStaffResult.getMsg())); throw new RenException(customerStaffResult.getCode()); } //3.发送短信验证码 SendVerificationCodeFormDTO sendVerificationCodeFormDTO = new SendVerificationCodeFormDTO(); sendVerificationCodeFormDTO.setMobile(formDTO.getMobile()); sendVerificationCodeFormDTO.setAliyunTemplateCode(SmsTemplateConstant.LGOIN_CONFIRM); Result smsCodeResult = epmetMessageOpenFeignClient.sendVerificationCode(sendVerificationCodeFormDTO); if (!smsCodeResult.success()) { logger.warn(String.format(str, formDTO.getMobile(), smsCodeResult.getCode(), smsCodeResult.getMsg())); throw new RenException(smsCodeResult.getCode()); } //4.保存短信验证码(删除现有短信验证码 将新的短信验证码存入Redis) SendSmsCodeFormDTO sendSmsCodeFormDTO = new SendSmsCodeFormDTO(); sendSmsCodeFormDTO.setMobile(formDTO.getMobile()); captchaRedis.saveSmsCode(sendSmsCodeFormDTO, smsCodeResult.getData().getCode()); logger.info(String.format("发送短信验证码成功,手机号[%s]", formDTO.getMobile())); } /** * @Description 发送登录事件 * @return * @author wxz * @date 2021.06.08 15:27 */ private void sendLoginEvent(String userId, String appId, String fromApp, String fromClient) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); LoginMQMsg loginMQMsg = new LoginMQMsg(); loginMQMsg.setUserId(userId); loginMQMsg.setLoginTime(new Date()); loginMQMsg.setAppId(appId); loginMQMsg.setIp(IpUtils.getIpAddr(request)); loginMQMsg.setFromApp(fromApp); loginMQMsg.setFromClient(fromClient); SystemMsgFormDTO form = new SystemMsgFormDTO(); form.setMessageType(AuthOperationConstants.LOGIN); form.setContent(loginMQMsg); messageOpenFeignClient.sendSystemMsgByMQ(form); //getResultDataOrThrowsException(result, ServiceConstant.EPMET_MESSAGE_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "调用Message服务,发送登录事件到MQ失败"); } }