LikeShop 小程序分享卡片二开:自定义商品卡片与带参溯源统计

本文详解LikeShop小程序分享功能的二次开发,聚焦自定义商品分享卡片(动态title/imageUrl/path)与带参溯源机制(path直传与scene短码映射),强调归因与分销绑定解耦、防刷策略及分层统计(进入UV、注册转化、首单GMV)。方案兼容原生逻辑,通过后台配置表与幂等落库实现可运营、可归因、可防刷的分享裂变体系。

一、原生分享的边界:一个“默认截图 + 裸链接”

LikeShop 小程序端确实支持分享,但原生的分享行为停留在“系统默认”层面。用户在商品详情页点击右上角转发,onShareAppMessage 返回的是微信默认的分享卡片:图片是当前页面的实时截图,标题是小程序名称或页面默认标题,path 不带任何用户维度参数。分销员分享出去的商品链接,和普通用户分享出去的链接在数据上没有任何区别——谁分享的、从哪个渠道来的、带来了多少新用户,系统完全不感知。

原生系统的分销绑定依赖的是注册或首次下单时的邀请关系写入,而不是分享链路的参数携带。如果分销员只是分享了一个商品卡片,好友点进来浏览但最终没有注册或下单,这次分销行为就彻底“蒸发”了,既不计入分享次数,也无法归因到具体分销员。分享是分销裂变的起点,但原生在这个起点上缺少两样东西:可定制的卡片内容和可溯源的携带参数。

二开的核心策略是:不修改 LikeShop 原生的分销关系绑定逻辑,在分享卡片组装层做动态定制,在 path / scene 中注入分销员标识和渠道参数,接收方进入页面时解析并落库,形成“分享——进入——绑定——转化”的可统计链路。

二、分享卡片的自定义:动态组装,而非静态配置

2.1 onShareAppMessage 的三个可控字段

微信小程序的分享卡片通过 onShareAppMessage 返回的对象控制三个核心字段:title(转发标题)、path(转发路径,必须 / 开头)、imageUrl(自定义图片,5:4比例,支持 PNG/JPG)。原生 LikeShop 通常只返回了 path 的默认值,title 和 imageUrl 没有按商品动态填充。

自定义分享卡片的正确做法不是“后台给每个商品手工配一张图、一段文案”,而是在页面层根据商品数据动态组装。商品名称、卖点、价格、分销员信息都可以在 onShareAppMessage 触发时实时拼装:

javascript

onShareAppMessage(res) {
  const inviter = getApp().globalData.user?.distributorId || '';
  const goods = this.data.goods;

  return {
    title: `${goods.name} ¥${goods.price} 起`,
    path: `/pages/goods_details/index?id=${goods.id}&inviter=${inviter}&ch=share`,
    imageUrl: goods.share_cover || goods.image, // 优先用运营配置的分享图
  };
}

imageUrl 的降级策略:商品主图不一定适合做分享卡片(比例、留白、文字可读性都可能不达标),后台应支持为商品单独上传“分享封面图”。没有单独配置时,降级到商品主图;主图页没有时,才走微信默认截图。默认截图的问题是不可控——截图时机、页面滚动位置不同,卡片效果差异很大。

2.2 分享卡片配置表

“可定制”意味着运营能在后台控制分享的标题模版和封面图,而不是让开发写死在代码里:

sql

