mj-li 2 months ago
commit
39d81014fe
100 changed files with 3926 additions and 0 deletions
  1. 84 0
      .gitignore
  2. 77 0
      pom.xml
  3. 54 0
      weixin-java-common/pom.xml
  4. 59 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/AesException.java
  5. 26 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/ByteGroup.java
  6. 67 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/PKCS7Encoder.java
  7. 63 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/SHA1.java
  8. 291 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/WXBizMsgCrypt.java
  9. 73 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/XMLParse.java
  10. 46 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/TupConfigModelProperty.java
  11. 27 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/TupConfigParamItemModel.java
  12. 53 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/TupConfigParamItemUtils.java
  13. 20 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxApiConfig.java
  14. 25 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxMpConfig.java
  15. 50 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxWorkConfig.java
  16. 12 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxWorkThirdConfig.java
  17. 45 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/constant/BaseEnum.java
  18. 30 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/constant/WxErrorEnum.java
  19. 7 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/constant/WxHttpMethodEnum.java
  20. 68 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/exception/WxException.java
  21. 58 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/BaseModel.java
  22. 19 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/BaseReqModel.java
  23. 17 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/BaseRespModel.java
  24. 38 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/WxJSSDKSignModel.java
  25. 62 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/AesUtils.java
  26. 28 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/EnumValid.java
  27. 41 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/EnumValidator.java
  28. 55 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/UrlUtils.java
  29. 35 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxCommonUtils.java
  30. 131 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxHttpRequestUtils.java
  31. 43 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxJSSDKSignUtils.java
  32. 29 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxVerificationUtils.java
  33. 54 0
      weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/XmlUtils.java
  34. 41 0
      weixin-java-im/pom.xml
  35. 75 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImAccountAPi.java
  36. 8 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImGroupApi.java
  37. 8 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImMsgApi.java
  38. 34 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImProfileApi.java
  39. 8 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImSnsApi.java
  40. 170 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/enums/WxIMApiType.java
  41. 33 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/enums/WxIMDomain.java
  42. 8 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMBaseModel.java
  43. 19 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMBaseReqModel.java
  44. 19 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMBaseRespModel.java
  45. 40 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMSignModel.java
  46. 19 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountBatchImportModel.java
  47. 17 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountCheckModel.java
  48. 16 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountCheckRespModel.java
  49. 29 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountCheckResultModel.java
  50. 19 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountDeleteItemsModel.java
  51. 16 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountDeleteRespModel.java
  52. 17 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountDeleteResultModel.java
  53. 23 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountImportModel.java
  54. 17 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountKickModel.java
  55. 15 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineDetailsModel.java
  56. 15 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineErrorResultModel.java
  57. 18 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineRespModel.java
  58. 15 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineResultModel.java
  59. 24 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineStatusModel.java
  60. 16 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountUserIdModel.java
  61. 18 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileGetModel.java
  62. 20 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileGetRespModel.java
  63. 15 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileModel.java
  64. 18 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileSetModel.java
  65. 14 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileSetRespModel.java
  66. 21 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/UserProfileModel.java
  67. 130 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/utils/IMWxHttpRequestUtils.java
  68. 38 0
      weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/utils/WxIMUtils.java
  69. 22 0
      weixin-java-mini/pom.xml
  70. 8 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxCodeApi.java
  71. 8 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxDataAnalysisApi.java
  72. 7 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerFollowerApi.java
  73. 8 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerGoodsApi.java
  74. 10 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerRoleApi.java
  75. 12 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerRoomApi.java
  76. 40 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxMessageCustomerApi.java
  77. 34 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxMessageDynamicApi.java
  78. 83 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxMiniApi.java
  79. 47 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/enums/WxMiniApiType.java
  80. 33 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/enums/WxMiniDomain.java
  81. 78 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/enums/WxMiniEnum.java
  82. 26 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/Code2SessionModel.java
  83. 20 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/Code2SessionResp.java
  84. 20 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/DecryptDataModel.java
  85. 18 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/MiniprogramMsgModel.java
  86. 25 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/MpTemplateMsgModel.java
  87. 24 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WeappTemplateMsgModel.java
  88. 17 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WxMiniDataValModel.java
  89. 21 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WxMiniSendMsgModel.java
  90. 28 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WxMpDataValModel.java
  91. 27 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/CreateActivityIdModel.java
  92. 21 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/CreateActivityIdResp.java
  93. 31 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/MediaUploadModel.java
  94. 25 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/MediaUploadResp.java
  95. 112 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/SendToUserModel.java
  96. 29 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/SetMsgTypingModel.java
  97. 47 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/SetUpdatableMsgModel.java
  98. 43 0
      weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/utils/WxMiniUtils.java
  99. 24 0
      weixin-java-mp/pom.xml
  100. 178 0
      weixin-java-mp/src/main/java/com/company/cloud/sdk/weixin/mp/WxMpApi.java

+ 84 - 0
.gitignore

@@ -0,0 +1,84 @@
+# maven output files
+/target/
+*/target/
+**/target/
+
+# virtual machine crash logs
+hs_err_pid*
+/bin/
+/build/
+*/bin/
+*/gen/
+*/out/
+
+# Java class files
+*.class
+
+# Files for the Dalvik VM
+*.dex
+
+#Built application files
+*.apk
+*.ap_
+proguard/
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+# *.jar
+*.war
+*.ear
+
+# Eclipse Project files
+.classpath
+*/.classpath
+**/.classpath
+.project
+*/.project
+**/.project
+.factorypath
+*/.factorypath
+**/.factorypath
+.settings/
+/.settings/
+*/.settings/
+**/.settings/
+*/.apt_generated/
+**/.apt_generated/
+*/.apt_generated_tests/
+**/.apt_generated_tests/
+
+# IntelliJ IDEA Project files
+.idea
+*.iml
+*/*.iml
+**/*.iml
+*.ipr
+*.iws
+out
+*/.DS_Store
+**/.DS_Store
+.DS_Store
+Thumbs.db
+/.idea/
+*/.idea/
+**/.idea/
+.idea/
+
+#gradle wrapper
+gradle/
+/.gradle/
+# Gradle files
+.gradle/
+build/
+*/build/
+**/build/
+gradlew
+gradlew.bat
+
+# Log Files
+*.log
+
+# VSCode
+.vscode

+ 77 - 0
pom.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.company.cloud.sdk</groupId>
+	<artifactId>wx-sdk</artifactId>
+	<version>2.0.0</version>
+	<packaging>pom</packaging>
+	<modules>
+		<module>weixin-java-common</module>
+		<module>weixin-java-work</module>
+		<module>weixin-java-mini</module>
+		<module>weixin-java-mp</module>
+		<module>weixin-java-open</module>
+	</modules>
+
+	<properties>
+		<java.version>1.8</java.version>
+		<weixin-common.version>1.0.0-SNAPSHOT</weixin-common.version>
+		<lombok.version>1.18.12</lombok.version>
+		<hutool.version>5.4.0</hutool.version>
+		<fastjson.version>1.2.73</fastjson.version>
+		<commons-codec.version>1.9</commons-codec.version>
+		<validation-api.version>2.0.1.Final</validation-api.version>
+		<jakarta.validation-api.version>3.0.0</jakarta.validation-api.version>
+	</properties>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.projectlombok</groupId>
+				<artifactId>lombok</artifactId>
+				<version>${lombok.version}</version>
+			</dependency>
+
+			<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
+			<dependency>
+				<groupId>cn.hutool</groupId>
+				<artifactId>hutool-all</artifactId>
+				<version>${hutool.version}</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.alibaba</groupId>
+				<artifactId>fastjson</artifactId>
+				<version>${fastjson.version}</version>
+			</dependency>
+
+			<!-- 使用微信提供的commons-codec -->
+<!--			<dependency>-->
+<!--				<groupId>commons-codec-wechat</groupId>-->
+<!--				<artifactId>commons-codec-wechat</artifactId>-->
+<!--				<version>${commons-codec.version}</version>-->
+<!--			</dependency>-->
+
+			<dependency>
+				<groupId>commons-codec</groupId>
+				<artifactId>commons-codec</artifactId>
+				<version>1.9</version>
+			</dependency>
+
+			<dependency>
+				<groupId>javax.validation</groupId>
+				<artifactId>validation-api</artifactId>
+				<version>${validation-api.version}</version>
+			</dependency>
+
+			<dependency>
+				<groupId>jakarta.validation</groupId>
+				<artifactId>jakarta.validation-api</artifactId>
+				<version>${jakarta.validation-api.version}</version>
+			</dependency>
+
+		</dependencies>
+	</dependencyManagement>
+</project>

+ 54 - 0
weixin-java-common/pom.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.company.cloud.sdk</groupId>
+    <artifactId>wx-sdk</artifactId>
+    <version>2.0.0</version>
+  </parent>
+  <artifactId>weixin-java-common</artifactId>
+  <description>微信基础SDK</description>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>${java.version}</source>
+          <target>${java.version}</target>
+          <encoding>utf8</encoding>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>cn.hutool</groupId>
+      <artifactId>hutool-all</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>fastjson</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 59 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/AesException.java

@@ -0,0 +1,59 @@
+package com.company.cloud.sdk.weixin.common.aes;
+
+@SuppressWarnings("serial")
+public class AesException extends Exception {
+
+	public final static int OK = 0;
+	public final static int ValidateSignatureError = -40001;
+	public final static int ParseXmlError = -40002;
+	public final static int ComputeSignatureError = -40003;
+	public final static int IllegalAesKey = -40004;
+	public final static int ValidateAppidError = -40005;
+	public final static int EncryptAESError = -40006;
+	public final static int DecryptAESError = -40007;
+	public final static int IllegalBuffer = -40008;
+	//public final static int EncodeBase64Error = -40009;
+	//public final static int DecodeBase64Error = -40010;
+	//public final static int GenReturnXmlError = -40011;
+
+	private int code;
+
+	private static String getMessage(int code) {
+		switch (code) {
+		case ValidateSignatureError:
+			return "签名验证错误";
+		case ParseXmlError:
+			return "xml解析失败";
+		case ComputeSignatureError:
+			return "sha加密生成签名失败";
+		case IllegalAesKey:
+			return "SymmetricKey非法";
+		case ValidateAppidError:
+			return "appid校验失败";
+		case EncryptAESError:
+			return "aes加密失败";
+		case DecryptAESError:
+			return "aes解密失败";
+		case IllegalBuffer:
+			return "解密后得到的buffer非法";
+//		case EncodeBase64Error:
+//			return "base64加密错误";
+//		case DecodeBase64Error:
+//			return "base64解密错误";
+//		case GenReturnXmlError:
+//			return "xml生成失败";
+		default:
+			return null; // cannot be
+		}
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	AesException(int code) {
+		super(getMessage(code));
+		this.code = code;
+	}
+
+}

+ 26 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/ByteGroup.java

@@ -0,0 +1,26 @@
+package com.company.cloud.sdk.weixin.common.aes;
+
+import java.util.ArrayList;
+
+class ByteGroup {
+	ArrayList<Byte> byteContainer = new ArrayList<Byte>();
+
+	public byte[] toBytes() {
+		byte[] bytes = new byte[byteContainer.size()];
+		for (int i = 0; i < byteContainer.size(); i++) {
+			bytes[i] = byteContainer.get(i);
+		}
+		return bytes;
+	}
+
+	public ByteGroup addBytes(byte[] bytes) {
+		for (byte b : bytes) {
+			byteContainer.add(b);
+		}
+		return this;
+	}
+
+	public int size() {
+		return byteContainer.size();
+	}
+}

+ 67 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/PKCS7Encoder.java

@@ -0,0 +1,67 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+package com.company.cloud.sdk.weixin.common.aes;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+/**
+ * 提供基于PKCS7算法的加解密接口.
+ */
+class PKCS7Encoder {
+	static Charset CHARSET = Charset.forName("utf-8");
+	static int BLOCK_SIZE = 32;
+
+	/**
+	 * 获得对明文进行补位填充的字节.
+	 * 
+	 * @param count 需要进行填充补位操作的明文字节个数
+	 * @return 补齐用的字节数组
+	 */
+	static byte[] encode(int count) {
+		// 计算需要填充的位数
+		int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
+		if (amountToPad == 0) {
+			amountToPad = BLOCK_SIZE;
+		}
+		// 获得补位所用的字符
+		char padChr = chr(amountToPad);
+		String tmp = new String();
+		for (int index = 0; index < amountToPad; index++) {
+			tmp += padChr;
+		}
+		return tmp.getBytes(CHARSET);
+	}
+
+	/**
+	 * 删除解密后明文的补位字符
+	 * 
+	 * @param decrypted 解密后的明文
+	 * @return 删除补位字符后的明文
+	 */
+	static byte[] decode(byte[] decrypted) {
+		int pad = (int) decrypted[decrypted.length - 1];
+		if (pad < 1 || pad > 32) {
+			pad = 0;
+		}
+		return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
+	}
+
+	/**
+	 * 将数字转化成ASCII码对应的字符,用于对明文进行补码
+	 * 
+	 * @param a 需要转化的数字
+	 * @return 转化得到的字符
+	 */
+	static char chr(int a) {
+		byte target = (byte) (a & 0xFF);
+		return (char) target;
+	}
+
+}

+ 63 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/SHA1.java

@@ -0,0 +1,63 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+package com.company.cloud.sdk.weixin.common.aes;
+
+import com.company.cloud.sdk.weixin.common.aes.AesException;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+/**
+ * SHA1 class
+ *
+ * 计算公众平台的消息签名接口.
+ */
+class SHA1 {
+
+	/**
+	 * 用SHA1算法生成安全签名
+	 * @param token 票据
+	 * @param timestamp 时间戳
+	 * @param nonce 随机字符串
+	 * @param encrypt 密文
+	 * @return 安全签名
+	 * @throws AesException
+	 */
+	public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException
+			  {
+		try {
+			String[] array = new String[] { token, timestamp, nonce, encrypt };
+			StringBuffer sb = new StringBuffer();
+			// 字符串排序
+			Arrays.sort(array);
+			for (int i = 0; i < 4; i++) {
+				sb.append(array[i]);
+			}
+			String str = sb.toString();
+			// SHA1签名生成
+			MessageDigest md = MessageDigest.getInstance("SHA-1");
+			md.update(str.getBytes());
+			byte[] digest = md.digest();
+
+			StringBuffer hexstr = new StringBuffer();
+			String shaHex = "";
+			for (int i = 0; i < digest.length; i++) {
+				shaHex = Integer.toHexString(digest[i] & 0xFF);
+				if (shaHex.length() < 2) {
+					hexstr.append(0);
+				}
+				hexstr.append(shaHex);
+			}
+			return hexstr.toString();
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.ComputeSignatureError);
+		}
+	}
+}

