From 941833ea1ab2477e596a2ec9e9c83288226b9c27 Mon Sep 17 00:00:00 2001 From: yuanqixun Date: Sat, 15 Sep 2018 10:33:38 +0800 Subject: [PATCH] =?UTF-8?q?#759=20=E5=A2=9E=E5=8A=A0=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E4=BB=A3=E5=B0=8F=E7=A8=8B=E5=BA=8F=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E6=8E=A5=E5=8F=A3=EF=BC=9A=E4=BB=A3=E7=A0=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E3=80=81=E6=A8=A1=E6=9D=BF=E7=AE=A1=E7=90=86=E3=80=81?= =?UTF-8?q?=E6=88=90=E5=91=98=E7=AE=A1=E7=90=86=E3=80=81=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wx/miniapp/api/impl/WxMaServiceImpl.java | 9 +- .../api/impl/WxMpMemberCardServiceImpl.java | 1 + .../impl/WxMpMemberCardServiceImplTest.java | 4 +- .../open/api/WxOpenComponentService.java | 13 +- .../weixin/open/api/WxOpenMaService.java | 335 ++++++++++++++++++ .../api/impl/WxOpenComponentServiceImpl.java | 35 +- .../open/api/impl/WxOpenMaServiceImpl.java | 312 +++++++++++++++- .../open/bean/ma/WxMaOpenCommitExtInfo.java | 96 +++++ .../open/bean/ma/WxMaOpenNetworkTimeout.java | 21 ++ .../weixin/open/bean/ma/WxMaOpenPage.java | 22 ++ .../weixin/open/bean/ma/WxMaOpenTab.java | 21 ++ .../weixin/open/bean/ma/WxMaOpenTabBar.java | 49 +++ .../weixin/open/bean/ma/WxMaOpenWindow.java | 34 ++ .../weixin/open/bean/ma/WxMaQrcodeParam.java | 86 +++++ .../weixin/open/bean/ma/WxOpenMaCategory.java | 40 +++ .../weixin/open/bean/ma/WxOpenMaMember.java | 19 + .../open/bean/ma/WxOpenMaSubmitAudit.java | 60 ++++ .../message/WxOpenMaSubmitAuditMessage.java | 21 ++ .../result/WxOpenMaCategoryListResult.java | 31 ++ .../bean/result/WxOpenMaDomainResult.java | 33 ++ .../bean/result/WxOpenMaPageListResult.java | 30 ++ .../result/WxOpenMaSubmitAuditResult.java | 26 ++ .../bean/result/WxOpenMaTesterListResult.java | 31 ++ .../ma/MaQrCodeApacheHttpRequestExecutor.java | 68 ++++ .../ma/MaQrCodeJoddHttpRequestExecutor.java | 62 ++++ .../ma/MaQrCodeOkhttpRequestExecutor.java | 59 +++ .../ma/MaQrCodeRequestExecutor.java | 37 ++ 27 files changed, 1524 insertions(+), 31 deletions(-) create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java index 7ee89cc8..df8afadd 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java @@ -4,16 +4,13 @@ import cn.binarywang.wx.miniapp.api.*; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.config.WxMaConfig; import com.google.common.base.Joiner; +import com.google.gson.Gson; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.DataUtils; import me.chanjar.weixin.common.util.crypto.SHA1; -import me.chanjar.weixin.common.util.http.HttpType; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.common.util.http.*; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; import org.apache.http.HttpHost; @@ -55,6 +52,8 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp() { diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java index 0e1502f2..67d7ce6f 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java @@ -22,8 +22,8 @@ public class WxMpMemberCardServiceImplTest { @Inject protected WxMpService wxService; - private String cardId = "p2iQk1kUixiypVJ1lJYIT-_fMdUg"; - private String code = "201808290001"; + private String cardId = "p2iQk1g2d03JXhVRDY5fZRVr236A"; + private String code = "435223630779"; private String openId = "o2iQk1u5X-XIJkatmAK1Q8VVuS90"; @Test diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index bf5cc6ff..7c1b8465 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -1,8 +1,5 @@ package me.chanjar.weixin.open.api; -import java.util.List; - -import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; @@ -13,6 +10,8 @@ import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; +import java.util.List; + /** * @author 007 */ @@ -41,7 +40,13 @@ public interface WxOpenComponentService { WxMpService getWxMpServiceByAppid(String appid); - WxMaService getWxMaServiceByAppid(String appid); + /** + * 获取指定appid的开放平台小程序服务(继承一般小程序服务能力) + * + * @param appid + * @return + */ + WxOpenMaService getWxMaServiceByAppid(String appid); WxOpenConfigStorage getWxOpenConfigStorage(); diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java new file mode 100644 index 00000000..2cb82ff7 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java @@ -0,0 +1,335 @@ +package me.chanjar.weixin.open.api; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; +import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; +import me.chanjar.weixin.open.bean.result.*; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + *
+ *     微信开放平台代小程序实现服务能力
+ *     https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489144594_DhNoV&token=&lang=zh_CN
+ * 
+ * + * @author yqx + * @date 2018/9/12 + */ +public interface WxOpenMaService extends WxMaService { + + /** + * 设置小程序服务器域名 + * + *
+   *     授权给第三方的小程序,其服务器域名只可以为第三方的服务器,当小程序通过第三方发布代码上线后,小程序原先自己配置的服务器域名将被删除,
+   *     只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加第三方自身的域名。
+   *     提示:需要先将域名登记到第三方平台的小程序服务器域名中,才可以调用接口进行配置
+   * 
+ */ + String API_MODIFY_DOMAIN = "https://api.weixin.qq.com/wxa/modify_domain"; + + /** + * 设置小程序业务域名(仅供第三方代小程序调用) + *
+   *     授权给第三方的小程序,其业务域名只可以为第三方的服务器,当小程序通过第三方发布代码上线后,小程序原先自己配置的业务域名将被删除,
+   *     只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加业务域名。
+   * 提示:
+   * 1、需要先将域名登记到第三方平台的小程序业务域名中,才可以调用接口进行配置。
+   * 2、为授权的小程序配置域名时支持配置子域名,例如第三方登记的业务域名如为qq.com,则可以直接将qq.com及其子域名(如xxx.qq.com)也配置到授权的小程序中。
+   * 
+ */ + String API_SET_WEBVIEW_DOMAIN = "https://api.weixin.qq.com/wxa/setwebviewdomain"; + + /** + * 获取帐号基本信息 + *
+   * GET请求
+   * 注意:需要使用1.3环节获取到的新创建小程序appid及authorization_code换取authorizer_refresh_token进而得到authorizer_access_token。
+   * 
+ */ + String API_GET_ACCOUNT_BASICINFO = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo"; + + /** + * 绑定微信用户为小程序体验者 + */ + String API_BIND_TESTER = "https://api.weixin.qq.com/wxa/bind_tester"; + + + /** + * 解除绑定微信用户为小程序体验者 + */ + String API_UNBIND_TESTER = "https://api.weixin.qq.com/wxa/unbind_tester"; + + + /** + * 获取体验者列表 + */ + String API_GET_TESTERLIST = "https://api.weixin.qq.com/wxa/memberauth"; + + /** + * 以下接口为三方平台代小程序实现的代码管理功能 + *

+ * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=fe774228c66725425675810097f9e48d0737a4bf&lang=zh_CN + *

+ */ + + /** + * 1. 为授权的小程序帐号上传小程序代码 + */ + String API_CODE_COMMIT = "https://api.weixin.qq.com/wxa/commit"; + + /** + * 2. 获取体验小程序的体验二维码 + */ + String API_TEST_QRCODE = "https://api.weixin.qq.com/wxa/get_qrcode"; + + /** + * 3. 获取授权小程序帐号的可选类目 + */ + String API_GET_CATEGORY = "https://api.weixin.qq.com/wxa/get_category"; + + /** + * 4. 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + */ + String API_GET_PAGE = "https://api.weixin.qq.com/wxa/get_page"; + + /** + * 5. 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + */ + String API_SUBMIT_AUDIT = "https://api.weixin.qq.com/wxa/submit_audit"; + + /** + * 7. 查询某个指定版本的审核状态(仅供第三方代小程序调用) + */ + String API_GET_AUDIT_STATUS = "https://api.weixin.qq.com/wxa/get_auditstatus"; + + /** + * 8. 查询最新一次提交的审核状态(仅供第三方代小程序调用) + */ + String API_GET_LATEST_AUDIT_STATUS = "https://api.weixin.qq.com/wxa/get_latest_auditstatus"; + + /** + * 9. 发布已通过审核的小程序(仅供第三方代小程序调用) + */ + String API_RELEASE = "https://api.weixin.qq.com/wxa/release"; + + /** + * 10. 修改小程序线上代码的可见状态(仅供第三方代小程序调用) + */ + String API_CHANGE_VISITSTATUS = "https://api.weixin.qq.com/wxa/change_visitstatus"; + + /** + * 11.小程序版本回退(仅供第三方代小程序调用) + */ + String API_REVERT_CODE_RELEASE = "https://api.weixin.qq.com/wxa/revertcoderelease"; + + /** + * 12.查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用) + */ + String API_GET_WEAPP_SUPPORT_VERSION = "https://api.weixin.qq.com/cgi-bin/wxopen/getweappsupportversion"; + + /** + * 13.设置最低基础库版本(仅供第三方代小程序调用) + */ + String API_SET_WEAPP_SUPPORT_VERSION = "https://api.weixin.qq.com/cgi-bin/wxopen/setweappsupportversion"; + + /** + * 14.设置小程序“扫普通链接二维码打开小程序”能力 + *

+ * TODO 暂时不实现 + *

+ */ + + /** + * 15.小程序审核撤回 + *

+ * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 + *

+ */ + String API_UNDO_CODE_AUDIT = "https://api.weixin.qq.com/wxa/undocodeaudit"; + + /** + * 16.1 小程序分阶段发布-分阶段发布接口 + */ + String API_GRAY_RELEASE = "https://api.weixin.qq.com/wxa/grayrelease"; + + /** + * 16.2 小程序分阶段发布-取消分阶段发布 + */ + String API_REVERT_GRAY_RELEASE = "https://api.weixin.qq.com/wxa/revertgrayrelease"; + + /** + * 16.3 小程序分阶段发布-查询当前分阶段发布详情 + */ + String API_GET_GRAY_RELEASE_PLAN = "https://api.weixin.qq.com/wxa/getgrayreleaseplan"; + + + /** + * 获得小程序的域名配置信息 + * + * @return + */ + WxOpenMaDomainResult getDomain() throws WxErrorException; + + /** + * 修改域名 + * + * @param action delete删除, set覆盖, get获取 + * @param requestdomainList + * @param wsrequestdomainList + * @param uploaddomainList + * @param downloaddomainList + * @return + * @throws WxErrorException + */ + WxOpenMaDomainResult modifyDomain(String action, List requestdomainList, List wsrequestdomainList, List uploaddomainList, List downloaddomainList) throws WxErrorException; + + /** + * 获取小程序的业务域名 + * + * @return 直接返回字符串 + */ + String getWebViewDomain() throws WxErrorException; + + /** + * 设置小程序的业务域名 + * + * @param action add添加, delete删除, set覆盖 + * @param domainList + * @return 直接返回字符串 + */ + String setWebViewDomain(String action, List domainList) throws WxErrorException; + + /** + * 获取小程序的信息 + * + * @return + * @throws WxErrorException + */ + String getAccountBasicInfo() throws WxErrorException; + + /** + * 绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + String bindTester(String wechatid) throws WxErrorException; + + /** + * 解除绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + String unbindTester(String wechatid) throws WxErrorException; + + /** + * 获得体验者列表 + * + * @return + * @throws WxErrorException + */ + WxOpenMaTesterListResult getTesterList() throws WxErrorException; + + /** + * 1、为授权的小程序帐号上传小程序代码 + * + * @param templateId 代码模板ID + * @param userVersion 用户定义版本 + * @param userDesc 用户定义版本描述 + * @param extInfo 第三方自定义的配置 + * @return + * @throws WxErrorException + */ + String codeCommit(Long templateId, String userVersion, String userDesc, WxMaOpenCommitExtInfo extInfo) throws WxErrorException; + + /** + * 获取体验小程序的体验二维码 + * + * @param pagePath + * @param params + * @return + */ + File getTestQrcode(String pagePath, Map params) throws WxErrorException; + + /** + * 获取授权小程序帐号的可选类目 + *

+ * 注意:该接口可获取已设置的二级类目及用于代码审核的可选三级类目。 + *

+ * + * @return WxOpenMaCategoryListResult + * @throws WxErrorException + */ + WxOpenMaCategoryListResult getCategoryList() throws WxErrorException; + + /** + * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + * + * @return + * @throws WxErrorException + */ + WxOpenMaPageListResult getPageList() throws WxErrorException; + + /** + * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + * + * @param submitAuditMessage + * @return + * @throws WxErrorException + */ + WxOpenMaSubmitAuditResult submitAudit(WxOpenMaSubmitAuditMessage submitAuditMessage) throws WxErrorException; + + /** + * 查询某个指定版本的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + String getAuditStatus(Long auditid) throws WxErrorException; + + /** + * 查询最新一次提交的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + String getLatestAuditStatus(Long auditid) throws WxErrorException; + + /** + * 发布已通过审核的小程序(仅供第三方代小程序调用) + * + * @return + * @throws WxErrorException + */ + String releaesAudited() throws WxErrorException; + + /** + * 11. 小程序版本回退(仅供第三方代小程序调用) + * + * @return + * @throws WxErrorException + */ + String revertCodeReleaes() throws WxErrorException; + + /** + * 15. 小程序审核撤回 + *

+ * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 + *

+ * + * @return + * @throws WxErrorException + */ + String undoCodeAudit() throws WxErrorException; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java index 69004659..2fd53dc5 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -1,14 +1,5 @@ package me.chanjar.weixin.open.api.impl; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -22,6 +13,7 @@ import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.open.api.WxOpenComponentService; import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.api.WxOpenMaService; import me.chanjar.weixin.open.api.WxOpenService; import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; @@ -32,13 +24,20 @@ import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Hashtable; +import java.util.List; +import java.util.Map; /** * @author 007 */ public class WxOpenComponentServiceImpl implements WxOpenComponentService { private static final JsonParser JSON_PARSER = new JsonParser(); - private static final Map WX_OPEN_MA_SERVICE_MAP = new Hashtable<>(); + private static final Map WX_OPEN_MA_SERVICE_MAP = new Hashtable<>(); private static final Map WX_OPEN_MP_SERVICE_MAP = new Hashtable<>(); protected final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -65,18 +64,18 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { } @Override - public WxMaService getWxMaServiceByAppid(String appId) { - WxMaService wxMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); - if (wxMaService == null) { + public WxOpenMaService getWxMaServiceByAppid(String appId) { + WxOpenMaService wxOpenMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); + if (wxOpenMaService == null) { synchronized (WX_OPEN_MA_SERVICE_MAP) { - wxMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); - if (wxMaService == null) { - wxMaService = new WxOpenMaServiceImpl(this, appId, getWxOpenConfigStorage().getWxMaConfig(appId)); - WX_OPEN_MA_SERVICE_MAP.put(appId, wxMaService); + wxOpenMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); + if (wxOpenMaService == null) { + wxOpenMaService = new WxOpenMaServiceImpl(this, appId, getWxOpenConfigStorage().getWxMaConfig(appId)); + WX_OPEN_MA_SERVICE_MAP.put(appId, wxOpenMaService); } } } - return wxMaService; + return wxOpenMaService; } public WxOpenService getWxOpenService() { diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java index acadd7e6..2cdfcc45 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java @@ -1,16 +1,34 @@ package me.chanjar.weixin.open.api.impl; -import cn.binarywang.wx.miniapp.api.WxMaUserService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenMaService; +import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; +import me.chanjar.weixin.open.bean.result.*; +import me.chanjar.weixin.open.util.requestexecuter.ma.MaQrCodeRequestExecutor; + +import java.io.File; +import java.util.List; +import java.util.Map; /** * @author 007 + *
+ *     增加开放平台代小程序管理服务能力
+ *     说明:这里让这个服务公开便于调用者模拟本地测试服务
+ * 
+ * @author yqx + * @date 2018-09-12 */ -/* package */ class WxOpenMaServiceImpl extends WxMaServiceImpl { +public class WxOpenMaServiceImpl extends WxMaServiceImpl implements WxOpenMaService { private WxOpenComponentService wxOpenComponentService; private WxMaConfig wxMaConfig; private String appId; @@ -26,6 +44,7 @@ import me.chanjar.weixin.open.api.WxOpenComponentService; public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException { return wxOpenComponentService.miniappJscode2Session(appId, jsCode); } + @Override public WxMaConfig getWxMaConfig() { return wxMaConfig; @@ -35,4 +54,293 @@ import me.chanjar.weixin.open.api.WxOpenComponentService; public String getAccessToken(boolean forceRefresh) throws WxErrorException { return wxOpenComponentService.getAuthorizerAccessToken(appId, forceRefresh); } + + /** + * 获得小程序的域名配置信息 + * + * @return + */ + @Override + public WxOpenMaDomainResult getDomain() throws WxErrorException { + return modifyDomain("get", null, null, null, null); + } + + /** + * 修改服务器域名 + * + * @param action delete删除, set覆盖, get获取 + * @param requestdomainList + * @param wsrequestdomainList + * @param uploaddomainList + * @param downloaddomainList + * @return + * @throws WxErrorException + */ + public WxOpenMaDomainResult modifyDomain(String action, List requestdomainList, List wsrequestdomainList, List uploaddomainList, List downloaddomainList) throws WxErrorException { + +// if (!"get".equals(action) && (requestdomainList == null || wsrequestdomainList == null || uploaddomainList == null || downloaddomainList == null)) { +// throw new WxErrorException(WxError.builder().errorCode(44004).errorMsg("域名参数不能为空").build()); +// } + JsonObject requestJson = new JsonObject(); + requestJson.addProperty("action", action); + if (!"get".equals(action)) { + requestJson.add("requestdomain", toJsonArray(requestdomainList)); + requestJson.add("wsrequestdomain", toJsonArray(wsrequestdomainList)); + requestJson.add("uploaddomain", toJsonArray(uploaddomainList)); + requestJson.add("downloaddomain", toJsonArray(downloaddomainList)); + } + String response = post(API_MODIFY_DOMAIN, GSON.toJson(requestJson)); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaDomainResult.class); + } + + /** + * 获取小程序的业务域名 + * + * @return + */ + @Override + public String getWebViewDomain() throws WxErrorException { + return setWebViewDomain("get", null); + } + + /** + * 设置小程序的业务域名 + * + * @param action add添加, delete删除, set覆盖 + * @param domainList + * @return + */ + @Override + public String setWebViewDomain(String action, List domainList) throws WxErrorException { + JsonObject requestJson = new JsonObject(); + requestJson.addProperty("action", action); + if (!"get".equals(action)) { + requestJson.add("webviewdomain", toJsonArray(domainList)); + } + String response = post(API_SET_WEBVIEW_DOMAIN, GSON.toJson(requestJson)); + //TODO 转化为对象返回 + return response; + } + + /** + * 获取小程序的信息,GET请求 + *
+   *     注意:这里不能直接用小程序的access_token
+   *     //TODO 待调整
+   * 
+ * + * @return + * @throws WxErrorException + */ + @Override + public String getAccountBasicInfo() throws WxErrorException { + String response = get(API_GET_ACCOUNT_BASICINFO, ""); + return response; + } + + /** + * 绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + @Override + public String bindTester(String wechatid) throws WxErrorException { + JsonObject paramJson = new JsonObject(); + paramJson.addProperty("wechatid", wechatid); + String response = post(API_BIND_TESTER, GSON.toJson(paramJson)); + return response; + } + + /** + * 解除绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + @Override + public String unbindTester(String wechatid) throws WxErrorException { + JsonObject paramJson = new JsonObject(); + paramJson.addProperty("wechatid", wechatid); + String response = post(API_UNBIND_TESTER, GSON.toJson(paramJson)); + return response; + } + + /** + * 获得体验者列表 + * + * @return + * @throws WxErrorException + */ + @Override + public WxOpenMaTesterListResult getTesterList() throws WxErrorException { + JsonObject paramJson = new JsonObject(); + paramJson.addProperty("action", "get_experiencer"); + String response = post(API_GET_TESTERLIST, GSON.toJson(paramJson)); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaTesterListResult.class); + } + + /** + * 1、为授权的小程序帐号上传小程序代码 + * + * @param templateId 代码模板ID + * @param userVersion 用户定义版本 + * @param userDesc 用户定义版本描述 + * @param extInfo 第三方自定义的配置 + * @return + * @throws WxErrorException + */ + @Override + public String codeCommit(Long templateId, String userVersion, String userDesc, WxMaOpenCommitExtInfo extInfo) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("template_id", templateId); + params.addProperty("user_version", userVersion); + params.addProperty("user_desc", userDesc); + //注意:ext_json必须是字符串类型 + params.addProperty("ext_json", GSON.toJson(extInfo)); + String response = post(API_CODE_COMMIT, GSON.toJson(params)); + return response; + } + + /** + * 获取体验小程序的体验二维码 + * + * @param pagePath + * @param params + * @return + */ + @Override + public File getTestQrcode(String pagePath, Map params) throws WxErrorException { + WxMaQrcodeParam qrcodeParam = WxMaQrcodeParam.create(pagePath); + qrcodeParam.addPageParam(params); + return execute(MaQrCodeRequestExecutor.create(getRequestHttp()), API_TEST_QRCODE, qrcodeParam); + } + + /** + * 获取授权小程序帐号的可选类目 + *

+ * 注意:该接口可获取已设置的二级类目及用于代码审核的可选三级类目。 + *

+ * + * @return WxOpenMaCategoryListResult + * @throws WxErrorException + */ + @Override + public WxOpenMaCategoryListResult getCategoryList() throws WxErrorException { + String response = get(API_GET_CATEGORY, null); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaCategoryListResult.class); + } + + /** + * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + * + * @return + * @throws WxErrorException + */ + @Override + public WxOpenMaPageListResult getPageList() throws WxErrorException { + String response = get(API_GET_PAGE, null); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaPageListResult.class); + } + + /** + * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + * + * @param submitAuditMessage + * @return + * @throws WxErrorException + */ + public WxOpenMaSubmitAuditResult submitAudit(WxOpenMaSubmitAuditMessage submitAuditMessage) throws WxErrorException { + String response = post(API_SUBMIT_AUDIT, GSON.toJson(submitAuditMessage)); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaSubmitAuditResult.class); + } + + /** + * 7. 查询某个指定版本的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + @Override + public String getAuditStatus(Long auditid) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("auditid", auditid); + String response = post(API_GET_AUDIT_STATUS, GSON.toJson(params)); + return response; + } + + /** + * 8. 查询最新一次提交的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + @Override + public String getLatestAuditStatus(Long auditid) throws WxErrorException { + String response = get(API_GET_LATEST_AUDIT_STATUS, null); + return response; + } + + /** + * 9. 发布已通过审核的小程序(仅供第三方代小程序调用) + *

+ * 请填写空的数据包,POST的json数据包为空即可。 + *

+ * + * @return + * @throws WxErrorException + */ + @Override + public String releaesAudited() throws WxErrorException { + JsonObject params = new JsonObject(); + String response = post(API_RELEASE, GSON.toJson(params)); + return response; + } + + /** + * 11. 小程序版本回退(仅供第三方代小程序调用) + * + * @return + * @throws WxErrorException + */ + @Override + public String revertCodeReleaes() throws WxErrorException { + String response = get(API_REVERT_CODE_RELEASE, null); + return response; + } + + /** + * 15. 小程序审核撤回 + *

+ * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 + *

+ * + * @return + * @throws WxErrorException + */ + @Override + public String undoCodeAudit() throws WxErrorException { + String response = get(API_UNDO_CODE_AUDIT, null); + return response; + } + + /** + * 将字符串对象转化为GsonArray对象 + * + * @param strList + * @return + */ + private JsonArray toJsonArray(List strList) { + JsonArray jsonArray = new JsonArray(); + if (strList != null && !strList.isEmpty()) { + for (String str : strList) { + jsonArray.add(str); + } + } + return jsonArray; + } } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java new file mode 100644 index 00000000..c38867ba --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java @@ -0,0 +1,96 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 微信小程序三方平台代上传代码提交额外信息对象 + *

+ * 如果代码中已经有配置,则配置的合并规则为:除了pages和tabBar.list直接覆盖原配置,其他都为插入或同级覆盖。 + *

+ * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenCommitExtInfo implements Serializable { + + WxMaOpenCommitExtInfo() { + + } + + /** + * 授权小程序Appid,可填入商户小程序AppID,以区分不同商户 + */ + private String extAppid; + + @SerializedName("ext") + private Map extMap; + + @SerializedName("extPages") + private Map extPages; + + /** + * 页面路径列表(和app.json结构一致) + */ + @SerializedName("pages") + private List pageList; + + @SerializedName("window") + private WxMaOpenWindow window; + + @SerializedName("networkTimeout") + private WxMaOpenNetworkTimeout networkTimeout; + + @SerializedName("tabBar") + private WxMaOpenTabBar tabBar; + + /** + * 添加扩展项 + * + * @param key + * @param value + */ + public void addExt(String key, String value) { + if (extMap == null) + extMap = new HashMap<>(); + if (StringUtils.isNoneBlank(key, value)) + extMap.put(key, value); + } + + /** + * 添加扩展页面 + * + * @param pagePath + * @param page + */ + public void addExtPage(String pagePath, WxMaOpenPage page) { + if (extPages == null) + extPages = new HashMap<>(); + if (StringUtils.isNotBlank(pagePath) && page != null) + extPages.put(pagePath, page); + } + + /** + * 添加页面 + * + * @param pagePath + */ + public void addPage(String pagePath) { + if (pageList == null) + pageList = new ArrayList<>(); + if (StringUtils.isNotBlank(pagePath)) + pageList.add(pagePath); + } + + public static WxMaOpenCommitExtInfo INSTANCE() { + return new WxMaOpenCommitExtInfo(); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java new file mode 100644 index 00000000..9717f42a --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenNetworkTimeout implements Serializable { + + private Integer request; + + private Integer connectSocket; + + private Integer uploadFile; + + private Integer downloadFile; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java new file mode 100644 index 00000000..ca63fc3d --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenPage implements Serializable { + private String navigationBarBackgroundColor; + private String navigationBarTextStyle; + private String navigationBarTitleText; + private String backgroundColor; + private String backgroundTextStyle; + private Boolean enablePullDownRefresh; + private Integer onReachBottomDistance; + private Boolean disableScroll; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java new file mode 100644 index 00000000..68d7cacb --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; +import lombok.NonNull; + +import java.io.Serializable; + +/** + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenTab implements Serializable { + @NonNull + private String pagePath; + + @NonNull + private String text; + private String iconPath; + private String selectedIconPath; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java new file mode 100644 index 00000000..6245c033 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * tabBar对象 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +@NoArgsConstructor +public class WxMaOpenTabBar implements Serializable { + @NonNull + private String color; + + @NonNull + private String selectedColor; + + @NonNull + private String backgroundColor; + + private String borderStyle; + + @NonNull + @SerializedName("list") + private List tabList; + + private String position; + + /** + * 添加tab + * + * @param text + * @param pagePath + */ + public void addTab(String text, String pagePath) { + if (tabList == null) + tabList = new ArrayList<>(); + tabList.add(new WxMaOpenTab(pagePath, text)); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java new file mode 100644 index 00000000..4848f8c7 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java @@ -0,0 +1,34 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * window对象 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenWindow implements Serializable { + private String navigationBarBackgroundColor; + + private String navigationBarTextStyle; + + private String navigationBarTitleText; + + private String navigationStyle; + + private String backgroundColor; + + private String backgroundTextStyle; + + private String backgroundColorTop; + + private String backgroundColorBottom; + + private Boolean enablePullDownRefresh; + + private Integer onReachBottomDistance; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java new file mode 100644 index 00000000..2dafa037 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java @@ -0,0 +1,86 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * 微信小程序体验二维码参数 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaQrcodeParam { + + WxMaQrcodeParam() { + + } + + /** + * 页面路径 + */ + private String pagePath; + + /** + * 页面参数 + */ + private Map pageParams; + + /** + * 添加页面参数 + * + * @param key + * @param value + */ + public WxMaQrcodeParam addPageParam(String key, String value) { + if (StringUtils.isNoneBlank(key, value)) { + if (pageParams == null) + pageParams = new HashMap<>(); + pageParams.put(key, value); + } + return this; + } + + /** + * 添加页面参数 + * + * @param params + * @return + */ + public WxMaQrcodeParam addPageParam(Map params) { + if (params != null) { + if (pageParams == null) + pageParams = new HashMap<>(); + pageParams.putAll(params); + } + return this; + } + + /** + * 组装完整的页面请求路径(带参数) + * + * @return + */ + public String getRequestPath() { + if (StringUtils.isNotBlank(getPagePath()) && getPageParams() != null && !getPageParams().isEmpty()) { + Set keys = getPageParams().keySet(); + StringBuilder sb = new StringBuilder(); + for (String key : keys) { + sb.append("&").append(key).append("=").append(getPageParams().get(key)); + } + return pagePath + "?" + sb.substring(1); + } else { + return pagePath; + } + } + + public static WxMaQrcodeParam create(String pagePath) { + WxMaQrcodeParam instance = new WxMaQrcodeParam(); + instance.setPagePath(pagePath); + return instance; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java new file mode 100644 index 00000000..88ca63ae --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 微信小程序分类目录 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxOpenMaCategory implements Serializable { + + @SerializedName("first_class") + private String firstClass; + + @SerializedName("second_class") + private String secondClass; + + @SerializedName("third_class") + private String thirdClass; + + @SerializedName("first_id") + private Integer firstId; + + @SerializedName("second_id") + private Integer secondId; + + @SerializedName("third_id") + private Integer thirdId; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java new file mode 100644 index 00000000..dc939373 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java @@ -0,0 +1,19 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 微信开放平台小程序成员对象 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaMember implements Serializable { + /** + * 人员对应的唯一字符串 + */ + private String userstr; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java new file mode 100644 index 00000000..9c9e7122 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java @@ -0,0 +1,60 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 三方平台提交小程序代码审核 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxOpenMaSubmitAudit implements Serializable { + + + /** + * 小程序的页面,可通过“获取小程序的第三方提交代码的页面配置”接口获得 + */ + @SerializedName("address") + private String pagePath; + + /** + * 小程序的标签,多个标签用空格分隔,标签不能多于10个,标签长度不超过20 + */ + @SerializedName("tag") + private String tag; + + /** + * 类目名称,可通过“获取授权小程序帐号的可选类目”接口获得 + */ + @SerializedName("first_class") + private String firstClass; + + @SerializedName("second_class") + private String secondClass; + + @SerializedName("third_class") + private String thirdClass; + + /** + * 类目的ID,可通过“获取授权小程序帐号的可选类目”接口获得 + */ + @SerializedName("first_id") + private Integer firstId; + + @SerializedName("second_id") + private Integer secondId; + + @SerializedName("third_id") + private Integer thirdId; + + /** + * 小程序页面的标题,标题长度不超过32 + */ + @SerializedName("title") + private String title; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java new file mode 100644 index 00000000..a8d806b3 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.bean.message; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaSubmitAudit; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信小程序代码包提交审核(仅供第三方开发者代小程序调用) + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxOpenMaSubmitAuditMessage implements Serializable { + + @SerializedName("item_list") + private List itemList; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java new file mode 100644 index 00000000..af113f16 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaCategory; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序分类目录列表返回 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaCategoryListResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("category_list") + List categoryList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java new file mode 100644 index 00000000..79775e4b --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java @@ -0,0 +1,33 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序域名设置返回对象 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaDomainResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("requestdomain") + List requestdomainList; + + @SerializedName("wsrequestdomain") + List wsrequestdomainList; + + @SerializedName("uploaddomain") + List uploaddomainList; + + @SerializedName("downloaddomain") + List downloaddomainList; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java new file mode 100644 index 00000000..b4c34fb2 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java @@ -0,0 +1,30 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序第三方提交代码的页面配置列表 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaPageListResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("page_list") + List pageList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java new file mode 100644 index 00000000..77f150c2 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 微信开放平台小程序发布代码审核结果 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaSubmitAuditResult implements Serializable { + + private String errcode; + private String errmsg; + + /** + * 审核编号 + */ + @SerializedName("auditid") + Long auditId; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java new file mode 100644 index 00000000..91c4af2a --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaMember; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序体验者列表返回 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaTesterListResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("members") + List membersList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java new file mode 100644 index 00000000..14bed802 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java @@ -0,0 +1,68 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * @author yqx + * @date 2018-09-13 + */ +public class MaQrCodeApacheHttpRequestExecutor extends MaQrCodeRequestExecutor { + public MaQrCodeApacheHttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMaQrcodeParam qrcodeParam) throws WxErrorException, IOException { + if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8") + : "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8"); + } + + HttpGet httpGet = new HttpGet(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpGet.setConfig(config); + } + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet); + InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) { + Header[] contentTypeHeader = response.getHeaders("Content-Type"); + if (contentTypeHeader != null && contentTypeHeader.length > 0) { + // 出错 + if (ContentType.TEXT_PLAIN.getMimeType() + .equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); + } + } + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } finally { + httpGet.releaseConnection(); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java new file mode 100644 index 00000000..5c027115 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java @@ -0,0 +1,62 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.MimeTypes; +import jodd.util.StringPool; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import org.apache.commons.lang3.StringUtils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * @author yqx + * @date 2018-09-13 + */ +public class MaQrCodeJoddHttpRequestExecutor extends MaQrCodeRequestExecutor { + public MaQrCodeJoddHttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMaQrcodeParam qrcodeParam) throws WxErrorException, IOException { + if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8") + : "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8"); + } + + + HttpRequest request = HttpRequest.get(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + String contentTypeHeader = response.header("Content-Type"); + if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) { + String responseContent = response.bodyText(); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); + } + try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) { + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java new file mode 100644 index 00000000..dbcbac9b --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java @@ -0,0 +1,59 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * @author yqx + * @date 2018-09-13 + */ +public class MaQrCodeOkhttpRequestExecutor extends MaQrCodeRequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MaQrCodeOkhttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMaQrcodeParam qrcodeParam) throws WxErrorException, IOException { + if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8") + : "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8"); + } + + OkHttpClient client = requestHttp.getRequestHttpClient(); + Request request = new Request.Builder().url(uri).get().build(); + Response response = client.newCall(request).execute(); + String contentTypeHeader = response.header("Content-Type"); + if ("text/plain".equals(contentTypeHeader)) { + String responseContent = response.body().string(); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); + } + + try (InputStream inputStream = response.body().byteStream()) { + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } + + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java new file mode 100644 index 00000000..55766d99 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java @@ -0,0 +1,37 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; + +import java.io.File; + +/** + * 获得小程序体验QrCode图片 请求执行器 + * + * @author yqx + * @date 2018-09-13 + */ +public abstract class MaQrCodeRequestExecutor implements RequestExecutor { + protected RequestHttp requestHttp; + + public MaQrCodeRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new MaQrCodeApacheHttpRequestExecutor(requestHttp); + case JODD_HTTP: + return new MaQrCodeJoddHttpRequestExecutor(requestHttp); + case OK_HTTP: + return new MaQrCodeOkhttpRequestExecutor(requestHttp); + default: + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); + } + } + +}