diff --git a/epmet-auth/src/main/java/com/epmet/controller/ThirdLoginController.java b/epmet-auth/src/main/java/com/epmet/controller/ThirdLoginController.java index efcf97ef5b..56b97fa2c6 100644 --- a/epmet-auth/src/main/java/com/epmet/controller/ThirdLoginController.java +++ b/epmet-auth/src/main/java/com/epmet/controller/ThirdLoginController.java @@ -9,10 +9,7 @@ import com.epmet.dto.result.UserTokenResultDTO; import com.epmet.service.ThirdLoginService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -118,7 +115,14 @@ public class ThirdLoginController { } /** - *接入流程:https://open.dingtalk.com/document/isvapp-server/unified-authorization-suite-access-process + * 钉钉应用的登录-居民端 + * 产品服务商建立第三方企业应用 + * 参考文档:https://open.dingtalk.com/document/isvapp-server/unified-authorization-suite-access-process + * @param formDTO + * @return + */ + /** + * 接入流程: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 * 接口逻辑: @@ -135,10 +139,43 @@ public class ThirdLoginController { return new Result().ok(thirdLoginService.resiLoginDing(formDTO)); } - + /** + * 烟台建立应用,授权给我们,走企业免登 + * 企业简历内部应用授权给第三方 + * 可参考文档: 获取第三方应用授权企业的accessToken https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-the-authorized-enterprise + * https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free + * @param formDTO + * @return + */ @PostMapping("resilogin-ding-md") public Result resiLoginDingMd(@RequestBody ResiDingAppLoginMdFormDTO formDTO) { ValidatorUtils.validateEntity(formDTO); return new Result().ok(thirdLoginService.resiLoginDingMd(formDTO)); } + + /** + * 企业内部应用开发,不授权了 文档地址:https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free + * 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 + */ + @PostMapping("resilogin-internalding") + public Result resiLoginInternalDing(@RequestBody ResiDingAppLoginMdFormDTO formDTO) { + ValidatorUtils.validateEntity(formDTO); + return new Result().ok(thirdLoginService.resiLoginInternalDing(formDTO)); + } } diff --git a/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java b/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java index eeab9296a3..19b0e0dc91 100644 --- a/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java +++ b/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java @@ -70,10 +70,26 @@ public interface ThirdLoginService { /** * 钉钉应用的登录-居民端 + * 产品服务商建立第三方企业应用 + * 参考文档:https://open.dingtalk.com/document/isvapp-server/unified-authorization-suite-access-process * @param formDTO * @return */ ResiDingAppLoginResDTO resiLoginDing(ResiDingAppLoginFormDTO formDTO); + /** + * 企业简历内部应用授权给第三方 + * 可参考文档: 获取第三方应用授权企业的accessToken https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-the-authorized-enterprise + * https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free + * @param formDTO + * @return + */ ResiDingAppLoginResDTO resiLoginDingMd(ResiDingAppLoginMdFormDTO formDTO); + + /** + * 企业内部应用免登 文档地址:https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free + * @param formDTO + * @return + */ + ResiDingAppLoginResDTO resiLoginInternalDing(ResiDingAppLoginMdFormDTO formDTO); } diff --git a/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java b/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java index 10c3f8a2e8..65b53528fa 100644 --- a/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java +++ b/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java @@ -728,18 +728,7 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol ResiDingAppLoginResDTO resDTO= null; try { resDTO = new ResiDingAppLoginResDTO(); - EnvEnum currentEnv = EnvEnum.getCurrentEnv(); - if (EnvEnum.PROD.getCode().equals(currentEnv.getCode())) { - //烟台的客户id - resDTO.setCustomerId("1535072605621841922"); - }else if(EnvEnum.TEST.getCode().equals(currentEnv.getCode())){ - //最美琴岛 - resDTO.setCustomerId("0c41b272ee9ee95ac6f184ad548a30eb"); - }else{ - //其余统一走开发环境 - resDTO.setCustomerId("45687aa479955f9d06204d415238f7cc"); - } - + resDTO.setCustomerId(getCurrentCustomerId()); //1、获取用户手机号 String miniAppId = formDTO.getMiniAppId(); DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId); @@ -811,18 +800,7 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol log.info("1、钉钉居民端应用登录入参:" + JSON.toJSONString(formDTO)); ResiDingAppLoginResDTO resDTO = null; resDTO = new ResiDingAppLoginResDTO(); - EnvEnum currentEnv = EnvEnum.getCurrentEnv(); - if (EnvEnum.PROD.getCode().equals(currentEnv.getCode())) { - // 烟台的客户id - resDTO.setCustomerId("1535072605621841922"); - } else if (EnvEnum.TEST.getCode().equals(currentEnv.getCode())) { - // 最美琴岛 - resDTO.setCustomerId("0c41b272ee9ee95ac6f184ad548a30eb"); - } else { - // 其余统一走开发环境 - resDTO.setCustomerId("45687aa479955f9d06204d415238f7cc"); - } - + resDTO.setCustomerId(getCurrentCustomerId()); // 1、获取用户手机号 DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOMd(formDTO.getMiniAppId(), formDTO.getAuthCode()); dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId()); @@ -896,4 +874,130 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol } + /** + * 企业内部应用开发,不授权了 + * 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(ResiDingAppLoginMdFormDTO 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()); + + // 2、调用userfeign接口获取userId、注册网格相关信息 + Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO); + if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) { + // 临时打个日志 + log.error(String.format("resiLoginInternalDing获取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; + } + + /** + * 最原始的企业内部应用开发,不授权给产品服务商 + * @param miniAppId + * @param authCode + * @return + */ + private DingLoginResiFormDTO getDingLoginResiFormDTOInternal(String miniAppId, String authCode) { + DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId); + + // 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.getSuiteSecret(), 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; + } }