+ 291 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/WXBizMsgCrypt.java

@@ -0,0 +1,291 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ */
+package com.company.cloud.sdk.weixin.common.aes;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+
+import org.apache.commons.codec.binary.Base64;
+
+
+/**
+ * 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
+ * <ol>
+ * 	<li>第三方回复加密消息给公众平台</li>
+ * 	<li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
+ * </ol>
+ * 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
+ * <ol>
+ * 	<li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
+ *      http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
+ * 	<li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
+ * 	<li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
+ * 	<li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
+ * </ol>
+ */
+public class WXBizMsgCrypt {
+	static Charset CHARSET = Charset.forName("utf-8");
+	Base64 base64 = new Base64();
+	byte[] aesKey;
+	String token;
+	String appId;
+
+	/**
+	 * 构造函数
+	 * @param token 公众平台上,开发者设置的token
+	 * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
+	 * @param appId 公众平台appid
+	 * 
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public WXBizMsgCrypt(String token, String encodingAesKey, String appId) throws AesException {
+		if (encodingAesKey.length() != 43) {
+			throw new AesException(AesException.IllegalAesKey);
+		}
+
+		this.token = token;
+		this.appId = appId;
+		aesKey = Base64.decodeBase64(encodingAesKey + "=");
+	}
+
+	// 生成4个字节的网络字节序
+	byte[] getNetworkBytesOrder(int sourceNumber) {
+		byte[] orderBytes = new byte[4];
+		orderBytes[3] = (byte) (sourceNumber & 0xFF);
+		orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
+		orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
+		orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);
+		return orderBytes;
+	}
+
+	// 还原4个字节的网络字节序
+	int recoverNetworkBytesOrder(byte[] orderBytes) {
+		int sourceNumber = 0;
+		for (int i = 0; i < 4; i++) {
+			sourceNumber <<= 8;
+			sourceNumber |= orderBytes[i] & 0xff;
+		}
+		return sourceNumber;
+	}
+
+	// 随机生成16位字符串
+	String getRandomStr() {
+		String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+		Random random = new Random();
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < 16; i++) {
+			int number = random.nextInt(base.length());
+			sb.append(base.charAt(number));
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 对明文进行加密.
+	 * 
+	 * @param text 需要加密的明文
+	 * @return 加密后base64编码的字符串
+	 * @throws AesException aes加密失败
+	 */
+	String encrypt(String randomStr, String text) throws AesException {
+		ByteGroup byteCollector = new ByteGroup();
+		byte[] randomStrBytes = randomStr.getBytes(CHARSET);
+		byte[] textBytes = text.getBytes(CHARSET);
+		byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length);
+		byte[] appidBytes = appId.getBytes(CHARSET);
+
+		// randomStr + networkBytesOrder + text + appid
+		byteCollector.addBytes(randomStrBytes);
+		byteCollector.addBytes(networkBytesOrder);
+		byteCollector.addBytes(textBytes);
+		byteCollector.addBytes(appidBytes);
+
+		// ... + pad: 使用自定义的填充方式对明文进行补位填充
+		byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
+		byteCollector.addBytes(padBytes);
+
+		// 获得最终的字节流, 未加密
+		byte[] unencrypted = byteCollector.toBytes();
+
+		try {
+			// 设置加密模式为AES的CBC模式
+			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+			SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
+			IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
+			cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+
+			// 加密
+			byte[] encrypted = cipher.doFinal(unencrypted);
+
+			// 使用BASE64对加密后的字符串进行编码
+			String base64Encrypted = base64.encodeToString(encrypted);
+
+			return base64Encrypted;
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.EncryptAESError);
+		}
+	}
+
+	/**
+	 * 对密文进行解密.
+	 * 
+	 * @param text 需要解密的密文
+	 * @return 解密得到的明文
+	 * @throws AesException aes解密失败
+	 */
+	String decrypt(String text) throws AesException {
+		byte[] original;
+		try {
+			// 设置解密模式为AES的CBC模式
+			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+			SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
+			IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
+			cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
+
+			// 使用BASE64对密文进行解码
+			byte[] encrypted = Base64.decodeBase64(text);
+
+			// 解密
+			original = cipher.doFinal(encrypted);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.DecryptAESError);
+		}
+
+		String xmlContent, from_appid;
+		try {
+			// 去除补位字符
+			byte[] bytes = PKCS7Encoder.decode(original);
+
+			// 分离16位随机字符串,网络字节序和AppId
+			byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
+
+			int xmlLength = recoverNetworkBytesOrder(networkOrder);
+
+			xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
+			from_appid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
+					CHARSET);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.IllegalBuffer);
+		}
+
+		// appid不相同的情况
+		if (!from_appid.equals(appId)) {
+			throw new AesException(AesException.ValidateAppidError);
+		}
+		return xmlContent;
+
+	}
+
+	/**
+	 * 将公众平台回复用户的消息加密打包.
+	 * <ol>
+	 * 	<li>对要发送的消息进行AES-CBC加密</li>
+	 * 	<li>生成安全签名</li>
+	 * 	<li>将消息密文和安全签名打包成xml格式</li>
+	 * </ol>
+	 * 
+	 * @param replyMsg 公众平台待回复用户的消息,xml格式的字符串
+	 * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
+	 * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce
+	 * 
+	 * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public String encryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {
+		// 加密
+		String encrypt = encrypt(getRandomStr(), replyMsg);
+
+		// 生成安全签名
+		if (timeStamp == "") {
+			timeStamp = Long.toString(System.currentTimeMillis());
+		}
+
+		String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt);
+
+		// System.out.println("发送给平台的签名是: " + signature[1].toString());
+		// 生成发送的xml
+		String result = XMLParse.generate(encrypt, signature, timeStamp, nonce);
+		return result;
+	}
+
+	/**
+	 * 检验消息的真实性,并且获取解密后的明文.
+	 * <ol>
+	 * 	<li>利用收到的密文生成安全签名,进行签名验证</li>
+	 * 	<li>若验证通过,则提取xml中的加密消息</li>
+	 * 	<li>对消息进行解密</li>
+	 * </ol>
+	 * 
+	 * @param msgSignature 签名串,对应URL参数的msg_signature
+	 * @param timeStamp 时间戳,对应URL参数的timestamp
+	 * @param nonce 随机串,对应URL参数的nonce
+	 * @param postData 密文,对应POST请求的数据
+	 * 
+	 * @return 解密后的原文
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData)
+			throws AesException {
+
+		// 密钥,公众账号的app secret
+		// 提取密文
+		Object[] encrypt = XMLParse.extract(postData);
+
+		// 验证安全签名
+		String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString());
+
+		// 和URL中的签名比较是否相等
+		// System.out.println("第三方收到URL中的签名:" + msg_sign);
+		// System.out.println("第三方校验签名:" + signature);
+		if (!signature.equals(msgSignature)) {
+			throw new AesException(AesException.ValidateSignatureError);
+		}
+
+		// 解密
+		String result = decrypt(encrypt[1].toString());
+		return result;
+	}
+
+	/**
+	 * 验证URL
+	 * @param msgSignature 签名串,对应URL参数的msg_signature
+	 * @param timeStamp 时间戳,对应URL参数的timestamp
+	 * @param nonce 随机串,对应URL参数的nonce
+	 * @param echoStr 随机串,对应URL参数的echostr
+	 * 
+	 * @return 解密之后的echostr
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr)
+			throws AesException {
+		String signature = SHA1.getSHA1(token, timeStamp, nonce, echoStr);
+
+		if (!signature.equals(msgSignature)) {
+			throw new AesException(AesException.ValidateSignatureError);
+		}
+
+		String result = decrypt(echoStr);
+		return result;
+	}
+
+}

+ 73 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/aes/XMLParse.java

@@ -0,0 +1,73 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+package com.company.cloud.sdk.weixin.common.aes;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import com.company.cloud.sdk.weixin.common.aes.AesException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * XMLParse class
+ *
+ * 提供提取消息格式中的密文及生成回复消息格式的接口.
+ */
+class XMLParse {
+
+	/**
+	 * 提取出xml数据包中的加密消息
+	 * @param xmltext 待提取的xml字符串
+	 * @return 提取出的加密消息字符串
+	 * @throws AesException
+	 */
+	public static Object[] extract(String xmltext) throws AesException     {
+		Object[] result = new Object[3];
+		try {
+			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			StringReader sr = new StringReader(xmltext);
+			InputSource is = new InputSource(sr);
+			Document document = db.parse(is);
+
+			Element root = document.getDocumentElement();
+			NodeList nodelist1 = root.getElementsByTagName("Encrypt");
+			NodeList nodelist2 = root.getElementsByTagName("ToUserName");
+			result[0] = 0;
+			result[1] = nodelist1.item(0).getTextContent();
+			result[2] = nodelist2.item(0).getTextContent();
+			return result;
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.ParseXmlError);
+		}
+	}
+
+	/**
+	 * 生成xml消息
+	 * @param encrypt 加密后的消息密文
+	 * @param signature 安全签名
+	 * @param timestamp 时间戳
+	 * @param nonce 随机字符串
+	 * @return 生成的xml字符串
+	 */
+	public static String generate(String encrypt, String signature, String timestamp, String nonce) {
+
+		String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+				+ "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+				+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "</xml>";
+		return String.format(format, encrypt, signature, timestamp, nonce);
+
+	}
+}

+ 46 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/TupConfigModelProperty.java

@@ -0,0 +1,46 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 用于注解配置,展示给前端配置字段信息
+ */
+@Deprecated
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TupConfigModelProperty {
+
+    /**
+     * 字段含义
+     */
+    String name() default "";
+
+    /**
+     * 字段本体
+     */
+    String key() default "";
+
+    /**
+     * 字段默认值
+     */
+    String defVal() default "";
+
+    /**
+     * 字段是否必须
+     */
+    String need() default "Y";  //Y N
+
+    /**
+     * 字段类型
+     * text: 文本类型;select: 下拉选择类型;obj:对象类型;list:字符串数组类型;list.obj:对象数据类型
+     */
+    String eleType() default "text";
+
+    /**
+     * 若字段为select类型则列出所有option
+     */
+    String[] eleItems() default "";
+}

+ 27 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/TupConfigParamItemModel.java

@@ -0,0 +1,27 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Deprecated
+@Getter
+@Setter
+public class TupConfigParamItemModel {
+
+    private String name;
+
+    private String key;
+
+    private String defVal;
+
+    private String need;
+
+    private String eleType;
+
+    private String[] eleItems;
+    
+    private List<TupConfigParamItemModel> item;
+
+}

+ 53 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/TupConfigParamItemUtils.java

@@ -0,0 +1,53 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.hutool.core.util.ReflectUtil;
+import com.company.cloud.sdk.weixin.common.config.TupConfigModelProperty;
+import com.company.cloud.sdk.weixin.common.config.TupConfigParamItemModel;
+
+@Deprecated
+public class TupConfigParamItemUtils {
+
+    public static List<TupConfigParamItemModel> getTupConfigParamItem(Class<?> clazz){
+        List<TupConfigParamItemModel> data=new ArrayList<>();
+        Field[] fields= ReflectUtil.getFields(clazz);
+        if(fields.length > 0){
+            for(Field field:fields){
+                TupConfigModelProperty channelModelProperty = field.getAnnotation(TupConfigModelProperty.class);
+                if(channelModelProperty!=null){
+                    TupConfigParamItemModel model = new TupConfigParamItemModel();
+                    model.setName(channelModelProperty.name());
+                    model.setKey(channelModelProperty.key());
+                    model.setDefVal(channelModelProperty.defVal());
+                    model.setNeed(channelModelProperty.need());
+                    model.setEleType(channelModelProperty.eleType());
+                    model.setEleItems(channelModelProperty.eleItems());
+                    if ("obj".equals(channelModelProperty.eleType())) {
+                        model.setItem(getTupConfigParamItem(field.getType()));
+                    } else if ("list".equals(channelModelProperty.eleType())) {
+                        model.setItem(getTupConfigParamItem(String.class));
+                    } else if ("list.obj".equals(channelModelProperty.eleType())) {
+                        model.setItem(listTypeHandle(field.getGenericType()));
+                    }
+                    data.add(model);
+                }
+            }
+        }
+        return data;
+    }
+    
+    /**
+     * 获取list中泛型的类型
+     * 注意list中泛型为String和包装类型问题,一律接收String
+     */
+    private static List<TupConfigParamItemModel> listTypeHandle(Type listType) {
+        ParameterizedType type = (ParameterizedType) listType;
+        Class<?> clazz = (Class<?>) type.getActualTypeArguments()[0];
+        return getTupConfigParamItem(clazz);
+    }
+}

+ 20 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxApiConfig.java

@@ -0,0 +1,20 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 微信(小程序、公众号、开放平台)配置
+ * */
+@Getter
+@Setter
+public class WxApiConfig {
+
+    /**appId*/
+    private String appid;
+
+    /**appSecret*/
+    private String secret;
+
+
+}

+ 25 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxMpConfig.java

