From e0532a7028d031326a21409494e863d15e053d43 Mon Sep 17 00:00:00 2001
From: wanggeng888 <450292408@qq.com>
Date: Wed, 28 Apr 2021 12:02:39 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BE=AE=E4=BF=A1=E6=A8=A1?=
=?UTF-8?q?=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
module-wechat/pom.xml | 22 ++++++
.../module/wechat/enums/ErrorMsgEnum.java | 50 ++++++++++++
.../OfficialAccountAccessTokenManager.java | 59 ++++++++++++++
.../pojo/OfficialAccountAccessToken.java | 44 +++++++++++
.../account/pojo/OfficialAccountEvent.java | 77 +++++++++++++++++++
.../request/AccessTokenRestTemplate.java | 76 ++++++++++++++++++
.../account/result/AccessTokenResult.java | 35 +++++++++
.../wechat/result/BaseWechatResult.java | 33 ++++++++
.../module/wechat/startup/WechatStartUp.java | 47 +++++++++++
pom.xml | 1 +
10 files changed, 444 insertions(+)
create mode 100644 module-wechat/pom.xml
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/enums/ErrorMsgEnum.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/official/account/manager/OfficialAccountAccessTokenManager.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountAccessToken.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountEvent.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/official/account/request/AccessTokenRestTemplate.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/official/account/result/AccessTokenResult.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/result/BaseWechatResult.java
create mode 100644 module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java
diff --git a/module-wechat/pom.xml b/module-wechat/pom.xml
new file mode 100644
index 00000000..aa0f1b09
--- /dev/null
+++ b/module-wechat/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ wg-basic
+ ink.wgink
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ module-wechat
+
+
+
+ ink.wgink
+ common
+ 1.0-SNAPSHOT
+
+
+
+
\ No newline at end of file
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/enums/ErrorMsgEnum.java b/module-wechat/src/main/java/ink/wgink/module/wechat/enums/ErrorMsgEnum.java
new file mode 100644
index 00000000..675dd7b7
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/enums/ErrorMsgEnum.java
@@ -0,0 +1,50 @@
+package ink.wgink.module.wechat.enums;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: ErrorMsgEnums
+ * @Description:
+ * @Author: wanggeng
+ * @Date: 2021/4/28 6:08 上午
+ * @Version: 1.0
+ */
+public enum ErrorMsgEnum {
+
+ SYSTEM_BUSY(-1, "系统繁忙,此时请开发者稍候再试"),
+ SUCCESS(0, "请求成功"),
+ ERROR_40001(40001, "AppSecret错误或者AppSecret不属于这个公众号,请开发者确认AppSecret的正确性"),
+ ERROR_40002(40002, "请确保grant_type字段值为client_credential"),
+ ERROR_40164(40164, "调用接口的IP地址不在白名单中,请在接口IP白名单中进行设置。(小程序及小游戏调用不要求IP地址在白名单内。)"),
+ ERROR_89503(89503, "此IP调用需要管理员确认,请联系管理员"),
+ ERROR_89501(89501, "此IP正在等待管理员确认,请联系管理员"),
+ ERROR_89506(89506, "24小时内该IP被管理员拒绝调用两次,24小时内不可再使用该IP调用"),
+ ERROR_89507(89507, "1小时内该IP被管理员拒绝调用一次,1小时内不可再使用该IP调用");
+
+ private int errCode;
+ private String errMsg;
+
+ ErrorMsgEnum(int errCode, String errMsg) {
+ this.errCode = errCode;
+ this.errMsg = errMsg;
+ }
+
+ public int getErrCode() {
+ return errCode;
+ }
+
+ public String getErrMsg() {
+ return errMsg == null ? "" : errMsg;
+ }
+
+ public static String getErrMsg(int errCode) {
+ ErrorMsgEnum[] errorMsgEnums = values();
+ for (ErrorMsgEnum errorMsgEnum : errorMsgEnums) {
+ if (errorMsgEnum.errCode == errCode) {
+ return errorMsgEnum.getErrMsg();
+ }
+ }
+ return null;
+ }
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/manager/OfficialAccountAccessTokenManager.java b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/manager/OfficialAccountAccessTokenManager.java
new file mode 100644
index 00000000..a6653980
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/manager/OfficialAccountAccessTokenManager.java
@@ -0,0 +1,59 @@
+package ink.wgink.module.wechat.official.account.manager;
+
+import ink.wgink.module.wechat.official.account.pojo.OfficialAccountAccessToken;
+import ink.wgink.module.wechat.official.account.request.AccessTokenRestTemplate;
+import ink.wgink.properties.wechat.official.account.OfficialAccountProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AccessTokenManager
+ * @Description: access_token控制器
+ * @Author: wanggeng
+ * @Date: 2021/4/27 5:19 下午
+ * @Version: 1.0
+ */
+public class OfficialAccountAccessTokenManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OfficialAccountAccessTokenManager.class);
+ /**
+ * 最大过期毫秒
+ */
+ private static long MAXIMUM_EXPIRE_MILLISECOND = 5400000;
+ private static OfficialAccountAccessTokenManager officialAccountAccessTokenManager = AccessTokenManagerFactory.officialAccountAccessTokenManager;
+ private OfficialAccountAccessToken officialAccountAccessToken;
+
+ private OfficialAccountAccessTokenManager() {
+ }
+
+ public static OfficialAccountAccessTokenManager getInstance() {
+ return officialAccountAccessTokenManager;
+ }
+
+ /**
+ * 刷新access_token
+ */
+ public void refreshAccessToken(OfficialAccountProperties officialAccountProperties) {
+ long currentTime = System.currentTimeMillis();
+ if (officialAccountAccessToken != null && (currentTime - this.officialAccountAccessToken.getLastUpdated()) < MAXIMUM_EXPIRE_MILLISECOND) {
+ return;
+ }
+ LOG.debug("刷新公众号 AccessToken 开始");
+ AccessTokenRestTemplate accessTokenRestTemplate = new AccessTokenRestTemplate(officialAccountProperties);
+ accessTokenRestTemplate.post(officialAccountProperties.getAccessTokenUrl());
+ LOG.debug("accessToken: {}", this.officialAccountAccessToken);
+ LOG.debug("刷新公众号 AccessToken 结束");
+ }
+
+ public void setAccessToken(OfficialAccountAccessToken officialAccountAccessToken) {
+ this.officialAccountAccessToken = officialAccountAccessToken;
+ }
+
+ private static class AccessTokenManagerFactory {
+ public static OfficialAccountAccessTokenManager officialAccountAccessTokenManager = new OfficialAccountAccessTokenManager();
+ }
+
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountAccessToken.java b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountAccessToken.java
new file mode 100644
index 00000000..3b6a3316
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountAccessToken.java
@@ -0,0 +1,44 @@
+package ink.wgink.module.wechat.official.account.pojo;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AccessToken
+ * @Description:
+ * @Author: wanggeng
+ * @Date: 2021/4/28 5:29 上午
+ * @Version: 1.0
+ */
+public class OfficialAccountAccessToken {
+
+ private String accessToken;
+ private long lastUpdated;
+
+ public String getAccessToken() {
+ return accessToken == null ? "" : accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ public long getLastUpdated() {
+ return lastUpdated;
+ }
+
+ public void setLastUpdated(long lastUpdated) {
+ this.lastUpdated = lastUpdated;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"accessToken\":\"")
+ .append(accessToken).append('\"');
+ sb.append(",\"lastUpdated\":")
+ .append(lastUpdated);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountEvent.java b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountEvent.java
new file mode 100644
index 00000000..9a990845
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/pojo/OfficialAccountEvent.java
@@ -0,0 +1,77 @@
+package ink.wgink.module.wechat.official.account.pojo;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AttentionCancel
+ * @Description: 公众号事件
+ * @Author: wanggeng
+ * @Date: 2021/4/28 11:20 上午
+ * @Version: 1.0
+ */
+public class OfficialAccountEvent {
+
+ private String toUserName;
+ private String fromUserName;
+ private String createTime;
+ private String msgType;
+ private String event;
+
+ public String getToUserName() {
+ return toUserName == null ? "" : toUserName;
+ }
+
+ public void setToUserName(String toUserName) {
+ this.toUserName = toUserName;
+ }
+
+ public String getFromUserName() {
+ return fromUserName == null ? "" : fromUserName;
+ }
+
+ public void setFromUserName(String fromUserName) {
+ this.fromUserName = fromUserName;
+ }
+
+ public String getCreateTime() {
+ return createTime == null ? "" : createTime;
+ }
+
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getMsgType() {
+ return msgType == null ? "" : msgType;
+ }
+
+ public void setMsgType(String msgType) {
+ this.msgType = msgType;
+ }
+
+ public String getEvent() {
+ return event == null ? "" : event;
+ }
+
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"toUserName\":\"")
+ .append(toUserName).append('\"');
+ sb.append(",\"fromUserName\":\"")
+ .append(fromUserName).append('\"');
+ sb.append(",\"createTime\":\"")
+ .append(createTime).append('\"');
+ sb.append(",\"msgType\":\"")
+ .append(msgType).append('\"');
+ sb.append(",\"event\":\"")
+ .append(event).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/request/AccessTokenRestTemplate.java b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/request/AccessTokenRestTemplate.java
new file mode 100644
index 00000000..7304ccfc
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/request/AccessTokenRestTemplate.java
@@ -0,0 +1,76 @@
+package ink.wgink.module.wechat.official.account.request;
+
+import ink.wgink.module.wechat.enums.ErrorMsgEnum;
+import ink.wgink.module.wechat.official.account.manager.OfficialAccountAccessTokenManager;
+import ink.wgink.module.wechat.official.account.pojo.OfficialAccountAccessToken;
+import ink.wgink.module.wechat.official.account.result.AccessTokenResult;
+import ink.wgink.properties.wechat.official.account.OfficialAccountProperties;
+import ink.wgink.util.request.AbstractRestTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.client.HttpClientErrorException;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AccessTokenRestTemplate
+ * @Description:
+ * @Author: wanggeng
+ * @Date: 2021/4/28 5:31 上午
+ * @Version: 1.0
+ */
+public class AccessTokenRestTemplate extends AbstractRestTemplate> {
+ private static final Logger LOG = LoggerFactory.getLogger(AccessTokenRestTemplate.class);
+ private OfficialAccountProperties officialAccountProperties;
+
+ public AccessTokenRestTemplate(OfficialAccountProperties officialAccountProperties) {
+ this.officialAccountProperties = officialAccountProperties;
+ }
+
+ @Override
+ public Map postBody() {
+ Map params = new HashMap<>(6);
+ params.put("grant_type", officialAccountProperties.getGrantType());
+ params.put("appid", officialAccountProperties.getAppId());
+ params.put("secret", officialAccountProperties.getAppSecret());
+ return params;
+ }
+
+ @Override
+ public Class successResultType() {
+ return AccessTokenResult.class;
+ }
+
+ @Override
+ public void success200(AccessTokenResult result) {
+ if (result.getErrcode() == ErrorMsgEnum.SUCCESS.getErrCode()) {
+ OfficialAccountAccessToken officialAccountAccessToken = new OfficialAccountAccessToken();
+ officialAccountAccessToken.setAccessToken(result.getAccess_token());
+ officialAccountAccessToken.setLastUpdated(System.currentTimeMillis());
+ OfficialAccountAccessTokenManager.getInstance().setAccessToken(officialAccountAccessToken);
+ return;
+ }
+ if (result.getErrcode() == ErrorMsgEnum.SYSTEM_BUSY.getErrCode()) {
+ LOG.error("系统繁忙,3s后重试");
+ try {
+ TimeUnit.SECONDS.sleep(3);
+ } catch (InterruptedException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ this.post(officialAccountProperties.getAccessTokenUrl());
+ return;
+ }
+ LOG.error(ErrorMsgEnum.getErrMsg(result.getErrcode()));
+ }
+
+ @Override
+ public void error400(HttpClientErrorException error) {
+ LOG.error(error.getMessage(), error);
+ }
+
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/result/AccessTokenResult.java b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/result/AccessTokenResult.java
new file mode 100644
index 00000000..52d5073d
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/official/account/result/AccessTokenResult.java
@@ -0,0 +1,35 @@
+package ink.wgink.module.wechat.official.account.result;
+
+import ink.wgink.module.wechat.result.BaseWechatResult;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AccessTokenResult
+ * @Description:
+ * @Author: wanggeng
+ * @Date: 2021/4/28 6:00 上午
+ * @Version: 1.0
+ */
+public class AccessTokenResult extends BaseWechatResult {
+
+ private String access_token;
+ private Long expires_in;
+
+ public String getAccess_token() {
+ return access_token == null ? "" : access_token;
+ }
+
+ public void setAccess_token(String access_token) {
+ this.access_token = access_token;
+ }
+
+ public Long getExpires_in() {
+ return expires_in == null ? 0 : expires_in;
+ }
+
+ public void setExpires_in(Long expires_in) {
+ this.expires_in = expires_in;
+ }
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/result/BaseWechatResult.java b/module-wechat/src/main/java/ink/wgink/module/wechat/result/BaseWechatResult.java
new file mode 100644
index 00000000..0027b113
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/result/BaseWechatResult.java
@@ -0,0 +1,33 @@
+package ink.wgink.module.wechat.result;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: BaseWechatResult
+ * @Description: 微信基础返回类
+ * @Author: wanggeng
+ * @Date: 2021/4/28 5:59 上午
+ * @Version: 1.0
+ */
+public class BaseWechatResult {
+
+ private Integer errcode;
+ private String errmsg;
+
+ public Integer getErrcode() {
+ return errcode == null ? 0 : errcode;
+ }
+
+ public void setErrcode(Integer errcode) {
+ this.errcode = errcode;
+ }
+
+ public String getErrmsg() {
+ return errmsg == null ? "" : errmsg;
+ }
+
+ public void setErrmsg(String errmsg) {
+ this.errmsg = errmsg;
+ }
+}
diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java b/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java
new file mode 100644
index 00000000..38b79ff8
--- /dev/null
+++ b/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java
@@ -0,0 +1,47 @@
+package ink.wgink.module.wechat.startup;
+
+import ink.wgink.module.wechat.official.account.manager.OfficialAccountAccessTokenManager;
+import ink.wgink.module.wechat.official.account.pojo.OfficialAccountEvent;
+import ink.wgink.properties.wechat.official.account.OfficialAccountProperties;
+import ink.wgink.util.xml.XMLUtil;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: WechatStartUp
+ * @Description: 微信启动
+ * @Author: wanggeng
+ * @Date: 2021/4/28 6:40 上午
+ * @Version: 1.0
+ */
+@Component
+public class WechatStartUp implements ApplicationRunner {
+ @Autowired
+ private OfficialAccountProperties officialAccountProperties;
+
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+
+ }
+
+ @Scheduled(cron = "0 0/5 * * * ? *")
+ public void refreshOfficialAccountAccessToken() {
+ OfficialAccountAccessTokenManager.getInstance().refreshAccessToken(officialAccountProperties);
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 9e5df7a3..aeab9354 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,7 @@
login-wechat
basic-properties
module-article
+ module-wechat
pom