Authored by 陈峰

Merge branch 'feature/tracking' into 'gray'

Feature/tracking



See merge request !104
@@ -43,7 +43,8 @@ const handleBrandList = origin => { @@ -43,7 +43,8 @@ const handleBrandList = origin => {
43 shopId: subValue.shop_id, 43 shopId: subValue.shop_id,
44 shopName: subValue.brand_name_en || subValue.brand_name_cn || subValue.brand_name, 44 shopName: subValue.brand_name_en || subValue.brand_name_cn || subValue.brand_name,
45 isRedShop: subValue.is_red_shop, 45 isRedShop: subValue.is_red_shop,
46 - shopTemplateType: subValue.shop_template_type 46 + shopTemplateType: subValue.shop_template_type,
  47 + brandId: subValue.id
47 }); 48 });
48 }); 49 });
49 50
@@ -82,7 +83,8 @@ const handleBrandList = origin => { @@ -82,7 +83,8 @@ const handleBrandList = origin => {
82 shopId: subValue.shop_id, 83 shopId: subValue.shop_id,
83 shopName: subValue.brand_name_en || subValue.brand_name_cn || subValue.brand_name, 84 shopName: subValue.brand_name_en || subValue.brand_name_cn || subValue.brand_name,
84 isRedShop: subValue.is_red_shop, 85 isRedShop: subValue.is_red_shop,
85 - shopTemplateType: subValue.shop_template_type 86 + shopTemplateType: subValue.shop_template_type,
  87 + brandId: subValue.id
86 }); 88 });
87 }); 89 });
88 dest.brandList.push({ 90 dest.brandList.push({
@@ -12,7 +12,8 @@ @@ -12,7 +12,8 @@
12 a.async = 1; 12 a.async = 1;
13 a.src = j; 13 a.src = j;
14 m.parentNode.insertBefore(a, m); 14 m.parentNode.insertBefore(a, m);
15 -}(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//cdn.yoho.cn/yas-jssdk/2.4.13/yas.js', '_yas')); 15 +}(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') +
  16 + '//cdn.yoho.cn/yas-jssdk/2.4.15/yas.js', '_yas'));
16 17
17 (function() { 18 (function() {
18 function getUid() { 19 function getUid() {
@@ -54,7 +55,7 @@ @@ -54,7 +55,7 @@
54 uid = uid === 0 ? '' : uid; 55 uid = uid === 0 ? '' : uid;
55 window._ozuid = uid; // 暴露ozuid 56 window._ozuid = uid; // 暴露ozuid
56 if (window._yas) { 57 if (window._yas) {
57 - window._yas(1 * new Date(), '2.4.14', 'yohoblk_m', uid, '', ''); 58 + window._yas(1 * new Date(), '2.4.15', 'yohoblk_m', uid, '', '');
58 } 59 }
59 }()); 60 }());
60 var _hmt = _hmt || []; 61 var _hmt = _hmt || [];
@@ -131,6 +131,35 @@ const miniVersion = function (miniVersion) { @@ -131,6 +131,35 @@ const miniVersion = function (miniVersion) {
131 return false; 131 return false;
132 }; 132 };
133 133
  134 +const debounce = function(idle, action) { // 函数去抖动,超过一定时间才会执行,如果周期内触发,重置计时器
  135 + let last;
  136 +
  137 + return function() {
  138 + let args = arguments;
  139 +
  140 + if (last) {
  141 + clearTimeout(last);
  142 + }
  143 + last = setTimeout(() => {
  144 + action.apply(this, args);
  145 + }, idle);
  146 + };
  147 +};
  148 +
  149 +const throttle = function(delay, action) { // 函数节流器,定义函数执行间隔,按频率触发函数
  150 + let last = 0;
  151 +
  152 + return function() {
  153 + let args = arguments;
  154 + let curr = +new Date();
  155 +
  156 + if (curr - last > delay) {
  157 + action.apply(this, args);
  158 + last = curr;
  159 + }
  160 + };
  161 +};
  162 +
134 export default { 163 export default {
135 getImgHost, 164 getImgHost,
136 getImgUrl, 165 getImgUrl,
@@ -138,5 +167,7 @@ export default { @@ -138,5 +167,7 @@ export default {
138 visibilitychange, 167 visibilitychange,
139 getChannel, 168 getChannel,
140 replaceHttp, 169 replaceHttp,
141 - miniVersion 170 + miniVersion,
  171 + debounce,
  172 + throttle
142 }; 173 };
@@ -66,28 +66,33 @@ function BrandHrefBinding(el, binding) { @@ -66,28 +66,33 @@ function BrandHrefBinding(el, binding) {
66 } 66 }
67 67
68 if (!yoho.isYohoBuy) { 68 if (!yoho.isYohoBuy) {
69 - el.href = href; 69 + el.href = href + `?brandId=${binding.value.brandId}`;
70 } 70 }
71 } else { 71 } else {
72 - el.href = `/product/shop/${binding.value}`; 72 + if (binding.value) {
  73 + el.href = `/product/shop/${binding.value.brand_domain}?brandId=${binding.value.brand_id}`;
  74 + }
73 } 75 }
74 } 76 }
75 function GoodHrefBinding(el, binding) { 77 function GoodHrefBinding(el, binding) {
76 if (binding.value === binding.oldValue) { 78 if (binding.value === binding.oldValue) {
77 return; 79 return;
78 } 80 }
79 - let {product_id, goods_id, cn_alphabet, product_skn} = binding.value; 81 + let {product_id, goods_id, cn_alphabet, product_skn, from_page_name, from_page_param} = binding.value;
80 82
81 if (!binding.modifiers.collect) { 83 if (!binding.modifiers.collect) {
82 goods_id = binding.value.goods_list.length ? binding.value.goods_list[0].goods_id : ''; 84 goods_id = binding.value.goods_list.length ? binding.value.goods_list[0].goods_id : '';
83 } 85 }
84 let href = `/product/pro_${product_id}_${goods_id}/${cn_alphabet || 'item'}.html`; 86 let href = `/product/pro_${product_id}_${goods_id}/${cn_alphabet || 'item'}.html`;
85 87
  88 + const prefix = yoho.isiOS ? 'i' : (yoho.isAndroid ? 'a' : '');
86 if (yoho.isYohoBuy) { 89 if (yoho.isYohoBuy) {
87 let goParams = { 90 let goParams = {
88 action: 'go.productDetail', 91 action: 'go.productDetail',
89 params: { 92 params: {
90 - product_skn: product_skn 93 + product_skn: product_skn,
  94 + from_page_name: `${prefix}${from_page_name}`,
  95 + from_page_param
91 } 96 }
92 }; 97 };
93 98
@@ -16,9 +16,6 @@ @@ -16,9 +16,6 @@
16 <style> 16 <style>
17 .brand-list-box { 17 .brand-list-box {
18 width: 100%; 18 width: 100%;
19 -  
20 - /* padding: 20px 0; */  
21 -  
22 background: #f6f6f6; 19 background: #f6f6f6;
23 20
24 /* border-top: 1px solid #eee; */ 21 /* border-top: 1px solid #eee; */
  1 +<template>
  2 + <div class="exposure-item">
  3 + <slot></slot>
  4 + </div>
  5 +</template>
  6 +<script>
  7 + import _ from 'lodash';
  8 + import yoho from 'yoho';
  9 + import util from 'common/util';
  10 +
  11 + export default {
  12 + name: 'ExposureItem',
  13 + props: {
  14 + pageName: {
  15 + type: String
  16 + },
  17 + pageParam: {
  18 + type: String,
  19 + },
  20 + index: {
  21 + type: [String, Number]
  22 + },
  23 + productSkn: {
  24 + type: [String, Number]
  25 + }
  26 + },
  27 + data() {
  28 + return {
  29 + isVisible: false,
  30 + appPrefix: yoho.isiOS ? 'i' : (yoho.isAndroid ? 'a' : 'h5')
  31 + };
  32 + },
  33 + methods: {
  34 + record(visible, init) {
  35 + if (init) {
  36 + this.isVisiable = false;
  37 + }
  38 +
  39 + // 元素由不可见变为可见则记录,否则不记录
  40 + if (!this.isVisiable && visible) {
  41 + const param = {
  42 + P_NAME: `${this.appPrefix}${this.pageName}` || '', // 页面名称
  43 + P_PARAM: this.pageParam || '', // 页面参数
  44 + I_INDEX: this.index + 1, // 内部item的序号
  45 + PRD_SKN: this.productSkn // 商品SKN (可选)
  46 + };
  47 +
  48 + if (param.P_PARAM === '') {
  49 + delete param.P_PARAM;
  50 + }
  51 +
  52 + this.$parent.addIntoWaiting(param);
  53 + }
  54 + this.isVisiable = visible;
  55 + }
  56 + }
  57 + };
  58 +</script>
  59 +<style>
  60 +</style>
  1 +<template>
  2 + <div class="exposure" ref="exposure">
  3 + <slot></slot>
  4 + </div>
  5 +</template>
  6 +<script>
  7 + import _ from 'lodash';
  8 + import yoho from 'yoho';
  9 + import util from 'common/util';
  10 +
  11 + export default {
  12 + name: 'Exposure',
  13 + props: {
  14 + topClassName: {
  15 + type: String,
  16 + default: 'top-filter'
  17 + }
  18 + },
  19 + data() {
  20 + return {
  21 + viewArea: {
  22 + top: 0,
  23 + bottom: 0
  24 + },
  25 + waiting: []
  26 + };
  27 + },
  28 + watch: {
  29 + },
  30 + methods: {
  31 + checkReport(e, init) {
  32 + // 顶部区域可能切换显示和隐藏所以动态获取
  33 + const topRect = document.querySelector(`.${this.topClassName}`).getBoundingClientRect();
  34 +
  35 + // 可见区域顶部距离视口的上边的距离
  36 + this.viewArea.top = topRect.bottom;
  37 +
  38 + // 可见区域底部距离视口的上边的距离
  39 + this.viewArea.bottom = window.screen.height;
  40 +
  41 + let children = _.filter(this.$children, child => {
  42 + return child.$options.name === 'ExposureItem'
  43 + });
  44 +
  45 + _.each(children, child => {
  46 + return child.record(this.isVisible(child.$el), init)
  47 + });
  48 + },
  49 + isVisible($el) {
  50 + const rect = $el.getBoundingClientRect();
  51 +
  52 + return ((rect.top > this.viewArea.top && rect.top < this.viewArea.bottom) ||
  53 + rect.bottom > this.viewArea.top && rect.bottom < this.viewArea.bottom)
  54 + },
  55 + addIntoWaiting(param) {
  56 + this.waiting.push(param);
  57 + }
  58 + },
  59 + mounted() {
  60 + if (yoho.isYohoBuy) {
  61 + document.addEventListener('visibilitychange', () => {
  62 + if (document.visibilityState === 'visible') {
  63 + this.checkReport(void 0, true);
  64 + }
  65 + });
  66 +
  67 + setTimeout(() => {
  68 + this.$scrollEl = window;
  69 + this.scrollEvent = util.throttle(50, this.checkReport);
  70 + if (this.$scrollEl) {
  71 + this.$scrollEl.addEventListener('scroll', this.scrollEvent);
  72 + }
  73 +
  74 + if (this.$children.length) {
  75 + this.checkReport(void 0, true);
  76 + }
  77 + }, 500);
  78 +
  79 + let reportTimer = setInterval(() => {
  80 + if (!this.$children.length) { return clearInterval(reportTimer); }
  81 + if (!this.waiting.length) { return }
  82 + this.$yas.event('YB_SHOW_EVENT', this.waiting);
  83 + this.waiting = [];
  84 + }, 3000);
  85 + }
  86 + }
  87 + };
  88 +</script>
  89 +<style>
  90 +</style>
1 <template> 1 <template>
2 <div class="goods-box" v-infinite-scroll="fetch" infinite-scroll-disable="disableFetch" :infinite-scroll-distance="1200"> 2 <div class="goods-box" v-infinite-scroll="fetch" infinite-scroll-disable="disableFetch" :infinite-scroll-distance="1200">
3 <ul class="cardlist card-large clearfix"> 3 <ul class="cardlist card-large clearfix">
4 - <li class="card" v-for="(item, index) in data" :key="item.product_skn" @click="clickProduct(item, index)">  
5 - <div class="card-pic">  
6 - <a v-good-href="item" :class="hrefClass">  
7 - <img v-img-src="{src: item.default_images, width: 330, height: 440}" :alt="item.product_name">  
8 - </a>  
9 - </div>  
10 - <div class="card-bd">  
11 - <h2 class="card-label">  
12 - <a v-good-href="item" class="line-clamp-1" :class="hrefClass">{{item.product_name}}</a>  
13 - </h2>  
14 - <h2 class="card-label-desc" v-if="item.product_name1">  
15 - <a v-good-href="item" class="line-clamp-1" :class="hrefClass">{{item.product_name}}</a>  
16 - </h2>  
17 - <span class="good-price sale-price">¥{{item.sales_price |  
18 - toFixed}}</span>  
19 - <span class="good-price" :class="{'old-price': item.market_price}" v-if="item.market_price">¥{{item.market_price | toFixed}}</span>  
20 - </div>  
21 - </li> 4 + <exposure :top-class-name="topClassName">
  5 + <li class="card" v-for="(item, index) in data" :key="item.product_skn"
  6 + @click="clickProduct(item, index)">
  7 + <exposure-item :page-name="reportPageName" :page-param="reportPageParam" :index="index"
  8 + :product-skn="item.product_skn">
  9 + <div class="card-pic">
  10 + <a v-good-href="item" :class="hrefClass">
  11 + <img v-img-src="{src: item.default_images, width: 330, height: 440}" :alt="item.product_name">
  12 + </a>
  13 + </div>
  14 + <div class="card-bd">
  15 + <h2 class="card-label">
  16 + <a v-good-href="item" class="line-clamp-1" :class="hrefClass">{{item.product_name}}</a>
  17 + </h2>
  18 + <h2 class="card-label-desc" v-if="item.product_name1">
  19 + <a v-good-href="item" class="line-clamp-1" :class="hrefClass">{{item.product_name}}</a>
  20 + </h2>
  21 + <span class="good-price sale-price">¥{{item.sales_price |
  22 + toFixed}}</span>
  23 + <span class="good-price" :class="{'old-price': item.market_price}" v-if="item.market_price">¥{{item.market_price | toFixed}}</span>
  24 + </div>
  25 + </exposure-item>
  26 + </li>
  27 + </exposure>
22 </ul> 28 </ul>
23 <p class="cardlist--loading text-center" v-show="state === 1">loading...</p> 29 <p class="cardlist--loading text-center" v-show="state === 1">loading...</p>
24 <!--<p class="cardlist--end text-center" v-show="state === 0 ">--End--</p>--> 30 <!--<p class="cardlist--end text-center" v-show="state === 0 ">--End--</p>-->
@@ -35,6 +41,8 @@ import Vue from 'vue'; @@ -35,6 +41,8 @@ import Vue from 'vue';
35 import lazyload from 'vue-lazyload'; 41 import lazyload from 'vue-lazyload';
36 import infinitScroll from 'vue-infinite-scroll'; 42 import infinitScroll from 'vue-infinite-scroll';
37 import bus from 'common/vue-bus'; 43 import bus from 'common/vue-bus';
  44 +import Exposure from 'component/product/exposure/exposure.vue';
  45 +import ExposureItem from 'component/product/exposure/exposure-item.vue';
38 46
39 Vue.use(lazyload, { preLoad: 3 }); 47 Vue.use(lazyload, { preLoad: 3 });
40 Vue.use(infinitScroll); 48 Vue.use(infinitScroll);
@@ -49,9 +57,15 @@ export default { @@ -49,9 +57,15 @@ export default {
49 /* 开启滚动加载 */ 57 /* 开启滚动加载 */
50 disableFetch: Boolean, 58 disableFetch: Boolean,
51 59
  60 + topClassName: String,
  61 +
52 // 数据 62 // 数据
53 data: Array, 63 data: Array,
54 - state: [Number, Object] // -1: 无数据 0: 全部加载完 1: 正在加载 64 + state: [Number, Object], // -1: 无数据 0: 全部加载完 1: 正在加载
  65 +
  66 + // for yas report
  67 + reportPageName: String,
  68 + reportPageParam: String,
55 }, 69 },
56 computed: { 70 computed: {
57 // 空列表: data.length === 0 71 // 空列表: data.length === 0
@@ -59,6 +73,12 @@ export default { @@ -59,6 +73,12 @@ export default {
59 return !this.data.length; 73 return !this.data.length;
60 } 74 }
61 }, 75 },
  76 + watch: {
  77 + reportPageName(v) {
  78 + console.log(v)
  79 + }
  80 +
  81 + },
62 mounted() { 82 mounted() {
63 const $scrollEl = this.getScrollEventTarget(this.$el); 83 const $scrollEl = this.getScrollEventTarget(this.$el);
64 84
@@ -105,6 +125,10 @@ export default { @@ -105,6 +125,10 @@ export default {
105 }, delay); 125 }, delay);
106 }; 126 };
107 } 127 }
  128 + },
  129 + components: {
  130 + Exposure,
  131 + ExposureItem
108 } 132 }
109 }; 133 };
110 134
1 <template> 1 <template>
2 <div class="goods"> 2 <div class="goods">
3 - <product-list :data="productList"></product-list> 3 + <product-list :data="productList" top-class-name="channel-tab"></product-list>
4 </div> 4 </div>
5 </template> 5 </template>
6 6
@@ -2,19 +2,19 @@ @@ -2,19 +2,19 @@
2 <div class="fav-type" v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10"> 2 <div class="fav-type" v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
3 <ul class="fav-brand-list"> 3 <ul class="fav-brand-list">
4 <v-touch 4 <v-touch
5 - v-for="(item, index) in brandData" 5 + v-for="(item, index) in brandData"
6 tag="li" 6 tag="li"
7 - :key="item.fav_id"  
8 - :id="'li-' + item.fav_id"  
9 - :pan-options="{ direction: 'horizontal', threshold: 100}" 7 + :key="item.fav_id"
  8 + :id="'li-' + item.fav_id"
  9 + :pan-options="{ direction: 'horizontal', threshold: 100}"
