问问今天(AI复盘助手)复盘 — 2026-05-04
本次:分享卡片添加小程序码 + 修复保存权限问题
📋 本次完成
| 事项 | 状态 | 说明 | |------|------|------| | 分享卡片添加小程序码 | ✅ | 白色卡片内右下角,100px | | 保存图片权限修复 | ✅ | app.json + 后台隐私保护指引 | | 小程序码生成 | ✅ | 页面路径 pages/index/index | | 代码提交审核 | ✅ | 待审核通过 |
🔍 深度复盘:分享卡片添加小程序码踩坑记录
坑1:离屏 canvas 加载本地图片失败
场景:share-card 组件用 createOffscreenCanvas 画的分享图,canvas.createImage() 加载 /images/qrcode.png 始终不触发 onload。
根因:离屏 canvas 不在页面 DOM 中,本地图片路径解析行为与页面 canvas 不同。
教训:
- 离屏 canvas 的图片加载能力有限,本地资源可能加载不到
- 如果用
createOffscreenCanvas,最好用toDataURL直接嵌入 base64 数据 - 或者改用页面上的 canvas 元素(
createSelectorQuery获取)
坑2:ctx.canvas.createImage 报错 not a function
场景:在 result.js 里用页面 canvas 绘制分享图,调用 ctx.canvas.createImage() 报 TypeError: createImage is not a function。
根因:createImage 是 canvas 节点的方法,不是 context 的方法。要通过 canvas 对象(res[0].node)调用,不是 ctx.canvas。
正确写法:
// ❌ ctx.canvas.createImage() — 报错
// ✅ canvas.createImage() — canvas 是 res[0].node
const canvas = res[0].node;
const qrImg = canvas.createImage();
教训:Canvas 2D 的 API 挂在 canvas 节点上,不在 ctx 上。这个很容易搞混。
坑3:异步加载导致导出卡死
场景:小程序码异步加载,canvasToImage 用轮询等待 _qrReady,结果一直卡在 loading。
根因:
- 如果图片加载失败(路径不对、格式问题等),
_qrReady永远不会被设为 true toDataURL在某些情况下也可能卡住- 没有超时机制
教训:
- 异步加载图片必须有超时兜底
- 不要用轮询等待,用
setTimeout延迟导出更简单可靠 - 加载失败不应阻塞整个流程,没码也能出图
坑4:createImage 的 src 赋值时机
场景:先赋值 qrImg.src,再注册 qrImg.onload,导致图片在监听器绑定前就加载完了,onload 不触发。
根因:如果图片已被缓存(之前加载过),src 赋值瞬间就完成加载,此时 onload 还没注册。
正确顺序:
const img = canvas.createImage();
img.onload = () => { /* 画图 */ };
img.onerror = () => { /* 处理失败 */ };
img.src = '/images/qrcode.png'; // 最后赋值
坑5:保存图片权限(跟 SBTI 一样的问题)
跟 SBTI 复盘的 errno: 1025 问题完全一致:
app.json需要permission声明- 微信后台需要配置用户隐私保护指引
requiredPrivateInfos不支持相册权限(只支持地理位置)
💡 最佳实践总结
Canvas 2D 加载图片的标准写法
// 1. 从页面 canvas 节点创建图片
const canvas = res[0].node; // createSelectorQuery 获取
const img = canvas.createImage(); // 不是 ctx.canvas.createImage()
// 2. 先注册回调,再赋值 src
img.onload = () => {
ctx.drawImage(img, x, y, w, h);
};
img.onerror = () => {
console.log('图片加载失败');
};
img.src = '/images/xxx.png';
// 3. 导出时给异步操作留缓冲时间
setTimeout(() => {
wx.canvasToTempFilePath({ canvas, success, fail });
}, 800);
保存图片功能检查清单(与 SBTI 复盘一致)
- [ ]
app.json的permission声明scope.writePhotosAlbum - [ ] 微信后台 → 设置 → 功能设置 → 用户隐私保护指引 → 声明相册(仅写入)
- [ ] 隐私协议页面包含相册权限说明
- [ ] 提交审核时勾选「采集用户隐私」
- [ ] 体验版真机测试保存功能
🔍 深度复盘:2026-05-07 补充踩坑
坑6:页面未实现 onShareAppMessage 导致分享按钮灰色
场景:问问今天上线后,用户反馈右上角菜单的「转发」按钮是灰的,无法点击分享。
根因:页面 JS 中没有定义 onShareAppMessage() 方法。微信的规则是——如果页面没实现这个方法,右上角转发入口会被禁用。
影响:index、history、review、privacy、terms 5个页面全部缺失,严重影响社交传播。SBTI 之前也踩过同样的坑。
修复:给所有页面补上 onShareAppMessage,统一返回分享标题和路径。
教训:每个页面都必须实现 onShareAppMessage,开发新小程序时页面模板里就要默认带上。
// 标准写法,每个页面都加
onShareAppMessage() {
return {
title: '小程序名称 - 分享标题',
path: '/pages/index/index',
imageUrl: '' // 可选
};
}
坑7:提示文案与实际存储策略不符
场景:历史页面底部显示「数据仅保存在本地,清除缓存会丢失」,但实际数据同时存到了云端。
根因:开发时沿用了纯本地存储的文案模板,没有更新为云开发版本。
修复:直接去掉底部提示文案(用户不想看到涉及云端存储的说明)。
教训:提示文案要跟实际存储策略一致。更好的做法是——不涉及数据存储的说明,避免用户产生隐私顾虑。
坑8:批量修改代码后未验证语法,导致全站白屏
场景:批量给 5 个页面添加 onShareAppMessage 方法时,用 Python 脚本拼接字符串插入代码,但漏了逗号(} 后面直接接 onShareAppMessage),导致 5 个页面 JS 语法报错,首页完全无法加载。
根因:脚本拼接时只关注了「代码内容是否正确」,忽略了 JS 对象属性之间必须用逗号分隔的语法规则。
修复:给所有页面的 onShareAppMessage 前面补上逗号。
教训:批量修改代码后必须验证语法。至少要做两件事:
- 用
node -c file.js或类似工具检查语法 - 在开发者工具里实际编译运行一遍
复盘人:喵喵 | 关键词:onShareAppMessage、分享按钮灰色、提示文案、云存储、语法错误、批量修改、白屏