@@ -0,0 +1,25 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 微信公众号配置
+ * */
+@Getter
+@Setter
+public class WxMpConfig {
+
+
+    /**appId[Y]*/
+    private String appid;
+
+    /**appSecret[Y]*/
+    private String secret;
+
+    /**消息token[N]*/
+    private String msgToken;
+
+    /**消息加密密钥[N]*/
+    private String msgEncodingAesKey;
+}

+ 50 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxWorkConfig.java

@@ -0,0 +1,50 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.Value;
+
+/**
+ * 企业微信内部应用配置
+ * */
+@Getter
+@Setter
+public class WxWorkConfig {
+
+
+    /**企业ID*/
+    private String corpid;
+
+
+    // 企业微信应用---------------------------------------------------
+    /**应用的凭证密钥*/
+    private String appCorpsecret;
+
+
+    // 通讯录--------------------------------------------------------
+    /**密钥*/
+    private String contactCorpsecret;
+
+    /**消息token*/
+    private String contactToken;
+
+    /**消息加密密钥*/
+    private String contactEncodingAesKey;
+
+    /**同步基准数据 server服务端 wx_work企业微信*/
+    private String contactSyncData;
+
+    // 客户联系--------------------------------------------------------
+    /**密钥*/
+    private String customerCorpsecret;
+
+    /**消息token*/
+    private String customerToken;
+
+    /**消息加密密钥*/
+    private String customerEncodingAesKey;
+
+    /**同步基准数据 server服务端 wx_work企业微信*/
+    private String customerSyncData;
+
+}

+ 12 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/config/WxWorkThirdConfig.java

@@ -0,0 +1,12 @@
+package com.company.cloud.sdk.weixin.common.config;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 企业微信第三方应用配置
+ * */
+@Getter
+@Setter
+public class WxWorkThirdConfig {
+}

+ 45 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/constant/BaseEnum.java

@@ -0,0 +1,45 @@
+package com.company.cloud.sdk.weixin.common.constant;
+
+public class BaseEnum {
+    /**
+     * 是否有效 1:启用 0:禁用
+     */
+    public enum EnabledEnum{
+        ENABLED("1", "启用"),
+        DISABLED("0", "禁用");
+        private String code;
+        private String msg;
+
+        private EnabledEnum(String code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+
+        public String getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+
+    public enum GenderEnum {
+        Male("1", "男性"),
+        Female("2", "女性")
+        ;
+        private String code;
+        private String msg;
+        private GenderEnum(String code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+        public String getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+}

+ 30 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/constant/WxErrorEnum.java

@@ -0,0 +1,30 @@
+package com.company.cloud.sdk.weixin.common.constant;
+
+
+public enum WxErrorEnum {
+
+
+    WX_Http_ERROR("WX01","调用微信服务错误"),
+    WX_Para_NULL("WX02","调用微信服务参数为空"),
+    WX_Decrypt_ERROR("WX03","微信解密错误"),
+
+    ;
+
+    private String code;
+
+    private String msg;
+
+    WxErrorEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+}

+ 7 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/constant/WxHttpMethodEnum.java

@@ -0,0 +1,7 @@
+package com.company.cloud.sdk.weixin.common.constant;
+
+public enum WxHttpMethodEnum {
+    GET,
+    POST,
+    FORM,
+}

+ 68 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/exception/WxException.java

@@ -0,0 +1,68 @@
+package com.company.cloud.sdk.weixin.common.exception;
+
+import com.company.cloud.sdk.weixin.common.constant.WxErrorEnum;
+import lombok.Getter;
+
+@Getter
+public class WxException extends RuntimeException{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 错误码
+     */
+    private String code = "500";
+    /**
+     * 错误信息
+     */
+    private String msg;
+    /**
+     * 其他额外信息
+     */
+    private String extra;
+
+
+    public WxException(String msg) {
+        super(msg);
+        this.msg = msg;
+    }
+
+    public WxException(String msg, Throwable e) {
+        super(msg, e);
+        this.msg = msg;
+    }
+
+
+
+    public WxException(WxErrorEnum error) {
+        super(error.getMsg());
+        this.msg = error.getMsg();
+        this.code = error.getCode();
+    }
+
+    public WxException(String code, String msg) {
+        super(msg);
+        this.msg = msg;
+        this.code = code;
+    }
+
+    public WxException(Integer code, String msg) {
+        super(msg);
+        this.msg = msg;
+        this.code = code==null?"-100":code.toString();
+    }
+
+    public WxException(String code, String msg, Throwable e) {
+        super(msg, e);
+        this.msg = msg;
+        this.code = code;
+    }
+
+    public WxException(String code, String msg, String extra) {
+        super(msg);
+        this.msg = msg;
+        this.code = code;
+        this.extra = extra;
+    }
+
+
+}

+ 58 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/BaseModel.java

@@ -0,0 +1,58 @@
+package com.company.cloud.sdk.weixin.common.model;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BaseModel {
+
+
+    /**
+     * 将建构的 builder 转为 Map
+     * @return 转化后的 Map
+     */
+    public Map<String, Object> toMap() {
+        String[] fieldNames = getFiledNames(this);
+        HashMap<String, Object> map = new HashMap<String, Object>(fieldNames.length);
+        for (String name : fieldNames) {
+            Object value = getFieldValueByName(name, this);
+            if(value!=null){
+                map.put(name, value);
+            }
+        }
+        return map;
+    }
+
+
+    /**
+     * 获取属性名数组
+     */
+    public String[] getFiledNames(Object obj) {
+        Field[] fields = obj.getClass().getDeclaredFields();
+        String[] fieldNames = new String[fields.length];
+        for (int i = 0; i < fields.length; i++) {
+            fieldNames[i] = fields[i].getName();
+        }
+        return fieldNames;
+    }
+    /**
+     * 根据属性名获取属性值
+     */
+    public Object getFieldValueByName(String fieldName, Object obj) {
+        try {
+            String firstLetter = fieldName.substring(0, 1).toUpperCase();
+            String getter = new StringBuffer().append("get")
+                    .append(firstLetter)
+                    .append(fieldName.substring(1))
+                    .toString();
+            Method method = obj.getClass().getMethod(getter);
+            return method.invoke(obj);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+
+
+}

+ 19 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/BaseReqModel.java

@@ -0,0 +1,19 @@
+package com.company.cloud.sdk.weixin.common.model;
+
+import com.company.cloud.sdk.weixin.common.model.BaseModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 基础AccessToken
+ */
+@Getter
+@Setter
+public class BaseReqModel extends BaseModel {
+
+    /**
+     * 必传
+     * 全局AccessToken
+     */
+    private String access_token;
+}

+ 17 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/BaseRespModel.java

@@ -0,0 +1,17 @@
+package com.company.cloud.sdk.weixin.common.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class BaseRespModel {
+
+
+    /**错误码*/
+    private Integer errcode;
+
+    /**错误信息*/
+    private String errmsg;
+
+}

+ 38 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/model/WxJSSDKSignModel.java

@@ -0,0 +1,38 @@
+package com.company.cloud.sdk.weixin.common.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 微信JSSDK签名
+ * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4
+ * @author wing
+ *
+ */
+@Getter
+@Setter
+@AllArgsConstructor
+public class WxJSSDKSignModel {
+
+    /**
+     * 微信公众号标示
+     */
+    private String appId;
+
+    /**
+     * 签名
+     */
+    private String signature;
+    
+    /**
+     * 随机字符串
+     */
+    private String nonceStr;
+
+    /**
+     * 时间戳
+     */
+    private String timestamp;
+
+}

+ 62 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/AesUtils.java

@@ -0,0 +1,62 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import com.company.cloud.sdk.weixin.common.aes.WXBizMsgCrypt;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AesUtils {
+    
+    /**
+     * 消息加密
+     */
+    public static String encryptMsg(String token, String appId, String encodingAesKey, String msg) throws Exception {
+        String timestamp = WxCommonUtils.getTimestamp();
+        String nonce = WxCommonUtils.getNonceStr();
+        WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
+        return pc.encryptMsg(msg, timestamp, nonce);
+    }
+    
+    /**
+     * 解析加密消息参数
+     */
+    public static Map<String, String> parseEncryptMsg(String encryptMsg) throws Exception {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        StringReader sr = new StringReader(encryptMsg);
+        InputSource is = new InputSource(sr);
+        Document document = db.parse(is);
+
+        Element root = document.getDocumentElement();
+        NodeList nodelist1 = root.getElementsByTagName("Encrypt");
+
+        String encrypt = nodelist1.item(0).getTextContent();
+
+        Map<String, String> map = new HashMap<>();
+        map.put("encrypt", encrypt);
+        return map;
+    }
+    
+    /**
+     * 消息解密
+     */
+    public static String decryptMsg(String token, String appId, String encodingAesKey, String encryptMsg, String msgSignature, String timestamp, String nonce) throws Exception {
+        WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
+
+        Map<String, String> map = parseEncryptMsg(encryptMsg);
+        String encrypt = map.get("encrypt");
+
+        String format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";
+        String fromXML = String.format(format, encrypt);
+
+        return pc.decryptMsg(msgSignature, timestamp, nonce, fromXML);
+    }
+    
+}

+ 28 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/EnumValid.java

@@ -0,0 +1,28 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = {EnumValidator.class})
+public @interface EnumValid {
+    String message() default "";
+
+    // 作用参考@Validated和@Valid的区别
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+
+    /**
+     * 目标枚举类
+     */
+    Class<?> target() default Class.class;
+
+    /**
+     * 是否忽略空值
+     */
+    boolean ignoreEmpty() default true;
+}

+ 41 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/EnumValidator.java

@@ -0,0 +1,41 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import com.company.cloud.sdk.weixin.common.utils.EnumValid;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public class EnumValidator  implements ConstraintValidator<EnumValid, Integer> {
+    // 枚举校验注解
+    private EnumValid annotation;
+
+    @Override
+    public void initialize(EnumValid constraintAnnotation) {
+
+        annotation = constraintAnnotation;
+    }
+
+    @Override
+    public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
+        boolean result = false;
+
+        Class<?> cls = annotation.target();
+        boolean ignoreEmpty = annotation.ignoreEmpty();
+
+        // target为枚举,并且value有值,或者不忽视空值,才进行校验
+        if (cls.isEnum() && (value != null || !ignoreEmpty)) {
+
+            Object[] objects = cls.getEnumConstants();
+            for (Object obj : objects) {
+                // 使用此注解的枚举类需要重写toString方法,改为需要验证的值
+                if (obj.toString().equals(String.valueOf(value))) {
+                    result = true;
+                    break;
+                }
+            }
+        } else {
+            result = true;
+        }
+        return result;
+    }
+}

+ 55 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/UrlUtils.java

@@ -0,0 +1,55 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import com.company.cloud.sdk.weixin.common.exception.WxException;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+public class UrlUtils {
+    
+    public static boolean strIsEmpty(String str) {
+        return null == str || "".equals(str.trim());
+    }
+
+    public static String getParseUrl(String urlStr, Map<String, Object> params) {
+        try {
+            URL url = new URL(urlStr.trim());
+            
+            String protocol = url.getProtocol();
+            String host = url.getHost();
+            String path = url.getPath();
+
+            String query = getUrlQuery(params);
+            
+            if (strIsEmpty(protocol)) {
+                protocol = "http";
+            }
+            
+            StringBuilder urlStrBuilder = new StringBuilder(protocol);
+            urlStrBuilder.append("://" + host);
+            if (!strIsEmpty(path)) {
+                urlStrBuilder.append(path);
+            }
+            if (!strIsEmpty(query)) {
+                urlStrBuilder.append("?" + query);
+            }
+
+            return urlStrBuilder.toString();
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+            throw new WxException(e.getMessage());
+        }
+    }
+    
+    public static String getUrlQuery(Map<String, Object> params) {
+        StringBuilder queryStr = new StringBuilder();
+        params.forEach((key, value) -> {
+            if (null != key && !"".equals(key.trim())) {
+                queryStr.append(key + "=" + value.toString() + "&");
+            }
+            
+        });
+        return queryStr.length() > 0 ? queryStr.substring(0, queryStr.length() - 1) : "";
+    }
+}

+ 35 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxCommonUtils.java

@@ -0,0 +1,35 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import java.util.Random;
+
+/**
+ * 微信签名
+ * 
+ * @author wing
+ *
+ */
+public class WxCommonUtils {
+
+    public static String getNonceStr() {
+        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+        Random random = new Random();
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < 16; i++) {
+            int number = random.nextInt(62);
+            sb.append(str.charAt(number));
+        }
+        return sb.toString();
+    }
+
+    public static String getTimestamp() {
+        return String.valueOf(System.currentTimeMillis() / 1000);
+    }
+
+    public static String getUrl(String url) {
+        if (url.indexOf("#") == -1) {
+            return url;
+        }
+
+        return url.substring(0, url.indexOf("#"));
+    }
+}

+ 131 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxHttpRequestUtils.java

@@ -0,0 +1,131 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.company.cloud.sdk.weixin.common.constant.WxErrorEnum;
+import com.company.cloud.sdk.weixin.common.constant.WxHttpMethodEnum;
+import com.company.cloud.sdk.weixin.common.exception.WxException;
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import com.company.cloud.sdk.weixin.common.utils.UrlUtils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+public class WxHttpRequestUtils {
+
+    public static String getReqUrl(String wxApi, String wxDomain, Map<String, Object> baseParams) {
+        String url = wxDomain.concat(wxApi);
+        if (null == baseParams) {
+            return url;
+        }
+        return UrlUtils.getParseUrl(url, baseParams);
+    }
+
+    public static String req(String wxApi, WxHttpMethodEnum method, String wxDomain, Map<String, Object> params) {
+        try {
+            Map<String, Object> baseParams = null;
+            String accessToken = (String) params.get("access_token");
+            if (null != accessToken) {
+                baseParams = new HashMap<String, Object>();
+                baseParams.put("access_token", accessToken);
+                params.remove("access_token");
+            }
+
+            String suiteAccessToken = (String) params.get("suite_access_token");
+            if (null != suiteAccessToken) {
+                baseParams = new HashMap<String, Object>();
+                baseParams.put("suite_access_token", accessToken);
+                params.remove("suite_access_token");
+            }
+
+            String url = getReqUrl(wxApi, wxDomain, baseParams);
+
+            System.out.println(url);
+            if (WxHttpMethodEnum.FORM.equals(method)) {
+                return HttpUtil.post(url, params);
+            } else if (WxHttpMethodEnum.POST.equals(method)) {
+                return HttpUtil.post(url, JSONObject.toJSONString(params));
+            }
+            return HttpUtil.get(url, params);
+        } catch (Exception e) {
+            throw new WxException(WxErrorEnum.WX_Http_ERROR.getCode(), e.getMessage());
+        }
+    }
+
+    public static <T extends BaseRespModel> T getResp(T t, String wxApi, WxHttpMethodEnum method, String wxDomain, Object entity) {
+        Map<String, Object> params = BeanUtil.beanToMap(entity, false, true);
+        String result = req(wxApi, method, wxDomain, params);
+        if (StrUtil.isEmpty(result)) {
+            throw new WxException(WxErrorEnum.WX_Http_ERROR);
+        }
+        Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
+        T data = BeanUtil.fillBeanWithMapIgnoreCase(resultMap, t, false);
+        if (data.getErrcode() != null && data.getErrcode() != 0) {
+            throw new WxException(data.getErrcode(), data.getErrmsg());
+        }
+        return data;
+    }
+
+    // get请求
+    public static <T extends BaseRespModel> T getReq(T t, String wxApi, String wxDomain, Object entity) {
+        return getResp(t, wxApi, WxHttpMethodEnum.GET, wxDomain, entity);
+    }
+
+    // post请求
+    public static <T extends BaseRespModel> T postReq(T t, String wxApi, String wxDomain, Object entity) {
+        return getResp(t, wxApi, WxHttpMethodEnum.POST, wxDomain, entity);
+    }
+
+    // 表单请求
+    public static <T extends BaseRespModel> T formReq(T t, String wxApi, String wxDomain, Object entity) {
+        return getResp(t, wxApi, WxHttpMethodEnum.FORM, wxDomain, entity);
+    }
+
+    // 下载文件请求
+    public static File fileReq(String wxApi, String wxDomain, Object entity) {
+        HttpURLConnection conn = null;
+        try {
+            Map<String, Object> params = BeanUtil.beanToMap(entity, false, true);
+            String url = getReqUrl(wxApi,  wxDomain, params);
+            URL u = new URL(url);
+            conn = (HttpURLConnection) u.openConnection();
+            conn.setRequestMethod("POST");
+            conn.connect();
+            BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
+            String content_disposition = conn.getHeaderField("content-disposition");
+            //微信服务器生成的文件名称
+            String file_name ="";
+            String[] content_arr = content_disposition.split(";");
+            if(content_arr.length  == 2){
+                String tmp = content_arr[1];
+                int index = tmp.indexOf("\"");
+                file_name =tmp.substring(index+1, tmp.length()-1);
+            }
+            //生成不同文件名称
+            File file = new File(file_name);
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
+            byte[] buf = new byte[2048];
+            int length = bis.read(buf);
+            while(length != -1){
+                bos.write(buf, 0, length);
+                length = bis.read(buf);
+            }
+            bos.close();
+            bis.close();
+            return file;
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            throw new WxException(e.getMessage());
+        }finally {
+            conn.disconnect();
+        }
+        return null;
+    }
+}

+ 43 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxJSSDKSignUtils.java

@@ -0,0 +1,43 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import com.company.cloud.sdk.weixin.common.model.WxJSSDKSignModel;
+import com.company.cloud.sdk.weixin.common.utils.WxCommonUtils;
+
+import java.util.Arrays;
+
+/**
+ * 微信签名
+ * 
+ * @author wing
+ *
+ */
+public class WxJSSDKSignUtils {
+
+    public static WxJSSDKSignModel sign(String appId, String url, String ticket) {
+        String nonceStr = WxCommonUtils.getNonceStr();
+        String timestamp = WxCommonUtils.getTimestamp();
+        StringBuilder signStr = new StringBuilder();
+        signStr.append("jsapi_ticket=" + ticket);
+        signStr.append("&noncestr=" + nonceStr);
+        signStr.append("&timestamp=" + timestamp);
+        signStr.append("&url=" + WxCommonUtils.getUrl(url));
+        String signature = DigestUtil.sha1Hex(signStr.toString());
+        WxJSSDKSignModel model = new WxJSSDKSignModel(appId, signature, nonceStr, timestamp);
+        return model;
+    }
+
+    public static String tokenVerification(String token, String timestamp, String nonce) {
+        // 排序
+        String[] arr = new String[] { token, timestamp, nonce };
+        Arrays.sort(arr);
+
+        // 生成字符串
+        StringBuffer signStr = new StringBuffer();
+        for (int i = 0; i < arr.length; i++) {
+            signStr.append(arr[i]);
+        }
+
+        return DigestUtil.sha1Hex(signStr.toString());
+    }
+}

+ 29 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/WxVerificationUtils.java

@@ -0,0 +1,29 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+/**
+ * 微信验证
+ * 
+ * @author wing
+ *
+ */
+public class WxVerificationUtils {
+
+    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {
+        ArrayList<String> list = new ArrayList<>();
+        list.add(nonce);
+        list.add(timestamp);
+        list.add(token);
+        Collections.sort(list);
+        StringBuilder sb= new StringBuilder();
+        list.forEach(sb::append);
+        String result = sb.toString();
+        String sha1 = DigestUtils.sha1Hex(result);
+        return signature.equals(sha1);
+    }
+
+}

+ 54 - 0
weixin-java-common/src/main/java/com/company/cloud/sdk/weixin/common/utils/XmlUtils.java

@@ -0,0 +1,54 @@
+package com.company.cloud.sdk.weixin.common.utils;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+public class XmlUtils {
+
+    /** 
+     * 将对象直接转换成String类型的 XML输出 
+     *  
+     * @param obj 
+     * @return 
+     */  
+    public static String convertToXml(Object obj) {  
+        // 创建输出流  
+        StringWriter sw = new StringWriter();  
+        try {  
+            // 利用jdk中自带的转换类实现  
+            JAXBContext context = JAXBContext.newInstance(obj.getClass());  
+  
+            Marshaller marshaller = context.createMarshaller();  
+            // 格式化xml输出的格式  
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,  
+                    Boolean.TRUE);  
+            // 将对象转换成输出流形式的xml  
+            marshaller.marshal(obj, sw);  
+        } catch (JAXBException e) {  
+            e.printStackTrace();  
+        }  
+        return sw.toString();  
+    } 
+
+    /** 
+     * 将String类型的xml转换成对象 
+     */  
+    public static Object convertXmlStrToObject(Class<?> clazz, String xmlStr) {  
+        Object xmlObject = null;  
+        try {  
+            JAXBContext context = JAXBContext.newInstance(clazz);  
+            // 进行将Xml转成对象的核心接口  
+            Unmarshaller unmarshaller = context.createUnmarshaller();  
+            StringReader sr = new StringReader(xmlStr);  
+            xmlObject = unmarshaller.unmarshal(sr);  
+        } catch (JAXBException e) {  
+            e.printStackTrace();  
+        }  
+        return xmlObject;  
+    }
+}

+ 41 - 0
weixin-java-im/pom.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>wx-sdk</artifactId>
+        <groupId>com.company.cloud.sdk</groupId>
+        <version>2.0.0</version>
+    </parent>
+    <groupId>com.company.cloud.sdk.weixin.im</groupId>
+    <artifactId>weixin-java-im</artifactId>
+    <description>微信IM SDK</description>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <junit.version>5.7.1</junit.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.company.cloud.sdk</groupId>
+            <artifactId>weixin-java-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+<!--    <build>-->
+<!--        <plugins>-->
+<!--            <plugin>-->
+<!--                <groupId>org.apache.maven.plugins</groupId>-->
+<!--                <artifactId>maven-war-plugin</artifactId>-->
+<!--                <version>3.3.1</version>-->
+<!--            </plugin>-->
+<!--        </plugins>-->
+<!--    </build>-->
+
+
+</project>

+ 75 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImAccountAPi.java

@@ -0,0 +1,75 @@
+package com.company.cloud.sdk.weixin.im;
+
+import com.company.cloud.sdk.weixin.im.enums.WxIMApiType;
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import com.company.cloud.sdk.weixin.im.model.account.*;
+import com.company.cloud.sdk.weixin.im.utils.WxIMUtils;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 13:11
+ */
+public class WxImAccountAPi {
+
+    /**
+     * 导入单个帐号
+     * 参考: https://cloud.tencent.com/document/product/269/1608
+     */
+    public static IMBaseRespModel accountImport(AccountImportModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.account_import.getType(),entity);
+        return WxIMUtils.postReq(new IMBaseRespModel(),url, entity);
+    }
+
+
+    /**
+     * 导入多个帐号
+     * 参考: https://cloud.tencent.com/document/product/269/4919
+     */
+    public static IMBaseRespModel accountBatchImport(AccountBatchImportModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.multiaccount_import.getType(),entity);
+        return WxIMUtils.postReq(new IMBaseRespModel(),url, entity);
+    }
+
+
+    /**
+     * 删除帐号
+     * 参考:https://cloud.tencent.com/document/product/269/36443
+     */
+    public static AccountDeleteRespModel deleteAccount(AccountDeleteItemsModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.account_delete.getType(),entity);
+        return WxIMUtils.postReq(new AccountDeleteRespModel(),url, entity);
+    }
+
+
+    /**
+     * 查询帐号
+     * 参考: https://cloud.tencent.com/document/product/269/38417
+     */
+    public static AccountCheckRespModel accountCheck(AccountCheckModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.account_check.getType(),entity);
+        return WxIMUtils.postReq(new AccountCheckRespModel(),url, entity);
+    }
+
+
+
+    /**
+     * 失效帐号登录状态
+     * 参考: https://cloud.tencent.com/document/product/269/3853
+     */
+    public static IMBaseRespModel accountKick(AccountKickModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.kick.getType(),entity);
+        return WxIMUtils.postReq(new IMBaseRespModel(),url, entity);
+    }
+
+
+    /**
+     * 查询帐号在线状态
+     * 参考: https://cloud.tencent.com/document/product/269/2566
+     */
+    public static AccountQueryOnlineRespModel accountQueryOnlineStatus(AccountQueryOnlineStatusModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.query_online_status.getType(),entity);
+        return WxIMUtils.postReq(new AccountQueryOnlineRespModel(),url, entity);
+    }
+
+
+}

