forked from luyan/epmet-cloud-lingshan
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							730 lines
						
					
					
						
							35 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							730 lines
						
					
					
						
							35 KiB
						
					
					
				| 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.ExceptionUtils; | |
| import com.epmet.commons.tools.exception.RenException; | |
| import com.epmet.commons.tools.feign.ResultDataResolver; | |
| 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 com.taobao.dingtalk.client.DingTalkClientToken; | |
| 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 DingTalkClientToken dingTalkClientToken; | |
| 
 | |
|     /** | |
|      * @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<UserDTO> 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<String, Object> 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<StaffLatestAgencyResultDTO> 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<String, Object> 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<String> getDeptartmentIdList(String staffId) { | |
|         try { | |
|             Result<List<DepartmentListResultDTO>> deptListResult = govOrgOpenFeignClient.getDepartmentListByStaffId(staffId); | |
|             if (deptListResult.success()) { | |
|                 if (!CollectionUtils.isEmpty(deptListResult.getData())) { | |
|                     Set<String> 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<String> getGridIdList(String staffId) { | |
|         Result<List<GridByStaffResultDTO>> result = govOrgOpenFeignClient.listGridsbystaffid(staffId); | |
|         if (!result.success()) { | |
|             logger.error("登录:查询网格列表,远程调用返回错误:{}", result.getMsg()); | |
|             return null; | |
|         } else { | |
|             List<GridByStaffResultDTO> grids = result.getData(); | |
|             return grids.stream().map(grid -> grid.getGridId()).collect(Collectors.toSet()); | |
|         } | |
|     } | |
| 
 | |
|     /** | |
|      * 根据staffId查询所属的组织机构 | |
|      * | |
|      * @param staffId | |
|      */ | |
|     public CustomerAgencyDTO getAgencyByStaffId(String staffId) { | |
|         Result<CustomerAgencyDTO> result = govOrgOpenFeignClient.getAgencyByStaff(staffId); | |
|         if (!result.success()) { | |
|             logger.error("登录:查询登录人所属的机关OrgIdPath失败:{}", result.getMsg()); | |
|             return null; | |
|         } | |
|         return result.getData(); | |
|     } | |
| 
 | |
|     /** | |
|      * 查询人员在某机关单位下的角色列表 | |
|      * | |
|      * @param staffId orgId | |
|      */ | |
|     public List<GovTokenDto.Role> queryGovStaffRoles(String staffId, String orgId) { | |
|         StaffRoleFormDTO formDTO = new StaffRoleFormDTO(); | |
|         formDTO.setStaffId(staffId); | |
|         formDTO.setOrgId(orgId); | |
|         Result<List<GovStaffRoleDTO>> 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<CustomerAgencyDTO> 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<CustomerStaffDTO> 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 List<StaffOrgsResultDTO> 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<List<CustomerStaffDTO>> 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<String> customerIdList = new ArrayList<>(); | |
|         for (CustomerStaffDTO customerStaffDTO : customerStaffResult.getData()) { | |
|             customerIdList.add(customerStaffDTO.getCustomerId()); | |
|         } | |
|         StaffOrgFormDTO staffOrgFormDTO = new StaffOrgFormDTO(); | |
|         staffOrgFormDTO.setCustomerIdList(customerIdList); | |
|         Result<List<StaffOrgsResultDTO>> 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<StaffOrgsResultDTO> getMyOrgByPassword(ThirdStaffOrgsFormDTO formDTO) { | |
|         //0.根据appId查询对应客户Id | |
| //        Result<PublicCustomerResultDTO> 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<List<CustomerStaffDTO>> 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<CustomerStaffDTO> customerStaffList=customerStaffResult.getData(); | |
|         //3、查询用户所有的组织信息 | |
|         List<String> 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<List<StaffOrgsResultDTO>> 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<>(); | |
|     } | |
| 
 | |
|     /** | |
|      * @Description  获取客户信息 | |
|      * @param appId | |
|      * @author zxc | |
|      */ | |
|     public PaCustomerDTO getCustomerInfo(String appId){ | |
|         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<String,Object> map = (Map)json.get("customer"); | |
|         PaCustomerDTO customer = ConvertUtils.mapToEntity(map, PaCustomerDTO.class); | |
|         logger.info("小程序登陆third服务获取客户用户信息PaCustomerDTO->"+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<List<CustomerStaffDTO>> 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<SendVerificationCodeResultDTO> 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失败"); | |
|     } | |
| 
 | |
| // 接入流程:https://open.dingtalk.com/document/isvapp-server/unified-authorization-suite-access-process | |
| // 1、获取个人用户token:https://open.dingtalk.com/document/isvapp-server/obtain-user-token | |
| // 2、获取用户通讯录个人信息:https://open.dingtalk.com/document/isvapp-server/dingtalk-retrieve-user-information | |
| // 接口逻辑: | |
| // (1)根据clientId去XXX表找到customerId | |
| // (2)通过1、2拿到手机号之后,根据mobile+customerId去user_base_info表找userId, | |
| // 是否注册居民:register_relation | |
| // (3)没有则生成user、user_Base_info表记录 | |
|     /** | |
|      * 钉钉应用的登录-居民端 | |
|      * | |
|      * @param formDTO | |
|      * @return | |
|      */ | |
|     @Override | |
|     public ResiDingAppLoginResDTO resiLoginDing(ResiDingAppLoginFormDTO formDTO) { | |
|         //获取用户手机号 | |
|         log.info("钉钉居民端应用登录入参:"+ JSON.toJSONString(formDTO)); | |
|         //todo 调用一下接口 | |
|  | |
| 
 | |
|         ResiDingAppLoginResDTO resDTO=new ResiDingAppLoginResDTO(); | |
|         resDTO.setCustomerId("45687aa479955f9d06204d415238f7cc"); | |
|         resDTO.setGridId("763d6e09b9081d63195d53da84b3ae3a"); | |
|         resDTO.setEpmetUserId("f838614e67cf8ae0edaefe562b6660e5"); | |
|         //生成token串 | |
|         Map<String, Object> map = new HashMap<>(); | |
|         map.put("app", "resi"); | |
|         map.put("client", "miniding"); | |
|         map.put("userId", resDTO.getEpmetUserId()); | |
|         String token = jwtTokenUtils.createToken(map); | |
|         resDTO.setAuthorization(token); | |
|         return resDTO; | |
|     } | |
| }
 | |
| 
 |