Authored by 陈轩

Merge remote-tracking branch 'origin/release/5.1' into release/5.1

... ... @@ -47,12 +47,25 @@ exports.index = (req, res, next) => {
* 潮流优选首页-资源位
*/
exports.resourcesTemplate = (req, res, next) => {
let code = req.query.code || '';
let isApp = req.query.app_version || req.query.appVersion || false;
let uid = '';
let param = {};
plusstarModel.getResources({
content_code: code
}, {
if (req.yoho.isApp) {
uid = req.query.uid;
} else {
uid = req.user.uid;
}
if (uid) {
param.uid = uid;
}
param.content_code = req.query.code || '';
param.yh_channel = req.query.yh_channel || 1;
plusstarModel.getResourcesData(param, {
isApp: isApp
}).then(result => {
res.render('plusstar/resources-template', {
... ... @@ -62,3 +75,29 @@ exports.resourcesTemplate = (req, res, next) => {
});
}).catch(next);
};
/**
* 潮流优选首页-资源位-商品列表
*/
exports.resourcesGoodsList = (req, res, next) => {
let productSkn = req.body.productSkn || '';
let isApp = req.body.app_version || req.body.appVersion || false;
let param = {};
param = {
productSkn: productSkn.split(','),
yh_channel: req.body.yh_channel,
page: req.body.page,
limit: req.body.limit
};
plusstarModel.getProductBatch(param, {
isApp: isApp
}).then(result => {
res.render('plusstar/resources-goodsList', {
layout: false,
result: result,
title: '潮流优选'
});
}).catch(next);
};
... ...
... ... @@ -45,17 +45,40 @@ const getAllChannels = (params) => {
* @param {[string || array]} productSkn 商品skn
* @return {[array]}
*/
const getProductBatch = (productSkn, options) => {
productSkn = _.isArray(productSkn) ? productSkn : [productSkn];
const getProductBatch = (param, options) => {
param.productSkn = _.isArray(param.productSkn) ? param.productSkn : [param.productSkn];
return api.get('', {
method: 'h5.product.batch',
productSkn: productSkn.join(',')
productSkn: param.productSkn.join(','),
yh_channel: param.yh_channel,
page: param.page,
limit: param.limit
}).then(result => {
return result && result.data ? productProcess.processProductList(result.data.product_list, options) : [];
let data = {};
if (result && result.data) {
data = {
page_total: result.data.page_total,
product_list: productProcess.processProductList(result.data.product_list, options)
};
}
return data;
});
};
/**
* 商品推荐获取
* @param {[int]} yh_channel 当前频道
* @param {[int]} uid 用户id
* @return {[array]}
*/
const getFashionPrefer = (params) => {
return api.get('', Object.assign({
method: 'h5.product.fashionPrefer'
}, params));
};
/**
* 获取资源位数据
* @param {[string]} content_code
* @return {[array]}
... ... @@ -88,10 +111,11 @@ const getResources = (params, options) => {
};
if (res.focus_type * 1 === 1) {
data.focus1 = [];
data.focus1.push(list);
data.focus1 = list;
data.focus1.id = res.template_id;
} else {
data.focus2 = list;
data.focus2.id = res.template_id;
}
break;
... ... @@ -101,6 +125,7 @@ const getResources = (params, options) => {
}
list = {
id: res.template_id,
title: res.data.title,
moreUrl: res.data.more_url,
moreName: res.data.more_name,
... ... @@ -118,8 +143,10 @@ const getResources = (params, options) => {
if (res.data.title.name === '热门商品') {
data.goods.title = list;
data.goods.id = res.template_id;
} else if (res.data.title.name === '热门品类') {
data.recommend.title = list;
data.recommend.id = res.template_id;
}
break;
... ... @@ -138,19 +165,30 @@ const getResources = (params, options) => {
}
});
if (_.isEmpty(data.goods.productSkns)) {
return data;
return data;
});
};
const getResourcesData = (params, options) => {
return api.all([
getResources(params, options),
getFashionPrefer(params)
]).then(result => {
let skns = result[0] && result[0].goods && result[0].goods.productSkns || [];
let preferSkns = result[1] && result[1].data || [];
if (result[0] && result[0].goods && result[0].goods.productSkns) {
result[0].goods.productSkns = _.uniq(Object.assign(skns, preferSkns));
}
return getProductBatch(data.goods.productSkns, options).then(res => {
data.goods.data = res;
return data;
});
return result[0];
});
};
module.exports = {
getAllChannels,
getResources,
getProductBatch
getFashionPrefer,
getProductBatch,
getResourcesData
};
... ...
... ... @@ -36,29 +36,29 @@ const getRssArticle = (gender) => {
return articlePromise.then((article) => {
// 内容列表
if (article.data.list.artList) {
let build = {};
let build = {};
let artListFunc = (i, len, resolve) => {
if (i < len) {
let value = article.data.list.artList[i];
if (typeof value.id !== 'undefined') {
build = guangProcess.formatArticle(value, false, false, true);
build.author.name = build.author.name || '';
return _genIntro(value.id).then((intro) => {
build.intro = intro;
result.push(build);
artListFunc(++i, len, resolve);
});
}
} else {
let artListFunc = (i, len, resolve) => {
if (i < len) {
let value = article.data.list.artList[i];
if (typeof value.id !== 'undefined') {
build = guangProcess.formatArticle(value, false, false, true);
build.author.name = build.author.name || '';
return _genIntro(value.id).then((intro) => {
build.intro = intro;
result.push(build);
artListFunc(++i, len, resolve);
});
}
} else {
resolve(result);
}
};
}
};
return new Promise((resolve) => {
artListFunc(0, article.data.list.artList.length, resolve);
});
});
}
}
});
};
... ... @@ -75,18 +75,18 @@ const _genIntro = (id) => {
resData.data.forEach((value) => {
if (value.text) { // 文字
result += htmlProcess.removeHtml(htmlProcess.escapeToHtml(value.text.data.text)) + '<br/>';
} else if (value.singleImage) { // 单张图
result += `<img src="${helpers.image(value.singleImage.data[0].src, 640, 640)}"/><br/>`;
} else if (value.singleImage) { // 单张图
result += `<img src="${helpers.image(value.singleImage.data[0].src, 640, 640)}"/><br/>`;
} else if (value.smallPic && value.smallPic.data) { // 多张小图
value.smallPic.data.forEach((small) => {
result += `<img src="${helpers.image(small.src, 315, 420)}"/>`;
});
result += '<br/>';
value.smallPic.data.forEach((small) => {
result += `<img src="${helpers.image(small.src, 315, 420)}"/>`;
});
result += '<br/>';
}
});
});
return result;
}
});
}
});
};
module.exports = {
... ...
... ... @@ -32,6 +32,7 @@ router.get('/', homeController.index); // 逛首页
router.get('/plusstar', plusstar.index); // 潮流优选
router.get('/plusstar/resources-template', plusstar.resourcesTemplate); // 潮流优选首页-资源位
router.post('/plusstar/resources-goodsList', plusstar.resourcesGoodsList); // 潮流优选首页-资源位-商品列表
router.get('/', index.index); // 逛首页
router.get('/tags/index', index.tag); // 逛标签页
... ...
<div class='plusstar-page'>
<div class='yoho-page plusstar-page'>
{{#if result.channel}}
<div class="tab-nav">
<ul>
... ...
{{#if result.product_list}}
<input type='hidden' value='{{result.page_total}}' class='page-total' />
{{/if}}
{{#each result.product_list}}
{{> common/goods}}
{{/each}}
\ No newline at end of file
... ...
<div class="resources">
<!--banner-->
{{#each result.focus1}}
{{#if result.focus1}}
<div class="banner-top">
<div class="banner-swiper swiper-container">
<ul class="swiper-wrapper">
{{#each data}}
<ul class="swiper-wrapper" data-id={{result.focus1.id}}>
{{#each result.focus1.data}}
{{#if @first}}
<li class="swiper-slide">
<a href="{{url}}">
... ... @@ -27,9 +27,10 @@
</div>
</div>
</div>
{{/each}}
{{/if}}
{{#each result.title_image}}
<div class='speck-title-image' data-fid='{{id}}' data-name='{{title}}'>
<div class="header-title">
{{title}}
<a class="more" href="{{moreUrl}}">{{moreName}}</a>
... ... @@ -39,10 +40,11 @@
<img class="lazy" data-original="{{image image.src 750 364}}">
</a>
</div>
</div>
{{/each}}
{{#if result.focus2.data}}
<div class="focus-left-right">
<div class="focus-left-right speck-title-image" data-fid='{{result.focus2.id}}' data-name='焦点图'>
{{#each result.focus2.data}}
<a href="{{url}}" title="{{title}}">
<img class="lazy" data-original="{{image src 250 250}}">
... ... @@ -52,7 +54,9 @@
{{/if}}
<!--/focus-left-right-->
{{#if result.recommend.title}}
{{#if result.recommend}}
<div class='speck-title-image' data-fid='{{result.recommend.id}}' data-name='{{result.recommend.title.name}}'>
{{#if result.recommend.title}}
<div class="header-title">
{{result.recommend.title.name}}
<a class="more" href="{{result.recommend.title.moreUrl}}">
... ... @@ -63,12 +67,14 @@
{{#if result.recommend.data}}
<div class="recommend-content-five">
{{#each result.recommend.data}}
<a href="{{url}}" title="{{title}}">
<a href="{{url}}">
<img class="lazy" data-original="{{image src 375 375}}">
</a>
{{/each}}
</div>
{{/if}}
</div>
{{/if}}
{{#if result.goods.title}}
<div class="header-title">
... ... @@ -76,13 +82,12 @@
<a class="more" href="{{result.goods.title.moreUrl}}">
{{result.goods.title.moreName}}
</a>
<input type='hidden' value='{{result.goods.productSkns}}' class='product-skns' />
</div>
<div class="goods clearfix">
<!--商品--->
{{#each result.goods.data}}
{{> common/goods}}
{{/each}}
</div><!--/goods-->
{{/if}}
... ...
... ... @@ -162,4 +162,4 @@ if ($('#noData').length > 0) {
$mask.on('click', function() {
$mask.hide();
$message.hide();
});
\ No newline at end of file
});
... ...
... ... @@ -14,6 +14,8 @@ var $footer = $('#yoho-footer'),
var RECID = (new Date().getTime() + '_H5_YOHOBUY_' + Math.floor(Math.random() * 1000000 + 1000000) +
'_' + Math.floor(Math.random() * 1000000 + 1000000));
var _ChannelVary = {boys: 1, girls: 2, kids: 3, lifestyle: 4};
function cookie(name) {
var cookies = document.cookie,
cookieVal,
... ... @@ -195,8 +197,7 @@ function reMarginFooter(fixedElement) {
a.async = 1;
a.src = j;
m.parentNode.insertBefore(a, m);
})(window, document, 'script', (document.location.protocol === 'https:' ? 'https' : 'http') + '://cdn.yoho.cn/yas-jssdk/1.0.17/yas.js', '_yas');
}(window, document, 'script', (document.location.protocol === 'https:' ? 'https' : 'http') + '://cdn.yoho.cn/yas-jssdk/1.0.17/yas.js', '_yas'));
(function() {
var uid = getUid();
... ... @@ -307,22 +308,7 @@ function givePoint(parameter) {
}
// 男:1,女:2,潮童:3,创意生活:4
switch (cookie('_Channel')) {
case 'boys':
CID = 1;
break;
case 'girls':
CID = 2;
break;
case 'kids':
CID = 3;
break;
case 'lifestyle':
CID = 4;
break;
default:
CID = 1;
}
CID = _ChannelVary[cookie('_Channel')] || 1;
parameter = $.extend({
REC_POSE: '',
... ... @@ -340,7 +326,8 @@ function givePoint(parameter) {
window._yas.sendCustomInfo({
op: 'YB_CHOOSE_FOR_YOU_Y',
uid: getUid(),
apf: (queryString().app_version || queryString().appVersion) ? true : false,
ts: new Date().getTime(),
param: JSON.stringify(parameter)
}, true);
}
... ... @@ -365,3 +352,5 @@ window.reMarginFooter = reMarginFooter;
window.queryString = queryString();
window.givePoint = givePoint;
window._ChannelVary = _ChannelVary;
... ...
... ... @@ -258,7 +258,6 @@ function loadMore($container, opt, url) {
delete opt.isTab;
},
error: function() {
// console.log('error')
tip.show('网络断开连接了~');
searching = false;
delete opt.isTab;
... ...
... ... @@ -2,16 +2,33 @@ var $ = require('yoho-jquery'),
tip = require('../plugin/tip'),
Swiper = require('yoho-swiper'),
loading = require('../plugin/loading'),
debounce = require('lodash/debounce'),
lazyLoad = require('yoho-jquery-lazyload');
var plusstar = {},
$footer = $('#yoho-footer');
var windowHeight = $(window).height();
var scrollFn,
scrollTop,
RECPOSE,
CID,
isApp,
speckParamApp = {
udid: '',
apt: '',
sid: ''
};
require('../common');
plusstar = {
common: {
codeDefault: ''
codeDefault: '',
page: 1,
pagesize: 20,
pageTotal: 1,
productSkns: []
},
init: function() {
var that = this,
... ... @@ -41,7 +58,31 @@ plusstar = {
$(this).find('li').removeClass('focus');
$liDom.addClass('focus');
that.ParentLiDom = $liDom;// 保留当前tab先中的对象
that.tabNav($liDom.data('code'));
// 点击潮流优选上方的TAB按钮时
if (window._yas && window._yas.sendCustomInfo) {
window._yas.sendCustomInfo({
op: 'YB_FASHION_TAB_C',
apf: isApp,
ts: new Date().getTime(),
param: JSON.stringify($.extend(speckParamApp, {
C_ID: CID,
TAB_ID: $liDom.index() + 1
}))
}, true);
window._yas.sendCustomInfo({
op: 'YB_FASHION_HOME_L',
apf: isApp,
ts: new Date().getTime(),
param: JSON.stringify($.extend(speckParamApp, {
C_ID: CID,
TAB_ID: that.ParentLiDom.index() + 1
}))
}, true);
}
});
// start -- 默认选中
... ... @@ -55,23 +96,103 @@ plusstar = {
that.tabNav($liDom.data('code'));
// ent -- 默认选中
that.ParentLiDom = $liDom;// 保留当前tab先中的对象
setTimeout(function() {
that._yas();
}, 1000);
},
_yas: function() {
// http://redmine.yoho.cn/issues/12224
var that = this;
if (!window._yas || !window._yas.sendCustomInfo) {
return false;
}
RECPOSE = that.ParentLiDom.index() !== 0 ? 100015 : 100014;
$('.plusstar-resources').bind('click', function(event) {
var $dom, $domA, index;
if ($(event.target).closest('.good-info').length > 0) {
// 商品单击埋点
$dom = $(event.target).closest('.good-info');
index = $dom.index() + 1;
window.givePoint($.extend(speckParamApp, {
REC_POSE: RECPOSE,
PRD_ID: $dom.data('good-id'),
ORDER_CODE: '',
PRD_NUM: index % that.common.pagesize === 0 ? that.common.pagesize : index % that.common.pagesize,
ACTION_ID: 1,
page_num: Math.ceil(index / that.common.pagesize)
}));
} else if ($(event.target).closest('.banner-top').length > 0) {
// 头部banner楼层埋点
$dom = $(event.target).closest('li');
index = $dom.index() + 1;
window._yas.sendCustomInfo({
op: 'YB_FASHION_FLR_C',
apf: isApp,
ts: new Date().getTime(),
param: JSON.stringify($.extend(speckParamApp, {
C_ID: CID,
TAB_ID: that.ParentLiDom.index() + 1,
F_ID: $dom.closest('ul').data('id'),
F_NAME: '焦点图',
F_URL: $dom.find('a').attr('href'),
F_INDEX: 1,
I_INDEX: index
}))
}, true);
} else if ($(event.target).closest('.speck-title-image a').length > 0) {
// 各楼层埋点
$dom = $(event.target).closest('.speck-title-image');
$domA = $(event.target).closest('.speck-title-image a');
window._yas.sendCustomInfo({
op: 'YB_FASHION_FLR_C',
apf: isApp,
ts: new Date().getTime(),
param: JSON.stringify($.extend(speckParamApp, {
C_ID: CID,
TAB_ID: that.ParentLiDom.index() + 1,
F_ID: $dom.data('fid'),
F_NAME: $dom.data('name'),
F_URL: $domA.attr('href'),
F_INDEX: $dom.index() + 1,
I_INDEX: $domA.hasClass('more') ? 0 : ($domA.index() + 1)
}))
}, true);
}
});
// 潮流优选首页加载时
window._yas.sendCustomInfo({
op: 'YB_FASHION_HOME_L',
apf: isApp,
ts: new Date().getTime(),
param: JSON.stringify($.extend(speckParamApp, {
C_ID: CID,
TAB_ID: that.ParentLiDom.index() + 1
}))
}, true);
},
tabNav: function(code) {
var that = this;
this.common.codeDefault = code;// 记住最后一次的tab code
loading.showLoadingMask();
this.common.page = 1;// 商品列表从第一页开始
$.ajax({
type: 'GET',
url: '/guang/plusstar/resources-template',
data: {
code: code,
app_version: window.queryString.app_version || window.queryString.appVersion
app_version: isApp
},
dataType: 'html',
success: function(data) {
var productSkns = '';
$('.plusstar-resources').html(data);
if (data === '') {
... ... @@ -81,7 +202,6 @@ plusstar = {
that.resInit();
loading.hideLoadingMask();
lazyLoad($('img.lazy'));
// 处理左右滑动,未加载的图片
... ... @@ -97,10 +217,15 @@ plusstar = {
if (window.localStorage) {
$(document).scrollTop(localStorage.getItem(code) || 0);
}
productSkns = $(data).find('.product-skns').val();
if (productSkns) {
that.common.productSkns = productSkns.split(',');
}
},
error: function() {
tip.show('网络断开连接了~');
loading.hideLoadingMask();
}
});
},
... ... @@ -118,10 +243,95 @@ plusstar = {
pagination: '.banner-top .pagination-inner'
});
}
},
goodsList: function() {
var that = this,
skn = [];
if (that.common.page > that.common.pageTotal) {
return false;
}
loading.showLoadingMask();
$.ajax({
type: 'POST',
url: '/guang/plusstar/resources-goodsList',
timeout: 5000,
data: {
productSkn: that.common.productSkns.join(','),
app_version: isApp,
limit: that.common.pagesize,
page: that.common.page,
yh_channel: that.ParentLiDom.index() + 1
},
dataType: 'html',
success: function(data) {
skn = [];
loading.hideLoadingMask();
if (data === '') {
return true;
}
if (that.common.page <= 1) {
that.common.pageTotal = $(data).siblings('.page-total').val();
}
$.each($(data).siblings('.good-info'), function() {
skn.push($(this).data('good-id'));
});
window.givePoint($.extend(speckParamApp, {
REC_POSE: RECPOSE,
PRD_ID: skn.join(','),
ORDER_CODE: '',
PRD_NUM: that.common.pagesize,
ACTION_ID: 0,
page_num: that.common.page++
}));
$('.plusstar-resources .goods').append(data);
lazyLoad($('.plusstar-resources .goods').find('img.lazy:not([src])'));
$('.resources .goods .page-total').remove();
},
error: function() {
tip.show('网络断开连接了~');
loading.hideLoadingMask();
}
});
}
};
scrollFn = debounce(function() {
scrollTop = $(document).scrollTop();
// 当scroll到最后一列商品的高度后继续请求下一页数据
if (400 + scrollTop >= $(document).height() - windowHeight) {
plusstar.goodsList();
}
if (window.localStorage) {
localStorage.setItem(plusstar.common.codeDefault, $(this).scrollTop());
}
}, 200);
$(function() {
isApp = (window.queryString.app_version || window.queryString.appVersion) ? true : false;
if (isApp) {
speckParamApp = {
udid: window.queryString.udid || '',
apt: window.queryString.client_type || '',
sid: window.queryString.sid || '',
};
}
// 男:1,女:2,潮童:3,创意生活:4
CID = window._ChannelVary[window.cookie('_Channel')] || 1;
if (!(window.queryString.app_version || window.queryString.appVersion)) {
$('.tab-nav').css({
... ... @@ -137,9 +347,8 @@ $(function() {
plusstar.init();
if (window.localStorage) {
$(document).scroll(function() {
localStorage.setItem(plusstar.common.codeDefault, $(this).scrollTop());
});
}
// 滚动翻页
$(window).scroll(function() {
scrollFn();
});
});
... ...
... ... @@ -33,7 +33,7 @@ $('#nav-tab').on('touchend touchcancel', function(e) {
$navs.toggleClass('focus');
$contents.toggleClass('hide');
$(document).trigger('scroll'); //Trigger lazyLoad
$(document).trigger('scroll'); // Trigger lazyLoad
});
$('#nav-tab').on('touchstart', function(e) {
var target = e.target || e.srcElement;
... ... @@ -41,4 +41,4 @@ $('#nav-tab').on('touchstart', function(e) {
target.className = 'bytouch ' + target.className;
}).on('touchend touchcancel', function() {
$navs.removeClass('bytouch');
});
\ No newline at end of file
});
... ...
... ... @@ -89,7 +89,7 @@ ellipsis.init();
tip.show('网络断开连接了~');
}
});
} else if ($('.shopId').val().length > 0){
} else if ($('.shopId').val().length > 0) {
$.ajax({
url: '/product/index/baseShopFav',
data: {
... ...
... ... @@ -38,6 +38,7 @@ var $subNav = $('.home-sub-nav'),
favId = $('input[name="favId"]').val(),
uid = $('input[name="uid"]').val();
var winH = $(window).height(),
noResult = '<p class="no-result">未找到相关搜索结果</p>';
... ...
... ... @@ -20,7 +20,7 @@ const removeHtml = (str) => {
const htmlToEscape = (html) => {
return html.replace(/[<>&"]/g, (e) => {
return _htmlMap[e];
});
});
};
/**
... ... @@ -29,7 +29,7 @@ const htmlToEscape = (html) => {
const escapeToHtml = (str) => {
return str.replace(/&(lt|gt|nbsp|amp|quot);/g, (match, e) => {
return _EscapeMap[e];
});
});
};
module.exports = {
... ...