+ 8 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImGroupApi.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.im;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 13:13
+ */
+public class WxImGroupApi {
+}

+ 8 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImMsgApi.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.im;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 13:12
+ */
+public class WxImMsgApi {
+}

+ 34 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImProfileApi.java

@@ -0,0 +1,34 @@
+package com.company.cloud.sdk.weixin.im;
+
+import com.company.cloud.sdk.weixin.im.enums.WxIMApiType;
+import com.company.cloud.sdk.weixin.im.model.profile.ProfileGetModel;
+import com.company.cloud.sdk.weixin.im.model.profile.ProfileGetRespModel;
+import com.company.cloud.sdk.weixin.im.model.profile.ProfileSetModel;
+import com.company.cloud.sdk.weixin.im.model.profile.ProfileSetRespModel;
+import com.company.cloud.sdk.weixin.im.utils.WxIMUtils;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:41
+ */
+public class WxImProfileApi {
+
+    /**
+     * 设置资料
+     * 参考: https://cloud.tencent.com/document/product/269/1640
+     */
+    public static ProfileSetRespModel profileSet(ProfileSetModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.portrait_set.getType(),entity);
+        return WxIMUtils.postReq(new ProfileSetRespModel(),url, entity);
+    }
+
+
+    /**
+     * 拉取资料
+     * 参考: https://cloud.tencent.com/document/product/269/1639
+     */
+    public static ProfileGetRespModel profileGet(ProfileGetModel entity) {
+        String url = WxIMUtils.getUrl(WxIMApiType.portrait_get.getType(),entity);
+        return WxIMUtils.postReq(new ProfileGetRespModel(),url, entity);
+    }
+}

+ 8 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/WxImSnsApi.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.im;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 13:12
+ */
+public class WxImSnsApi {
+}

+ 170 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/enums/WxIMApiType.java