10 @panstart="(evt) => {panstart(item.fav_id, evt)}" 10 @panstart="(evt) => {panstart(item.fav_id, evt)}"
11 - @panmove="(evt) => {panmove(item.fav_id, evt)}" 11 + @panmove="(evt) => {panmove(item.fav_id, evt)}"
12 @panend="(evt) => {panend(item.fav_id, evt)}"> 12 @panend="(evt) => {panend(item.fav_id, evt)}">
13 <div :class="'fav-del-left ' + (editmodel ? 'delshow': '')" 13 <div :class="'fav-del-left ' + (editmodel ? 'delshow': '')"
14 @click="showDelBtn(item.fav_id)"> 14 @click="showDelBtn(item.fav_id)">
15 <span class="fav-del-span"><span class="icon icon-edit-del"></span></span> 15 <span class="fav-del-span"><span class="icon icon-edit-del"></span></span>
16 </div> 16 </div>
17 - <a v-brand-href="item.brand_domain"> 17 + <a v-brand-href="item">
18 <div class="fav-img-box"> 18 <div class="fav-img-box">
19 <img v-img-src="{src: item.imgUrl, width: 160, height: 125}" alt=""/> 19 <img v-img-src="{src: item.imgUrl, width: 160, height: 125}" alt=""/>
20 </div> 20 </div>
@@ -122,6 +122,7 @@ @@ -122,6 +122,7 @@
122 imgUrl: o.brand_ico, 122 imgUrl: o.brand_ico,
123 brandName: o.brand_name, 123 brandName: o.brand_name,
124 brand_domain: o.brand_domain, 124 brand_domain: o.brand_domain,
  125 + brand_id: o.brand_id,
