Authored by 陈轩

列表模版 ok

... ... @@ -61,6 +61,8 @@ const newGoods = (req, res, next) => {
};
const _newGoods = (req, res, next) => {
const channel = req.cookies._Channel;
res.render('new/index', {
module: 'product',
page: 'new-arrival',
... ... @@ -69,21 +71,46 @@ const _newGoods = (req, res, next) => {
pageHeader: headerModel.setNav({
navTitle: '新品到着'
}),
brand: '0',
sort: '0',
gender: req.query.gender || searchProcess.getGenderByChannel(channel),
channel,
price: '0',
size: '0',
dayLimit: 1,
discount: '',
cartUrl: helpers.urlFormat('/cart/index/index', null),
pageFooter: true,
showDownloadApp: true
});
};
/**
* 新品到着 落地页: 为您推荐
*/
const brands = (req, res, next) => {
res.render('new/brands', {
module: 'product',
page: 'new-brands',
width750: true,
localCss: true,
pageHeader: headerModel.setNav({
navTitle: '为您推荐'
}),
});
const channel = req.cookies._Channel;
const uid = req.user.uid;
newModel.recbrand(uid, channel).then(data => {
res.render('new/brands', {
module: 'product',
page: 'new-brands',
width750: true,
localCss: true,
pageHeader: headerModel.setNav({
navTitle: '为您推荐'
}),
hotBrands: data.hot_brand_list,
browseBrands: data.browse_brand_list,
newBrands: data.new_brand_list
});
}).catch(next);
};
const selectNewSale = (req, res, next) => {
let params = _.assign({}, req.query);
... ... @@ -101,6 +128,47 @@ const selectNewSale = (req, res, next) => {
};
/**
* 新品到着----为您推荐
* Router: /product/new/recommend-shop.json
*/
const recommendShop = (req, res, next) => {
const channel = req.cookies._Channel;
const uid = req.user.uid;
newModel.recommendShops(uid, channel).then(data => {
res.json(data);
});
};
/**
* 获取上架新品
*/
const fetchNew = (req, res, next) => {
const uid = req.user.uid;
const channel = req.cookies._Channel;
delete req.query.uid;
delete req.query.channel;
newModel.reclist(uid, channel, req.query).then(data => {
return res.json(data);
}).catch(next);
};
const goodsFilter = (req, res, next) => {
const uid = req.user.uid;
const channel = req.cookies._Channel;
newModel.reclistFilter(uid, channel).then(result => {
res.render('search/filter', {
layout: false,
filter: result
});
}).catch(next);
};
/**
* 筛选
* @param {[object]} req
* @param {[object]} res
... ... @@ -121,9 +189,13 @@ let filter = (req, res, next) => {
module.exports = {
blkNewGoods,
newGoods,
newGoods, // TODO remove
_newGoods,
brands,
selectNewSale,
filter
selectNewSale, // TODO remove
filter, // TODO remove
recommendShop,
fetchNew,
goodsFilter
};
... ...
... ... @@ -16,6 +16,7 @@ const serviceAPI = global.yoho.ServiceAPI;
const api = global.yoho.API;
/**
* TODO: remove
* 商品搜索接口请求
* @param {[object]} params
* @return {[array]}
... ... @@ -66,6 +67,7 @@ const getNewFocus = (channel) => {
};
/**
* TODO remove
* 获取商品数据
*/
const getSearchData = (params) => {
... ... @@ -88,6 +90,7 @@ const getSearchData = (params) => {
};
/**
* TODO remove
* 获取筛选数据
* @param {[object]} params
* @return {[array]}
... ... @@ -103,8 +106,129 @@ const getFilterData = (params) => {
});
};
/**
* method=app.newproduct.recshop 推荐店铺
* http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/BigData/新品到着.md
*/
const recommendShops = (uid, channel, limit, page) => {
limit = limit || 20;
page = page || 1;
let params = {
method: 'app.newproduct.recshop',
channel,
limit,
page,
uid
};
return api.get('', params, {cache: true})
.then(result=> {
let shopData = _.get(result, 'data', {});
return shopData;
})
.catch(() => {});
};
/**
* method=app.newproduct.recbrand 推荐品牌
* http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/BigData/新品到着.md
*/
const recbrand = (uid, channel, limit, page) => {
limit = limit || 20;
page = page || 1;
let params = {
method: 'app.newproduct.recbrand',
channel,
limit,
page,
uid
};
return api.get('', params, {cache: true})
.then(result => {
let data = _.get(result, 'data', {});
return data;
})
.catch(() => {});
};
const newGoodsAPI = (params) => {
let method = 'app.newproduct.reclist';
// 排除基本筛选项默认值为0的对象
for (let str in params) {
if ((str !== 'order' && params[str] === '0') || params[str] === null) {
delete params[str];
}
}
params.yh_channel = searchProcess.getChannelType(params.channel);
delete params.channel;
params = _.assign({
limit: '60'
}, params);
params.order = params.order === '0' ? 's_t_desc' : 's_t_asc';
return api.get('', _.assign({
method: method
}, params), {
cache: true
});
};
/**
* method:app.newproduct.reclist 新品上架
* http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/BigData/新品到着.md
*/
const reclist = (uid, channel, searchOptions) => {
let params = Object.assign({}, {uid, channel}, searchOptions);
return newGoodsAPI(params).then(result => {
if (result && result.code === 200) {
let newList = {};
newList.list = productProcess.processProductList(result.data.product_list || [], {showTags: true});
if (parseInt(params.page, 10) === 1) {
newList.total = result.data.total;
}
return newList;
} else {
logger.error('get product search api return code is not 200');
return [];
}
});
};
const reclistFilter = (uid, channel) => {
let params = Object.assign({}, {uid, channel});
return newGoodsAPI(params).then(result => {
if (result && result.code === 200) {
return productProcess.processFilter(result.data.filter || []);
} else {
logger.error('get filter data api return code is not 200');
return [];
}
});
};
module.exports = {
getNewFocus,
getSearchData,
getFilterData
getSearchData, // TODO remove
getFilterData, // TODO remove
recommendShops,
recbrand,
reclist,
reclistFilter
};
... ...
... ... @@ -158,8 +158,12 @@ router.get('/list/new', news.newGoods); // 兼容 PC 的链接
router.get('/new/selectNewSale', news.selectNewSale);
router.get('/new/filter', news.filter);
router.get('/newnew', news._newGoods);
router.get('/new/brands', news.brands);
router.get('/newnew', news._newGoods); // TODO: repleace /new
router.get('/new/recommend-shop.json', news.recommendShop);
router.get('/new/goods.json', news.fetchNew);
router.get('/new/goods-filter', news.goodsFilter);
router.get('/new/shops', news.brands);
// 新品到着(blk)
router.get('/blknew', news.blkNewGoods);
... ...
<div class="new-brands">
<div class="recommend-brands">
{{!--浏览过的品牌--}}
{{> new/recommend-brands
title="浏览过的品牌"
}}
{{#if browseBrands}}
{{> new/recommend-brands
title="浏览过的品牌"
shops=browseBrands
}}
{{/if}}
{{!--热门品牌--}}
{{> new/recommend-brands title="热门品牌"}}
{{> new/recommend-brands
title="热门品牌"
shops=hotBrands
}}
{{!--新入驻品牌--}}
{{> new/recommend-brands title="新入驻品牌"}}
{{> new/recommend-brands
title="新入驻品牌"
style="new-brands"
shops=newBrands
}}
</div>
\ No newline at end of file
... ...
... ... @@ -17,15 +17,24 @@
</div>
{{!--为您推荐--}}
{{> 'new/recommend-brands'
style="new-recommend "
title="为您推荐"
more='/product/new/brands'
}}
<div id="new-recommend" class="new-recommend panel">
<header class="panel-header">
<h3>为您推荐</h3>
<a href="/product/new/shops" class="panel-header-r more">
<i class="iconfont more">&#xe606;</i>
</a>
</header>
<div class="panel-body"></div>
</div>
{{!--精选抢先看--}}
{{> 'new/handpick'}}
{{!--最新上架--}}
{{> 'new/goods'}}
{{> common/query-param}}
{{> common/suspend-home}}
{{> common/suspend-cart}}
</div>
\ No newline at end of file
... ...
{{!-- 商品列表中的 品牌上新--}}
<div class="good-info brand-info">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5 class="bname">这是一个品牌</h5>
<p class="summary">上新<span class="red">11</span>&nbsp;&nbsp;<span class="red">1111</span>人收藏</p>
<a href="#" class="entry">进入店铺</a>
</div>
\ No newline at end of file
{{!-- 新品到着: 最新上架--}}
<div>
<div id="new-goods">
<div>
{{> common/filter-nav}}
</div>
<div class="goods-container">
{{# goods}}
{{> common/goods}}
{{/ goods}}
{{> new/tags}}
{{> new/brand}}
{{> new/brand-recommend}}
{{> new/article}}
{{> common/filter}}
<div class="container" data-rel="new-0"></div>
<div class="container" data-rel="price-0"></div>
<div class="container" data-rel="price-1"></div>
<div class="container" data-rel="discount-0"></div>
<div class="container" data-rel="discount-1"></div>
<div class="container" data-rel="filter"></div>
<div id="js-filter"></div>
</div>
{{> common/query-param}}
... ...
{{!-- 新品到着: 为您推荐--}}
<div id="new-recommend" class="{{style}} panel">
<div id="{{id}}" class="{{style}} panel">
<header class="panel-header">
<h3>{{title}}</h3>
{{#more}}
... ... @@ -9,54 +9,6 @@
{{/more}}
</header>
<div class="panel-body">
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
<div class="brand-news-count">
<div class="brand-logo">
<img src="//img11.static.yhbimg.com/brandLogo/2016/08/16/16/01cfd27979a572e6d26018eebfcb6d3583.jpg?imageMogr2/thumbnail/120x120/extent/120x120/background/d2hpdGU=/position/center/quality/80" alt="">
<h5>品牌品牌</h5>
</div>
<div class="count">上新10款<i class="iconfont">&#xe604;</i></div>
</div>
{{> product/brands}}
</div>
</div>
\ No newline at end of file
... ...
<div class="good-info good-tags season-tags ">
<div>
<ul class="good-tags-list">
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
<li><a href="#" class="good-tag">夹克</a></li>
</ul>
</div>
</div>
\ No newline at end of file
... ... @@ -17,6 +17,7 @@ module.exports = {
assetUrl: '//127.0.0.1:5001',
testCode: 'yoho4946abcdef#$%&!@',
domains: {
api: 'http://api-test2.yohops.com:9999/',
// api: 'http://api-test3.yohops.com:9999/',
// service: 'http://service-test3.yohops.com:9999/',
// liveApi: 'http://testapi.live.yohops.com:9999/',
... ... @@ -25,7 +26,7 @@ module.exports = {
// imCs: 'http://im.yohobuy.com/api',
// imServer: 'http://im.yohobuy.com/server'
// api: 'http://192.168.102.205:8080/gateway/',
api: 'http://api.yoho.cn/',
// api: 'http://api.yoho.cn/',
service: 'http://service.yoho.cn/',
liveApi: 'http://api.live.yoho.cn/',
singleApi: 'http://single.yoho.cn/',
... ... @@ -76,7 +77,7 @@ module.exports = {
port: '4444' // influxdb port
},
console: {
level: 'info',
level: 'debug',
colorize: 'all',
prettyPrint: true
}
... ...
{{!--新品到着 品牌推荐--}}
{{#each shops}}
<div class="brand-news-count">
<div class="brand-logo">
<img src="{{image shop_logo 186 115}}" alt="{{shop_domain}}">
<h5>{{shop_name}}</h5>
</div>
<div class="count">上新{{new_product_num}}<i class="iconfont">&#xe604;</i></div>
<a class="link" href="http://m.yohobuy.com/product/index/brand?domain={{shop_domain}}"></a>
</div>
{{/each}}
\ No newline at end of file
... ...
{{> product/brands}}
\ No newline at end of file
... ...
{{# goods}}
{{#if _isFashionArticle}}
{{#with this.data}}
{{> guang-article}}
{{/with}}
{{else if _isSeasonSort}}
{{#with this.data}}
{{> search-tag kind="season-tags" tags=this}}
{{/with}}
{{else if _isHotShop}}
{{#with this.data}}
{{> hot-shop}}
{{/with}}
{{else if _isHotSearchTerm}}
{{#with this.data}}
{{> search-tag kind="search-tags" tags=this}}
{{/with}}
{{else}}
{{> common/goods}}
{{/if}}
{{/ goods}}
\ No newline at end of file
... ...
<div class="good-info">
<div class="guang-article">
<div class="cate tip">潮品</div>
<img src="//img13.static.yhbimg.com/article/2016/12/28/09/024949cb26c998cb9fccd2e0819e1a9e43.jpg?imageView2/2/w/640/h/640/q/60" alt="">
<img src="{{image src 322 214 1}}" alt="">
<div class="footer">
<p class="digest">Supreme这个牌子有什么超魔力为什么玩潮女生都爱穿它?</p>
<p class="digest">{{title}}</p>
<div class="meta clearfix">
<div class="pull-left">
<i class="iconfont">&#xe603;</i>&nbsp;<span>12月27日 13:05</span>
<i class="iconfont">&#xe603;</i>&nbsp;<span>{{publish_time}}</span>
</div>
<div class="pull-right">
<i class="iconfont">&#xe602;</i>&nbsp;<span>26789</span>
<i class="iconfont">&#xe602;</i>&nbsp;<span>{{praise_num}}</span>
</div>
</div>
</div>
... ...
{{!-- 商品列表中的 品牌上新--}}
<div class="good-info brand-info">
<img src="{{image shop_logo 240 100}}" alt="{{shop_name}}">
<h5 class="bname">{{shop_name}}</h5>
<p class="summary">上新<span class="red">{{new_product_num}}</span>&nbsp;&nbsp;<span class="red">{{favorite_num}}</span>人收藏</p>
<a href="//m.yohobuy.com/product/index/brand?domain={{shop_domain}}" class="entry">进入店铺</a>
</div>
\ No newline at end of file
... ...
{{!--
描述: 商品列表里的 特殊goods-info
@param kind
season-tags 应季热门
search-tags 热门搜索
brand-tags 热门品牌 【已废除】
@param tags ul 的数据
--}}
<div class="good-info good-tags {{kind}} ">
<div>
<ul class="good-tags-list">
{{#each tags}}
{{> (lookup .. 'kind')}}
{{/each}}
</ul>
</div>
</div>
{{#*inline 'season-tags'}}
{{!--
TODO: 如果要搜索品类,修改这里,目前是query查询
--}}
<li>
<a href="//search.m.yohobuy.com/?query={{encodeURIComponent categoryName}}&from=search" class="good-tag">{{categoryName}}</a>
</li>
{{/inline}}
{{#*inline 'search-tags'}}
<li>
<a href="//search.m.yohobuy.com/?query={{encodeURIComponent .}}&from=search" class="good-tag">{{.}}</a>
</li>
{{/inline}}
\ No newline at end of file
... ...
module.exports = (str) => {
return encodeURIComponent(str);
};
\ No newline at end of file
... ...
/**
* 四舍五入
* @param {[type]} num 数字
* @param {[type]} precision 精度
* @return {[type]}
*/
module.exports = (num, precision) => {
precision = precision || 2;
num = Number(num).toFixed(precision);
return num;
};
... ...
'use strict';
require('product/new-arrival.page.css');
require('common');
require('common/suspend-cart');
let Swiper = require('yoho-swiper');
let lazyLoad = require('yoho-jquery-lazyload');
var mySwiper = new Swiper('.handpick-swiper', {
let filter = require('plugin/filter');
let mySwiper = new Swiper('.handpick-swiper', {
// Optional parameters
loop: true,
... ... @@ -14,3 +18,97 @@ var mySwiper = new Swiper('.handpick-swiper', {
spaceBetween: 30,
pagination: '.swiper-pagination',
});
// ==============================================
// function: 为您推荐
let recommendShops = function() {
let $container = $('#new-recommend');
let fetchURI = '/product/new/recommend-shop.json';
let template = require('product/new/brands.hbs');
// 渲染模版并插入
function render(shops) {
let html = template({shops});
$container.find('.panel-body').append(html);
}
$.get(fetchURI).done(shopData => {
render(shopData.shop_list || []);
});
};
recommendShops();
// ==============================================
let searchView = function() {
let $c = $('#new-goods');
let $nav = $c.find('filter-nav');
let $goodsBox = $c.find('.goods-container');
let $prevNav = null;
let goodsT = require('product/new/goods.hbs');
// 给nav 设置 数据属性
$nav.children('.new').data('order', ['new', '0']); // 从新到旧
$nav.children('.price').data('order', ['price', '1']); // 从低到高
$nav.children('.discount').data('order', ['discount', '0']); // 折扣从大到小
function initFilter() {
$.get('/product/new/goods-filter').done(filterHtml => {
$('#js-filter').replaceWith(filterHtml);
filter.initFilter({
fCbFn: $.noop,
hCbFn: $.noop
});
});
}
function switchNav($nextNav) {
}
function renderGoods($container, data) {
let html = goodsT({
goods: data
});
$container.append(html);
lazyLoad($container.find('.lazy'));
}
// search state
function fetchNew(searchParams) {
return $.get('/product/new/goods.json', searchParams)
.then(data => {
console.log(data);
renderGoods($('.goods-container'), data.list);
});
}
$nav.on('click', 'li', function(event) {
let $curNav = $(event.target);
switchNav($curNav);
});
initFilter();
return {
fetchNew,
switchNav
};
};
window.search = searchView();
window.$ = $;
... ...
... ... @@ -2,3 +2,4 @@
* 新品到着---品牌推荐
*/
require('product/new-brands.page.css');
require('common');
... ...
... ... @@ -31,6 +31,10 @@ body {
}
}
.new-recommend .panel-body {
min-height: 193px;
}
.filter-nav {
border-top: 1PX solid #dededf;
border-bottom: 1PX solid #dededf;
... ...
... ... @@ -5,7 +5,7 @@
background-color: #f0f0f0;
}
.new-brands {
.recommend-brands {
.panel-header {
border-bottom: none;
}
... ... @@ -25,4 +25,8 @@
height: auto;
}
}
}
.new-brands .brand-news-count .count{
display: none;
}
\ No newline at end of file
... ...
... ... @@ -6,6 +6,7 @@
}
.brand-news-count {
position: relative;
display: inline-block;
color: #fff;
text-align: center;
... ... @@ -21,6 +22,9 @@
margin-bottom: 25px;
h5 {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: #b8b8b8;
}
}
... ... @@ -39,4 +43,12 @@
font-size: inherit;
}
}
.link {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
\ No newline at end of file
... ...
... ... @@ -79,7 +79,29 @@ exports.processProductList = (list, options) => {
}
// 商品信息有问题,则不显示
if (!product.product_id || !product.goods_list || product.goods_list.length === 0) {
if (!(
(product.product_id && _.get(product, 'goods_list.length', 0)) || product.recommend_type
)) {
return;
}
if (product.recommend_type) {
// recommend_type 对应 附加属性
let flagMap = {
fashionArticle: '_isFashionArticle',
seasonSort: '_isSeasonSort',
hotShop: '_isHotShop',
hotSearchTerm: '_isHotSearchTerm',
};
let extraAttr = flagMap[product.recommend_type];
if (extraAttr) {
product[extraAttr] = true;
pruductList.push(product);
}
return;
}
... ...