@@ -0,0 +1,170 @@
+package com.company.cloud.sdk.weixin.im.enums;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/22 15:01
+ */
+public enum WxIMApiType {
+
+    //账号管理
+
+    /**导入单个帐号*/
+    account_import("v4/im_open_login_svc/account_import"),
+    /**导入多个帐号*/
+    multiaccount_import("v4/im_open_login_svc/multiaccount_import"),
+    /**删除帐号*/
+    account_delete("v4/im_open_login_svc/account_delete"),
+    /**查询帐号	*/
+    account_check("v4/im_open_login_svc/account_check"),
+    /**失效帐号登录态*/
+    kick("v4/im_open_login_svc/kick"),
+    /**查询帐号在线状态	*/
+    query_online_status("v4/openim/query_online_status"),
+
+
+    //单聊消息
+
+    /**单发单聊消息	*/
+    sendmsg("v4/openim/sendmsg"),
+    /**批量发单聊消息	*/
+    batchsendmsg("v4/openim/batchsendmsg"),
+    /**导入单聊消息	*/
+    importmsg("v4/openim/importmsg"),
+    /**查询单聊消息	*/
+    admin_getroammsg("v4/openim/admin_getroammsg"),
+    /**撤回单聊消息	*/
+    admin_msgwithdraw("v4/openim/admin_msgwithdraw"),
+    /**设置单聊消息已读	*/
+    admin_set_msg_read("v4/openim/admin_set_msg_read"),
+    /**查询单聊未读消息计数	*/
+    get_c2c_unread_msg_num("v4/openim/get_c2c_unread_msg_num"),
+    /**修改单聊历史消息	*/
+    modify_c2c_msg("v4/openim/modify_c2c_msg"),
+
+
+    //资料管理
+
+    /**设置资料	*/
+    portrait_set("v4/profile/portrait_set"),
+    /**拉取资料	*/
+    portrait_get("v4/profile/portrait_get"),
+
+
+    //关系链管理
+
+    /**添加好友	*/
+    friend_add("v4/sns/friend_add"),
+    /**导入好友	*/
+    friend_import("v4/sns/friend_import"),
+    /**更新好友	*/
+    friend_update("v4/sns/friend_update"),
+    /**删除好友	*/
+    friend_delete("v4/sns/friend_delete"),
+    /**删除所有好友	*/
+    friend_delete_all("v4/sns/friend_delete_all"),
+    /**校验好友	*/
+    friend_check("v4/sns/friend_check"),
+    /**拉取好友	*/
+    friend_get("v4/sns/friend_get"),
+    /**拉取指定好友	*/
+    friend_get_list("v4/sns/friend_get_list"),
+    /**添加黑名单	*/
+    black_list_add("v4/sns/black_list_add"),
+    /**删除黑名单	*/
+    black_list_delete("v4/sns/black_list_delete"),
+    /**拉取黑名单	*/
+    black_list_get("v4/sns/black_list_get"),
+    /**校验黑名单	*/
+    black_list_check("v4/sns/black_list_check"),
+    /**添加分组	*/
+    group_add("v4/sns/group_add"),
+    /**删除分组	*/
+    group_delete("v4/sns/group_delete"),
+    /**拉取分组	*/
+    group_get("v4/sns/group_get"),
+
+    //群组管理
+
+    /**获取 App 中的所有群组	*/
+    get_appid_group_list("v4/group_open_http_svc/get_appid_group_list"),
+    /**创建群组	*/
+    create_group("v4/group_open_http_svc/create_group"),
+    /**获取群详细资料	*/
+    get_group_info("v4/group_open_http_svc/get_group_info"),
+    /**获取群成员详细资料	*/
+    get_group_member_info("v4/group_open_http_svc/get_group_member_info"),
+    /**修改群基础资料	*/
+    modify_group_base_info("v4/group_open_http_svc/modify_group_base_info"),
+    /**增加群成员		*/
+    add_group_member("v4/group_open_http_svc/add_group_member"),
+    /**删除群成员	*/
+    delete_group_member("v4/group_open_http_svc/delete_group_member"),
+    /**修改群成员资料	*/
+    modify_group_member_info("v4/group_open_http_svc/modify_group_member_info"),
+    /**解散群组	*/
+    destroy_group("v4/group_open_http_svc/destroy_group"),
+    /**获取用户所加入的群组	*/
+    get_joined_group_list("v4/group_open_http_svc/get_joined_group_list"),
+    /**查询用户在群组中的身份	*/
+    get_role_in_group("v4/group_open_http_svc/get_role_in_group"),
+    /**批量禁言和取消禁言	*/
+    forbid_send_msg("v4/group_open_http_svc/forbid_send_msg"),
+    /**获取被禁言群成员列表	*/
+    get_group_shutted_uin("v4/group_open_http_svc/get_group_shutted_uin"),
+    /**在群组中发送普通消息	*/
+    send_group_msg("v4/group_open_http_svc/send_group_msg"),
+    /**在群组中发送系统通知	*/
+    send_group_system_notification("v4/group_open_http_svc/send_group_system_notification"),
+    /**撤回群消息	*/
+    group_msg_recall("v4/group_open_http_svc/group_msg_recall"),
+    /**转让群主	*/
+    change_group_owner("v4/group_open_http_svc/change_group_owner"),
+    /**导入群基础资料	*/
+    import_group("v4/group_open_http_svc/import_group"),
+    /**导入群消息	*/
+    import_group_msg("v4/group_open_http_svc/import_group_msg"),
+    /**导入群成员	*/
+    import_group_member("v4/group_open_http_svc/import_group_member"),
+    /**设置成员未读消息计数	*/
+    set_unread_msg_num("v4/group_open_http_svc/set_unread_msg_num"),
+    /**删除指定用户发送的消息	*/
+    delete_group_msg_by_sender("v4/group_open_http_svc/delete_group_msg_by_sender"),
+    /**拉取群历史消息	*/
+    group_msg_get_simple("v4/group_open_http_svc/group_msg_get_simple"),
+    /**获取直播群在线人数	*/
+    get_online_member_num("v4/group_open_http_svc/get_online_member_num"),
+    /**获取群自定义属性	*/
+    get_group_attr("v4/group_open_attr_http_svc/get_group_attr"),
+    /**获取封禁群成员列表	*/
+    get_group_ban_member("v4/group_open_http_svc/get_group_ban_member"),
+    /**群成员封禁	*/
+    ban_group_member("v4/group_open_http_svc/ban_group_member"),
+    /**群成员解封	*/
+    unban_group_member("v4/group_open_http_svc/unban_group_member"),
+    /**修改群自定义属性	*/
+    modify_group_attr("v4/group_open_http_svc/modify_group_attr"),
+    /**清空群自定义属性	*/
+    clear_group_attr("v4/group_open_http_svc/clear_group_attr"),
+    /**重置群自定义属性	*/
+    set_group_attr("v4/group_open_http_svc/set_group_attr"),
+    /**修改群聊历史消息	*/
+    modify_group_msg("v4/openim/modify_group_msg"),
+    /**直播群广播消息	*/
+    send_broadcast_msg("v4/group_open_http_svc/send_broadcast_msg");
+
+    private final String type;
+
+    WxIMApiType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    @Override
+    public String toString() {
+        return type;
+    }
+
+}

+ 33 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/enums/WxIMDomain.java

@@ -0,0 +1,33 @@
+package com.company.cloud.sdk.weixin.im.enums;
+
+/**
+ *  微信小程序可用域名枚举
+ * */
+public enum WxIMDomain {
+
+
+    /**
+     * 中国国内
+     */
+    CHINA("https://console.tim.qq.com/")
+    ;
+
+    /**
+     * 域名
+     */
+    private final String domain;
+
+    WxIMDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getType() {
+        return domain;
+    }
+
+    @Override
+    public String toString() {
+        return domain;
+    }
+
+}

+ 8 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMBaseModel.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.im.model;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 14:53
+ */
+public class IMBaseModel {
+}

+ 19 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMBaseReqModel.java

@@ -0,0 +1,19 @@
+package com.company.cloud.sdk.weixin.im.model;
+
+import com.company.cloud.sdk.weixin.common.model.BaseModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 基础AccessToken
+ */
+@Getter
+@Setter
+public class IMBaseReqModel extends BaseModel {
+
+    /**
+     * 必传
+     * 全局AccessToken
+     */
+    private String access_token;
+}

+ 19 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMBaseRespModel.java

@@ -0,0 +1,19 @@
+package com.company.cloud.sdk.weixin.im.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class IMBaseRespModel {
+
+    /**请求处理的结果,OK 表示处理成功,FAIL 表示失败*/
+    private String ActionStatus;
+
+    /**错误码,0表示成功,非0表示失败*/
+    private Integer ErrorCode;
+
+    /**错误信息*/
+    private String ErrorInfo;
+
+}

+ 40 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/IMSignModel.java

@@ -0,0 +1,40 @@
+package com.company.cloud.sdk.weixin.im.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 微信IM签名
+ * @author wing
+ *
+ */
+@Getter
+@Setter
+public class IMSignModel {
+
+    /**
+     * 创建应用时即时通信 IM 控制台分配的 SDKAppID
+     */
+    private String sdkappid;
+
+    /**
+     * 	必须为 App 管理员帐号,更多详情请参见 App 管理员
+     */
+    private String identifier;
+    
+    /**
+     *	App 管理员帐号生成的签名,具体操作请参见 生成 UserSig
+     */
+    private String usersig;
+
+    /**
+     * 请输入随机的32位无符号整数,取值范围0 - 4294967295
+     */
+    private String random;
+
+    /**
+     * 请求格式固定值为json
+     */
+    private String contenttype;
+
+}

+ 19 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountBatchImportModel.java

@@ -0,0 +1,19 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 15:34
+ */
+@Data
+public class AccountBatchImportModel extends IMSignModel {
+
+    /**
+     * 用户名,单个用户名长度不超过32字节,单次最多导入100个用户名
+     */
+    private List<String> Accounts;
+}

+ 17 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountCheckModel.java

@@ -0,0 +1,17 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:13
+ */
+@Data
+public class AccountCheckModel extends IMSignModel {
+
+    private List<AccountUserIdModel> CheckItem;
+
+}

+ 16 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountCheckRespModel.java

@@ -0,0 +1,16 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:15
+ */
+@Data
+public class AccountCheckRespModel extends IMBaseRespModel {
+
+    private List<AccountCheckResultModel> ResultItem;
+}

+ 29 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountCheckResultModel.java

@@ -0,0 +1,29 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:15
+ */
+@Data
+public class AccountCheckResultModel {
+    /**
+     *请求检查的帐号的 UserID
+     */
+    private String UserID;
+    /**
+     *单个帐号检查失败时的错误描述信息
+     */
+    private String ResultInfo;
+
+    /**
+     *单个帐号的检查结果:0表示成功,非0表示失败
+     */
+    private String ResultCode;
+
+    /**
+     * 单个帐号的导入状态:Imported 表示已导入,NotImported 表示未导入
+     */
+    private String AccountStatus;
+}

+ 19 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountDeleteItemsModel.java

@@ -0,0 +1,19 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 16:20
+ */
+@Data
+public class AccountDeleteItemsModel extends IMSignModel {
+
+    /**
+     * 请求删除的帐号对象数组,单次请求最多支持100个帐号
+     */
+    private List<AccountUserIdModel> DeleteItem;
+}

+ 16 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountDeleteRespModel.java

@@ -0,0 +1,16 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 16:30
+ */
+@Data
+public class AccountDeleteRespModel extends IMBaseRespModel {
+
+   private List<AccountDeleteResultModel> ResultItem;
+}

+ 17 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountDeleteResultModel.java

@@ -0,0 +1,17 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 16:30
+ */
+@Data
+public class AccountDeleteResultModel {
+
+    private String ResultCode;
+
+    private String ResultInfo;
+
+    private String UserID;
+}

+ 23 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountImportModel.java

@@ -0,0 +1,23 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 15:08
+ */
+@Data
+public class AccountImportModel extends IMSignModel {
+
+    /** 用户名,长度不超过32字节 必填*/
+    private String UserID;
+
+    /** 用户昵称 选填*/
+    private String Nick;
+
+    /** 用户头像 URL 选填*/
+    private String FaceUrl;
+
+
+}

+ 17 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountKickModel.java

@@ -0,0 +1,17 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:20
+ */
+@Data
+public class AccountKickModel extends IMSignModel {
+
+    /**
+     *  UserID
+     */
+    private String UserID;
+}

+ 15 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineDetailsModel.java

@@ -0,0 +1,15 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:34
+ */
+@Data
+public class AccountQueryOnlineDetailsModel {
+
+    private String Platform;
+
+    private String Status;
+}

+ 15 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineErrorResultModel.java

@@ -0,0 +1,15 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:31
+ */
+@Data
+public class AccountQueryOnlineErrorResultModel {
+
+    private String To_Account;
+
+    private String ErrorCode;
+}

+ 18 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineRespModel.java

@@ -0,0 +1,18 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:29
+ */
+@Data
+public class AccountQueryOnlineRespModel extends IMBaseRespModel {
+
+    private List<AccountQueryOnlineResultModel> QueryResult;
+
+    private List<AccountQueryOnlineErrorResultModel> ErrorList;
+}

+ 15 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineResultModel.java

@@ -0,0 +1,15 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:30
+ */
+@Data
+public class AccountQueryOnlineResultModel extends AccountQueryOnlineDetailsModel{
+
+    private String To_Account;
+
+    private String Status;
+}

+ 24 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountQueryOnlineStatusModel.java

@@ -0,0 +1,24 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:23
+ */
+@Data
+public class AccountQueryOnlineStatusModel extends IMSignModel {
+
+    /**
+     * 必填	需要查询这些 UserID 的登录状态,一次最多查询500个 UserID 的状态
+     */
+    private List<String> To_Account;
+
+    /**
+     * 选填	是否需要返回详细的登录平台信息。0表示不需要,1表示需要
+     */
+    private String IsNeedDetail;
+}

+ 16 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/account/AccountUserIdModel.java

@@ -0,0 +1,16 @@
+package com.company.cloud.sdk.weixin.im.model.account;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 16:20
+ */
+@Data
+public class AccountUserIdModel {
+
+    /**
+     * 请求删除的帐号的 UserID
+     */
+    private String UserID;
+}

+ 18 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileGetModel.java

@@ -0,0 +1,18 @@
+package com.company.cloud.sdk.weixin.im.model.profile;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:49
+ */
+@Data
+public class ProfileGetModel extends IMSignModel {
+
+    private List<String> To_Account;
+
+    private List<String> TagList;
+}

+ 20 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileGetRespModel.java

@@ -0,0 +1,20 @@
+package com.company.cloud.sdk.weixin.im.model.profile;
+
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:58
+ */
+@Data
+public class ProfileGetRespModel extends IMBaseRespModel {
+
+    private List<String> Fail_Account;
+
+    private List<UserProfileModel> UserProfileItem;
+
+    private String ErrorDisplay;
+}

+ 15 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileModel.java

@@ -0,0 +1,15 @@
+package com.company.cloud.sdk.weixin.im.model.profile;
+
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:44
+ */
+@Data
+public class ProfileModel {
+
+    private String Tag;
+
+    private String Value;
+}

+ 18 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileSetModel.java

