You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1006 lines
47 KiB

  1. package com.iformall.controller;
  2. import cn.binarywang.wx.miniapp.api.WxMaService;
  3. import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult;
  4. import com.alibaba.fastjson.JSON;
  5. import com.alibaba.fastjson.JSONArray;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.github.pagehelper.PageInfo;
  8. import com.google.gson.Gson;
  9. import com.google.gson.GsonBuilder;
  10. import com.google.gson.reflect.TypeToken;
  11. import com.iformall.common.ErrorCode;
  12. import com.iformall.common.Result;
  13. import com.iformall.common.ResultData;
  14. import com.iformall.controller.base.BaseController;
  15. import com.iformall.domain.po.*;
  16. import com.iformall.domain.vo.WxWeappAuditStatusVo;
  17. import com.iformall.domain.vo.WxWeappCodeStatusVo;
  18. import com.iformall.domain.vo.WxWeappInfo;
  19. import com.iformall.domain.vo.WxWeappReleaseStatusVo;
  20. import com.iformall.enums.*;
  21. import com.iformall.service.*;
  22. import com.iformall.service.wechat.FmOpenService;
  23. import io.swagger.annotations.Api;
  24. import io.swagger.annotations.ApiImplicitParam;
  25. import io.swagger.annotations.ApiImplicitParams;
  26. import io.swagger.annotations.ApiOperation;
  27. import me.chanjar.weixin.common.error.WxErrorException;
  28. import me.chanjar.weixin.open.api.WxOpenMaService;
  29. import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo;
  30. import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage;
  31. import me.chanjar.weixin.open.bean.result.WxOpenMaDomainResult;
  32. import me.chanjar.weixin.open.bean.result.WxOpenMaQueryAuditResult;
  33. import me.chanjar.weixin.open.bean.result.WxOpenMaSubmitAuditResult;
  34. import me.chanjar.weixin.open.bean.result.WxOpenResult;
  35. import org.apache.commons.lang3.StringUtils;
  36. import org.slf4j.Logger;
  37. import org.slf4j.LoggerFactory;
  38. import org.springframework.beans.factory.annotation.Autowired;
  39. import org.springframework.stereotype.Controller;
  40. import org.springframework.web.bind.annotation.*;
  41. import java.util.*;
  42. /**
  43. * Stormeye Wu
  44. */
  45. @Controller
  46. @RequestMapping("/weapp")
  47. @Api(description = "小程序")
  48. public class WxWeappInfoController extends BaseController {
  49. private final Logger logger = LoggerFactory.getLogger(getClass());
  50. @Autowired
  51. private Integer getFmDeploy;
  52. @Autowired
  53. private WxAuthorizerInfoService authorizerInfoService;
  54. @Autowired
  55. private WxWeappBasicSetService weappBasicSetService;
  56. @Autowired
  57. private WxWeappExtSetService weappExtSetService;
  58. @Autowired
  59. private WxWeappCodeStatusService weappCodeStatusService;
  60. @Autowired
  61. private WxWeappAuditStatusService weappAuditStatusService;
  62. @Autowired
  63. private WxWeappReleaseStatusService weappReleaseStatusService;
  64. @Autowired
  65. private FmOpenService openService;
  66. @Autowired
  67. private WxAppinfoService appinfoService;
  68. @Autowired
  69. private WxTemplateMsgService templateMsgService;
  70. @ApiOperation(value = "小程序分页列表接口", notes = "查询支持小程序类型,名称,appid,version")
  71. @GetMapping("list")
  72. @ApiImplicitParams({
  73. @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
  74. @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
  75. public ResultData list(@ModelAttribute WxWeappInfo weappInfo, Integer pageNum, Integer pageSize) {
  76. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::list");
  77. if (null == weappInfo) {
  78. weappInfo = new WxWeappInfo();
  79. } else {
  80. if(StringUtils.isBlank(weappInfo.getName())) {
  81. weappInfo.setName(null);
  82. }
  83. }
  84. weappInfo.setSortColumns(BaseEntity.SortField.TenantId_ASC,BaseEntity.SortField.Type_ASC,BaseEntity.SortField.Name_ASC);
  85. final PageInfo<WxWeappInfo> page = authorizerInfoService.listVoAsPage(weappInfo, pageNum, pageSize);
  86. return new ResultData(page);
  87. }
  88. @ApiOperation("小程序列表接口")
  89. @GetMapping("allist")
  90. public ResultData getList(@ModelAttribute WxWeappInfo weappInfo) {
  91. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::list");
  92. if (null == weappInfo) {
  93. weappInfo = new WxWeappInfo();
  94. } else {
  95. if(StringUtils.isBlank(weappInfo.getName())) {
  96. weappInfo.setName(null);
  97. }
  98. }
  99. weappInfo.setSortColumns(BaseEntity.SortField.CurrentVersion_DESC);
  100. final List<WxWeappInfo> list = authorizerInfoService.getList(weappInfo);
  101. return new ResultData(list);
  102. }
  103. @ApiOperation(value = "APPs基础设置(服务器域名、业务域名、基础版本、微信模板)", notes = "{\"apps\":\"appid,appid\",\"type\":\"String\"}")
  104. @PostMapping("batchBasicSet")
  105. public ResultData batchSet(@RequestBody Map<String, String> params) {
  106. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchBasicSet");
  107. String appsStr = params.get("apps");
  108. String typeStr = params.get("type");
  109. if(StringUtils.isBlank(typeStr)) {
  110. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "type参数不能为空");
  111. }
  112. Integer type = 0;
  113. try {
  114. type = Integer.parseInt(typeStr);
  115. } catch (Exception e) {
  116. return new ResultData(ErrorCode.SYS_PARAMETER_ERROR);
  117. }
  118. // 检查基础配置参数
  119. WxWeappBasicSet weappBasicSetQ = new WxWeappBasicSet();
  120. weappBasicSetQ.setType(type);
  121. weappBasicSetQ.setDeploy(getFmDeploy);
  122. WxWeappBasicSet weappBasicSet = weappBasicSetService.getByTypeAndDeploy(weappBasicSetQ);
  123. if(weappBasicSet == null) {
  124. logger.error("未找到相关的基础设置参数");
  125. return new ResultData(ErrorCode.WEAPP_BASIC_SET_ERR);
  126. }
  127. JSONObject domainObj = JSON.parseObject(weappBasicSet.getDomainUrl());
  128. if(domainObj == null) {
  129. logger.error("未找到相关的基础设置参数");
  130. return new ResultData(ErrorCode.WEAPP_BASIC_SET_DOMAIN_ERR);
  131. }
  132. JSONObject templeObj = JSON.parseObject(weappBasicSet.getTemplateInfo());
  133. if(StringUtils.isBlank(appsStr)) {
  134. WxWeappInfo weappInfoQ = new WxWeappInfo();
  135. weappInfoQ.setType(type);
  136. List<WxWeappInfo> list = authorizerInfoService.getList(weappInfoQ);
  137. for(WxWeappInfo info: list) {
  138. appsStr += info.getAuthorizerAppid() + ",";
  139. }
  140. appsStr = appsStr.substring(0, appsStr.length() - 1);
  141. }
  142. // 逐一设置app配置
  143. String [] apps = appsStr.split(",");
  144. for(String appId: apps) {
  145. // 检查appId是否已授权
  146. WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId);
  147. if(authorizerInfo == null) {
  148. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  149. }
  150. if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) {
  151. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  152. }
  153. ResultData openRet = setBasicForAppId(appId, weappBasicSet, domainObj, templeObj);
  154. if (openRet != null) return openRet;
  155. }
  156. return new ResultData();
  157. }
  158. private ResultData setBasicForAppId(String appId, WxWeappBasicSet weappBasicSet, JSONObject domainObj, JSONObject templeObj) {
  159. WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId);
  160. if(authorizerInfo == null) {
  161. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  162. }
  163. try {
  164. WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId);
  165. // 设置基础版本
  166. String versionRet = openMaService.setSupportVersion(weappBasicSet.getVersion());
  167. logger.info(versionRet);
  168. JSONObject verObj = JSON.parseObject(versionRet);
  169. if(verObj.getInteger("errcode").equals(0)) {
  170. authorizerInfo.setBaseStatus(0);
  171. } else {
  172. authorizerInfo.setBaseStatus(1);
  173. }
  174. authorizerInfo.setBaseTime(new Date());
  175. authorizerInfo.setUpdateTime(new Date());
  176. authorizerInfoService.updateBaseVersion(authorizerInfo);
  177. // 服务器域名
  178. String action = "set";
  179. JSONObject urlObj = domainObj.getJSONObject("url");
  180. List<String> requestDomain = getUrlList(urlObj.getJSONArray("requestdomain"));
  181. List<String> wsrequestDomain = getUrlList(urlObj.getJSONArray("wsrequestdomain"));
  182. List<String> uploadDomain = getUrlList(urlObj.getJSONArray("uploaddomain"));
  183. List<String> downloadDomain = getUrlList(urlObj.getJSONArray("downloaddomain"));
  184. logger.info(downloadDomain.toString());
  185. WxOpenMaDomainResult openRet = openMaService.modifyDomain(action,
  186. requestDomain, wsrequestDomain,
  187. uploadDomain, downloadDomain);
  188. logger.info(openRet.toString());
  189. if(openRet.isSuccess()) {
  190. logger.info("设置服务器域名成功");
  191. authorizerInfo.setDomainStatus(0);
  192. authorizerInfo.setDomainTime(new Date());
  193. authorizerInfo.setUpdateTime(new Date());
  194. } else {
  195. logger.info("设置服务器域名成功");
  196. authorizerInfo.setDomainStatus(1);
  197. authorizerInfo.setDomainTime(new Date());
  198. authorizerInfo.setUpdateTime(new Date());
  199. }
  200. authorizerInfoService.updateDomainUrl(authorizerInfo);
  201. // 业务域名
  202. JSONObject webObj = domainObj.getJSONObject("web");
  203. List<String> urlList = getUrlList(webObj.getJSONArray("webviewdomain"));
  204. String openRet1 = openMaService.setWebViewDomain(action, urlList);
  205. logger.info(openRet1);
  206. JSONObject webRetObj = JSON.parseObject(openRet1);
  207. if(webRetObj.getInteger("errcode").equals(0)) {
  208. logger.info("设置服务器业务域名成功");
  209. authorizerInfo.setWebdomainStatus(0);
  210. authorizerInfo.setWebdomainTime(new Date());
  211. authorizerInfo.setUpdateTime(new Date());
  212. } else {
  213. logger.info("设置服务器业务域名失败");
  214. authorizerInfo.setWebdomainStatus(1);
  215. authorizerInfo.setWebdomainTime(new Date());
  216. authorizerInfo.setUpdateTime(new Date());
  217. }
  218. authorizerInfoService.updateWebDomainUrl(authorizerInfo);
  219. } catch (WxErrorException e) {
  220. logger.error(e.getMessage());
  221. return new ResultData(Result.ERROR, e.getMessage());
  222. }
  223. // 设置微信模板
  224. if(weappBasicSet.getType().equals(EnumAppType.C.getCode())) {
  225. if(authorizerInfo.getTemplateStatus() == null ||
  226. !authorizerInfo.getTemplateStatus().equals(EnumWxAuthotizationTemplateStatus.SUCCESS.getCode())) {
  227. // 模板未设置或者设置失败
  228. // 获取模板
  229. WxAppinfo appinfo = appinfoService.getByAppId(appId);
  230. WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId);
  231. try {
  232. // 核销成功消息
  233. JSONObject verify_success = templeObj.getJSONObject("verify_success");
  234. String id = verify_success.getString("id");
  235. JSONArray keyidlist = verify_success.getJSONArray("keyword_id_list");
  236. String customParam = verify_success.getString("custom_param");
  237. logger.info(customParam);
  238. List<Integer> keyArr = getIdList(keyidlist);
  239. WxMaTemplateAddResult ret = maService.getTemplateService().addTemplate(id, keyArr);
  240. logger.info(ret.toString());
  241. if(appinfo != null) {
  242. // wx_template_msg
  243. WxTemplateMsg templateMsgQ = new WxTemplateMsg();
  244. templateMsgQ.setTenantId(appinfo.getTenantId());
  245. templateMsgQ.setType(EnumTemplateType.VERIFY_SUCCESS.getCode());
  246. WxTemplateMsg templateMsg = templateMsgService.getByObj(templateMsgQ);
  247. if(templateMsg != null) {
  248. templateMsg.setTemplateId(ret.getTemplateId());
  249. templateMsg.setCustomParam(customParam);
  250. templateMsgService.saveOrUpdate(templateMsg);
  251. } else {
  252. templateMsgQ.setTemplateId(ret.getTemplateId());
  253. templateMsg.setCustomParam(customParam);
  254. templateMsgService.saveOrUpdate(templateMsgQ);
  255. }
  256. }
  257. // 核销失败消息
  258. JSONObject verify_fail = templeObj.getJSONObject("verify_fail");
  259. id = verify_fail.getString("id");
  260. keyidlist = verify_fail.getJSONArray("keyword_id_list");
  261. customParam = verify_fail.getString("custom_param");
  262. logger.info(customParam);
  263. List<Integer> keyArr1 = getIdList(keyidlist);
  264. ret = maService.getTemplateService().addTemplate(id, keyArr1);
  265. logger.info(ret.toString());
  266. if(appinfo != null) {
  267. // wx_template_msg
  268. WxTemplateMsg templateMsgQ = new WxTemplateMsg();
  269. templateMsgQ.setTenantId(appinfo.getTenantId());
  270. templateMsgQ.setType(EnumTemplateType.VERIFY_FAIL.getCode());
  271. WxTemplateMsg templateMsg = templateMsgService.getByObj(templateMsgQ);
  272. if(templateMsg != null) {
  273. templateMsg.setTemplateId(ret.getTemplateId());
  274. templateMsg.setCustomParam(customParam);
  275. templateMsgService.saveOrUpdate(templateMsg);
  276. } else {
  277. templateMsgQ.setTemplateId(ret.getTemplateId());
  278. templateMsg.setCustomParam(customParam);
  279. templateMsgService.saveOrUpdate(templateMsgQ);
  280. }
  281. }
  282. // 砍价成功消息
  283. JSONObject press_success = templeObj.getJSONObject("press_success");
  284. id = press_success.getString("id");
  285. keyidlist = press_success.getJSONArray("keyword_id_list");
  286. customParam = press_success.getString("custom_param");
  287. logger.info(customParam);
  288. List<Integer> keyArr2 = getIdList(keyidlist);
  289. ret = maService.getTemplateService().addTemplate(id, keyArr2);
  290. logger.info(ret.toString());
  291. if(appinfo != null) {
  292. // wx_template_msg
  293. WxTemplateMsg templateMsgQ = new WxTemplateMsg();
  294. templateMsgQ.setTenantId(appinfo.getTenantId());
  295. templateMsgQ.setType(EnumTemplateType.PRESS_SUCCESS.getCode());
  296. WxTemplateMsg templateMsg = templateMsgService.getByObj(templateMsgQ);
  297. if(templateMsg != null) {
  298. templateMsg.setTemplateId(ret.getTemplateId());
  299. templateMsg.setCustomParam(customParam);
  300. templateMsgService.saveOrUpdate(templateMsg);
  301. } else {
  302. templateMsgQ.setTemplateId(ret.getTemplateId());
  303. templateMsg.setCustomParam(customParam);
  304. templateMsgService.saveOrUpdate(templateMsgQ);
  305. }
  306. }
  307. // 更新状态
  308. authorizerInfo.setTemplateStatus(EnumWxAuthotizationTemplateStatus.SUCCESS.getCode());
  309. authorizerInfo.setTemplateTime(new Date());
  310. authorizerInfo.setUpdateTime(new Date());
  311. authorizerInfoService.updateTemplate(authorizerInfo);
  312. } catch (WxErrorException e) {
  313. logger.error(e.getMessage());
  314. // 更新状态
  315. authorizerInfo.setTemplateStatus(EnumWxAuthotizationTemplateStatus.Fail.getCode());
  316. authorizerInfo.setTemplateTime(new Date());
  317. authorizerInfo.setUpdateTime(new Date());
  318. authorizerInfoService.updateTemplate(authorizerInfo);
  319. return new ResultData(Result.ERROR, e.getMessage());
  320. }
  321. }
  322. }
  323. // 设置成功返回null
  324. return null;
  325. }
  326. private List<Integer> getIdList(JSONArray keyidlist) {
  327. List<Integer> keyArr = new ArrayList<Integer>();
  328. for (int i = 0; i < keyidlist.size(); i++) {
  329. keyArr.add(keyidlist.getIntValue(i));
  330. }
  331. return keyArr;
  332. }
  333. private List<String> getUrlList(JSONArray urlList) {
  334. List<String> keyArr = new ArrayList<String>();
  335. for (int i = 0; i < urlList.size(); i++) {
  336. keyArr.add(urlList.getString(i));
  337. }
  338. return keyArr;
  339. }
  340. @ApiOperation(value = "批量授权的小程序code提交", notes = "{\"apps\":\"appid,appid\",\"templateId\":\"String\",\"type\":\"String\",\"userVersion\":\"String\",\"userDesc\":\"String\"}")
  341. @PostMapping("batchCodeCommit")
  342. public ResultData batchCodeCommit(@RequestBody Map<String, String> params) {
  343. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchExtSet");
  344. String appsStr = params.get("apps");
  345. String templateIdStr = params.get("templateId");
  346. String typeStr = params.get("type");
  347. String userVersion = params.get("userVersion");
  348. String userDesc = params.get("userDesc");
  349. Integer type = null;
  350. Long templateId = null;
  351. try {
  352. templateId = Long.parseLong(templateIdStr);
  353. } catch (Exception e) {
  354. return new ResultData(ErrorCode.SYS_PARAMETER_ERROR);
  355. }
  356. try {
  357. type = Integer.parseInt(typeStr);
  358. } catch (Exception e) {
  359. logger.error("type为null");
  360. }
  361. if(StringUtils.isBlank(appsStr)) {
  362. if(type == null) {
  363. logger.error("type为null");
  364. return new ResultData(ErrorCode.SYS_PARAMETER_ERROR);
  365. }
  366. WxWeappInfo authQ = new WxWeappInfo();
  367. authQ.setType(type);
  368. List<WxWeappInfo> appList = authorizerInfoService.getList(authQ);
  369. appsStr = "";
  370. StringBuilder sb = new StringBuilder();
  371. boolean bfirst = true;
  372. for(WxWeappInfo app: appList) {
  373. if(bfirst) {
  374. sb.append(app.getAuthorizerAppid());
  375. bfirst = false;
  376. } else {
  377. sb.append(app.getAuthorizerAppid()).append(",");
  378. }
  379. }
  380. }
  381. String [] apps = appsStr.split(",");
  382. // 逐一检查app的设置
  383. for(String appId: apps) {
  384. WxWeappExtSet extSetQ = new WxWeappExtSet();
  385. extSetQ.setAppId(appId);
  386. WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ);
  387. if(extSet == null) {
  388. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  389. }
  390. if(StringUtils.isBlank(extSet.getExtJson())) {
  391. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  392. }
  393. if(StringUtils.isBlank(extSet.getReleaseJson())) {
  394. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  395. }
  396. }
  397. // 逐一设置app配置
  398. for(String appId: apps) {
  399. // 检查appId是否已授权
  400. WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId);
  401. if(authorizerInfo == null) {
  402. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  403. }
  404. if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) {
  405. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  406. }
  407. codeCommit(appId, userVersion, userDesc, templateId);
  408. }
  409. return new ResultData();
  410. }
  411. private void codeCommit(String appId, String userVersion, String userDesc, Long templateId) {
  412. WxAppinfo appinfo = appinfoService.getByAppId(appId);
  413. int iAppType = 0;
  414. String appTypeStr = userVersion.substring(0, 1);
  415. if(appTypeStr.equalsIgnoreCase("C"))
  416. iAppType = EnumAppType.C.getCode();
  417. else if(appTypeStr.equalsIgnoreCase("B"))
  418. iAppType = EnumAppType.B.getCode();
  419. if(!appinfo.getType().equals(iAppType)) {
  420. // 如果版本号与小程序的类型不一致,不提交版本
  421. return;
  422. }
  423. // get ext json
  424. WxWeappExtSet extSetQ = new WxWeappExtSet();
  425. extSetQ.setAppId(appId);
  426. WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ);
  427. WxWeappCodeStatus codeStatus = weappCodeStatusService.getByAppId(appId);
  428. if(extSet != null) {
  429. boolean codeCommitStatus = false;
  430. if(codeStatus != null && codeStatus.getCodeStatus().equals(0) && codeStatus.getUserVersion().equals(userVersion)) {
  431. codeCommitStatus = true;
  432. }
  433. if(!codeCommitStatus) {
  434. codeCommitStatus = doCodeCommit(userVersion, userDesc, templateId, appinfo, extSet, codeStatus);
  435. }
  436. }
  437. }
  438. @ApiOperation(value = "小程序批量提交审核", notes = "{\"type\":\"String\",\"userVersion\":\"String\",\"apps\":\"appid,appid\"}")
  439. @PostMapping("batchCodeAudit")
  440. public ResultData batchCodeAudit(@RequestBody Map<String, String> params) {
  441. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchExtSet");
  442. String appsStr = params.get("apps");
  443. String typeStr = params.get("type");
  444. String userVersion = params.get("userVersion");
  445. Integer type = null;
  446. try {
  447. type = Integer.parseInt(typeStr);
  448. } catch (Exception e) {
  449. logger.error("小程序类型");
  450. }
  451. if(StringUtils.isBlank(appsStr)) {
  452. if(type == null) {
  453. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  454. }
  455. WxWeappInfo authQ = new WxWeappInfo();
  456. authQ.setType(type);
  457. List<WxWeappInfo> appList = authorizerInfoService.getList(authQ);
  458. appsStr = "";
  459. StringBuilder sb = new StringBuilder();
  460. boolean bfirst = true;
  461. for(WxWeappInfo app: appList) {
  462. if(bfirst) {
  463. sb.append(app.getAuthorizerAppid());
  464. bfirst = false;
  465. } else {
  466. sb.append(app.getAuthorizerAppid()).append(",");
  467. }
  468. }
  469. }
  470. String [] apps = appsStr.split(",");
  471. // 逐一检查app的设置
  472. for(String appId: apps) {
  473. WxWeappExtSet extSetQ = new WxWeappExtSet();
  474. extSetQ.setAppId(appId);
  475. WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ);
  476. if(extSet == null) {
  477. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  478. }
  479. if(StringUtils.isBlank(extSet.getExtJson())) {
  480. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  481. }
  482. if(StringUtils.isBlank(extSet.getReleaseJson())) {
  483. return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
  484. }
  485. }
  486. // 逐一设置app配置
  487. for(String appId: apps) {
  488. // 检查appId是否已授权
  489. WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId);
  490. if(authorizerInfo == null) {
  491. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  492. }
  493. if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) {
  494. return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH);
  495. }
  496. codeAudit(appId, userVersion);
  497. }
  498. return new ResultData();
  499. }
  500. private void codeAudit(String appId, String userVersion) {
  501. // get ext json
  502. WxWeappExtSet extSetQ = new WxWeappExtSet();
  503. extSetQ.setAppId(appId);
  504. WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ);
  505. WxWeappCodeStatus codeStatus = weappCodeStatusService.getByAppId(appId);
  506. if(extSet != null) {
  507. boolean codeCommitStatus = false;
  508. if(codeStatus != null
  509. && codeStatus.getCodeStatus().equals(EnumWeappCodeCommitStatus.SUCCESS.getCode())
  510. && codeStatus.getUserVersion().equals(userVersion)) {
  511. codeCommitStatus = true;
  512. }
  513. if(codeCommitStatus) {
  514. WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId);
  515. if(auditStatus != null && auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.AUDITING.getCode())) {
  516. logger.error("审核中不能再提交审核");
  517. return;
  518. }
  519. doCodeAudit(codeStatus, auditStatus, extSet);
  520. } else {
  521. logger.error("CODE提交失败");
  522. }
  523. }
  524. }
  525. private boolean doCodeCommit(String userVersion, String userDesc, Long templateId, WxAppinfo appinfo, WxWeappExtSet extSet, WxWeappCodeStatus codeStatus) {
  526. Gson gson = new GsonBuilder().create();
  527. // code提交
  528. boolean codeCommitStatus = false;
  529. String codeErrCode = "";
  530. try {
  531. WxMaOpenCommitExtInfo extInfo = gson.fromJson(extSet.getExtJson(), new TypeToken<WxMaOpenCommitExtInfo>() {}.getType());
  532. logger.info("OLD: " + extInfo.toString());
  533. // 自动修改提交的版本
  534. if(extInfo.getExtMap().containsKey("appVersion")) {
  535. extInfo.getExtMap().put("appVersion", userVersion);
  536. }
  537. logger.info("NEW: " + extInfo.toString());
  538. WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appinfo.getAppId());
  539. WxOpenResult openRet = openMaService.codeCommit(templateId, userVersion, userDesc, extInfo);
  540. logger.info(openRet.toString());
  541. if (openRet.isSuccess()) {
  542. codeCommitStatus = true;
  543. }
  544. codeErrCode = gson.toJson(openRet);
  545. } catch (WxErrorException e) {
  546. codeCommitStatus = false;
  547. codeErrCode = e.getMessage();
  548. logger.error(codeErrCode);
  549. }
  550. if (codeStatus == null) {
  551. codeStatus = new WxWeappCodeStatus();
  552. codeStatus.setId(appinfo.getId());
  553. codeStatus.setTenantId(appinfo.getTenantId());
  554. codeStatus.setAppId(appinfo.getAppId());
  555. if (appinfo != null) {
  556. codeStatus.setType(appinfo.getType());
  557. }
  558. codeStatus.setUserVersion(userVersion);
  559. codeStatus.setVersionDesc(userDesc);
  560. if(codeCommitStatus) {
  561. codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.SUCCESS.getCode());
  562. } else {
  563. codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode());
  564. }
  565. codeStatus.setCodeErrCode(codeErrCode);
  566. codeStatus.setCodeTime(new Date());
  567. weappCodeStatusService.saveStatus(codeStatus);
  568. } else {
  569. codeStatus.setUserVersion(userVersion);
  570. codeStatus.setVersionDesc(userDesc);
  571. if(codeCommitStatus) {
  572. codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.SUCCESS.getCode());
  573. } else {
  574. codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode());
  575. }
  576. codeStatus.setCodeErrCode(codeErrCode);
  577. codeStatus.setCodeTime(new Date());
  578. weappCodeStatusService.updateStatus(codeStatus);
  579. }
  580. return codeCommitStatus;
  581. }
  582. private void doCodeAudit(WxWeappCodeStatus codeStatus, WxWeappAuditStatus auditStatus, WxWeappExtSet extSet) {
  583. Gson gson = new GsonBuilder().create();
  584. boolean submitStatus = false;
  585. Long auditid = null;
  586. String codeErrCode = "";
  587. try {
  588. WxOpenMaSubmitAuditMessage subMessage = gson.fromJson(extSet.getReleaseJson(), new TypeToken<WxOpenMaSubmitAuditMessage>() {}.getType());
  589. logger.info(subMessage.toString());
  590. WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(codeStatus.getAppId());
  591. WxOpenMaSubmitAuditResult openRet = openMaService.submitAudit(subMessage);
  592. logger.info(openRet.toString());
  593. if(openRet.isSuccess()) {
  594. submitStatus = true;
  595. auditid = openRet.getAuditId();
  596. } else {
  597. submitStatus = false;
  598. }
  599. codeErrCode = gson.toJson(openRet);
  600. } catch (WxErrorException e) {
  601. logger.error(e.getMessage());
  602. submitStatus = false;
  603. codeErrCode = e.getMessage();
  604. }
  605. if (auditStatus == null) {
  606. auditStatus = new WxWeappAuditStatus();
  607. auditStatus.setId(codeStatus.getId());
  608. auditStatus.setTenantId(codeStatus.getTenantId());
  609. auditStatus.setAppId(codeStatus.getAppId());
  610. auditStatus.setType(codeStatus.getType());
  611. auditStatus.setUserVersion(codeStatus.getUserVersion());
  612. auditStatus.setVersionDesc(codeStatus.getVersionDesc());
  613. if(submitStatus) {
  614. auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode());
  615. auditStatus.setAuditid(auditid);
  616. } else {
  617. auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode());
  618. }
  619. auditStatus.setAuditErrCode(codeErrCode);
  620. auditStatus.setAuditTime(new Date());
  621. weappAuditStatusService.saveStatus(auditStatus);
  622. } else {
  623. if(!submitStatus) {
  624. if(!auditStatus.getUserVersion().equals(codeStatus.getUserVersion())
  625. && auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.AUDITING.getCode())) {
  626. // 当前审核中的数据不能替换
  627. return;
  628. }
  629. auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode());
  630. } else {
  631. auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode());
  632. auditStatus.setAuditid(auditid);
  633. }
  634. auditStatus.setUserVersion(codeStatus.getUserVersion());
  635. auditStatus.setVersionDesc(codeStatus.getVersionDesc());
  636. auditStatus.setAuditErrCode(codeErrCode);
  637. auditStatus.setAuditTime(new Date());
  638. weappAuditStatusService.updateStatus(auditStatus);
  639. }
  640. }
  641. @ApiOperation(value = "批量审核查询", notes = "{\"type\":\"string\",\"version\":\"string\"}")
  642. @PostMapping("batchAuditQuery")
  643. public ResultData batchAuditQuery(@RequestBody Map<String, String> params) {
  644. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchAuditQuery");
  645. Gson gson = new GsonBuilder().create();
  646. String typeStr = params.get("type");
  647. String version = params.get("version");
  648. Integer type = null;
  649. try {
  650. type = Integer.parseInt(typeStr);
  651. } catch (Exception e) {
  652. logger.error(e.getMessage());
  653. }
  654. WxWeappAuditStatusVo queryVo = new WxWeappAuditStatusVo();
  655. if(StringUtils.isNotBlank(typeStr)) {
  656. queryVo.setType(type);
  657. }
  658. if(StringUtils.isNotBlank(version)) {
  659. queryVo.setUserVersion(version);
  660. }
  661. queryVo.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode());
  662. List<WxWeappAuditStatusVo> apps = weappAuditStatusService.getList(queryVo);
  663. apps.stream().forEach( auditStatus -> {
  664. // 审核中,可以发起审核查询
  665. try {
  666. WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(auditStatus.getAppId());
  667. WxOpenMaQueryAuditResult openResult = openMaService.getLatestAuditStatus();
  668. logger.info(openResult.toString());
  669. if (openResult.isSuccess()) {
  670. // 审核状态,其中0为审核成功,1为审核失败,2为审核中,3已撤回
  671. switch (openResult.getStatus().intValue()) {
  672. case 0:
  673. auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode());
  674. break;
  675. case 1:
  676. auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode());
  677. break;
  678. case 2:
  679. auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode());
  680. break;
  681. case 3:
  682. auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode());
  683. break;
  684. default:
  685. auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode());
  686. break;
  687. }
  688. auditStatus.setAuditErrCode(gson.toJson(openResult));
  689. auditStatus.setAuditid(openResult.getAuditId());
  690. auditStatus.setAuditTime(new Date());
  691. weappAuditStatusService.updateStatus(auditStatus);
  692. }
  693. } catch (WxErrorException e) {
  694. logger.error(e.getMessage());
  695. }
  696. });
  697. return new ResultData();
  698. }
  699. @ApiOperation(value = "批量审核撤回", notes = "{\"type\":\"string\",\"version\":\"string\"}")
  700. @PostMapping("batchAuditCancel")
  701. public ResultData batchAuditCancel(@RequestBody Map<String, String> params) {
  702. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchAuditCancel");
  703. Gson gson = new GsonBuilder().create();
  704. String typeStr = params.get("type");
  705. String version = params.get("version");
  706. Integer type = null;
  707. try {
  708. type = Integer.parseInt(typeStr);
  709. } catch (Exception e) {
  710. logger.error(e.getMessage());
  711. }
  712. WxWeappAuditStatusVo queryVo = new WxWeappAuditStatusVo();
  713. if(StringUtils.isNotBlank(typeStr)) {
  714. queryVo.setType(type);
  715. }
  716. if(StringUtils.isNotBlank(version)) {
  717. queryVo.setUserVersion(version);
  718. }
  719. queryVo.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode());
  720. List<WxWeappAuditStatusVo> apps = weappAuditStatusService.getList(queryVo);
  721. apps.stream().forEach( auditStatus -> {
  722. // 审核通过,已发布不可撤回
  723. try {
  724. WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(auditStatus.getAppId());
  725. WxOpenResult openResult = openMaService.undoCodeAudit();
  726. logger.info(openResult.toString());
  727. if(openResult.isSuccess()) {
  728. auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode());
  729. auditStatus.setAuditErrCode(gson.toJson(openResult));
  730. auditStatus.setAuditTime(new Date());
  731. weappAuditStatusService.updateStatus(auditStatus);
  732. }
  733. } catch (WxErrorException e) {
  734. logger.error(e.getMessage());
  735. }
  736. });
  737. return new ResultData();
  738. }
  739. @ApiOperation(value = "批量发布", notes = "{\"type\":\"string\", \"version\":\"string\"}")
  740. @PostMapping("batchRelease")
  741. public ResultData batchRelease(@RequestBody Map<String, String> params) {
  742. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchRelease");
  743. Gson gson = new GsonBuilder().create();
  744. String typeStr = params.get("type");
  745. String version = params.get("version");
  746. Integer type = null;
  747. try {
  748. type = Integer.parseInt(typeStr);
  749. } catch (Exception e) {
  750. logger.error(e.getMessage());
  751. }
  752. WxWeappAuditStatusVo queryVo = new WxWeappAuditStatusVo();
  753. if(StringUtils.isNotBlank(typeStr)) {
  754. queryVo.setType(type);
  755. }
  756. if(StringUtils.isNotBlank(version)) {
  757. queryVo.setUserVersion(version);
  758. }
  759. queryVo.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode());
  760. List<WxWeappAuditStatusVo> apps = weappAuditStatusService.getList(queryVo);
  761. apps.stream().forEach( auditStatus -> {
  762. boolean isUpdate = false;
  763. WxWeappReleaseStatus releaseStatus = weappReleaseStatusService.getByAppId(auditStatus.getAppId());
  764. if(releaseStatus != null) {
  765. // 当前版本已发布成功,跳过
  766. if(releaseStatus.getUserVersion().equals(version)
  767. && releaseStatus.getReleaseStatus().equals(EnumWeappReleaseStatus.SUCCESS.getCode())) {
  768. return;
  769. }
  770. releaseStatus.setUserVersion(auditStatus.getUserVersion());
  771. releaseStatus.setVersionDesc(auditStatus.getVersionDesc());
  772. isUpdate = true;
  773. } else {
  774. releaseStatus = new WxWeappReleaseStatus();
  775. releaseStatus.setId(auditStatus.getId());
  776. releaseStatus.setTenantId(auditStatus.getTenantId());
  777. releaseStatus.setAppId(auditStatus.getAppId());
  778. releaseStatus.setType(auditStatus.getType());
  779. releaseStatus.setUserVersion(auditStatus.getUserVersion());
  780. releaseStatus.setVersionDesc(auditStatus.getVersionDesc());
  781. }
  782. try {
  783. WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(auditStatus.getAppId());
  784. WxOpenResult openRet = openMaService.releaesAudited();
  785. logger.info(openRet.toString());
  786. boolean releaseSuccess = false;
  787. if(openRet.isSuccess()) {
  788. releaseSuccess = true;
  789. }
  790. if(releaseSuccess) {
  791. releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.SUCCESS.getCode());
  792. } else {
  793. if(openRet.getErrcode().equals("85052")) {
  794. releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.SUCCESS.getCode());
  795. } else {
  796. releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.FAIL.getCode());
  797. }
  798. }
  799. releaseStatus.setReleaseErrCode(gson.toJson(openRet));
  800. releaseStatus.setReleaseTime(new Date());
  801. if(isUpdate) {
  802. weappReleaseStatusService.updateStatus(releaseStatus);
  803. } else {
  804. weappReleaseStatusService.saveStatus(releaseStatus);
  805. }
  806. } catch (WxErrorException e) {
  807. logger.error(e.getMessage());
  808. if(e.getError().getErrorCode() == 85052) {
  809. releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.SUCCESS.getCode());
  810. } else {
  811. releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.FAIL.getCode());
  812. }
  813. releaseStatus.setReleaseErrCode(e.getMessage());
  814. releaseStatus.setReleaseTime(new Date());
  815. if(isUpdate) {
  816. weappReleaseStatusService.updateStatus(releaseStatus);
  817. } else {
  818. weappReleaseStatusService.saveStatus(releaseStatus);
  819. }
  820. }
  821. });
  822. return new ResultData();
  823. }
  824. @ApiOperation(value = "小程序code提交状态分页列表接口", notes = "查询支持小程序类型,名称,appid,version")
  825. @GetMapping("codeStatusList")
  826. @ApiImplicitParams({
  827. @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
  828. @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
  829. public ResultData codeStatusList(@ModelAttribute WxWeappCodeStatusVo weappCodeStatusVo, Integer pageNum, Integer pageSize) {
  830. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::codeStatusList");
  831. if (null == weappCodeStatusVo) {
  832. weappCodeStatusVo = new WxWeappCodeStatusVo();
  833. } else {
  834. if(StringUtils.isBlank(weappCodeStatusVo.getAppId())) {
  835. weappCodeStatusVo.setAppId(null);
  836. }
  837. if(StringUtils.isBlank(weappCodeStatusVo.getName())) {
  838. weappCodeStatusVo.setName(null);
  839. }
  840. }
  841. weappCodeStatusVo.setSortColumns(BaseEntity.SortField.CodeTime_DESC, BaseEntity.SortField.TenantId_ASC, BaseEntity.SortField.Type_ASC, BaseEntity.SortField.UserVersion_DESC);
  842. final PageInfo<WxWeappCodeStatusVo> page = weappCodeStatusService.listAsPage(weappCodeStatusVo, pageNum, pageSize);
  843. return new ResultData(page);
  844. }
  845. @ApiOperation(value = "小程序审核状态分页列表接口", notes = "查询支持小程序类型,名称,appid,version")
  846. @GetMapping("auditStatusList")
  847. @ApiImplicitParams({
  848. @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
  849. @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
  850. public ResultData auditStatusList(@ModelAttribute WxWeappAuditStatusVo weappAuditStatusVo, Integer pageNum, Integer pageSize) {
  851. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::auditStatusList");
  852. if (null == weappAuditStatusVo) {
  853. weappAuditStatusVo = new WxWeappAuditStatusVo();
  854. } else {
  855. if(StringUtils.isBlank(weappAuditStatusVo.getAppId())) {
  856. weappAuditStatusVo.setAppId(null);
  857. }
  858. if(StringUtils.isBlank(weappAuditStatusVo.getName())) {
  859. weappAuditStatusVo.setName(null);
  860. }
  861. }
  862. weappAuditStatusVo.setSortColumns(BaseEntity.SortField.AuditTime_DESC, BaseEntity.SortField.TenantId_ASC, BaseEntity.SortField.Type_ASC, BaseEntity.SortField.UserVersion_DESC);
  863. final PageInfo<WxWeappAuditStatusVo> page = weappAuditStatusService.listAsPage(weappAuditStatusVo, pageNum, pageSize);
  864. return new ResultData(page);
  865. }
  866. @ApiOperation(value = "小程序发布状态分页列表接口", notes = "查询支持小程序类型,名称,appid,version")
  867. @GetMapping("releaseStatusList")
  868. @ApiImplicitParams({
  869. @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
  870. @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
  871. public ResultData releaseStatusList(@ModelAttribute WxWeappReleaseStatusVo weappReleaseStatusVo, Integer pageNum, Integer pageSize) {
  872. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::releaseStatusList");
  873. if (null == weappReleaseStatusVo) {
  874. weappReleaseStatusVo = new WxWeappReleaseStatusVo();
  875. } else {
  876. if(StringUtils.isBlank(weappReleaseStatusVo.getAppId())) {
  877. weappReleaseStatusVo.setAppId(null);
  878. }
  879. if(StringUtils.isBlank(weappReleaseStatusVo.getName())) {
  880. weappReleaseStatusVo.setName(null);
  881. }
  882. }
  883. weappReleaseStatusVo.setSortColumns(BaseEntity.SortField.ReleaseTime_DESC, BaseEntity.SortField.TenantId_ASC, BaseEntity.SortField.Type_ASC,BaseEntity.SortField.UserVersion_DESC);
  884. final PageInfo<WxWeappReleaseStatusVo> page = weappReleaseStatusService.listAsPage(weappReleaseStatusVo, pageNum, pageSize);
  885. return new ResultData(page);
  886. }
  887. @ApiOperation("小程序code提交版本列表")
  888. @GetMapping("codeVersionList")
  889. @ApiImplicitParams({
  890. @ApiImplicitParam(name = "type", value = "小程序类型", dataType = "int", paramType = "query", required = true)})
  891. public ResultData getCodeVersionList(Integer type) {
  892. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::getCodeVersionList");
  893. final List<Map> list = weappCodeStatusService.getVersionList(type);
  894. return new ResultData(list);
  895. }
  896. @ApiOperation("小程序审核版本列表")
  897. @GetMapping("auditVersionList")
  898. @ApiImplicitParams({
  899. @ApiImplicitParam(name = "type", value = "小程序类型", dataType = "int", paramType = "query", required = true),
  900. @ApiImplicitParam(name = "status", value = "审核状态", dataType = "int", paramType = "query")})
  901. public ResultData getAuditVersionList(Integer type, Integer status) {
  902. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::getAuditVersionList");
  903. final List<Map> list = weappAuditStatusService.getVersionList(type, status);
  904. return new ResultData(list);
  905. }
  906. @ApiOperation("小程序发布版本列表")
  907. @GetMapping("releaseVersionList")
  908. @ApiImplicitParams({
  909. @ApiImplicitParam(name = "type", value = "小程序类型", dataType = "int", paramType = "query", required = true)})
  910. public ResultData getReleaseVersionList(Integer type) {
  911. logger.debug("[" + getIpAddr() + "] WxWeappInfoController::getReleaseVersionList");
  912. final List<Map> list = weappReleaseStatusService.getVersionList(type);
  913. return new ResultData(list);
  914. }
  915. /*
  916. * 0. 回调搭建好
  917. * 1. wx_appinfo配置好
  918. *
  919. * 10. 授权
  920. * 11. 设置服务器域名及业务域名 - B/C 配置表
  921. * C 服务器域名 c.malls.iformall.com
  922. * 业务域名 c.malls.iformall.com,game.malls.iformall.com
  923. * B 服务器域名 b.malls.iformall.com
  924. * 业务域名 mobile.malls.iformall.com,admin.malls.iformall.com
  925. * C 服务器域名 ciformall.youlane.cn
  926. * 业务域名 ciformall.youlane.cn,game.youlane.cn
  927. * B 服务器域名 biformall.youlane.cn
  928. * 业务域名 mobile.youlane.cn,mall.youlane.cn
  929. * C 服务器域名 ctest.malls.iformall.com
  930. * 业务域名 ctest.malls.iformall.com,gametest.malls.iformall.com
  931. * B 服务器域名 btest.malls.iformall.com
  932. * 业务域名 mobiletest.malls.iformall.com,admintest.malls.iformall.com
  933. * 12. 设置微信基础版本 - 配置
  934. * 2.0.9
  935. * 13. 设置微信模板 - 配置
  936. * 核销成功模板 AT0423 14,15,16,7,10,3,9
  937. * 核销失败模板 AT1824 1,3,4,5
  938. * 14. 草稿提交
  939. * 15. 模板
  940. * 16. 上传小程序代码 - 配置 ext.json
  941. * 17. 体验二维码
  942. * 18. 提交审核 - json --- 获取审核ID
  943. * 19. 获取审核结果 - 基于审核ID查询 -- event 回调
  944. * 20. 审核撤回
  945. * 21. 发布已通过审核的小程序
  946. * 22. oauth2refreshAccessToken
  947. */
  948. }