本文将描述在公司开发平台实现小程序代码的上传审核,审核结果获取更新及代码的发布流程,详细资料可参阅官方文档代小程序实现业务-代码管理;
将小程序授权给第三方平台,授权完成之后,小程序将不能进行小程序代码的上传审核,此时需要第三方平台统一开发管理小程序模板,第三方平台开发小程序模板版本的迭代更新升级;
新版本小程序模板进行提交审核将进入到第三方平台草稿箱中,小程序想要上传发布代码,需将小程序模板添加到小程序模板库中,获取小程序模板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;
}