@@ -0,0 +1,18 @@
+package com.company.cloud.sdk.weixin.im.model.profile;
+
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:43
+ */
+@Data
+public class ProfileSetModel extends IMSignModel {
+
+    private String From_Account;
+
+    private List<ProfileModel> ProfileItem;
+}

+ 14 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/ProfileSetRespModel.java

@@ -0,0 +1,14 @@
+package com.company.cloud.sdk.weixin.im.model.profile;
+
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import lombok.Data;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:47
+ */
+@Data
+public class ProfileSetRespModel extends IMBaseRespModel {
+
+    private String ErrorDisplay;
+}

+ 21 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/model/profile/UserProfileModel.java

@@ -0,0 +1,21 @@
+package com.company.cloud.sdk.weixin.im.model.profile;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author dhz
+ * @Date 2022/9/23 18:54
+ */
+@Data
+public class UserProfileModel {
+
+    private String To_Account;
+
+    private String ResultInfo;
+
+    private Integer ResultCode;
+
+    private List<ProfileModel> ProfileItem;
+}

+ 130 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/utils/IMWxHttpRequestUtils.java

@@ -0,0 +1,130 @@
+package com.company.cloud.sdk.weixin.im.utils;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.company.cloud.sdk.weixin.common.constant.WxErrorEnum;
+import com.company.cloud.sdk.weixin.common.constant.WxHttpMethodEnum;
+import com.company.cloud.sdk.weixin.common.exception.WxException;
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import com.company.cloud.sdk.weixin.common.utils.UrlUtils;
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+public class IMWxHttpRequestUtils {
+
+    public static String getReqUrl(String wxApi, String wxDomain, Map<String, Object> baseParams) {
+        String url = wxDomain.concat(wxApi);
+        if (null == baseParams) {
+            return url;
+        }
+        return UrlUtils.getParseUrl(url, baseParams);
+    }
+
+    public static String req(String wxApi, WxHttpMethodEnum method, String wxDomain, Map<String, Object> params) {
+        try {
+            Map<String, Object> baseParams = null;
+            String accessToken = (String) params.get("access_token");
+            if (null != accessToken) {
+                baseParams = new HashMap<String, Object>();
+                baseParams.put("access_token", accessToken);
+                params.remove("access_token");
+            }
+
+            String suiteAccessToken = (String) params.get("suite_access_token");
+            if (null != suiteAccessToken) {
+                baseParams = new HashMap<String, Object>();
+                baseParams.put("suite_access_token", accessToken);
+                params.remove("suite_access_token");
+            }
+
+            String url = getReqUrl(wxApi, wxDomain, baseParams);
+            if (WxHttpMethodEnum.FORM.equals(method)) {
+                return HttpUtil.post(url, params);
+            } else if (WxHttpMethodEnum.POST.equals(method)) {
+                return HttpUtil.post(url, JSONObject.toJSONString(params));
+            }
+            return HttpUtil.get(url, params);
+        } catch (Exception e) {
+            throw new WxException(WxErrorEnum.WX_Http_ERROR.getCode(), e.getMessage());
+        }
+    }
+
+    public static <T extends IMBaseRespModel> T getResp(T t, String wxApi, WxHttpMethodEnum method, String wxDomain, Object entity) {
+        Map<String, Object> params = BeanUtil.beanToMap(entity, false, true);
+        String result = req(wxApi, method, wxDomain, params);
+        if (StrUtil.isEmpty(result)) {
+            throw new WxException(WxErrorEnum.WX_Http_ERROR);
+        }
+        Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
+        T data = BeanUtil.fillBeanWithMapIgnoreCase(resultMap, t, false);
+        if (data.getActionStatus() != "OK" && data.getErrorCode() != 0) {
+            throw new WxException(data.getErrorCode(), data.getErrorInfo());
+        }
+        return data;
+    }
+
+    // get请求
+    public static <T extends IMBaseRespModel> T getReq(T t, String wxApi, String wxDomain, Object entity) {
+        return getResp(t, wxApi, WxHttpMethodEnum.GET, wxDomain, entity);
+    }
+
+    // post请求
+    public static <T extends IMBaseRespModel> T postReq(T t, String wxApi, String wxDomain, Object entity) {
+        return getResp(t, wxApi, WxHttpMethodEnum.POST, wxDomain, entity);
+    }
+
+    // 表单请求
+    public static <T extends IMBaseRespModel> T formReq(T t, String wxApi, String wxDomain, Object entity) {
+        return getResp(t, wxApi, WxHttpMethodEnum.FORM, wxDomain, entity);
+    }
+
+    // 下载文件请求
+    public static File fileReq(String wxApi, String wxDomain, Object entity) {
+        HttpURLConnection conn = null;
+        try {
+            Map<String, Object> params = BeanUtil.beanToMap(entity, false, true);
+            String url = getReqUrl(wxApi,  wxDomain, params);
+            URL u = new URL(url);
+            conn = (HttpURLConnection) u.openConnection();
+            conn.setRequestMethod("POST");
+            conn.connect();
+            BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
+            String content_disposition = conn.getHeaderField("content-disposition");
+            //微信服务器生成的文件名称
+            String file_name ="";
+            String[] content_arr = content_disposition.split(";");
+            if(content_arr.length  == 2){
+                String tmp = content_arr[1];
+                int index = tmp.indexOf("\"");
+                file_name =tmp.substring(index+1, tmp.length()-1);
+            }
+            //生成不同文件名称
+            File file = new File(file_name);
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
+            byte[] buf = new byte[2048];
+            int length = bis.read(buf);
+            while(length != -1){
+                bos.write(buf, 0, length);
+                length = bis.read(buf);
+            }
+            bos.close();
+            bis.close();
+            return file;
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            throw new WxException(e.getMessage());
+        }finally {
+            conn.disconnect();
+        }
+        return null;
+    }
+}

+ 38 - 0
weixin-java-im/src/main/java/com/company/cloud/sdk/weixin/im/utils/WxIMUtils.java

@@ -0,0 +1,38 @@
+package com.company.cloud.sdk.weixin.im.utils;
+
+import com.company.cloud.sdk.weixin.common.constant.WxHttpMethodEnum;
+import com.company.cloud.sdk.weixin.common.utils.WxHttpRequestUtils;
+import com.company.cloud.sdk.weixin.im.enums.WxIMDomain;
+import com.company.cloud.sdk.weixin.im.model.IMBaseRespModel;
+import com.company.cloud.sdk.weixin.im.model.IMSignModel;
+
+public class WxIMUtils {
+
+    public static String getUrl(String wxApi, IMSignModel entity) {
+        String url = wxApi + "?sdkappid=" + entity.getSdkappid() + "&identifier=" + entity.getIdentifier() + "&usersig=" + entity.getUsersig() + "&random=" + entity.getRandom() + "&contenttype=" + entity.getContenttype();
+        return url;
+    }
+
+
+    public static <T extends IMBaseRespModel> T getResp(T t, String wxApi, WxHttpMethodEnum method, WxIMDomain wxDomain, Object entity) {
+        if (null == wxDomain) {
+            wxDomain = WxIMDomain.CHINA;
+        }
+        return IMWxHttpRequestUtils.getResp(t, wxApi, method, wxDomain.getType(), entity);
+    }
+
+    // get请求
+    public static <T extends IMBaseRespModel> T getReq(T t, String wxApi, Object entity) {
+        return IMWxHttpRequestUtils.getReq(t, wxApi, WxIMDomain.CHINA.getType(), entity);
+    }
+
+    // post请求
+    public static <T extends IMBaseRespModel> T postReq(T t, String wxApi, Object entity) {
+        return IMWxHttpRequestUtils.postReq(t, wxApi, WxIMDomain.CHINA.getType(), entity);
+    }
+
+    // 表单请求
+    public static <T extends IMBaseRespModel> T formReq(T t, String wxApi, Object entity) {
+        return IMWxHttpRequestUtils.formReq(t, wxApi, WxIMDomain.CHINA.getType(), entity);
+    }
+}

+ 22 - 0
weixin-java-mini/pom.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>wx-sdk</artifactId>
+        <groupId>com.company.cloud.sdk</groupId>
+        <version>2.0.0</version>
+    </parent>
+    <groupId>com.company.cloud.sdk</groupId>
+    <artifactId>weixin-java-mini</artifactId>
+    <description>微信小程序Java SDK</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.company.cloud.sdk</groupId>
+            <artifactId>weixin-java-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 8 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxCodeApi.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.mini;
+
+/**
+ * 小程序码API
+ * */
+@Deprecated
+public class WxCodeApi {
+}

+ 8 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxDataAnalysisApi.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.mini;
+
+/**
+ * 小程序数据分析API
+ * */
+@Deprecated
+public class WxDataAnalysisApi {
+}

+ 7 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerFollowerApi.java

@@ -0,0 +1,7 @@
+package com.company.cloud.sdk.weixin.mini;
+/**
+ * 微信小程序直播(长期订阅)接口
+ * */
+@Deprecated
+public class WxLivePlayerFollowerApi {
+}

+ 8 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerGoodsApi.java

@@ -0,0 +1,8 @@
+package com.company.cloud.sdk.weixin.mini;
+
+/**
+ * 微信小程序直播(商品)接口
+ * */
+@Deprecated
+public class WxLivePlayerGoodsApi {
+}

+ 10 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerRoleApi.java

@@ -0,0 +1,10 @@
+package com.company.cloud.sdk.weixin.mini;
+
+/**
+ * 微信小程序直播(成员)接口
+ * */
+@Deprecated
+public class WxLivePlayerRoleApi {
+
+
+}

+ 12 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxLivePlayerRoomApi.java

@@ -0,0 +1,12 @@
+package com.company.cloud.sdk.weixin.mini;
+
+/**
+ * 微信小程序直播(直播间)接口
+ * */
+@Deprecated
+public class WxLivePlayerRoomApi {
+
+
+
+
+}

+ 40 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxMessageCustomerApi.java

@@ -0,0 +1,40 @@
+package com.company.cloud.sdk.weixin.mini;
+
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniApiType;
+import com.company.cloud.sdk.weixin.mini.model.message.MediaUploadModel;
+import com.company.cloud.sdk.weixin.mini.model.message.MediaUploadResp;
+import com.company.cloud.sdk.weixin.mini.model.message.SendToUserModel;
+import com.company.cloud.sdk.weixin.mini.model.message.SetMsgTypingModel;
+import com.company.cloud.sdk.weixin.mini.utils.WxMiniUtils;
+
+/**
+ * 小程序客服消息API
+ * */
+public class WxMessageCustomerApi {
+
+
+    /**
+     * 发送客服消息给用户
+     * 参考:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.send.html
+     */
+    public static BaseRespModel send(SendToUserModel entity) {
+        return WxMiniUtils.postReq(new BaseRespModel(), WxMiniApiType.SendToUser.getType(), entity);
+    }
+
+    /**
+     * 下发客服当前输入状态给用户
+     * 参考:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.setTyping.html
+     */
+    public static BaseRespModel setTyping(SetMsgTypingModel entity) {
+        return WxMiniUtils.postReq(new BaseRespModel(), WxMiniApiType.SendTypingCommand.getType(), entity);
+    }
+
+    /**
+     * 把媒体文件上传到微信服务器
+     * 参考:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.uploadTempMedia.html
+     */
+    public static MediaUploadResp uploadTempMedia(MediaUploadModel entity) {
+        return WxMiniUtils.formReq(new MediaUploadResp(), WxMiniApiType.MediaUpload.getType(), entity);
+    }
+}

+ 34 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxMessageDynamicApi.java

@@ -0,0 +1,34 @@
+package com.company.cloud.sdk.weixin.mini;
+
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniApiType;
+import com.company.cloud.sdk.weixin.mini.model.message.CreateActivityIdModel;
+import com.company.cloud.sdk.weixin.mini.model.message.CreateActivityIdResp;
+import com.company.cloud.sdk.weixin.mini.model.message.SetUpdatableMsgModel;
+import com.company.cloud.sdk.weixin.mini.utils.WxMiniUtils;
+
+/**
+ * 小程序动态信息API
+ * */
+public class WxMessageDynamicApi {
+
+
+    /**
+     * 创建被分享动态消息或私密消息的 activity_id
+     * 参考: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.createActivityId.html
+     */
+    public static CreateActivityIdResp createActivityId(CreateActivityIdModel entity) {
+        return WxMiniUtils.getReq(new CreateActivityIdResp(), WxMiniApiType.CreateActivityId.getType(), entity);
+    }
+
+    /**
+     * 修改被分享的动态消息
+     * 参考: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.setUpdatableMsg.html
+     */
+    public static BaseRespModel setUpdatableMsg(SetUpdatableMsgModel entity) {
+        return WxMiniUtils.postReq(new BaseRespModel(), WxMiniApiType.SetUpdatableMsg.getType(), entity);
+    }
+
+
+
+}

+ 83 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/WxMiniApi.java