125 down: o.status === 0 126 down: o.status === 0
126 }); 127 });
127 } 128 }
1 <template> 1 <template>
2 <div> 2 <div>
3 <ul class="item-action"> 3 <ul class="item-action">
4 - <li><a v-brand-href="brand && brand.brand_domain"><i class="icon icon-store"></i><span 4 + <li><a v-brand-href="brand"><i class="icon icon-store"></i><span
5 class="action-text">{{brand && brand.brand_name 5 class="action-text">{{brand && brand.brand_name
6 }}</span></a></li> 6 }}</span></a></li>
7 <li><i class="icon" 7 <li><i class="icon"
@@ -2,12 +2,14 @@ @@ -2,12 +2,14 @@
2 <div class="product-list" :class="{'no-header': noheader}"> 2 <div class="product-list" :class="{'no-header': noheader}">
3 <header-box :title="sortName" class="list-header"></header-box> 3 <header-box :title="sortName" class="list-header"></header-box>
4 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder"></filter-box> 4 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder"></filter-box>
5 - <product-list :data="productList" :state="listState" class="list-items"></product-list> 5 + <product-list :data="productList" :state="listState" class="list-items"
  6 + :report-page-name="pageName" :report-page-param="pageParam"></product-list>
6 <shopping-bag :cart-count="cartCount" v-if="isApp"></shopping-bag> 7 <shopping-bag :cart-count="cartCount" v-if="isApp"></shopping-bag>
7 </div> 8 </div>
8 </template> 9 </template>
9 <script> 10 <script>
10 import $ from 'jquery'; 11 import $ from 'jquery';
  12 + import _ from 'lodash';
