个人案例
- 微慕+
微慕WordPress小程序增强版
微慕增强版扫码体验
- 微慕
微慕WordPress小程序专业版
微慕扫码体验
- “2024版微信小店”接入说明、指引及小程序相关开发接入指南(最近更新日期2024年12月4日,小程序跳转小店订单详情)
写在最前面 之前曾写过“自定义交易组件相关接入指引”,广受好评,解决了很多开发者接入时遇到的问题,当然,其中也不乏一些喂不饱的白眼狼,得到便利还反咬一口,无耻至极,内容如有错误请指正,请文明交流! 本文会尽可能跟随官方功能迭代而更新内容 有问题可以跟帖回复,尽可能的给你解决(解决不了也没办法🤷♀️) 良言一句三冬暖,恶语伤人六月寒。 腾讯在2024年8月12日发布公告:腾讯计划自08月25日起,正式支持商家将视频号小店升级成微信小店。公告原文->点我查看 本文主要介绍24版的“微信小店”的升级内容及对接过程中各流程的注意事项与易错点(暂不包含新店开店流程),文档篇幅较长,如无需查看完整文档可以使用浏览器自带页面搜索功能进行关键字搜索(快捷键Ctrl+F )。 本文更新日志(后续会对本文变动内容进行标注) 2024.12.13 更新支持小程序跳转小店订单详情 2024.12.04 更新商品卡片样式自定义 2024.09.06 更新微信小店关联账号数量新规则 2024.08.27 小程序内嵌入商品跟佣问题修复 2024.08.26 更新客服、小程序内嵌入商品跟佣相关内容 2024.08.25 本文发布 1、“原视频号小店”升级“24版微信小店”后新增内容: 1.1 店铺管理新增“主页管理”入口 升级“微信小店”后,在管理后台->店铺管理会新增一个“主页管理”,相当于店铺有了一个首页,目前支持配置精选展示位、商品商品分类、主页背景图以及推荐商品排序 “小店”主页商品排序 调整店铺主页销售中商品的默认展示顺序,可以按照序号排序,数字越小越靠前;同时也支持对单个商品进行置顶或隐藏(图一为后台操作排序,图二圈中部分为对应排序展示) [图片] [图片] 注意事项及其他说明 最多可以置顶50个商品 后序置顶商品会在前序置顶前展示 “小店”主页商品分类 可以在主页创建分类并关联商品,当前支持2级分类 [图片] 注意事项及其他说明 1)分类目前只支持上移/下移排序,暂不支持置顶操作 2)单个分类不能超过10个汉字,支持emoji(这个好评) 3)一二级分类暂未测试到数量上限,不过不建议单个一级分类下配置二级分类过多,有可能会影响其他分类展示,尤其是该分类在第一位的时候 4)分类名称会有内容审核,敏感词及平台不允许发布的内容无法进行创建 5)一个商品是支持挂在多个分类下 主页背景图 可配置一张主页背景图,会按16:9比例展示在主页顶部(自己店铺上传的还在审核,先放官方示意图) [图片] 注意事项及其他说明 1)图片仅支持JPEG、JPG、PNG、BMP格式,大小不超过10M 2)背景图片需审核,带二维码、违反公序良序及其他违反法律法规的内容会被驳回 精选展示位 在主页店铺信息下展示推荐内容,目前支持配置展示商品、指定视频号视频、单篇公众号内容三种内容,样式目前只有大图和小图两种展示方式。 用户端展示商品内容示例-小图模式: [图片] 用户端展示视频号内容示例-小图模式 [图片] 用户端展示公众号内容示例-小图模式 [图片] 用户端展示商品内容示例-大图模式 [图片] 用户端展示视频号内容示例-大图模式 [图片] 用户端展示公众号内容示例-大图模式 [图片] 注意事项及其他说明 1)图片仅支持JPEG、JPG、PNG、BMP格式,测试图片可以超过10M(后续是否会改不清楚,不过图片过大加载是真的慢) 2)展示内容会根据展示内容拉取对应商品首图、视频号视频封面以及公众号文章封面,也可以自行上传图片,这里需要注意的点是即使你的图片在商品可以过审核,但在主页推荐不一定能过审核,两者审核尺度不同 3)小图模式至少配置3个展示位才可以保存,而大图模式配置1个展示位就可以,最多允许配置5个展示位 4)商品仅支持配置自己店铺内商品,视频号内容支持配置任意视频号博主任意公开视频,公众号内容支持选择任意公众号任意公开内容 5)无论大图模式还是小图模式,目前仅支持配置1:1的图片,后续是否优化暂不可知 1.2 客服由企业微信客服切换为小店客服 类似原小程序客服,可通过网页和手机端接收、处理客户咨询。目前已支持查询咨询客户下单信息,向咨询用户发送商品、订单消息,配置快捷短语等,基础功能可以满足大部分用户需求,终于可以不用再去付费买三方客服应用了,这个要👍。 注:这里截图不放自己店铺了,涉及用户隐私太多,图示为官方示意图 1.2 PC端: [图片] 1.2 移动端: [图片] 注意事项及其他说明 客服功能存量商户升级指引"->点我查看"(需升级为微信小店后操作) 1.3 新增店铺关联账号 关联账号可以直接售卖小店内的商品,目前支持关联5个视频号与5个公众号,分别可设置1个对外展示账号。 对外展示账号样式-示例图(目前不会显示视频号、公众号名称,只有入口) [图片] 注意事项及其他说明 1)对外展示账号可以进行修改,每种对外展示类型账号每年3次修改机会。 2)配置关联账号后,该账号可在视频号带货中心>橱窗管理中管理带货商品 3)关联账号详细说明及要求:“->点我查看” 4)如果在电脑上打开了客服网页版且在活跃中,当前手机上是不会重复接收到消息推送,预计9月份会有客服PC端和手机APP推出 5)若微信小店店铺开店满30天,且近30天内DSR均大于等于4.6分,关联账号数量可提升至视频号和公众号各10个。(2024.09.06更新) 2、小程序侧新增能力 2.1 小程序支持内嵌微信小店首页,展示小店首页,并进行跳转交易 store-home 开发文档地址:->点我直达 小程序嵌入微信小店首页组件样式 [图片] 注意事项及其他说明 1)基础库需要3.5.5,否则真机调试不显示,可以在开发者工具选择3.5.5版本进行推送 [图片] 2)支持任意升级微信小店后的任意微信小店APPID 3)内嵌入微信小店首页时会有一个“小店”文字显示在下方,可以通过下述方式屏蔽, .wx_store_home .wx_store_home_img_desc { display: none; } 4)第3点中的代码同时也支持屏蔽组件其他类型信息 wx_store_home_info wx_store_home_img_box wx_store_home_info_logo wx_store_home_img_box wx_store_home_info_title wx_store_home_info_title_text wx_store_home_info_history 2.2 小程序内嵌微信小店商品,展示小店商品,并进行跳转交易且支持小店优选联盟带货跟佣功能。 store-product 开发文档地址:->点我直达 小程序内嵌微信小店商品组件样式 [图片] 2024.12.04 新增支持自定义样式 custom-style ,支持自定义的样式有 键名 说明 允许自定义的属性 card 卡片样式 background-color title 标题样式 color price 价格样式 color buy-button 购买按钮样式 width、border-radius、color、background-color buy-button-disabled 购买按钮禁用态样式 width、border-radius、color、background-color 示例图: [图片] 注意事项及其他说明 1)基础库需要3.5.5,否则真机调试不显示 2)支持任意升级微信小店后的任意微信小店商品ID,这里需要使用微信小店商品id,不支持商户自定义商品ID 3)如果商品违规下架,内嵌商品会直接显示商品违规下架 4)商品组件也可以参考店铺主页代码,屏蔽对应组件内容信息 5)跟佣还未测试,稍后补充 2.2.1 小程序内嵌微信小店商品优选联盟带货跟佣 2024.08.26 14:00:00 目前带货跟佣测试不通,视频号助手API接口实际请求返回无“product_promotion_link”参数,接口返回参数“promotion_key”值类似“product_promotion_link”,疑似为“product_promotion_link”信息。 在小程序前端测试中,store-product组件包含“product_promotion_link”参数时,无法展示对应小店商品,改为“promotion_key”可以正常显示。 目前测试来看小程序侧并不会校验跟佣信息是否正确,建议自己开发测试时一定要慎重一下此处… 2024.08.27 17:30:00 跟佣测试成功,视频号助手API接口实际请求返回无“product_promotion_link”参数,接口返回参数“promotion_key”即为store-product组件的product_promotion_link参数。 注意:文档写的是product-promotion-link,实际应为product_promotion_link,如果使用product-promotion-link,在前端是不会展示对应商品的。 2.3 小程序跳转小店订单详情 wx.openStoreOrderDetail() 开发文档地址:->点我直达 测试暂未发现什么异常 3、搜一搜新增“小店”分类 截止文章更新,目前只支持根据关键词搜索到店铺,暂不支持搜索到商品 [图片] 持续更新中…
2024-12-13 - 关于微信小程序加载本地资源文件的一种解决方案
一、需求背景 有些时候在代码包里存在一些稳定的或者说保底的配置或资源文件,不希望通过http从服务端获取。此时,可能想到的办法就是利用本地来存储这样的一些文件或资源。 二、存在的问题 但是上面的想法,存在一个问题:如何在js代码逻辑中读取到这些文件内容呢? 官方api提供了 readFile 或 readFileSync 来读取文件内容。但是在代码包里的文件在打包后不一定还是原来的样子。而 readFile 或 readFileSync 是可以读取本地文件的。但是这里说的本地,不是代码包的这个本地,而是微信封装好的隔离性的目录。所以,代码包编译上传,readFile 或 readFileSync 将无法读取到这些文件了。要么提示no such file or directory 要么提示 permission denied 等错误。反正就是读取失败 三、解决方案 出现上面的问题的根本原因是:当代码build和上传,最后被微信下载渲染成小程序后。代码已经不是源码的结构了,有些文件也不会被打包进去。此外整个目录结构不一样了;还有所谓的本地路径也不一样了。 所以要解决以上的几个问题,就可以最终实现读取“本地”资源文件了。 问题1:如何让某个代码中的目录或文件一定被打包进build后的代码中:详见packOptions问题2:所谓的本地路径以及本地用户路径是什么?本地路径不是源代码中的路径,而是 详见本地路径 详见本地用户文件问题3:哪些文件(白名单后缀)可以被访问?详见允许上传的文件;也就是说,不是所有的后缀名都可以被存放到 本地路径或本地用户路径中。也就是说如果资源文件中的 白名单后缀的文件,无法被上传。那如何解决这个问题呢?问题4:如何让我们的文件被访问到呢?以下是我实践下来的解决方案和思路。因为问题2,所以需要将代码中的文件,通过某种方式放到 本地用户文件 中,然后还需要避免问题3 的后缀问题。还需要将资源文件加到 packOptions 中include列表,解决问题1; 综上,解决思路如下: 源代码中 添加资源文件所在的目录比如 asserts 到 packOptions.include将 asserts 通过预编译逻辑压缩为 zip包,且将后缀更改为问题3中的任意后缀,比如json,asserts.json利用 copyFile 或 copyFileSync 将 asserts.json 复制到 ${wx.env.USER_DATA_PATH}/asserts/asserts.json,此次主要 需要通过 mkdir 创建 asserts目录利用 unzip 解压 ${wx.env.USER_DATA_PATH}/asserts/asserts.json,即可解压出 源代码中 asserts中的所有文件到 ${wx.env.USER_DATA_PATH}/asserts/ 中通过 readFile 或 readFileSync 读取 asserts/xxx.json 需要封装一下 读取 ${wx.env.USER_DATA_PATH}/asserts/xxx.json 即可完成整个流程的读取。其中有个前提需要处理,上面的 第2步需要一个 预编译,由于我是用的uniapp实现的开发,在vue.config.js 中的webpackplugin中实现了一个zip plugin,实现了资源文件zip。如果原生小程序,需要自行处理。 具体代码如下: // 执行文件复制操作 const fs = wx.getFileSystemManager(); // let src = `asserts/3.json` // let dst = `${wx.env.USER_DATA_PATH}/asserts/3.json` // fs.copyFile({ // srcPath: src, // destPath: dst, // success: res => { // console.log(`文件复制成功 ${src} -> ${dst}`, res); // }, // fail: err => { // console.error(`文件复制失败 ${src} -> ${dst}`, err); // } // }); // fs.readdir({ // dirPath: `asserts/`, // success(res) { // console.log(res.files) // 会卡死 // for (let i = 0; i < res.files.length; i++) { // let path = res.files[i] // let src = `asserts/${path}` // let dst = `${wx.env.USER_DATA_PATH}/${path}` // fs.copyFileSync(src, dst); // // fs.copyFile({ // // srcPath: src, // // destPath: dst, // // success: res => { // // console.log(`文件复制成功 ${src} -> ${dst}`, res); // // }, // // fail: err => { // // console.error(`文件复制失败 ${src} -> ${dst}`, err); // // } // // }); // } // }, fail(res) { // console.error(res) // } // }) try { const files = fs.readdirSync(`asserts/`) console.log(files) // 清空原来的数据 fs.rmdirSync(`${wx.env.USER_DATA_PATH}/asserts`, true) fs.mkdir({ // 创建目录 dirPath: `${wx.env.USER_DATA_PATH}/asserts`, recursive: false, complete() { fs.unzip({ zipFilePath: `asserts/asserts.json`, targetPath: `${wx.env.USER_DATA_PATH}/asserts`, success(res) { console.log(res) // 此次可以抽象为一个独立函数 fs.readFile({ filePath: `${wx.env.USER_DATA_PATH}/asserts/xxx.json`, encoding: 'utf8', position: 0, success(res) { console.log(`readFile成功`, res.data); }, fail(err) { console.log(`readFile失败`, err); } }) fs.readdir({ dirPath: `${wx.env.USER_DATA_PATH}/asserts`, success(res) { console.log(res.files) }, fail(res) { console.error(res) } }) }, fail(res) { console.error(res) } }) } }) } catch (e) { console.error(e) } 上面的代码中存在一个测试出来的问题,我在 readdir 出的 文件,我本打断逐个copyFile到 ${wx.env.USER_DATA_PATH} 结果测试下来,开发工具直接卡死了。这个应该是 开发工具的bug。 后面仔细想想,如果asserts的文件很多,循环 copyFile 性能也不够。所以改成 copyFile -> unzip 的方式。应该性能上有所提高。 最后,如果是uniapp项目,对应的vue.config.js 文件可以添加 如下插件,实现编译时,自动资源目录zip的功能 new (class ZipPlugin { apply(compiler) { compiler.hooks.done.tap('ZipPlugin', async () => { let assertOutputPath = getPackageDir(staticDir) deleteDirectory(assertOutputPath); const outputPath = path.join(compiler.options.output.path, `${staticDir}/zip.json`); const output = fs.createWriteStream(outputPath); const archive = archiver('zip', {zlib: {level: 9}}); output.on('close', function () { console.log(archive.pointer() + ' total bytes'); console.log('close archiver has been finalized and the output file descriptor has closed.'); }); output.on('end', function () { console.log('end Data has been drained'); }); archive.on('warning', function (err) { console.error('warning: ', res); }); archive.on('error', function (err) { console.error('error: ', err); }); archive.pipe(output); // add directory const sourceDir = path.join(__dirname, `${staticDir}/`); archive.directory(sourceDir, false); await archive.finalize() console.log(`ZipPlugin sourceDir :${sourceDir} ->\n\toutputPath: ${outputPath}`) }); } })() 完结
2024-06-20 - 视频号无法直播,提示该地区不支持播?
[图片]视频号认证的公众号是香港的,然后在深圳也提示不支持直播,是什么原因呢?
2024-04-08 - 视频号视频或者视频号直播时,如果挂载小程序(即跳转到小程序)?
请问一下,视频号中视频、视频号直播时、或者视频号主页,怎么样点击能跳转到微信小程序里呢? 视频号一致与小程序主体一致。
2024-03-21 - 小程序使用webview嵌套H5中使用iframe真机无法跳转 wx.miniProgram.getEnv等失效问题分享
小程序使用webview嵌套H5真机无法跳转 wx.miniProgram.getEnv、wx.miniProgram.navigateTo等失效无响应问题分享 原因分析:由于页面使用了iframe导致在子页面中真机无法准确获取页面运行环境(开发者工具中无影响); 解决方案:在调用方法前加一个 parent. 在父页面中调用方法即可正常运行; 过程:尝试过切换jweixin代码版本但是问题依旧; 分享:遇到同类问题用这个方法解决了的小伙伴欢迎评论区留言点赞👍! <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> 核心代码: var ua = navigator.userAgent.toLowerCase(); if(ua.match(/MicroMessenger/i)=="micromessenger") { //由于页面是iframe 所以在调用wx.miniProgram.getEnv的时候直接调用会没反应,需要加一个parent父组件调用即可成功调起来。(开发者工具可以成功跳转但是真机没办法跳转1.3.2-1.6.0的js都试过问题依旧) parent.wx.miniProgram.getEnv((res)=>{ if (res.miniprogram) { // alert("在微信内,在小程序内") // console.log('在小程序内') // alert("在小程序内") parent.wx.miniProgram.navigateTo({ url: "/pages/minipay/minipay?outTradeNo="+outTradeNo+"&type=miniapp&code=" , //小程序的支付地址,queryParam是需要传递的商品id等数据 fail: function(err){ alert("跳转小程序失败!") }, }); return false; } else{ alert("在微信内,但是不在小程序内") console.log('在微信内,但是不在小程序内')//嵌入公众号 return false; } }) } else{ console.log('在微信外') if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { console.log("移动") // 支付在同一页面打开 // return; } else { console.log("PC") // 支付在同一页面打开 // return; } return false; }
2020-12-21 - 更换视频号小店超级管理员,新管理员必须有视频号吗?
微信A:没有视频号,没有视频号小店 微信B:有视频号,有视频号小店(是小店超级管理员) 要把微信B的视频号和视频号小店(包括小店超管),都转移到微信A上,怎么操作? 疑惑: 1、更换微信B视频号管理员的时候,提示要先“更换小店管理员到其他视频号账号”下,能直接换成微信A吗? 2、更换视频号小店超级管理员,新管理员必须有视频号吗?
2023-10-27 - 虚拟支付解决方案案例简析
虚拟支付解决方案案例简析 在墨问便签的用户交流群里,无意看到一种虚拟支付的解决方式,目前不知道是否合规,但是还是比较新颖的,墨问便签的池老师也算是行业大咖,感觉不太会有问题 iOS 里 小程序不给卖虚拟商品? 我看到墨问的解决方案是用公众号去套一层 [图片][图片] [图片] [图片] 扫码后跳转到墨问的公众号进行支付,而且这个二维码是有时效性的,过一段时间就失效了 [图片] 也看到了斗鱼的公众号里面就有充值入口 [图片] 以上方案仅供参考,是否合规,还需要时间来验证 # 虚拟支付解决方案
2023-12-09 - iOS微信小程序虚拟支付解决方案
众所周知,在IOS微信小程序不支持虚拟支付,一直是困扰IOS开发者、运营最头疼的问题,主要原因是苹果不允许IOS微信上架这类产品。导致微信小程序的开发者在IOS上都不能支付虚拟商品,虚拟商品包含了虚拟课程、会员、虚拟书等。 那么针对这个问题,有什么解决方案呢?今天就这个问题,来分享一下关于个人在这方面的一点经验。 做虚拟开发支付,要弄明白为什么微信小程序不支持iOS进行虚拟支付,所谓的虚拟支付又是指的什么? 第一个问题很简单,如果微信小程序支持iOS虚拟支付,就会绕过苹果商店的应用支付方式,在苹果商店下载的APP进行支付,苹果商店会扣除一部分费用的,这样苹果就减少了一部分收入,这也是iOS系统中一个明确规定的条款。 第二个问题,虚拟支付是指包括银行卡支付、电话卡预付费、信用卡支付、网上支付、手机支付等各种非现金的支付方式。 对于知识付费的博主、知识店铺和企业影响来说,不支持iOS虚拟支付,自然就影响了收入。毕竟微信用户中iOS用户群体占比还是非常大的。 要规避这个问题,很多应用的解决方案是: 1、提供应用官方充值(支付)渠道,例如需要充值时,跳转到官网的充值网站,购买消费时,直接从个人的钱包中进行扣除。 [图片] 2、通过微信小程序客服助手,当用户进行支付时,默认跳转到客服助手聊天界面,系统会默认给用户发送一个支付链接,这种链接是一个公众号,或者是一个H5的链接。用户点击链接就可以正常下单,实则上和第一种方案是一样的逻辑。 [图片] 3、微信扫码支付,当用户进行支付时,直接弹出支付二维码,让用户扫码支付。这种逻辑仍然是一个H5的链接方式。
2024-11-28 - 微信公众号部分相关客服(可转人工)
微信公众平台-小程序代码审核咨询微信公众平台-监管相关咨询微信公众平台-名称审核咨询公众号帐号审核-高危open官网咨询客服小程序交易组件第三方代创建小程序咨询MP客服消息规则调整反馈入口公众号作者小程序注册公众号客服消息调整视频号直播官方客服微信公众平台微信公众平台客服公众号账号审核-低质公众号账号审核-诱导公众号申诉咨询微信公众平台-公众号业务咨询发货信息管理客服小程序订单中心页Path设置审核订单发货管理客服小程序客服咨询模板消息问题咨询小程序隐私保护咨询付费管理-客服咨询模板消息枚举值审核咨询公众号营销内容咨询微信公众平台-小程序类目审核咨询小程序备案-客服咨询小程序年费咨询服务商采购-客服咨询公众号
2023-11-02 - 【完整攻略】2023小程序商城对接视频号小店
视频号的短视频能力,直播能力,小店能力都给企业赋能了很多营销手段,那如果微信将更多的营销能力集中在视频号,比如目前小程序官方直播已经不被支持,未开通过小程序直播功能的企业无法再申请使用小程序直播,并且功能恢复没有具体时间预告!微信可能不再支持小程序直播,将直播入口集中在视频号生态内。那么运营小程序商城的企业该如何应对?企业的私域小程序商城可以如何利用视频号的公域流量实现变现?微信生态运营的商家需要:使用视频号的短视频营销,直播营销助力商家商品曝光和成交;利用视频号的分享员功能,刺激会员在视频号生态进行转发分享;结合自有小程序商城玩法,将公域流量的用户留存到私域商城内;结合自有小程序的用户关系,实现订单的多种分润和奖励;【视频号小店】实现场景:增加购买渠道:企业将自有小程序商城商品同步到视频小店→客户可以不进入商城,通过视频号小店直接在微信下单,订单同步回小程序商城;增加锁客方式:使用视频号分享员接口对接,会员可在自有小程序商城申请成为视频号的分享员→成为分享员后通过分享视频号直播间;短视频;商品等链接给新会员;新会员用户下单后自动注册为商城会员,并且成为分享人的下级客户,锁定推荐关系;增加获客渠道:如果未通过分享员的链接,新会员通过视频号小店直接下单,同样自动注册为商城会员,上级为总平台,无其他推荐人;增加订单奖励:无论是新会员还是老会员,视频号小店下单后订单同步回小程序商城平台,可在小程序商城内获得平台设定的订单奖励;执行订单分润:会员在视频号小店下单后,订单同步至小程序商城,依据下单会员的上级关系链,执行小程序商城内其他分润逻辑;注意事项:二次分享无效,例如:分享员A在直播间分享给新会员,新会员点击消息(有效),新会员把这个消息分享给新会员B,B点击,无效;如果新会员进入分享员A分享的视频号进入,没有下单支付,后面再进入别的分享员b分享的视频号进入下单支付了,成为B的下线(因下单支付后同步的订单才会记录会员);通过分享视频号直接下单并支付的可以锁定关系,若是从微信的订单管理去付款,这个商城无法控制,这个是微信功能。这笔订单归属哪个分享员,这种逻辑是微信那边决定的;接入教程:一、基础设置1.信息在视频号小店https://channels.weixin.qq.com/shop 服务市场--自研处获取,获取信息这里只有超级管理员才能设置,IP白名单暂不用设 [图片] [图片] 消息推送填写内容可以到后台插件复制回调地址填写到服务器地址处(Token令牌自行设置后填写到后台) [图片] [图片] 2.视频号小店商品下单不进入商城,直接在微信下单,若要订单同步到商城,需要在开放平台绑定视频号小店 [图片]3.分享员设置 [图片] 1)分销商邀请页面:开启按钮,可以邀请用户成为分享员 2)邀请页面链接:复制链接到邀请页面,输入微信号(微信-我的-个人昵称下单的微信号,不一定是手机号),再点击加入分享员后显示二维码,识别二维码进行邀请,确认后则会提示已接收邀请 若分享员对应微信号未在商场注册会员,则会自动创建会员并赋予推广员权限 [图片][图片][图片][图片] 3)邀请限制-会员等级:勾选的会员等级才可以申请为视频号分享员,如未勾选的等级进行申请则会提示未满足需求 邀请限制-推广员:开启推广员,是推广员身份才可以申请为视频号分享员,如未勾选的等级进行申请则会提示未满足需求 [图片][图片] 4)邀请页面顶部图片:邀请页面上方显示的图片 [图片] 5)分享员说明: [图片] 二、微信地址管理[图片]三、微信物流管理[图片] 四、微信品牌管理[图片] 五、微信类目管理[图片]六、微信商品管理只有开启视频号小店的商品才会在此处显示商品挂件:行业类,视频号挂件,开启视频号小店,设置相关信息(视频号小店显示的商品详情在此挂件设置,不显示商品描述挂件的)[图片][图片] 3.只支持平台自营、供应链、供应商、聚合供应链的商品 4.在列表点击推送会将商品推送到视频号小店,需要微信那边审核,审核通过或驳回都会通过服务通知发送给视频号店长、管理员、店员 [图片] 5.商品到视频号小店,视频号小店需要支付保证金,保证金金额与选择的类目相关,可根据提示操作 视频号小店保证金条款 https://support.weixin.qq.com/cgi-bin/mmsupportacctnodeweb-bin/pages/XirwVKy6kfyQvG0E 当店铺中有多个商品类目时,类目保证金不会叠加计算,以金额更高者为准缴纳,具体金额见《视频号小店保证金-类目保证金额度》。 6.线上状态、草稿状态都是视频号小店那里商品的状态 7.草稿数据和线上数据也是显示视频号小店里的商品数据 8.点击同步是将视频号小店的商品数据同步到本地 9.上架/下架是修改线上的状态 10.只有修改库存和下架商品才会自动同步到视频号小店,修改其他内容都需要手动点击推送视频号小店处的商品才会同步更改,每次推送/上架都需要重新审核(编辑商品推送的审核会很快) 11.审核通过后重新编辑商品推送即使审核失败也不会更改线上商品的状态,只是不会将此次修改的内容推送到视频号小店 12.推送了的商品不管审核通过或失败都会在视频号小店后台显示,审核通过的商品显示在上架销售中那一栏 [图片] 13.若要将商品显示在视频号,还需要视频号的超级管理员在视频号助手https://channels.weixin.qq.com/platform/commodity/window或移动端的带货中心处将商品添加到橱窗 [图片][图片] 微信上搜索视频号可以看到橱窗管理在售的商品 [图片] 七、商品审核列表1,每次推送都会有记录 [图片] 2.点击查看详情可查看审核驳回原因 [图片] 八、订单同步列表[图片] 九、订单列表显示全部订单(待支付,待发货,已完成,退款中,已退款,已关闭) 订单可进行筛选,按照购买会员ID,名称,收件人手机,姓名等,支持导出订单 [图片] [图片] 若点击同步订单没更新订单状态的话,在订单列表点击发货推送即可。[图片] 注意:视频号小店不支持在商城里申请退款,因为微信没有提供我们这边主动发起退款的接口,所以没有申请售后的按钮,只能用户进入视频号订单里申请. [图片][图片] [图片] 十、商品变动列表显示商品变动ID,商品名称,变动类型,备注[图片]十一、分享员列表分享员绑定后会有一条信息记录,如绑定了没有显示可以点击更新分享员 [图片] 区别于传统分销的分享商品,利用视频号的优质内容代替,弱化传统的看得见的分销模式,将分享商品变为分享内容,结合小程序商城的分润模式,放大视频号的营销效果。
2023-10-08 - 公众号运营:如何文章内跳转公众号主页(不是历史文章页面)
近期社区中运营公众号的朋友咨询,如何文章内跳转到公众号主页 [图片] 不是历史文章页面 [图片] 这点是可以通过文章内的图片实现的。 接下来教大家如何实现图片跳转公众号主页: 1、首先获取历史文章链接 打开该公众号任意一篇内容,复制链接,在浏览器打开 [图片] 右击鼠标查看源代码 [图片] 快捷键ctrl+F开启全局搜索“ __biz”然后把该公众号卡版ID复制,记得后面两个“==”号必须都复制上。 [图片] 2、这个功能要通过SVG排版来实现。官方编辑器是不支持的,所以在这里我们使用某排版中的SVG编辑器。 [图片] 打开某排版SVG编辑器后,在组件这里搜索公众号或10214 [图片] 找到公众号——图片(免费的) 组件 [图片] 然后添加图片,粘贴公众号卡片ID [图片] 设置好后,先保存,后同步到微信后台 [图片] 这时候就可以去公众号预览了。 当然要注意的是,这种SVG排版同步到公众号后是不能修改的。所以建议在某排版编辑好所有内容之后,再同步到微信公众号后台。 而且这种排版可以跳转任何公众号主页。 还有一点这种跳转没有任何提示,直接跳到公众号主页,大家快去试试吧。 当然,还有朋友不知道如何跳转历史文章,可以参考:公众号运营:公众号菜单如何跳转历史文章? https://developers.weixin.qq.com/community/develop/article/doc/000e2e5dca09589f9f6fc985456013 我是立十,非官方人员💍公众号💍运营资深忠实粉丝,专注回答社区中关于公众号的问题。
2023-06-21 - 小程序支付用户不点击“完成”的处理方案
小程序支付,用户在付费成功后,没有点击“完成”,就没有支付成功回调触发,只能通过notify_url来接收异步回调通知,处理流程,当然这是正常的处理流程。 以下是另类的处理流程: 1、不处理notify_url; 2、在wx.requestPayment之前,将流程进度缓存,比如wx.setStorageSync('out_trade_no',out_trade_no); 3、那么,如果用户点击了“完成”或者取消支付,则必然会触发wx.requestPayment的回调success或者fail,则清除缓存,wx.removeStorageSync('out_trade_no'); 4、如果用户没有点击“完成”,则用户下次打开小程序,一定是冷启动即重启小程序,因为如果是热启动,将还是停留在支付界面,用户可以继续点击“完成”,继续业务流程; 5、因为是冷启动,所以在pages/index/index的onLoad里常驻一个进程,检查是否有支付未完成缓存,如果有,则按照out_trade_no查询订单支付状态,再继续支付流程。 以上只是另类做法,仅供参考。 虽然不符合支付的标准流程,但是可以不需要专门的进程来负责notify_url。
2021-03-22 - 视频号小店虚拟号内测
为保护用户个人隐私,平台默认为用户提供虚拟号服务,买家支付成功后的订单,商家后台默认是看不到买家的真实手机号码。平台自动生成了11位虚拟号+4位转接号。 [图片] 点击订单详情,商家每个月可以查看100个用户的真实手机号码,应该是为了纠纷率,方便商家联系用户使用 [图片] 虚拟号的优点是保护了用户隐私,缺点是用户收不到取件码短信。
2023-05-26 - 小程序购物订单躺过的坑记录
文档:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/shopping-order/shopping-order.html 一、上传购物详情 1.购物订单上传订单详情的接口商品列表少了item_detail_jump_link描述https://developers.weixin.qq.com/community/develop/doc/0002ae02bc8cc0f26afe8e1fa5b000 2.上传一个订单后就可以再后台使用“测试工具测试” 订单号+用户openid (这边使用微信侧支付单号+openid) 这里需要注意的是,提交审核后,系统会验证所有上传的单是否小于等于5秒,没有则审核不通过,但会进入自动审核过程 也就是他会在一个周期来来看你上传的数据,没有问题就可以自动审核过了,所以自己测试没有问题就提审就ok。 3.重复上传,会提示已经上传过。 二、上传物流信息 1.目前来看这个接口不是强制必须要对的,因为上面对成功就可以提审成功,但为了客户整个体验我们还是要对的。 2.请求参数中缺少payer的描述,建议加上 https://developers.weixin.qq.com/community/develop/doc/0000e0a0a48ae83f99fe9fd5051400 3.物流公司查下问题(如果没有仔细看到上面这一段,有可能不知道怎么去找,我就去找交易组件的去了) [图片] 4.统一发货的场景下,item_list的值只能传[] 长度为零的空数组,而不能是null,或者其他。 [图片] 5.顺丰快递记得天联系人信息; 6.重复提交是ok的。
2022-12-12 - 公众号运营:公众号菜单如何跳转历史文章?
1、首先获取历史文章链接 打开该公众号任意一篇内容,复制链接,在浏览器打开 [图片] 右击鼠标查看源代码 [图片] 快捷键ctrl+F开启全局搜索“ __biz” [图片] 将后面跟的参数(包括=号)替换下面的XXX即可获取历史消息链接 https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=XXX&scene=110#wechat_redirect 2、添加到自定义菜单 把历史文章 的链接粘贴进去,保存即可 [图片]
2023-03-11 - 按钮组件send-message-path未生效
- 当前 Bug 的表现(可附上截图) 进入客服按钮属性send-message-path未生效,属性值填写为“../test/test?source=kfxx0”或“pages/test/test?source=kfxx0”或不带参数均未生效,在客服会话窗口点击分享小程序后仍然回到按钮所在页面 [图片] - 预期表现 进入send-message-path属性值定义的页面test - 复现路径 - 提供一个最简复现 Demo
2019-02-12 - wx.openDocument打开文件后,有办法显示自定义文件名吗?
使用 wx.downloadFile + wx.openDocument 方法后可以打开pdf文件,但安卓显示乱码名,苹果显示文件预览很不好看,请问有什么办法可以显示自定义名吗
2023-03-09 - Skyline|小程序页面转场动画
开发者A:小程序跳转时,页面切换效果可以自定义实现吗? 开发者B:搞个单页自己写呢 开发者A:这个写起来代码量有点大,而且放单页里面代码太复杂了🥹 官方:来啦来啦~小程序页面转场动画可以使用小程序自定义路由来实现,赶紧往下 ⬇️ 看~ 我们先来看下有无自定义路由的效果对比 没有自定义路由:只能使用默认路由切换效果,从右到左推入页面使用自定义路由:支持自定义转场动画,示例下沉式路由效果[图片] 在使用默认路由的时候,只需要调用 wx.navigateTo 即可,而自定义路由,则需要先声明 1、通过 wx.router.addRouteBuilder( 命名,builder 函数 ) 来声明自定义路由 2、页面跳转新增 routeType 参数,值为上一步的命名 [图片] 接着,我们来看下声明自定义路由中 builder 函数,这个函数主要是定义两个动画 定义页面推入动画:结合 推入进度、推入状态 等参数,由开发者自定义计算得来定义页面被推出动画:结合 被推出进度、被推出状态 等参数,由开发者自定义计算得来[图片] 当打开一个新页面的过程中,就会触发自定义路由动画,此时有两个动画 新页面:打开动画旧页面:隐藏动画下图演示在页面 A 打开 页面 B,打开过程的动画效果: 新页面:页面 B 半屏打开旧页面:页面 A 页面下沉[图片] 动画除了上述讲的动画效果之外,还有一个关键的点就是动画曲线,动画曲线可以让动画效果更加丰富。 👇 下面我们可以看出来,相同的动画效果,但是使用不同的动画曲线,展示出来的页面切换效果是很不一样的。worklet 支持了常见的动画缓动函数 Easing,开发者可以根据业务需求实现页面动画切换效果。 [图片] 那么我们就来看一下页面切换动画的代码是怎么实现的~ 页面的切换动画通过 worklet 函数来实现的,worklet 函数运行在 UI 线程,使得小程序可以做到 类原生动画般的体验。 我们先来看下这里设计的新页面打开时的动画,在页面打开的过程中,开发者可以收到一个 primaryAnimation 的参数,这个参数表示当前页面从 0 到 1 打开的进度,此时,我们通过 handlePrimaryAnimation 来实现页面打开过程我们希望页面展示的动画效果,例如:改变页面高度、圆角、与顶部的偏移距离等。 这样,就实现页面展示的动画效果。 // 新页面:页面 B 半屏打开 const handlePrimaryAnimation = () => { 'worklet' // primaryAnimation 为 builder 函数的参数,表示当前页面从 0 - 1 展示动画的进度 // primaryAnimation 为 sharedValue 类型,当 primaryAnimation 变化时,这个函数就会被执行 let t = primaryAnimation.value // 非手势触发时,可以通过动画曲线 easeInToLinear 来改变动画的进度值 // worklet 支持了常见的动画缓动函数,开发者可以根据业务需求实现需要的页面切换动画效果 if (!userGestureInProgress.value) { t = wx.worklet.Easing.bezier(0.35, 0.91, 0.33, 0.97).factory()(t) } const top = 0.12 // 半屏页面距离顶部的距离比例 const selfHeight = (1 - top) * screenHeight // 半屏页面高度 const marginTop = top * screenHeight // 半屏页面距离顶部的距离 const translateY = selfHeight * (1 - t) // 页面动画过程中的纵向偏移值 // 返回 AnimatedStyle,改变页面展示 return { marginTop: `${marginTop}px`, borderRadius: '10px', height: `${selfHeight}px`, transform: `translateY(${translateY}px)`, } } 同样的,页面隐藏跟页面展示是类似的,开发收到的是 secondaryAnimation 参数,表示的是页面从 1 到 0 的关闭进度,这里我们通过 [代码]handleSecondaryAnimation 来实现页面隐藏的效果。[代码] 注意:handleSecondaryAnimation 表示下一页面推入时,当前页面的隐藏动画,在下沉式动画这个案例中,handleSecondaryAnimation 是旧页面的,而 handlePrimaryAnimation 是新页面的。 // 旧页面:页面 A 页面下沉 const handleSecondaryAnimation = () => { 'worklet' // secondaryAnimation 为 builder 函数的参数,表示下一个页面推入时,当前页面从 1 - 0 隐藏动画的进度 // secondaryAnimation 为 sharedValue 类型,当 secondaryAnimation 变化时,这个函数就会被执行 let t = secondaryAnimation.value // 非手势触发时,可以通过动画曲线 fastOutSlowIn 来改变动画的进度值 if (!userGestureInProgress.value) { t = wx.worklet.Easing.bezier(0.4, 0.0, 0.2, 1.0).factory()(t) } const top = 0.1 // 页面距离顶部的距离比例 const scaleRatio = 0.08 // 缩放比例 const translateY = screenHeight * (top - 0.5 * scaleRatio) * t // 页面动画过程中的纵向偏移值 const scale = 1 - scaleRatio * t // 缩放过程中的比例 const radius = 12 * t // 页面圆角 // 返回 AnimatedStyle,改变页面展示 return { borderRadius: `${radius}px`, transform: `translateY(${translateY}px) scale(${scale})`, } } 实现完动画切换的函数之后,我们需要包装到 builder 函数中并注册这个 builder 函数。 // 注册 builder 函数 wx.router.addRouteBuilder("HalfScreenDialog", HalfScreenDialogRouteBuilder) wx.router.addRouteBuilder("ScaleTransition", ScaleTransitionRouteBuilder) // 实现页面 B 的 builder 函数:页面打开时半屏打开 const HalfScreenDialogRouteBuilder = ({ primaryAnimation }) => { return { handlePrimaryAnimation // 页面 B 打开时的动画,上文中实现的 handlePrimaryAnimation 函数 } } // 实现页面 A 的 builder 函数:下一个页面打开时,当前页面下沉 const ScaleTransitionRouteBuilder = ({ primaryAnimation, secondaryAnimation }) => { return { handlePrimaryAnimation, // 页面 A 打开时的动画 handleSecondaryAnimation // 页面 B 隐藏时的动画,上文中实现的 handleSecondaryAnimation 函数 } } 在文章开头我们知道,声明完自定义路由之后,需要在页面跳转时指定路由类型。 到这里,通过页面跳转,返回按钮已经达到我们要的效果了。 // home.js // 首页打开页面 A, wx.navigateTo({ url: 'pageA', routeType: 'ScaleTransition', }) // page.js // 页面 A 打开页面 B wx.navigateTo({ url: 'pageB', routeType: 'HalfScreenDialog', }) 我们在体验原生页面切换时,手势也是顺滑切换的重要组成部分,在上一篇 小程序手势:让半屏弹窗更顺滑 我们已经了解手势的使用,那么我们这里给页面绑定手势,支持向右、向下拖动页面返回。 我们在页面最外层嵌套一个手势组件 horizontal-drag-gesture-handler(横向滑动时触发) 当手势向右滑动时,根据触摸位置改变页面当前的状态 触摸中:页面随手指拖动触摸结束:根据手势速度和位置判断关闭还是打开页面// .wxml // .js // 根据手势状态改变页面展示状态 // this.customRouteContext 中包含当前页面定义路由 builder 时的全部变量 handleHorizontalDrag(gestureEvent) { "worklet"; if (gestureEvent.state === GestureState.BEGIN) { // 触摸开始 const { startUserGesture } = this.customRouteContext; startUserGesture(); } else if (gestureEvent.state === GestureState.ACTIVE) { // 触摸中,实现跟随手指拖动页面效果 const delta = gestureEvent.deltaX / windowWidth; const { primaryAnimation } = this.customRouteContext; const newVal = primaryAnimation.value - delta; primaryAnimation.value = clamp(newVal, 0.0, 1.0); } else if (gestureEvent.state === GestureState.END) { // 触摸结束 const { stopUserGesture, didPop } = this.customRouteContext; ... didPop(); // 退出页面调用 stopUserGesture(); // 结束必须调用 } else if (gestureEvent.state === GestureState.CANCELLED) { // 触摸取消 } } 添加完手势之后,就可以通过手势关闭页面了~ [图片] 除了案例中实现的下沉式半屏效果,自定义路由可以根据开发者需要自行定制动画。 目前,官方提供了几个常用的路由效果供大家使用,mark 这个 代码片段 即可使用。
2023-08-03 - 长期订阅模板收集
修改日期:2023-05-05, 目前全部扑街… 状态说明:❌代表已失效,理由大多是[代码]由于该模板被滥用过多,已不能选用[代码] 不需要资质 标题 常见关键词 服务类目 状态 汽车票出票状态通知 出票状态、行程、出发时间、取票凭证、乘车建议 长途汽车 ❌ 巴士动态变更提醒 行程动态、行程、班次号、预计出发时间、乘车口、乘车说明 长途汽车 ❌ 车辆入场通知 车牌号、停车场、入场日期、入场时间、提示说明 停车服务 ❌ 车辆出场通知 车牌号、停车场、停车费用、提示说明、停车时间 停车服务 ❌ 停车费付款提醒 车牌号、停车场、停车时间、停车费用、提示说明 停车服务 ❌ 公交待付款提醒 待付金额、乘车线路、乘车时间、乘车说明 公交/地铁 ❌ 公交延时扣款通知 乘车线路、乘车时间、扣款时间、扣款金额、行程单号、提示说明 公交/地铁 ❌ 公交乘车通知 通知日期、乘车线路、乘车时间、行程单号、支付金额、乘车人 公交/地铁 ❌ 乘车退款通知 订单编号、乘车线路、乘车时间、退款金额、退款方式 公交/地铁 ❌ 地铁待付款提醒 待付金额、乘车线路、乘车时间、乘车说明 公交/地铁 ❌ 地铁延时扣款通知 乘车线路、乘车时间、扣款时间、扣款金额、行程单号、提示说明 公交/地铁 ❌ 乘车站点补登记提醒 乘车站点补登记、进站站点、出站站点、乘车时间、商户名称 公交/地铁 ❌ 地铁乘车通知 通知日期、乘车线路、乘车时间、行程单号、支付金额 公交/地铁 ❌ 选座登机牌办理提醒 客票号、航班、乘机人、提示说明、航程、座位号 航空 ❌ 机票出票状态通知 出发时间、航班、航程、客票号、出票状态 航空 ❌ 航班动态变更提醒 登机时间、温馨提示、变更动态、起飞时间、行程、预计起飞时间、航班号 航空 ❌ 选座办理成功提醒 航班、乘机人、提示说明、航程、座位号、客票号 航空 ❌ 座位变更提醒 航班信息、原座位号、新座位号 航空 ❌ 登机口变更提醒 航班信息、原登机口号、现登机口号 航空 ❌ 加油卡交易提醒 油卡号、加油站、交易时间、交易类型、交易费用 加油站服务 ❌ 高速扣费通知 通行时间、出入口站点、车牌号、扣费金额、扣款状态、解释权声明、入口时间、出口时间、入口站点、出口站点、备注说明、消费金额 高速服务 ❌ 高速延时扣款通知 通行时间、出入口站点、车牌号、扣费金额、交易单号、解释权声明 高速服务 ❌ ETC续卡提醒 续卡提示、设备编号、设备状态、操作指引 高速服务 ❌ 高速入站通知 入站提示、车牌号、入口站点、入站时间 高速服务 ❌ 高速出站通知 出站提示、车牌号、出口站点、出站时间 高速服务 ❌ ETC还款成功通知 车牌号、通行费、支付时间、支付方式、说明 高速服务 ❌ ETC退款通知 退款原因、车牌号、退款金额、支付时间、退款结果 高速服务 ❌ ETC欠费提醒 车牌号、欠费金额、补缴时限、欠费说明 高速服务 ❌ ETC服务状态提醒 车牌号、当前状态、起始时间、说明 高速服务 ❌ 高速通行通知 车牌号、入口站点、出口站点、出口时间、消费金额 高速服务 ❌ 船票出票状态通知 出票状态、航线名称、出发时间、取票凭证、乘车建议 水运 ❌ 船舶动态提醒 行程动态、延误原因、航线名称、班次号、预计出发时间、乘船口 水运 ❌ 火车票动态变更提醒 车次、行程、出发时间、到达时间、正晚点提醒 火车/高铁/动车 ❌ 火车票购票结果通知 购票结果、订单号码、车次及发到站、发车时间、车厢席位 火车/高铁/动车 ❌ 火车票退票结果通知 退票结果、订单号码、退票数量、乘客姓名、原购票出发时间、原购票座位号、原购票发到站、提示说明 火车/高铁/动车 ❌ 火车票改签结果通知 改签结果、订单号码、改签数量、乘客姓名、改签后座位号、行程信息、出发时间、提示说明 火车/高铁/动车 ❌ 火车票出票结果通知 出票结果、取票号码、保单号码、车次及发到站、发车时间、到达时间、乘客姓名、提示说明 火车/高铁/动车 ❌ 需要资质 这个我自己收集不了,希望有资质的行业开发者补充
2023-05-05 - 包含长期订阅消息模板的小程序类目
每个月修改的类目次数有限,统计起来,省得大家一个个试,浪费修改次数。 官方将长期订阅限定在了公共服务,“目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。” 需要资质 政务民生、医疗、金融全都需要资质; 交通服务需要资质的二级类目:航空业务,网约车,出租车,港口,顺丰车/拼车; 教育服务需要资质的二级类目:在线视频课程,学历教育(培训机构),驾校培训,学历教育(学校),教育平台,驾校平台; 不需要资质 免资质有模板的,都在交通服务里; 没有长期模板 教育服务 > 婴幼儿教育 教育服务 > 在线教育 教育服务 > 教育装备 教育服务 > 出国留学 教育服务 > 素质教育 教育服务 > 特殊人群教育; 交通服务 > 代驾服务 交通服务 > 租车 交通服务 > 骑车 交通服务 > 充电服务 交通服务 > 导航地图 有长期模板 交通服务 > 长途汽车 交通服务 > 公交/地铁 交通服务 > 停车服务 交通服务 > 加油站服务 交通服务 > 高速服务 交通服务 > 航空 // 航空业务和航空是不同的 交通服务 > 火车/高铁/动车 交通服务 > 水运 详细模板内容 单独整理到另一篇文章: 长期订阅模板收集
2022-11-02 - 微信支付 服务商代特约商户唤起小程序支付报错?
现特约商户绑定了小程序 A A和服务商又不是同一主体 代特约商户发起支付时 报appid与openid不匹配,
2023-02-18 - Skyline|小程序手势:让半屏弹窗更顺滑
在小程序页面开发中,我们经常用半屏弹窗来进来内容展示,例如:微信开放社区切换主页、加入购物车的选项页、文章留言区等等。 [图片] 常见的半屏弹窗展示逻辑是这样的: 打开弹窗:点击 “打开弹窗” 按钮展示弹窗关闭弹窗:点击“关闭按钮” or 遮罩层 关闭弹窗当我们想在半屏弹窗加一些交互动画时,可以监听节点的 touch 事件来做一些手势判断,进而处理拖拽事件。但是这种方式实现的滚动动画容易卡顿,出现延迟的情况,效果并不理想。 为了丰富小程序的交互体验,我们内置了一批手势组件,可以帮助开发者更好的实现交互动画的效果。 下图演示使用手势的半屏弹窗下拉效果与普通半屏下拉的对比。 当内部评论列表往下拉到顶部时,变为半屏的下拉,可直接下拉关闭弹窗。 [图片] 我们来看下这种操作是怎么实现的 在上面评论列表的半屏弹窗中会有一个 scroll-view 滚动组件,在 scroll-view 中会有滚动事件,当滚动到顶部时,我们希望有整个半屏的下拉事件。 所以我们需要在半屏的最外层放置一个拖动手势组件 pan-gesture-handler 由于拖动组件内部的 scroll-view 也是可以滚动的,所以这里需要进行一个手势协商的处理,就是什么条件下由哪个组件来响应手势。 当手势往下 ⬇️ 滚动时,此时判断内部 scroll-view 滚动条的位置 滚动条处于顶部:外层 pan-gesture-handler 响应滚动,此时半屏往下拖动至关闭半屏滚动条不处于顶部:内层 scroll-view 响应滚动,此时内部列表往上滚[图片] 当手势往上 ⬆️ 滚动时,此时判断半屏的位置 半屏不完全打开时:外层 pan-gesture-handler 响应滚动,此时半屏往上拖动至完全打开半屏半屏完全打开时:内层 scroll-view 响应滚动,此时内部列表往下滚[图片] 我们来看一下代码的实现,这里用到的手势组件 pan-gesture-handler(拖动时触发)和 vertical-drag-gesture-handler(纵向滑动时触发),手势组件有以下属性 on-gesture-event:手势回调事件should-response-on-move:是否响应当前手势的 move 阶段simultaneous-handlers:指定需要协商的手势是哪几个,下面演示表示 pan 和 scroll 协同触发。native-view:代理的原生节点,这里 scroll-view(scroll-y) 内有个 vertical-drag 手势,scroll-view 自身无法处理,需要被代理出来 ... 接着,我们看看在页面 js 中怎么处理手势。 在手势处理的回调中因为会改变半屏的状态值,所以这里的回调函数采用 worklet 函数,worklet 函数运行在 UI 线程,使得小程序可以做到类原生动画般的体验。 // page.js // shared 创建的变量为共享变量,可在 UI 线程和 JS 线程间同步 this.transY = wx.worklet.shared(1000) this.scrollTop = wx.worklet.shared(0) this.startPan = wx.worklet.shared(true) // shouldPanResponse 和 shouldScrollViewResponse 用于 pan 手势和 scroll-view 滚动手势的协商 shouldPanResponse() { 'worklet' return this.startPan.value }, shouldScrollViewResponse(pointerEvent) { 'worklet' // transY > 0 说明 pan 手势在移动半屏,此时 scroll-view 滚动不应生效 if (this.transY.value > 0) return false const scrollTop = this.scrollTop.value const { deltaY } = pointerEvent // deltaY > 0 是往上滚动,scrollTop <= 0 是滚动到顶部边界,此时 pan 开始生效,scroll-view 滚动不生效 const result = scrollTop <= 0 && deltaY > 0 this.startPan.value = result return !result }, // pan 手势处理 handlePan(gestureEvent) { 'worklet' if (gestureEvent.state === GestureState.ACTIVE) { const curPosition = this.transY.value const destination = Math.max(0, curPosition + gestureEvent.deltaY) // 改变半屏的位置 this.transY.value = destination } // 其他手势状态的处理,如滚动结束时计算半屏处于打开还是关闭的状态 } 目前,同程旅行 已经上线了手势结合半屏的效果 体验路径:酒店查询 - 选择酒店 - 选择入住人 - 新增入住人 [图片] 普通半屏结合手势代码片段:https://developers.weixin.qq.com/s/lx0RH1mD7rGj 手势除了在普通半屏的应用之外,也可以实现分段式半屏。下面演示的分段式半屏比普通半屏的判断条件更多一些。 判断条件同普通半屏类似,根据手势方向 和 分段式半屏当前的位置来判断是响应分段式半屏还是内部列表,响应分段式半屏是改变到哪一个位置。 [图片] 这里与普通半屏不同的是我们还改变了地图的缩放级别(scale) 因为 worklet 函数是在 UI 线程运行的,当要改变 data 值时,需要通过 wx.worklet.runOnJS 调回 JS 线程。 // page.js // 设置 map scale // 运行在 JS 线程 setMapScale(scale) { this.setData({ scale }) }, // worklet 函数,运行在 UI 线程 scrollTo(toValue) { 'worklet' let scale = 18 if (toValue > screenHeight / 2) { scale = 16 } // 从 UI 线程调回 JS 线程 wx.worklet.runOnJS(this.setMapScale.bind(this))(scale) this.transY.value = timing(toValue, { duration: 200 }) }, // 处理拖动半屏的手势 handlePan(gestureEvent) { 'worklet' // 滚动半屏的位置 if (gestureEvent.state === GestureState.ACTIVE) { // deltaY < 0,往上滑动 this.upward.value = gestureEvent.deltaY < 0 // 当前半屏位置 const curPosition = this.transY.value // 只能在 [statusBarHeight, screenHeight] 之间移动 const destination = clamp(curPosition + gestureEvent.deltaY, statusBarHeight, screenHeight) if (curPosition === destination) return // 改变 transY,来改变半屏的位置 this.transY.value = destination } if (gestureEvent.state === GestureState.END || gestureEvent.state === GestureState.CANCELLED) { if (this.transY.value <= screenHeight / 2) { // 在上面的位置 if (this.upward.value) { this.scrollTo(statusBarHeight) } else { this.scrollTo(screenHeight / 2) } } else if (this.transY.value > screenHeight / 2 && this.transY.value <= this.initTransY.value) { // 在中间位置的时候 if (this.upward.value) { this.scrollTo(screenHeight / 2) } else { this.scrollTo(this.initTransY.value) } } else { // 在最下面的位置 this.scrollTo(this.initTransY.value) } } }, 分段式页面代码片段:https://developers.weixin.qq.com/s/fw0U31mI7bGf 半屏的交互除了在页面内实现,也能跨页面实现,如常见的下沉式半屏交互。其中,半屏效果与上述实现类似,而前一页面的下沉实现需要结合自定义路由 后面的文章中我们会介绍自定义路由结合手势怎么去实现下沉式半屏效果,不仅如此,还有很多类原生的页面切换效果都能通过自定义路由实现 [图片]
2023-08-03 - 「微信开发平台Donut」入门指南|安全网关篇
一、 背景叙述 从公众号开始,小程序、移动应用、网站应用,到现在的视频号小店,微信提供很多种应用形态,让企业和个人开发者可以用适合的形式接入微信生态,满足自己的业务需求。 另外微信还提供第三方平台,为各行业的解决方案服务商提供了一个窗口,能够服务更多商家或中小企业个体接入微信生态,提升客户体验。 但无论是小程序、公众号还是第三方平台,依然只是在C端提供服务。无论是服务商还是企业个人开发者,想要通过上述形态接入微信生态,仍然离不开云端服务。 微信团队提供很优秀的开发和调试工具,单独做一个不联网的小程序,实现一些简单的功能,简单入门上手开发并不是很难。但如果是联网提供完整的带服务的小程序,对很多开发者来说就比较难了;更难的是另一个问:如何做一个稳定的、安全的后端服务? 2018年,微信联合腾讯云推出云开发,主要解决的是小程序后端服务的高门槛问题。但提供的云函数对传统开发模式的改造成本太大,灵活度不是很高。于是在2020年推出微信云托管,提供通用的容器服务,将服务构建环节交给开发者。 无论是云开发和云托管,最关键的并不是提供一个后端服务,而是提供后端服务的安全访问。所以可以看到,无论是云开发还是云托管,在微信应用(小程序、公众号服务)中提供的callFunction、callContainer方法,相比request方法本质上是提供了一个安全的访问入口。 云开发、云托管在一定程度上承担了运维和部署环节,使得其非常容易入门,对新手开发者很友好。但并不是所有开发者都是新手,很多成熟的开发者都有自己的一套成熟后端服务。如果为了接入微信的安全访问,而直接迁移自己的服务到云开发或云托管,阻力是相当大的。 另外云开发、云托管提供的是可独立存在的后端云服务,有独立的数据存储,使得其在调用方上挣脱不开同主体的限制,这也是服务商开发者使用起来最为难受的点。 所以有没有一种方案,让开发者既可以使用自己熟悉的后端服务基座,又可以非常灵活方便的接入微信的安全访问? 这就是新推出的Donut安全网关! 二、 什么是安全网关,有什么特色? Donut安全网关提供了一个安全的接入链路,从调用端(小程序、公众号H5、APP、WEB)发起的请求直接进入微信环境接入层,微信接入层通过中转域名将请求转发至后端服务网络的「网关实例」中,在「网关实例」中通过路由配置将请求转发到开发者自己的上游业务服务,完成整个请求。 [图片] 以上是整个链路的全景图,其中「网关实例」指的是部署在服务器或者是容器服务中的一套envoy网关(经过微信信息处理,有专属的证书加密)。 相比于云开发或云托管的访问链路,安全网关的链路是完全独立的,相对来说也更加成熟和安全。并且由于只做请求转发,不受同主体可用的限制。也就是说任何一个小程序或者公众号H5或其他形态应用,都可以使用安全网关链路实现请求。 当然,微信在链路中也提供了来源客户端的appid等标识,开发者可以在控制台或自己的后端服务针对的限制,防止其他未授权的客户端调用。 但是需要注意,安全网关并不是替代云开发或者云托管,安全网关可以与现在的云托管做深度融合,使得最终形态一定是对各类开发者均友好的。在云端服务领域还有很长的路程需要探索和精进! 三、 开始配置安全网关 1. 登录注册Donut平台 访问Donut控制台,使用微信扫码登录。 [图片] 扫码完成后页面会自动跳转,进入控制台。首先先点击右上角头像,在列表中点击实名认证。 [图片] 填入自己的姓名和身份证号码后,会弹出如下二维码,使用微信客户端扫码验证。 [图片] 验证完成后会自动提示如下,此时就完成了实名认证流程。 [图片] 2. 开通安全网关 在控制台页面点击安全网关的「立即开通」按钮 [图片] 阅读服务协议并同意,开通完成! [图片] 页面会自动刷新,点击上方菜单栏「安全网关」,显示下述页面,开通流程完成。 [图片] 3. 新建网关 在安全网关页面点击「新建网关」按钮,在弹出的对话框中填写网关名称,完成新建。一般网关以使用角度的应用维度区分,一般只需要一个即可,可以再创建一个用于规则测试。 [图片] 在这里我填写的是app,大家可以按自己想法来填。 4. 安装网关实例 网关实例是一个经过处理过的envoy网关,主要作用就是接收微信侧发过来的请求,并按照自己设置做路由分发等流量管理。所以网关实例运行的服务器或者容器服务,应该具备以下几个条件: 有公网接入:可以是带公网IP的服务器,也可以是任何一个公网访问的容器服务[比如TKE、云托管等],如果服务器没有公网IP,可以在服务器的VPC网络中配置NAT网关,转发端口流量。尽量靠近业务后端服务:网关实例最重要的作用就是路由分发,分发的上游服务可以用内网IP访问,也可以用私有域名访问;不推荐使用公网再发出去,会增加请求耗时。所以尽量与业务后端服务处于同一个私有网络,如果跨地域了,可以考虑对等连接,或者在不同地域配置多个网关实例(用域名解析来实现就近接入)尽量避免与高峰值服务混在一起:虽然envoy本身对资源的消耗很小,但仍然需要注意不要与其他重资源消耗并可能引发宕机的服务部署在一起,否则将会导致网关实例不可用,从而影响请求顺利的转发。一般根据自身的情况,有很多种方案可以选择。选择好实例所在位置后,根据环境不同,参照控制台给出的详细步骤,安装实例。目前有如下几种: Docker:如果你的服务器安装有Docker,这是最方便的。将镜像直接下载下来运行即可。[图片] Linux:适用于大多数情况。有很多系统版本,注意自己的系统版本不要出错。安装过程基本就是开管理员权限进入终端,然后安装curl、wget、jq(基本都有,如果没有就搜索一下linux怎么安装XXX),剩下的就是直接复制一把运行,如果有出错,可以先搜索引擎一下解决,实在不知道怎么解决,可以评论下来看看[图片] K8s:如果你的服务有运行于K8s运管的容器平台,可以用这个方法快速新建网关实例。最省心的方法![图片] 在这里我使用一个服务器来执行安装过程,配置截图如下: [图片] 启动后进入root账号,执行命令如下:(最后一个是启动网关实例,可以使用nohup不挂断运行) [图片] 网关实例安装完毕后,控制台中点击「完成」按钮,进入下一步,可以在实例列表中看到已经安装在线的实例。 [图片] 注意:1. 在线情况下不可以从列表删除,需要先将网关下线,才可以从列表删除。2. 默认的对外端口为9903,但根据自己配置也会有所不同,注意打印的port内容。 5. 发布网关配置 网关配置主要分为两部分:上游服务、路由配置。我们来分别配置。 5.1 上游服务 上游服务就是请求最终到达的地方,一般可以称为业务服务地址。可以是域名,也可以是IP地址。 [图片] 在配置页点击「新建上游服务」按钮,弹出对话框,我们来填写一下。 [图片] 上游服务名称:路由配置时用它来区分,一般言简意赅的单词即可,比如login_server。备注:有时候英文不太容易记起具体是个什么,这里可以用中文长句描述一下给自己看。协议:有HTTP和HTTPS,一般内网就HTTP,节省耗时,外网或者有安全需要的HTTPS类型:分域名和IP,根据自己的情况来选择,一般选择IP。域名:内网可以用私有DNS解析来配置域名,公网可以正常填写。IP:类型为IP时可见,IP可以填写公网IP;同属一个私有网络可以填写内部IP;如果跟网关实例同属于一个服务器,则可以填127.0.0.1。在这里测试为了能让大家都能测试顺利并没有差异,直接填写一个mp官网的域名,后续可以根据自己的情况自己来变更。 注意:只在本测试中使用mp.weixin.qq.com,请不要在生产环境中尝试调用或恶意攻击操作。 [图片] 5.2 路由配置 配置完上游服务后,会提示配置路由,点击即可跳转至路由配置页面的对话框 [图片] 路由名称:清楚表示这个路由的作用即可,一般言简意赅的英文单词组合。上游服务:拉取当前配置的服务列表,以上游服务名称为索引。服务路径:就是访问时的路径,比如https://xx.com/api,想要匹配这个规则,路径就填写/api,如果没有路径就填 /路径改写-可选:目前只支持静态改写,就是将匹配的服务路径改写为指定的路径,再传递给上游服务。比如上面说的 /api 进来,可以改写成 /interface 传递给上游。请求限频-可选:配置这条路由的QPS值,流量防治的一种策略,默认是1000,范围是1-10000准入域名-可选:发过来的请求会匹配请求头中的host值;如果配置则只接受此host发来的请求,一般在接入层有多个时但需要区分流量时使用。在这里我们来配置一个测试用的路径,后面我们再配置更多来测试一下路由的能力。 [图片] 5.3 发布配置 在控制台中反复配置的路由和上游服务,并不会影响实际线上的网关实例。我们在配置完成后,需要点击控制台的「发布配置」按钮,将配置上传至网关实例。此时网关实例才能够应用我们的最新配置。 · [图片] 线上有了配置之后,我们就可以在右侧点击「线上网关配置」查看线上生效的配置情况 [图片] [图片] 6. 配置接入层 接入层是在微信侧的概念。网关接入层承接并转发业务流量,具备分布式安全防护能力,支持就近接入弱网加速,同时集成微信安全风控能力。 通俗来讲,就是客户端在访问网关时,需要有一个地址,而这个地址就是接入层的一个节点。微信对每一个接入节点创建了一个专门的地址,用来接收客户端流量。 接入节点一般以客户端应用区分(比如A应用APP、B小程序,C网页WEB),或者应用矩阵区分(A应用多端APP、小程序、WEB),这样可以随时阻断或者转移流量。另外可以通过路由配置的准入域名,来实现不同应用的差异化转发;服务商第三方平台也可以利用此特性,来实现普通客户的应用承载,以及VIP客户的应用承载分流。 只有一个接入节点的域名地址也没有用,还需要我们配置一下进入到这里的请求流量转发到哪里。 在控制台中,点击「接入层」的「新建接入节点」按钮。 [图片] 节点名称:一般以应用命名,言简意赅的英文单词组合即可。备注:可以详细描述一下服务的应用是哪些,给自己备注一下。访问方式:公网访问、小程序访问,可以根据自己的接入需要来选择,这会控制你的客户端请求的访问许可。APPID:当选择「小程序访问」时会出现,需要将允许访问的小程序appid填入,多个需要用,(英文逗号)隔开。服务接入节点类型:域名、IP或云托管,就是网关实例应该以什么形式发现。如果就一个实例,则直接IP,域名一般用于IP容易变化的服务器或者容器服务,另外在多地域就近配置时使用也很不错,需要搭配DNS高级解析能力;云托管需要在空间管理TAB中绑定云托管所属账号,这个另外开一篇指引。域名:填写域名,可以在公网指向网关实例所在的服务器,端口填写网关实例对外暴露的服务端口。IP:填写公网IP,能够指向网关实例所在的服务器,端口填写网关实例对外暴露的服务端口。云托管:选择云托管环境-服务作为服务接入节点。 注意:1. 多个接入层可以使用同一个网关实例,没有什么限制。一个接入层用多个实例,需要用域名来实现。2. 需要注意配置安全规则,保证网关实例对外暴露的端口能够被公网访问。不要使用七层负载均衡来转发端口,可以使用NAT网关转发。 在这里配置的如下,IP自己注意替换一下 [图片] 如果顺利完成不弹窗报错,则一切顺利,控制台可以看到节点。如果提示报错连接失败等,首先看下端口IP安全规则是否放开,注意是TCP协议。 [图片] 7. 简单访问 上面步骤的接入域名为:https://a04fa8d0a-wx79c3e1e62f1acac0.preview.wxcloudrun.com 格式大概如下:https://${接入节点ID}-${Donut平台Appid}.preview.wxcloudrun.com 下面所有访问都请替换成自己的接入域名 我们在浏览器中访问域名时,效果应该如下: [图片] 当我们访问下面地址(替换自己的前缀),效果为: https://xxx-wxxxx.preview.wxcloudrun.com/cgi-bin/scanloginqrcode?action=ask [图片] 也就是说,我们之前配置的路由,访问路径只是前缀匹配。 接下来我们新增一个配置,如下所示。记得「发布配置」线上生效。 [图片] 当我们访问下面地址(替换自己的前缀) https://xxx-wxxxx.preview.wxcloudrun.com/test?action=ask 会是404的提示。 接下来我们将一开始的index路由删掉,只保留api路由。 [图片] 再次访问时会发现,页面为正常的返回了。 [图片] 当我们再次将index路由配置回来,如下时: [图片] 一切都是可以的! 以上是一个路由优先级的实验,当流量转发过来时,会根据配置规则列表依次匹配,当匹配存在时立刻转发,匹配不存在时再向后匹配,直到匹配到或者匹配完为止。因此如果是/根路径,一般放置在路径最后,否则将直接从/转发走。 另外还有准入域名的实验,如果感兴趣我后面再补充。原理先在这里写一下: 准入域名一般填写的是接入域名或者是自定义域名,支持*通配符;当一个路由规则配置了准入域名A,则A的流量只会匹配这一个规则,其他未填写准入域名,或者准入域名不是一个优先级的路由规则根本不匹配。准入域名可以写如下格式: 准确域名,例:www.wx.com后缀通配符,例:*.wx.com,*-wx.com前缀通配符,例:wx.*,wx-**不匹配空,比如*wx.com 将匹配 mpwx.com 而不匹配 wx.com当一个域名打到了多个路由的准入域名,则优先级按最长的来。比如www.wx.qq.com 匹配 *.wx.qq.com ,而不是 *.wx.com 四、 在客户端中使用安全网关 目前可以在微信小程序中使用安全网关,使用步骤如下: 1. 准备环境 公测阶段,小程序调用安全网关需要开白名单,可以在申请页面填写问卷提交信息,通过后重新进入小程序,能够在基础库的列表最后,看到 develop 基础库,环境准备就完成了。 [图片] 2. 获取接入节点ID 在安全网关控制台,转到「接入层」页面,将接入节点的默认域名取出,截取ID部分,如下图所示: [图片] 上图中,接入节点的ID为:a04fa8d0a-wx79c3e1e62f1acac0 这个ID需要替换成自己,每个人都不一样。 3. 配置请求域名 当前,网关的请求需要在mp后台配置request域名,直接将节点域名的完整地址填入就可以,协议为https,如下: [图片] [图片] 团队正在优化这个点,后面就不需要这个合法域名的配置了! 4. 编写请求代码 在这里我已经写了一个代码片段,可以直接导入到IDE 小程序端调用代码片段:https://developers.weixin.qq.com/s/D5lCBnmD77Ey 导入时需要注意使用第一步申请公测时填写的APPID,不要填写其他或者接口测试号,将不会显示 develop 基础库。 [图片] 导入后,右上角点击「详情」按钮,在本地设置中,基础库选择develop [图片] 然后打开 app.js 文件,按下图所示,替换自己在第2步的接入节点ID [图片] 保存文件后,触发重新编译,在调试器console中可以看到网关请求打印的返回数据: [图片] 请求实际上有两个步骤,第一是网关的初始化,第二是call请求,在这里我对call请求做了简单的封装,并挂载在app下,大家也可以根据自己的需要封装。 [图片] 请求的触发在 pages/index/index.js 中,代码片段中初始的是前面步骤简单访问时的页面 https://xxx-wxxxx.preview.wxcloudrun.com/test?action=ask [图片] 当method为GET时,data的数据将拼接成url参数,除了path之外,其他的大部分参数都遵循wx.request。所以可以参考这里。 当将上面的data参数去掉后,由于接口的特点会直接返回页面html内容而不是JSON字符串,所以会出现下述报错。 [图片] 这是因为请求时传入datatype为json,会自动尝试对请求返回结果做json解析,如果不是json字符串,就会引起解析报错。可以直接将datatype改为text,如下图: [图片] 5. 上传体验版 公测期间,IDE内调试开发使用的是 develop 基础库,但是线上不会存在这种基础库,因此网关的调用代码需要跟随你的应用代码包一起上传。 在app.json中加入如下配置: { "cloud": true, "cloudVersion": "alpha" } [图片] 这样在你上传体验版时,网关的相关代码就随着你的代码一起打包上传了。 如果后面有一些新的特性,需要重新执行上传的步骤,其中的cloudVersion指的就是网关代码的版本,和你引入模块的版本管理形式相同,自己把握就行。 6. 降级重试 推荐大家有条件做一下降级策略,防止网关实例出现异常,或者接入层的规则出现问题,影响线上的用户调用。 先使用网关调用,网关调用失败时,使用wx.request再来一次。 异常情况下,返回的内容中有errCode,所以可以根据此来设置降级策略。 { "data": {}, "statusCode": 404, // http状态码 "errMsg": "gateway.call:ok", // 请求正常则始终为 gateway.call:ok "errCode": -651000, // 正常时无此属性。异常时会返回负值,代表云开发网关侧异常 "header": { "date": "Wed, 19 May 2021 02:37:59 GMT", "server": "envoy", "content-length": "0" }, "callID": "1665645158626-tsmg9Dpy" } 上面代码片段里,在封装的方法中有预留降级的插入为止,大家根据自己的业务做一下改造就可以。 五、 其他补充 1、 网关实例9903是正式给微信接入层做请求转发用的,端口有证书校验,不需要担心这里的攻击问题。由于默认证书可能在多处用,你可以在控制台中生成一个专属的证书,直接在对应路径替换文件,然后重启一下实例。 [图片] 2、 网关实例还有一个9902端口,是用来做路由测试的,你可以直接拼IP地址+9902端口,按照路由规则的路径测试,这个是不带证书校验的纯本地测试,也可以用于内网的流量转发,安全性不是很好,内网注意安全规则设置。 3、 网关实例还有一个19000端口,这个是管理控制台,所有人只要能访问到,就能把网关实例给停止了,还能读取你的所有配置,比较高危险了,不要裸露在外网,调试也尽量配置安全规则只允许你自己的IP访问。 [图片] 4、网关实例已经启动了,但是没在控制台的列表里显示?先看下secret有没有填写正确,重新init一下;其次再看一下网络安全规则是否放通,在实例所在服务端ping一下xds.preview.wxcloudrun.com,或者telnet一下其80端口,如果不通需要放通。 5、当配置多个网络实例时,个别实例配置不更新还是旧的?重新启动一下实例基本能解决问题,或者19000控制台进入,看一下clusters和config_dump的信息是否和配置的描述相符,不相符控制台quitquitquit,然后重新运行启动命令。 6、当确认操作步骤正确,但是效果不符合预期时,可以将启动后的log日志完整截取复制,反馈到社区相关板块。docker启动执行 docker logs envoy;linux启动,将stdout或者nohup.out的内容截取复制。 7、如果代码片段打开切换develop基础库时,长时间不启动进入页面,调试器也没有输出,请耐心等待develop基础库下载完成,会有loading的动画加载。如果等待3min仍然不变化,重新启动IDE可解决。
2022-12-21