@@ -0,0 +1,83 @@
+package com.company.cloud.sdk.weixin.mini;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.company.cloud.sdk.weixin.common.constant.WxErrorEnum;
+import com.company.cloud.sdk.weixin.common.exception.WxException;
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniApiType;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniDomain;
+import com.company.cloud.sdk.weixin.mini.model.Code2SessionModel;
+import com.company.cloud.sdk.weixin.mini.model.Code2SessionResp;
+import com.company.cloud.sdk.weixin.mini.model.DecryptDataModel;
+import com.company.cloud.sdk.weixin.mini.model.WxMiniSendMsgModel;
+import com.company.cloud.sdk.weixin.mini.utils.WxMiniUtils;
+import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Map;
+
+/**微信小程序API*/
+public class WxMiniApi {
+
+
+    /**
+     * 登录凭证校验
+     */
+    public static Code2SessionResp code2Session(Code2SessionModel model) {
+        return  WxMiniUtils.getReq(new Code2SessionResp(), WxMiniApiType.Code2Session.getType(), model);
+    }
+
+    /**
+     * 小程序消息服务uniformMessage.send
+     * https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
+     */
+    public static BaseRespModel uniformSend(WxMiniSendMsgModel model) {
+        return WxMiniUtils.postReq(new BaseRespModel(), WxMiniApiType.SendMessage.getType(), model.toMap());
+    }
+
+    /**
+     * 数据解密
+     * */
+    public static String decryptData(DecryptDataModel entity){
+        if(entity==null){
+            throw new WxException(WxErrorEnum.WX_Para_NULL);
+        }
+        if(StrUtil.hasEmpty(entity.getEncryptedData(),entity.getIv(),entity.getSessionKey())){
+            throw new WxException(WxErrorEnum.WX_Para_NULL);
+        }
+        try {
+            byte[] encrypData = Base64.decode(entity.getEncryptedData());
+            byte[] ivData = Base64.decode(entity.getIv());
+            byte[] sessionKeyByte = Base64.decode(entity.getSessionKey());
+            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
+            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+            SecretKeySpec keySpec = new SecretKeySpec(sessionKeyByte, "AES");
+            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
+            //解析解密后的字符串
+            String decryptDataResult = new String(cipher.doFinal(encrypData),"UTF-8");
+            System.out.println(StrUtil.format("++++解析解密后的字符串={}",decryptDataResult));
+            JSONObject jsonObjects = JSONObject.parseObject(decryptDataResult);
+            return jsonObjects.getString("phoneNumber");
+        }catch (Exception e){
+            System.out.println(e);
+            throw new WxException(WxErrorEnum.WX_Decrypt_ERROR);
+        }
+    }
+
+
+    public static void main(String[] args) {
+        Code2SessionModel param=new Code2SessionModel();
+        param.setAppid("wxc42ae6dc5e0882e1");
+        param.setSecret("ba5593185158601be7cbe40e19b4221e");
+        param.setJs_code("0f1NelFa1ZgesF0bqYGa1ZAqLS3NelFy");
+        Code2SessionResp resp= WxMiniApi.code2Session(param);
+        System.out.println(resp.getOpenid());
+    }
+}

+ 47 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/enums/WxMiniApiType.java

@@ -0,0 +1,47 @@
+package com.company.cloud.sdk.weixin.mini.enums;
+/**
+ * <p>微信小程序接口枚举</p>
+ */
+public enum WxMiniApiType {
+
+    /**登录凭证校验*/
+    Code2Session("/sns/jscode2session"),
+
+    /**小程序和公众号统一的服务消息*/
+    SendMessage("/cgi-bin/message/wxopen/template/uniform_send"),
+
+
+    /***/
+
+    CreateActivityId("/cgi-bin/message/wxopen/activityid/create"),
+    SetUpdatableMsg("/cgi-bin/message/wxopen/updatablemsg/send"),
+
+
+    SendToUser("/cgi-bin/message/custom/send"),
+    SendTypingCommand("/cgi-bin/message/custom/typing"),
+    MediaUpload("/cgi-bin/media/upload"),
+
+    /***/
+
+    /***/
+
+    ;
+
+    /**
+     * 类型
+     */
+    private final String type;
+
+    WxMiniApiType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    @Override
+    public String toString() {
+        return type;
+    }
+}

+ 33 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/enums/WxMiniDomain.java

@@ -0,0 +1,33 @@
+package com.company.cloud.sdk.weixin.mini.enums;
+
+/**
+ *  微信小程序可用域名枚举
+ * */
+public enum WxMiniDomain {
+
+
+    /**
+     * 中国国内
+     */
+    CHINA("https://api.weixin.qq.com")
+    ;
+
+    /**
+     * 域名
+     */
+    private final String domain;
+
+    WxMiniDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getType() {
+        return domain;
+    }
+
+    @Override
+    public String toString() {
+        return domain;
+    }
+
+}

+ 78 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/enums/WxMiniEnum.java

