结果分享闭环 — 设计规格(2026-09-17)
1. 为什么做
2026-09-16 查清 zh/dass-21 的流量来源:30 天约 300 个访客里只有约 20 个带 referrer,其余全是无来源直接访问;国家 CN 297,手机 238(Android 148 > iOS 105),tool_calculate 242 人 ≈ 80% 完赛。放大到整个 CN:1,198 个去重访客中仅 127 个带来源(约 89% 直接访问,全站约一半),落地页高度集中在简中心理测评簇。weixin110.qq.com 的 2 个访客是唯一物证。
判读:微信/QQ 打开外链会剥掉 referrer,所以站内最大的一条自然分享渠道在所有统计里都表现为「直接访问」。
同期另一个样本:澳门有人用 me-qr.com 生成指向 zh-TW/tools/dass-21 的二维码做线下分发,50 个访客86% 完赛(全站平均 44%)。
两件事指向同一个结论:分享已经在自发发生,转化质量远高于搜索流量,但我们既没有为它做任何设计,也测不到它。
2. 目标
- 让用户能把「我的结果」分享出去(现在只能保存图片)。
- 让收到图片的人能回到站点 —— 封闭 App 内图片不可点,二维码是唯一通路。
- 让分享与回流可测量 —— 现在分享率为 0 可见度,扫码进来的人混在 89% 的直接访问里。
3. 现状(已有骨架,不是从零建)
components/tools/common/AssessmentResult.vue(280 行)已被 20 个工具使用,内部渲染ResultShareCard.vue(457 行):分数、分档、解读、维度条、建议、日期、底部moodji.net水印。- 「保存图片」按钮 →
utils/captureNode.ts的saveOrShareNode(),移动端自动调起系统分享面板,返回'shared' | 'downloaded'。 utils/captureNode.ts基于html-to-image;AboutCard.vue已有ClipboardItem复制图片的实现可复用。qrcode@^1.5.4与qr-code-styling@^1.9.2已在package.json。- PK 链接(
useChallengeLink+challenge_share/arrival/complete)只覆盖 stroop / schulte / trail-making 三个客观测评。
缺口
| # | 缺口 | 后果 |
|---|---|---|
| 1 | 卡片底部只有文字水印,无二维码 | 微信里图片不可点,回流断裂 |
| 2 | 保存/分享无任何埋点 | 分享率不可见,做完无法验收 |
| 3 | 扫码进来的人无标记 | 混进 89% 的直接访问,无法归因 |
| 4 | 按钮文案是「保存图片」 | 定位成存档而非分享 |
| 5 | 无「复制图片」 | 桌面端微信/QQ 粘贴场景缺失 |
4. 范围
做:
ResultShareCard.vue底部加二维码AssessmentResult.vue按钮文案与「复制图片」- 两个新埋点事件 + 落地页参数识别
- 5 语言文案
不做(本期):
- 未接入
AssessmentResult的 15+ 个计算器类工具 - 分享图的视觉重做(版式沿用现有卡片)
- 分数进链接的任何形式(见红线)
- 百分位/常模数据(无可引用来源前不写,见 §5.2)
5. 设计
5.1 二维码
- 位置:
ResultShareCard.vue:159那行底部水印的右侧,尺寸 不小于 72 CSS px。左侧文案由result_share_qr_hint提供(如「扫码测你的」)。 - 生成:组件内用
qrcode生成 dataURL,而非外链<img src>——html-to-image遇跨域外链图会静默丢失。 - 样式:朴素黑白方码,纠错级别 M。不用
qr-code-styling的花式码 —— 微信长按识别对花式码兼容差。 - 页面上与导出图中都显示,所见即所得。
5.2 二维码编码的 URL
https://www.moodji.net/<locale 前缀>/tools/<slug>/?s=qr- 基础 URL 走
utils/seo.ts的getCanonicalUrl(),避免手拼语言前缀出错。 - 只带
s=qr,不得带任何分数、等级、日期或用户输入参数。
🔴 隐私红线(与
useChallengeLink现有规则一致):分数可以出现在图片里(用户主动导出、自己决定发给谁),绝不能进 URL(链接会被转发、缓存、进浏览器历史与服务端日志)。本期不为心理测评引入任何形式的带分数链接。
5.3 埋点
沿用 utils/events.ts 的 safeTrack(埋点失败静默吞掉,绝不影响工具本身)。
| 事件 | 触发时机 | 参数 |
|---|---|---|
result_share | 分享/保存/复制成功完成后 | slug、locale、method: shared | downloaded | copied |
share_arrival | 落地页 URL 含 ?s=qr | slug、locale;同一 path 每次会话只报一次(照抄 reportToolCalculate 的去重写法) |
method直接取saveOrShareNode()的返回值;复制图片路径传copied。- 导出失败(捕获抛错)不上报。
- ⚠️ 已知口径偏差:用户在系统分享面板点「取消」时浏览器抛
AbortError,现有saveOrShareNode将其当作shared返回。本期不改这个行为(改了要区分「取消」与「发送成功」,而 Web Share API 本身不告诉我们用户最终发给了谁,做不到准确)。→method='shared'的口径是「调起了分享面板」,不是「确实发出去了」,读数时按上限理解;share_arrival才是真实回流的硬指标。 - 完赛仍用既有
tool_calculate,用于计算扫码进来的人的完成率。
5.4 按钮与文案
| 位置 | 现在 | 改为 |
|---|---|---|
| 主按钮 | result_save_image(保存图片) | result_share_image(分享结果) |
| 新增 | — | result_copy_image(复制图片),失败回退下载 |
| 卡片内 | — | result_share_qr_hint(扫码文案) |
新增 key 需补齐 en / zh / zh-TW / ja / ko 五份 i18n/lang/*.json。
result_save_image 目前只被 AssessmentResult.vue:119 引用,替换后应从五份 i18n/lang/*.json 中删除(实现时先 grep 复核无其他引用)。
5.5 接入范围
改的是共用组件,二维码与分享按钮会同时出现在全部 20 个接入 AssessmentResult 的工具上,不只是心理测评簇。
这是有意为之:埋点带 slug,按工具、按簇的归因照样做得出来,不需要额外的白名单开关。心理测评簇(dass-21 / depression / anxiety / stress / wellbeing)仍是重点观察对象。
⚠️ 影响面同时是风险面:任何版式或导出回归会一次性影响 20 个工具,验证必须覆盖(见 §6)。
6. 验证
必须实际导出图片肉眼检查,不能只看组件渲染。 html-to-image 对 canvas/dataURL 的处理是本期最大不确定性。
| 项 | 方法 | 通过标准 |
|---|---|---|
| 二维码进了图 | 导出 PNG 后打开看 | 二维码完整、清晰 |
| 二维码可扫 | 手机扫导出的图 | 落地到正确的工具页且带 ?s=qr |
| 微信长按识别 | 真机在微信里长按 | 能识别(花式码风险即在此) |
| 窄屏版式 | 375px 宽下查看 | 卡片不溢出、二维码不被裁切 |
| 五语言 | 逐个 locale 导出 | 无 i18n key 泄漏、文案不溢出 |
| 未回归 | 抽查非心理类(如 BMI、FFMI) | 卡片与导出正常 |
| 埋点 | 本地 dev 下 safeTrack 不发,需在预览环境验证 | 三种 method 各触发一次 |
7. 验收与可证伪预测
首轮无历史基线,result_share 本身即建立基线(分享人数 ÷ 完赛人数,按工具拆)。
预测(验收日 2026-10-01):上线后 30 天内
share_arrival≥ 30。 若为 0:说明「在分享图里嵌二维码能把人带回来」这个前提不成立 —— 此时应推翻整套方案重想回流路径,而不是继续优化文案或版式。
8. 风险
| 风险 | 缓解 |
|---|---|
html-to-image 不渲染二维码 | 用 dataURL 而非外链;导出后肉眼验证 |
| 二维码太小/太密扫不出 | ≥72px、纠错 M、导出 pixelRatio 2 |
| 微信不识别花式码 | 强制朴素黑白方码 |
| 卡片变高影响 20 个工具版式 | 窄屏 + 非心理类抽查 |
| 分数意外进入 URL | 代码评审专门检查;URL 只允许 s=qr 一个参数 |
| 埋点在 dev 被静默 | 在预览环境验证,不靠本地 |