Authored by ccbikai(👎🏻🍜)

Merge remote-tracking branch 'origin/feature/new-goods' into release/5.4

Showing 55 changed files with 2186 additions and 20 deletions
... ... @@ -7,11 +7,13 @@ const mRoot = '../models';
const listModel = require(`${mRoot}/list`);
const searchModel = require(`${mRoot}/search`);
const redsShopModel = require(`${mRoot}/popular-shop`);
const headerModel = require('../../../doraemon/models/header');
const _ = require('lodash');
const helpers = global.yoho.helpers;
const productProcess = require(`${utils}/product-process`);
const shop = {
index(req, res, next) {
let params = Object.assign({}, req.query);
... ... @@ -298,6 +300,38 @@ const shop = {
_noLazy: true
});
}).catch(next);
},
/**
* 红人店铺
*/
redShop(req, res, next) {
let shopId = 34; // test
Promise.all([
redsShopModel.getBanner(shopId), // 0: 获取红人店 banner
redsShopModel.getShopsBrands(shopId), // 1: 获取店铺品牌数据
redsShopModel.getIntro(shopId), // 2. 获取店铺介绍
redsShopModel.getShopsdecorator(shopId) // 3. 获取店铺装修元素
]).then(valArr => {
let banner = _.get(valArr[0], 'data.banner');
let brand = _.get(valArr[1], 'data[0]', {});
let introData = valArr[2];
let decoratorsData = valArr[3];
res.render('newshop/shop-reds', {
width750: true,
localCss: true,
module: 'product',
page: 'reds-shop',
shopId,
banner, brand, introData, decoratorsData,
time3: [0, 1, 2]
});
});
}
};
... ...
... ... @@ -33,7 +33,7 @@ const blkNewGoods = (req, res) => {
// 新品到着
const newGoods = (req, res, next) => {
let channel = req.cookies._Channel;
let channel = req.yoho.channel;
newModel.getNewFocus(channel).then((result) => {
res.render('new/new', {
... ... @@ -60,6 +60,74 @@ const newGoods = (req, res, next) => {
}).catch(next);
};
const _newGoods = (req, res, next) => {
const channel = req.yoho.channel;
const uid = req.user.uid;
newModel.indexData(uid, channel).then(result => {
let shopList = _.get(result, 'shop_list', []);
let banner = _.get(result, 'ads[0]', {});
let handPick = _.get(result, 'ads[1]', {});
// console.log(handPick)
res.render('new/index', {
module: 'product',
page: 'new-arrival',
width750: true,
localCss: true,
pageHeader: headerModel.setNav({
navTitle: '新品到着'
}),
cartUrl: helpers.urlFormat('/cart/index/index', null),
pageFooter: true,
showDownloadApp: true,
// 资源位
shopList,
banner,
handPick,
// 搜索参数,貌似没用到
brand: '0',
sort: '0',
gender: req.query.gender || searchProcess.getGenderByChannel(channel),
channel,
price: '0',
size: '0',
dayLimit: 1,
discount: ''
});
}).catch(next);
};
/**
* 新品到着 落地页: 为您推荐
*/
const brands = (req, res, next) => {
const channel = req.yoho.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);
... ... @@ -77,6 +145,49 @@ const selectNewSale = (req, res, next) => {
};
/**
* 新品到着----为您推荐
* Router: /product/new/recommend-shop.json
*/
const recommendShop = (req, res, next) => {
const channel = req.yoho.channel;
const uid = req.user.uid;
console.log(channel)
newModel.recommendShops(uid, channel).then(data => {
res.json(data);
});
};
/**
* 获取上架新品
*/
const fetchNew = (req, res, next) => {
const uid = req.user.uid;
const channel = req.yoho.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.yoho.channel;
newModel.reclistFilter(uid, channel).then(result => {
res.render('search/filter', {
layout: false,
filter: result
});
}).catch(next);
};
/**
* 筛选
* @param {[object]} req
* @param {[object]} res
... ... @@ -97,7 +208,13 @@ let filter = (req, res, next) => {
module.exports = {
blkNewGoods,
newGoods,
selectNewSale,
filter
newGoods, // TODO remove
_newGoods,
brands,
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,133 @@ const getFilterData = (params) => {
});
};
/**
* method=app.newproduct.recshop 推荐店铺
* http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/BigData/新品到着.md
*/
const indexData = (uid, channel, limit, page) => {
let yh_channel = searchProcess.getChannelType(channel);
limit = limit || 20;
page = page || 1;
let params = {
method: 'app.newproduct.recshop',
yh_channel,
contentCode: contentCode.newV2[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) => {
let yh_channel = searchProcess.getChannelType(channel);
limit = limit || 20;
page = page || 1;
let params = {
method: 'app.newproduct.recbrand',
yh_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);
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;
newList.pageTotal = result.data.page_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
indexData,
recbrand,
reclist,
reclistFilter
};
... ...
/**
* desc: 店铺装修----红人店铺
*/
'use strict';
const api = global.yoho.API;
/**
* 获取红人店铺 banner
* doc: http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/商品列表/店铺装修.md
* @param int shopId 店铺id
*/
exports.getBanner = shopId => {
let params = {
// method: 'app.popular.shop.banner',
method: 'app.shop.banner', //TODO: this is mock api,use up
shop_id: shopId,
app_type: 0 // 0 有货 1 blk
};
return api.get('', params, {cache: true, code: 200});
};
/**
* 获取店铺 品牌数据
* @param int shopId 店铺id
*/
exports.getShopsBrands = shopId => {
let params = {
method: 'app.shops.getShopsBrands',
shop_id: shopId
};
return api.get('', params, {cache: true, code: 200});
};
/**
* 获取店铺 介绍
* @param int shopId 店铺id
*/
exports.getIntro = shopId => {
let params = {
// method: 'app.popular.shops.getIntro',
method: 'app.shops.getIntro',
shop_id: shopId,
app_type: 0
};
return api.get('', params, {cache: true, code: 200});
};
/**
* 查询红人店铺对应的装修元素
*
* @param int shopId 店铺id
*/
exports.getShopsdecorator = shopId => {
let params = {
method: 'app.popular.shopsdecorator',
shop_id: shopId,
app_type: 0
};
return api.get('', params, {cache: true, code: 200});
};
... ...
... ... @@ -145,6 +145,8 @@ router.get('/index/baseShopFav', newShop.baseShopFav);
router.get('/index/brandFav', newShop.brandFav);
router.get('/new/shop/hotlist', newShop.shopHotList);
router.get('/red_shop', newShop.redShop); // TODO,TODO,TODO,TODO
// end- 店铺重构
// 店铺介绍
... ... @@ -159,6 +161,13 @@ router.get('/list/new', news.newGoods); // 兼容 PC 的链接
router.get('/new/selectNewSale', news.selectNewSale);
router.get('/new/filter', news.filter);
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="recommend-brands">
{{!--浏览过的品牌--}}
{{#if browseBrands}}
{{> new/recommend-brands
title="浏览过的品牌"
shops=browseBrands
}}
{{/if}}
{{!--热门品牌--}}
{{> new/recommend-brands
title="热门品牌"
shops=hotBrands
}}
{{!--新入驻品牌--}}
{{> new/recommend-brands
title="新入驻品牌"
style="new-brands"
shops=newBrands
}}
</div>
\ No newline at end of file
... ...
{{!--新品到着--}}
<div>
{{!--top banner--}}
{{#if banner}}
<div class="banner-top">
<div class="banner-swiper swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
{{#each banner.data}}
<div class="swiper-slide">
<a href="{{url}}">
<img class="banner-top-pic swiper-lazy" data-src="{{image2 src w=750 h=234 q=60}}" alt="">
</a>
</div>
{{/each}}
</div>
<div class="swiper-pagination-s1">
<div id="banner-pagination" class="pagination-inner"></div>
</div>
</div>
</div>
{{/if}}
{{!--为您推荐--}}
{{#if shopList}}
<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">
{{> product/brands shops=shopList}}
</div>
</div>
{{/if}}
{{!--精选抢先看--}}
{{#if handPick.data}}
{{> 'new/handpick' swiper=handPick.data}}
{{/if}}
{{!--最新上架--}}
{{> 'new/goods'}}
{{> common/query-param}}
{{> common/suspend-home}}
{{> common/suspend-cart}}
</div>
\ No newline at end of file
... ...
{{!--
desc: 红人店铺
--}}
<input type="hidden" name="shop-id" class="shop-id" value="{{shopId}}">
<div class="reds-shop">
{{!--shop-header--}}
<div class="shop-header brand-header" data-id="{{brand.brand_id}}">
<img class="banner" {{#if banner}} src="{{image banner 750 234}}"{{/if}} alt="banner">
<div class="shop-info">
<img class="logo" src="{{image brand.brand_ico 120 120}}" alt="logo">
<div class="shop-info-base">
<h1 class="shopname">{{brand.brand_name}}</h1>
<div class="favs">粉丝数: 534 <i class="iconfont favs-btn like">&#xe605;</i></div>
</div>
<div class="shop-intro">
<div class="line-clamp-2">这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍这里是介绍</div>
<div class="shop-intro-folder">
<i class="iconfont">&#xe616;</i>
</div>
</div>
</div>
</div>
{{!--shop-tab-nav: 红人首页 | 全部商品--}}
<div class="tab">
<ul class="shop-tabs tab-navs" data-sticky>
<li class="shop-tab-nav tab-nav active">
<a href="#red-index" data-trigger="tab">红人首页</a>
</li>
<em>|</em>
<li class="shop-tab-nav tab-nav">
<a href="#all-goods" data-trigger="tab">全部商品</a>
</li>
</ul>
<div class="tab-panels">
{{!--shop-tab: 红人首页--}}
<div id="red-index" class="tab-panel active">
<div class="shop-coupon coupon-group"></div>
{{!--<div class="shop-coupon coupon-content">
{{#each time3}}
<div class="coupon-small">
<div class="coupon-left">
<span class="coupon-left-price">
<span class="coupon-sign">¥</span>
<span class="coupon-price">88</span>
</span>
<span class="coupon-left-name">
VANS圣诞礼券:满588减88
</span>
</div>
<div class="coupon-right receive-btn">
立即领取
</div>
</div>
{{/each}}
</div>--}}
<div class="shop-swiper">
</div>
{{!--视屏--}}
<div class="shop-video shop-section">
<header>
<i class="section-more iconfont">&#xe606;</i>
<h4 class="section-title">视屏直播</h4>
</header>
<div class="video-player">
<div class="video-poster">
<div class="video-meta-customers">
<i class="iconfont">&#xe602;</i>&nbsp;&nbsp;<span>13145</span>
</div>
</div>
</div>
<div class="video-intro">
<h6 class="video-title">这是视屏标题</h6>
<p class="text-line-2">这是视屏内容这是视屏内容这是视屏内容这是视屏内容这是视屏内容这是视屏内容这是视屏内容这是视屏内容</p>
</div>
</div>
{{!--人气单品--}}
<div class="shop-hot shop-section">
<header>
{{!--<i class="section-more iconfont">&#xe606;</i>--}}
<h4 class="section-title">人气单品</h4>
</header>
<div class="section-content">
<div class="items-s1">
{{> item}}
</div>
<div class="items-s2">
{{> item}}
</div>
{{!--风格: 3图2列, 大图 在左--}}
<div class="items-3-2 items-3-2-left">
{{#each time3}}
{{> item}}
{{/each}}
</div>
</div>
{{!--风格: 3图2列, 大图 在右--}}
<div class="items-3-2 items-3-2-right">
{{#each time3}}
{{> item}}
{{/each}}
</div>
<div class="shop-item-div"></div>
<div class="items-s1">
{{> item}}
</div>
{{!--风格: 3图 3列--}}
<div class="items-3-3">
{{#each time3}}
{{> item}}
{{/each}}
</div>
<div class="items-c2">
{{#each time3}}
{{> item}}
{{/each}}
</div>
{{!--风格: 3图 3列--}}
<div class="items-3-3 items-small">
{{#each time3}}
{{> item}}
{{/each}}
{{#each time3}}
{{> item}}
{{/each}}
</div>
</div>
</div>
{{!--shop-tab: 全部商品--}}
<div id="all-goods" class="tab-panel"></div>
</div>
</div>
</div>
{{#*inline 'item'}}
<div class="item">
<img class="item-pic" src="http://img1.gamersky.com/image2016/12/20161224_zl_91_3/gamersky_02origin_03_201612241718D33.jpg" alt="">
<div class="item-info">
<div class="">
ABCDEFG ABCDEFG
</div>
<div>
<span class="new-price">¥ 199.00</span>
<span class="price">¥ 299.00</span>
</div>
</div>
</div>
{{/inline}}
\ No newline at end of file
... ...
{{!-- 新品到着: 最新上架--}}
<div id="new-goods">
<div class="filter-nav-wrap" data-sticky>
{{> common/filter-nav}}
<div id="js-filter"></div>
</div>
<div class="goods-container">
<div class="goods-box"></div>
{{!--
<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>
{{> common/query-param}}
</div>
\ No newline at end of file
... ...
{{!-- 新品到着: 精选 --}}
<div id="handpick" class="panel handpick">
<header class="panel-header">
<h4>精选抢先看</h4>
{{!--<a href="#javascript" class="panel-header-r more">
<i class="iconfont">&#xe606;</i>
</a>--}}
</header>
<main class="panel-body">
<!-- Slider main container -->
<div class="handpick-swiper swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
{{#each swiper}}
<div class="swiper-slide">
<a href="{{url}}">
<img class="swiper-lazy" data-src="{{image2 src w=332 h=194 q=60}}" alt="">
</a>
</div>
{{/each}}
</div>
</div>
</main>
</div>
\ No newline at end of file
... ...
{{!-- 新品到着: 为您推荐--}}
<div id="{{id}}" class="{{style}} panel">
<header class="panel-header">
<h3>{{title}}</h3>
{{#more}}
<a href="{{.}}" class="panel-header-r more">
<i class="iconfont more">&#xe606;</i>
</a>
{{/more}}
</header>
<div class="panel-body">
{{> product/brands}}
</div>
</div>
\ No newline at end of file
... ...
<div class="item">
<img class="item-pic" src="http://img1.gamersky.com/image2016/12/20161224_zl_91_3/gamersky_02origin_03_201612241718D33.jpg" alt="">
<div class="item-info">
<div class="">
ABCDEFG ABCDEFG
</div>
<div>
<span class="new-price">¥ 199.00</span>
<span class="price">¥ 299.00</span>
</div>
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -32,6 +32,7 @@ module.exports = {
// imSocket: 'wss://imsocket.yohobuy.com:443',
// imCs: 'https://imhttp.yohobuy.com/api',
// imServer: 'https://imhttp.yohobuy.com/server'
},
subDomains: {
host: '.m.yohobuy.com',
... ... @@ -76,7 +77,7 @@ module.exports = {
port: '4444' // influxdb port
},
console: {
level: 'info',
level: 'debug',
colorize: 'all',
prettyPrint: true
}
... ...
... ... @@ -49,6 +49,7 @@ const bottomBannerContentCode = {
const outletContentCode = 'c19ffa03f053f4cac3690b22c8da26b7';
// TODO: remove
const newContentCode = {
boys: '3cf2c1be5217fbab6009ce83959e1e12',
girls: '1cf7f9f10e2a2670e73d05c568793ad9',
... ... @@ -56,6 +57,13 @@ const newContentCode = {
lifestyle: '04953a61cbf1db426a681e55d496d2fe'
};
const newContentCodeV2 = {
boys: '1f2e07cb63811680154ba693c954dd62',
girls: '375f201d1ec56f7515509249c9c66959',
kids: '74c62151673e7dde9fb154c90dcff3f0',
lifestyle: 'b9b4bd0de670f982e1f8e7dc23980e81'
};
const liveContentCode = {
index: '345c80537dca15611f37ae4863004bfe'
};
... ... @@ -66,6 +74,7 @@ module.exports = {
channel: channelContentCode,
bottom: bottomBannerContentCode,
guang: guangContentCode,
new: newContentCode,
new: newContentCode, // TODO: remove
newV2: newContentCodeV2,
live: liveContentCode
};
... ...
<div class='list-nav-layer'>
<ul id="list-nav" class="list-nav clearfix">
<li class="default active first-li-more">
<ul id="list-nav" class="list-nav filter-nav clearfix">
<li class="default active first-li-more" data-order="s_t_desc">
<a href="javascript:void(0);">
<span class="span-test">默认</span>
<span class="iconfont up cur hide">&#xe615;</span>
... ... @@ -11,8 +11,8 @@
<a href="javascript:void(0);">
<span class="span-test">价格</span>
<span class="icon">
<i class="iconfont up cur">&#xe615;</i>
<i class="iconfont down">&#xe616;</i>
<i class="iconfont up cur" data-order="s_p_asc">&#xe615;</i>
<i class="iconfont down" data-order="s_p_desc">&#xe616;</i>
</span>
</a>
</li>
... ... @@ -20,8 +20,8 @@
<a href="javascript:void(0);">
<span class="span-test">折扣</span>
<span class="icon">
<i class="iconfont up cur">&#xe615;</i>
<i class="iconfont down">&#xe616;</i>
<i class="iconfont up cur" data-order="p_d_asc">&#xe615;</i>
<i class="iconfont down" data-order="p_d_desc">&#xe616;</i>
</span>
</a>
</li>
... ... @@ -35,5 +35,3 @@
<!--搜索默认排序列表-->
{{> product/search-default-sort-list}}
</div>
... ...
{{!--新品到着 品牌推荐--}}
{{#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">
<a href="{{url}}">
{{guangType category_id}}
<img src="{{image src 322 214 1}}" alt="">
<div class="footer">
<p class="digest">{{title}}</p>
<div class="meta clearfix">
<div class="pull-left">
<i class="iconfont">&#xe603;</i>&nbsp;<span>{{publish_time}}</span>
</div>
<div class="pull-right">
<i class="iconfont">&#xe602;</i>&nbsp;<span>{{praise_num}}</span>
</div>
</div>
</div>
</a>
</div>
</div>
\ No newline at end of file
... ...
let Handlebars = require('handlebars');
module.exports = guangType => {
let html = '';
switch(guangType) {
case '1':
html = '<div class="cate topic">话题</div>';
break;
case '2':
html = '<div class="cate collocation">搭配</div>';
break;
case '3':
html = '<div class="cate fashion-man">潮人</div>';
break;
case '4':
html = '<div class="cate fashion-good">潮品</div>';
break;
case '5':
html = '<div class="cate tip">小贴士</div>';
break;
case '19':
html = '<div class="cate tip">专题</div>';
break;
}
return new Handlebars.SafeString(html);
};
\ No newline at end of file
... ...
<div class="good-info brand-recommend">
<img src="" alt="">
<div class="footer">
<div class="brand-name">品牌名</div>
<h5 class="good-name">这是商品名称</h5>
<div class="price">
<span class="sale-price">¥ 799.00</span>
</div>
</div>
</div>
\ No newline at end of file
... ...
{{!-- 商品列表中的 品牌上新--}}
<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;
};
... ...
/**
* Module: sticky
* Desc: 滚动固定
* @author: xuan.chen@yoho.cn
*/
'use strict';
const dataAPI = '[data-sticky]';
var Sticky = function(elem, options) {
this.options = $.extend({}, Sticky.DEAFAULT, options);
this.$elem = $(elem);
this.$holder = $('<div></div>').height(this.$elem.height());
this.$holder = this.$elem.wrap(this.$holder).parent();
this.stickyState = null;
this.$target = $(this.options.target)
.on('scroll.yoho.sticky', $.proxy(this.checkPosition, this));
this.checkPosition();
};
Sticky.DEAFAULT = {
top: 0, // offset top, 距离附着元素的位移
target: window // 附着元素
};
Sticky.prototype.checkPosition = function() {
let options = this.options;
if (!this.$elem.is(':visible')) {
return;
}
let offsetTop = this.$holder.offset().top - options.top;
let scrollTop = this.$target.scrollTop();
let willSticky = scrollTop >= offsetTop;
this.$elem.toggleClass('sticky', willSticky);
};
function Plugin(option) {
this.each(function() {
let $this = $(this);
let data = $this.data('yoho.sticky');
let options = typeof option === 'object' && option;
if (!data) {
$this.data('yoho.sticky', new Sticky($this, options));
}
if (typeof option === 'string') {
$this[option]();
}
});
}
$.fn.Stricky = Plugin;
$.fn.Stricky.Constructor = Sticky;
window.onload = function() {
$(dataAPI).each(function() {
let $this = $(this);
Plugin.call($this);
});
};
module.exports = Sticky;
... ...
/**
* Module: tab.js
*
* markup:
* <div class="tab">
* <ul class="tab-navs">
* <li class="tab-nav active">
* <a href="javascript:;" data-trigger="tab" data-target="#a"></a>
* </li>
* <li class="tab-nav">
* <a href="javascript:;" data-trigger="tab" data-target="#b"></a>
* </li>
* </ul>
* <div class="tab-panels">
* <div id="a" class="tab-panel">
* </div id="b" class="tab-panel">
* </div>
* </div>
*/
var Tab = function(elem) {
this.$elem = $(elem);
};
Tab.prototype.show = function() {
var $nav = this.$elem;
var targetSelector = (function(elem) {
var selector = elem.dataset.target;
if (!selector) {
selector = elem.getAttribute('href') || '';
selector = /^#[a-z]/i.test(selector) ? selector : null;
}
return selector;
}($nav[0]));
var $target = $(targetSelector);
if ($nav.hasClass('active')) {
return;
}
function active($elem, $parent) {
$parent.children('.active').removeClass('active');
$elem.addClass('active');
}
active($nav.parent('.tab-nav'), $nav.closest('.tab-navs'));
active($target, $target.closest('.tab-panels'));
};
function Plugin(option) {
this.each(function() {
var $this = $(this);
var data = $this.data('yoho.tab');
var options = typeof option === 'object' && option;
if (!data) {
$this.data('yoho.tab', (data = new Tab(this, options)));
}
if (typeof option === 'string') {
data[option]();
}
});
}
$.fn.yoTab = Plugin;
$.fn.yoTab.constructor = Tab;
$(document).on('click', '[data-trigger=tab]', function(event) {
event.preventDefault();
event.stopPropagation();
var $nav = $(event.target);
Plugin.call($nav, 'show');
});
... ...
'use strict';
require('product/new-arrival.page.css');
require('common');
require('common/suspend-cart');
require('plugin/sticky');
let Swiper = require('yoho-swiper');
let lazyLoad = require('yoho-jquery-lazyload');
let filter = require('plugin/filter');
new Swiper('.handpick-swiper', {
// Optional parameters
lazyLoading: true,
lazyLoadingInPrevNext: true,
loop: true,
// If we need pagination
slidesPerView: 'auto',
centeredSlides: true,
paginationClickable: true,
spaceBetween: 30,
});
new Swiper('.banner-swiper', {
lazyLoading: true,
// If we need pagination
centeredSlides: true,
paginationClickable: true,
pagination: (function() {
if ($('.banner-swiper').find('.swiper-slide').length > 1) {
return '#banner-pagination';
} else {
$('#banner-pagination').hide();
return null;
}
}()),
});
// ==============================================
// 1 滚动: 搜索参数不变, 追加数据
// 2 筛选,切换排序: 重新搜索
//
let searchView = function() {
let body = document.body;
let $c = $('#new-goods');
let $navBox = $c.find('.filter-nav');
let $goodsWraper = $c.find('.goods-container');
let goodsT = require('product/new/goods.hbs');
let $loading = $('<div class="yo-loading"></div>');
let $prevNav = $navBox.children('.new');
let $goodBox = $goodsWraper.children('.goods-box');
let fetchXhr = null;
/**
* 搜索 参数
* Note:filter 没有重置功能
* see: search-process.js
*/
let searchParams = {
order: 's_t_desc',
filter: {
},
page: {
cur: 0,
total: null
}
};
function initFilter() {
return $.get('/product/new/goods-filter').done(filterHtml => {
$('#js-filter').html(filterHtml);
filter.initFilter({
/**
* filterObj:
* {filtering, id, type}
*/
fCbFn: function(filterObj) {
let filterKey = filterObj.type;
// 字段正规化
let normalizeKey = ({
ageLevel: 'age_level'
// TODO: 哪些字段不正规,添加再这里
})[filterKey];
normalizeKey && (filterKey = normalizeKey);
// 放入查询参数
searchParams.filter[filterKey] = filterObj.id;
console.log(searchParams);
fetchNew({ // eslint-disable-line
$box: $goodBox,
before: $box => {
fetchXhr.abort();
$box.html('');
}
});
},
hCbFn: function() {
// hide filter ,switch prev nav;
$navBox.children('.filter').removeClass('active');
$prevNav.addClass('active');
}
});
});
}
/**
* 切换nav
*/
function switchNav($nextNav) {
let _$prevNav = $navBox.children('.active'); // 当前active nav
// active 不是filter, 都暂存起来,filter hide的时候用到
if (!_$prevNav.hasClass('filter')) {
$prevNav = _$prevNav;
}
// 点击的nav 是filter nav
if ($nextNav.hasClass('filter')) {
let filterActived = $nextNav.hasClass('active');
filterActived ? filter.hideFilter() : filter.showFilter();
$prevNav.toggleClass('active', filterActived);
$nextNav.toggleClass('active', !filterActived);
return;
}
// 以下都是 order nav的情况, $prevNav始终是order nav;
filter.hideFilter();
if (!$prevNav.is($nextNav)) {
$prevNav.removeClass('active');
} else if ($nextNav.is('.price,.discount')) { // same && is price, discount
let $cur = $nextNav.find('.cur');
$cur.removeClass('cur').siblings().addClass('cur');
}
$nextNav.toggleClass('active', true);
return $nextNav;
}
/**
* order是否改变
* Note: filter的改变,有filter的回调处理
*/
function checkOrderChange($activeNav, changeAction) {
if (!$activeNav) {
return;
}
let order = $activeNav.data('order') || $activeNav.find('.cur').data('order');
searchParams.order = order;
changeAction();
}
function renderGoods($container, data) {
let html = goodsT({
goods: data
});
$container.append(html);
lazyLoad(html);
}
/**
* 搜索
* @param conf
* {
* $box: 数据塞入的容器,
* nextPage: true // 有该字段,且为true, 会去fetch 下一页数据
* before: 搜索之前的动作,第一个参数为 $box
* }
*/
function fetchNew(conf) {
let $box = conf.$box;
let page = {
cur: 0,
total: null
};
if (conf.nextPage) {
page = searchParams.page;
if (page.cur === page.total) { // no nore next
return;
}
}
conf.before && conf.before.apply(null, [$box]);
// search params
let data = {};
data.page = page.cur + 1; // fetch one page
data.order = searchParams.order;
$.extend(data, searchParams.filter);
$loading.appendTo($box);
return (fetchXhr = $.get('/product/new/goods.json', data))
.done(res => {
searchParams.page.total = res.pageTotal;
searchParams.page.cur = page.cur + 1;
renderGoods($box, res.list);
})
.always(() => {
$loading.remove();
});
}
/**
* 滚动到底部一定距离时, 加载下一页
*/
function fetchNextPage() {
fetchNew({
$box: $goodBox,
nextPage: true
});
}
initFilter()
.done(function() {
$navBox.on('click', 'li', function(event) {
let $curNav = $(event.currentTarget);
let $activeNav = switchNav($curNav);
checkOrderChange($activeNav, function() {
fetchNew({ // eslint-disable-line
$box: $goodBox,
before: $box => {
fetchXhr.abort();
$box.html('');
}
});
});
});
});
$(window).scroll(function() {
setTimeout(() => {
if (body.scrollHeight - (body.scrollTop + body.scrollWidth) < 300 && fetchXhr.readyState === 4) {
fetchNextPage();
}
}, 0);
});
fetchNew({
$box: $goodBox
});
return {
fetchNew,
switchNav
};
};
window.search = searchView();
window.filter = filter;
window.$ = $;
... ...
/**
* 新品到着---品牌推荐
*/
require('product/new-brands.page.css');
require('common');
... ...
require('product/shop/redshop.page.css');
require('plugin/sticky');
require('plugin/tab');
require('./shop/coupon');
... ...
.filter-nav {
background-color: #fff;
border-top: 2px solid #fff;
border-bottom: 1px solid #e6e6e6;
> li {
float: left;
width: 25%;
height: 66px;
line-height: 66px;
text-align: center;
font-size: 28px;
color: #999;
}
.bytouch {
background: #eee;
}
a {
display: inline-block;
box-sizing: border-box;
width: auto;
height: 100%;
color: #999;
}
.active > a {
color: #000;
box-sizing: border-box;
}
.active > .iconfont {
color: #000;
&.cur {
color: #000;
}
}
.filter .iconfont {
font-size: 24px;
transition: transform 0.1 ease-in;
}
.filter.active .iconfont {
transform: rotate(-180deg);
}
}
.filter-mask,
.filter-body {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 2;
}
.filter-mask {
... ...
... ... @@ -224,4 +224,5 @@
padding-top: 8px;
padding-left: 15px;
min-height: 880px;
background-color: #fff;
}
... ...
.panel {
margin-bottom: 25px;
background-color: #fff;
}
.panel-body {
padding-top: 30px;
padding-bottom: 30px;
border-bottom: 1PX solid #dededf;
}
.panel-header {
position: relative;
height: 84px;
line-height: 84px;
font-size: 34px;
font-weight: bold;
text-align: center;
color: #444;
border-top: 1PX solid #dededf;
border-bottom: 1PX solid #dededf;
.more {
color: #b0b0b0;
}
}
.panel-header-r {
position: absolute;
top: 0;
right: 30px;
}
\ No newline at end of file
... ...
... ... @@ -523,4 +523,36 @@
}
}
.swiper-pagination-s1 {
position: absolute;
left: 0;
right: 0;
bottom: 0.5rem;
text-align: center;
z-index: 1;
.pagination-inner {
display: inline-block;
padding: 0 0.2rem 0.1rem;
background: rgba(0, 0, 0, 0.2);
border-radius: 1.25rem;
}
.pagination-inner span {
display: inline-block;
width: 0.35rem;
height: 0.35rem;
background: #fff;
opacity: 0.5;
margin: 0 0.225rem;
border-radius: 50%
}
.pagination-inner span.swiper-pagination-bullet-active {
background: #fff;
opacity: 1;
}
}
/* stylelint-enable */
... ...
.tab-panel {
display: none;
&.active {
display: block;
}
}
\ No newline at end of file
... ...
.relative {
position: relative;
}
.text-left {
text-align: left;
}
... ... @@ -41,20 +45,20 @@
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical
-webkit-box-orient: vertical;
}
.vh-center {
text-align: center;
> *,
> *,
&:before {
display: inline-block;
vertical-align: middle;
}
&:before {
content: '';
content: "";
width: 0;
height: 100%;
line-height: 100%;
... ...
.yo-loading {
height: 80px;
background: resolve('loading.gif') #fff no-repeat center center;
background-size: 50px 20px;
}
.goods-container .yo-loading {
float: left;
width: 100%;
}
\ No newline at end of file
... ...
/* 新品到着 css */
@import '../layout/panel';
@import '../layout/swiper';
@import '../layout/yo-loading';
@import '../common/filter';
@import '../common/good';
@import 'new/recommend';
@import 'new/handlepick';
@import 'new/good-tags';
@import 'new/brand-info';
@import 'new/brand-recommend';
@import 'new/article';
body {
background-color: #f0f0f0;
}
.banner-swiper .swiper-slide {
height: 234px;
}
.swiper-slide img {
height: 100%;
width: 100%;
}
.goods-container {
overflow: hidden;
}
.good-info {
width: 325px;
height: 550px;
}
.new-recommend,
.handpick {
.panel-header {
border-bottom: none;
}
}
.new-recommend .panel-body {
min-height: 193px;
}
#js-filter {
position: relative;
}
.filter-nav-wrap.sticky {
position: fixed;
top: 0;
width: 100%;
z-index: 2;
}
.filter-nav {
border-top: 1PX solid #dededf;
border-bottom: 1PX solid #dededf;
}
.filter-nav .iconfont {
color: #999;
}
.filter-nav li > a{
position: relative;
}
.filter-nav .icon {
position: absolute;
top: 0;
bottom: 0;
left: 100%;
.up, .down {
position: absolute;
}
.up {
transform: translateY(-6px);
}
.down {
transform: translateY(6px);
}
}
.filter-nav .iconfont.cur {
color: inherit;
}
.banner-top {
border-bottom: 1PX solid #dededf;
margin-bottom: 30px;
}
.banner-top-pic {
height: 234px;
}
.brand-news-count h5 {
display: none;
}
\ No newline at end of file
... ...
@import '../layout/panel';
@import 'new/recommend';
.main-wrap {
background-color: #f0f0f0;
}
.recommend-brands {
.panel-header {
border-bottom: none;
}
.panel-body {
padding-left: 20px;
padding-right: 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.brand-news-count {
margin-top: 20px;
width: 32%;
img {
height: auto;
}
}
}
.new-brands .brand-news-count .count{
display: none;
}
\ No newline at end of file
... ...
.guang-article {
position: relative;
.cate {
position: absolute;
top: 0;
left: 0;
height: 40px;
line-height: 40px;
padding-left: 20px;
padding-right: 50px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
background-repeat: no-repeat;
background-position: top right;
background-size: 40px 40px;
font-size: 18px;
background-color: #000;
color: #fff;
&.collocation {
background-image: resolve('guang/info/collocation.png');
}
&.fashion-good {
background-image: resolve('guang/info/fashion-good.png');
}
&.fashion-man {
background-image: resolve('guang/info/fashion-man.png');
}
&.tip,
&.special-topic {
background-image: resolve('guang/info/tip.png');
}
&.topic {
background-image: resolve('guang/info/topic.png');
}
}
img {
width: 100%;
height: 215px;
}
.footer {
padding: 15px 20px 20px;
color: #fff;
background-color: #444;
}
.digest {
font-size: 23px;
}
.meta {
margin-top: 40px;
font-size: 17px;
.iconfont {
vertical-align: middle;
}
span {
vertical-align: middle;
}
}
}
\ No newline at end of file
... ...
.brand-info {
padding-top: 55px;
padding-bottom: 55px;
background-color: #f5f5f5;
text-align: center;
img {
width: 141px;
height: 66px;
}
.bname {
font-size: 18px;
color: #b0b0b0;
margin-top: 40px;
margin-bottom: 70px;
}
.summary {
font-size: 25px;
margin-bottom: 50px;
.red {
color: #e27b88;
}
}
.entry {
display: inline-block;
height: 50px;
padding-left: 19px;
padding-right: 19px;
line-height: 46px;
color: #444;
border: 2px solid #444;
border-radius: 5px;
}
}
... ...
.brand-recommend {
img {
height: 426px;
background-color: gray;
}
.footer {
position: relative;
height: 122px;
line-height: 1;
border-top: 1px solid transparent;
color: #fff;
background-color: #ff4333;
text-align: center;
}
.brand-name {
position: absolute;
top: -25px;
left: 50%;
transform: translateX(-50%);
min-width: 150px;
max-width: 60%;
height: 50px;
line-height: 50px;
padding-left: 20px;
padding-right: 20px;
background-color: #000;
color: #fff;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.good-name {
font-size: 20px;
margin-top: 40px;
margin-bottom: 15px;
}
.sale-price {
font-size: 20px;
}
}
\ No newline at end of file
... ...
.good-tags {
padding-top: 159px;
background-repeat: no-repeat;
background-size: 100% 159px;
&.season-tags {
background-image: url('/product/new/season-hot.jpg');
}
&.search-tags {
background-image: url('/product/new/hot-search.jpg');
}
&.brand-tags {
background-image: url('/product/new/brand-rec.jpg');
}
}
.good-tags-list {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-content: space-between;
height: 395px;
padding: 55px 0;
background-color: #f0f0f0;
li {
width: 50%;
text-align: center;
}
.good-tag {
display: inline-block;
height: 50px;
line-height: 50px;
width: 130px;
padding-left: 20px;
padding-right: 20px;
border-radius: 8px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
background-color: #fff;
font-size: 24px;
color: #808080;
}
}
\ No newline at end of file
... ...
/* 精选抢先看 */
.handpick {
.swiper-wrapper {
align-items: center;
}
.swiper-container {
height: 220px;
}
.swiper-slide {
width: 300px;
height: 173px;
background-color: #444;
border-radius: 6px;
overflow: hidden;
}
.swiper-slide-active {
height: 220px;
width: 378px;
}
}
\ No newline at end of file
... ...
.new-recommend {
.panel-body {
white-space: nowrap;
overflow: auto;
}
}
.brand-news-count {
position: relative;
display: inline-block;
color: #fff;
text-align: center;
width: 166px;
img {
max-width: 100%;
height: 68px;
margin-bottom: 25px;
}
.brand-logo {
margin-bottom: 25px;
h5 {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: #b8b8b8;
}
}
.count {
display: inline-block;
padding-left: 10px;
padding-right: 10px;
height: 30px;
line-height: 30px;
font-size: 18px;
border-radius: 32px;
background-color: #999;
.iconfont {
font-size: inherit;
}
}
.link {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
\ No newline at end of file
... ...
.shop-header {
.banner {
height: 234px;
}
}
.shop-info {
position: relative;
padding-right: 30px;
padding-left: 30px;
.logo {
position: absolute;
top: -40px;
width: 120px;
height: 120px;
box-shadow: 0 0 2px 1px #dedede;
}
.shopname {
font-size: 32px;
color: #444;
margin-left: 180px;
}
.favs-btn {
margin-left: 30px;
&.like {
color: #e33333;
}
}
}
.shop-info-base {
display: flex;
justify-content: space-between;
line-height: 1;
padding-top: 38px;
padding-bottom: 35px;
}
.shop-intro {
font-size: 28px;
color: #444;
}
.shop-intro-folder {
margin-top: 26px;
margin-bottom: 24px;
text-align: center;
font-size: 18px;
line-height: 1;
}
... ...
.shop-tabs {
display: flex;
justify-content: space-around;
width: 100%;
font-size: 30px;
line-height: 80px;
border-top: 1PX solid #dededf;
border-bottom: 1PX solid #dededf;
background-color: #fff;
em {
color: #dededf;
}
&.sticky {
z-index: 10;
}
}
.shop-tab-nav {
color: #dededf;
&.active {
color: #434241;
}
a {
color: inherit;
}
}
\ No newline at end of file
... ...
/*
红人首页
*/
.shop-section {
header {
font-size: 32px;
font-weight: bold;
color: #444;
line-height: 80px;
padding-right: 30px;
padding-left: 30px;
background-color: #f0f0f0;
}
.section-title {
text-align: center;
}
.section-more {
font-size: 40px;
color: #a9a9a9;
float: right;
}
}
.shop-coupon {
// padding-right: 30px;
background-color: #f0f0f0;
// white-space: nowrap;
/*.coupon-small {
float: none;
display: inline-block !important;
white-space: normal;
}
&::-webkit-scrollbar {
display: none;
}*/
}
.shop-swiper {
height: 234px;
}
.shop-video {
.video-player {
height: 363px;
}
.video-intro {
padding: 30px;
}
.video-title {
font-size: 36px;
color: #444;
margin-bottom: 30px;
}
.video-desc {
font-size: 28px;
color: #444;
}
.video-poster {
position: relative;
height: 363px;
color: #fff;
}
.video-meta-customers {
position: absolute;
top: 20px;
right: 30px;
font-size: 24px;
padding: 10px 20px;
border-radius: 50px;
background-color: rgba(0, 0, 0, 0.5);
}
}
.shop-hot {
.item {
position: relative;
}
.item-pic {
width: 100%;
height: 100%;
}
.item-info {
position: absolute;
bottom: 0;
width: 100%;
padding-left: 20px;
padding-right: 20px;
color: #fff;
}
.items-s1 {
position: relative;
background-color: #fff;
margin: 30px;
.item-info {
font-size: 28px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.items-s2 {
font-size: 24px;
position: relative;
.item {
height: 234px;
}
.item-info {
height: 70px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
}
}
.items-3-2 {
font-size: 18px;
overflow: hidden;
.item {
width: 50%;
height: 234px;
}
.item:first-child {
height: 468px;
}
.item-info {
display: flex;
justify-content: space-between;
align-items: center;
}
}
.items-3-2-left .item { float: left; }
.items-3-2-right .item { float: right; }
/* 风格: 3图 3列 */
.items-3-3 {
overflow: hidden;
font-size: 18px;
.item {
float: left;
width: 33.3333333333%;
height: 333px;
}
.item-info {
height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
background-color: rgba(0, 0, 0, 0.5);
}
}
.items-small {
.item {
height: 250px;
}
.item-info {
height: 48px;
}
}
.items-c2 {
overflow: hidden;
font-size: 20px;
.item {
float: left;
width: 50%;
height: 375px;
}
.item-info {
height: 90px;
display: flex;
flex-direction: column;
justify-content: center;
background-color: rgba(0, 0, 0, 0.5);
}
}
}
.shop-item-div {
height: 30px;
background-color: #f0f0f0;
}
... ...
@charset "utf-8";
@import "../../layout/sticky";
@import "../../layout/tab";
@import "shop-index-coupon";
@import "reds-shop/header";
@import "reds-shop/nav-tab";
@import "reds-shop/section";
\ No newline at end of file
... ...
... ... @@ -96,7 +96,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;
}
... ...