CREATE TABLE `ls_share_card_config` (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `scope_type` tinyint NOT NULL DEFAULT 1 COMMENT '范围:1-全局默认,2-指定商品,3-指定分类',
  `scope_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '商品ID/分类ID,全局默认为0',
  `title_template` varchar(200) NOT NULL DEFAULT '' COMMENT '标题模板,支持{goods_name}/{price}占位符',
  `cover_image` varchar(500) NOT NULL DEFAULT '' COMMENT '分享封面图',
  `subtitle` varchar(100) NOT NULL DEFAULT '' COMMENT '卡片副标题(部分场景透出)',
  `is_enable` tinyint NOT NULL DEFAULT 1,
  `create_time` int UNSIGNED NOT NULL DEFAULT 0,
  `update_time` int UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  KEY `idx_scope` (`scope_type`, `scope_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分享卡片配置表';

匹配优先级为:指定商品 > 指定分类 > 全局默认。标题模板中的 {goods_name} 和 {price} 在分享时替换为实时数据,避免“同一个商品在不同促销期标题完全一样”的僵化感。

三、带参溯源:path 直传 VS scene 短码

带参溯源有两种路径,适用场景不同,不能混为一谈。

3.1 path 直传:轻量、适合会话分享

在 onShareAppMessage 的 path 中直接拼接 inviter(分销员ID)、ch(渠道标识)、goods_id 等参数,接收方面 onLoad(options) 从 options 中解析。这是最直接的方式,腾讯云开发的官方方案也是这个思路:path 中塞入 inviter,接收方 onLoad 解析后落库到 share_events,用 inviter + invitee 复合唯一约束防重。

javascript

// 接收方页面
async onLoad(options) {
  const inviter = options.inviter;
  const channel = options.ch || 'share';
  if (!inviter || inviter === myUserId) return;

  // 落库分享进入事件,复合唯一约束防重
  await db.collection('share_enter_log').add({
    inviter_id: inviter,
    invitee_id: myUserId,
    goods_id: options.id,
    channel: channel,
    enter_time: db.serverDate(),
  });
}

path 直传的限制是参数长度没有官方硬上限,但过长的 path 会影响分享卡片的生成和解析稳定性。适合参数少、结构简单的会话分享场景。

3.2 scene 短码映射:适合海报、二维码等线下/跨端场景

当分享不是通过小程序卡片,而是通过小程序码海报、线下物料、公众号文章进入时,入口参数是 scene。getwxacodeunlimit 生成的 scene 参数最大长度 32 个可见字符,且只支持特定字符集,不能直接塞入 inviter=12345&ch=poster&goods=678 这样的长串。

正确的做法是短码映射:服务端生成一个6-8位的随机短码,将真正的归因信息(分销员ID、渠道类型、落地页、业务ID)存入 qrcode_scene 表,scene 中只放这个短码。用户扫码进入后,onLoad(options.scene) 拿到短码,回传服务端反查完整业务参数。

短码不能用自增 ID 转 62 进制生成。自增 ID 可预测,黑产可以遍历短码爬取所有分销员的推广码,甚至伪造扫码关系。必须用密码学随机源生成,配合唯一键冲突重试。

3.3 两条路径的统一归因

无论从 path 直传还是 scene 短码进入,最终都汇入同一张进入事件表,归因字段统一:

sql

CREATE TABLE `ls_share_attribution` (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `inviter_user_id` int UNSIGNED NOT NULL COMMENT '分享者/分销员ID',
  `invitee_user_id` int UNSIGNED NOT NULL COMMENT '进入者ID,0为未登录',
  `goods_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '商品ID',
  `channel` varchar(20) NOT NULL DEFAULT 'share' COMMENT '渠道:share/poster/scene/qrcode',
  `source_type` tinyint NOT NULL DEFAULT 1 COMMENT '来源:1-path直传,2-scene短码',
  `enter_time` int UNSIGNED NOT NULL DEFAULT 0,
  `bind_status` tinyint NOT NULL DEFAULT 0 COMMENT '绑定状态:0-未绑定,1-已绑定',
  `create_time` int UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_invitee_goods` (`invitee_user_id`, `goods_id`),
  KEY `idx_inviter` (`inviter_user_id`),
  KEY `idx_enter_time` (`enter_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分享进入归因记录表';

uk_invitee_goods 唯一约束保证同一用户对同一商品只记录一次进入归因,防止用户反复刷新页面产生重复统计。归因记录只在首次进入时写入,后续的注册和下单动作通过 invitee_user_id 关键回溯,而不是每次下单都重新解析分享参数。

四、绑定与防刷:分享归因和分销关系解耦

4.1 进入归因 ≠ 绑定上下级

一个常见的错误设计是:用户通过分享链接进入,立刻把分享者写成该用户的上级。这会导致任何一个点击了分享链接的人都被强行绑定,包括分销员自己切换小号测试、用户误点、机器人爬取等场景。LikeShop 原生的分销绑定时机是“注册或首次下单”,二开应保持这个边界不变——分享进入只记录归因,不立即建立上下级关系;归因记录在用户后续注册或首单时被消费,作为分销关系绑定的参考依据。

4.2 归因消费的时机

归因消费发生在两个节点:

注册时:如果用户是通过带参分享进入后完成注册,且该用户此前没有上级,则将 inviter_user_id 作为其上级写入。如果用户已有上级(例如之前通过其他分销员注册),分享归因只统计“分享带来的进入”,不改变已有的绑定关系。

首单时:如果用户在注册时没有消费归因(比如先注册、后从分享链接进入并下单),首单支付成功时可以作为兜底绑定时机。但必须校验该订单的商品是否与归因记录中的 goods_id 一致,避免“分享A商品、下单B商品也绑定”的错配。 4.3 自分享与循环归因的排除 归因落库前必须排除两种无效场景:分享者和进入者是同一用户(inviter === invitee),以及进入者已经在归因表中存在同一商品的记录(唯一约束兜底)。这两条规则在腾讯云开发方案中也是明确列出的。

五、分享效果统计:从“进入”到“转化”

统计口径需要分层,而不是一个笼统的“分享次数”:

分享行为层:分销员触发 onShareAppMessage 的次数(前端埋点上报)、分享卡片的曝光和点击率(微信侧有限,主要通过进入归因反推)。

进入归因层:通过 ls_share_attribution 统计每个分销员带来的进入 UV、各渠道(share / poster / scene)的占比、商品维度的进入排行。

转化层:归因进入的用户中,注册转化率、首单转化率、首单 GMV。转化层的数据通过 invitee_user_id 关联订单表计算,统计的是“由该分销员分享链接首次带入的用户”的后续行为,而不是该分销员所有下级的整体 GMV——两者口径不同,不能混用。

ql

-- 分销员分享效果汇总示例
SELECT
  a.inviter_user_id,
  COUNT(DISTINCT a.invitee_user_id) AS enter_uv,
  COUNT(DISTINCT CASE WHEN u.id IS NOT NULL THEN a.invitee_user_id END) AS register_uv,
  COUNT(DISTINCT o.user_id) AS order_uv,
  COALESCE(SUM(o.order_amount), 0) AS gmv
FROM ls_share_attribution a
LEFT JOIN ls_user u ON u.id = a.invitee_user_id
LEFT JOIN ls_order o ON o.user_id = a.invitee_user_id AND o.pay_status = 1
WHERE a.inviter_user_id = ?
GROUP BY a.inviter_user_id;

统计结果在后台“分销 → 分享效果”中按分销员和商品维度展示,支持按时间范围筛选。

六、后台配置与开发注意事项

6.1 后台配置清单

配置项类型说明
分享卡片总开关开关关闭后回退到原生默认分享
全局标题模板文本支持 {goods_name} {price} 占位符
全局分享封面图片兜底封面,商品未配置时使用
商品分享封面图片(按商品)优先级高于全局封面
归因参数开关开关path 是否携带 inviter 参数
归因有效窗口数字(天)分享进入后N天内注册/首单可归因,默认7天
自分享排除开关默认开启,分享者=进入者时不落归因
短码有效期数字(天)scene 短码的有效期,0为永久

6.2 开发注意事项

分享卡片的 imageUrl 必须控制尺寸和格式。微信要求5:4比例,支持 PNG/JPG,过大的图片会导致卡片加载缓慢甚至分享失败。商品分享封面在上传时应做裁剪和压缩,而不是把原图直接塞进 imageUrl。

path 参数的编码不能遗漏。inviter 和 ch 的值如果包含特殊字符,在 path 中必须做 URL 编码,否则参数解析会截断或错位。接收方 onLoad 解析 options 时,微信已经做了一次解码,不需要重复解码 path 中的 query 参数,但 scene 参数需要显式 decodeURIComponent 后再使用。

归因落库的幂等靠复合唯一约束,不靠“先查后插”。用户可能反复从同一个分享链接进入,先查后插在并发下仍然可能产生重复记录。uk_invitee_goods 唯一约束是最终防线,插入冲突时直接忽略并返回成功,而不是报错阻断页面加载。

分享归因不改变原生分销的结算链路。归因记录只用于统计和绑定时参考,分销佣金的计算仍然走 LikeShop 原生的佣金公式和结算条件,不因为“分享带来”就额外计算奖励。两者是解耦的:归因管“谁带来了谁”,佣金管“谁买了谁拿钱”。

兼容性。新增的分享卡片配置表和归因记录表独立于 ls_user 和 ls_order。原生 onShareAppMessage 的默认行为在配置关闭时完全保留。归因参数的注入通过页面层的分享方法扩展实现,不修改 LikeShop 核心的 OrderLogic 和分销绑定逻辑。短码映射表仅在 scene 入口场景启用,不干扰 path 直传的会话分享链路。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值