Предположим, что есть несколько коммерческих и официальных аккаунтов/мини-программ с одинаковым функциональным режимом.Если это только для разработки апплета, нужно ли копировать несколько наборов кодов, изменять информацию об аппиде, настраивать сервер доменных имен и ключ и т. д. , на фоне официальной учетной записи WeChat Утомительная информация публикуется один раз при каждом изменении представления, и шаги повторяются. По мере того, как количество официальных учетных записей/мини-программ, которые необходимо поддерживать, постепенно увеличивается, ресурсы и затраты, которые необходимо инвестировать, также увеличиваются.
Вы когда-нибудь задумывались, что нам нужно всего лишь разработать набор кода официальной учетной записи/мини-программы, использовать его как шаблон, а затем систему управления фоном, и перенести все дела, сделанные в фоне официальной учетной записи WeChat, в нашу собственную система. Чтобы зайти в апплет с тем же бизнесом, только после авторизации администратора, достаточно нажать несколько кнопок в нашей системе, апплет может быть выпущен онлайн, разработан для N официальных учетных записей одновременно, и предоставлять стандартизированные услуги интерфейса для удовлетворения основные потребности бизнеса. Сканируя QR-код для авторизации на платформе, он может помочь N более чем одной официальной учетной записи реализовать бизнес, больше не нужно разбираться в громоздких настройках параметров, а пароль не предоставляется разработчику для обеспечения безопасности и действительно освобождает руки операционных студентов и разработчиков.Было бы неплохо иметь больше времени, чтобы поговорить о подружках. Правильно, разработка сторонней платформы WeChat — это артефакт, который поможет вам сэкономить больше времени на подбор девушек.
Обзор
Общедоступная платформа WeChat — сторонняя платформа (называемая сторонней платформой) открыта для всех разработчиков, прошедших квалификационную сертификацию разработчика. После получения авторизации официального аккаунта или оператора апплета (именуемого оператором) сторонние разработчики платформы могут предоставить официальному аккаунту или оператору апплета приложение для создания аккаунта, создание апплета, техническую разработку, отраслевые решения, маркетинг мероприятий, плагины. в возможностях и других услугах с полным спектром услуг. Операторы одной и той же учетной записи могут выбрать несколько третьих сторон, которые подходят им для предоставления возможностей продукта или доверить операции.
С точки зрения бизнес-характеристик сторонняя платформа должна быть такой, как показано на рисунке:С точки зрения конкретных бизнес-сценариев сторонние платформы включают следующие сценарии:
Предоставлять отраслевые решения, такие как решения для индустрии электронной коммерции или решения для индустрии туризма и т. д.;
Отрасль: (горизонтально) предоставлять более профессиональные возможности работы и более усовершенствованно управлять официальными учетными записями пользователей или мини-программами;
Функция: (вертикальная) оптимизация функций общедоступной платформы, таких как инструмент для оптимизации визуального стиля и макета графических сообщений, или специально настроенная функция управления пользователями CRM, или мощный подключаемый модуль апплета и т. д.
Обязательным условием для доступа к сторонним разработкам является наличие приложений открытой платформы WeChat.Подробные шаги по созданию см.
Developers.WeChat.QQ.com/doc/О, пилатес… 1, чтобы получить билет аутентификации
Билет проверки (component_verify_ticket), после того как сторонняя платформа прошла проверку, сервер WeChat будет отправлять component_verify_ticket по POST каждые 10 минут на свой «авторизованный URL-адрес для получения события».
После получения запроса POST просто верните строку успеха напрямую. В целях повышения безопасности XML-файл в postdata будет зашифрован с использованием ключа шифрования и дешифрования при подаче заявки на услугу, и его необходимо расшифровать после получения push-уведомления.
public void saveTicket(HttpServletRequest request, HttpServletResponse response) throws IOException {
String msgSignature = request.getParameter("msg_signature");// 微信加密签名
String timeStamp = request.getParameter("timestamp");// 时间戳
String nonce = request.getParameter("nonce"); // 随机数
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8"));
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
sb = sb.append(line);
}
String postData = sb.toString();
try {
AuthorizedUtils.saveComponentVerifyTicket(msgSignature, timeStamp, nonce, postData);
} catch (Exception e) {
logger.error("系统异常", e);
} finally {
// 响应消息
PrintWriter out = response.getWriter();
out.print("success");
}
}
2. Получите токен
Маркер (component_access_token) — это учетные данные для вызова интерфейса сторонней платформы. Существуют ограничения на получение токенов. Срок действия каждого токена составляет 2 часа. Управляйте токеном самостоятельно. Когда срок действия токена подходит к концу (например, 1 час 50 минут), снова вызовите API для его получения .
public static ComponentToken getComponentToken(String ticket) {
RedisService<ComponentToken> redisService = RedisService.load();
ComponentToken componentToken = redisService.load(ComponentToken.COMPONENTTOKEN_ID, ComponentToken.class);
if (componentToken == null) {
String encryptAppId = ThirdPlat.PLAT_APPID;
String appId = EnDecryptUtil.d3esDecode(encryptAppId);
String encryptSecret = ThirdPlat.PLAT_SECRET;
String secret = EnDecryptUtil.d3esDecode(encryptSecret);
String requestUrl = AuthAccessUrl.COMPONENT_ACCESS_URL;
Map<String, String> map = new HashMap<>();
map.put("component_appid", appId); //第三方平台appid
map.put("component_appsecret", secret); //第三方平台appsecret
map.put("component_verify_ticket", ticket);
String outputStr = JSONObject.toJSONString(map);
logger.warn("请求数据"+outputStr);
JSONObject jsonObject = HttpRequestUtils.httpRequest(requestUrl, "POST", outputStr);
if (null != jsonObject) {
long expires = System.currentTimeMillis() + 7200;
try{
expires = System.currentTimeMillis() + jsonObject.getIntValue("expires_in");
}catch (Exception e) {
}
try {
componentToken = new ComponentToken();
componentToken.setComponentAccessToken(jsonObject.getString("component_access_token"));
componentToken.setExpiresIn(expires);
redisService.save(componentToken, ComponentToken.class);
} catch (Exception e) {
componentToken = null;
logger.error("系统异常", e);
}
}
} else {
long sysTime = System.currentTimeMillis();
if (sysTime >= componentToken.getExpiresIn()) {
redisService.delete(ComponentToken.COMPONENTTOKEN_ID, ComponentToken.class);
componentToken = getComponentToken(ticket);
}else{
}
}
return componentToken;
}
3. Быстро создавайте небольшие программы
Быстрое создание интерфейса мини-программы оптимизирует процесс регистрации и сертификации мини-программы и может помочь сторонним платформам быстро расширять офлайн-продавцов, расширять спектр услуг продавцов и использовать офлайн-бизнес-возможности мини-программ. Использование распознавания лица юридического лица для замены процессов аутентификации, таких как небольшие платежи, значительно снизило трудозатраты на основную часть мини-программы и сбор информации о квалификации категории. Сторонней платформе необходимо собрать только четыре информации: имя юридического лица, юридическое лицо WeChat, название предприятия и информацию о коде предприятия, а затем она может отправить шаблон сообщения юридическому лицу для сбора информации о лице юридического лица и завершить все процессы регистрации и аутентификации. И когда юридическое лицо получает успешно созданный апплет APPID, юридическому лицу одновременно отправляется шаблон сообщения, предлагающий юридическому лицу установить почтовый ящик и пароль, чтобы юридическое лицо могло войти в консоль апплета для управление позже.
Создание небольшой программы с помощью этого интерфейса является «сертифицированным». Чтобы снизить порог стоимости доступа к апплету, апплет, созданный интерфейсом, не должен платить сбор за сертификацию в размере 300 юаней.
public AjaxResult fastRegister(String merchantId) {
Merchant merchant = merchantService.getById(merchantId);
if (merchant == null) {
logger.warn("快速创建小程序---->失败,merchant为null");
return AjaxResult.error("快速创建小程序失败,merchant为null",null);
} else {
RedisService<ComponentVerifyTicket> redisService = RedisService.load();
ComponentVerifyTicket componentVerifyTicket = redisService.load(ComponentVerifyTicket.COMPONENT_VERIFY_TICKET_ID,
ComponentVerifyTicket.class);
if (componentVerifyTicket == null) {
logger.warn("快速创建小程序---->失败,component_verify_ticket为null");
return AjaxResult.error("快速创建小程序失败,component_verify_ticket为null",null);
} else {
ComponentToken componentToken = AuthorizedUtils.getComponentToken(componentVerifyTicket.getComponentVerifyTicket());
RegisterWeappOut out = new RegisterWeappOut();
out.setName(merchant.getName())
.setCode(merchant.getCode())
.setCode_type(merchant.getCodeType())
.setLegal_persona_wechat(merchant.getLegalPersonaWechat())
.setLegal_persona_name(merchant.getLegalPersonaName())
.setComponent_phone(merchant.getComponentPhone());
JSONObject obj = BaseUtils.createRegisterWeapp(componentToken,out);
if (obj.getInteger("errcode") == 0 && "ok".equalsIgnoreCase(obj.getString("errmsg"))) {
return AjaxResult.success();
} else {
return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
}
}
}
}
4, чтобы получить код предварительной авторизации
Код преавторизации (pre_auth_code) необходимая информация для сторонней платформы для реализации авторизации и хостинга.Каждый код преавторизации действителен 10 минут. Перед вызовом необходимо получить токен.
public static String getPreAuthCode(String ticket) {
ComponentToken componentToken = getComponentToken(ticket);
String encryptAppId = ThirdPlat.PLAT_APPID;
String appId = EnDecryptUtil.d3esDecode(encryptAppId);
String url = AuthAccessUrl.PRE_AUTH_CODE_URL + componentToken.getComponentAccessToken();
Map<String, String> map = new HashMap<String, String>();
map.put("component_appid", appId);
JSONObject jsonObject = HttpRequestUtils.httpRequest(url, "POST", JSONObject.toJSONString(map));
return jsonObject.getString("pre_auth_code");
}
5. Направляйте продавцов к авторизации для получения авторизационной информации
Сторонний поставщик услуг строит авторизационную ссылку и размещает ее на своем сайте, после нажатия пользователем открывается страница авторизации.
public AjaxResult getMchWebAuthUrl(@PathVariable("id") String id) {
RedisService<ComponentVerifyTicket> redisService = RedisService.load();
ComponentVerifyTicket componentVerifyTicket = redisService.load(ComponentVerifyTicket.COMPONENT_VERIFY_TICKET_ID,
ComponentVerifyTicket.class);
if(componentVerifyTicket == null){
return AjaxResult.error("引入用户进入授权页失败,component_verify_ticket为null",null);
}else{
String preAuthCode = AuthorizedUtils.getPreAuthCode(componentVerifyTicket.getComponentVerifyTicket());
String encryptAppId = ThirdPlat.PLAT_APPID;
String appId = EnDecryptUtil.d3esDecode(encryptAppId);
String auth_type = ThirdPlat.AUTH_TYPE;
String requestUrl = AuthAccessUrl.WEB_AUTH_URL;
try {
requestUrl = requestUrl.replace("COMPONENT_APPID", appId).replace("PRE_AUTH_CODE", preAuthCode)
.replace("REDIRECT_URI", URLEncoder.encode(ThirdPlat.REDIRECT_URI.replace("MERCHANTID", id),"UTF-8")).replace("AUTH_TYPE", auth_type);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
logger.warn("步骤2:引入用户进入授权页---->成功,url为:" + requestUrl);
return AjaxResult.success("操作成功",requestUrl);
}
}
6. Установите основную информацию апплета
Установите имя апплета.Если имя не соответствует ключевому слову, настройка выполнена успешно, если имя соответствует ключевому слову, вам необходимо предоставить подтверждающие материалы и проверить. Измените аватар апплета. Измените введение функции. Измените настройки конфиденциальности апплета, то есть измените, можно ли его искать.
public AjaxResult setBasicInfo(BasicInfo basicInfo) throws IOException {
Merchant merchant = merchantService.getById(basicInfo.getMerchantId());
if (merchant == null) {
logger.warn("设置基本信息---->失败,merchant为null");
return AjaxResult.error("设置基本信息失败,merchant为null",null);
} else {
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
//修改头像
if (StringUtils.isNotEmpty(basicInfo.getHeadImage())) {
UploadIn uli = new UploadIn();
uli.setType("image").setUrlPath(basicInfo.getHeadImage());
JSONObject uploadJson = BaseUtils.upload(info,uli);
String mediaId = uploadJson.getString("media_id");
ModifyHeadImageIn mhi = new ModifyHeadImageIn();
mhi.setHead_img_media_id(mediaId).setX1("0").setY1("0").setX2("1").setY2("1");
JSONObject obj = BaseUtils.modifyHeadImage(info,mhi);
if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
} else {
merchant.setAppletsHeadImg(basicInfo.getHeadImage());
}
}
//修改名称
if (StringUtils.isNotEmpty(basicInfo.getNickname())) {
UploadIn uli = new UploadIn();
uli.setType("image").setUrlPath(merchant.getBusinessLicense());
JSONObject uploadJson = BaseUtils.upload(info,uli);
String mediaId = uploadJson.getString("media_id");
SetNicknameIn sni = new SetNicknameIn();
sni.setNick_name(basicInfo.getNickname());
sni.setLicense(mediaId);
JSONObject obj = BaseUtils.setNickname(info,sni);
if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
} else {
merchant.setAppletsName(basicInfo.getNickname());
if (obj.containsKey("audit_id") && StringUtils.isNotEmpty(obj.getString("audit_id"))) {
merchant.setAuditId(obj.getString("audit_id"));
}
}
}
//修改功能介绍
if (StringUtils.isNotEmpty(basicInfo.getSignature())) {
ModifySignatureIn msi = new ModifySignatureIn();
msi.setSignature(basicInfo.getSignature());
JSONObject obj = BaseUtils.modifySignature(info, msi);
if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
} else {
merchant.setAppletsSignature(basicInfo.getSignature());
}
}
//修改隐私设置,即修改是否可被搜索
if (StringUtils.isNotEmpty(basicInfo.getStatus())) {
SearchStatusIn ssi = new SearchStatusIn();
ssi.setStatus(basicInfo.getStatus());
JSONObject obj = BaseUtils.changeWxaSearchStatus(info, ssi);
if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
} else {
merchant.setSearchStatus(basicInfo.getStatus());
}
}
merchantService.updateById(merchant);
return AjaxResult.success();
}
}
7, авторизация оплаты
То есть заполните номер продавца и клавиши купец и загрузки сертификатов P12 8. Установите доменное имя сервера
Доменное имя сервера апплета, авторизованного третьей стороной, может быть только сервером сторонней платформы.Когда апплет выпускает код через стороннюю платформу и выходит в сеть, доменное имя сервера, изначально настроенное апплетом, будет будет удалено, и останется только доменное имя сервера сторонней платформы.Поэтому, прежде чем сторонняя платформа выпустит код вместо апплета, ей необходимо вызвать интерфейс для добавления собственного доменного имени сторонней платформы к апплету.
Уведомление:
Вам необходимо зарегистрировать доменное имя в доменном имени сервера апплета сторонней платформы, прежде чем вы сможете вызывать интерфейс для настройки.
Можно добавить не более 1000 легитимных доменных имен сервера; среди них поддерживается максимальное количество настроек для запрашиваемого доменного имени, сокетного доменного имени, доменного имени загружаемого файла, загружаемого доменного имени и доменного имени UDP — не более 200.
Заявки на внесение изменений можно подавать 50 раз в месяц.
public AjaxResult modifyDomain(ModifyDomain modifyDomain) {
Merchant merchant = merchantService.getById(modifyDomain.getMerchantId());
if (merchant == null) {
logger.warn("设置服务器域名---->失败,merchant为null");
return AjaxResult.error("设置服务器域名失败,merchant为null",null);
} else {
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
ModifyDomainOut out = new ModifyDomainOut();
out.setAction(modifyDomain.getAction());
String[] requests = modifyDomain.getRequestdomain().split(",");
List<String> requestList = Arrays.asList(requests);
out.setRequestdomain(requestList);
String[] wsrequests = modifyDomain.getWsrequestdomain().split(",");
List<String> wsrequestList = Arrays.asList(wsrequests);
out.setWsrequestdomain(wsrequestList);
String[] uploads = modifyDomain.getUploaddomain().split(",");
List<String> uploadList = Arrays.asList(uploads);
out.setUploaddomain(uploadList);
String[] downloads = modifyDomain.getDownloaddomain().split(",");
List<String> downloadsList = Arrays.asList(downloads);
out.setDownloaddomain(downloadsList);
JSONObject obj = BaseUtils.modifyDomain(info, out);
if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
return AjaxResult.success();
} else {
return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
}
}
}
9. Настройте доменное имя для бизнеса
Имя бизнес-домена апплета, авторизованного третьей стороной, может быть только сервером сторонней платформы.Когда апплет подключается к сети с помощью стороннего кода выпуска, имя бизнес-домена, изначально настроенное апплетом, будет удалено, и останется только доменное имя сторонней платформы. , поэтому сторонней платформе необходимо вызвать интерфейс, чтобы добавить бизнес-доменное имя для апплета, прежде чем выпускать код вместо апплета.
Уведомление:
Прежде чем вызывать интерфейс для настройки, необходимо зарегистрировать имя бизнес-домена в имени бизнес-домена апплета сторонней платформы.
При настройке имени домена для авторизованного апплета вы можете настроить имя поддомена.Например, если имя бизнес-домена, зарегистрированное третьей стороной, — qq.com, вы можете напрямую настроить qq.com и его имя поддомена (например, xxx .qq.com) в авторизованный апплет.
Вы можете добавить до 100 бизнес-доменов.
public AjaxResult webviewDomain(WebviewDomain webviewDomain) {
Merchant merchant = merchantService.getById(webviewDomain.getMerchantId());
if (merchant == null) {
logger.warn("设置业务域名---->失败,merchant为null");
return AjaxResult.error("设置业务域名失败,merchant为null",null);
} else {
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
SetWebViewDomainOut out = new SetWebViewDomainOut();
out.setAction(webviewDomain.getAction());
String[] webviews = webviewDomain.getWebviewdomain().split(",");
List<String> webviewList = Arrays.asList(webviews);
out.setWebviewdomain(webviewList);
JSONObject obj = BaseUtils.setWebViewDomain(info, out);
if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
return AjaxResult.success();
} else {
return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
}
}
}
10, загрузка небольшого программного кода
Сторонняя платформа должна сначала добавить черновик в библиотеку шаблонов кода или выбрать шаблон кода из библиотеки шаблонов кода, чтобы получить соответствующий идентификатор шаблона (template_id); затем вызвать этот API, чтобы загрузить код для авторизованного апплета.
public AjaxResult commit(CommitModel model) {
Merchant merchant = merchantService.selectMerchantById(model.getMerchantId());
if (merchant == null) {
logger.warn("上传代码---->失败,merchant为null");
return AjaxResult.error("上传代码,merchant为null",null);
}
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
CommitIn commitIn = new CommitIn();
String value = model.getValue();
String[] items = value.split("_");
String version = items[2];
commitIn.setTemplate_id(items[0])
.setUser_desc(items[1])
.setUser_version(version);
//第三方自定义的配置
JSONObject obj = new JSONObject();
obj.put("extAppid", merchant.getAppid());
Map<String, Object> map = new HashMap<>();
map.put("merchantId", model.getMerchantId());
map.put("userVersion", commitIn.getUser_version());
obj.put("ext", map);
map = new HashMap<>();
Map<String, Object> maps = new HashMap<>();
maps.put("pages/index/index", map);
obj.put("extPages", maps);
commitIn.setExt_json(JSONObject.toJSONString(obj));
//接受微信返回的数据
obj = CodeUtils.commit(info, commitIn);
if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper<AppletsRelease>()
.eq(AppletsRelease::getMerchantId,merchant.getId()));
if(ar == null){
ar = new AppletsRelease();
ar.setMerchantId(model.getMerchantId()).setHistoryversion(version);
} else{
ar.setHistoryversion(version);
}
appletsReleaseService.saveOrUpdate(ar);
return AjaxResult.success();
} else {
return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
}
}
11. Управление участниками
Прежде чем сторонняя платформа поможет авторизованному апплету отправить код на проверку, она может позволить оператору апплета испытать его.Перед этим личная учетная запись оператора в WeChat должна быть добавлена в список испытателей апплета.
Примечание. Если оператор также является администратором апплета, привязка не требуется, и администратор по умолчанию имеет разрешение на взаимодействие.
/**
* 绑定体验者
* @parambindTester
* @return
*/
@Override
public AjaxResult bindTester(BindTester bindTester) {
Merchant merchant = merchantService.getById(bindTester.getMerchantId());
if (merchant == null) {
logger.warn("绑定体验者---->失败,merchant为null");
return AjaxResult.error("绑定体验者失败,merchant为null",null);
} else {
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
JSONObject obj = MemberUtils.bindTester(info, bindTester.getWechatId());
if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
AppletsTester at = new AppletsTester();
at.setMerchantId(bindTester.getMerchantId()).setWechatId(bindTester.getWechatId()).setUserStr(obj.getString("userstr"));
appletsTesterService.insertAppletsTester(at);
return AjaxResult.success();
} else {
return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
}
}
}
/**
* 解除体验者
* @paramtesterIds
* @return
*/
@Override
public AjaxResult unbindTester(Long[] testerIds) {
for (Long id : testerIds) {
AppletsTester tester = appletsTesterService.getById(id);
if (tester == null) {
logger.warn("解除体验者---->失败,tester为null");
return AjaxResult.error("解除体验者,tester为null",null);
}
Merchant merchant = merchantService.getById(tester.getMerchantId());
if (merchant == null) {
logger.warn("解除体验者---->失败,merchant为null");
return AjaxResult.error("解除体验者,merchant为null",null);
}
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
JSONObject obj = MemberUtils.unbindTester(info, tester.getWechatId());
if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
appletsTesterService.removeById(id);
} else {
return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
}
}
return AjaxResult.success();
}
12. Получите QR-код пробной версии
public AjaxResult getQrcode(String merchantId) {
Merchant merchant = merchantService.getById(merchantId);
if (merchant == null) {
logger.warn("获取体验二维码---->失败,merchant为null");
return AjaxResult.error("获取体验二维码,merchant为null",null);
}
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
String qrcodeUrl = CodeUtils.getQrcode(info, "pages/index/index");
return AjaxResult.success("操作成功",qrcodeUrl);
}
13. Отправить на рассмотрение
public AjaxResult submitAudit(SubmitAudit submit) {
Merchant merchant = merchantService.getById(submit.getMerchantId());
if (merchant == null) {
logger.warn("获取体验二维码---->失败,merchant为null");
return AjaxResult.error("获取体验二维码,merchant为null", null);
}
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
List<String> categorys = submit.getCategory();
submit.setFirst_id(categorys.get(0).split("-")[0])
.setFirst_class(categorys.get(0).split("-")[1])
.setSecond_id(categorys.get(1).split("-")[0])
.setSecond_class(categorys.get(1).split("-")[1])
.setTag(submit.getTag().replace(",", " "));
List<SubmitAudit> submits = new ArrayList<>();
submits.add(submit);
JSONObject sa = CodeUtils.submitAudit(info, submits);
if (sa.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(sa.getString(ResStatus.ERRMSG))) {
JSONObject obj = CodeUtils.getAuditStatus(info, sa.getString("auditid"));
if (obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper<AppletsRelease>()
.eq(AppletsRelease::getMerchantId,merchant.getId()));
if (ar == null) {
return AjaxResult.error("请先上传代码");
}
ar.setMerchantId(submit.getMerchantId())
.setAuditId(sa.getString("auditid"))
.setStatus(obj.getString("status"))
.setRemark(obj.getString("screenshot"));
if (AppletsRelease.STATUS_0.equals(ar.getStatus())) {
ar.setRemark(AppletsRelease.MSG_0);
} else if (AppletsRelease.STATUS_1.equals(ar.getStatus())) {
ar.setReason(obj.getString("reason"))
.setScreenshot(obj.getString("screenshot"))
.setRemark(AppletsRelease.MSG_1);
} else if (AppletsRelease.STATUS_2.equals(ar.getStatus())) {
ar.setRemark(AppletsRelease.MSG_2);
} else if (AppletsRelease.STATUS_3.equals(ar.getStatus())) {
ar.setRemark(AppletsRelease.MSG_3);
} else if (AppletsRelease.STATUS_4.equals(ar.getStatus())) {
ar.setRemark(AppletsRelease.MSG_4);
}
appletsReleaseService.updateById(ar);
return AjaxResult.success();
} else {
return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE), obj.getString(ResStatus.ERRMSG));
}
} else {
return AjaxResult.error(sa.getInteger(ResStatus.ERRCODE), sa.getString(ResStatus.ERRMSG));
}
}
14, отзыв отзыв
Примечание. Количество индивидуальных счетов проверено каждый день для вывода не более одного раза в месяц, не более 10 раз.
public AjaxResult undoCodeAudit(String[] ids) {
StringBuilder sb = new StringBuilder();
for (String id : ids) {
Merchant merchant = merchantService.getById(id);
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
JSONObject obj = CodeUtils.undoCodeAudit(info);
if (obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper<AppletsRelease>()
.eq(AppletsRelease::getMerchantId,merchant.getId()));
ar.setStatus(AppletsRelease.MSG_3);
appletsReleaseService.updateById(ar);
} else{
sb.append(merchant.getName()+",");
}
}
if (sb.length() == 0) {
return AjaxResult.success();
} else {
String name = sb.substring(0, sb.length()-1);
return AjaxResult.error(name+"审核撤回失败");
}
}
15. Публикуйте одобренные мини-программы
public AjaxResult releaseApplets(String[] ids) {
StringBuilder sb = new StringBuilder();
for (String id : ids) {
Merchant merchant = merchantService.getById(id);
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
JSONObject obj = CodeUtils.release(info);
if (obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper<AppletsRelease>()
.eq(AppletsRelease::getMerchantId,merchant.getId()));
ar.setStatus(AppletsRelease.STATUS_5);
appletsReleaseService.updateById(ar);
} else{
sb.append(merchant.getName()+",");
}
}
if (sb.length() == 0) {
return AjaxResult.success();
} else {
String name = sb.substring(0, sb.length()-1);
return AjaxResult.error(name+"发布失败");
}
}
16. Откат версии мини-программы
Уведомление:
Если предыдущей онлайн-версии нет, вернуться назад невозможно.
Откат вверх возможен только для одной версии, то есть после отката текущей версии интерфейс отката версии не может быть вызван повторно.
public AjaxResult revertCodeRelease(String[] ids) {
StringBuilder sb = new StringBuilder();
for (String id : ids) {
Merchant merchant = merchantService.getById(id);
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
JSONObject obj = CodeUtils.revertCodeRelease(info);
if (!(obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG)))) {
sb.append(merchant.getName()+",");
}
}
if (sb.length() == 0) {
return AjaxResult.success();
} else {
String name = sb.substring(0, sb.length()-1);
return AjaxResult.error(null,name+"审核撤回失败");
}
}
17. Получите код апплета
public AjaxResult getMiniQrcode(@PathVariable("merchantId") String merchantId) {
Merchant merchant = merchantService.getById(merchantId);
if (merchant == null) {
logger.warn("获取小程序码---->失败,merchant为null");
return AjaxResult.error("获取小程序码,merchant为null",null);
}
String qrcode;
if (StringUtils.isNotEmpty(merchant.getAppletImage())) {
qrcode = merchant.getAppletImage();
} else {
AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
qrcode = WxUtils.getMiniQrcode(merchantId, "pages/index/index", "merchant", "miniQrcode", info.getAuthorizer_access_token());
merchant.setAppletImage(qrcode);
merchantService.updateById(merchant);
}
return AjaxResult.success("操作成功",qrcode);
}