- 编辑器商品导入(两种落地方式,用户已确认「两者都要」)
海淘万代日版金猫 龙珠 一番赏 D赏 假面巴达克¥270.00立即领券
- 在富文本编辑器工具栏新增「拼多多商品」入口,弹窗支持粘贴商品 ID / 商品链接 / goods_sign,一键解析并插入可视化商品卡片(主图、标题、价格、推广链接)到文章正文。
- 现有「关联商品(文中好物)」面板新增 ID / 链接解析导入入口,解析后加入文章挂载商品列表。
- 列表页升级
- 资讯列表直观展示已关联拼多多商品状态:价格变动(绑定价 vs 当前价涨/降/持平)、上下架状态(来自 ddk_goods.is_hidden)。
- 支持按关联商品类目、营销活动(如百亿补贴,来源于 ddk_goods.activity_tags)筛选与聚合。
- 数据分析强化(收益口径用户已确认「真实订单归因」)
- 新增点击与转化追踪字段:详情页点击商品卡片异步上报,累加 ddk_article_goods.clicks。
- 通过推广链接 custom_parameters 嵌入 {"aid":文章ID,"gid":商品ID},订单同步时解析并归因佣金到对应文章商品,累加 revenue / conv。
- 资讯列表直接展示关联商品点击率(clicks / 文章 views)与预估收益,支持按收益排序;custom_parameters 未备案时回退启发式预估(clicks × 假定转化率 × 单品佣金)。
技术栈选型
- 后端:PHP(原生,沿用项目现有 Controller/Service/Database/Cache 分层),MySQL(InnoDB,复用 ddk_* 表)。
- 前端:服务端渲染(PHP + Bootstrap 类 + 自定义 qie-* 样式),编辑器与列表交互沿用原生 JS(fetch + FormData),不引入新框架。
- 拼多多接入:复用 PddApi(签名/限流/熔断/重试)与 GoodsService(归一化/落库/推广链接)。
- 校验:PHP 改动执行
php -l;前端 JS 沿用现有渐进增强模式。
实现方案
总体策略
围绕「解析→关联→渲染→追踪→归因」闭环实施:在编辑器解析商品并写入 ddk_article_goods;列表聚合状态与收益;前台详情页承载点击追踪与归因推广链接;订单同步负责真实收益归因。全程向后兼容旧文章(无关联商品时列表正常渲染),custom_parameters 未备案时降级为启发式预估。
关键技术决策
- 内联卡片存储方式:在富文本中插入带
data-gid/data-sign/data-aid的卡片 HTML 片段,正文保存时经 Xss 白名单过滤。需扩展app/Core/Xss.php的 ALLOWED_ATTRS,放行这三个 inert 的 data 属性(不会执行脚本,安全),否则卡片属性会被剥离。推广链接不在编辑期写死,改为详情页渲染时由promotionUrlForArticle实时解析,避免链接过期。 - 链接/ID 解析:新增
PddApi::parseGoodsInput($input),兼容纯数字 goods_id、goods_sign 字符串、含goods_id=/goods_sign=的商品链接(mobile.yangkeduo.com等),输出{goods_id, goods_sign}。 - 真实订单归因:
GoodsService::promotionUrlForArticle在系统已备案 custom_parameters 基础上合并{"aid":文章ID,"gid":商品ID};OrderService落库custom_parameters并在同步时解析 aid/gid,将有效订单佣金累加到ddk_article_goods.revenue、conv。归因采用「按 (aid,gid) 重算」而非增量加减,避免订单状态回退导致账目漂移。 - 点击追踪与 CTR:详情页卡片点击先
navigator.sendBeacon上报?c=home&a=goodsClick(累加 clicks,含基础 IP 频控),再跳转归因推广链接。CTR = 文章 clicks 聚合 / ddk_articles.views。 - 列表聚合与排序:在
ContentController::index的 SELECT 中增加SUM(clicks)/SUM(revenue)/SUM(conv)相关子查询(每文章 1 行,LIMIT 100,开销可接受);收益排序ORDER BY revenue DESC;类目/活动筛选经 INNER JOIN ddk_article_goods→ddk_goods 实现(activity_tags用 LIKE 匹配,管理端低频可接受)。
性能与可靠性
index()仍为单页 ≤100 行,相关子查询与聚合成本低;activity_tags为低频后台筛选,无需索引。goodsResolve复用goodsDetail1 小时缓存;promotionUrlForArticle复用 promotionUrl 的 1 小时缓存(按 aid+gid 维度)。- 点击端点无鉴权但仅做计数,加 Cache 简单频控防刷;失败不影响跳转。
- 归因回退:若解析不到 aid/gid 或 custom_parameters 为空,revenue 保持启发式值,不影响现有推广链路。
实现注意事项
- Xss 白名单:仅在白名单追加
data-gid/data-sign/data-aid,不得放宽href/src危险协议校验(沿用 javascript:/data: 拦截)。 - 向后兼容:
syncArticleGoods写入bind_price(关联时取 ddk_goods 当前价快照);旧文章无关联时列表子查询返回 0/空,UI 跳过状态列。 - 日志:解析失败、归因解析异常复用
Logger::warning,不记录商品/用户隐私明文;避免高频日志。 - 落库安全:所有写操作走现有 RBAC + CSRF(goodsResolve 用 content.view,goodsClick 为公开只读计数)。