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.aliyun.dingtalk.module.DingTalkResult; 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.NumConstant; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.constant.StrConstant; import com.epmet.commons.tools.enums.EnvEnum; 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.common.CustomerDingDingRedis; import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; 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.utils.*; import com.epmet.commons.tools.utils.api.yt.YantaiApi; import com.epmet.commons.tools.utils.api.yt.YantaiSSOUser; 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.dingres.DingUserDetailDTO; import com.epmet.dto.dingres.V2UserGetuserinfoResDTO; 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.feign.ThirdOpenFeignClient; import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; import com.epmet.redis.CaptchaRedis; import com.epmet.sdt.SdtStaffDetailResult; import com.epmet.sdt.SdtStaffInfoResult; import com.epmet.service.GovWebService; import com.epmet.service.ThirdLoginService; import com.taobao.api.ApiException; import com.taobao.dingtalk.client.DingTalkClientToken; import com.taobao.dingtalk.client.DingTalkClientUser; import com.taobao.dingtalk.vo.result.AccessTokenResult; import com.taobao.dingtalk.vo.result.UserBaseInfo; 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 DingTalkClientToken dingTalkClientToken; @Autowired private DingTalkClientUser dingTalkClientUser; @Autowired private GovWebService govWebService; @Autowired private ThirdOpenFeignClient thirdOpenFeignClient; /** * @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(); //2022.11.24校验下用户是否被禁用 //2.1根据手机号查询到用户信息 前端不跳转,暂时先注释吧 ThirdCustomerStaffFormDTO dto = new ThirdCustomerStaffFormDTO(); dto.setCustomerId(staffLatestAgencyResultDTO.getCustomerId()); dto.setMobile(staffLatestAgencyResultDTO.getMobile()); Result> customerStaffResult = epmetUserOpenFeignClient.getCustsomerStaffByIdAndPhone(dto); if (!customerStaffResult.success()) { logger.error(String.format("手机验证码登录异常,手机号[%s],code[%s],msg[%s]", staffLatestAgencyResultDTO.getMobile(), customerStaffResult.getCode(), customerStaffResult.getMsg())); throw new RenException(customerStaffResult.getCode()); } // 8008 前端会提示:登录失效,请重新登录 跳转到登录界面。所以这里写死返回8008. if("disabled".equals(customerStaffResult.getData().get(NumConstant.ZERO).getEnableFlag())){ throw new EpmetException(EpmetErrorCode.PLEASE_LOGIN.getCode(),EpmetErrorCode.GOV_STAFF_DISABLED.getMsg(),EpmetErrorCode.GOV_STAFF_DISABLED.getMsg()); } //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, AuthOperationConstants.LOGIN); } 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.warn(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, AuthOperationConstants.LOGIN); } 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, AuthOperationConstants.LOGIN); } 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()); } if("disabled".equals(customerStaffResult.getData().get(NumConstant.ZERO).getEnableFlag())){ throw new EpmetException(EpmetErrorCode.GOV_STAFF_DISABLED.getCode(),EpmetErrorCode.GOV_STAFF_DISABLED.getMsg(),EpmetErrorCode.GOV_STAFF_DISABLED.getMsg()); } //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()||CollectionUtils.isEmpty(customerStaffResult.getData())) { 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(); // 禁用的给予提示 if("disabled".equals(customerStaffList.get(NumConstant.ZERO).getEnableFlag())){ throw new EpmetException(EpmetErrorCode.GOV_STAFF_DISABLED.getCode(),EpmetErrorCode.GOV_STAFF_DISABLED.getMsg(),EpmetErrorCode.GOV_STAFF_DISABLED.getMsg()); } //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) { //0.根据appId查询对应客户Id PaCustomerDTO customer = this.getCustomerInfo(formDTO.getAppId()); //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()); } //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.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()); } 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.getUserAccount(), 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 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> 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 */ @Override public void sendLoginEvent(String userId, String appId, String fromApp, String fromClient,String messageType) { 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.setMessageType(messageType); 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("1、钉钉居民端应用登录入参:"+ JSON.toJSONString(formDTO)); ResiDingAppLoginResDTO resDTO= null; try { resDTO = new ResiDingAppLoginResDTO(); resDTO.setCustomerId(getCurrentCustomerId()); //1、获取用户手机号 String miniAppId = formDTO.getMiniAppId(); DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId); DingTalkResult userAccessToken = dingTalkClientToken.getUserAccessToken(formDTO.getAuthCode(), dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret()); log.info("2、resiLoginDing userAccessToken:{}",JSON.toJSONString(userAccessToken)); if (!userAccessToken.success() || null == userAccessToken.getData()) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "调用微信api异常:" + JSON.toJSONString(userAccessToken), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg()); } DingTalkResult me = dingTalkClientUser.getUserInfo("me", userAccessToken.getData().getAccessToken()); log.info("3、resiLoginDing me:{}",JSON.toJSONString(me)); resDTO.setExtInfo(JSON.toJSONString(me.getData())); if (!me.success() || StringUtils.isBlank(me.getData().getMobile())) { log.error("resilogin-ding登录接口报错,入参:" + JSON.toJSONString(formDTO) + ";获取手机号为空, userAccessToken.getData().getAccessToken()=" + userAccessToken.getData().getAccessToken()); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取手机号为空", "获取手机号为空"); } // 2、调用userfeign接口获取userId、注册网格相关信息 todo DingLoginResiFormDTO dingLoginResiFormDTO=ConvertUtils.sourceToTarget(me.getData(),DingLoginResiFormDTO.class); dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId()); Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO); if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) { //临时打个日志 log.error(String.format("resilogin-ding获取epmetUserId异常,入参:%s,user服务返参:%s", JSON.toJSONString(formDTO), JSON.toJSONString(loginResiResDTOResult))); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取epmetUserId异常:" + JSON.toJSONString(loginResiResDTOResult), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg()); } DingLoginResiResDTO resiResDTO=loginResiResDTOResult.getData(); resDTO.setGridId(resiResDTO.getGridId()); resDTO.setGridName(resiResDTO.getGridName()); resDTO.setAgencyId(resiResDTO.getAgencyId()); resDTO.setEpmetUserId(resiResDTO.getEpmetUserId()); resDTO.setRegFlag(resiResDTO.getRegFlag()); //3.生成token,并且存放Redis String token=this.saveTokenDtoDing(formDTO.getMiniAppId(),AppClientConstant.APP_RESI,AppClientConstant.MINI_DING, resDTO.getEpmetUserId(), resDTO.getCustomerId()); resDTO.setAuthorization(token); } catch (ApiException e) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), e.getErrMsg(), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg()); } return resDTO; } private String saveTokenDtoDing(String miniAppId,String app,String client, String userId,String customerId) { //生成token串 Map map = new HashMap<>(); map.put(AppClientConstant.APP, app); // map.put(AppClientConstant.CLIENT, client); // 第三方企业应用传应用的SuiteKey 作为client map.put(AppClientConstant.CLIENT, client.concat(miniAppId)); map.put("userId", userId); String token = jwtTokenUtils.createToken(map); int expire = jwtTokenProperties.getExpire(); TokenDto tokenDto = new TokenDto(); tokenDto.setCustomerId(customerId); tokenDto.setApp(app); tokenDto.setClient(client.concat(miniAppId)); tokenDto.setUserId(userId); tokenDto.setToken(token); tokenDto.setUpdateTime(System.currentTimeMillis()); tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); cpUserDetailRedis.set(tokenDto, expire); // cpUserDetailRedis.setForDingApp(miniAppId,tokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); return token; } private String saveTokenDtoHfive(String app,String client, String userId,String customerId) { //生成token串 Map map = new HashMap<>(); map.put(AppClientConstant.APP, app); // map.put(AppClientConstant.CLIENT, client); // 第三方企业应用传应用的SuiteKey 作为client map.put(AppClientConstant.CLIENT, client); map.put("userId", userId); String token = jwtTokenUtils.createToken(map); int expire = jwtTokenProperties.getExpire(); TokenDto tokenDto = new TokenDto(); tokenDto.setCustomerId(customerId); tokenDto.setApp(app); tokenDto.setClient(client); tokenDto.setUserId(userId); tokenDto.setToken(token); tokenDto.setUpdateTime(System.currentTimeMillis()); tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); cpUserDetailRedis.set(tokenDto, expire); // cpUserDetailRedis.setForDingApp(miniAppId,tokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); return token; } @Override public ResiDingAppLoginResDTO resiLoginDingMd(DingAppLoginMdFormDTO formDTO) { // 获取用户手机号 log.info("1、钉钉居民端应用登录入参:" + JSON.toJSONString(formDTO)); ResiDingAppLoginResDTO resDTO = null; resDTO = new ResiDingAppLoginResDTO(); resDTO.setCustomerId(getCurrentCustomerId()); // 1、获取用户手机号 DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOMd(formDTO.getMiniAppId(), formDTO.getAuthCode()); dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId()); // 2、调用userfeign接口获取userId、注册网格相关信息 Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO); if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) { // 临时打个日志 log.error(String.format("resiLoginDingMd获取epmetUserId异常,入参:%s,user服务返参:%s", JSON.toJSONString(formDTO), JSON.toJSONString(loginResiResDTOResult))); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取epmetUserId异常:" + JSON.toJSONString(loginResiResDTOResult), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg()); } DingLoginResiResDTO resiResDTO = loginResiResDTOResult.getData(); resDTO.setGridId(resiResDTO.getGridId()); resDTO.setGridName(resiResDTO.getGridName()); resDTO.setAgencyId(resiResDTO.getAgencyId()); resDTO.setEpmetUserId(resiResDTO.getEpmetUserId()); resDTO.setRegFlag(resiResDTO.getRegFlag()); // 3.生成token,并且存放Redis String token = this.saveTokenDtoDing(formDTO.getMiniAppId(), AppClientConstant.APP_RESI, AppClientConstant.MINI_DING, resDTO.getEpmetUserId(), resDTO.getCustomerId()); resDTO.setAuthorization(token); return resDTO; } private DingLoginResiFormDTO getDingLoginResiFormDTOMd(String miniAppId, String authCode) { DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId); // 1、服务商获取第三方应用授权企业的access_token,文档地址:https://open.dingtalk.com/document/orgapp-server/obtains-the-enterprise-authorized-credential // 烟台的CorpId: dingaae55cbc47a96845f5bf40eda33b7ba0 String yantaiCorpId = "dingaae55cbc47a96845f5bf40eda33b7ba0"; DingTalkResult res = dingTalkClientToken.getThirdAuthCorpAccessToken(dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret(), "abc", yantaiCorpId); if (!res.success() || StringUtils.isBlank(res.getData())) { log.error(String.format("企业内部应用免登服务商获取第三方应用授权企业的access_token失败,customKey:%s,customSecret:%s,corpId:%s", dingMiniInfo.getSuiteSecret(), dingMiniInfo.getSuiteSecret(), yantaiCorpId)); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "服务商获取第三方应用授权企业的access_token", "服务商获取第三方应用授权企业的access_token"); } String accessToken = res.getData(); log.info(String.format("1、服务商获取第三方应用授权企业的access_token返参:%s", accessToken)); // 2、通过免登码获取用户信息,文档地址:https://open.dingtalk.com/document/orgapp-server/obtain-the-userid-of-a-user-by-using-the-log-free DingTalkResult v2UserGetuserinfoRes = dingTalkClientToken.getUserInfo(accessToken, authCode); if (!v2UserGetuserinfoRes.success() || StringUtils.isBlank(v2UserGetuserinfoRes.getData())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "通过免登码获取用户信息异常", "通过免登码获取用户信息异常"); } log.info(String.format("2、通过免登码获取用户信息返参:%s", v2UserGetuserinfoRes.getData())); V2UserGetuserinfoResDTO v2UserGetuserinfoResDTO = JSON.parseObject(v2UserGetuserinfoRes.getData(), V2UserGetuserinfoResDTO.class); if (null == v2UserGetuserinfoResDTO || StringUtils.isBlank(v2UserGetuserinfoResDTO.getUserid())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取钉钉用户userid为空", "获取钉钉用户userid为空"); } // 3、查询用户详情,文档地址:https://open.dingtalk.com/document/isvapp-server/query-user-details DingTalkResult v2UserGetRes = dingTalkClientToken.getUserDetail(v2UserGetuserinfoResDTO.getUserid(), accessToken); if (!v2UserGetRes.success() || StringUtils.isBlank(v2UserGetRes.getData())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "根据userId查询用户详情失败", "根据userId查询用户详情失败"); } log.info(String.format("3、查询用户详情:%s", v2UserGetRes.getData())); DingUserDetailDTO dingUserDetailDTO = JSON.parseObject(v2UserGetRes.getData(), DingUserDetailDTO.class); if (null == dingUserDetailDTO || StringUtils.isBlank(dingUserDetailDTO.getMobile())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取手机号为空", "获取手机号为空"); } DingLoginResiFormDTO dingLoginResiFormDTO = new DingLoginResiFormDTO(); dingLoginResiFormDTO.setAvatarUrl(dingUserDetailDTO.getAvatar()); dingLoginResiFormDTO.setEmail(dingUserDetailDTO.getOrg_email()); dingLoginResiFormDTO.setMobile(dingUserDetailDTO.getMobile()); dingLoginResiFormDTO.setNick(dingUserDetailDTO.getName()); dingLoginResiFormDTO.setOpenId(StrConstant.EPMETY_STR); dingLoginResiFormDTO.setStateCode(dingUserDetailDTO.getState_code()); dingLoginResiFormDTO.setUnionId(dingUserDetailDTO.getUnionid()); return dingLoginResiFormDTO; } /** * 企业内部应用开发,不授权了 * https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free * 建议用户信息保存在前端缓存中(dd.setStorage)或者cookie中,避免每次进入应用都调用钉钉接口进行免登。 * * 获取免登授权码。 * 小程序免登 * 微应用免登 * 获取AccessToken。 * 调用接口获取access_token,详情请参考获取企业内部应用的access_token。 * * 获取userid。 * 调用接口获取用户的userid,详情请参考通过免登码获取用户信息。 * * 获取用户详情。 * 调用接口获取用户详细信息,详情请参考根据userId获取用户详情。 * * @param formDTO * @return */ @Override public ResiDingAppLoginResDTO resiLoginInternalDing(DingAppLoginMdFormDTO formDTO) { // 获取用户手机号 log.info("1、钉钉居民端应用登录入参:" + JSON.toJSONString(formDTO)); ResiDingAppLoginResDTO resDTO = new ResiDingAppLoginResDTO(); resDTO.setCustomerId(getCurrentCustomerId()); // 1、获取用户手机号 DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOInternal(formDTO.getMiniAppId(), formDTO.getAuthCode()); dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId()); resDTO.setRealName(dingLoginResiFormDTO.getNick()); // 2、调用userfeign接口获取userId、注册网格相关信息 Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO); if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) { // 临时打个日志 log.error(String.format("resiLoginInternalDing获取epmetUserId异常,入参:%s", JSON.toJSONString(dingLoginResiFormDTO))); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取epmetUserId异常:"+ JSON.toJSONString(loginResiResDTOResult), "获取epmetUserId异常"); } DingLoginResiResDTO resiResDTO = loginResiResDTOResult.getData(); resDTO.setGridId(resiResDTO.getGridId()); resDTO.setGridName(resiResDTO.getGridName()); resDTO.setAgencyId(resiResDTO.getAgencyId()); resDTO.setEpmetUserId(resiResDTO.getEpmetUserId()); resDTO.setRegFlag(resiResDTO.getRegFlag()); // 3.生成token,并且存放Redis String token = this.saveTokenDtoDing(formDTO.getMiniAppId(), AppClientConstant.APP_RESI, AppClientConstant.MINI_DING, resDTO.getEpmetUserId(), resDTO.getCustomerId()); resDTO.setAuthorization(token); return resDTO; } /** * h5-登陆 随手拍 议事厅 * @param formDTO * @return */ @Override public ResiHfiveAppLoginResDTO resiLoginHfive(HfiveLoginMdFormDTO formDTO) { // 获取用户手机号 ResiHfiveAppLoginResDTO resDTO = new ResiHfiveAppLoginResDTO(); // 1、获取用户手机号 // DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOInternal(formDTO.getMiniAppId(), formDTO.getAuthCode()); HfiveLoginResiFormDTO hfiveLoginResiFormDTO = new HfiveLoginResiFormDTO(); hfiveLoginResiFormDTO.setUserBaseInfoId(formDTO.getUserBaseInfoId()); hfiveLoginResiFormDTO.setCustomerId(getCurrentCustomerId()); // 2、调用userfeign接口获取userId、注册网格相关信息 Result loginResiResDTOResult = epmetUserOpenFeignClient.hFiveResiLogin(hfiveLoginResiFormDTO); if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) { // 临时打个日志 log.error(String.format("resiLoginHfive获取epmetUserId异常,入参:%s", JSON.toJSONString(hfiveLoginResiFormDTO))); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "提供的居民id获取居民信息失败:"+ formDTO.getUserBaseInfoId(), "获取token失败"); } DingLoginResiResDTO resiResDTO = loginResiResDTOResult.getData(); // 网格id resDTO.setGridId(loginResiResDTOResult.getData().getGridId()); // 3.生成token,并且存放Redis String token = this.saveTokenDtoHfive(AppClientConstant.APP_RESI, AppClientConstant.LAN_TU, resiResDTO.getEpmetUserId(), getCurrentCustomerId()); resDTO.setAuthorization(token); return resDTO; } @Override public ResiRegisterLantuResultDTO resiRegisterLantu(ResiRegisterLantuFormDTO formDTO) { // 最后返回给烟台的东西 最后可以跟我们系统关联起来 ResiRegisterLantuResultDTO resiRegisterLantuResultDTO = new ResiRegisterLantuResultDTO(); // 用来注册居民端 LantuRegisterResiFormDTO lantuRegisterResiFormDTO = new LantuRegisterResiFormDTO(); // customer 给蓝图用 customerId 写死 烟台 // lantuRegisterResiFormDTO.setCustomerId("1535072605621841922"); lantuRegisterResiFormDTO.setCustomerId(getCurrentCustomerId()); lantuRegisterResiFormDTO.setSex(formDTO.getSex()); lantuRegisterResiFormDTO.setMobile(formDTO.getLoginMobile()); lantuRegisterResiFormDTO.setNick(formDTO.getNickName()); lantuRegisterResiFormDTO.setRealName(formDTO.getRealName()); lantuRegisterResiFormDTO.setAvatarUrl(formDTO.getAvatarUrl()); // 通过给的areaCode 去获取一下当前社区统建网格id LanhuAgencyResultDTO lanhuAgencyResultDTO = govOrgOpenFeignClient.getGridIdByCommunityCode(formDTO.getAreaCode()).getData(); lantuRegisterResiFormDTO.setGridId(lanhuAgencyResultDTO.getGridId()); lantuRegisterResiFormDTO.setStreetName(lanhuAgencyResultDTO.getStreetName()); // 注册 Result lantuRegisterResi = epmetUserOpenFeignClient.lantuRegisterResi(lantuRegisterResiFormDTO); if (!lantuRegisterResi.success() || null == lantuRegisterResi.getData()) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), JSON.toJSONString(lantuRegisterResi), "居民注册异常"); } resiRegisterLantuResultDTO.setUserBaseInfoId(lantuRegisterResi.getData().getEpmetUserId()); return resiRegisterLantuResultDTO; } @Override public ResiRegisterLantuResultDTO resiInfoLantu(ResiInfoLantuFormDTO formDTO) { // 最后返回给烟台的东西 最后可以跟我们系统关联起来 ResiRegisterLantuResultDTO resiRegisterLantuResultDTO = new ResiRegisterLantuResultDTO(); // 用来注册居民端 LantuRegisterResiFormDTO lantuRegisterResiFormDTO = new LantuRegisterResiFormDTO(); // customer 给蓝图用 customerId 写死 烟台 // lantuRegisterResiFormDTO.setCustomerId("1535072605621841922"); lantuRegisterResiFormDTO.setCustomerId(getCurrentCustomerId()); lantuRegisterResiFormDTO.setMobile(formDTO.getLoginMobile()); // 注册 Result lantuRegisterResi = epmetUserOpenFeignClient.lantuResiInfo(lantuRegisterResiFormDTO); if (!lantuRegisterResi.success() || null == lantuRegisterResi.getData()) { }else{ resiRegisterLantuResultDTO.setUserBaseInfoId(lantuRegisterResi.getData().getEpmetUserId()); } return resiRegisterLantuResultDTO; } @Override public UserTokenResultDTO govLoginInternalDing(DingAppLoginMdFormDTO formDTO) { // 获取用户手机号 log.info("1、钉钉居民端应用登录入参:" + JSON.toJSONString(formDTO)); ResiDingAppLoginResDTO resDTO = null; resDTO = new ResiDingAppLoginResDTO(); resDTO.setCustomerId(getCurrentCustomerId()); // 1、获取用户手机号 DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOInternal(formDTO.getMiniAppId(), formDTO.getAuthCode()); dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId()); GovWebLoginFormDTO loginGovParam = new GovWebLoginFormDTO(); loginGovParam.setCustomerId(dingLoginResiFormDTO.getCustomerId()); loginGovParam.setPhone(dingLoginResiFormDTO.getMobile()); return govWebService.loginByThirdPlatform(loginGovParam); } @Override public UserTokenResultDTO yanTaiSSOLogin(String authCode) { YantaiSSOUser ssoUserInfo = YantaiApi.getLoginToken(authCode); if (ssoUserInfo== null){ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(),"登录失败-sso获取用户失败","登录失败-sso获取用户失败"); } GovWebLoginFormDTO loginGovParam = new GovWebLoginFormDTO(); loginGovParam.setCustomerId("1535072605621841922"); loginGovParam.setPhone(ssoUserInfo.getMobile()); return govWebService.loginByThirdPlatform(loginGovParam); } /** * 最原始的企业内部应用开发,不授权给产品服务商 * @param miniAppId * @param authCode * @return */ private DingLoginResiFormDTO getDingLoginResiFormDTOInternal(String miniAppId, String authCode) { DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId); if (dingMiniInfo == null){ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取钉钉应用配置异常", "获取钉钉应用配置异常"); } // 1、获取企业内部应用的accessToken文档地址:https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app String accessToken = ""; DingTalkResult dingTalkResult = dingTalkClientToken.getAppAccessTokenToken(dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret()); if (!dingTalkResult.success() || StringUtils.isBlank(dingTalkResult.getData())) { log.error(String.format("获取企业内部应用的accessToken失败,customKey:%s,customSecret:%s", dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret())); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取企业内部应用的accessToken异常", "获取企业内部应用的accessToken"); } accessToken = dingTalkResult.getData(); log.info(String.format("1、获取企业内部应用的accessToken返参:%s", accessToken)); // 2、通过免登码获取用户信息,文档地址:https://open.dingtalk.com/document/orgapp-server/obtain-the-userid-of-a-user-by-using-the-log-free DingTalkResult v2UserGetuserinfoRes = dingTalkClientToken.getUserInfo(accessToken, authCode); if (!v2UserGetuserinfoRes.success() || StringUtils.isBlank(v2UserGetuserinfoRes.getData())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "通过免登码获取用户信息异常", "通过免登码获取用户信息异常"); } log.info(String.format("2、通过免登码获取用户信息返参:%s", v2UserGetuserinfoRes.getData())); V2UserGetuserinfoResDTO v2UserGetuserinfoResDTO = JSON.parseObject(v2UserGetuserinfoRes.getData(), V2UserGetuserinfoResDTO.class); if (null == v2UserGetuserinfoResDTO || StringUtils.isBlank(v2UserGetuserinfoResDTO.getUserid())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取钉钉用户userid为空", "获取钉钉用户userid为空"); } // 3、查询用户详情,文档地址:https://open.dingtalk.com/document/isvapp-server/query-user-details DingTalkResult v2UserGetRes = dingTalkClientToken.getUserDetail(v2UserGetuserinfoResDTO.getUserid(), accessToken); if (!v2UserGetRes.success() || StringUtils.isBlank(v2UserGetRes.getData())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "根据userId查询用户详情失败", "根据userId查询用户详情失败"); } log.info(String.format("3、查询用户详情:%s", v2UserGetRes.getData())); DingUserDetailDTO dingUserDetailDTO = JSON.parseObject(v2UserGetRes.getData(), DingUserDetailDTO.class); if (null == dingUserDetailDTO || StringUtils.isBlank(dingUserDetailDTO.getMobile())) { throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取手机号为空", "获取手机号为空"); } DingLoginResiFormDTO dingLoginResiFormDTO = new DingLoginResiFormDTO(); dingLoginResiFormDTO.setAvatarUrl(dingUserDetailDTO.getAvatar()); dingLoginResiFormDTO.setEmail(dingUserDetailDTO.getOrg_email()); dingLoginResiFormDTO.setMobile(dingUserDetailDTO.getMobile()); dingLoginResiFormDTO.setNick(dingUserDetailDTO.getName()); dingLoginResiFormDTO.setOpenId(StrConstant.EPMETY_STR); dingLoginResiFormDTO.setStateCode(dingUserDetailDTO.getState_code()); dingLoginResiFormDTO.setUnionId(dingUserDetailDTO.getUnionid()); return dingLoginResiFormDTO; } /** * 客户写死吧 * @return */ private String getCurrentCustomerId() { String customerId=""; EnvEnum currentEnv = EnvEnum.getCurrentEnv(); if (EnvEnum.PROD.getCode().equals(currentEnv.getCode())) { // 烟台的客户id customerId="1535072605621841922"; } else if (EnvEnum.TEST.getCode().equals(currentEnv.getCode())) { // 最美琴岛 customerId="0c41b272ee9ee95ac6f184ad548a30eb"; } else { // 其余统一走开发环境 customerId="45687aa479955f9d06204d415238f7cc"; } return customerId; } @Override public UserTokenResultDTO sdtSSOLogin(String authCode, String customerId) { // 1.获取用户编码 SdtStaffInfoResult staffInfo = getResultDataOrThrowsException(thirdOpenFeignClient.getUserInfoByAuthCode(authCode, customerId), ServiceConstant.EPMET_THIRD_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "获取山东通用户基础信息失败", null); if (staffInfo == null) { throw new EpmetException(EpmetErrorCode.SERVER_ERROR.getCode(), "获取山东通用户基础信息返回null,流程终止"); } // 2.获取用户详细信息 SdtStaffDetailResult staffDetail = getResultDataOrThrowsException(thirdOpenFeignClient.getUserDetailByUserId(staffInfo.getUserId(), customerId), ServiceConstant.EPMET_THIRD_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "获取山东通用户详细信息失败", null); // 3.有了手机号,可以做登录了 String mobile = staffDetail.getMobile(); GovWebLoginFormDTO loginGovParam = new GovWebLoginFormDTO(); loginGovParam.setCustomerId(customerId); loginGovParam.setPhone(mobile); return govWebService.loginByThirdPlatform(loginGovParam); } @Override public UserTokenResultDTO videoLogin(String customerId) { JSONObject jsonObject = new JSONObject(); jsonObject.put("userName","apizhsq"); jsonObject.put("password","12345678@df"); jsonObject.put("type",1); String videoData = HttpClientManager.getInstance().sendPostByJSON(AuthHttpUrlConstant.VIDEO_LOGIN_URL, jsonObject.toString()).getData(); JSONObject toResult = JSON.parseObject(videoData); if(!"0".equals(toResult.getString("code"))){ throw new EpmetException(EpmetErrorCode.SERVER_ERROR.getCode(),"视频验签失败"); } JSONObject data = (JSONObject) toResult.get("data"); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setCustomerId(customerId); userTokenResultDTO.setToken((String) data.get("token")); return userTokenResultDTO; } }