- 加固插件已激活,加固前,加固配置内没有合法的js文件
最近,微信开发工具的代码加固秃然用不了了。每次预览时都会提示 加固插件已激活,加固前,加固配置内没有合法的js文件,请检查路径 [图片] 尝试了把加固插件卸载重装、开发工具升级最新版、基础库切换到最新版本依然无法解决问题。社区中也有人6月份反馈类似问题:https://developers.weixin.qq.com/community/develop/doc/0000cc339300d0c325ef9570b56c00 配置其实都是正确的,这个提示真是让人一头雾水。 没办法啊,只能自己继续摸索 尝试把开发工具的授权全部清除,这样在预览时加固插件会先请求授权,但是授权的弹窗提示让我觉得有些奇怪: [图片] null extension description。。。这是插件没有安装成功吗? 然后在工具的输出栏可以看到加固插件(appid是wxext871b2e053677418)运行日志,无意间发现插件的安装目录其实是在C:\Users\Yunfay\AppData\Local\微信开发者工具\User Data\,这个目录因为之前因为占用空间太大,已经达到了15G,C盘告警,所以我有更换过储存目录,然后用mklink建了一个软链,这个方法很早前官方人员也有在社区中提及过,这个是帖子链接 https://developers.weixin.qq.com/community/develop/doc/000e8eed8a4448555dc9c877f5b400 最后把软链删除,并将之前移走的文件挪回原来目录,代码加固插件也就恢复正常了。。。 现在只能把开发工具卸载重装,不然C盘的占用空间有些夸张。 不清楚加固插件里面的处理逻辑或者说是mklink有什么副作用(欢迎知道原理的大佬评论指点一下),这里简单把这个问题记录一下,希望那些还在被这个问题困扰的小伙伴也能有所启发。 [图片]
2023-09-17 - 记录云开发lookup多表嵌套查询优化
最近在优化一个云开发用lookup实现的多表嵌套查询SQL,发现测试环境最大的表数据量还不到2W,但是整体查询耗时竟然要2,3s,这让我觉得有些意外,能加的索引也都加了,有点头大。。。 主要是以下几个表: user-card-list(清单表,大概1.9W条)user-comment(评论表,大概500条)user-info(用户信息表,大概9000条)black-list(黑名单表,12条)具体的业务是分页查询出清单,并关联出发布清单的用户信息、清单评论信息、评论者的用户信息,同时过滤掉黑名单用户。在测试SQL的过程中发现在pipeline中用到的父表字段其实不会使用索引,如果是用localField/foreignField关联表时索引可以生效,但是遗憾的是这种方式不可用嵌套查询... 写惯了关系型数据库SQL,通常是会把分页以及过滤条件写在SQL最后的位置。但是在非关系型数据库,如果尽量把过滤条件或者分页的SQL前置,可能会有意想不到的效果。 下面的这个SQL我把match跟limit前置后查询速度从2,3s降到了3,400ms,有点苦笑不得[捂脸]。。 在这里蛮记录一下。或许对看到的小伙伴可以有一点点小启发。 db.collection('user-card-list').aggregate() .lookup({ from: 'black-list', let: { openid: '$openid'//将变量openid的值等于user-card-list表的openid,在pipeline可以使用,let需要和pipeline一起使用 }, pipeline: $.pipeline() .match(_.expr($.and([ $.eq(['$openid', '$$openid']), ]))) .done(), as: 'blackList', }) .addFields({ inBlackList: $.gt([$.size('$blackList'), 0]), //排序字段,由公开时间+ID组成 cursor: $.concat(['$lightAt', '', '$_id']), }) .match(_.expr($.and( $.eq(['$light', 'Y']), //$.gt(['$cursor', '2023-05-20 23:58:23ozzW05Gch7jMMhsn1r_SWLGdGtF0_add_1563634289607']) $.or([ //当前清单的发布用户不在黑名单中,直接展示 $.eq(['$inBlackList', false]), //当前清单的发布用户在黑名单中,且是本人浏览时,直接展示 $.and([ $.eq(['$inBlackList', true]), $.eq(['$openid', 'ozzW05Gch7jMMhsn1r_SWLGdGtF0']), ]) ]) ))) //按cursor降序排序 .sort({cursor: -1}) //分页前置,提升查询速度 .limit(30) .lookup({ from: 'user-comment', let: { id: '$_id'//将变量id的值等于user-card-list表的_id,在pipeline可以使用,let需要和pipeline一起使用 }, pipeline: $.pipeline() .match(_.expr($.eq(['$belongTo', '$$id']))) //按createAt降序 .sort({createAt: -1}) .lookup({ from: 'user-info', let: { replyOpenid: '$replyOpenid'//将变量replyOpenid的值等于user-comment表的replyOpenid,在pipeline可以使用,let需要和pipeline一起使用 }, pipeline: $.pipeline() .match(_.expr($.eq(['$openid', '$$replyOpenid']))) .done(), as: 'replyUserInfoList', }) .done(), as: 'userCommentList', }) .project({ momentContent: 1, author: 1, cursor: 1, lightAt: 1, comments: $.reverseArray('$commentsReverse'), userCommentList: 1, likes: 1, wishes: 1, time: '$lightAt', }) .end();
2023-05-26 - 省钱有道之 减少云函数调用次数
由于云函数有一项计费规则是按调用次数计费,在小程序访问量比较小的情况下还比较无所谓,但当体量上来之后不得不考虑控制一下对公共接口的调用次数从而减少一些不必要的开销。比如获取用户信息接口、获取配置信息接口 这里分享一个我自己几个小程序用到的方法,公共接口的调用都放在app.js,然后提供函数供其他页面调用。同时由于异步问题,有可能页面加载完接口还未返回,因此还需能够注册回调函数,在接口返回数据后回调给调用页面 代码示例: app.js App({ onLaunch: async function (options) { //判断是否需要更新小程序 updateCheck.check(); await api.wxCloudInit(); //获取用户信息 this._getUserInfo().catch(res => { console.warn("获取用户信息失败,准备重试"); this._getUserInfo().then(); }); }, /** * 获取用户信息 * @param callback * @param refresh 等于true时表示重新查询用户信息,同时也会更新会员状态 */ getUserInfo: function (callback, refresh) { if (!refresh) { const userInfo = this.globalData.userInfo; if (!userInfo.ready) { if (typeof callback == 'function') { this.callbackFunctions.userInfoReadyCallback.push(callback); } if (!this.userInfoReadyCallback) { this.userInfoReadyCallback = res => { console.log("获取用户信息完毕,开始回调", res); const callbacks = this.callbackFunctions.userInfoReadyCallback; while (callbacks.length) { const callback = callbacks.pop(); typeof callback == 'function' && callback(res); } /*callbacks.forEach(callback => { typeof callback == 'function' && callback(res); })*/ } console.log("注册userInfoReadyCallback成功"); } else { console.log("已经注册了userInfoReadyCallback,不再重复注册"); } } else { typeof callback == 'function' && callback(userInfo); } } else { console.log("准备更新用户信息") this._getUserInfo().then(userInfo => { typeof callback == 'function' && callback(userInfo); }); } }, /** * 执行云函数,获取用户信息 * @returns {Promise<unknown>} * @private */ _getUserInfo: function () { return new Promise((resolve, reject) => { api.callCloudUserCenterFunction("UserInfoHandler/getUserInfo", {}, res => { console.log("获取用户数据完毕:", res.result); const result = res.result; if (result.success) { const data = result.data; this.globalData.userInfo = data; // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(data); } resolve(data); } else { console.error("没有获取到用户信息"); reject("没有获取到用户信息"); } }, e => { console.error("获取用户信息失败", e); reject("获取用户信息失败"); }); }); }, /** * 异步事件回调函数列表 * 增加这个列表是为了避免不同地方同时调用,互相覆盖回调函数 */ callbackFunctions: { //用户信息异步回调 userInfoReadyCallback: [], }, globalData: { userInfo: { confirm: false//用来标记用户信息查询动作是否已经结束,等于true时,userInfo才可信 }, } }) 某page.js app.getUserInfo(res => { const isVip = res.isVip; if (isVip) { console.log("已开通会员", res); } });
02-07