@@ -0,0 +1,78 @@
+package com.company.cloud.sdk.weixin.mini.enums;
+
+public class WxMiniEnum {
+
+
+    public enum DistributionIndexEnum{
+
+        /**
+         *场景值参考:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/analysis.getVisitDistribution.html
+         */
+        Source_Session_Cnt("access_source_session_cnt", "访问来源分布"),
+        Staytime_Info("access_staytime_info", "访问时长分布"),
+        Depth_Info("access_depth_info", "访问深度的分布")
+        ;
+        private String code;
+        private String msg;
+        private DistributionIndexEnum(String code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+        public String getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+
+
+    /*客服发送消息*/
+    public enum KfMsgType{
+        /**
+         *场景值参考:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/analysis.getVisitDistribution.html
+         */
+        Kf_Text("text", "文本消息"),
+        Kf_Image("image", "图片消息"),
+        Kf_Link("link", "图文链接"),
+        Kf_Miniprogrampage("miniprogrampage","小程序卡片")
+        ;
+        private String code;
+        private String msg;
+        private KfMsgType(String code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+        public String getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+
+    /*客服当前输入状态指令*/
+    public enum KfTypingCommand{
+        KF_TYPING("Typing", "对用户下发\"正在输入\"状态"),
+        Kf_Cancel_Typing("CancelTyping", "取消对用户的\"正在输入\"状态")
+        ;
+        private String code;
+        private String msg;
+        private KfTypingCommand(String code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+        public String getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+
+
+
+}

+ 26 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/Code2SessionModel.java

@@ -0,0 +1,26 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import com.company.cloud.sdk.weixin.common.model.BaseModel;
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import lombok.Getter;
+import lombok.Setter;
+
+//@Builder
+//@AllArgsConstructor
+@Getter
+@Setter
+public class Code2SessionModel extends BaseReqModel {
+
+    /**小程序 appId(是)*/
+    private String appid;
+
+    /**小程序 appSecret(是)*/
+    private String secret;
+
+    /**登录时获取的 code(是)*/
+    private String js_code;
+
+    /**授权类型(是)*/
+    private String grant_type="authorization_code";
+
+}

+ 20 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/Code2SessionResp.java

@@ -0,0 +1,20 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class Code2SessionResp extends BaseRespModel {
+
+    /**用户唯一标识*/
+    private String openid;
+
+    /**会话密钥*/
+    private String session_key;
+
+    /**用户在开放平台的唯一标识符*/
+    private String unionid;
+
+}

+ 20 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/DecryptDataModel.java

@@ -0,0 +1,20 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import com.company.cloud.sdk.weixin.common.model.BaseModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 加密数据解密算法
+ * */
+@Getter
+@Setter
+public class DecryptDataModel extends BaseModel {
+
+    /**加密内容*/
+    private String encryptedData;
+    /***/
+    private String iv;
+    /***/
+    private String sessionKey;
+}

+ 18 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/MiniprogramMsgModel.java

@@ -0,0 +1,18 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 公众号模板消息所要跳转的小程序
+ * */
+@Getter
+@Setter
+@AllArgsConstructor
+public class MiniprogramMsgModel {
+    /***/
+    private String appid;
+    /***/
+    private String pagepath;
+}

+ 25 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/MpTemplateMsgModel.java

@@ -0,0 +1,25 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+/**
+ * 公众号模板消息相关的信息
+ * */
+@Getter
+@Setter
+public class MpTemplateMsgModel {
+    /**公众号appid,要求与小程序有绑定且同主体*/
+    private String appid;
+    /**公众号模板id*/
+    private String template_id;
+    /**公众号模板消息所要跳转的url*/
+    private String url;
+    /**公众号模板消息所要跳转的小程序,小程序的必须与公众号具有绑定关系*/
+    private MiniprogramMsgModel miniprogram;
+    /**公众号模板消息的数据*/
+    private Map<String, WxMpDataValModel> data;
+
+}

+ 24 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WeappTemplateMsgModel.java

@@ -0,0 +1,24 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+/**
+ * 小程序模板消息相关的信息
+ * */
+@Getter
+@Setter
+public class WeappTemplateMsgModel {
+    /**小程序模板ID*/
+    private String template_id;
+    /**小程序页面路径*/
+    private String page;
+    /**小程序模板消息formid*/
+    private String form_id;
+    /**小程序模板数据*/
+    private Map<String, WxMiniDataValModel> data;
+    /**小程序模板放大关键词*/
+    private String emphasis_keyword;
+}

+ 17 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WxMiniDataValModel.java

@@ -0,0 +1,17 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小程序模板数据
+ * */
+@Getter
+@Setter
+@AllArgsConstructor
+public class WxMiniDataValModel {
+    /***/
+    private String value;
+}
+

+ 21 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WxMiniSendMsgModel.java

@@ -0,0 +1,21 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小程序消息服务
+ * */
+@Getter
+@Setter
+public class WxMiniSendMsgModel extends BaseReqModel {
+
+    /**用户openid*/
+    private String touser;
+    /**小程序模板消息相关的信息,可以参考小程序模板消息接口; 有此节点则优先发送小程序模板消息*/
+    private WeappTemplateMsgModel weapp_template_msg;
+    /**公众号模板消息相关的信息,可以参考公众号模板消息接口;有此节点并且没有weapp_template_msg节点时,发送公众号模板消息*/
+    private MpTemplateMsgModel mp_template_msg;
+
+}

+ 28 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/WxMpDataValModel.java

@@ -0,0 +1,28 @@
+package com.company.cloud.sdk.weixin.mini.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 公众号模板消息的数据
+ * */
+@Getter
+@Setter
+public class WxMpDataValModel {
+    /***/
+    private String value;
+    /***/
+    private String color = "#000000";
+
+    public WxMpDataValModel(String value){
+        this.value = value;
+        this.color = "#000000";
+    }
+
+    public WxMpDataValModel(String value, String color){
+        this.value = value;
+        this.color = color;
+    }
+
+}
+

+ 27 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/CreateActivityIdModel.java

@@ -0,0 +1,27 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import cn.hutool.core.util.StrUtil;
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CreateActivityIdModel extends BaseReqModel {
+
+    /**
+     * 为私密消息创建activity_id时,指定分享者为unionid用户。其余用户不能用此activity_id分享私密消息。openid与unionid填一个即可。私密消息暂不支持云函数生成activity id
+     */
+    private String unionid;
+    private String openid;
+
+//    @AssertTrue(message = "unionid,openid不能同时为空")
+    private Boolean check(){
+        if(StrUtil.isBlank(unionid)||StrUtil.isBlank(openid)){
+            return false;
+        }
+        return true;
+    }
+
+
+}

+ 21 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/CreateActivityIdResp.java

@@ -0,0 +1,21 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CreateActivityIdResp extends BaseRespModel {
+
+    /**
+     *动态消息的 ID
+     */
+    private String activity_id;
+    /**
+     *activity_id 的过期时间戳。默认24小时后过期。
+     */
+    private Integer expiration_time;
+
+
+}

+ 31 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/MediaUploadModel.java

@@ -0,0 +1,31 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.AssertTrue;
+import java.io.File;
+
+@Getter
+@Setter
+public class MediaUploadModel extends BaseReqModel {
+
+    /**
+     *文件类型(只能传image类型)
+     */
+    private String type="image";
+
+    @AssertTrue(message = "只支持image文件类型")
+    private Boolean checkType(){
+        if(!"image".equals(type)){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     *是 form-data 中媒体文件标识,有filename、filelength、content-type等信息
+     */
+    private File media;
+}

+ 25 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/MediaUploadResp.java

@@ -0,0 +1,25 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class MediaUploadResp extends BaseRespModel {
+
+    /**
+     *媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb,主要用于视频与音乐格式的缩略图)
+     */
+    private String type;
+    /**
+     *媒体文件上传后,获取标识
+     */
+    private String media_id;
+    /**
+     *媒体文件上传时间戳
+     */
+    private Integer created_at;
+
+
+}

+ 112 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/SendToUserModel.java

@@ -0,0 +1,112 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import cn.hutool.core.util.StrUtil;
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import com.company.cloud.sdk.weixin.common.utils.EnumValid;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniEnum;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class SendToUserModel extends BaseReqModel {
+
+
+    /**
+     *用户的 OpenID
+     */
+    @NotEmpty(message = "用户的OpenID不能为空")
+    private String touser;
+    /**
+     *消息类型
+     */
+    @NotEmpty(message = "消息类型不能为空")
+    @EnumValid(target = WxMiniEnum.KfMsgType.class,message = "消息类型传值非法")
+    private String msgtype;
+    /**
+     *文本消息(msgtype="text" 时必填)
+     */
+    private TextMessage text;
+
+    @AssertTrue
+    private Boolean isHaveText(){
+        if(WxMiniEnum.KfMsgType.Kf_Text.getCode().equals(msgtype)){
+            if(StrUtil.isBlank(text.getContent())){
+                return false;
+            }
+        }
+        return true;
+    }
+    /**
+     *图片消息,msgtype="image" 时必填
+     */
+    private ImageMessage	imag;
+    @AssertTrue
+    private Boolean isHaveImag(){
+        if(WxMiniEnum.KfMsgType.Kf_Image.getCode().equals(msgtype)){
+            if(StrUtil.isBlank(imag.getMedia_id())){
+                return false;
+            }
+        }
+        return true;
+    }
+    /**
+     *图文链接,msgtype="link" 时必填
+     */
+    private LinkMessage	link;
+    @AssertTrue
+    private Boolean isHaveLink(){
+        if(WxMiniEnum.KfMsgType.Kf_Link.getCode().equals(msgtype)){
+            if(StrUtil.isBlank(link.getTitle())
+                    ||StrUtil.isBlank(link.getDescription())
+                    ||StrUtil.isBlank(link.getThumb_url())
+                    ||StrUtil.isBlank(link.getUrl())){
+                return false;
+            }
+        }
+        return true;
+    }
+    /**
+     *小程序卡片,msgtype="miniprogrampage" 时必填
+     */
+    private MiniprogrampageMessage	miniprogrampage;
+    @AssertTrue
+    private Boolean isHaveMiniprogrampage(){
+        if(WxMiniEnum.KfMsgType.Kf_Miniprogrampage.getCode().equals(msgtype)){
+            if(StrUtil.isBlank(miniprogrampage.getTitle())
+                    ||StrUtil.isBlank(miniprogrampage.getPagepath())
+                    || StrUtil.isBlank(miniprogrampage.getThumb_media_id())){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Data
+    public static class TextMessage {
+        private String content;
+    }
+    @Data
+    private class ImageMessage {
+        private String media_id;
+    }
+    @Data
+    private class LinkMessage {
+        private String title;
+        private String description;
+        private String url;
+        private String thumb_url;
+    }
+    @Data
+    private class MiniprogrampageMessage {
+        private String title;
+        private String pagepath;
+        private String thumb_media_id;
+    }
+
+
+}

+ 29 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/SetMsgTypingModel.java

@@ -0,0 +1,29 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniEnum;
+import com.company.cloud.sdk.weixin.common.utils.EnumValid;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class SetMsgTypingModel extends BaseReqModel {
+
+    /**
+     * 必传
+     * 普通用户(openid)
+     */
+    @NotEmpty(message = "用户openid不能为空")
+    private String touser;
+
+    /**
+     * 必传
+     * "Typing":对用户下发“正在输入"状态  "CancelTyping":取消对用户的”正在输入"状态
+     */
+    @NotEmpty(message = "指令不能为空")
+    @EnumValid(target = WxMiniEnum.KfTypingCommand.class,message = "输入状态指令不合法")
+    private String command;
+}

+ 47 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/model/message/SetUpdatableMsgModel.java

@@ -0,0 +1,47 @@
+package com.company.cloud.sdk.weixin.mini.model.message;
+
+import com.company.cloud.sdk.weixin.common.model.BaseReqModel;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Getter
+@Setter
+public class SetUpdatableMsgModel extends BaseReqModel {
+
+
+    /**
+     *动态消息的 ID,通过 updatableMessage.createActivityId 接口获取
+     */
+    @NotEmpty(message = "消息Id不能为空")
+    private String activity_id;
+    /**
+     *动态消息修改后的状态[0,未开始,1已开始]
+     */
+    @NotNull
+    private Integer target_state;
+    /**
+     *动态消息对应的模板信息
+     */
+    @NotNull
+    private TemplateInfo template_info;
+
+    @Data
+    public static class TemplateInfo {
+        private List<Parme> parameter_list;
+
+        @Data
+        public static class Parme {
+            @NotEmpty
+            private String name;
+            @NotEmpty
+            private String value;
+        }
+    }
+
+
+}

+ 43 - 0
weixin-java-mini/src/main/java/com/company/cloud/sdk/weixin/mini/utils/WxMiniUtils.java

@@ -0,0 +1,43 @@
+package com.company.cloud.sdk.weixin.mini.utils;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.company.cloud.sdk.weixin.common.constant.WxErrorEnum;
+import com.company.cloud.sdk.weixin.common.constant.WxHttpMethodEnum;
+import com.company.cloud.sdk.weixin.common.exception.WxException;
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+import com.company.cloud.sdk.weixin.common.utils.WxHttpRequestUtils;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniApiType;
+import com.company.cloud.sdk.weixin.mini.enums.WxMiniDomain;
+
+import java.util.Map;
+
+public class WxMiniUtils {
+
+
+
+
+    public static <T extends BaseRespModel> T getResp(T t, String wxApi, WxHttpMethodEnum method, WxMiniDomain wxDomain, Object entity) {
+        if (null == wxDomain) {
+            wxDomain = WxMiniDomain.CHINA;
+        }
+        return WxHttpRequestUtils.getResp(t, wxApi, method, wxDomain.getType(), entity);
+    }
+
+    // get请求
+    public static <T extends BaseRespModel> T getReq(T t, String wxApi, Object entity) {
+        return WxHttpRequestUtils.getReq(t, wxApi, WxMiniDomain.CHINA.getType(), entity);
+    }
+
+    // post请求
+    public static <T extends BaseRespModel> T postReq(T t, String wxApi, Object entity) {
+        return WxHttpRequestUtils.postReq(t, wxApi, WxMiniDomain.CHINA.getType(), entity);
+    }
+
+    // 表单请求
+    public static <T extends BaseRespModel> T formReq(T t, String wxApi, Object entity) {
+        return WxHttpRequestUtils.formReq(t, wxApi, WxMiniDomain.CHINA.getType(), entity);
+    }
+}

+ 24 - 0
weixin-java-mp/pom.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.company.cloud.sdk</groupId>
+        <artifactId>wx-sdk</artifactId>
+        <version>2.0.0</version>
+    </parent>
+    <groupId>com.company.cloud.sdk</groupId>
+    <artifactId>weixin-java-mp</artifactId>
+    <description>微信公众号Java SDK</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.company.cloud.sdk</groupId>
+            <artifactId>weixin-java-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+
+</project>

+ 178 - 0
weixin-java-mp/src/main/java/com/company/cloud/sdk/weixin/mp/WxMpApi.java

@@ -0,0 +1,178 @@
+package com.company.cloud.sdk.weixin.mp;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSON;
+import com.company.cloud.sdk.weixin.common.model.WxJSSDKSignModel;
+import com.company.cloud.sdk.weixin.common.utils.WxJSSDKSignUtils;
+import com.company.cloud.sdk.weixin.mp.enums.WxMpApiType;
+import com.company.cloud.sdk.weixin.mp.enums.WxMpDomain;
+import com.company.cloud.sdk.weixin.mp.model.*;
+import com.company.cloud.sdk.weixin.mp.model.autoreply.CurrentAutoReplyInfoModel;
+import com.company.cloud.sdk.weixin.mp.model.msgmanage.SendTempMsgModel;
+import com.company.cloud.sdk.weixin.mp.model.msgmanage.SendTempMsgResp;
+import com.company.cloud.sdk.weixin.mp.utils.WxMpUtils;
+import com.company.cloud.sdk.weixin.common.model.BaseRespModel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**微信公众号API*/
+public class WxMpApi {
+
+    /**
+     * 基础access_token:access_token (公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token)
+     * */
+    public static AccessTokenResp accessToken(AccessTokenModel entity){
+        Map<String, Object> params =  BeanUtil.beanToMap(entity,false,true);
+        return WxMpUtils.getReq(new AccessTokenResp(), WxMpApiType.Access_Token, params);
+    }
+
+    /**
+     * jsapi_ticket
+     * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
+     * */
+    public static JsapiTicketResp jsapiTicket(JsapiTicketModel entity){
+        Map<String, Object> params =  BeanUtil.beanToMap(entity,false,true);
+        return WxMpUtils.getReq(new JsapiTicketResp(), WxMpApiType.Jsapi_Ticket, params);
+    }
+
+    /**
+     *网页授权:用户同意授权,获取code
+     * */
+    public static Authorize2CodeResp authorize2Code(Authorize2CodeModel entity) {
+        String url = WxMpUtils.getReqUrl(WxMpApiType.Authorize2Code, WxMpDomain.OPEN);
+        String path = url.concat("?appid="+entity.getAppid()+"&redirect_uri="+entity.getRedirect_uri()+"&response_type=code&scope="+entity.getScope().getScope()+"&state="+entity.getState()+"#wechat_redirect");
+        Authorize2CodeResp resp = new Authorize2CodeResp();
+        resp.setUrl(path);
+        return  resp;
+    }
+
+    /**
+     *页面access_token:通过code换取网页授权access_token
+     * */
+    public static Code2AccessTokenResp code2Ticket(Code2AccessTokenModel entity){
+        Map<String, Object> params =  BeanUtil.beanToMap(entity,false,true);
+        return WxMpUtils.getReq(new Code2AccessTokenResp(), WxMpApiType.Code2AccessToken, params);
+    }
+
+    /**
+     * 刷新页面access_token:使用refresh_token进行刷新页面access_token,
+     * refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权
+     * */
+    public static RefreshTokenResp token2RefreshToken(RefreshTokenModel entity) {
+        Map<String, Object> params =  BeanUtil.beanToMap(entity,false,true);
+        return WxMpUtils.getReq(new RefreshTokenResp(), WxMpApiType.RefreshToken, params);
+    }
+
+    /**
+     * 拉取用户信息(需scope为 snsapi_userinfo)
+     * 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了
+     * */
+    public static MpUserInfoResp userInfo(MpUserInfoModel entity) {
+        Map<String, Object> params =  BeanUtil.beanToMap(entity,false,true);
+        return WxMpUtils.getReq(new MpUserInfoResp(), WxMpApiType.UserInfo, params);
+    }
+
+    /**
+     * 页面access_token:检验授权凭证(access_token)是否有效
+     * */
+    public static CurrentAutoReplyInfoModel authAccessToken(AuthTokenModel entity) {
+        Map<String, Object> params =  BeanUtil.beanToMap(entity,false,true);
+        return WxMpUtils.getReq(new CurrentAutoReplyInfoModel(), WxMpApiType.AuthToken, params);
+    }
+
+    /**
+     * 获取公众号当前使用的自动回复规则
+     * */
+    public static BaseRespModel getCurrentAutoReplyInfo(String accessToken) {
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("access_token", accessToken);
+        return WxMpUtils.getReq(new BaseRespModel(), WxMpApiType.CurrentAutoReplyInfo, params);
+    }
+
+    public static void main(String[] args) {
+//        AccessTokenModel entity=new AccessTokenModel();
+//        entity.setAppid("wxe5bb3017fd108c5d");
+//        entity.setSecret("c1d31167a5edc9c66772bea7009ee160");
+//        AccessTokenResp data= WxMpApi.accessToken(entity);
+//        System.out.println(JSON.toJSONString(data));
+
+//        AccessTokenModel entity=new AccessTokenModel();
+//        entity.setAppid("wx3cf98c292baf4eb3");
+//        entity.setSecret("a91c7e01053d5c8f0cf278afd1dd3820");
+//        AccessTokenResp data= WxMpApi.accessToken(entity);
+//        System.out.println(JSON.toJSONString(data));
+
+
+        String accessToken="64_eWXp2VeDgHt0tFmDH5hmS9X_1ogcBSSZhdTtZqmmUN5NIxtrWv_P8Am7mijdQyISmN7K4-9IBYjPZAhx2YN-SwiXTO4TESBH2ecOgWqi5_3V0PhBfOv6UIPRcXoXKGcAHACPL";
+
+        String touser="oC3k75m9pIW3oqUuIJVVx9L4k_oM";
+        String url="https://dev1.cloud-seal.com/1";
+
+        String templateId="BIYRvHrU08dCa8I5G2tMSg1iIpm2NUgUq5iIHURw4nk";
+
+
+
+        SendTempMsgModel sendTempMsgModel=new SendTempMsgModel();
+//        sendTempMsgModel.setAccess_token(accessToken);
+        sendTempMsgModel.setTemplate_id(templateId);
+        sendTempMsgModel.setTouser(touser);
+        sendTempMsgModel.setUrl(url);
+
+//        sendTempMsgModel.addData("first.DATA","您测量的血压值上传成功,并为您生成健康报告。123");
+//        sendTempMsgModel.addData("keyword1.DATA","2018年04月02日 12:12:23");// 报告时间
+//        sendTempMsgModel.addData("keyword2.DATA","李正"); //会员名字
+//        sendTempMsgModel.addData("keyword3.DATA","您在大庆路门店测量的血压值为120/78mmHg,血压值正常。"); //报告内容
+//        sendTempMsgModel.addData("remark.DATA","怡适康为您服务。");
+
+
+        sendTempMsgModel.addData("first","您测量的血压值上传成功,并为您生成健康报告。测试");
+        sendTempMsgModel.addData("keyword1","2018年04月02日 12:12:23");// 报告时间
+        sendTempMsgModel.addData("keyword2","李正"); //会员名字
+        sendTempMsgModel.addData("keyword3","您在大庆路门店测量的血压值为120/78mmHg,血压值正常。"); //报告内容
+        sendTempMsgModel.addData("remark","怡适康为您服务。");
+
+
+//        Map<String, Object> params = BeanUtil.beanToMap(sendTempMsgModel, false, true);
+//
+//        System.out.println(JSON.toJSONString(sendTempMsgModel));
+
+        SendTempMsgResp resp =WxMpMsgManageApi.sendTempMsg(accessToken,sendTempMsgModel);
+        System.out.println(JSON.toJSONString(resp));
+
+
+
+
+//        JsapiTicketModel entity=new JsapiTicketModel();
+//        entity.setAccess_token("64_uH-1DY-K17Ie1zU-mU-vZY2ThAz8BLf4dIcD5SncmW93piT42S8S6D4WfaROgw5Kaj6_mz9gmHsz_oXQx2fbIBQItZtshh5uu9rbyf3Q8ydTiPiltbnj3dexUNcNCVhAFAIXQ");
+//        JsapiTicketResp data= WxMpApi.jsapiTicket(entity);
+//        System.out.println(JSON.toJSONString(data));
+
+//        https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
+
+
+//        AccessTokenModel  entity=new AccessTokenModel();
+//        entity.setAppid("wx3cf98c292baf4eb3");
+//        entity.setSecret("a91c7e01053d5c8f0cf278afd1dd3820");
+//        AccessTokenResp data= WxMpApi.accessToken(entity);
+//        System.out.println(JSON.toJSONString(data));
+
+
+//        WxJSSDKSignModel  data= WxJSSDKSignUtils.sign("wxe5bb3017fd108c5d",
+//                "https://1.1.1.1/a/b","LIKLckvwlJT9cWIhEQTwfCQ6zhv6QRmCv457AO5PztytZ2Yg3N1U2lcIfKF6PXNz0OKzrs3UiS3qnkTLMpwvhg");
+//        System.out.println(JSON.toJSONString(data));
+
+    }
+
+
+
+//
+//    /**
+//     * 获取用户基本信息
+//     * */
+//    public MpUserInfoResp getUserInfo(MpUserInfoModel params){
+//        return null;
+//    }
+
+
+}

Some files were not shown because too many files changed in this diff