代小程序實現業務之代碼管理
本文將描述在公司開發平臺實現小程序代碼的上傳審覈,審覈結果獲取更新及代碼的發佈流程,詳細資料可參閱官方文檔代小程序實現業務-代碼管理;
小程序第三方平臺模板
將小程序授權給第三方平臺,授權完成之後,小程序將不能進行小程序代碼的上傳審覈,此時需要第三方平臺統一開發管理小程序模板,第三方平臺開發小程序模板版本的迭代更新升級;
新版本小程序模板進行提交審覈將進入到第三方平臺草稿箱中,小程序想要上傳發布代碼,需將小程序模板添加到小程序模板庫中,獲取小程序模板id(templateID)配合代碼程序實現代碼的提交審覈及發佈
小程序模板草稿箱
小程序模板庫及綁定測試小程序
代碼實現
給指定小程序上傳代碼
請求參數
後臺接口
/**
* @Description: 小程序上傳/提交審覈
* @Author: Mr.Jkx
* @Date: 2019/5/11 15:15
*/
@RequestMapping("/appletsUploadCheck")
@ResponseBody
public Map<String, String> appletsUploadCheck(TWarrantMerchant tWarrantMerchant) throws IOException {
TPayConfig payConfig = payService.getPayConfig(tWarrantMerchant);
if(null != payConfig){
tWarrantMerchant.setPayConfig("1");
}else{
tWarrantMerchant.setPayConfig("0");
}
Map<String, String> stringStringMap = appletsUploadCheck(tWarrantMerchant);
if(StringUtils.equals("0", stringStringMap.get("errcode"))){
TUser tUser = new TUser();
tUser.setUserId(tWarrantMerchant.getWarrantCreater());
tUser.setTemplateType("1"); // 模板狀態;1,已上傳;0,未上傳;2,審覈通過;3,發佈成功
int i = userService.updateTemplateType(tUser);
if(i > 0){
LOGGER.info("--------小程序上傳/提交審覈,數據狀態修改-------成功!!!");
}else {
LOGGER.info("--------小程序上傳/提交審覈,數據狀態修改-------失敗!!!");
}
}
return stringStringMap;
}
package com.litte.util;
import com.google.gson.JsonArray;
import com.litte.entity.reception.TWarrantMerchant;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: 第三方小程序配置相關
* @Author: Mr.Jkx
* @UpdateDate: 2019/5/11 15:29
*/
public class AppletsConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(AppletsConfiguration.class);
// 設置小程序服務器域名
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/wxa/modify_domain?access_token=TOKEN";
// 設置小程序業務域名(僅供第三方代小程序調用)
private static final String SET_WEBVIEW_DOMAIN = "https://api.weixin.qq.com/wxa/setwebviewdomain?access_token=TOKEN";
// 爲授權的小程序帳號上傳小程序代碼
private static final String APPLETS_CODE_COMMIT = "https://api.weixin.qq.com/wxa/commit?access_token=TOKEN";
// 請求參數模板數據
private static final String DOMAIN_NAME = "https://www.xxx.com";
// 模板id
private static final String TEMPLATE_ID = "14";
// 獲取授權小程序帳號已設置的類目
private static final String APPLETS_CATEGORY_URL = "https://api.weixin.qq.com/wxa/get_category?access_token=TOKEN";
// 獲取小程序的第三方提交代碼的頁面配置
private static final String APPLETS_PAGE_URL = "https://api.weixin.qq.com/wxa/get_page?access_token=TOKEN";
// 將第三方提交的代碼包提交審覈
private static final String SUBMIT_AUDIT_URL = "https://api.weixin.qq.com/wxa/submit_audit?access_token=TOKEN";
// 查詢最新一次提交的審覈狀態
private static final String GET_LATEST_AUDITSTATUS = "https://api.weixin.qq.com/wxa/get_latest_auditstatus?access_token=TOKEN";
// 發佈已通過審覈的小程序
private static final String APPLETS_RELEASE_URL = "https://api.weixin.qq.com/wxa/release?access_token=TOKEN";
/**
* @Description: 代小程序實現業務
* 參考鏈接:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489138143_WPbOO&token=52693293ec662d6feb87eb805f97c1fc23c80c50&lang=zh_CN
* @Author: Mr.Jkx
* @Date: 2019/5/11 15:29
*/
public static Map<String, String> appletsUploadCheck(TWarrantMerchant tWarrantMerchant) throws IOException {
HashMap<String, String> AppletsDomainNameMap = new HashMap<>();
// 設置小程序服務器域名
HashMap<String, String> domainNameMap = domainNameConfiguration(tWarrantMerchant);
if(!StringUtils.equals("85017", domainNameMap.get("errcode")) && !StringUtils.equals("0", domainNameMap.get("errcode"))){
return domainNameMap;
}
// 設置小程序業務域名(僅供第三方代小程序調用)
HashMap<String, String> businessDomainMap = businessDomainConfiguration(tWarrantMerchant);
if(!StringUtils.equals("0", businessDomainMap.get("errcode"))){
return businessDomainMap;
}
// 爲授權的小程序帳號上傳小程序代碼
HashMap<String, String> appletsCodeCommitMap = appletsCodeCommit(tWarrantMerchant);
if(!StringUtils.equals("0", appletsCodeCommitMap.get("errcode"))){
return appletsCodeCommitMap;
}
// 獲取授權小程序帳號已設置的類目
HashMap<String, String> submitAuditMap = appletsSubmitAudit(tWarrantMerchant);
if("0" != submitAuditMap.get("errcode")){
return submitAuditMap;
}
AppletsDomainNameMap.put("errcode", "0");
AppletsDomainNameMap.put("errmsg", "SUCCESS");
return AppletsDomainNameMap;
}
/**
* @Description: 設置小程序服務器域名
* @Author: Mr.Jkx
* @Date: 2019/5/11 19:22
*/
public static HashMap<String, String> domainNameConfiguration(TWarrantMerchant tWarrantMerchant) throws IOException {
HashMap<String, String> domainNameMap = new HashMap<>();
JsonArray requestdomainArray = new JsonArray();
// 不要刪除這裏就是兩個參數
requestdomainArray.add(DOMAIN_NAME);
requestdomainArray.add(DOMAIN_NAME);
JSONObject json = new JSONObject();
json.accumulate("action", "add");
json.accumulate("requestdomain", requestdomainArray.toString());
json.accumulate("wsrequestdomain", requestdomainArray.toString());
json.accumulate("uploaddomain", requestdomainArray.toString());
json.accumulate("downloaddomain", requestdomainArray.toString());
/**發送Https請求到微信*/
String url = ACCESS_TOKEN_URL.replace("TOKEN", tWarrantMerchant.getAuthorizerAccessToken());
LOGGER.info("==========設置小程序服務器域名=====請求參數{}", json.toString());
JSONObject retStr = WinxinUtil.doPostStr(url, json.toString());
LOGGER.info("==========設置小程序服務器域名=====回執參數{}", retStr);
JSONObject retJSONObject = JSONObject.fromObject(retStr);
domainNameMap.put("errcode", retJSONObject.getString("errcode"));
domainNameMap.put("errmsg", retJSONObject.getString("errmsg"));
return domainNameMap;
}
/**
* @Description: 設置小程序業務域名(僅供第三方代小程序調用)
* @Author: Mr.Jkx
* @Date: 2019/5/11 19:27
*/
public static HashMap<String, String> businessDomainConfiguration(TWarrantMerchant tWarrantMerchant) throws IOException {
HashMap<String, String> businessDomainMap = new HashMap<>();
JsonArray requestdomainArray = new JsonArray();
requestdomainArray.add(DOMAIN_NAME);
requestdomainArray.add(DOMAIN_NAME);
JSONObject json = new JSONObject();
json.accumulate("action", "add");
json.accumulate("webviewdomain", requestdomainArray.toString());
/**發送Https請求到微信*/
String url = SET_WEBVIEW_DOMAIN.replace("TOKEN", tWarrantMerchant.getAuthorizerAccessToken());
LOGGER.info("==========設置小程序業務域名(僅供第三方代小程序調用)=====請求參數{}", json.toString());
JSONObject retStr = WinxinUtil.doPostStr(url, json.toString());
LOGGER.info("==========設置小程序業務域名(僅供第三方代小程序調用)=====回執信息{}", retStr);
JSONObject retJSONObject = JSONObject.fromObject(retStr);
businessDomainMap.put("errcode", retJSONObject.getString("errcode"));
businessDomainMap.put("errmsg", retJSONObject.getString("errmsg"));
return businessDomainMap;
}
/**
* @Description: 爲授權的小程序帳號上傳小程序代碼
* @Author: Mr.Jkx
* @Date: 2019/5/12 10:57
*/
public static HashMap<String, String> appletsCodeCommit(TWarrantMerchant tWarrantMerchant) throws IOException {
HashMap<String, String> appletsCodeCommitMap = new HashMap<>();
JSONObject jsonData = new JSONObject();
JSONObject extDate = new JSONObject();
JSONObject windowDate = new JSONObject();
JSONObject extJson = new JSONObject();
// 自定義參數
extDate.accumulate("merchantId", tWarrantMerchant.getId());
// window參數定義
windowDate.accumulate("navigationBarBackgroundColor", "#fff");
windowDate.accumulate("navigationBarTitleText", tWarrantMerchant.getNickName());
windowDate.accumulate("navigationBarTextStyle", "black");
// ext_json字段數據組裝
// 授權小程序配置自己的商戶平臺信息則用自己的,沒有使用欣星尚的信息
if(StringUtils.equals("0", tWarrantMerchant.getPayConfig())){
extJson.accumulate("extAppid", "wx64219b04c3af9d85");
}else{
extJson.accumulate("extAppid", tWarrantMerchant.getAuthorizationAppid());
}
extJson.accumulate("ext", extDate.toString());
extJson.accumulate("window", windowDate.toString());
jsonData.accumulate("template_id", TEMPLATE_ID);
jsonData.accumulate("ext_json", "'"+extJson.toString()+"'");
jsonData.accumulate("user_version", "V1.0");
jsonData.accumulate("user_desc", "test");
/**發送Https請求到微信*/
String url = APPLETS_CODE_COMMIT.replace("TOKEN", tWarrantMerchant.getAuthorizerAccessToken());
LOGGER.info("==========爲授權的小程序帳號上傳小程序代碼=====請求參數{}", jsonData.toString());
JSONObject retStr = WinxinUtil.doPostStr(url, jsonData.toString());
LOGGER.info("==========爲授權的小程序帳號上傳小程序代碼=====回執信息{}", retStr);
JSONObject retJSONObject = JSONObject.fromObject(retStr);
appletsCodeCommitMap.put("errcode", retJSONObject.getString("errcode"));
appletsCodeCommitMap.put("errmsg", retJSONObject.getString("errmsg"));
return appletsCodeCommitMap;
}
/**
* @Description: 將第三方提交的代碼包提交審覈
* @Author: Mr.Jkx
* @Date: 2019/5/14 10:48
*/
public static HashMap<String, String> appletsSubmitAudit(TWarrantMerchant tWarrantMerchant) throws IOException {
HashMap<String, String> submitAuditMap = new HashMap<>();
JSONObject jsonData = new JSONObject();
JSONObject itemListData = new JSONObject();
String firstClass = "";
String secondClass = "";
String firstId = "";
String secondId = "";
// 獲取授權小程序帳號已設置的類目
JSONObject appletsCategory = getAppletsCategory(tWarrantMerchant);
if(StringUtils.equals("ok", appletsCategory.getString("errmsg"))){
String categoryList = appletsCategory.getString("category_list");
JSONArray jsonArray = JSONArray.fromObject(categoryList);
JSONObject jsonObject = (JSONObject) jsonArray.get(0);
firstClass = jsonObject.getString("first_class");
secondClass = jsonObject.getString("second_class");
firstId = jsonObject.getString("first_id");
secondId = jsonObject.getString("second_id");
}else{
submitAuditMap.put("errcode", appletsCategory.getString("errcode"));
submitAuditMap.put("errmsg", appletsCategory.getString("errmsg"));
return submitAuditMap;
}
itemListData.accumulate("address", "pages/index/index");
itemListData.accumulate("tag", "xxx"); // 小程序名稱
itemListData.accumulate("first_class", firstClass);
itemListData.accumulate("second_class", secondClass);
itemListData.accumulate("first_id", firstId);
itemListData.accumulate("second_id", secondId);
itemListData.accumulate("title", "首頁");
jsonData.accumulate("item_list", "["+itemListData.toString()+"]");
String url = SUBMIT_AUDIT_URL.replace("TOKEN", tWarrantMerchant.getAuthorizerAccessToken());
LOGGER.info("==========將第三方提交的代碼包提交審覈=====請求參數{}", jsonData.toString());
// 代碼編碼格式爲UTF_8,注意編碼格式,以免出現“category is in invalid format hint”錯誤
JSONObject retStr = WinxinUtil.doPostStr(url, jsonData.toString());
LOGGER.info("==========將第三方提交的代碼包提交審覈=====回執信息{}", retStr);
JSONObject retJSONObject = JSONObject.fromObject(retStr);
submitAuditMap.put("errcode", retJSONObject.getString("errcode"));
submitAuditMap.put("errmsg", retJSONObject.getString("errmsg"));
return submitAuditMap;
}
/**
* @Description: 獲取授權小程序帳號已設置的類目
* @Author: Mr.Jkx
* @Date: 2019/5/14 10:30
*/
public static JSONObject getAppletsCategory(TWarrantMerchant tWarrantMerchant) throws IOException {
String url = APPLETS_CATEGORY_URL.replace("TOKEN", tWarrantMerchant.getAuthorizerAccessToken());
JSONObject retStr = WinxinUtil.doGetStr(url);
JSONObject retJSONAppletsCategory = JSONObject.fromObject(retStr);
LOGGER.info("==========獲取授權小程序帳號已設置的類目=====回執信息{}", retStr);
return retJSONAppletsCategory;
}
小程序提交審覈結果
小程序模板上傳審覈之後,編寫了一個定時任務獲取審覈結果,審覈通過則將數據狀態修改爲“審覈通過”,以便工作人員操作將代碼“發佈”到授權小程序;
/**
* @Description: 查詢代碼審覈狀態,修改用戶模板狀態
* @Author: Mr.Jkx
* @Date: 2019/5/20 11:55
*/
@Scheduled(fixedRate = 1800000)
public void uploadCheckStatus() throws IOException {
LOGGER.info("------查詢代碼審覈狀態,修改用戶審覈狀態------START---------");
StringBuffer userIdBuffer = new StringBuffer();
// 查詢小程序提交用戶對應的authorizer_access_token
List<TUser> tUsers = userService.getCheckStatus();
for (TUser tUser : tUsers) {
if (StringUtils.equals("0", tUser.getServiceTypeInfo()) && StringUtils.equals("0", tUser.getVerifyTypeInfo())) {
// authorizerAccessToken,小程序授權時獲取,時效兩個小時,保存於數據庫或緩存中,定時刷新
String authorizerAccessToken = tUser.getAuthorizerAccessToken();
// 查詢最新一次小程序提交的審覈狀態
net.sf.json.JSONObject retStr = selUploadCheckStatus(authorizerAccessToken);
if (StringUtils.equals("0", retStr.getString("status"))) {
userIdBuffer.append(tUser.getUserId()).append(",");
}
}
}
// 修改用戶模板狀態
LOGGER.info("--------修改用戶模板狀態----------{}", userIdBuffer);
if (StringUtils.isNotBlank(userIdBuffer.toString())) {
userService.uploadUserTemplateType(userIdBuffer.toString());
}
}
/**
* @Description: 查詢最新一次小程序提交的審覈狀態
* @Author: Mr.Jkx
* @Date: 2019/5/20 13:00
*/
public static JSONObject selUploadCheckStatus(String authorizerAccessToken) throws IOException {
String url = GET_LATEST_AUDITSTATUS.replace("TOKEN", authorizerAccessToken);
JSONObject retStr = WinxinUtil.doGetStr(url);
LOGGER.info("==========查詢最新一次小程序提交的審覈狀態=====回執信息{}", retStr);
return retStr;
}
小程序發佈
定時任務,定時刷新授權小程序代碼審覈狀態,審覈通過之後,工作人員手動將小程序發佈
@RequestMapping("/appletsRelease")
@ResponseBody
public Map<String, String> appletsRelease(TWarrantMerchant tWarrantMerchant) throws IOException {
Map<String, String> appletsReleaseMap = appletsRelease(tWarrantMerchant);
// 發佈成功修改用戶模板狀態
if(StringUtils.equals("0",appletsReleaseMap.get("errcode"))){
TUser tUser = new TUser();
tUser.setUserId(tWarrantMerchant.getWarrantCreater());
tUser.setTemplateType("3"); // 模板狀態;1,已上傳;0,未上傳;2,審覈通過;3,發佈成功
int i = userService.updateTemplateType(tUser);
if(i > 0){
LOGGER.info("--------小程序發佈成功,數據狀態修改-------成功!!!");
}else {
LOGGER.info("--------小程序發佈成功,數據狀態修改-------失敗!!!");
}
}
return appletsReleaseMap;
}
/**
* @Description: 小程序發佈
* @Author: Mr.Jkx
* @Date: 2019/5/14 13:04
*/
public static Map<String, String> appletsRelease(TWarrantMerchant tWarrantMerchant) throws IOException {
HashMap<String, String> appletsReleaseMap = new HashMap<>();
JSONObject jsonData = new JSONObject();
// authorizerAccessToken,小程序授權時獲取,時效兩個小時,保存於數據庫或緩存中,定時刷新
String url = APPLETS_RELEASE_URL.replace("TOKEN", tWarrantMerchant.getAuthorizerAccessToken());
LOGGER.info("==========小程序發佈=====請求參數{}", jsonData.toString());
JSONObject retStr = WinxinUtil.doPostStr(url, jsonData.toString());
LOGGER.info("==========小程序發佈=====回執信息{}", retStr);
appletsReleaseMap.put("errcode", retStr.getString("errcode"));
appletsReleaseMap.put("errmsg", retStr.getString("errmsg"));
return appletsReleaseMap;
}