Authored by 陈轩

新品到着 埋点

@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 {{!--浏览过的品牌--}} 2 {{!--浏览过的品牌--}}
3 {{#if browseBrands}} 3 {{#if browseBrands}}
4 {{> new/recommend-brands 4 {{> new/recommend-brands
  5 + id="browse-brands"
5 title="浏览过的品牌" 6 title="浏览过的品牌"
6 shops=browseBrands 7 shops=browseBrands
7 }} 8 }}
@@ -9,12 +10,14 @@ @@ -9,12 +10,14 @@
9 10
10 {{!--热门品牌--}} 11 {{!--热门品牌--}}
11 {{> new/recommend-brands 12 {{> new/recommend-brands
  13 + id="hot-brands"
12 title="热门品牌" 14 title="热门品牌"
13 shops=hotBrands 15 shops=hotBrands
14 }} 16 }}
15 17
16 {{!--新入驻品牌--}} 18 {{!--新入驻品牌--}}
17 {{> new/recommend-brands 19 {{> new/recommend-brands
  20 + id="new-brands"
18 title="新入驻品牌" 21 title="新入驻品牌"
19 style="new-brands" 22 style="new-brands"
20 shops=newBrands 23 shops=newBrands
@@ -96,8 +96,8 @@ @@ -96,8 +96,8 @@
96 <script src="//cdn.yoho.cn/m-yohobuy-node/{{version}}/libs.js"></script> 96 <script src="//cdn.yoho.cn/m-yohobuy-node/{{version}}/libs.js"></script>
97 <script src="//cdn.yoho.cn/m-yohobuy-node/{{version}}/{{module}}.{{page}}.js"></script> 97 <script src="//cdn.yoho.cn/m-yohobuy-node/{{version}}/{{module}}.{{page}}.js"></script>
98 {{/if}} 98 {{/if}}
99 - {{#unless devEnv}} 99 + {{!--{{#unless devEnv}}--}}
100 {{> analysis}} 100 {{> analysis}}
101 - {{/unless}} 101 + {{!--{{/unless}}--}}
102 </body> 102 </body>
103 </html> 103 </html>
1 {{!--新品到着 品牌推荐--}} 1 {{!--新品到着 品牌推荐--}}
2 {{#each shops}} 2 {{#each shops}}
3 -<div class="brand-news-count"> 3 +<div class="brand-news-count"
  4 + {{#if brand_id}} data-brand="{{brand_id}}" {{/if}}
  5 + {{#if shops_id}} data-shop="{{shops_id}}" {{/if}}
  6 +>
4 <div class="brand-logo"> 7 <div class="brand-logo">
5 <img src="{{image shop_logo 186 115}}" alt="{{shop_domain}}"> 8 <img src="{{image shop_logo 186 115}}" alt="{{shop_domain}}">
6 <h5>{{shop_name}}</h5> 9 <h5>{{shop_name}}</h5>
1 -<div class="good-info"> 1 +<div class="good-info" data-type="guang-article" data-id="{{id}}">
2 <div class="guang-article"> 2 <div class="guang-article">
3 <a href="{{url}}"> 3 <a href="{{url}}">
4 {{guangType category_id}} 4 {{guangType category_id}}
1 {{!-- 商品列表中的 品牌上新--}} 1 {{!-- 商品列表中的 品牌上新--}}
2 -<div class="good-info brand-info"> 2 +<div class="good-info brand-info" data-type="hot-shop" data-brand="{{brand_id}}" data-shop="{{shop_id}}">
3 <img src="{{image shop_logo 240 100}}" alt="{{shop_name}}"> 3 <img src="{{image shop_logo 240 100}}" alt="{{shop_name}}">
4 <h5 class="bname">{{shop_name}}</h5> 4 <h5 class="bname">{{shop_name}}</h5>
5 <p class="summary">上新<span class="red">{{new_product_num}}</span>&nbsp;&nbsp;<span class="red">{{favorite_num}}</span>人收藏</p> 5 <p class="summary">上新<span class="red">{{new_product_num}}</span>&nbsp;&nbsp;<span class="red">{{favorite_num}}</span>人收藏</p>
@@ -8,7 +8,7 @@ brand-tags 热门品牌 【已废除】 @@ -8,7 +8,7 @@ brand-tags 热门品牌 【已废除】
8 8
9 @param tags ul 的数据 9 @param tags ul 的数据
10 --}} 10 --}}
11 -<div class="good-info good-tags {{kind}} "> 11 +<div class="good-info good-tags {{kind}}" data-type="{{kind}}">
12 <div> 12 <div>
13 <ul class="good-tags-list"> 13 <ul class="good-tags-list">
14 {{#each tags}} 14 {{#each tags}}
@@ -24,7 +24,7 @@ brand-tags 热门品牌 【已废除】 @@ -24,7 +24,7 @@ brand-tags 热门品牌 【已废除】
24 {{!-- 24 {{!--
25 TODO: 如果要搜索品类,修改这里,目前是query查询 25 TODO: 如果要搜索品类,修改这里,目前是query查询
26 --}} 26 --}}
27 -<li> 27 +<li data-cate="{{categoryId}}">
28 <a href="//search.m.yohobuy.com/?query={{encodeURIComponent categoryName}}&from=search" class="good-tag">{{categoryName}}</a> 28 <a href="//search.m.yohobuy.com/?query={{encodeURIComponent categoryName}}&from=search" class="good-tag">{{categoryName}}</a>
29 </li> 29 </li>
30 {{/inline}} 30 {{/inline}}
@@ -9,6 +9,8 @@ let lazyLoad = require('yoho-jquery-lazyload'); @@ -9,6 +9,8 @@ let lazyLoad = require('yoho-jquery-lazyload');
9 9
10 let filter = require('plugin/filter'); 10 let filter = require('plugin/filter');
11 11
  12 +let $callback = $.Callbacks(); // eslint-disable-line
  13 +
12 new Swiper('.handpick-swiper', { 14 new Swiper('.handpick-swiper', {
13 // Optional parameters 15 // Optional parameters
14 lazyLoading: true, 16 lazyLoading: true,
@@ -178,10 +180,14 @@ let searchView = function() { @@ -178,10 +180,14 @@ let searchView = function() {
178 goods: data 180 goods: data
179 }); 181 });
180 182
  183 +
  184 +
181 $container.append(html); 185 $container.append(html);
182 186
183 187
184 lazyLoad(html); 188 lazyLoad(html);
  189 +
  190 + return html;
185 } 191 }
186 192
187 /** 193 /**
@@ -223,7 +229,12 @@ let searchView = function() { @@ -223,7 +229,12 @@ let searchView = function() {
223 searchParams.page.total = res.pageTotal; 229 searchParams.page.total = res.pageTotal;
224 searchParams.page.cur = page.cur + 1; 230 searchParams.page.cur = page.cur + 1;
225 231
226 - renderGoods($box, res.list); 232 + let html = renderGoods($box, res.list);
  233 +
  234 +
  235 + $callback.fire(html, searchParams);
  236 +
  237 +
227 }) 238 })
228 .always(() => { 239 .always(() => {
229 $loading.remove(); 240 $loading.remove();
@@ -274,12 +285,177 @@ let searchView = function() { @@ -274,12 +285,177 @@ let searchView = function() {
274 285
275 return { 286 return {
276 fetchNew, 287 fetchNew,
277 - switchNav 288 + switchNav,
  289 + searchParams
278 }; 290 };
279 }; 291 };
280 292
  293 +let search = searchView();
  294 +
  295 +
  296 +
  297 +// analysis
  298 +
  299 +// 两个轮播 获取 分析的数据
  300 +function _swiperData($item, bool) {
  301 + let $img = $item.find('img');
  302 + let $anchor = $item.find('a');
  303 +
  304 + if (bool) {
  305 + return {
  306 + IMAGE_URL: $img.attr('src') || $img.attr('data-atrr'),
  307 + ACTION_URL: $anchor.attr('href')
  308 + };
  309 + } else {
  310 + return {
  311 + F_URL: $anchor.attr('href')
  312 + };
  313 + }
  314 +}
  315 +
  316 +// 楼层分析配置
  317 +let analysisMap = {
  318 + 'banner-top': {
  319 + container: '.banner-top', // floor容器
  320 + item: '.swiper-slide', // floor item
  321 + floorInfo: {F_NAME: 'banner', F_ID: '0'}, // analysis 信息
  322 +
  323 + extraAttrs: _swiperData // 从item 获取 额外字段
  324 + },
  325 +
  326 + 'new-recommend': {
  327 + container: '#new-recommend',
  328 + item: '.brand-news-count',
  329 + floorInfo: {F_NAME: '为您推荐', F_ID: '1'},
  330 +
  331 + extraAttrs: function($item) {
  332 + return {
  333 + BRAND_ID: $item.data('brand'),
  334 + SHOP_ID: $item.data('shop')
  335 + };
  336 + }
  337 + },
  338 +
  339 + handpick: {
  340 + container: '#handpick',
  341 + item: '.swiper-slide',
  342 + floorInfo: {F_NAME: '精选抢先看', F_ID: '2'},
  343 +
  344 + extraAttrs: _swiperData
  345 + },
  346 +
  347 + 'new-goods': {
  348 + container: '#new-goods',
  349 + item: '.good-info',
  350 + floorInfo: {F_NAME: '最新上架', F_ID: '3'},
  351 +
  352 +
  353 + /**
  354 + * $item .good-info
  355 + * $target recommend-type 里面的<a>
  356 + */
  357 + extraAttrs: function($item, $target) {
  358 + let type = $item.data('type');
  359 + let _attrs = {};
  360 +
  361 + $target = $target instanceof $ && $target;
  362 +
  363 + function tagsStr(_$item, handler, $_target) {
  364 + let $li;
  365 +
  366 + if (!$_target) {
  367 + $li = _$item.find('li');
  368 + } else {
  369 + $li = $_target.closest('li');
  370 + }
  371 +
  372 + return [].map.call($li, handler).join();
  373 + }
  374 +
  375 + function tagIndex(arr, $_target) {
  376 + if ($_target) {
  377 + arr.L_INDEX = $_target.index();
  378 + }
  379 + }
  380 +
  381 + let handler;
  382 +
  383 + switch (type) {
  384 + case 'guang-article':
  385 + _attrs = {
  386 + RECOMMEND_TYPE: 'fashionArticle',
  387 + ARTICLE_ID: $item.data('id')
  388 + };
  389 + break;
  390 + case 'season-tags':
  391 + handler = li => $(li).data('cate');
  392 + _attrs = {
  393 + RECOMMEND_TYPE: 'seasonSort',
  394 + CATE_ID: tagsStr($item, handler, $target)
  395 + };
  396 +
  397 + tagIndex(_attrs, $target);
  398 + break;
  399 + case 'search-tags':
  400 + handler = li => $(li).find('a').text();
  401 + _attrs = {
  402 + RECOMMEND_TYPE: 'hotSearchTerm',
  403 + KEYWORD_WORD: tagsStr($item, handler, $target)
  404 + };
  405 +
  406 + tagIndex(_attrs, $target);
  407 + break;
  408 + case 'hot-shop':
  409 + _attrs = {
  410 + RECOMMEND_TYPE: 'hotShop',
  411 + BRAND_ID: $item.data('brand'),
  412 + SHOP_ID: $item.data('shop')
  413 + };
  414 + break;
  415 + default:
  416 + _attrs = {
  417 + PRD_SKN: $item.data('id')
  418 + };
  419 + break;
  420 + }
  421 +
  422 + if ($target) {
  423 + _attrs.SORT_NM = search.searchParams.order;
  424 + _attrs.FILTER_VALUE = search.searchParams.filter;
  425 + }
  426 +
  427 + return _attrs;
  428 + }
  429 + }
  430 +};
  431 +
  432 +let analysis = require('./new/analysis');
  433 +let analysisWorker = require('./new/new-arrival-analysis');
  434 +
  435 +
  436 +let {analysisShowData} = analysisWorker(analysisMap, 'YB_NEW_ARRIVAL_FLR_C');
  437 +
  438 +
  439 +// 最新上架 的 每页的曝光数据,发送给yas
  440 +$callback.add(function(html, searchParams) {
  441 + let pageData = analysisShowData('new-goods', {container: $(`<div>${html}</div>`)});
  442 +
  443 + pageData.SORT_NM = searchParams.order;
  444 + pageData.FILTER_VALUE = searchParams.filter;
  445 +
  446 + analysis('YB_SHOW_NEW_ARRIVAL', {data: pageData});
  447 +});
  448 +
  449 +$(function() {
  450 + setTimeout(()=> {
  451 + // 新品到着页面曝光时的页面数据,异步的单独发
  452 + analysis('YB_SHOW_NEW_ARRIVAL', {
  453 + data: ['banner-top', 'new-recommend', 'handpick'].map(analysisShowData)
  454 + });
  455 + }, 1000);
  456 +});
  457 +
281 458
282 -window.search = searchView();  
283 window.filter = filter; 459 window.filter = filter;
284 window.$ = $; 460 window.$ = $;
285 461
@@ -3,3 +3,47 @@ @@ -3,3 +3,47 @@
3 */ 3 */
4 require('product/new-brands.page.css'); 4 require('product/new-brands.page.css');
5 require('common'); 5 require('common');
  6 +
  7 +
  8 +let extraAttrs = ($item) => {
  9 + return {
  10 + BRAND_ID: $item.data('brand'),
  11 + SHOP_ID: $item.data('shop')
  12 + };
  13 +};
  14 +
  15 +// analysis
  16 +let analysisMap = {
  17 + 'browse-brands': {
  18 + container: '#browse-brands',
  19 + item: '.brand-news-count',
  20 + floorInfo: {F_NAME: '浏览过的品牌', F_ID: '0'},
  21 + extraAttrs
  22 + },
  23 + 'hot-brands': {
  24 + container: '#hot-brands',
  25 + item: '.brand-news-count',
  26 + floorInfo: {F_NAME: '热门品牌', F_ID: '1'},
  27 + extraAttrs
  28 + },
  29 + 'new-brands': {
  30 + container: 'new-brands',
  31 + item: '.brand-news-count',
  32 + floorInfo: {F_NAME: '新入驻品牌', F_ID: '2'},
  33 + extraAttrs
  34 + }
  35 +};
  36 +
  37 +let analysis = require('./new/analysis');
  38 +let analysisWorker = require('./new/new-arrival-analysis');
  39 +
  40 +let {analysisShowData} = analysisWorker(analysisMap, 'YB_NEW_ARRIVAL_RECOMMEND_FLR_C');
  41 +
  42 +$(function() {
  43 + setTimeout(()=> {
  44 + // 新品到着页面曝光时的页面数据,异步的单独发
  45 + analysis('YB_SHOW_NEW_ARRIVAL_RECOMMEND', {
  46 + data: ['browse-brands', 'hot-brands', 'new-brands'].map(analysisShowData)
  47 + });
  48 + }, 1000);
  49 +});
  1 +/**
  2 + * @param [string] eventName 埋点事件名
  3 + * @param [object] param 参数,请根据文档,C_ID 不用传,已做处理
  4 + */
  5 +module.exports = (eventName, param) => {
  6 + var yas = window._yas;
  7 + var channel = ({
  8 + boys: 1,
  9 + girls: 2,
  10 + kids: 3,
  11 + lifestyle: 4
  12 + })[window.cookie('_Channel')];
  13 +
  14 + param.C_ID = channel;
  15 + param = JSON.stringify(param);
  16 +
  17 + if (yas && yas.sendCustomInfo) {
  18 + yas.sendCustomInfo({
  19 + op: eventName,
  20 + param
  21 + }, true);
  22 + }
  23 +};
  1 +let analysis = require('./analysis');
  2 +
  3 +/**
  4 + * user: new-arrival.page.js, new-brands.page.js
  5 + */
  6 +
  7 +module.exports = function(analysisMap, clickEvent) {
  8 + $(function() {
  9 + // 给个楼层 a标签 配置click 事件
  10 + $.each(analysisMap, (key, config) => {
  11 + let container = config.container;
  12 + let _floorInfo = config.floorInfo;
  13 + let _item = config.item;
  14 +
  15 +
  16 + $(container).on('click', 'a', _floorInfo, function(event) {
  17 + let $anchor = $(event.currentTarget);
  18 + let $item = $anchor.closest(_item);
  19 +
  20 + let iIndex = $item.index() + 1;
  21 + let fIndex = $(event.delegateTarget).index();
  22 +
  23 + let extraAttrs = {
  24 + F_URL: event.currentTarget.href
  25 + };
  26 +
  27 + if ($anchor.hasClass('more')) {
  28 + iIndex = 0;
  29 + }
  30 +
  31 + // 不是more button, 并且有extraAttrs function
  32 + if (iIndex !== 0 && config.extraAttrs) {
  33 + extraAttrs = config.extraAttrs($item, $anchor);
  34 + }
  35 +
  36 +
  37 + let param = $.extend({
  38 + F_INDEX: fIndex,
  39 + I_INDEX: iIndex
  40 + }, _floorInfo, extraAttrs);
  41 +
  42 + analysis(clickEvent, param);
  43 + });
  44 + });
  45 + });
  46 +
  47 + function _buildDataList(floor, item, extraAttrs, bool) {
  48 + let _list = [];
  49 +
  50 + $(floor).find(item).each((i, elem)=> {
  51 + let obj = {
  52 + I_INDEX: i + 1
  53 + };
  54 +
  55 + let _extraAttrs = extraAttrs($(elem), bool);
  56 +
  57 + $.extend(obj, _extraAttrs);
  58 +
  59 + _list.push(obj);
  60 + });
  61 +
  62 + return _list;
  63 + }
  64 +
  65 + // 分析楼层曝光数据
  66 + /**
  67 + * @param string floor 楼层名称
  68 + * @param object options 要覆盖的楼层配置
  69 + */
  70 + function analysisShowData(floor, options) {
  71 +
  72 + let floorConfig = analysisMap[floor];
  73 +
  74 + floorConfig = $.extend({}, floorConfig, options);
  75 +
  76 + let floorInfo = floorConfig.floorInfo;
  77 + let extraAttrs = floorConfig.extraAttrs;
  78 + let container = floorConfig.container;
  79 + let item = floorConfig.item;
  80 +
  81 + let floorData = $.extend({
  82 + LIST: [],
  83 + }, floorInfo);
  84 +
  85 + floorData.LIST = _buildDataList(container, item, extraAttrs, true);
  86 +
  87 + return floorData;
  88 + }
  89 +
  90 +
  91 + return {
  92 + analysisShowData // 曝光的数据
  93 + };
  94 +};
  95 +
  96 +