Authored by 周少峰

shop index

... ... @@ -12,17 +12,28 @@ const helpers = global.yoho.helpers;
const searchApi = require(`${mRoot}/search-api`);
// 店铺页
const shop = (shopId, uid, res, next) => {
let resData = {};
const shop = (shopId, req, res, next) => {
list.getShopInfo(shopId, uid).then(result => {
console.log(result);
list.getShopInfo(shopId, req.user.id).then(shopInfo => {
return list.getShopData();
}).then(result =>{
Object.assign(resData, result);
res.render('list/shop-index', resData);
// 暂定2
shopInfo.shopTemplateType = 2;
if (shopInfo.shopTemplateType === 2) {
// 经典模板
list.getShopData(shopId, req.user.id, req.query, shopInfo).then(result => {
res.render('list/shop-index', result);
}).catch(next);
} else {
// 基础模板
list.getBaseShopData(shopId, req.user.id, req.query).then(result => {
res.render('list/index', result);
}).catch(next);
}
}).catch(next);
};
... ... @@ -67,18 +78,19 @@ exports.new = (req, res, next) => {
exports.brand = (req, res, next) => {
let resData = {};
// shopId存在,直接走店铺
// req.shopId存在,直接走店铺
if (req.shopId) {
shop(req.shopId, req.user.id, res, next);
shop(req.shopId, req, res, next);
}
let brandDomain = req.brandDomain || 'vans';
let brandDomain = req.brandDomain || 'colormad';
// 获取品牌信息
list.getBrandInfo({domain: brandDomain}).then(brandInfo => {
brandInfo.type = 2;
brandInfo.shopId = 702;
switch (brandInfo.type) {
// brandInfo.type = 2;
// brandInfo.shopId = 746;
switch (parseInt(brandInfo.type, 10)) {
case 1:
// 搜索
res.location(helpers.urlFormat('', {query: brandInfo.brandDomain}, 'search'));
... ... @@ -86,19 +98,16 @@ exports.brand = (req, res, next) => {
case 2:
// 店铺
shop(brandInfo.shopId, req.user.id, res, next);
break;
return shop(brandInfo.shopId, req, res, next);
default:
// 品牌
return list.getBrandData(req.query, Object.assign({uid: req.user.id}, brandInfo));
// break;
// 品牌
return list.getBrandData(req.query, Object.assign({uid: req.user.id}, brandInfo)).then(result => {
Object.assign(resData, result);
res.render('list/brand', resData);
});
}
}).then(result => {
Object.assign(resData, result);
res.render('list/brand', resData);
}).catch(next);
};
... ...
... ... @@ -10,7 +10,9 @@ const searchApi = require('./search-api');
const headerModel = require('../../../doraemon/models/header');
const productProcess = require(`${utils}/product-process`);
const searchHandler = require('./search-handler');
const shopHandler = require('./shop-handler');
const helpers = global.yoho.helpers;
const _ = require('lodash');
// 品牌页folder名称
const brandFolderSeries = '经典系列';
... ... @@ -218,7 +220,6 @@ exports.getBrandData = (params, extra) => {
// 品牌页不显示品牌筛选项
delete finalResult.brand.filters.brand;
return finalResult;
});
};
... ... @@ -269,30 +270,132 @@ exports.getAdnav = (params) => {
exports.getShopInfo = (shopId, uid) => {
return searchApi.getShopInfo(shopId, uid).then(result => {
return {
brandName: result.shop_name,
brandCont: result.shop_intro,
domain: result.shop_domain,
logo: result.shop_logo,
isFavorite: result.is_favorite === 'Y',
shopTemplateType: result.shop_template_type,
multBrandShopType: result.mult_brand_shop_type,
showShopName: result.is_show_shop_name === 'Y'
};
if (result.code === 200) {
return {
brandName: result.data.shop_name,
brandCont: result.data.shop_intro,
domain: result.data.shop_domain,
logo: result.data.shop_logo,
isFavorite: result.data.is_favorite === 'Y',
shopTemplateType: result.data.shop_template_type,
multBrandShopType: result.data.mult_brand_shop_type,
showShopName: result.data.is_show_shop_name === 'Y'
};
} else {
// log
}
});
};
/**
* 获取店铺数据
* 获取经典模板店铺数据
* @param shopId
* @param uid
* @param params
* @param shopInfo 店铺介绍
*/
exports.getShopData = (shopId, uid) => {
exports.getShopData = (shopId, uid, params, shopInfo) => {
// 调用接口
// let apiMethod = [
// 店铺所有品牌
return searchApi.getShopBrands(shopId).then(shopBrands => {
if (shopBrands.code === 200 && shopBrands.data) {
return shopBrands.data;
}
}).then(shopBrands => {
// 店铺的所有品牌id
let shopBrandIds = [],
// 通过品牌获取相关文章接口
articleApiMethod = [],
// 需要调用的接口数组
apiMethod = [
// 头部数据
headerModel.requestHeaderData('boys'),
// 店铺装修数据
searchApi.getShopDecorator(shopId),
// 搜索店铺商品
searchApi.getProductList(params)
];
_.forEach(shopBrands, (value) => {
shopBrandIds.push(value.brand_id);
articleApiMethod.push(
// // 店铺基本信息
// searchApi.getSortList({brand: extra.brandId}),
// ];
// 店铺装修数据
searchApi.getArticleByBrand(value.brand_id, 'udid')
);
});
// 根据品牌获取分类 (腾讯云测试没有该接口,暂时不调用分类)
// apiMethod.push(
// // 店铺分类
// searchApi.getSortList({brand: shopBrandIds})
// );
// apiMethod 添加调用相关文章的接口
apiMethod = _.concat(apiMethod, articleApiMethod);
return api.all(apiMethod).then(result => {
let finalResult = {
headerData: Object.assign(result[0].headerData, {header: true}),
pathNav: searchHandler.handlePathNavData(shopInfo, params, 'shop')
};
// 面包屑导航
Object.assign(finalResult, searchHandler.handlePathNavData(shopInfo, params, 'shop'));
// 店铺介绍
// 店铺装修
if (result[1].code === 200) {
Object.assign(finalResult, shopHandler.getShopDecorator(result[1].data, params, shopId));
} else {
return Promise.reject('No ShopDecorator data');
}
// // 获取左侧类目数据
// if (result[1].code === 200) {
// Object.assign(finalResult.shop, {
// leftContent: searchHandler.handleSortData(result[1].data.sort, params),
// pathNav: searchHandler.handlePathNavData(extra, params, 'brand')
// });
// }
// if (result[1].code === 200) {
// console.log(result[1].data);
// }
// 获取商品数据和顶部筛选条件
// if (result[2].code === 200) {
// Object.assign(finalResult.shop, {
// filters: searchHandler.handleFilterData(result[2].data.filter, params),
// opts: searchHandler.handleOptsData(params, result[2].data.total, result[2].data.filter),
// totalCount: result[2].data.total,
// footPager: searchHandler.handlePagerData(result[2].data.total, params),
// goods: productProcess.processProductList(result[2].data.product_list,
// Object.assign({showDiscount: false}, params))
// });
// }
return finalResult;
});
});
};
/**
* 获取基础模板店铺数据
*/
exports.getBaseShopData = (shopId, uid) => {
return searchApi.getShopInfo(shopId, uid);
};
... ...
... ... @@ -21,6 +21,9 @@ const adsUrl = '/shops/api/v1/ads/getList';
// 判断用户是否收藏品牌
const isFavoriteBrandUrl = '/shops/service/v1/favorite/';
// 根据品牌查询相关文章
const relateArticleUrl = 'guang/service/v2/article/getArticleByBrand';
/**
* 获取商品列表
* @return
... ... @@ -195,6 +198,35 @@ const getShopInfo = (shopId, uid) => {
};
/**
* 查询店铺下面的所有品牌
*/
const getShopBrands = (shopId) => {
return yohoApi.get('', {method: 'app.shops.getShopsBrands', shop_id: shopId || 0});
};
/**
* 查询店铺装修
*/
const getShopDecorator = (shopId) => {
return yohoApi.get('', {method: 'app.shopsdecorator.getList', shop_id: shopId || 0});
};
/**
* 通过品牌获取相关文章
*/
const getArticleByBrand = (brand, udid, limit) => {
let params = {
brand_id: brand || 0,
udid: udid,
limit: limit || 6
};
return serviceApi.get(relateArticleUrl, params);
};
module.exports = {
getSortByConditionAsync,
getProductList,
... ... @@ -209,7 +241,10 @@ module.exports = {
getBrandData,
getNodeContent,
isFavoriteBrand,
getShopInfo
getShopInfo,
getShopBrands,
getShopDecorator,
getArticleByBrand
};
... ...
... ... @@ -638,6 +638,16 @@ exports.handlePathNavData = (data, params, page) => {
}
);
break;
case 'shop':
// 店铺
pathNav.push(
{
name: data.brandName,
pathTitle: data.brandName
}
);
break;
default :
// 分类
_.forEach(data, (sort) => {
... ... @@ -870,7 +880,7 @@ exports.handleBrandBanner = (data) => {
return {
bannerHeight: 150,
banner: data.brandBanner.split('?')[0],
banner: data.brandBanner,
brandHome: data.url,
brandIntro: helpers.urlFormat('/about', '', data.brandDomain),
dataId: data.brandId
... ...
/*
* @Author: sefon
* @Date: 2016-07-31 22:13:24
*/
'use strict';
const _ = require('lodash');
// const helpers = global.yoho.helpers;
// const queryString = require('querystring');
const newProductsName = '新品上架 NEW';
const hotProductsName = '人气单品 HOT';
const shopListUrl = '/shoplist';
/**
* 新品上架
*/
const newProducts = (data) => {
let dest = {
name: newProductsName,
list: []
};
_.forEach(data, (value) => {
dest.list.push({
productId: value.productId,
title: value.productName,
productSkn: value.productSkn,
price: '¥' + value.salesPrice,
img: value.src
// url: helpers.getProductUrl(value.productId, value.productSkn, value.productName)
});
});
return dest;
};
/**
* 人气单品
*/
const hotProducts = (data) => {
let dest = {
name: hotProductsName,
list: []
};
_.forEach(data, (value, key) => {
dest.list.push({
productId: value.productId,
title: value.productName,
productSkn: value.productSkn,
price: '¥' + value.salesPrice,
img: value.src,
// url: helpers.getProductUrl(value.productId, value.productSkn, value.productName),
index: key + 1
});
});
return dest;
};
/**
* tabBar
*/
const goodsTabBar = (data, shopId) => {
let dest = {
hot: [],
new: []
},
more = {name: 'MORE', href: shopListUrl + '?shopId=' + shopId};
_.forEach(data.hot, (value) => {
if (value.url) {
dest.hot.push({
name: value.name,
href: value.url
});
}
});
_.forEach(data.new, (value) => {
if (value.url) {
dest.new.push({
name: value.name,
href: value.url
});
}
});
dest.hot.push(more);
dest.new.push(more);
return dest;
};
/**
* 店铺经典模板banner
* @param data 装修数据
* @returns {{}}
*/
const shopTopBanner = (data) => {
return {
shopTopBanner: {
banner: data[0]['shopSrc'] || '',
detailSrc: data[0]['detailSrc'] || '',
isShowShopName: data[0]['isShowShopName'] === 'Y'
}
};
};
/**
* 导航
* @param data 装修数据
* @returns {{}}
*/
const navigationBar = (data, shopId) => {
let shopNav = [
{
name: '店铺首页',
url: '/?navBar=0&shopId=' + shopId
},
{
name: '全部商品',
url: shopListUrl + '/?navBar=1&shopId=' + shopId
},
{
name: '人气单品',
url: shopListUrl + '/?navBar=2&shopId=' + shopId
},
{
name: '新品上架',
url: shopListUrl + '/?navBar=3&shopId=' + shopId
}
];
return {navigationBar: _.union(shopNav, _.filter(data, (value) => {
return value.url;
}))
};
};
/**
* 资源位小图
* @param data 装修数据
* @returns {{}}
*/
const oneRowTwoColImages = (data) => {
let dest = [];
_.forEach(data, (value) => {
dest.push({
img: value.data.src,
url: value.data.url
});
});
return [
{
img: data[0]['data']['src'],
url: data[0]['data']['url']
},
{
img: data[1]['data']['src'],
url: data[1]['data']['url']
}
];
};
/**
* 店铺装修楼层数据
* @param data 装修数据
* @returns {{}}
*/
exports.getShopDecorator = (data, params, shopId) => {
let dest = {
newArrivel: {},
hotSingle: {}
};
_.forEach(data.list, (value) => {
switch (value.resource_name) {
case 'signboard':
break;
case 'newProducts':
dest.newArrivel = newProducts(JSON.parse(value.resource_data));
break;
case 'hotProducts':
dest.hotSingle = hotProducts(JSON.parse(value.resource_data));
break;
case 'goodsTabBar':
Object.assign(dest.newArrivel, {navs: goodsTabBar(JSON.parse(value.resource_data))['new']});
Object.assign(dest.hotSingle, {navs: goodsTabBar(JSON.parse(value.resource_data))['hot']});
break;
case 'shopTopBanner':
Object.assign(dest, shopTopBanner(JSON.parse(value.resource_data)));
break;
case 'navigationBar':
Object.assign(dest, navigationBar(JSON.parse(value.resource_data), shopId));
break;
case 'oneRowTwoColImages':
Object.assign(dest, oneRowTwoColImages(JSON.parse(value.resource_data), shopId));
break;
default:
break;
}
});
// console.log(dest);
return dest;
};
... ...
... ... @@ -40,13 +40,13 @@
{{#newArrivel}}
<div class="new-arrivel clearfix">
{{> index/floor-header}}
{{> product/shop-single-list}}
{{> list/shop-single-list}}
</div>
{{/newArrivel}}
{{#hotSingle}}
<div class="hot-single clearfix">
{{> index/floor-header}}
{{> product/shop-single-list}}
{{> list/shop-single-list}}
</div>
{{/hotSingle}}
{{#allGoods}}
... ...
<ul>
{{#each list}}
<li>
<a class="item item-{{@index}}" href="{{url}}" target= "_blank">
<img class="lazy" data-original="{{img}}"/>
<p class="title">
{{title}}
</p>
<p class="price">
{{price}}
</p>
{{#if index}}
<span class="hat">{{index}}</span>
{{/if}}
</a>
</li>
{{/each}}
</ul>
... ...
... ... @@ -14,13 +14,15 @@ module.exports = {
port: 6002,
siteUrl: 'http://www.yohobuy.com',
domains: {
// api: 'http://api.yoho.yohoops.org',
api: 'http://api.yoho.yohoops.org',
// api: 'http://devapi.yoho.cn:58078/',
api: 'http://testapi.yoho.cn:28078/',
// api: 'http://testapi.yoho.cn:28078/',
// service: 'http://devservice.yoho.cn:58077/',
// service: 'http://service.yoho.yohoops.org',
service: 'http://testservice.yoho.cn:28077/',
service: 'http://service.yoho.yohoops.org/',
// service: 'http://testservice.yoho.cn:28077/',
search: 'http://192.168.102.216:8080/yohosearch/'
},
subDomains: {
... ...
... ... @@ -11,6 +11,7 @@
@import "detail";
@import "sale/index";
@import "outlets/index";
@import "shop-index";
.product-page {
.list-left {
... ...
.shop-index-page {
margin: 10px auto 30px;
width: 1150px;
.shop-banner {
position: relative;
.shop-name {
position: absolute;
left: 260px;
bottom: 20px;
font-size: 36px;
color: #fff;
}
.banner-img {
width: 100%;
height: 150px;
}
.opt-wrap {
position: absolute;
top: 65%;
right: 0;
padding: 0 10px;
}
.shop-intro,
.shop-collect {
display: inline-block;
width: 110px;
height: 30px;
margin-right: 10px;
font-size: 16px;
line-height: 30px;
text-align: center;
color: #fff;
border: 1px solid #fff;
cursor: pointer;
i {
background-repeat: no-repeat;
float: left;
position: relative;
left: 11px;
top: 5px;
}
.shop-intro-ico {
width: 16px;
height: 20px;
background-image: resolve(product/shop-instro.png);
margin-right: 12px;
}
.shop-collect-ico {
width: 20px;
height: 19px;
background-image: resolve(product/shop-collection.png);
top: 6px;
margin-right: 12px;
&.on {
background-image: resolve(product/shop-collection-on.png);
}
}
}
}
.shop-nav {
box-sizing: border-box;
margin-bottom: 30px;
padding: 0 20px;
width: 100%;
height: 40px;
color: #fff;
background: #000;
font-size: 16px;
a {
position: relative;
top: 8px;
display: inline-block;
line-height: 26px;
color: #fff;
}
.nav-item {
position: relative;
float: left;
width: 160px;
text-align: center;
&.first {
width: 100px;
text-align: left;
}
}
.current {
a {
border-bottom: 2px solid #fff;
}
}
}
.coupon {
margin-top: 20px;
width: 100%;
height: 80px;
.coupon-title {
width: 162px;
height: 100%;
background: url(product/coupon-title.png);
}
}
.slider-wrap {
height: 360px;
.slide-wrapper {
img {
width: auto;
height: auto;
}
}
}
.slider-left {
float: left;
margin-right: 10px;
width: 660px;
height: 100%;
overflow: hidden;
position: relative;
.slide-wrapper {
height: 358px;
}
.slide-switch {
a.prev {
margin-left: -330px;
}
a.next {
margin-right: -330px;
}
}
img {
width: 100%;
height: 100%;
}
.slide-pagination {
display: none;
}
}
.slider-right {
float: left;
width: 300px;
height: 100%;
.slider-item {
display: block;
margin-bottom: 10px;
width: 100%;
height: 175px;
}
}
.floor-header {
margin-top: 50px;
}
.new-arrivel,
.hot-single {
width: 980px;
.item {
float: left;
position: relative;
margin-right: 10px;
margin-bottom: 20px;
width: 235px;
height: 315px;
font-size: 14px;
text-align: center;
line-height: 1.5;
background: #f5f5f5;
font-weight: bold;
img {
width: 235px;
height: 250px;
}
.title {
width: 220px;
padding: 0 5px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
.hat {
position: absolute;
top: 0;
right: 0;
width: 50px;
height: 50px;
color: #ffc513;
text-align: center;
line-height: 57px;
background: url(product/hat.png);
}
}
.mask {
background-color: #000;
opacity: .5;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1001;
display: none;
cursor: pointer;
}
.pop-shop-intro {
display: none;
}
.shop-intro-bg {
width: 908px;
height: 604px;
background-color: #000;
opacity: .5;
position: fixed;
left: 50%;
top: 50%;
z-index: 1002;
margin: -302px 0 0 -454px;
}
.shop-intro-area {
width: 898px;
height: 594px;
padding: 60px 10px 35px 40px;
background-color: #fff;
position: fixed;
left: 50%;
top: 50%;
margin: -297px 0 0 -449px;
z-index: 1003;
box-sizing: border-box;
.close-btn {
width: 18px;
height: 18px;
background-image: resolve(product/shop-instro-close.png);
position: absolute;
right: 20px;
top: 20px;
cursor: pointer;
}
.brand-cont {
overflow: auto;
width: 100%;
height: 499px;
padding-right: 30px;
box-sizing: border-box;
}
.intro-title {
float: left;
h2 {
width: 100%;
float: left;
text-align: left;
font-size: 26px;
font-weight: bold;
color: #000;
font-style: italic;
}
p {
font-family: "黑体";
font-size: 20px;
text-align: left;
padding: 10px 0;
float: left;
}
}
.intro-cont {
width: 100%;
float: left;
margin-top: 55px;
font-size: 14px;
line-height: 20px;
p {
text-indent: 2em;
}
img {
width: 100%;
margin-top: 10px;
}
}
}
.fixed-area {
background: #fff;
z-index: 1;
width: 970px;
}
.all-goods-menu {
width: 100%;
height: 40px;
line-height: 40px;
.menu-tag {
color: #d0021b;
font-size: 18px;
font-weight: bold;
text-align: left;
padding: 0 20px 0 10px;
border-right: 1px solid #000;
float: left;
}
.menu-list {
width: 810px;
height: 40px;
overflow: hidden;
float: left;
font-size: 14px;
li {
display: inline-block;
padding: 0 15px;
}
.on {
background: #000;
height: 28px;
line-height: 28px;
a {
color: #fff;
}
}
}
.more {
font-size: 14px;
float: right;
}
}
.sort-pager .sort-type:first-child .iconfont {
display: inline-block;
}
.loading {
position: relative;
width: 100%;
text-align: center;
a {
display: block;
height: 35px;
width: 120px;
margin: 0 auto;
background-color: #000;
color: #fff;
font-size: 14px;
line-height: 35px;
text-align: center;
}
}
.trend-info {
width: 100%;
.trend-list {
width: 100%;
li {
float: left;
width: 316px;
margin-left: 10px;
text-align: center;
&:first-child {
margin-left: 0;
}
}
img {
width: 100%;
height: 181px;
}
.main-title,
.sub-title {
box-sizing: border-box;
font-size: 16px;
margin-top: 15px;
padding: 0 10px;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 24px;
}
.sub-title {
margin-top: 0;
font-size: 14px;
}
}
}
.goods-wrap {
.goods-container {
.good-info {
width: 235px;
height: auto;
margin-bottom: 35px;
}
.good-detail-text {
text-align: left;
}
}
}
.left-modular {
width: 160px;
font-size: 14px;
margin-top: 20px;
float: left;
.title {
width: 100%;
height: 25px;
line-height: 25px;
background: #000;
color: #fff;
font-family: "黑体";
padding-left: 14px;
box-sizing: border-box;
}
.left-list {
width: 100%;
margin-top: 5px;
li {
width: 100%;
height: 42px;
line-height: 42px;
background: #f5f5f5;
float: left;
box-sizing: border-box;
margin-top: 5px;
padding-left: 14px;
a {
color: #000;
}
&.on {
border: 1px solid #000;
}
}
}
}
.classic-recommend {
.left-list li {
height: 50px;
line-height: 50px;
}
.classic-name {
width: 96px;
display: inline-block;
line-height: 14px;
vertical-align: middle;
font-weight: bold;
.name {
font-size: 14px;
}
.en-name {
font-size: 12px;
}
}
img {
width: 40px;
max-height: 40px;
margin-right: 5px;
vertical-align: middle;
}
}
.sell-recommend {
.left-list li {
padding-left: 0;
height: auto;
margin-bottom: 25px;
line-height: inherit;
img {
width: 100%;
}
}
}
::-webkit-scrollbar {
width: 16px;
height: 16px;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
border-radius: 999px;
border: 5px solid transparent;
}
::-webkit-scrollbar-track {
box-shadow: 0 0 6px rgba(0, 0, 0, 0) inset;
}
::-webkit-scrollbar-thumb {
min-height: 20px;
background-clip: content-box;
box-shadow: 0 0 0 6px rgba(0, 0, 0, .3) inset;
}
::-webkit-scrollbar-corner {
background: transparent;
}
.page-nav {
padding: 7px 0;
float: right;
font-size: 14px;
.page-prev {
width: 33px;
height: 33px;
background: #ccc;
text-align: center;
float: left;
}
.arrow-left {
width: 10px;
height: 10px;
display: inline-block;
position: relative;
top: -7px;
background: resolve(product/arrow-left.png) no-repeat;
}
a .page-prev,
a .page-next {
background: #000;
color: #fff;
}
.page-next {
min-width: 110px;
height: 33px;
background: #a9a9a9;
float: left;
margin-left: 1px;
line-height: 33px;
padding-left: 10px;
box-sizing: border-box;
padding-right: 10px;
}
.arrow-right {
width: 10px;
height: 10px;
display: inline-block;
vertical-align: middle;
background: resolve(product/arrow-right.png) no-repeat;
}
.pages {
margin-left: 10px;
}
}
}
... ...