From b237f35fc3185004e08de7848d08539f48691b35 Mon Sep 17 00:00:00 2001 From: "450292408@qq.com" Date: Mon, 31 Aug 2020 22:25:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=92=89=E9=92=89=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud-common-dingding/pom.xml | 30 ++++++ .../properties/DingDingAppProperties.java | 93 +++++++++++++++++++ .../manager/app/DingDingAppManager.java | 91 ++++++++++++++++++ .../service/IDingDingAppUserService.java | 37 ++++++++ .../impl/DingDingAppUserServiceImpl.java | 70 ++++++++++++++ .../dingding/startup/DingDingStartUp.java | 40 ++++++++ .../cm/common/dingding/task/DingDingTask.java | 39 ++++++++ .../DingDingAccessTokenException.java | 35 +++++++ pom.xml | 1 + 9 files changed, 436 insertions(+) create mode 100644 cloud-common-dingding/pom.xml create mode 100644 cloud-common-dingding/src/main/java/com/cm/common/dingding/config/properties/DingDingAppProperties.java create mode 100644 cloud-common-dingding/src/main/java/com/cm/common/dingding/manager/app/DingDingAppManager.java create mode 100644 cloud-common-dingding/src/main/java/com/cm/common/dingding/service/IDingDingAppUserService.java create mode 100644 cloud-common-dingding/src/main/java/com/cm/common/dingding/service/impl/DingDingAppUserServiceImpl.java create mode 100644 cloud-common-dingding/src/main/java/com/cm/common/dingding/startup/DingDingStartUp.java create mode 100644 cloud-common-dingding/src/main/java/com/cm/common/dingding/task/DingDingTask.java create mode 100644 cloud-common/src/main/java/com/cm/common/exception/DingDingAccessTokenException.java diff --git a/cloud-common-dingding/pom.xml b/cloud-common-dingding/pom.xml new file mode 100644 index 0000000..00117e7 --- /dev/null +++ b/cloud-common-dingding/pom.xml @@ -0,0 +1,30 @@ + + + + cm-cloud + com.cm + 1.0.1-SNAPSHOT + + 4.0.0 + + cloud-common-dingding + + + + com.cm + cloud-common + 1.0.1-SNAPSHOT + + + + + com.aliyun + alibaba-dingtalk-service-sdk + 1.0.1 + + + + + \ No newline at end of file diff --git a/cloud-common-dingding/src/main/java/com/cm/common/dingding/config/properties/DingDingAppProperties.java b/cloud-common-dingding/src/main/java/com/cm/common/dingding/config/properties/DingDingAppProperties.java new file mode 100644 index 0000000..e91ca57 --- /dev/null +++ b/cloud-common-dingding/src/main/java/com/cm/common/dingding/config/properties/DingDingAppProperties.java @@ -0,0 +1,93 @@ +package com.cm.common.dingding.config.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: DingDingAppProperties + * @Description: 钉钉小程序配置 + * @Author: WangGeng + * @Date: 2020/8/31 17:45 + * @Version: 1.0 + **/ +@Configuration +@ConfigurationProperties(prefix = "open-platform.dingding.app") +public class DingDingAppProperties { + + private Boolean active; + private String appKey; + private String appSecret; + private String tokenUrl; + private String useridByUnionidUrl; + private String userinfoByIdUrl; + + public Boolean getActive() { + return active; + } + + public void setActive(Boolean active) { + this.active = active; + } + + public String getAppKey() { + return appKey == null ? "" : appKey.trim(); + } + + public void setAppKey(String appKey) { + this.appKey = appKey; + } + + public String getAppSecret() { + return appSecret == null ? "" : appSecret.trim(); + } + + public void setAppSecret(String appSecret) { + this.appSecret = appSecret; + } + + public String getTokenUrl() { + return tokenUrl == null ? "" : tokenUrl.trim(); + } + + public void setTokenUrl(String tokenUrl) { + this.tokenUrl = tokenUrl; + } + + public String getUseridByUnionidUrl() { + return useridByUnionidUrl == null ? "" : useridByUnionidUrl.trim(); + } + + public void setUseridByUnionidUrl(String useridByUnionidUrl) { + this.useridByUnionidUrl = useridByUnionidUrl; + } + + public String getUserinfoByIdUrl() { + return userinfoByIdUrl == null ? "" : userinfoByIdUrl.trim(); + } + + public void setUserinfoByIdUrl(String userinfoByIdUrl) { + this.userinfoByIdUrl = userinfoByIdUrl; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"active\":") + .append(active); + sb.append(",\"appKey\":\"") + .append(appKey).append('\"'); + sb.append(",\"appSecret\":\"") + .append(appSecret).append('\"'); + sb.append(",\"tokenUrl\":\"") + .append(tokenUrl).append('\"'); + sb.append(",\"useridByUnionidUrl\":\"") + .append(useridByUnionidUrl).append('\"'); + sb.append(",\"userinfoByIdUrl\":\"") + .append(userinfoByIdUrl).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-dingding/src/main/java/com/cm/common/dingding/manager/app/DingDingAppManager.java b/cloud-common-dingding/src/main/java/com/cm/common/dingding/manager/app/DingDingAppManager.java new file mode 100644 index 0000000..978b4e1 --- /dev/null +++ b/cloud-common-dingding/src/main/java/com/cm/common/dingding/manager/app/DingDingAppManager.java @@ -0,0 +1,91 @@ +package com.cm.common.dingding.manager.app; + +import com.cm.common.dingding.config.properties.DingDingAppProperties; +import com.cm.common.exception.DingDingAccessTokenException; +import com.cm.common.exception.WechatAccessTokenException; +import com.dingtalk.api.DefaultDingTalkClient; +import com.dingtalk.api.request.OapiGettokenRequest; +import com.dingtalk.api.response.OapiGettokenResponse; +import com.taobao.api.ApiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: DingDingAppManager + * @Description: 钉钉APP管理 + * @Author: WangGeng + * @Date: 2020/8/31 17:56 + * @Version: 1.0 + **/ +public class DingDingAppManager { + private static final Logger LOG = LoggerFactory.getLogger(DingDingAppManager.class); + private static final DingDingAppManager dingDingAppManager = DingDingAppManagerBuilder.dingDingAppManager; + private DingDingAppProperties dingDingAppProperties; + private String accessToken; + private long updateTime = 0L; + + private DingDingAppManager() { + } + + public static DingDingAppManager getInstance() { + return dingDingAppManager; + } + + /** + * 刷新AccessToken,超过1小时30分刷新一次 + */ + public void refreshAccessToken() { + long currentTime = System.currentTimeMillis(); + if ((currentTime - this.updateTime) >= 5400000L) { + LOG.debug("刷新钉钉 App AccessToken 开始"); + this.accessToken = getNewAccessToken(); + LOG.debug("accessToken: {}", this.accessToken); + this.updateTime = System.currentTimeMillis(); + LOG.debug("刷新钉钉 App AccessToken 结束"); + } + } + + /** + * 获取access_token + * + * @return + */ + private String getNewAccessToken() { + DefaultDingTalkClient dingTalkClient = new DefaultDingTalkClient(dingDingAppProperties.getTokenUrl()); + OapiGettokenRequest request = new OapiGettokenRequest(); + request.setAppkey(dingDingAppProperties.getAppKey()); + request.setAppsecret(dingDingAppProperties.getAppSecret()); + request.setHttpMethod("GET"); + try { + OapiGettokenResponse response = dingTalkClient.execute(request); + if (response.getErrcode() != 0) { + throw new DingDingAccessTokenException("获取钉钉AccessToken异常"); + } + return response.getAccessToken(); + } catch (ApiException e) { + LOG.error(e.getMessage(), e); + throw new DingDingAccessTokenException("获取钉钉AccessToken异常"); + } + } + + public String getAccessToken() { + return accessToken == null ? "" : accessToken.trim(); + } + + public void setDingDingAppProperties(DingDingAppProperties dingDingAppProperties) { + this.dingDingAppProperties = dingDingAppProperties; + } + + private static class DingDingAppManagerBuilder { + public static final DingDingAppManager dingDingAppManager = new DingDingAppManager(); + } + +} diff --git a/cloud-common-dingding/src/main/java/com/cm/common/dingding/service/IDingDingAppUserService.java b/cloud-common-dingding/src/main/java/com/cm/common/dingding/service/IDingDingAppUserService.java new file mode 100644 index 0000000..4ff45a2 --- /dev/null +++ b/cloud-common-dingding/src/main/java/com/cm/common/dingding/service/IDingDingAppUserService.java @@ -0,0 +1,37 @@ +package com.cm.common.dingding.service; + +import com.cm.common.exception.SearchException; +import com.dingtalk.api.response.OapiUserGetResponse; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IDingDingUserService + * @Description: 钉钉App用户业务 + * @Author: WangGeng + * @Date: 2020/8/31 20:18 + * @Version: 1.0 + **/ +public interface IDingDingAppUserService { + + /** + * 通过UnionId获取userId + * + * @param unionId + * @return + * @throws SearchException + */ + String getUserIdByUnionId(String unionId) throws SearchException; + + /** + * 通过UserId获取用户详情 + * + * @param userId + * @return + * @throws SearchException + */ + OapiUserGetResponse getUserByUserId(String userId) throws SearchException; + + +} diff --git a/cloud-common-dingding/src/main/java/com/cm/common/dingding/service/impl/DingDingAppUserServiceImpl.java b/cloud-common-dingding/src/main/java/com/cm/common/dingding/service/impl/DingDingAppUserServiceImpl.java new file mode 100644 index 0000000..1cc979c --- /dev/null +++ b/cloud-common-dingding/src/main/java/com/cm/common/dingding/service/impl/DingDingAppUserServiceImpl.java @@ -0,0 +1,70 @@ +package com.cm.common.dingding.service.impl; + +import com.cm.common.base.AbstractService; +import com.cm.common.dingding.config.properties.DingDingAppProperties; +import com.cm.common.dingding.manager.app.DingDingAppManager; +import com.cm.common.dingding.service.IDingDingAppUserService; +import com.cm.common.exception.SearchException; +import com.dingtalk.api.DefaultDingTalkClient; +import com.dingtalk.api.DingTalkClient; +import com.dingtalk.api.request.OapiUserGetRequest; +import com.dingtalk.api.request.OapiUserGetUseridByUnionidRequest; +import com.dingtalk.api.response.OapiUserGetResponse; +import com.dingtalk.api.response.OapiUserGetUseridByUnionidResponse; +import com.taobao.api.ApiException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: DingDingAppUserServiceImpl + * @Description: 钉钉App用户业务 + * @Author: WangGeng + * @Date: 2020/8/31 20:19 + * @Version: 1.0 + **/ +@Service +public class DingDingAppUserServiceImpl extends AbstractService implements IDingDingAppUserService { + + @Autowired + private DingDingAppProperties dingDingAppProperties; + + @Override + public String getUserIdByUnionId(String unionId) throws SearchException { + DingTalkClient dingTalkClient = new DefaultDingTalkClient(dingDingAppProperties.getUseridByUnionidUrl()); + OapiUserGetUseridByUnionidRequest oapiUserGetUseridByUnionidRequest = new OapiUserGetUseridByUnionidRequest(); + oapiUserGetUseridByUnionidRequest.setUnionid(unionId); + oapiUserGetUseridByUnionidRequest.setHttpMethod("GET"); + try { + OapiUserGetUseridByUnionidResponse oapiUserGetUseridByUnionidResponse = dingTalkClient.execute(oapiUserGetUseridByUnionidRequest, DingDingAppManager.getInstance().getAccessToken()); + if (oapiUserGetUseridByUnionidResponse.getErrcode() != 0) { + throw new SearchException(oapiUserGetUseridByUnionidResponse.getErrmsg()); + } + return oapiUserGetUseridByUnionidResponse.getUserid(); + } catch (ApiException e) { + LOG.error(e.getMessage(), e); + throw new SearchException("获取钉钉用户失败"); + } + } + + @Override + public OapiUserGetResponse getUserByUserId(String userId) throws SearchException { + try { + DingTalkClient dingTalkClient = new DefaultDingTalkClient(dingDingAppProperties.getUserinfoByIdUrl()); + OapiUserGetRequest oapiUserGetRequest = new OapiUserGetRequest(); + oapiUserGetRequest.setUserid(userId); + oapiUserGetRequest.setHttpMethod("GET"); + OapiUserGetResponse oapiUserGetResponse = dingTalkClient.execute(oapiUserGetRequest, DingDingAppManager.getInstance().getAccessToken()); + if (oapiUserGetResponse.getErrcode() != 0) { + throw new SearchException(oapiUserGetResponse.getErrmsg()); + } + return oapiUserGetResponse; + } catch (ApiException e) { + LOG.error(e.getMessage(), e); + throw new SearchException("获取钉钉用户详情失败"); + } + } + +} diff --git a/cloud-common-dingding/src/main/java/com/cm/common/dingding/startup/DingDingStartUp.java b/cloud-common-dingding/src/main/java/com/cm/common/dingding/startup/DingDingStartUp.java new file mode 100644 index 0000000..c5fa865 --- /dev/null +++ b/cloud-common-dingding/src/main/java/com/cm/common/dingding/startup/DingDingStartUp.java @@ -0,0 +1,40 @@ +package com.cm.common.dingding.startup; + +import com.cm.common.dingding.config.properties.DingDingAppProperties; +import com.cm.common.dingding.manager.app.DingDingAppManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: DingDingStartUp + * @Description: 钉钉启动 + * @Author: WangGeng + * @Date: 2020/8/31 20:10 + * @Version: 1.0 + **/ +@Configuration +public class DingDingStartUp implements ApplicationRunner { + private static final Logger LOG = LoggerFactory.getLogger(DingDingStartUp.class); + + @Autowired + private DingDingAppProperties dingDingAppProperties; + + @Override + public void run(ApplicationArguments args) throws Exception { + if (dingDingAppProperties.getActive() == null || !dingDingAppProperties.getActive()) { + LOG.debug("钉钉应用未启动"); + return; + } + DingDingAppManager dingDingAppManager = DingDingAppManager.getInstance(); + dingDingAppManager.setDingDingAppProperties(dingDingAppProperties); + dingDingAppManager.refreshAccessToken(); + } +} diff --git a/cloud-common-dingding/src/main/java/com/cm/common/dingding/task/DingDingTask.java b/cloud-common-dingding/src/main/java/com/cm/common/dingding/task/DingDingTask.java new file mode 100644 index 0000000..02ad781 --- /dev/null +++ b/cloud-common-dingding/src/main/java/com/cm/common/dingding/task/DingDingTask.java @@ -0,0 +1,39 @@ +package com.cm.common.dingding.task; + +import com.cm.common.dingding.config.properties.DingDingAppProperties; +import com.cm.common.dingding.manager.app.DingDingAppManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: DingDingTask + * @Description: 钉钉任务 + * @Author: WangGeng + * @Date: 2020/8/31 20:09 + * @Version: 1.0 + **/ +@Configuration +@EnableScheduling +public class DingDingTask { + + private static final Logger LOG = LoggerFactory.getLogger(DingDingTask.class); + @Autowired + private DingDingAppProperties dingDingAppProperties; + + @Scheduled(cron = "0 0/10 * * * ?") + public void refreshAppAccessToken() { + if (dingDingAppProperties.getActive() == null || !dingDingAppProperties.getActive()) { + LOG.debug("钉钉应用未启动"); + return; + } + DingDingAppManager.getInstance().refreshAccessToken(); + } + +} diff --git a/cloud-common/src/main/java/com/cm/common/exception/DingDingAccessTokenException.java b/cloud-common/src/main/java/com/cm/common/exception/DingDingAccessTokenException.java new file mode 100644 index 0000000..ad87c28 --- /dev/null +++ b/cloud-common/src/main/java/com/cm/common/exception/DingDingAccessTokenException.java @@ -0,0 +1,35 @@ +package com.cm.common.exception; + +import com.cm.common.exception.base.SystemException; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: DingDingAccessTokenException + * @Description: 钉钉accessToken异常 + * @Author: WangGeng + * @Date: 2020/8/31 18:16 + * @Version: 1.0 + **/ +public class DingDingAccessTokenException extends SystemException { + + public DingDingAccessTokenException() { + } + + public DingDingAccessTokenException(String message) { + super(message); + } + + public DingDingAccessTokenException(String message, boolean withMsg) { + super(message, withMsg); + } + + public DingDingAccessTokenException(String message, Throwable cause) { + super(message, cause); + } + + public DingDingAccessTokenException(Throwable cause) { + super(cause); + } +} diff --git a/pom.xml b/pom.xml index 342f6b3..bcd4cf1 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,7 @@ cloud-central-control cloud-central-control-client cloud-hardware-smart-gate + cloud-common-dingding pom 成迈云