Authored by TaoHuang

Merge remote-tracking branch 'origin/develop' into develop

@@ -5,6 +5,9 @@ @@ -5,6 +5,9 @@
5 </template> 5 </template>
6 6
7 <script> 7 <script>
  8 +import { mapGetters } from 'vuex';
  9 +import queryString from 'querystring'
  10 +
8 export default { 11 export default {
9 name: 'LayoutLink', 12 name: 'LayoutLink',
10 props: { 13 props: {
@@ -14,6 +17,9 @@ export default { @@ -14,6 +17,9 @@ export default {
14 }, 17 },
15 reportEvent: String, 18 reportEvent: String,
16 }, 19 },
  20 + computed: {
  21 + ...mapGetters(['getLogin'])
  22 + },
17 watch: { 23 watch: {
18 report: function(newVal) { 24 report: function(newVal) {
19 }, 25 },
@@ -24,6 +30,13 @@ export default { @@ -24,6 +30,13 @@ export default {
24 if (!this.href) { 30 if (!this.href) {
25 return; 31 return;
26 } 32 }
  33 + // 资源位跳转 领券等需判断是否登录
  34 + // 判断条件为查询参数 isNeedLogin
  35 + const qsParams = queryString.parse(this.href.split('?')[1]);
  36 + if(!this.getLogin && +qsParams.isNeedLogin === 1) {
  37 + this.$yoho.auth();
  38 + return;
  39 + }
27 40
28 this.$xianyu.goXianyuNewPage({ 41 this.$xianyu.goXianyuNewPage({
29 url: this.href 42 url: this.href
@@ -320,7 +320,7 @@ export default { @@ -320,7 +320,7 @@ export default {
320 }, 320 },
321 { 321 {
322 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/1/4.png', 322 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/1/4.png',
323 - token: 'b13ebf9a-e5bc-4dec-8904-975008daaff5' 323 + token: 'b13ebf9a-e5bc-4dec-8904-975007daaff5'
324 }, 324 },
325 { 325 {
326 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/1/5.png', 326 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/1/5.png',
@@ -443,7 +443,7 @@ export default { @@ -443,7 +443,7 @@ export default {
443 }, 443 },
444 { 444 {
445 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/2/3.png', 445 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/2/3.png',
446 - token: '4ce7d50c-fa8e-47e8-81cc-4700854d5cbc' 446 + token: '4ce7d50c-fa8e-47e8-81cc-4700754d5cbc'
447 }, 447 },
448 { 448 {
449 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/2/4.png', 449 image: '//ad.yoho.cn/html5/2019/10/activity/008/coupon/2/4.png',
@@ -2,9 +2,10 @@ @@ -2,9 +2,10 @@
2 <layout-app title="商品列表" class="brand-product-list"> 2 <layout-app title="商品列表" class="brand-product-list">
3 <LayoutScroll 3 <LayoutScroll
4 class="scroll-view" 4 class="scroll-view"
  5 + ref="pageScroll"
5 @scroll-end="scrollEndHandler"> 6 @scroll-end="scrollEndHandler">
6 <div class="list-wrapper" v-if="brandProductList != null"> 7 <div class="list-wrapper" v-if="brandProductList != null">
7 - <product-list ref="productList" :list="brandProductList" priceKey="price" :yas-params="recommendYasParams"/> 8 + <product-list :list="brandProductList" priceKey="price" :yas-params="recommendYasParams"/>
8 </div> 9 </div>
9 </LayoutScroll> 10 </LayoutScroll>
10 </layout-app> 11 </layout-app>
@@ -17,10 +18,12 @@ import ProductList from '../list/components/productList'; @@ -17,10 +18,12 @@ import ProductList from '../list/components/productList';
17 18
18 const STORE_PATH = 'product'; 19 const STORE_PATH = 'product';
19 const { mapState } = createNamespacedHelpers(STORE_PATH); 20 const { mapState } = createNamespacedHelpers(STORE_PATH);
  21 +import trackingMixins from './tracking-mixins';
20 22
21 export default { 23 export default {
22 name: 'BrandProductList', 24 name: 'BrandProductList',
23 props: ['productId'], 25 props: ['productId'],
  26 + mixins: [trackingMixins],
24 components: { 27 components: {
25 ProductList, 28 ProductList,
26 ScrollView, 29 ScrollView,
@@ -60,17 +63,52 @@ export default { @@ -60,17 +63,52 @@ export default {
60 return this.topLists[this.$route.params.productId]; 63 return this.topLists[this.$route.params.productId];
61 }, 64 },
62 }, 65 },
  66 + watch: {
  67 + brandProductList(list) {
  68 + if (list && list.length > 0) {
  69 + this.listDataDirty = true;
  70 + this.scrollEndHandler();
  71 + }
  72 + }
  73 + },
63 asyncData({store, router}) { 74 asyncData({store, router}) {
64 return store.dispatch(`${STORE_PATH}/fetchBrandTop`, {productId: router.params.productId}); 75 return store.dispatch(`${STORE_PATH}/fetchBrandTop`, {productId: router.params.productId});
65 }, 76 },
66 activated() { 77 activated() {
67 - this.$refs.productList && this.$refs.productList.yasShowEvent(0); 78 + this.scrollEndHandler();
68 }, 79 },
69 methods: { 80 methods: {
70 - scrollEndHandler({y}) {  
71 - const scrollTop = Math.abs(y); 81 + collectTrackingInfo(viewInfo, force = false) {
  82 + if (!this.yasTargets) {
  83 + this.yasTargets = {};
  84 + }
  85 +
  86 + if (this.brandProductList && this.brandProductList.length > 0 && (!this.yasTargets.productItem0 || force)) {
  87 + let productElList = document.querySelectorAll('.product-list-item');
  88 +
  89 + if (productElList && productElList.length > 0) {
  90 + this.brandProductList.forEach((item, idx) => {
  91 + if (productElList[idx] && item) {
  92 + const id = `productItem${idx}`;
72 93
73 - this.$refs.productList && this.$refs.productList.yasShowEvent(scrollTop); 94 + /**
  95 + * 1.P_NAME:页面名称,XY_UFOProductDetail;
  96 + * 2.P_PARAM:页面参数;
  97 + * 3.I_INDEX:曝光顺序;
  98 + * 4.PRD_SKN:商品id
  99 + * 5.POS_ID: 1:相关商品,2: 推荐推荐,3: 相关商品列表页面
  100 + */
  101 + this.yasTargets[id] = {
  102 + el: {
  103 + offsetTop: productElList[idx].offsetTop,
  104 + offsetHeight: productElList[idx].offsetHeight,
  105 + },
  106 + yasParams: {...this.recommendYasParams, I_INDEX: idx + 1, PRD_SKN: item.id},
  107 + };
  108 + }
  109 + });
  110 + }
  111 + }
74 }, 112 },
75 }, 113 },
76 }; 114 };
@@ -30,8 +30,8 @@ @@ -30,8 +30,8 @@
30 </div> 30 </div>
31 <div class="info-name"><div>{{productDetail.product_name}}</div></div> 31 <div class="info-name"><div>{{productDetail.product_name}}</div></div>
32 </div> 32 </div>
33 - <a class="banner" v-if="resource.src" @click.prevent="gotoNewPage">  
34 - <img-size ref="resourceImg" :src="sizeImg(resource.src)"/> 33 + <a class="banner" ref="resourceImg" v-if="resource.src" @click.prevent="gotoNewPage">
  34 + <img-size :src="sizeImg(resource.src)"/>
35 </a> 35 </a>
36 <div class="info"> 36 <div class="info">
37 <transition-group name="info-list" tag="div" class="info-list"> 37 <transition-group name="info-list" tag="div" class="info-list">
@@ -96,12 +96,13 @@ import BuySheet from './components/buy-sheet'; @@ -96,12 +96,13 @@ import BuySheet from './components/buy-sheet';
96 import TopList from './components/top-list'; 96 import TopList from './components/top-list';
97 import SquareImg from './components/square-img'; 97 import SquareImg from './components/square-img';
98 import stateShortCutsMixins from './mixins'; 98 import stateShortCutsMixins from './mixins';
  99 +import trackingMixins from './tracking-mixins';
99 100
100 const { mapActions, mapState } = createNamespacedHelpers('product'); 101 const { mapActions, mapState } = createNamespacedHelpers('product');
101 102
102 export default { 103 export default {
103 name: 'ProductDetail', 104 name: 'ProductDetail',
104 - mixins: [stateShortCutsMixins], 105 + mixins: [stateShortCutsMixins, trackingMixins],
105 components: { 106 components: {
106 SizeSelectSheet, 107 SizeSelectSheet,
107 ActivityListSheet, 108 ActivityListSheet,
@@ -173,11 +174,11 @@ export default { @@ -173,11 +174,11 @@ export default {
173 }, { 174 }, {
174 text: '发售时间', 175 text: '发售时间',
175 value: this.productDetail.sale_time 176 value: this.productDetail.sale_time
176 - }, 177 + },
177 // { 178 // {
178 // text: '发售价格', 179 // text: '发售价格',
179 // value: this.productDetail.offer_price 180 // value: this.productDetail.offer_price
180 - // }, 181 + // },
181 { 182 {
182 text: '货号', 183 text: '货号',
183 value: this.productDetail.product_code 184 value: this.productDetail.product_code
@@ -201,6 +202,24 @@ export default { @@ -201,6 +202,24 @@ export default {
201 showSizeSelectSheet: 'onSizeSelectSheetHide', 202 showSizeSelectSheet: 'onSizeSelectSheetHide',
202 showSizeRequestSheet: 'onSizeRequestHide', 203 showSizeRequestSheet: 'onSizeRequestHide',
203 }; 204 };
  205 +
  206 + // create watcher for list data
  207 + this.watchList = [];
  208 + ['resource.url', 'topList', 'recommend'].forEach(key => {
  209 + this.watchList.push(this.$watch(key, val => {
  210 + if (val) {
  211 + this.listDataDirty = true;
  212 + }
  213 + }));
  214 + });
  215 + },
  216 + beforeDestroy() {
  217 + if (this.watchList) {
  218 + this.watchList.forEach(item => {
  219 + item && item();
  220 + });
  221 + this.watchList = null;
  222 + }
204 }, 223 },
205 asyncData({store, router}) { 224 asyncData({store, router}) {
206 const productId = parseInt(router.params.productId, 10); 225 const productId = parseInt(router.params.productId, 10);
@@ -233,17 +252,15 @@ export default { @@ -233,17 +252,15 @@ export default {
233 } 252 }
234 253
235 if (this.resource && this.resource.url) { 254 if (this.resource && this.resource.url) {
236 - this.yasResourceVisible(); 255 + this.yasResourceAvailable();
237 } else { 256 } else {
238 this._resourceImgWatcher = this.$watch(() => { 257 this._resourceImgWatcher = this.$watch(() => {
239 return this.resource && this.resource.url; 258 return this.resource && this.resource.url;
240 }, (url) => { 259 }, (url) => {
241 if (url) { 260 if (url) {
242 this._resourceImgWatcher && this._resourceImgWatcher(); 261 this._resourceImgWatcher && this._resourceImgWatcher();
243 - this.yasResourceVisible(); 262 + this.yasResourceAvailable();
244 } 263 }
245 - }, {  
246 - immediate: true,  
247 }); 264 });
248 } 265 }
249 266
@@ -318,96 +335,80 @@ export default { @@ -318,96 +335,80 @@ export default {
318 refresh() { 335 refresh() {
319 this.$refs.slide && this.$refs.slide.refresh && this.$refs.slide.refresh(); 336 this.$refs.slide && this.$refs.slide.refresh && this.$refs.slide.refresh();
320 }, 337 },
321 - scrollEndHandler({y}) {  
322 - const scrollTop = Math.abs(y);  
323 - const pageScrollHeight = this.$refs.pageScroll.$el.offsetHeight;  
324 -  
325 - // 相关商品  
326 - if (!this._topListYas && this.$refs.topList) {  
327 - if (this._topListTop === undefined) {  
328 - this._topListTop = this.$refs.topList.$el.offsetTop;  
329 - }  
330 -  
331 - if (scrollTop < this._topListTop && (scrollTop + pageScrollHeight) > this._topListTop) {  
332 - const DATA = this.topList.slice(0, 3).map((value, i) => {  
333 - return {...this.recommendYasParams, I_INDEX: i + 1, PRD_SKN: value.id, POS_ID: 1};  
334 - });  
335 -  
336 - /**  
337 - *  
338 - * 1.P_NAME:页面名称,XY_UFOProductDetail;  
339 - * 2.P_PARAM:页面参数;  
340 - * 3.I_INDEX:曝光顺序;  
341 - * 4.PRD_SKN:商品id  
342 - * 5.POS_ID: 1:相关商品,2: 推荐推荐,3: 相关商品列表页面  
343 - */  
344 - this.$store.dispatch('reportYas', {  
345 - params: {  
346 - param: {DATA},  
347 - appop: 'XY_UFO_SHOW_EVENT'  
348 - }  
349 - });  
350 - this._topListYas = true;  
351 - } 338 + collectTrackingInfo(viewInfo, force) {
  339 + if (!this.yasTargets) {
  340 + this.yasTargets = {};
352 } 341 }
353 342
354 - // 推荐商品  
355 - if (this._productItemHeight === undefined) {  
356 - let item = document.querySelector('.product-list-item');  
357 -  
358 - if (item) {  
359 - this._productItemHeight = item.offsetHeight;  
360 - this._productListOffsetTop = item.offsetTop;  
361 - } 343 + // banner
  344 + if (this.$refs.resourceImg && this.resource.url && (!this.yasTargets.banner || force)) {
  345 + /**
  346 + * 商品详情页中的资源位曝光
  347 + * XY_UFO_SHOW_EVENT
  348 + * 1.P_NAME:当前页面名称,XY_UFOProductDetail;
  349 + * 2.P_PARAM:当前页面资源位code;
  350 + * 3.PRD_ID:商品ID;
  351 + * 4.ACTION_URL:资源位跳转URL;
  352 + */
  353 + this.yasTargets.banner = {
  354 + el: {
  355 + offsetTop: this.$refs.resourceImg.offsetTop,
  356 + offsetHeight: this.$refs.resourceImg.offsetHeight,
  357 + },
  358 + yasParams: {
  359 + P_NAME: 'XY_UFOProductDetail',
  360 + P_PARAM: this.resourceContentCode,
  361 + PRD_ID: this.productId,
  362 + ACTION_URL: this.resource.url,
  363 + }
  364 + };
362 } 365 }
363 366
364 - if (this.$refs.recommendList && this._productItemHeight) {  
365 - const productListVisibleHeight = scrollTop + pageScrollHeight - this._productListOffsetTop;  
366 -  
367 - if (productListVisibleHeight > 0) {  
368 - const maxRow = Math.floor(productListVisibleHeight / this._productItemHeight);  
369 -  
370 - const listScrollTop = Math.max(0, scrollTop - this._productListOffsetTop);  
371 - const row = Math.floor(listScrollTop / this._productItemHeight);  
372 -  
373 - const list = this.recommend.slice(row * 2, (row + maxRow) * 2).filter(item => !item.yas);  
374 -  
375 - if (list.length > 0) {  
376 - const DATA = list.map(item => {  
377 - item.yas = true;  
378 - return {...this.recommendYasParams, I_INDEX: ++this.recommendYasIndex, PRD_SKN: item.id};  
379 - }); 367 + // 相关商品
  368 + if (this.$refs.topList && this.topList && (!this.yasTargets.topList0 || force)) {
  369 + const elInfo = {
  370 + offsetTop: this.$refs.topList.$el.offsetTop,
  371 + offsetHeight: this.$refs.topList.$el.offsetHeight,
  372 + };
  373 +
  374 + /**
  375 + * 1.P_NAME:页面名称,XY_UFOProductDetail;
  376 + * 2.P_PARAM:页面参数;
  377 + * 3.I_INDEX:曝光顺序;
  378 + * 4.PRD_SKN:商品id
  379 + * 5.POS_ID: 1:相关商品,2: 推荐推荐,3: 相关商品列表页面
  380 + */
  381 + this.topList.slice(0, 3).forEach((value, i) => {
  382 + this.yasTargets[`topList${i}`] = {
  383 + el: elInfo,
  384 + yasParams: {...this.recommendYasParams, I_INDEX: i + 1, PRD_SKN: value.id, POS_ID: 1},
  385 + };
  386 + });
  387 + }
380 388
381 - this.$store.dispatch('reportYas', {  
382 - params: {  
383 - param: {DATA},  
384 - appop: 'XY_UFO_SHOW_EVENT'  
385 - }  
386 - });  
387 - } 389 + // 推荐商品
  390 + if (this.$refs.recommendList && this.recommend && this.recommend.length > 0 && (!this.yasTargets.productItem0 || force)) {
  391 + let productElList = document.querySelectorAll('.product-list-item');
  392 +
  393 + if (productElList && productElList.length > 0) {
  394 + this.recommend.forEach((item, i) => {
  395 + if (productElList[i] && item) {
  396 + const id = `productItem${i}`;
  397 +
  398 + this.yasTargets[id] = {
  399 + el: {
  400 + offsetTop: productElList[i].offsetTop,
  401 + offsetHeight: productElList[i].offsetHeight,
  402 + },
  403 + yasParams: {...this.recommendYasParams, I_INDEX: i + 1, PRD_SKN: item.id},
  404 + };
  405 + }
  406 + });
388 } 407 }
389 } 408 }
390 }, 409 },
391 - yasResourceVisible() {  
392 - /**  
393 - * 商品详情页中的资源位曝光  
394 - * XY_UFO_SHOW_EVENT  
395 - * 1.P_NAME:当前页面名称,XY_UFOProductDetail;  
396 - * 2.P_PARAM:当前页面资源位code;  
397 - * 3.PRD_ID:商品ID;  
398 - * 4.ACTION_URL:资源位跳转URL;  
399 - */  
400 - this.$store.dispatch('reportYas', {  
401 - params: {  
402 - appop: 'XY_UFO_SHOW_EVENT',  
403 - param: {  
404 - P_NAME: 'XY_UFOProductDetail',  
405 - P_PARAM: this.resourceContentCode,  
406 - PRD_ID: this.productId,  
407 - ACTION_URL: this.resource.url,  
408 - },  
409 - }  
410 - }); 410 + yasResourceAvailable() {
  411 + this.scrollEndHandler();
411 if (this._resourceImgWatcher) { 412 if (this._resourceImgWatcher) {
412 this._resourceImgWatcher(); 413 this._resourceImgWatcher();
413 this._resourceImgWatcher = null; 414 this._resourceImgWatcher = null;
@@ -421,8 +422,8 @@ export default { @@ -421,8 +422,8 @@ export default {
421 422
422 // 加载商品详情数据 423 // 加载商品详情数据
423 loadData(productId = this.productId) { 424 loadData(productId = this.productId) {
424 - this.fetchBrandTop({productId});  
425 - this.fetchFav({productId}); 425 + this.fetchBrandTop({ productId });
  426 + this.fetchFav({ productId });
426 }, 427 },
427 428
428 /** 429 /**
  1 +export default {
  2 + deactivated() {
  3 + this.preVisibleEls = null;
  4 + },
  5 + methods: {
  6 + isVisible(offsetInfo, viewInfo, ratio = 0.5) {
  7 + return !((offsetInfo.offsetTop + offsetInfo.offsetHeight * (1 - ratio)) < viewInfo.top ||
  8 + (offsetInfo.offsetTop + offsetInfo.offsetHeight * ratio) > viewInfo.bottom);
  9 + },
  10 + scrollEndHandler({y = this.$refs.pageScroll && this.$refs.pageScroll.$el.offsetTop} = {}) {
  11 + const scrollTop = Math.abs(y);
  12 +
  13 + let pageScrollHeight = this.$refs.pageScroll.$el.offsetHeight;
  14 +
  15 + if (pageScrollHeight === 0) {
  16 + const app = document.querySelector('#app');
  17 + const header = document.querySelector('.layout-header');
  18 + const footer = document.querySelector('.footer');
  19 +
  20 + pageScrollHeight = app && app.offsetHeight || window.innerHeight;
  21 + if (header) {
  22 + pageScrollHeight -= header.offsetHeight;
  23 + }
  24 + if (footer) {
  25 + pageScrollHeight -= footer.offsetHeight;
  26 + }
  27 + }
  28 +
  29 + const viewInfo = {
  30 + top: scrollTop,
  31 + bottom: scrollTop + pageScrollHeight,
  32 + };
  33 +
  34 + this.collectTrackingInfo(viewInfo, this.listDataDirty);
  35 +
  36 + const visibleEls = Object.keys(this.yasTargets).filter(key => {
  37 + return this.isVisible(this.yasTargets[key].el, viewInfo);
  38 + });
  39 +
  40 + let visibleChangedEls;
  41 +
  42 + if (!this.preVisibleEls) {
  43 + visibleChangedEls = visibleEls;
  44 + } else {
  45 + visibleChangedEls = visibleEls.filter(key => {
  46 + return !this.preVisibleEls.includes(key);
  47 + });
  48 + }
  49 +
  50 + this.preVisibleEls = visibleEls;
  51 +
  52 + if (visibleChangedEls.length > 0) {
  53 + const DATA = visibleChangedEls.map(key => this.yasTargets[key].yasParams);
  54 +
  55 + this.$store.dispatch('reportYas', {
  56 + params: {
  57 + param: {DATA},
  58 + appop: 'XY_UFO_SHOW_EVENT'
  59 + }
  60 + });
  61 + }
  62 +
  63 + this.listDataDirty = false;
  64 + },
  65 + },
  66 +};
@@ -3,15 +3,18 @@ module.exports = [ @@ -3,15 +3,18 @@ module.exports = [
3 route: /xianyu\/index\/channel/, 3 route: /xianyu\/index\/channel/,
4 cacheTime: 60, 4 cacheTime: 60,
5 cache: true, 5 cache: true,
  6 + pageName: 'channel'
6 }, 7 },
7 { 8 {
8 route: /xianyu\/index/, 9 route: /xianyu\/index/,
9 cacheTime: 60, 10 cacheTime: 60,
10 cache: true, 11 cache: true,
  12 + pageName: 'channel'
11 }, 13 },
12 { 14 {
13 route: /xianyu\/index\/category/, 15 route: /xianyu\/index\/category/,
14 cacheTime: 30, 16 cacheTime: 30,
15 cache: true, 17 cache: true,
  18 + pageName: 'category'
16 }, 19 },
17 ]; 20 ];
@@ -8,6 +8,7 @@ const pkg = require('./package.json'); @@ -8,6 +8,7 @@ const pkg = require('./package.json');
8 const devtools = require('./doraemon/middleware/devtools'); 8 const devtools = require('./doraemon/middleware/devtools');
9 const _ = require('lodash'); 9 const _ = require('lodash');
10 const uuid = require('uuid'); 10 const uuid = require('uuid');
  11 +const favicon = require('serve-favicon');
11 12
12 // 全局注册library 13 // 全局注册library
13 yohoLib.global(config); 14 yohoLib.global(config);
@@ -38,6 +39,7 @@ exports.createApp = async(app) => { @@ -38,6 +39,7 @@ exports.createApp = async(app) => {
38 } 39 }
39 40
40 app.set('etag', false); 41 app.set('etag', false);
  42 + app.use(favicon(path.join(__dirname, './favicon.ico')));
41 43
42 app.use('/xianyu/node/status.html', (req, res) => { 44 app.use('/xianyu/node/status.html', (req, res) => {
43 res.status(200).end(); 45 res.status(200).end();
@@ -8,14 +8,14 @@ exports.serverError = (err, req, res, next) => { // eslint-disable-line @@ -8,14 +8,14 @@ exports.serverError = (err, req, res, next) => { // eslint-disable-line
8 logger.error(`error at path: ${req.url}`); 8 logger.error(`error at path: ${req.url}`);
9 logger.error(`${req.url},${typeof err === 'object' ? JSON.stringify(err) : err}`); 9 logger.error(`${req.url},${typeof err === 'object' ? JSON.stringify(err) : err}`);
10 10
11 - res.status(err.code || 500);  
12 -  
13 if (req.xhr) { 11 if (req.xhr) {
14 return res.json({ 12 return res.json({
15 - code: 500,  
16 - message: '服务器错误!' 13 + code: err.code || 500,
  14 + message: err.message || '服务器错误!'
17 }); 15 });
18 } 16 }
19 17
  18 + res.status(err.code || 500);
  19 +
20 return res.send('服务器开小差了~'); 20 return res.send('服务器开小差了~');
21 }; 21 };
@@ -140,6 +140,7 @@ const render = (route) => { @@ -140,6 +140,7 @@ const render = (route) => {
140 app: config.appName, 140 app: config.appName,
141 ip: req.yoho.clientIp, 141 ip: req.yoho.clientIp,
142 path: req.url, 142 path: req.url,
  143 + pageName: _.get(route, 'pageName', 'unknown'),
143 uid: req.user.uid, 144 uid: req.user.uid,
144 udid: req.cookies.udid || '', 145 udid: req.cookies.udid || '',
145 clientType: req.yoho.clientType || '', 146 clientType: req.yoho.clientType || '',
No preview for this file type
1 { 1 {
2 "name": "xianyu-ufo-app-web", 2 "name": "xianyu-ufo-app-web",
3 - "version": "0.0.1-beta-40", 3 + "version": "0.0.2-beta-1",
4 "private": true, 4 "private": true,
5 "description": "Xianyu Project With Express", 5 "description": "Xianyu Project With Express",
6 "repository": { 6 "repository": {