diff --git a/epmet-auth/pom.xml b/epmet-auth/pom.xml index d14d863674..1822235cdc 100644 --- a/epmet-auth/pom.xml +++ b/epmet-auth/pom.xml @@ -138,6 +138,16 @@ epmet-auth-client 2.0.0 + + dingtalk-spring-boot-starter + com.taobao + 1.0.0 + + + commons-codec + commons-codec + 1.15 + diff --git a/epmet-auth/src/main/java/com/epmet/AuthApplication.java b/epmet-auth/src/main/java/com/epmet/AuthApplication.java index 0bf685bd5b..07d85a0d5f 100644 --- a/epmet-auth/src/main/java/com/epmet/AuthApplication.java +++ b/epmet-auth/src/main/java/com/epmet/AuthApplication.java @@ -8,6 +8,7 @@ package com.epmet; +import com.taobao.dingtalk.spring.annotations.EnableDingTalk; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @@ -20,6 +21,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; * @author Mark sunlightcs@gmail.com * @since 1.0.0 */ +@EnableDingTalk @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients 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 e8977cd508..0bb11c468a 100644 --- a/epmet-auth/src/main/java/com/epmet/controller/ThirdLoginController.java +++ b/epmet-auth/src/main/java/com/epmet/controller/ThirdLoginController.java @@ -3,15 +3,13 @@ package com.epmet.controller; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.ValidatorUtils; import com.epmet.dto.form.*; +import com.epmet.dto.result.ResiDingAppLoginResDTO; import com.epmet.dto.result.StaffOrgsResultDTO; 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; @@ -142,4 +140,68 @@ public class ThirdLoginController { return new Result(); } + /** + * 钉钉应用的登录-居民端 + * 产品服务商建立第三方企业应用 + * 参考文档: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 + * 接口逻辑: + * (1)根据clientId去XXX表找到customerId + * (2)通过1、2拿到手机号之后,根据mobile+customerId去user_base_info表找userId, + * 是否注册居民:register_relation + * (3)没有则生成user、user_Base_info表记录 + * @param formDTO + * @return + */ + @PostMapping("resilogin-ding") + public Result resiLoginDing(@RequestBody ResiDingAppLoginFormDTO formDTO) { + ValidatorUtils.validateEntity(formDTO,ResiDingAppLoginFormDTO.InnerMiniApp.class); + 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/dto/dingres/DingUserDetailDTO.java b/epmet-auth/src/main/java/com/epmet/dto/dingres/DingUserDetailDTO.java new file mode 100644 index 0000000000..4a46922590 --- /dev/null +++ b/epmet-auth/src/main/java/com/epmet/dto/dingres/DingUserDetailDTO.java @@ -0,0 +1,73 @@ +package com.epmet.dto.dingres; + +import lombok.Data; + +/** + * @Description + * @Author yzm + * @Date 2022/9/22 14:16 + */ +@Data +public class DingUserDetailDTO { + // 接口文档:https://open.dingtalk.com/document/isvapp-server/query-user-details + /** + * 员工的userId。 + */ + private String userid; + + /** + * 员工在当前开发者企业账号范围内的唯一标识。 + */ + private String unionid; + + /** + * 员工姓名。 + */ + private String name; + /** + * 头像。 + *

+ * 说明 员工使用默认头像,不返回该字段,手动设置头像会返回 + */ + private String avatar; + /** + * 国际电话区号。 + *

+ * 说明 第三方企业应用不返回该字段;如需获取state_code,可以使用钉钉统一授权套件方式获取。 + */ + private String state_code; + /** + * 手机号码。 + *

+ * 说明 + * 企业内部应用,只有应用开通通讯录邮箱等个人信息权限,才会返回该字段。 + * 第三方企业应用不返回该字段,如需获取mobile,可以使用钉钉统一授权套件方式获取。 + */ + private String mobile; + /** + * 是否号码隐藏: + *

+ * true:隐藏 + *

+ * false:不隐藏 + *

+ * 说明 隐藏手机号后,手机号在个人资料页隐藏,但仍可对其发DING、发起钉钉免费商务电话。 + */ + private String hide_mobile; + /** + * 分机号。 + *

+ * 说明 第三方企业应用不返回该参数。 + */ + private String telephone; + + /** + * 员工的企业邮箱。 + * + * 如果员工的企业邮箱没有开通,返回信息中不包含该数据。 + * + * 说明 第三方企业应用不返回该参数。 + */ + private String org_email; +} + diff --git a/epmet-auth/src/main/java/com/epmet/dto/dingres/V2UserGetuserinfoResDTO.java b/epmet-auth/src/main/java/com/epmet/dto/dingres/V2UserGetuserinfoResDTO.java new file mode 100644 index 0000000000..ea9eb3b46b --- /dev/null +++ b/epmet-auth/src/main/java/com/epmet/dto/dingres/V2UserGetuserinfoResDTO.java @@ -0,0 +1,54 @@ +package com.epmet.dto.dingres; + +import lombok.Data; + +/** + * @Description + * @Author yzm + * @Date 2022/9/22 14:08 + */ +@Data +public class V2UserGetuserinfoResDTO { + // 接口返参:https://open.dingtalk.com/document/orgapp-server/obtain-the-userid-of-a-user-by-using-the-log-free + /** + * 用户的userid。 + */ + private String userid; + /** + * 设备ID。 + */ + private String device_id; + /** + * 是否是管理员。 + *

+ * true:是 + *

+ * false:不是 + */ + private Boolean sys; + /** + * 级别。 + *

+ * 1:主管理员 + *

+ * 2:子管理员 + *

+ * 100:老板 + *

+ * 0:其他(如普通员工) + */ + private Number sys_level; + /** + * 用户关联的unionId。 + */ + private String associated_unionid; + /** + * 用户unionId。 + */ + private String unionid; + /** + * 用户名字。 + */ + private String name; +} + diff --git a/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginFormDTO.java b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginFormDTO.java new file mode 100644 index 0000000000..b18e95478a --- /dev/null +++ b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginFormDTO.java @@ -0,0 +1,41 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @Description + * @Author yzm + * @Date 2022/9/14 17:11 + */ +@Data +public class ResiDingAppLoginFormDTO { + public interface InnerMiniApp {} + public interface ThirdMiniApp {} + /** + * 授权统一后的authCode + */ + @NotBlank(message = "authCode不能为空",groups = InnerMiniApp.class) + private String authCode; +// /** +// * 第三方企业应用传应用的SuiteKey +// */ +// @NotBlank(message = "clientId不能为空") +// private String clientId; + /** + * 第三方企业应用传应用的SuiteKey + */ + @NotBlank(message = "miniAppId不能为空",groups = InnerMiniApp.class) + private String miniAppId; + + // @NotBlank(message = "当前访问用户的企业corpId不能为空") + // private String corpId; + + /** + * third:第三方应用 + * company_customize:企业定制应用 + */ + private String appType="company_customize"; +} + diff --git a/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginMdFormDTO.java b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginMdFormDTO.java new file mode 100644 index 0000000000..0b3b9ae0f8 --- /dev/null +++ b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginMdFormDTO.java @@ -0,0 +1,23 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @Description + * @Author yzm + * @Date 2022/9/22 10:42 + */ +@Data +public class ResiDingAppLoginMdFormDTO { + @NotBlank(message = "authCode不能为空") + private String authCode; + /** + * 第三方企业应用传应用的SuiteKey + */ + @NotBlank(message = "miniAppId不能为空") + private String miniAppId; + +} + diff --git a/epmet-auth/src/main/java/com/epmet/dto/result/ResiDingAppLoginResDTO.java b/epmet-auth/src/main/java/com/epmet/dto/result/ResiDingAppLoginResDTO.java new file mode 100644 index 0000000000..7a0517574a --- /dev/null +++ b/epmet-auth/src/main/java/com/epmet/dto/result/ResiDingAppLoginResDTO.java @@ -0,0 +1,42 @@ +package com.epmet.dto.result; + +import lombok.Data; + +/** + * @Description + * @Author yzm + * @Date 2022/9/14 17:20 + */ +@Data +public class ResiDingAppLoginResDTO { + private String authorization; + private String customerId; + private String gridId; + /** + * 网格名 + */ + private String gridName; + /** + * 网格所属的组织id + */ + private String agencyId; + /** + * 居民端用户id + */ + private String epmetUserId; + + /** + * 5.获取用户手机号。使用用户个人access_token调用获取用户通讯录个人信息接口获取 + * 返参信息 + * 接口文档:https://open.dingtalk.com/document/isvapp-server/dingtalk-retrieve-user-information + */ + private String extInfo; + + /** + * 是否注册居民 + * true:已注册 + * false:未注册 + */ + private Boolean regFlag; +} + 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 69d13bf926..70bcc92338 100644 --- a/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java +++ b/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java @@ -1,6 +1,7 @@ package com.epmet.service; import com.epmet.dto.form.*; +import com.epmet.dto.result.ResiDingAppLoginResDTO; import com.epmet.dto.result.StaffOrgsResultDTO; import com.epmet.dto.result.UserTokenResultDTO; @@ -84,4 +85,29 @@ public interface ThirdLoginService { * @description 单客户-工作端微信小程序登录-发送验证码 **/ void sendSmsCode(ThirdSendSmsCodeFormDTO formDTO); + + /** + * 钉钉应用的登录-居民端 + * 产品服务商建立第三方企业应用 + * 参考文档: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 cd1495ddb2..91812aaeda 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 @@ -5,15 +5,21 @@ 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.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; @@ -23,6 +29,8 @@ 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; @@ -32,6 +40,11 @@ import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; import com.epmet.redis.CaptchaRedis; 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; @@ -73,6 +86,10 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol private EpmetMessageOpenFeignClient messageOpenFeignClient; @Autowired private LoginUserUtil loginUserUtil; + @Autowired + private DingTalkClientToken dingTalkClientToken; + @Autowired + private DingTalkClientUser dingTalkClientUser; /** * @param formDTO @@ -815,4 +832,297 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol //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; + } + + @Override + public ResiDingAppLoginResDTO resiLoginDingMd(ResiDingAppLoginMdFormDTO 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(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", 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; + } + + /** + * 最原始的企业内部应用开发,不授权给产品服务商 + * @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; + } } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/AppClientConstant.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/AppClientConstant.java index 0b42461f6e..049f335aa4 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/AppClientConstant.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/AppClientConstant.java @@ -32,6 +32,11 @@ public interface AppClientConstant { */ String CLIENT_WXMP = "wxmp"; + /** + * 钉钉小程序 + */ + String MINI_DING = "mini_ding"; + /** * 客户来源App * */ diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/DingMiniInfoFormDTO.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/DingMiniInfoFormDTO.java new file mode 100644 index 0000000000..bd36526985 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/DingMiniInfoFormDTO.java @@ -0,0 +1,26 @@ +package com.epmet.commons.tools.dto.form; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * @Author zxc + * @DateTime 2022/9/15 10:25 + * @DESC + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DingMiniInfoFormDTO implements Serializable { + + private static final long serialVersionUID = 2661531490851265637L; + + public interface DingMiniInfoForm{} + + @NotBlank(message = "miniAppId不能为空",groups = DingMiniInfoForm.class) + private String miniAppId; +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/enums/DingMiniAppEnum.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/enums/DingMiniAppEnum.java new file mode 100644 index 0000000000..b0c0054ebb --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/enums/DingMiniAppEnum.java @@ -0,0 +1,79 @@ +package com.epmet.commons.tools.enums; + +/** + * @Description + * @Author yzm + * @Date 2022/9/14 19:11 + */ +public enum DingMiniAppEnum { + // 亿联云盘CorpId:dingd1e19e397c754c7735c2f4657eb6378f + // + // //各应用秘钥 + // 随手拍 + // SuiteId:27501006 + // AppId:119450 + // MiniAppId:5000000002934668 + // SuiteKey:suitew6ccvkquinmrghqy + // SuiteSecret:TooAxiegdsE5BPP6xo1AxK1LdmaUoMpPMyomOcGcBSXtnsxRc8dEfyOlG56oSmEB + // + // 随时讲 + // SuiteId:27564007 + // AppId:119451 + // MiniAppId:5000000002934374 + // SuiteKey:suitezhyj12glsrp8em0f + // SuiteSecret:-z5Q_lvMP6l7fTzlArEzUT8D_-5pvqBQaJMuTGHoXnz0nuiqGQMZ8aeya_cxTsN- + // + // 我的报事 + // SuiteId:27569006 + // AppId:119452 + // MiniAppId:5000000002934456 + // SuiteKey:suite5yxliro6wawv514w + // SuiteSecret:aQxiPi7DwJSUa9HlbUU_L7Q4wGCLEDmgf__Ffx75cTn3jZwuHy9vdl-9Iv5FeyJU + // + // 实时动态 + // SuiteId:27458011 + // AppId:119453 + // MiniAppId:5000000002934488 + // SuiteKey:suitemcestnonr6y0xigc + // SuiteSecret:kKCNCkfDhmLoVnl_wuAiScyDG4776mkTevuSBuiYhHg-Bvz1-vhb_4IA-Km7nK2I + SSP("suitew6ccvkquinmrghqy", "随手拍", "TooAxiegdsE5BPP6xo1AxK1LdmaUoMpPMyomOcGcBSXtnsxRc8dEfyOlG56oSmEB"), + SSJ("suitezhyj12glsrp8em0f", "随时讲", "-z5Q_lvMP6l7fTzlArEzUT8D_-5pvqBQaJMuTGHoXnz0nuiqGQMZ8aeya_cxTsN-"), + MY_REPORT_EVENT("suite5yxliro6wawv514w", "我的报事", "aQxiPi7DwJSUa9HlbUU_L7Q4wGCLEDmgf__Ffx75cTn3jZwuHy9vdl-9Iv5FeyJU"), + SSDT("suitemcestnonr6y0xigc", "实时动态", "kKCNCkfDhmLoVnl_wuAiScyDG4776mkTevuSBuiYhHg-Bvz1-vhb_4IA-Km7nK2I"); + + private String suiteKey; + private String name; + private String suiteSecret; + + + DingMiniAppEnum(String suiteKey, String name, String suiteSecret) { + this.suiteKey = suiteKey; + this.name = name; + this.suiteSecret = suiteSecret; + } + + public static DingMiniAppEnum getEnum(String suiteKey) { + DingMiniAppEnum[] values = DingMiniAppEnum.values(); + for (DingMiniAppEnum value : values) { + if (value.getSuiteKey().equals(suiteKey)) { + return value; + } + } + return null; + } + + + public String getSuiteKey() { + return suiteKey; + } + + public String getName() { + return name; + } + + public String getSuiteSecret() { + return suiteSecret; + } + +} + diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonThirdFeignClient.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonThirdFeignClient.java new file mode 100644 index 0000000000..6bc986aca0 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonThirdFeignClient.java @@ -0,0 +1,24 @@ +package com.epmet.commons.tools.feign; + +import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; +import com.epmet.commons.tools.feign.fallback.CommonThirdFeignClientFallBackFactory; +import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; +import com.epmet.commons.tools.utils.Result; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + + +/** + * @Description + * @Author zxc + */ +@FeignClient(name = ServiceConstant.EPMET_THIRD_SERVER, fallbackFactory = CommonThirdFeignClientFallBackFactory.class) +// @FeignClient(name = ServiceConstant.EPMET_THIRD_SERVER, fallbackFactory = CommonAggFeignClientFallBackFactory.class,url = "localhost:8110") +public interface CommonThirdFeignClient { + + @PostMapping("/third/dingTalk/getDingMiniInfo") + Result getDingMiniInfo(@RequestBody DingMiniInfoFormDTO formDTO); + +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonThirdFeignClientFallBackFactory.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonThirdFeignClientFallBackFactory.java new file mode 100644 index 0000000000..4a43935086 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonThirdFeignClientFallBackFactory.java @@ -0,0 +1,20 @@ +package com.epmet.commons.tools.feign.fallback; + +import com.epmet.commons.tools.exception.ExceptionUtils; +import com.epmet.commons.tools.feign.CommonThirdFeignClient; +import feign.hystrix.FallbackFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class CommonThirdFeignClientFallBackFactory implements FallbackFactory { + + private CommonThirdFeignClientFallback fallback = new CommonThirdFeignClientFallback(); + + @Override + public CommonThirdFeignClient create(Throwable cause) { + log.error(String.format("FeignClient调用发生异常,异常信息:%s", ExceptionUtils.getThrowableErrorStackTrace(cause))); + return fallback; + } +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonThirdFeignClientFallback.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonThirdFeignClientFallback.java new file mode 100644 index 0000000000..47e278f846 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonThirdFeignClientFallback.java @@ -0,0 +1,24 @@ +package com.epmet.commons.tools.feign.fallback; + +import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; +import com.epmet.commons.tools.feign.CommonThirdFeignClient; +import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; +import com.epmet.commons.tools.utils.ModuleUtils; +import com.epmet.commons.tools.utils.Result; +import org.springframework.stereotype.Component; + +/** + * + * @Author zxc + * @Description + * @Date + **/ +@Component +public class CommonThirdFeignClientFallback implements CommonThirdFeignClient { + + @Override + public Result getDingMiniInfo(DingMiniInfoFormDTO formDTO) { + return ModuleUtils.feignConError(ServiceConstant.EPMET_THIRD_SERVER, "getDingMiniInfo", formDTO); + } +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java index bb7edb3e2a..ac55205beb 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java @@ -104,6 +104,10 @@ public class RedisKeys { return rootPrefix.concat("sys:security:user:").concat(app).concat(StrConstant.COLON).concat(client).concat(StrConstant.COLON).concat(userId); } + public static String getCpUserKeyForDingApp(String suiteKey,String app, String client, String userId) { + return rootPrefix.concat("sys:security:user:").concat(app).concat(StrConstant.COLON).concat(client).concat(StrConstant.COLON).concat(suiteKey).concat(StrConstant.COLON).concat(userId); + } + /** * 拼接手机验证码key---后面需要改!!! * @@ -871,4 +875,18 @@ public class RedisKeys { public static String getDhToken() { return rootPrefix.concat("dh:token"); } + + /** + * Desc: 票据 + * @param suiteKey + * @author zxc + * @date 2022/9/14 10:46 + */ + public static String getSuiteTicketKey(String suiteKey) { + return rootPrefix.concat("ding:suiteTicket:" + suiteKey); + } + + public static String getDingMiniInfoKey(String suiteKey) { + return rootPrefix.concat("ding:miniInfo:" + suiteKey); + } } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/CustomerDingDingRedis.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/CustomerDingDingRedis.java new file mode 100644 index 0000000000..8a57fb1ca7 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/CustomerDingDingRedis.java @@ -0,0 +1,58 @@ +package com.epmet.commons.tools.redis.common; + +import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; +import com.epmet.commons.tools.exception.EpmetException; +import com.epmet.commons.tools.feign.CommonThirdFeignClient; +import com.epmet.commons.tools.redis.RedisKeys; +import com.epmet.commons.tools.redis.RedisUtils; +import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; +import com.epmet.commons.tools.utils.ConvertUtils; +import com.epmet.commons.tools.utils.Result; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.PostConstruct; +import java.util.Map; + +/** + * @Author zxc + * @DateTime 2022/9/15 10:01 + * @DESC + */ +@Slf4j +@Component +public class CustomerDingDingRedis { + + @Autowired + private CommonThirdFeignClient thirdFeignClient; + @Autowired + private RedisUtils redisUtils; + + private static CustomerDingDingRedis customerDingDingRedis; + + @PostConstruct + public void init() { + customerDingDingRedis = this; + customerDingDingRedis.thirdFeignClient = this.thirdFeignClient; + customerDingDingRedis.redisUtils = this.redisUtils; + } + + public static DingMiniInfoCache getDingMiniInfo(String miniAppId){ + String key = RedisKeys.getDingMiniInfoKey(miniAppId); + Map miniInfoMap = customerDingDingRedis.redisUtils.hGetAll(key); + if (!CollectionUtils.isEmpty(miniInfoMap)){ + return ConvertUtils.mapToEntity(miniInfoMap,DingMiniInfoCache.class); + } + Result dingMiniInfoResult = customerDingDingRedis.thirdFeignClient.getDingMiniInfo(new DingMiniInfoFormDTO(miniAppId)); + if (!dingMiniInfoResult.success()){ + throw new EpmetException("查询dingMiniInfo失败..."); + } + if (null == dingMiniInfoResult.getData()){ + return null; + } + return dingMiniInfoResult.getData(); + } + +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/DingMiniInfoCache.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/DingMiniInfoCache.java new file mode 100644 index 0000000000..bd656c9a7e --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/DingMiniInfoCache.java @@ -0,0 +1,52 @@ +package com.epmet.commons.tools.redis.common.bean; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author zxc + * @DateTime 2022/9/15 10:11 + * @DESC + */ +@Data +public class DingMiniInfoCache implements Serializable { + + private static final long serialVersionUID = -6956910978074595334L; + + private String id; + + /** + * + */ + private String suiteId; + + /** + * + */ + private String appId; + + /** + * + */ + private String miniAppId; + + /** + * + */ + private String suiteName; + + /** + * + */ + private String suiteKey; + + /** + * + */ + private String suiteSecret; + + private String token; + + private String aesKey; +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/CpUserDetailRedis.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/CpUserDetailRedis.java index 4c0845fc6c..856cb6449d 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/CpUserDetailRedis.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/CpUserDetailRedis.java @@ -41,6 +41,15 @@ public class CpUserDetailRedis { redisUtils.hMSet(key, map, expire); } + public void setForDingApp(String suiteKey,TokenDto user, long expire) { + if (user == null) { + return; + } + String key = RedisKeys.getCpUserKeyForDingApp(suiteKey,user.getApp(), user.getClient(), user.getUserId()); + //bean to map + Map map = BeanUtil.beanToMap(user, false, true); + redisUtils.hMSet(key, map, expire); + } /** * 获取token信息 * diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/NameUtils.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/NameUtils.java new file mode 100644 index 0000000000..8dec710c4a --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/NameUtils.java @@ -0,0 +1,89 @@ +package com.epmet.commons.tools.utils; + +import com.epmet.commons.tools.constant.NumConstant; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Description + * @Author zhaoqifeng + * @Date 2022/9/14 14:40 + */ +public class NameUtils { + /** + * 复姓(两字),国内现存81个。末尾添加三字以上的部分满姓 + */ + private static final String[] SURNAME_NOW = {"百里", "北堂", "北野", "北宫", "辟闾", "孛尔", "淳于", "成公", "陈生", "褚师", + "端木", "东方", "东郭", "东野", "东门", "第五", "大狐", "段干", "段阳", "带曰", "第二", "东宫", "公孙", "公冶", "公羊", + "公良", "公西", "公孟", "高堂", "高阳", "公析", "公肩", "公坚", "郭公", "谷梁", "毌将", "公乘", "毌丘", "公户", "公广", + "公仪", "公祖", "皇甫", "黄龙", "胡母", "何阳", "夹谷", "九方", "即墨", "梁丘", "闾丘", "洛阳", "陵尹", "冷富", "龙丘", + "令狐", "林彭", "南宫", "南郭", "女娲", "南伯", "南容", "南门", "南野", "欧阳", "欧侯", "濮阳", "青阳", "漆雕", "亓官", + "渠丘", "壤驷", "上官", "少室", "少叔", "司徒", "司马", "司空", "司寇", "士孙", "申屠", "申徒", "申鲜", "申叔", "夙沙", + "叔先", "叔仲", "侍其", "叔孙", "澹台", "太史", "太叔", "太公", "屠岸", "唐古", "闻人", "巫马", "微生", "王孙", "无庸", + "夏侯", "西门", "信平", "鲜于", "轩辕", "相里", "新垣", "徐离", "羊舌", "羊角", "延陵", "於陵", "伊祁", "吾丘", "乐正", + "只斤", "诸葛", "颛孙", "仲孙", "仲长", "钟离", "宗政", "主父", "中叔", "左人", "左丘", "宰父", "长儿", "仉督", "单于", + "叱干", "叱利", "车非", "车公", "车侯", "车长", "车绵", "独孤", "大野", "独吉", "达奚", "达官", "达仲", "达品", "哥舒", + "哥夜", "哥翰", "哥汗", "赫连", "呼延", "贺兰", "黑齿", "斛律", "斛粟", "贺若", "贺奴", "贺远", "贺元", "夹谷", "吉胡", + "吉利", "吉家", "可频", "慕容", "万俟", "万红", "万中", "抹捻", "纳兰", "纳西", "纳吉", "纳罕", "纳塞", "纳博", "纳称", + "纳勉", "普周", "仆固", "仆散", "蒲察", "屈突", "屈卢", "钳耳", "是云", "索卢", "厍狄", "拓跋", "同蹄", "秃发", "完颜", + "完明", "完忠", "宇文", "尉迟", "耶律", "耶红", "也先", "耶鲜", "耶闻", "长孙", "长南", "长北", "长西", "长红", "长元", + "长秋", "长寸", "长李", "长云", "萨嘛喇","赫舍里","萨克达","钮祜禄","他塔喇","喜塔腊","库雅喇","瓜尔佳","舒穆禄","索绰络", + "叶赫那拉","依尔觉罗","额尔德特","讷殷富察","叶赫那兰","爱新觉罗","依尔根觉罗"}; + + /** + * 获取复姓,非单字姓氏。未匹配上则依旧返回单字姓氏 + * @param name + * @return + */ + public static String getSurNameComplex(String name){ + for (String s : SURNAME_NOW) { + if (name.startsWith(s)) { + return name.substring(0, s.length()); + } + } + return name.substring(0,1); + } + + /** + * 获取复姓名,去除姓氏后名 + * @param name + * @return + */ + public static String getNameComplex(String name){ + for (String s : SURNAME_NOW) { + if (name.startsWith(s)) { + return name.substring(s.length()); + } + } + return name.substring(1); + } + + /** + * 获取姓氏与姓名
+ * 姓名在两字时,首字为姓。
+ * 姓名大于两字时,优先匹配复姓。
+ * 姓氏未匹配且姓名多于5字时,姓与名均在姓氏中,名为空;少于5字时则采用第一个字为姓。
+ * @param name 姓名 + * @return map类型数据,姓氏为key值“X”,名字为value值“M” + */ + public static Map getSurName(String name) { + Map mapData = new HashMap<>(NumConstant.TWO); + if (name.length() > NumConstant.ZERO && name.length() <= NumConstant.TWO){ + mapData.put("X", name.substring(NumConstant.ZERO, NumConstant.ONE)); + mapData.put("M", name.substring(NumConstant.ONE)); + } else if (name.length() > NumConstant.TWO) { + for (String s : SURNAME_NOW) {//遍历复姓数组 + if (name.startsWith(s)) { + mapData.put("X", s); + mapData.put("M", name.substring(s.length())); + return mapData; + } + } + //姓氏没有匹配时采用第一个字为姓 + mapData.put("X", name.substring(NumConstant.ZERO, NumConstant.ONE)); + mapData.put("M", name.substring(NumConstant.ONE)); + } + return mapData; + } +} diff --git a/epmet-gateway/src/main/resources/bootstrap.yml b/epmet-gateway/src/main/resources/bootstrap.yml index b0b2492d33..bfc3d86130 100644 --- a/epmet-gateway/src/main/resources/bootstrap.yml +++ b/epmet-gateway/src/main/resources/bootstrap.yml @@ -498,6 +498,7 @@ epmet: - /resi/voice/** - /point/** - /heart/** + - /oss/** # 内部认证url白名单(在白名单中的,就不会再校验登录了) internalAuthUrlsWhiteList: diff --git a/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java b/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java index 8946e7e73a..49160b176d 100644 --- a/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java +++ b/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java @@ -10,6 +10,7 @@ package com.epmet.controller; import com.epmet.cloud.CloudStorageConfig; import com.epmet.cloud.OssFactory; +import com.epmet.commons.tools.annotation.LoginUser; import com.epmet.commons.tools.constant.NumConstant; import com.epmet.commons.tools.constant.StrConstant; import com.epmet.commons.tools.exception.EpmetErrorCode; @@ -17,6 +18,7 @@ import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.page.PageData; import com.epmet.commons.tools.redis.RedisKeys; import com.epmet.commons.tools.redis.RedisUtils; +import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.ValidatorUtils; import com.epmet.commons.tools.validator.group.AliyunGroup; @@ -404,8 +406,10 @@ public class OssController { * @date 2021.08.03 16:23 */ @PostMapping("upload-resi-event-file") - public Result uploadResiEventFile(@RequestPart(value = "file") MultipartFile file, @RequestParam("customerId") String customerId) { - + public Result uploadResiEventFile(@LoginUser TokenDto tokenDto, @RequestPart(value = "file") MultipartFile file, @RequestParam(value = "customerId",required = false) String customerId) { + if (StringUtils.isBlank(customerId)){ + customerId = tokenDto.getCustomerId(); + } // 体积限制 int sizeMb = 10; int sizeThreshold = sizeMb * 1024 * 1024; // 大小限制10m diff --git a/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/DingMiniInfoDTO.java b/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/DingMiniInfoDTO.java new file mode 100644 index 0000000000..19ebfacdd9 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/DingMiniInfoDTO.java @@ -0,0 +1,89 @@ +package com.epmet.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * 钉钉小程序信息 + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2022-09-14 + */ +@Data +public class DingMiniInfoDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * + */ + private String suiteId; + + /** + * + */ + private String appId; + + /** + * + */ + private String miniAppId; + + /** + * + */ + private String suiteName; + + /** + * + */ + private String suiteKey; + + /** + * + */ + private String suiteSecret; + + private String token; + + private String aesKey; + + /** + * + */ + private Integer delFlag; + + /** + * 乐观锁 + */ + private Integer revision; + + /** + * 创建人 + */ + private String createdBy; + + /** + * 创建时间 + */ + private Date createdTime; + + /** + * 更新人 + */ + private String updatedBy; + + /** + * 更新时间 + */ + private Date updatedTime; + +} \ No newline at end of file diff --git a/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/OpenSyncBizDataDTO.java b/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/OpenSyncBizDataDTO.java new file mode 100644 index 0000000000..12dac445f0 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/OpenSyncBizDataDTO.java @@ -0,0 +1,99 @@ +package com.epmet.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2022-09-14 + */ +@Data +public class OpenSyncBizDataDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * + */ + private String id; + + /** + * 第三方企业应用的suiteid加下划线0 + */ + private String subscribeId; + + private String suiteKey; + + /** + * 第三方企业应用的corpid + */ + private String corpId; + + /** + * 第三方企业应用的suiteid + */ + private String bizId; + + /** + * 数据为Json格式 + */ + private String bizData; + + /** + * 2:第三方企业应用票据; +4:企业授权变更,包含授权、解除授权、授权变更; +7:第三方企业应用变更,包含停用、启用、删除(删除保留授权); +13:企业用户变更,包含用户添加、修改、删除; +14:企业部门变更,包含部门添加、修改、删除; +15:企业角色变更,包含角色添加、修改、删除; +16:企业变更,包含企业修改、删除; +17:市场订单; +20:企业外部联系人变更,包含添加、修改、删除; +22:ISV自定义审批; +25:家校通讯录1.0(Deprecated)信息变更。家校通讯录升级,请查看家校通讯录2.0数据推送; +32:智能硬件绑定类型; +37:因订单到期或者用户退款等导致的服务关闭,目前仅推送因退款等导致的服务关闭; +50:家校通讯录2.0,部门信息变更; +51:家校通讯录2.0,人员信息变更; +63:应用试用记录回调信息; +66:工作台组件变更回调事件; +67:钉钉假期相关回调事件; +133:CRM客户动态相关数据回调事件; +137:人事平台员工异动V2相关数据回调事件; +139:异步转译通讯录id任务完成通知; +165:人事平台员工档案变动事件相关数据的回调事件; +175:人事解决方案变更事件; + */ + private String bizType; + + /** + * + */ + private Integer delFlag; + + /** + * + */ + private Date createdTime; + + /** + * + */ + private String createdBy; + + /** + * + */ + private Date updatedTime; + + /** + * + */ + private String updatedBy; + +} \ No newline at end of file diff --git a/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/form/ExemptLoginUserDetailFormDTO.java b/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/form/ExemptLoginUserDetailFormDTO.java new file mode 100644 index 0000000000..7e84993d2f --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-client/src/main/java/com/epmet/dto/form/ExemptLoginUserDetailFormDTO.java @@ -0,0 +1,28 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * @Author zxc + * @DateTime 2022/9/14 14:52 + * @DESC + */ +@Data +public class ExemptLoginUserDetailFormDTO implements Serializable { + + private static final long serialVersionUID = -4333806195203619201L; + + public interface ExemptLoginUserDetailForm{} + + @NotBlank(message = "code不能为空",groups = ExemptLoginUserDetailForm.class) + private String code; + + @NotBlank(message = "corpId不能为空",groups = ExemptLoginUserDetailForm.class) + private String corpId; + + @NotBlank(message = "miniAppId不能为空",groups = ExemptLoginUserDetailForm.class) + private String miniAppId; +} diff --git a/epmet-module/epmet-third/epmet-third-server/pom.xml b/epmet-module/epmet-third/epmet-third-server/pom.xml index e991b981f3..a70d2ac789 100644 --- a/epmet-module/epmet-third/epmet-third-server/pom.xml +++ b/epmet-module/epmet-third/epmet-third-server/pom.xml @@ -157,7 +157,16 @@ rocketmq-acl 4.9.2 - + + dingtalk-spring-boot-starter + com.taobao + 1.0.0 + + + commons-codec + commons-codec + 1.15 + @@ -229,7 +238,7 @@ SECfcc020bdc83bb17a2c00f39977b1fbc409ef4188c7beaea11c5caa90eeaf87fd - + diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/EpmetThirdApplication.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/EpmetThirdApplication.java index 3efd642c87..21c518e033 100644 --- a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/EpmetThirdApplication.java +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/EpmetThirdApplication.java @@ -1,6 +1,7 @@ package com.epmet; import com.epmet.mq.properties.RocketMQProperties; +import com.taobao.dingtalk.spring.annotations.EnableDingTalk; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -8,6 +9,7 @@ import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; +@EnableDingTalk @EnableConfigurationProperties(RocketMQProperties.class) @SpringBootApplication @EnableDiscoveryClient diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/controller/dingtalk/CallbackController.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/controller/dingtalk/CallbackController.java new file mode 100644 index 0000000000..8164c4cdbe --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/controller/dingtalk/CallbackController.java @@ -0,0 +1,155 @@ +package com.epmet.controller.dingtalk; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.aliyun.dingtalk.util.DingCallbackCrypto; +import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; +import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; +import com.epmet.commons.tools.utils.Result; +import com.epmet.commons.tools.validator.ValidatorUtils; +import com.epmet.dao.OpenSyncBizDataDao; +import com.epmet.dto.DingMiniInfoDTO; +import com.epmet.dto.form.ExemptLoginUserDetailFormDTO; +import com.epmet.entity.OpenSyncBizDataEntity; +import com.epmet.redis.DingDingCallbackRedis; +import com.epmet.service.DingTalkService; +import com.epmet.service.OpenSyncBizDataService; +import org.apache.commons.collections4.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * ISV 小程序回调信息处理 + */ +@RestController +@RequestMapping("/dingTalk") +public class CallbackController { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + /** + * 创建应用,验证回调URL创建有效事件(第一次保存回调URL之前) + */ + private static final String EVENT_CHECK_CREATE_SUITE_URL = "check_create_suite_url"; + + /** + * 创建应用,验证回调URL变更有效事件(第一次保存回调URL之后) + */ + private static final String EVENT_CHECK_UPADTE_SUITE_URL = "check_update_suite_url"; + + /** + * suite_ticket推送事件 + */ + private static final String EVENT_SUITE_TICKET = "suite_ticket"; + + /** + * 企业授权开通应用事件 + */ + private static final String EVENT_TMP_AUTH_CODE = "tmp_auth_code"; + + private static final String EVENT_SYNC_HTTP_PUSH_HIGH = "SYNC_HTTP_PUSH_HIGH"; + + @Autowired + private OpenSyncBizDataService openSyncBizDataService; + @Autowired + private OpenSyncBizDataDao openSyncBizDataDao; + @Autowired + private DingDingCallbackRedis dingCallbackRedis; + @Autowired + private DingTalkService dingTalkService; + + @PostMapping(value = "dingCallback") + public Object dingCallback( + @RequestParam(value = "signature") String signature, + @RequestParam(value = "timestamp") Long timestamp, + @RequestParam(value = "nonce") String nonce, + @RequestParam(value = "suiteKey") String suiteKey, + @RequestBody(required = false) JSONObject body + ) { + String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body + "suiteKey::"+suiteKey; + try { + log.info("begin callback:" + params); + DingMiniInfoDTO dingMiniInfo = openSyncBizDataDao.getDingMiniInfo(suiteKey); + DingCallbackCrypto dingTalkEncryptor = new DingCallbackCrypto(dingMiniInfo.getToken(), dingMiniInfo.getAesKey(), suiteKey); + + // 从post请求的body中获取回调信息的加密数据进行解密处理 + String encrypt = body.getString("encrypt"); + String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt); + JSONObject callBackContent = JSON.parseObject(plainText); + + log.info("推来的消息体:"+plainText); + + // 根据回调事件类型做不同的业务处理 + String eventType = callBackContent.getString("EventType"); + if (EVENT_CHECK_CREATE_SUITE_URL.equals(eventType)) { + log.info("验证新创建的回调URL有效性: " + plainText); + } else if (EVENT_CHECK_UPADTE_SUITE_URL.equals(eventType)) { + log.info("验证更新回调URL有效性: " + plainText); + } else if (EVENT_SUITE_TICKET.equals(eventType)) { + // suite_ticket用于用签名形式生成accessToken(访问钉钉服务端的凭证),需要保存到应用的db。 + // 钉钉会定期向本callback url推送suite_ticket新值用以提升安全性。 + // 应用在获取到新的时值时,保存db成功后,返回给钉钉success加密串(如本demo的return) + log.info("应用suite_ticket数据推送: " + plainText); + } else if (EVENT_TMP_AUTH_CODE.equals(eventType)) { + // 本事件应用应该异步进行授权开通企业的初始化,目的是尽最大努力快速返回给钉钉服务端。用以提升企业管理员开通应用体验 + // 即使本接口没有收到数据或者收到事件后处理初始化失败都可以后续再用户试用应用时从前端获取到corpId并拉取授权企业信息,进而初始化开通及企业。 + log.info("企业授权开通应用事件: " + plainText); + } else if (EVENT_SYNC_HTTP_PUSH_HIGH.equals(eventType)){ + List> bizData = (List>) callBackContent.get("bizData"); + if (CollectionUtils.isNotEmpty(bizData)){ + List list = new ArrayList<>(); + bizData.forEach(b -> { + OpenSyncBizDataEntity e = new OpenSyncBizDataEntity(); + e.setSuiteKey(suiteKey); + e.setSubscribeId(b.get("subscribe_id").toString()); + e.setCorpId(b.get("corp_id").toString()); + e.setBizId(b.get("biz_id").toString()); + e.setBizData(b.get("biz_data").toString()); + e.setBizType(b.get("biz_type").toString()); + list.add(e); + openSyncBizDataService.delete(e); + if (e.getBizType().equals(NumConstant.TWO_STR)){ + Map ticketMap = JSON.parseObject(e.getBizData(), Map.class); + dingCallbackRedis.set(suiteKey,ticketMap.get("suiteTicket")); + } + }); + openSyncBizDataService.insertBatch(list); + } + } else{ + // 其他类型事件处理 + } + + // 返回success的加密信息表示回调处理成功 + return dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce); + } catch (Exception e) { + //失败的情况,应用的开发者应该通过告警感知,并干预修复 + log.error("process callback fail." + params, e); + return "fail"; + } + } + + @PostMapping("getExemptLoginUserDetail") + public Result getExemptLoginUserDetail(@RequestBody ExemptLoginUserDetailFormDTO formDTO){ + ValidatorUtils.validateEntity(formDTO, ExemptLoginUserDetailFormDTO.ExemptLoginUserDetailForm.class); + return new Result().ok(dingTalkService.getExemptLoginUserDetail(formDTO)); + } + + /** + * Desc: 获取钉钉小程序信息 + * @param formDTO + * @author zxc + * @date 2022/9/15 10:46 + */ + @PostMapping("getDingMiniInfo") + public Result getDingMiniInfo(@RequestBody DingMiniInfoFormDTO formDTO){ + ValidatorUtils.validateEntity(formDTO, DingMiniInfoFormDTO.DingMiniInfoForm.class); + return new Result().ok(dingTalkService.getDingMiniInfo(formDTO)); + } +} diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/dao/OpenSyncBizDataDao.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/dao/OpenSyncBizDataDao.java new file mode 100644 index 0000000000..4737dabf93 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/dao/OpenSyncBizDataDao.java @@ -0,0 +1,29 @@ +package com.epmet.dao; + +import com.epmet.commons.mybatis.dao.BaseDao; +import com.epmet.dto.DingMiniInfoDTO; +import com.epmet.dto.OpenSyncBizDataDTO; +import com.epmet.entity.OpenSyncBizDataEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2022-09-14 + */ +@Mapper +public interface OpenSyncBizDataDao extends BaseDao { + + DingMiniInfoDTO getDingMiniInfo(@Param("suiteKey")String suiteKey); + + DingMiniInfoDTO getDingMiniInfoByAppId(@Param("miniAppId")String miniAppId); + + Integer delOpenSyncData(OpenSyncBizDataEntity e); + + List getOpenSyncData(@Param("suiteKey")String suiteKey, @Param("bizType")String bizType,@Param("corpId")String corpId); + +} \ No newline at end of file diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/entity/OpenSyncBizDataEntity.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/entity/OpenSyncBizDataEntity.java new file mode 100644 index 0000000000..b881b457bb --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/entity/OpenSyncBizDataEntity.java @@ -0,0 +1,70 @@ +package com.epmet.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.epmet.commons.mybatis.entity.BaseEpmetEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2022-09-14 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("open_sync_biz_data") +public class OpenSyncBizDataEntity extends BaseEpmetEntity { + + private static final long serialVersionUID = 1L; + + /** + * 第三方企业应用的suiteid加下划线0 + */ + private String subscribeId; + + private String suiteKey; + + /** + * 第三方企业应用的corpid + */ + private String corpId; + + /** + * 第三方企业应用的suiteid + */ + private String bizId; + + /** + * 数据为Json格式 + */ + private String bizData; + + /** + * 2:第三方企业应用票据; +4:企业授权变更,包含授权、解除授权、授权变更; +7:第三方企业应用变更,包含停用、启用、删除(删除保留授权); +13:企业用户变更,包含用户添加、修改、删除; +14:企业部门变更,包含部门添加、修改、删除; +15:企业角色变更,包含角色添加、修改、删除; +16:企业变更,包含企业修改、删除; +17:市场订单; +20:企业外部联系人变更,包含添加、修改、删除; +22:ISV自定义审批; +25:家校通讯录1.0(Deprecated)信息变更。家校通讯录升级,请查看家校通讯录2.0数据推送; +32:智能硬件绑定类型; +37:因订单到期或者用户退款等导致的服务关闭,目前仅推送因退款等导致的服务关闭; +50:家校通讯录2.0,部门信息变更; +51:家校通讯录2.0,人员信息变更; +63:应用试用记录回调信息; +66:工作台组件变更回调事件; +67:钉钉假期相关回调事件; +133:CRM客户动态相关数据回调事件; +137:人事平台员工异动V2相关数据回调事件; +139:异步转译通讯录id任务完成通知; +165:人事平台员工档案变动事件相关数据的回调事件; +175:人事解决方案变更事件; + */ + private String bizType; + +} diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/redis/DingDingCallbackRedis.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/redis/DingDingCallbackRedis.java new file mode 100644 index 0000000000..c6b02998f9 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/redis/DingDingCallbackRedis.java @@ -0,0 +1,46 @@ +package com.epmet.redis; + +import com.alibaba.fastjson.JSON; +import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.exception.EpmetException; +import com.epmet.commons.tools.redis.RedisKeys; +import com.epmet.commons.tools.redis.RedisUtils; +import com.epmet.dao.OpenSyncBizDataDao; +import com.epmet.dto.OpenSyncBizDataDTO; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +/** + * @Author zxc + * @DateTime 2022/9/14 10:32 + * @DESC + */ +@Component +public class DingDingCallbackRedis { + @Autowired + private RedisUtils redisUtils; + @Autowired + private OpenSyncBizDataDao openSyncBizDataDao; + + public void set(String suiteKey,String suiteTicket){ + String key = RedisKeys.getSuiteTicketKey(suiteKey); + redisUtils.set(key,suiteTicket,-1); + } + + public String get(String suiteKey){ + String ticket = redisUtils.getString(RedisKeys.getSuiteTicketKey(suiteKey)); + if (StringUtils.isNotBlank(ticket)){ + return ticket; + } + List openSyncData = openSyncBizDataDao.getOpenSyncData(suiteKey, NumConstant.TWO_STR, null); + if (null == openSyncData){ + throw new EpmetException("未查询到"+suiteKey+"的ticket"); + } + Map map = JSON.parseObject(openSyncData.get(NumConstant.ZERO).getBizData(), Map.class); + return map.get("suiteTicket").toString(); + } +} diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/DingTalkService.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/DingTalkService.java new file mode 100644 index 0000000000..ca0ba390f8 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/DingTalkService.java @@ -0,0 +1,24 @@ +package com.epmet.service; + +import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; +import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; +import com.epmet.dto.form.ExemptLoginUserDetailFormDTO; + +/** + * @Author zxc + * @DateTime 2022/9/14 14:56 + * @DESC + */ +public interface DingTalkService { + + Object getExemptLoginUserDetail(ExemptLoginUserDetailFormDTO formDTO); + + /** + * Desc: 获取钉钉小程序信息 + * @param formDTO + * @author zxc + * @date 2022/9/15 10:46 + */ + DingMiniInfoCache getDingMiniInfo(DingMiniInfoFormDTO formDTO); + +} diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/OpenSyncBizDataService.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/OpenSyncBizDataService.java new file mode 100644 index 0000000000..64f3668e38 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/OpenSyncBizDataService.java @@ -0,0 +1,80 @@ +package com.epmet.service; + +import com.epmet.commons.mybatis.service.BaseService; +import com.epmet.commons.tools.page.PageData; +import com.epmet.dto.OpenSyncBizDataDTO; +import com.epmet.entity.OpenSyncBizDataEntity; + +import java.util.List; +import java.util.Map; + +/** + * + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2022-09-14 + */ +public interface OpenSyncBizDataService extends BaseService { + + /** + * 默认分页 + * + * @param params + * @return PageData + * @author generator + * @date 2022-09-14 + */ + PageData page(Map params); + + /** + * 默认查询 + * + * @param params + * @return java.util.List + * @author generator + * @date 2022-09-14 + */ + List list(Map params); + + /** + * 单条查询 + * + * @param id + * @return OpenSyncBizDataDTO + * @author generator + * @date 2022-09-14 + */ + OpenSyncBizDataDTO get(String id); + + /** + * 默认保存 + * + * @param dto + * @return void + * @author generator + * @date 2022-09-14 + */ + void save(OpenSyncBizDataDTO dto); + + /** + * 默认更新 + * + * @param dto + * @return void + * @author generator + * @date 2022-09-14 + */ + void update(OpenSyncBizDataDTO dto); + + /** + * 批量删除 + * + * @param ids + * @return void + * @author generator + * @date 2022-09-14 + */ + void delete(String[] ids); + + void delete(OpenSyncBizDataEntity condition); +} \ No newline at end of file diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/impl/DingTalkServiceImpl.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/impl/DingTalkServiceImpl.java new file mode 100644 index 0000000000..ec239a3ee9 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/impl/DingTalkServiceImpl.java @@ -0,0 +1,68 @@ +package com.epmet.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.aliyun.dingtalk.module.DingTalkResult; +import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; +import com.epmet.commons.tools.redis.RedisKeys; +import com.epmet.commons.tools.redis.RedisUtils; +import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; +import com.epmet.commons.tools.utils.ConvertUtils; +import com.epmet.dao.OpenSyncBizDataDao; +import com.epmet.dto.DingMiniInfoDTO; +import com.epmet.dto.form.ExemptLoginUserDetailFormDTO; +import com.epmet.redis.DingDingCallbackRedis; +import com.epmet.service.DingTalkService; +import com.taobao.dingtalk.client.DingTalkClientToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Map; + +/** + * @Author zxc + * @DateTime 2022/9/14 14:57 + * @DESC + */ +@Service +@Slf4j +public class DingTalkServiceImpl implements DingTalkService { + + @Autowired + private DingTalkClientToken dingTalkClientToken; + @Autowired + private OpenSyncBizDataDao openSyncBizDataDao; + @Autowired + private DingDingCallbackRedis dingCallbackRedis; + @Autowired + private RedisUtils redisUtils; + + @Override + public Object getExemptLoginUserDetail(ExemptLoginUserDetailFormDTO formDTO) { + DingMiniInfoDTO dingMiniInfo = openSyncBizDataDao.getDingMiniInfoByAppId(formDTO.getMiniAppId()); + DingTalkResult exemptLoginUserDetail = dingTalkClientToken.getExemptLoginUserDetail(formDTO.getCorpId(), dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret(), dingCallbackRedis.get(dingMiniInfo.getSuiteKey()), formDTO.getCode()); + return exemptLoginUserDetail.getData(); + } + + /** + * Desc: 获取钉钉小程序信息 + * @param formDTO + * @author zxc + * @date 2022/9/15 10:46 + */ + @Override + public DingMiniInfoCache getDingMiniInfo(DingMiniInfoFormDTO formDTO) { + String key = RedisKeys.getDingMiniInfoKey(formDTO.getMiniAppId()); + Map dingMiniInfoMap = redisUtils.hGetAll(key); + if (!CollectionUtils.isEmpty(dingMiniInfoMap)) { + return ConvertUtils.mapToEntity(dingMiniInfoMap,DingMiniInfoCache.class); + } + DingMiniInfoDTO dingMiniInfo = openSyncBizDataDao.getDingMiniInfoByAppId(formDTO.getMiniAppId()); + if (null != dingMiniInfo){ + redisUtils.hMSet(key, BeanUtil.beanToMap(dingMiniInfo)); + return ConvertUtils.sourceToTarget(dingMiniInfo,DingMiniInfoCache.class); + } + return null; + } +} diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/impl/OpenSyncBizDataServiceImpl.java b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/impl/OpenSyncBizDataServiceImpl.java new file mode 100644 index 0000000000..85d508cbe4 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/service/impl/OpenSyncBizDataServiceImpl.java @@ -0,0 +1,88 @@ +package com.epmet.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.epmet.commons.mybatis.service.impl.BaseServiceImpl; +import com.epmet.commons.tools.constant.FieldConstant; +import com.epmet.commons.tools.page.PageData; +import com.epmet.commons.tools.utils.ConvertUtils; +import com.epmet.dao.OpenSyncBizDataDao; +import com.epmet.dto.OpenSyncBizDataDTO; +import com.epmet.entity.OpenSyncBizDataEntity; +import com.epmet.service.OpenSyncBizDataService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2022-09-14 + */ +@Service +public class OpenSyncBizDataServiceImpl extends BaseServiceImpl implements OpenSyncBizDataService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, FieldConstant.CREATED_TIME, false), + getWrapper(params) + ); + return getPageData(page, OpenSyncBizDataDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, OpenSyncBizDataDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String id = (String)params.get(FieldConstant.ID_HUMP); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), FieldConstant.ID, id); + + return wrapper; + } + + @Override + public OpenSyncBizDataDTO get(String id) { + OpenSyncBizDataEntity entity = baseDao.selectById(id); + return ConvertUtils.sourceToTarget(entity, OpenSyncBizDataDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(OpenSyncBizDataDTO dto) { + OpenSyncBizDataEntity entity = ConvertUtils.sourceToTarget(dto, OpenSyncBizDataEntity.class); + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(OpenSyncBizDataDTO dto) { + OpenSyncBizDataEntity entity = ConvertUtils.sourceToTarget(dto, OpenSyncBizDataEntity.class); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String[] ids) { + // 逻辑删除(@TableLogic 注解) + baseDao.deleteBatchIds(Arrays.asList(ids)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(OpenSyncBizDataEntity condition) { + baseDao.delOpenSyncData(condition); + } + +} \ No newline at end of file diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/resources/bootstrap.yml b/epmet-module/epmet-third/epmet-third-server/src/main/resources/bootstrap.yml index 67cbb2570e..225c468573 100644 --- a/epmet-module/epmet-third/epmet-third-server/src/main/resources/bootstrap.yml +++ b/epmet-module/epmet-third/epmet-third-server/src/main/resources/bootstrap.yml @@ -146,6 +146,9 @@ third: - https://epmet-ext10.elinkservice.cn dingTalk: + appKey: dingo53zvltapzrstzbo + appsecret: o1hjFvWKwLG1GIuivX0nbynqFvFDZiI3CoqLyhdZXhghXMEsr34LKCud0Rz2Hd16 + agentid: 1880131092 robot: webHook: @dingTalk.robot.webHook@ secret: @dingTalk.robot.secret@ diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/resources/db/migration/V0.0.14__add_ding_table.sql b/epmet-module/epmet-third/epmet-third-server/src/main/resources/db/migration/V0.0.14__add_ding_table.sql new file mode 100644 index 0000000000..9d13ecb53c --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/resources/db/migration/V0.0.14__add_ding_table.sql @@ -0,0 +1,51 @@ +CREATE TABLE `ding_mini_info` ( + `ID` varchar(64) NOT NULL COMMENT 'ID', + `SUITE_ID` varchar(255) NOT NULL, + `APP_ID` varchar(255) NOT NULL, + `MINI_APP_ID` varchar(255) NOT NULL, + `SUITE_NAME` varchar(255) NOT NULL, + `SUITE_KEY` varchar(255) NOT NULL, + `SUITE_SECRET` varchar(255) NOT NULL, + `TOKEN` varchar(255) NOT NULL, + `AES_KEY` varchar(255) DEFAULT NULL, + `DEL_FLAG` int(11) NOT NULL, + `REVISION` int(11) NOT NULL COMMENT '乐观锁', + `CREATED_BY` varchar(32) NOT NULL COMMENT '创建人', + `CREATED_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATED_BY` varchar(32) NOT NULL COMMENT '更新人', + `UPDATED_TIME` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='钉钉小程序信息'; + +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('1', '1903117866', '119453', '5000000003010492', '随时讲', 'suiter5nqmiwzwq4lodee', 'hHKnno_nGouRjB5LVFn0k11O20CCEhf9gaiErLNN0lKUExe5VzZrB8tN9hdRrhPA', '', '', 0, 0, '授权给亿联科技', '2022-09-14 11:11:13', '授权给亿联科技', '2022-09-14 11:11:13'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('1001', '1905492491', '', '5000000003022462', '随手拍', 'dingu6fdnlcqbyr1fdxu', 'r-Fi8awDyD5rBCPS1NnoBEqkrq0InheNMkc0xAOKvkD0-47oDFiClbJRiFQy-JO1', '', NULL, 0, 0, '烟台企业内部应用', '2022-09-22 16:54:09', '烟台企业内部应用', '2022-09-22 16:54:16'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('1002', '1905441943', '', '5000000003021766', '随时讲', 'dinguizzwnfnvjs6nntz', 'uUqJYGyoOjOBcc1bC5jCD2lipOaUxbrdZyeXSWKq1JfX7tWQYNz6ZfvvybWBENKS', '', NULL, 0, 0, '烟台企业内部应用', '2022-09-22 16:55:25', '烟台企业内部应用', '2022-09-22 16:55:28'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('1003', '1905455843', '', '5000000003022737', '我的报事', 'dingllzzs6g8u7htteg5', 'fjTJe31Ot4FylmO_hWY-aRckikdPKA2u640GjiW68R4JItFG8picnwFd8d9gLFm_', '', NULL, 0, 0, '烟台企业内部应用', '2022-09-22 16:56:29', '烟台企业内部应用', '2022-09-22 16:56:37'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('1004', '1905486539', '', '5000000003022522', '实时动态', 'dingf8hpd485mlgaov7c', 'CmUSLH-M-tDgpwRTmiAXf9p3v-hLZ27J1kscxUg3118EKX4mV-JLJ073PMxC6We1', '', NULL, 0, 0, '烟台企业内部应用', '2022-09-22 16:57:21', '烟台企业内部应用', '2022-09-22 16:57:24'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('2', '1903003033', '', '5000000003009021', '随手拍', 'suite44k7hacfbfx4zazi', 'EtamucmdHdQMe5nM7YW0qwn2b3m6UJXEk3JAr3ICoisZdZdcIBXsFI1uUHf9xUrl', '', '', 0, 0, '授权给亿联科技', '2022-09-14 11:11:13', '授权给亿联科技', '2022-09-14 11:11:13'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('27805834197073948', '27501006', '119450', '5000000002934668', '随手拍', 'suitew6ccvkquinmrghqy', 'TooAxiegdsE5BPP6xo1AxK1LdmaUoMpPMyomOcGcBSXtnsxRc8dEfyOlG56oSmEB', 'qN6Mg1XljdeHzVg2KeZGmBgY5', 'CzBxlN3uVCo6S3AzB8gfkUMBQxYsrRUdXRqX4XcYcyw', 0, 0, '亿联第三方企业应用', '2022-09-14 11:09:15', '亿联第三方企业应用', '2022-09-14 11:09:15'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('27805834197073949', '27501007', '119451', '5000000002934374', '随时讲', 'suitezhyj12glsrp8em0f', '-z5Q_lvMP6l7fTzlArEzUT8D_-5pvqBQaJMuTGHoXnz0nuiqGQMZ8aeya_cxTsN-', 'rKs2lIN1Oe6K34AtASGOQDh', 'a7hsIIHVTiIB7SQwOiGNgxVo7zAigGUk4InTUNIikWy', 0, 0, '亿联第三方企业应用', '2022-09-14 11:11:13', '亿联第三方企业应用', '2022-09-14 11:11:13'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('27805834197073950', '27501008', '119452', '5000000002934456', '我的报事', 'suite5yxliro6wawv514w', 'aQxiPi7DwJSUa9HlbUU_L7Q4wGCLEDmgf__Ffx75cTn3jZwuHy9vdl-9Iv5FeyJU', 'vTUvaf6QtOJZsa1h7Wkoteo', 'csRpvVFGL7Cf1N9ubajix8tDWhCllROhaxCHKFnbuAz', 0, 0, '亿联第三方企业应用', '2022-09-14 11:11:13', '亿联第三方企业应用', '2022-09-14 11:11:13'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('27805834197073951', '27501009', '119453', '5000000002934488', '实时动态', 'suitemcestnonr6y0xigc', 'kKCNCkfDhmLoVnl_wuAiScyDG4776mkTevuSBuiYhHg-Bvz1-vhb_4IA-Km7nK2I', 'MvWLkZGbC', 'iSVLw69AeNXS8jgGefTG2ulkKWDQjcSsMBgkFMgfPuB', 0, 0, '亿联第三方企业应用', '2022-09-14 11:11:13', '亿联第三方企业应用', '2022-09-14 11:11:13'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('3', '1903155647', '', '5000000003010470', '我的报事', 'suitedwccu2wbepxvdebi', 'OHbAMPBzPWnTL-VqPuJ4ngnwBGLVoxKkkl12uY1CPvIhfX0NqcNJMGl21gQqNpd2', '', '', 0, 0, '授权给亿联科技', '2022-09-14 11:11:13', '授权给亿联科技', '2022-09-14 11:11:13'); +INSERT INTO `epmet_third`.`ding_mini_info` (`ID`, `SUITE_ID`, `APP_ID`, `MINI_APP_ID`, `SUITE_NAME`, `SUITE_KEY`, `SUITE_SECRET`, `TOKEN`, `AES_KEY`, `DEL_FLAG`, `REVISION`, `CREATED_BY`, `CREATED_TIME`, `UPDATED_BY`, `UPDATED_TIME`) VALUES ('4', '1903147702', '', '5000000003010661', '实时动态', 'suitekcbekxzjnlrlgft2', 'fMKaF1UsORAftH7LdqR-CpHOCLzA56Q8S5WN6fRAOAI7E7T-p-96SspOyc-8CdnO', '', '', 0, 0, '授权给亿联科技', '2022-09-14 11:11:13', '授权给亿联科技', '2022-09-14 11:11:13'); + + +CREATE TABLE `open_sync_biz_data` +( + `ID` varchar(255) NOT NULL, + `SUITE_KEY` varchar(255) DEFAULT NULL, + `SUBSCRIBE_ID` varchar(255) NOT NULL COMMENT '第三方企业应用的suiteid加下划线0', + `CORP_ID` varchar(255) NOT NULL COMMENT '第三方企业应用的corpid', + `BIZ_ID` varchar(255) NOT NULL COMMENT '第三方企业应用的suiteid', + `BIZ_DATA` json NOT NULL COMMENT '数据为Json格式', + `BIZ_TYPE` varchar(10) NOT NULL COMMENT '2:第三方企业应用票据;\n4:企业授权变更,包含授权、解除授权、授权变更;\n7:第三方企业应用变更,包含停用、启用、删除(删除保留授权);\n13:企业用户变更,包含用户添加、修改、删除;\n14:企业部门变更,包含部门添加、修改、删除;\n15:企业角色变更,包含角色添加、修改、删除;\n16:企业变更,包含企业修改、删除;\n17:市场订单;\n20:企业外部联系人变更,包含添加、修改、删除;\n22:ISV自定义审批;\n25:家校通讯录1.0(Deprecated)信息变更。家校通讯录升级,请查看家校通讯录2.0数据推送;\n32:智能硬件绑定类型;\n37:因订单到期或者用户退款等导致的服务关闭,目前仅推送因退款等导致的服务关闭;\n50:家校通讯录2.0,部门信息变更;\n51:家校通讯录2.0,人员信息变更;\n63:应用试用记录回调信息;\n66:工作台组件变更回调事件;\n67:钉钉假期相关回调事件;\n133:CRM客户动态相关数据回调事件;\n137:人事平台员工异动V2相关数据回调事件;\n139:异步转译通讯录id任务完成通知;\n165:人事平台员工档案变动事件相关数据的回调事件;\n175:人事解决方案变更事件;', + `DEL_FLAG` int(1) NOT NULL, + `REVISION` int(1) NOT NULL, + `CREATED_TIME` datetime NOT NULL, + `CREATED_BY` varchar(255) NOT NULL, + `UPDATED_TIME` datetime NOT NULL, + `UPDATED_BY` varchar(255) NOT NULL, + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4; \ No newline at end of file diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/resources/logback-spring.xml b/epmet-module/epmet-third/epmet-third-server/src/main/resources/logback-spring.xml index 31d6de459d..c95ac8b0f3 100644 --- a/epmet-module/epmet-third/epmet-third-server/src/main/resources/logback-spring.xml +++ b/epmet-module/epmet-third/epmet-third-server/src/main/resources/logback-spring.xml @@ -145,6 +145,7 @@ + @@ -158,6 +159,7 @@ + diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/resources/mapper/OpenSyncBizDataDao.xml b/epmet-module/epmet-third/epmet-third-server/src/main/resources/mapper/OpenSyncBizDataDao.xml new file mode 100644 index 0000000000..d6bec2cfa5 --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/resources/mapper/OpenSyncBizDataDao.xml @@ -0,0 +1,30 @@ + + + + + + DELETE + FROM open_sync_biz_data + WHERE biz_id = #{bizId} + AND biz_type = #{bizType} + AND subscribe_id = #{subscribeId} + AND corp_id = #{corpId} + AND DEL_FLAG = 0 + + + + + + diff --git a/epmet-module/epmet-third/epmet-third-server/src/main/test/java/com/epmet/ThirdPlatformTest.java b/epmet-module/epmet-third/epmet-third-server/src/main/test/java/com/epmet/ThirdPlatformTest.java new file mode 100644 index 0000000000..02c064c0de --- /dev/null +++ b/epmet-module/epmet-third/epmet-third-server/src/main/test/java/com/epmet/ThirdPlatformTest.java @@ -0,0 +1,30 @@ +package com.epmet; + +import com.alibaba.fastjson.JSON; +import com.aliyun.dingtalk.module.DingTalkResult; +import com.taobao.dingtalk.client.DingTalkClientToken; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * desc:redisson测试类 + */ +@Slf4j +@RunWith(value = SpringRunner.class) +@SpringBootTest(classes = {EpmetThirdApplication.class}) +public class ThirdPlatformTest { + + + @Autowired + DingTalkClientToken dingTalkClientToken; + + @Test + public void sendText(){ + DingTalkResult appAccessTokenToken = dingTalkClientToken.getAppAccessTokenToken(); + System.out.println("=======:"+JSON.toJSONString(appAccessTokenToken)); + } +} diff --git a/epmet-module/gov-project/gov-project-server/src/main/java/com/epmet/service/impl/IcEventServiceImpl.java b/epmet-module/gov-project/gov-project-server/src/main/java/com/epmet/service/impl/IcEventServiceImpl.java index 6f4d7afe6e..dda3a90647 100644 --- a/epmet-module/gov-project/gov-project-server/src/main/java/com/epmet/service/impl/IcEventServiceImpl.java +++ b/epmet-module/gov-project/gov-project-server/src/main/java/com/epmet/service/impl/IcEventServiceImpl.java @@ -940,7 +940,7 @@ public class IcEventServiceImpl extends BaseServiceImpl dingResiLogin(@RequestBody DingLoginResiFormDTO formDTO); } diff --git a/epmet-user/epmet-user-client/src/main/java/com/epmet/feign/fallback/EpmetUserOpenFeignClientFallback.java b/epmet-user/epmet-user-client/src/main/java/com/epmet/feign/fallback/EpmetUserOpenFeignClientFallback.java index 08b4c30061..5726a772cd 100644 --- a/epmet-user/epmet-user-client/src/main/java/com/epmet/feign/fallback/EpmetUserOpenFeignClientFallback.java +++ b/epmet-user/epmet-user-client/src/main/java/com/epmet/feign/fallback/EpmetUserOpenFeignClientFallback.java @@ -692,4 +692,23 @@ public class EpmetUserOpenFeignClientFallback implements EpmetUserOpenFeignClien public Result updateYlfn() { return ModuleUtils.feignConError(ServiceConstant.EPMET_USER_SERVER, "updateYlfn", null); } + + /** + * 钉钉居民端登录 + * // 接入流程: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 Result dingResiLogin(DingLoginResiFormDTO formDTO) { + return ModuleUtils.feignConError(ServiceConstant.EPMET_USER_SERVER, "dingResiLogin", formDTO); + } } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserConstant.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserConstant.java index b9b1c5c87d..a51390f16f 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserConstant.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserConstant.java @@ -38,6 +38,7 @@ public interface UserConstant { */ String CLIENT_WX = "wxmp"; + /** * 居民角色 */ diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserBaseInfoController.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserBaseInfoController.java index a60efed8cc..edd488e9e4 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserBaseInfoController.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserBaseInfoController.java @@ -31,12 +31,10 @@ import com.epmet.commons.tools.validator.group.UpdateGroup; import com.epmet.dto.RegisterRelationDTO; import com.epmet.dto.UserBaseInfoDTO; import com.epmet.dto.form.CommonUserIdFormDTO; +import com.epmet.dto.form.DingLoginResiFormDTO; import com.epmet.dto.form.IssueInitiatorFormDTO; import com.epmet.dto.form.VolunteerRegResiFormDTO; -import com.epmet.dto.result.CustomerUserDetailResultDTO; -import com.epmet.dto.result.ExtUserInfoResultDTO; -import com.epmet.dto.result.ResiUserBaseInfoResultDTO; -import com.epmet.dto.result.UserBaseInfoResultDTO; +import com.epmet.dto.result.*; import com.epmet.entity.UserBaseInfoEntity; import com.epmet.excel.UserBaseInfoExcel; import com.epmet.service.UserBaseInfoService; @@ -221,5 +219,24 @@ public class UserBaseInfoController { public Result getUserInfo(@PathVariable("userId") String userId){ return new Result().ok(userBaseInfoService.getUserInfo(userId)); } + +// 接入流程: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表记录 + /** + * yapi: http://yapi.elinkservice.cn/project/245/interface/api/8118 + * + * @param formDTO + * @return + */ + @PostMapping("dingResiLogin") + public Result dingResiLogin(@RequestBody DingLoginResiFormDTO formDTO){ + return new Result().ok(userBaseInfoService.dingResiLogin(formDTO)); + } } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserResiInfoController.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserResiInfoController.java index 5f8a5ca171..de6daad253 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserResiInfoController.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/UserResiInfoController.java @@ -29,6 +29,7 @@ import com.epmet.commons.tools.validator.group.DefaultGroup; import com.epmet.commons.tools.validator.group.UpdateGroup; import com.epmet.dto.UserResiInfoDTO; import com.epmet.dto.form.*; +import com.epmet.dto.result.DingAutoRegResDTO; import com.epmet.dto.result.IssueInitiatorResultDTO; import com.epmet.dto.result.StaffAndResiResultDTO; import com.epmet.dto.result.UserResiInfoResultDTO; @@ -243,4 +244,21 @@ public class UserResiInfoController { return new Result>().ok(userResiInfoService.getStaffAndResi(userIds)); } + /** + * 进入网格,自动注册居民 + * + * @Param tokenDto + * @Param userResiInfoDTO + * @Return {@link Result} + * @Author zhaoqifeng + * @Date 2022/9/14 15:34 + */ + @PostMapping("autoreguser-ding") + public Result autoRegister(@LoginUser TokenDto tokenDto, @RequestBody UserResiInfoDTO userResiInfoDTO) { + userResiInfoDTO.setCustomerId(tokenDto.getCustomerId()); + userResiInfoDTO.setUserId(tokenDto.getUserId()); + userResiInfoDTO.setApp(tokenDto.getApp()); + return new Result().ok( userResiInfoService.autoRegister(userResiInfoDTO)); + } + } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/UserBaseInfoDao.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/UserBaseInfoDao.java index ab4ca3ec5c..b415ca67c8 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/UserBaseInfoDao.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/UserBaseInfoDao.java @@ -92,4 +92,6 @@ public interface UserBaseInfoDao extends BaseDao { @Param("excludeUserId")String excludeUserId); String selectIdCard(String userId); + + UserBaseInfoEntity selectUserByMobile(@Param("customerId") String customerId, @Param("mobile")String mobile); } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserBaseInfoService.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserBaseInfoService.java index f66453c243..ccd55f362c 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserBaseInfoService.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserBaseInfoService.java @@ -24,11 +24,9 @@ import com.epmet.commons.tools.utils.Result; import com.epmet.dto.RegisterRelationDTO; import com.epmet.dto.UserBaseInfoDTO; import com.epmet.dto.form.CommonUserIdFormDTO; +import com.epmet.dto.form.DingLoginResiFormDTO; import com.epmet.dto.form.VolunteerRegResiFormDTO; -import com.epmet.dto.result.CustomerUserDetailResultDTO; -import com.epmet.dto.result.ExtUserInfoResultDTO; -import com.epmet.dto.result.ResiUserBaseInfoResultDTO; -import com.epmet.dto.result.UserBaseInfoResultDTO; +import com.epmet.dto.result.*; import com.epmet.entity.UserBaseInfoEntity; import java.util.List; @@ -213,4 +211,13 @@ public interface UserBaseInfoService extends BaseService { * @Date 2022/6/15 16:09 */ ResiUserInfoCache getUserInfo(String userId); + + /** + * 钉钉用户注册 + * @Param formDTO + * @Return {@link DingLoginResiResDTO} + * @Author zhaoqifeng + * @Date 2022/9/15 11:17 + */ + DingLoginResiResDTO dingResiLogin(DingLoginResiFormDTO formDTO); } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserResiInfoService.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserResiInfoService.java index 9e3a9f86fe..d29db102e1 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserResiInfoService.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/UserResiInfoService.java @@ -22,6 +22,7 @@ import com.epmet.commons.tools.page.PageData; import com.epmet.commons.tools.utils.Result; import com.epmet.dto.UserResiInfoDTO; import com.epmet.dto.form.*; +import com.epmet.dto.result.DingAutoRegResDTO; import com.epmet.dto.result.IssueInitiatorResultDTO; import com.epmet.dto.result.StaffAndResiResultDTO; import com.epmet.dto.result.UserResiInfoResultDTO; @@ -213,4 +214,14 @@ public interface UserResiInfoService extends BaseService { */ List getStaffAndResi(List userIds); + /** + * 进入网格,自动注册居民 + * + * @Param userResiInfoDTO + * @Return + * @Author zhaoqifeng + * @Date 2022/9/14 14:19 + */ + DingAutoRegResDTO autoRegister(UserResiInfoDTO userResiInfoDTO); + } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserBaseInfoServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserBaseInfoServiceImpl.java index d039ea0cd4..a328399810 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserBaseInfoServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserBaseInfoServiceImpl.java @@ -18,16 +18,23 @@ package com.epmet.service.impl; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.epmet.commons.mybatis.service.impl.BaseServiceImpl; import com.epmet.commons.tools.constant.AppClientConstant; import com.epmet.commons.tools.constant.FieldConstant; import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.constant.StrConstant; +import com.epmet.commons.tools.exception.EpmetErrorCode; +import com.epmet.commons.tools.exception.EpmetException; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.page.PageData; +import com.epmet.commons.tools.redis.common.CustomerOrgRedis; +import com.epmet.commons.tools.redis.common.bean.GridInfoCache; import com.epmet.commons.tools.redis.common.bean.ResiUserInfoCache; import com.epmet.commons.tools.utils.ConvertUtils; +import com.epmet.commons.tools.utils.NameUtils; import com.epmet.commons.tools.utils.Result; import com.epmet.dao.*; import com.epmet.dto.RegisterRelationDTO; @@ -35,10 +42,13 @@ import com.epmet.dto.UserBaseInfoDTO; import com.epmet.dto.UserResiInfoDTO; import com.epmet.dto.UserWechatDTO; import com.epmet.dto.form.CommonUserIdFormDTO; +import com.epmet.dto.form.DingLoginResiFormDTO; import com.epmet.dto.form.UserRoleFormDTO; import com.epmet.dto.form.VolunteerRegResiFormDTO; import com.epmet.dto.result.*; +import com.epmet.entity.RegisterRelationEntity; import com.epmet.entity.UserBaseInfoEntity; +import com.epmet.entity.UserEntity; import com.epmet.entity.UserWechatEntity; import com.epmet.feign.GovOrgOpenFeignClient; import com.epmet.redis.UserBaseInfoRedis; @@ -56,6 +66,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import javax.annotation.Resource; import java.util.*; /** @@ -89,6 +100,8 @@ public class UserBaseInfoServiceImpl extends BaseServiceImpl page(Map params) { @@ -518,4 +531,75 @@ public class UserBaseInfoServiceImpl extends BaseServiceImpl registerWrapper = new LambdaQueryWrapper<>(); + registerWrapper.eq(RegisterRelationEntity::getCustomerId, formDTO.getCustomerId()); + registerWrapper.eq(RegisterRelationEntity::getUserId, baseInfo.getUserId()); + registerWrapper.eq(RegisterRelationEntity::getFirstRegister, NumConstant.ONE_STR); + RegisterRelationEntity registerRelation = registerRelationDao.selectOne(registerWrapper); + if (null != registerRelation) { + result.setAgencyId(registerRelation.getAgencyId()); + result.setGridId(registerRelation.getGridId()); + GridInfoCache gridInfo = CustomerOrgRedis.getGridInfo(registerRelation.getGridId()); + if (null == gridInfo) { + logger.error(String.format("获取用户注册网格信息为空,userId:%s,gridId:%s", baseInfo.getUserId(), registerRelation.getGridId())); + throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取网格信息为空", "获取小程序注册网格信息失败"); + } + result.setGridName(gridInfo.getGridNamePath()); + result.setRegFlag(true); + } + } + return result; + } } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserResiInfoServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserResiInfoServiceImpl.java index 5e7d901f6c..3efd7e01fa 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserResiInfoServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/UserResiInfoServiceImpl.java @@ -18,6 +18,7 @@ package com.epmet.service.impl; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.epmet.common.token.util.UserUtil; @@ -26,30 +27,28 @@ import com.epmet.commons.tools.constant.EpmetRoleKeyConstant; import com.epmet.commons.tools.constant.FieldConstant; import com.epmet.commons.tools.constant.NumConstant; import com.epmet.commons.tools.constant.StrConstant; -import com.epmet.commons.tools.enums.IdCardTypeEnum; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.EpmetException; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.page.PageData; +import com.epmet.commons.tools.redis.common.CustomerOrgRedis; +import com.epmet.commons.tools.redis.common.bean.GridInfoCache; +import com.epmet.commons.tools.redis.common.bean.ResiUserInfoCache; import com.epmet.commons.tools.utils.ConvertUtils; import com.epmet.commons.tools.utils.IdCardRegexUtils; +import com.epmet.commons.tools.utils.NameUtils; import com.epmet.commons.tools.utils.Result; import com.epmet.constant.SmsTemplateConstant; import com.epmet.constant.UserConstant; import com.epmet.constant.UserResiRegisterConstant; import com.epmet.constant.UserRoleConstant; -import com.epmet.dao.UserCustomerDao; -import com.epmet.dao.UserResiInfoDao; -import com.epmet.dao.UserWechatDao; +import com.epmet.dao.*; import com.epmet.dto.UserResiInfoDTO; import com.epmet.dto.UserResiRegisterVisitDTO; import com.epmet.dto.UserRoleDTO; import com.epmet.dto.form.*; import com.epmet.dto.result.*; -import com.epmet.entity.UserBaseInfoEntity; -import com.epmet.entity.UserResiInfoEntity; -import com.epmet.entity.UserResiRegisterVisitEntity; -import com.epmet.entity.UserWechatEntity; +import com.epmet.entity.*; import com.epmet.feign.EpmetMessageOpenFeignClient; import com.epmet.feign.GovIssueOpenFeignClient; import com.epmet.redis.UserBaseInfoRedis; @@ -67,6 +66,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; import java.util.*; /** @@ -103,9 +103,14 @@ public class UserResiInfoServiceImpl extends BaseServiceImpl page(Map params) { @@ -551,6 +556,116 @@ public class UserResiInfoServiceImpl extends BaseServiceImpl registerWrapper = new LambdaQueryWrapper<>(); + registerWrapper.eq(RegisterRelationEntity::getCustomerId, userResiInfoDTO.getCustomerId()); + registerWrapper.eq(RegisterRelationEntity::getUserId, userResiInfoDTO.getUserId()); + registerWrapper.eq(RegisterRelationEntity::getFirstRegister, NumConstant.ONE_STR); + RegisterRelationEntity registerRelation = registerRelationDao.selectOne(registerWrapper); + if (null != registerRelation) { + resDTO.setGridId(registerRelation.getGridId()); + GridInfoCache regGridInfo = CustomerOrgRedis.getGridInfo(registerRelation.getGridId()); + if (null == regGridInfo) { + throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取注册网格信息失败", "获取注册网格信息失败"); + } + resDTO.setGridName(regGridInfo.getGridNamePath()); + resDTO.setAgencyId(regGridInfo.getPid()); + } + } + //6:记录用户访问的网格grid_latest + LambdaQueryWrapper latestWrapper = new LambdaQueryWrapper<>(); + latestWrapper.eq(GridLatestEntity::getCustomerId, userResiInfoDTO.getCustomerId()); + latestWrapper.eq(GridLatestEntity::getGridId, userResiInfoDTO.getGridId()); + latestWrapper.eq(GridLatestEntity::getCustomerUserId, userResiInfoDTO.getUserId()); + GridLatestEntity latest = gridLatestDao.selectOne(latestWrapper); + if (null == latest) { + latest = new GridLatestEntity(); + latest.setCustomerId(userResiInfoDTO.getCustomerId()); + latest.setGridId(userResiInfoDTO.getGridId()); + latest.setCustomerUserId(userResiInfoDTO.getUserId()); + latest.setAreaCode(gridInfo.getAreaCode()); + latest.setPid(gridInfo.getPid()); + latest.setLatestTime(new Date()); + gridLatestDao.insert(latest); + } else { + GridLatestEntity latestEntity = new GridLatestEntity(); + latestEntity.setId(latest.getId()); + latestEntity.setLatestTime(new Date()); + gridLatestDao.updateById(latestEntity); + } + return resDTO; + } /** * 自动认证居民:志愿者注册,自动认证居民 diff --git a/epmet-user/epmet-user-server/src/main/resources/mapper/UserBaseInfoDao.xml b/epmet-user/epmet-user-server/src/main/resources/mapper/UserBaseInfoDao.xml index b8990fe155..c8f4d403a1 100644 --- a/epmet-user/epmet-user-server/src/main/resources/mapper/UserBaseInfoDao.xml +++ b/epmet-user/epmet-user-server/src/main/resources/mapper/UserBaseInfoDao.xml @@ -154,4 +154,17 @@ ubi.USER_ID = #{userId} AND ubi.DEL_FLAG = '0' + + + diff --git a/pom.xml b/pom.xml index 95a3495790..0eb19cb77e 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ com.aliyun alibaba-dingtalk-service-sdk - 1.0.1 + 2.0.0