11 import yoho from 'yoho'; 13 import yoho from 'yoho';
12 import Vue from 'vue'; 14 import Vue from 'vue';
13 import lazyload from 'vue-lazyload'; 15 import lazyload from 'vue-lazyload';
@@ -50,7 +52,11 @@ @@ -50,7 +52,11 @@
50 inSearching: false, // 请求中 52 inSearching: false, // 请求中
51 enableOrder: false, 53 enableOrder: false,
52 cartCount: 0, 54 cartCount: 0,
53 - fixIosTop: false 55 + fixIosTop: false,
  56 +
  57 + // for yas report
  58 + pageName: 'FP_BLK_Category_h5',
  59 + pageParam: locationQuery.sort || ''
54 60
55 }; 61 };
56 }, 62 },
@@ -104,6 +110,13 @@ @@ -104,6 +110,13 @@
104 if (res.data) { 110 if (res.data) {
105 this.page = res.data.page; 111 this.page = res.data.page;
106 this.totalPage = res.data.page_total; 112 this.totalPage = res.data.page_total;
  113 +
  114 + // yas report param injection
  115 + _.each(res.data.product_list, item => {
  116 + item.from_page_name = this.pageName;
  117 + item.from_page_param = this.pageParam;
  118 + });
  119 +
107 this.productList = this.productList.concat(res.data.product_list); 120 this.productList = this.productList.concat(res.data.product_list);
108 121
109 if (!this.filterConfig) { 122 if (!this.filterConfig) {
@@ -2,11 +2,13 @@ @@ -2,11 +2,13 @@
2 <div class="product-new" :class="{'no-header': noheader}"> 2 <div class="product-new" :class="{'no-header': noheader}">
3 <header-box title="NEW ARRIVAL"></header-box> 3 <header-box title="NEW ARRIVAL"></header-box>
4 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder"></filter-box> 4 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder"></filter-box>
5 - <product-list :data="productList" :state="listState" class="list-items"></product-list> 5 + <product-list :data="productList" :state="listState" class="list-items"
  6 + :report-page-name="pageName"></product-list>
6 <shopping-bag :cart-count="cartCount" v-if="isApp"></shopping-bag> 7 <shopping-bag :cart-count="cartCount" v-if="isApp"></shopping-bag>
7 </div> 8 </div>
8 </template> 9 </template>
9 <script> 10 <script>
  11 + import _ from 'lodash';
10 import $ from 'jquery'; 12 import $ from 'jquery';
11 import yoho from 'yoho'; 13 import yoho from 'yoho';
12 import Vue from 'vue'; 14 import Vue from 'vue';
@@ -49,6 +51,9 @@ @@ -49,6 +51,9 @@
49 enableOrder: false, 51 enableOrder: false,
50 order: 's_t_desc', 52 order: 's_t_desc',
51 cartCount: 0, 53 cartCount: 0,
  54 +
  55 + // for yas report
  56 + pageName: 'FP_BLK_New_h5'
52 }; 57 };
53 }, 58 },
54 computed: { 59 computed: {
@@ -98,6 +103,13 @@ @@ -98,6 +103,13 @@
98 if (res.code === 200) { 103 if (res.code === 200) {
99 this.page = res.data.page; 104 this.page = res.data.page;
100 this.totalPage = res.data.page_total; 105 this.totalPage = res.data.page_total;
  106 +
  107 + // yas report param injection
  108 + _.each(res.data.product_list, item => {
  109 + item.from_page_name = this.pageName;
  110 + item.from_page_param = this.query;
  111 + });
  112 +
101 this.productList = this.productList.concat(res.data.product_list); 113 this.productList = this.productList.concat(res.data.product_list);
102 114
103 if (!this.filterConfig) { 115 if (!this.filterConfig) {
1 <template> 1 <template>
2 <div> 2 <div>
3 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder" :search-page="true"></filter-box> 3 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder" :search-page="true"></filter-box>
4 - <product-list :data="productList" :state="listState" class="list-items" @click-product="clickProduct"></product-list> 4 + <product-list :data="productList" :state="listState" class="list-items"
  5 + @click-product="clickProduct" :report-page-name="pageName"
  6 + :report-page-param="query"></product-list>
5 </div> 7 </div>
6 </template> 8 </template>
7 <script> 9 <script>
8 import Vue from 'vue'; 10 import Vue from 'vue';
  11 + import _ from 'lodash';
9 import $ from 'jquery'; 12 import $ from 'jquery';
10 import lazyload from 'vue-lazyload'; 13 import lazyload from 'vue-lazyload';
11 import infinitScroll from 'vue-infinite-scroll'; 14 import infinitScroll from 'vue-infinite-scroll';
@@ -37,7 +40,10 @@ @@ -37,7 +40,10 @@
37 inSearching: false, 40 inSearching: false,
38 enableOrder: false, 41 enableOrder: false,
39 filterConfig: null, 42 filterConfig: null,
40 - filter: {} 43 + filter: {},
  44 +
  45 + // for yas report
  46 + pageName: 'FP_BLK_Search_h5',
41 }; 47 };
42 }, 48 },
43 computed: { 49 computed: {
@@ -89,7 +95,6 @@ @@ -89,7 +95,6 @@
89 95
90 this.inSearching = true; 96 this.inSearching = true;
91 97
92 -  
93 return $.get(this.url, Object.assign({ 98 return $.get(this.url, Object.assign({
94 order: this.order, // 排序 信息 99 order: this.order, // 排序 信息
95 query: this.query, 100 query: this.query,
@@ -99,8 +104,14 @@ @@ -99,8 +104,14 @@
99 if (res.data) { 104 if (res.data) {
100 this.page = res.data.page; 105 this.page = res.data.page;
101 this.totalPage = res.data.page_total; 106 this.totalPage = res.data.page_total;
102 - this.productList = this.productList.concat(res.data.product_list);  
103 107
  108 + // yas report param injection
  109 + _.each(res.data.product_list, item => {
  110 + item.from_page_name = this.pageName;
  111 + item.from_page_param = this.query;
  112 + });
  113 +
  114 + this.productList = this.productList.concat(res.data.product_list);
104 if (!this.filterConfig) { 115 if (!this.filterConfig) {
105 this.filterConfig = res.data.filter; 116 this.filterConfig = res.data.filter;
106 } 117 }
@@ -2,7 +2,8 @@ @@ -2,7 +2,8 @@
2 <div class="shop-box" :class="{'no-header': noheader}"> 2 <div class="shop-box" :class="{'no-header': noheader}">
3 <top-bar :share-data="shareData" :show-top-bar="showTopBar"></top-bar> 3 <top-bar :share-data="shareData" :show-top-bar="showTopBar"></top-bar>
4 <div :class='{"shop-goods-top": true}' class="list-items"> 4 <div :class='{"shop-goods-top": true}' class="list-items">
5 - <product-list :data="productList" :state="listState"></product-list> 5 + <product-list :report-page-name="pageName" :report-page-param="pageParam" :data="productList"
  6 + :state="listState"></product-list>
6 </div> 7 </div>
7 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder" ref="filter"></filter-box> 8 <filter-box :val="order" :filter="filterConfig" v-if="enableOrder" ref="filter"></filter-box>
8 <shopping-bag :cart-count="cartCount" v-if="isApp"></shopping-bag> 9 <shopping-bag :cart-count="cartCount" v-if="isApp"></shopping-bag>
@@ -33,6 +34,7 @@ @@ -33,6 +34,7 @@
33 </style> 34 </style>
34 <script> 35 <script>
35 import $ from 'jquery'; 36 import $ from 'jquery';
  37 + import _ from 'lodash';
36 import yoho from 'yoho'; 38 import yoho from 'yoho';
37 import qs from 'yoho-qs/parse'; 39 import qs from 'yoho-qs/parse';
38 import bus from 'common/vue-bus'; 40 import bus from 'common/vue-bus';
@@ -90,7 +92,11 @@ @@ -90,7 +92,11 @@
90 inSearching: false, 92 inSearching: false,
91 enableOrder: false, 93 enableOrder: false,
92 order: 's_t_desc', 94 order: 's_t_desc',
93 - cartCount: 0 95 + cartCount: 0,
  96 +
  97 + // for yas report
  98 + pageName: 'FP_BLK_Brand_h5',
  99 + pageParam: locationQuery.brandId || ''
94 }; 100 };
95 }, 101 },
96 computed: { 102 computed: {
@@ -193,6 +199,13 @@ @@ -193,6 +199,13 @@
193 if (result.code === 200) { 199 if (result.code === 200) {
194 this.page = result.data.page; 200 this.page = result.data.page;
195 this.totalPage = result.data.pageTotal; 201 this.totalPage = result.data.pageTotal;
  202 +
  203 + // yas report param injection
  204 + _.each(result.data.productList, item => {
  205 + item.from_page_name = this.pageName;
  206 + item.from_page_param = this.pageParam;
  207 + });
  208 +
196 this.productList = this.productList.concat(result.data.productList); 209 this.productList = this.productList.concat(result.data.productList);
197 if (!this.filterConfig) { 210 if (!this.filterConfig) {
198 this.filterConfig = result.data.filter; 211 this.filterConfig = result.data.filter;
@@ -32,11 +32,28 @@ export default { @@ -32,11 +32,28 @@ export default {
32 let {product_skn} = product; 32 let {product_skn} = product;
33 let href = `/product/pro_${product_skn}.html`; 33 let href = `/product/pro_${product_skn}.html`;
34 34
  35 + const pageNameMap = {
  36 + 'channel.home': 'FP_BLK_Home_h5',
  37 + 'channel.channelHome.channelMen': 'FP_BLK_MenHome_h5',
  38 + 'channel.channelHome.channelWomen': 'FP_BLK_WomenHome_h5'
  39 + };
  40 +
  41 + let from_page_name = this.$route.name;
  42 +
  43 + if (this.yoho) {
  44 + const prefix = this.yoho.env.isiOS ? 'i' : (this.yoho.env.isAndroid ? 'a' : '');
  45 + from_page_name = pageNameMap[this.$route.name] ? `${prefix}${pageNameMap[this.$route.name]}` :
  46 + this.$route.name;
  47 + }
  48 +
  49 + let from_page_param = Object.keys(this.$route.query).length ? this.$route.query : void 0;
35 if ((this.$yoho && this.$yoho.isYohoBuy) || this.yoho.env.isYohoBuy) { 50 if ((this.$yoho && this.$yoho.isYohoBuy) || this.yoho.env.isYohoBuy) {
36 let goParams = { 51 let goParams = {
37 action: 'go.productDetail', 52 action: 'go.productDetail',
38 params: { 53 params: {
39 - product_skn: product_skn 54 + product_skn: product_skn,
  55 + from_page_name: from_page_name,
  56 + from_page_param
40 } 57 }
41 }; 58 };
42 59
@@ -14,7 +14,13 @@ export default { @@ -14,7 +14,13 @@ export default {
14 name: 'ResourceBox', 14 name: 'ResourceBox',
15 data() { 15 data() {
16 return { 16 return {
17 - componentStatus: {} 17 + componentStatus: {},
  18 + waiting: [],
  19 + pageNameMap: {
  20 + 'channel.home': 'FP_BLK_Home_h5',
  21 + 'channel.channelHome.channelMen': 'FP_BLK_MenHome_h5',
  22 + 'channel.channelHome.channelWomen': 'FP_BLK_WomenHome_h5',
  23 + }
18 }; 24 };
19 }, 25 },
20 computed: { 26 computed: {
@@ -27,7 +33,7 @@ export default { @@ -27,7 +33,7 @@ export default {
27 } 33 }
28 }, 34 },
29 ['yoho.visible'](visible) { 35 ['yoho.visible'](visible) {
30 - if (visible && this.$yoho && this.$yoho.isiOS) { 36 + if (visible && this.$yoho) {
31 this.checkReport(void 0, true); 37 this.checkReport(void 0, true);
32 } 38 }
33 } 39 }
@@ -43,6 +49,14 @@ export default { @@ -43,6 +49,14 @@ export default {
43 this.$scrollEl.addEventListener('scroll', this.scrollEvent); 49 this.$scrollEl.addEventListener('scroll', this.scrollEvent);
44 this.checkReport(void 0, true); 50 this.checkReport(void 0, true);
45 } 51 }
  52 +
  53 + // 每隔三秒钟上报一次数据
  54 + setInterval(() => {
  55 + if (this.waiting.length) {
  56 + this.report(this.waiting);
  57 + this.waiting = [];
  58 + }
  59 + }, 3000);
46 }, 60 },
47 destroyed() { 61 destroyed() {
48 if (this.$scrollEl) { 62 if (this.$scrollEl) {
@@ -50,43 +64,115 @@ export default { @@ -50,43 +64,115 @@ export default {
50 } 64 }
51 }, 65 },
52 methods: { 66 methods: {
  67 + report(param) {
  68 +
  69 + const prefix = this.yoho.env.isiOS ? 'i' : (this.yoho.env.isAndroid ? 'a' : '');
  70 + _.each(param, item => {
  71 + if (this.pageNameMap[item.P_NAME]) {
  72 + item.P_NAME = this.pageNameMap[item.P_NAME];
  73 + }
  74 + item.P_NAME = `${prefix}${item.P_NAME}`;
  75 + });
  76 +
  77 + this.$store.dispatch(REPORT_YAS, {
  78 + params: {
  79 + appop: 'YB_SHOW_EVENT',
  80 + param
  81 + }
  82 + });
  83 + },
53 checkReport(evt, isInit) { 84 checkReport(evt, isInit) {
  85 + if (isInit) {
  86 + this.componentStatus = {};
  87 + }
54 _.each(this.$children, (component, index) => { 88 _.each(this.$children, (component, index) => {
55 - const visiable = this.isVisiable(component.$el, this.$scrollEl); 89 + const visible = this.isVisible(component.$el, this.$scrollEl);
56 90
57 - if (visiable && (this.componentStatus[index] !== visiable || isInit)) {  
58 - this.report(component, index + 1); 91 + if (visible && (this.componentStatus[index] !== visible || isInit)) {
  92 + this.record(component, index + 1, isInit);
59 } 93 }
60 - this.componentStatus[index] = visiable; 94 + this.componentStatus[index] = visible;
61 }); 95 });
62 }, 96 },
63 - report(component, index) { 97 + record(component, index) {
64 const reportData = _.get(component, '$options.propsData.value'); 98 const reportData = _.get(component, '$options.propsData.value');
65 99
  100 + // 区分不通组件记录以楼层内item为单位、而不是以整个楼层为单位组织数据上报
  101 + let param;
66 if (reportData) { 102 if (reportData) {
67 - const param = {  
68 - P_NAME: this.$route.name,  
69 - F_NAME: reportData.template_name,  
70 - F_ID: reportData.template_id,  
71 - F_INDEX: index  
72 - }; 103 + switch (reportData.template_name) {
  104 + case 'twoPicture':
  105 + param = [];
  106 + _.each(reportData.data.list, (item, idx) => {
  107 + param.push({
  108 + P_NAME: this.$route.name,
  109 + F_NAME: reportData.template_name,
  110 + F_ID: reportData.template_id,
  111 + F_INDEX: index,
  112 + I_INDEX: idx + 1,
  113 + ACTION_URL: item.url
  114 + });
  115 + });
  116 + break;
  117 +
  118 + case 'focus':
  119 + // 由于focus自动轮播的特殊性、上报数据由focus直接调用父组件方法
  120 + // 修改waiting数组所以这里不做数据监测
  121 + break;
  122 +
  123 + case 'tfGoodsList':
  124 + // 楼层内存在多个item, 交给子组件各自检测
  125 + let visible = component.checkReqFromParent();
  126 + if (visible.length) {
  127 + param = [];
  128 + _.each(visible, item => {
  129 + param.push(Object.assign(item, {
  130 + P_NAME: this.$route.name,
  131 + F_NAME: reportData.template_name,
  132 + F_ID: reportData.template_id,
  133 + F_INDEX: index,
  134 + }));
  135 + });
  136 + }
  137 + break;
  138 +
  139 + case 'newSingleImage':
  140 + param = {
  141 + P_NAME: this.$route.name,
  142 + F_NAME: reportData.template_name,
  143 + F_ID: reportData.template_id,
  144 + F_INDEX: index,
  145 + I_INDEX: 1,
  146 + ACTION_URL: reportData.data.list[0].url
  147 + };
  148 + break;
  149 + default:
  150 + break;
  151 + }
73 152
74 - this.$store.dispatch(REPORT_YAS, {  
75 - params: {  
76 - appop: 'YB_SHOW_EVENT',  
77 - param  
78 - }  
79 - }); 153 + if (param) {
  154 + _.isArray(param) ? (this.waiting = this.waiting.concat(param)) : this.waiting.push(param);
  155 + }
80 } 156 }
81 }, 157 },
82 - isVisiable($el, $parent) { 158 + isVisible($el, $parent) {
83 const rect = $el.getBoundingClientRect(); 159 const rect = $el.getBoundingClientRect();
84 const parentRect = $parent.getBoundingClientRect(); 160 const parentRect = $parent.getBoundingClientRect();
85 161
86 return ((parentRect.top >= rect.top && parentRect.top <= (rect.top + rect.height)) || 162 return ((parentRect.top >= rect.top && parentRect.top <= (rect.top + rect.height)) ||
87 - ((parentRect.top + parentRect.height) >= rect.top && (parentRect.top + parentRect.height) <= (rect.top + rect.height)) ||  
88 - (rect.top >= parentRect.top && (rect.top + rect.height) <= (parentRect.top + parentRect.height))); 163 + ((parentRect.top + parentRect.height) >= rect.top && (parentRect.top + parentRect.height) <= (rect.top + rect.height)) ||
  164 + (rect.top >= parentRect.top && (rect.top + rect.height) <= (parentRect.top + parentRect.height)));
  165 + },
  166 + checkReqFromChild(index) {
  167 + // 重置子组件显示状态方可重新记录
  168 + this.componentStatus[index] = false;
  169 + this.checkReport();
  170 + },
  171 + focusComponentDataRecord(index, param) {
  172 + if (this.componentStatus[index] && document.visibilityState === 'visible') {
  173 + this.waiting.push(param);
  174 + }
89 } 175 }
90 } 176 }
91 }; 177 };
92 -</script>  
  178 +</script>
@@ -32,8 +32,12 @@ @@ -32,8 +32,12 @@
32 autoplay: true, 32 autoplay: true,
33 pagination: { 33 pagination: {
34 el: '.swiper-pagination' 34 el: '.swiper-pagination'
  35 + },
  36 + on:{
  37 + slideChange: this._slideChange,
35 } 38 }
36 - } 39 + },
  40 + itemVisibleStatus: {}
37 }; 41 };
38 }, 42 },
39 computed: { 43 computed: {
@@ -44,6 +48,17 @@ @@ -44,6 +48,17 @@
44 methods: { 48 methods: {
45 swiperSuccess(swiper) { 49 swiperSuccess(swiper) {
46 this.mySwiper = swiper; 50 this.mySwiper = swiper;
  51 +
  52 + // 注册成功后上报首个slide
  53 + let param = {
  54 + I_INDEX: this.mySwiper.realIndex + 1,
  55 + P_NAME: this.$route.name,
  56 + F_NAME: this.value.template_name,
  57 + F_ID: this.value.template_id,
  58 + F_INDEX: this.index + 1,
  59 + ACTION_URL: this.value.data[this.mySwiper.realIndex].url
  60 + };
  61 + this.dataRecord(param);
47 }, 62 },
48 activeLink() { 63 activeLink() {
49 const img = this.value.data[this.mySwiper.realIndex]; 64 const img = this.value.data[this.mySwiper.realIndex];
@@ -54,6 +69,30 @@ @@ -54,6 +69,30 @@
54 this.$refs.linkA.click(); 69 this.$refs.linkA.click();
55 }); 70 });
56 } 71 }
  72 + },
  73 + _slideChange() {
  74 + if (this.mySwiper) {
  75 +
  76 + // fixed: slideChange回调执行时,realIndex为0会前后触发两次
  77 + if (this.mySwiper.previousIndex === this.value.data.length + 1) {
  78 + return;
  79 + }
  80 +
  81 + let param = {
  82 + I_INDEX: this.mySwiper.realIndex + 1,
  83 + P_NAME: this.$route.name,
  84 + F_NAME: this.value.template_name,
  85 + F_ID: this.value.template_id,
  86 + F_INDEX: this.index + 1,
  87 + ACTION_URL: this.value.data[this.mySwiper.realIndex].url
  88 + };
  89 +
  90 + this.dataRecord(param);
  91 + }
  92 + },
  93 + dataRecord(param) {
  94 + // index 用户父组件判断当前组件是否可见
  95 + this.$parent.focusComponentDataRecord(this.index, param)
57 } 96 }
58 }, 97 },
59 components: {Resource} 98 components: {Resource}
1 <template> 1 <template>
2 - <resource class="no-padding-right product-list-more"> 2 + <resource class="no-padding-right product-list-more" ref="resource">
3 <ul class="resource-tf-goods" 3 <ul class="resource-tf-goods"
4 @touchstart="touchStart" 4 @touchstart="touchStart"
5 @touchmove="touchMove" 5 @touchmove="touchMove"
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 </template> 23 </template>
24 24
25 <script> 25 <script>
  26 +import _ from 'lodash';
26 import Resource from './resource'; 27 import Resource from './resource';
27 28
28 export default { 29 export default {
@@ -34,7 +35,9 @@ export default { @@ -34,7 +35,9 @@ export default {
34 moveX: 0, 35 moveX: 0,
35 disX: 0, 36 disX: 0,
36 moreSlider: '', 37 moreSlider: '',
37 - moreMove: '' 38 + moreMove: '',
  39 + itemVisibleStatus: {},
  40 + checkTimer: ''
38 }; 41 };
39 }, 42 },
40 props: { 43 props: {
@@ -103,6 +106,13 @@ export default { @@ -103,6 +106,13 @@ export default {
103 } 106 }
104 }, 107 },
105 touchEnd(ev) { 108 touchEnd(ev) {
  109 +
  110 + // 手动触发父组件曝光检查, touchEnd事件触发后延迟500ms检查
  111 + clearTimeout(this.checkTimer);
  112 + this.checkTimer = setTimeout(() => {
  113 + this.$parent.checkReqFromChild(this.index);
  114 + }, 500);
  115 +
106 let wd = this.$refs.goodsList.scrollWidth - this.$refs.goodsList.offsetWidth; 116 let wd = this.$refs.goodsList.scrollWidth - this.$refs.goodsList.offsetWidth;
107 let moreWd = this.$refs.more.offsetWidth; 117 let moreWd = this.$refs.more.offsetWidth;
108 let scrollLeft = this.$refs.goodsList.scrollLeft; 118 let scrollLeft = this.$refs.goodsList.scrollLeft;
@@ -136,6 +146,36 @@ export default { @@ -136,6 +146,36 @@ export default {
136 this.$refs.linkA.click(); 146 this.$refs.linkA.click();
137 this.moreSlider = 'transform:translateX(0px)'; 147 this.moreSlider = 'transform:translateX(0px)';
138 this.moreMove = 'transform:translateX(' + this.$refs.more.offsetWidth + 'px)'; 148 this.moreMove = 'transform:translateX(' + this.$refs.more.offsetWidth + 'px)';
  149 + },
  150 +
  151 + // 用于检测楼层内部item的曝光状态, 暴露给父组件调用
  152 + checkReqFromParent(isInit) {
  153 +
  154 + // 重置item的显示状态重新检测
  155 + _.each(this.itemVisibleStatus, (v, k) => {
  156 + this.itemVisibleStatus[k] = false
  157 + });
  158 +
  159 + let rect;
  160 + let isVisible;
  161 + let visible = [];
  162 + let items = this.$el.querySelectorAll('.product-item');
  163 +
  164 + _.each(items, (item, idx) => {
  165 + rect = item.getBoundingClientRect();
  166 + isVisible = (rect.left > 0 && rect.left < window.screen.width) ||
  167 + ((rect.left + rect.width) > 0 && (rect.left + rect.width) < window.screen.width);
  168 +
  169 + if (isVisible && !this.itemVisibleStatus[idx]) {
  170 + visible.push({
  171 + I_INDEX: idx + 1,
  172 + PRD_SKN: this.value.data && this.value.data.list[idx].product_skn
  173 + });
  174 + }
  175 + this.itemVisibleStatus[idx] = isVisible;
  176 + });
  177 +
  178 + return visible;
139 } 179 }
140 }, 180 },
141 components: {Resource} 181 components: {Resource}
@@ -18,59 +18,59 @@ @@ -18,59 +18,59 @@
18 (function(w, d, s, j, f) { 18 (function(w, d, s, j, f) {
19 var a = d.createElement(s); 19 var a = d.createElement(s);
20 var m = d.getElementsByTagName(s)[0]; 20 var m = d.getElementsByTagName(s)[0];
21 - 21 +
22 w.YohoAcquisitionObject = f; 22 w.YohoAcquisitionObject = f;
23 - 23 +
24 w[f] = function() { 24 w[f] = function() {
25 w[f].p = arguments; 25 w[f].p = arguments;
26 }; 26 };
27 - 27 +
28 a.async = 1; 28 a.async = 1;
29 a.src = j; 29 a.src = j;
30 m.parentNode.insertBefore(a, m); 30 m.parentNode.insertBefore(a, m);
31 - }(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//cdn.yoho.cn/yas-jssdk/2.4.13/yas.js', '_yas'));  
32 - 31 + }(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//cdn.yoho.cn/yas-jssdk/2.4.15/yas.js', '_yas'));
  32 +
33 (function() { 33 (function() {
34 function getUid() { 34 function getUid() {
35 var uid, 35 var uid,
36 name = '_UID', 36 name = '_UID',
37 cookies = (document.cookie && document.cookie.split(';')) || []; 37 cookies = (document.cookie && document.cookie.split(';')) || [];
38 - 38 +
39 for (var i = 0; i < cookies.length; i++) { 39 for (var i = 0; i < cookies.length; i++) {
40 if (cookies[i].indexOf(name) > -1) { 40 if (cookies[i].indexOf(name) > -1) {
41 uid = decodeURIComponent(cookies[i].replace(name + '=', '').trim()); 41 uid = decodeURIComponent(cookies[i].replace(name + '=', '').trim());
42 break; 42 break;
43 } 43 }
44 } 44 }
45 - 45 +
46 if (!uid) return 0; 46 if (!uid) return 0;
47 - 47 +
48 uid = uid.split('::'); 48 uid = uid.split('::');
49 if (!uid || uid.length < 4) { 49 if (!uid || uid.length < 4) {
50 return 0; 50 return 0;
51 } 51 }
52 return uid[1]; 52 return uid[1];
53 } 53 }
54 - 54 +
55 function queryString() { 55 function queryString() {
56 var vars = {}, 56 var vars = {},
57 hash, 57 hash,
58 i; 58 i;
59 var hashes = window.location.search.slice(1).split('&'); 59 var hashes = window.location.search.slice(1).split('&');
60 - 60 +
61 for (i = 0; i < hashes.length; i++) { 61 for (i = 0; i < hashes.length; i++) {
62 hash = hashes[i].split('='); 62 hash = hashes[i].split('=');
63 vars[hash[0]] = hash[1]; 63 vars[hash[0]] = hash[1];
64 } 64 }
65 return vars; 65 return vars;
66 } 66 }
67 - 67 +
68 var uid = getUid() || queryString().uid; 68 var uid = getUid() || queryString().uid;
69 - 69 +
70 uid = uid === 0 ? '' : uid; 70 uid = uid === 0 ? '' : uid;
71 window._ozuid = uid; // 暴露ozuid 71 window._ozuid = uid; // 暴露ozuid
72 if (window._yas) { 72 if (window._yas) {
73 - window._yas(1 * new Date(), '2.4.14', 'yohoblk_m', uid, '', ''); 73 + window._yas(1 * new Date(), '2.4.15', 'yohoblk_m', uid, '', '');
74 } 74 }
75 }()); 75 }());
76 var _hmt = _hmt || []; 76 var _hmt = _hmt || [];
@@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
81 s.parentNode.insertBefore(hm, s); 81 s.parentNode.insertBefore(hm, s);
82 })(); 82 })();
83 </script> 83 </script>
84 - 84 +
85 <!--vue-ssr-outlet--> 85 <!--vue-ssr-outlet-->
86 </body> 86 </body>
87 -</html>  
  87 +</html>
@@ -41,12 +41,23 @@ export default { @@ -41,12 +41,23 @@ export default {
41 } 41 }
42 } 42 }
43 }; 43 };
44 - window.yohoInterface = window.yohoInterface; 44 +
  45 + const setInterface = () => {
  46 + if (window.frames['iframe']) {
  47 + window.frames['iframe'].yohoInterface = window.yohoInterface;
  48 + window.frames['iframe'].appBaseLogs = window.appBaseLogs;
  49 + }
  50 + };
  51 +
45 this.$bus.$on('after-view-enter', () => { 52 this.$bus.$on('after-view-enter', () => {
46 this.showIframe = true; 53 this.showIframe = true;
  54 + this.$nextTick(() => setInterface());
  55 +
47 }); 56 });
48 if (this.yoho.env.fs) { 57 if (this.yoho.env.fs) {
49 this.showIframe = true; 58 this.showIframe = true;
  59 + this.$nextTick(() => setInterface());
  60 +
50 } 61 }
51 }, 62 },
52 computed: { 63 computed: {