Authored by yyq

shop index

... ... @@ -14,11 +14,10 @@ exports.index = (req, res, next) => {
let shopId = req.query.shopId;
let shopInfo = req.params.shopInfo;
_.unset(req.query, 'domain');
if (shopInfo) { // 新路由 /shop/:domain-:id.html
shopId = _.last(_.split(shopInfo, '-'));
domain = shopInfo.replace(`-${shopId}`, '');
req.query.domain = domain;
req.query.shopId = shopId;
} else if (req.shopRedirect && domain && shopId) { // subdomain方式
_.unset(req.query, 'shopId');
... ... @@ -84,24 +83,51 @@ exports.index = (req, res, next) => {
// 经典店铺列表
exports.list = (req, res, next) => {
let shopId = req.query.shopId;
let shopInfo = req.params.shopInfo;
if (shopInfo && !req.query.shopId) {
const shopId = _.last(_.split(shopInfo, '-'));
if (!shopId) {
req.query.domain = shopInfo.replace(`-${shopId}`, '');
req.query.shopId = shopId;
}
if (!req.query.shopId) {
return next();
}
return req.ctx(shopModel).getShopListInfoAsync(req.yoho.channel, req.query).then(result => {
Object.assign(result, {
page: 'shop',
shopId: shopId,
shopKey: req.query.query || ''
});
return req.ctx(shopModel).getShopListAsync(req.yoho.channel, req.query).then(shopObj => {
// 数据异常,重定向
if (shopObj.redirect) {
if (shopObj.redirectType) {
return res.redirect(shopObj.redirectType, shopObj.redirect);
}
return res.redirect(shopObj.redirect);
}
// 店铺装修为空则不cache
if (!result.shopTopBanner) {
res.set('Cache-Control', 'no-cache');
if (shopObj.templateType === 2) { // 经典模板
Object.assign(shopObj, {
page: 'shop',
shopId: req.query.shopId,
shopKey: req.query.query || ''
});
// 店铺装修为空则不cache
if (!shopObj.shopTopBanner) {
res.set('Cache-Control', 'no-cache');
}
res.render('shop/list', shopObj);
} else { // 基础模版
Object.assign(shopObj, {page: 'list'});
// 基础店铺装修为空则不cache
if (!shopObj.brand || !shopObj.brand.shopBanner) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/brand', shopObj);
}
res.render('shop/list', result);
}).catch(next);
};
... ...
... ... @@ -6,15 +6,15 @@
'use strict';
const _ = require('lodash');
const Fn = require('lodash/fp');
const qs = require('querystring');
const helpers = global.yoho.helpers;
const handleStaticUrl = require(`${global.utils}/parameter`).fullParamToMinPath;
// const queryString = require('querystring');
const newProductsName = '新品上架 NEW';
const hotProductsName = '人气单品 HOT';
const shopListUrl = '/product/shoplist';
/**
* 新品上架
... ... @@ -68,7 +68,7 @@ const hotProducts = (data) => {
/**
* tabBar
*/
const goodsTabBar = (data, shopId) => {
const goodsTabBar = (data, shopId, baseUrl) => {
let dest = {
hot: [],
new: []
... ... @@ -96,8 +96,14 @@ const goodsTabBar = (data, shopId) => {
});
}
});
dest.hot.push({name: 'MORE', url: `${shopListUrl}?navBar=2&order=s_n_desc&shopId=${shopId}`});
dest.new.push({name: 'MORE', url: `${shopListUrl}?navBar=3&order=s_t_desc&shopId=${shopId}`});
dest.hot.push({name: 'MORE', url: handleStaticUrl(baseUrl, {
navBar: 2,
order: 's_n_desc'
})});
dest.new.push({name: 'MORE', url: handleStaticUrl(baseUrl, {
navBar: 3,
order: 's_t_desc'
})});
return dest;
};
... ... @@ -136,34 +142,46 @@ const shopTopBannerBase = (data) => {
* @param data 装修数据
* @returns {{}}
*/
const navigationBar = (data, shopId, params, domain) => {
const navigationBar = (data, shopId, params, baseUrl) => {
params = params || {};
const gender = params.gender ? `&gender=${params.gender}` : '';
let shopNav = [
{
name: '店铺首页',
url: `/shop/${domain || ''}-${shopId}.html`
url: `${baseUrl}.html`
},
{
name: '全部商品',
url: `${shopListUrl}/?navBar=1&shopId=${shopId}${gender}`
url: handleStaticUrl(baseUrl, {
navBar: 1,
gender: params.gender
})
},
{
name: '人气单品',
url: `${shopListUrl}/?navBar=2&order=s_n_desc&shopId=${shopId}${gender}`
url: handleStaticUrl(baseUrl, {
navBar: 2,
order: 's_n_desc',
gender: params.gender
})
},
{
name: '新品上架',
url: `${shopListUrl}/?navBar=3&order=s_t_desc&shopId=${shopId}${gender}`
url: handleStaticUrl(baseUrl, {
navBar: 3,
order: 's_t_desc',
gender: params.gender
})
}
];
_.forEach(data, (value) => {
if (value.url) {
value.url += _.indexOf(value.url, '?') > -1 ? '&' : '?';
shopNav.push({
name: value.name,
url: `${value.url}&navBar=${shopNav.length}`
url: `${value.url}navBar=${shopNav.length}`
});
}
});
... ... @@ -239,7 +257,7 @@ const recommend = (data) => {
* @param type $data
* @return type []
*/
const brandBrowse = (data, params) => {
const brandBrowse = (data, params, baseUrl) => {
let brand = _.get(params, 'brand', '');
let resData = {};
... ... @@ -248,7 +266,11 @@ const brandBrowse = (data, params) => {
_.forEach(data, value => {
list.push({
url: `${shopListUrl}?shopId=${params.shopId || ''}&brand=${value.id}&title=${value.title}$navBar=1`,
url: handleStaticUrl(baseUrl, {
brand: value.id,
title: value.title,
navBar: 1
}),
brandName: value.brandName,
title: value.title,
cur: (brand === +value.id)
... ... @@ -319,11 +341,12 @@ const signboard = (data) => {
const _handleSaleCategory = (shopId, baseUrl, resourceObj) => {
baseUrl = baseUrl || '';
const thisShop = (categoryId) => baseUrl + '?' + qs.stringify({
productPool: categoryId,
shopId: shopId,
navBar: -1
});
const thisShop = (categoryId) => {
return handleStaticUrl(baseUrl, {
productPool: categoryId,
navBar: -1
});
};
let hasSaleCategory = Fn.pipe(Fn.prop('linkType'), Fn.eq('1'));
... ... @@ -356,6 +379,7 @@ const _handleSaleCategory = (shopId, baseUrl, resourceObj) => {
exports.getShopDecorator = (data, params, shopId, base) => {
let dest = {};
let sourceFn;
const baseUrl = `/shop/${data.domain}-${shopId}`;
if (base) {
sourceFn = {
... ... @@ -372,11 +396,12 @@ exports.getShopDecorator = (data, params, shopId, base) => {
return;
}
let info = Fn.pipe(JSON.parse, _.partial(_handleSaleCategory, shopId, ''))(value.resource_data || '[]');
let info = Fn.pipe(JSON.parse, _.partial(_handleSaleCategory, shopId, baseUrl))(value.resource_data || '[]'); // eslint-disable-line
sourceFn[value.resource_name](info);
});
} else {
Object.assign(dest, {
newArrivel: {},
hotSingle: {}
... ... @@ -390,7 +415,7 @@ exports.getShopDecorator = (data, params, shopId, base) => {
Object.assign(dest.hotSingle, hotProducts(info));
},
goodsTabBar(info) {
let tabBar = goodsTabBar(info, shopId);
let tabBar = goodsTabBar(info, shopId, baseUrl);
Object.assign(dest.newArrivel, {navs: tabBar.new});
Object.assign(dest.hotSingle, {navs: tabBar.hot});
... ... @@ -399,7 +424,7 @@ exports.getShopDecorator = (data, params, shopId, base) => {
Object.assign(dest, shopTopBanner(info));
},
navigationBar(info) {
Object.assign(dest, navigationBar(info, shopId, params, data.domain));
Object.assign(dest, navigationBar(info, shopId, params, baseUrl));
},
largeSlideImg(info) {
Object.assign(dest, largeSlideImg(info, shopId));
... ... @@ -411,7 +436,7 @@ exports.getShopDecorator = (data, params, shopId, base) => {
Object.assign(dest, recommend(info, shopId));
},
brandBrowse(info) {
Object.assign(dest, brandBrowse(info, params));
Object.assign(dest, brandBrowse(info, params, baseUrl));
},
hotRecommend(info) {
Object.assign(dest, hotRecommend(info));
... ... @@ -423,7 +448,7 @@ exports.getShopDecorator = (data, params, shopId, base) => {
return;
}
let info = Fn.pipe(JSON.parse, _.partial(_handleSaleCategory, shopId, shopListUrl))(value.resource_data || '[]'); // eslint-disable-line
let info = Fn.pipe(JSON.parse, _.partial(_handleSaleCategory, shopId, baseUrl))(value.resource_data || '[]'); // eslint-disable-line
sourceFn[value.resource_name](info);
});
... ...
... ... @@ -12,6 +12,7 @@ const helpers = global.yoho.helpers;
const shopHandler = require('./shop-handler');
const searchHandler = require('./search-handler');
const listHandler = require('./list-handler');
const headerModel = require('../../../doraemon/models/header');
const productProcess = require('../../../utils/product-process-simple');
... ... @@ -48,8 +49,13 @@ function _getShopData(channel, params, shopInfo) {
params = params || {};
let gender = _getGender(channel),
shopId = params.shopId;
shopId = params.shopId,
domain = params.domain;
let resData = {shopId: shopId};
const baseUrl = `/shop/${domain}-${shopId}`;
params.domain && delete params.domain;
params.shopId && delete params.shopId;
return co(function* () {
let result = yield Promise.props({
... ... @@ -114,9 +120,9 @@ function _getShopData(channel, params, shopInfo) {
if (result.sort.code === 200) {
let groupSort = _.get(result.sort, 'data', []);
resData.leftContent = searchHandler.handleSortData(groupSort, params, params, shopListUrl);
resData.leftContent = listHandler.handleSortData(groupSort, params, params, baseUrl);
_.set(resData, 'brandShopAd', {baseUrl: shopListUrl});
_.set(resData, 'brandShopAd', {baseUrl: baseUrl});
if (resData.allGoods) {
Object.assign(resData.allGoods, searchHandler.setShopSort(groupSort, Object.assign({},
... ... @@ -206,9 +212,12 @@ function _getBaseShopData(channel, params, shopInfo) {
params = params || {};
let searchParams = searchHandler.getSearchParams(params);
let shopId = params.shopId;
const shopId = params.shopId || params.shop_id;
const domain = params.domain;
const baseUrl = `/shop/${domain}-${shopId}`;
delete params.shopId;
params.shopId && delete params.shopId;
params.domain && delete params.domain;
return co(function* () {
let result = yield Promise.props({
... ... @@ -268,7 +277,7 @@ function _getBaseShopData(channel, params, shopInfo) {
// 获取左侧类目数据
if (result.sort.code === 200) {
let dps = {shopId: shopId};
let dps = {shop_id: shopId};
_.forEach(needParams, value => {
if (params[value]) {
... ... @@ -277,14 +286,14 @@ function _getBaseShopData(channel, params, shopInfo) {
});
Object.assign(resData.brand, {
leftContent: searchHandler.handleSortData(result.sort.data, dps, params)
leftContent: listHandler.handleSortData(result.sort.data, dps, params, baseUrl)
});
}
// 获取商品数据和顶部筛选条件
if (result.product.code === 200) {
let data = result.product.data;
let filters = Object.assign(searchHandler.handleFilterDataAll(data, params),
let filters = Object.assign(listHandler.handleFilterData(data, params, baseUrl),
_.get(resData, 'brand.leftContent.sort', {}));
filters.checkedConditions.conditions = _.concat(filters.checkedConditions.conditions,
... ... @@ -292,12 +301,12 @@ function _getBaseShopData(channel, params, shopInfo) {
Object.assign(resData.brand, {
filters: filters,
opts: searchHandler.handleOptsData(params, data.total, data.filter),
opts: listHandler.handleOptsData(params, data.total, data.filter, baseUrl),
totalCount: data.total,
footPager: searchHandler.handlePagerData(data.total, params),
footPager: listHandler.handlePagerData(data.total, params, false, baseUrl),
goods: productProcess.processProductList(data.product_list,
Object.assign({showDiscount: false, from: {type: 'shop', params: params}}, params)),
hasNextPage: searchHandler.handleNextPage(params, data.total),
hasNextPage: listHandler.handleNextPage(params, data.total, baseUrl),
// 最近浏览记录
latestWalk: 7
... ... @@ -386,7 +395,7 @@ function getShopInfoAsync(domain, channel, params) {
}).bind(this)();
}
function getShopListInfoAsync(channel, params) {
function _getShopListData(channel, params, shopInfo) {
let gender = _getGender(channel),
shopId = params.shopId,
navBar = params.navBar || 1;
... ... @@ -396,7 +405,7 @@ function getShopListInfoAsync(channel, params) {
return co(function* () {
let result = yield Promise.props({
header: headerModel.requestHeaderData(channel), // 头部数据
shopInfo: this.api.getShopInfo(shopId), // 店铺介绍
shopInfo: shopInfo ? shopInfo : this.api.getShopInfo(shopId), // 店铺介绍
decorator: this.searchApi.getShopDecorator(shopId), // 店铺装修数据
sort: this.searchApi.getSortList({shop_id: shopId}),
product: this.searchApi.getProductList(Object.assign(searchParams,
... ... @@ -501,6 +510,29 @@ function getShopListInfoAsync(channel, params) {
}).bind(this)();
}
// 基础店铺&经典店铺共用列表
function getShopListAsync(channel, params) {
let resData = {};
return co(function* () {
let result = yield this.api.getShopInfo(params.shopId);
let shopInfo = result.data;
// 根据店铺ID,未取到店铺信息,跳转至首页
if (result.code !== 200 || _.isEmpty(shopInfo)) {
return {redirect: helpers.urlFormat('')};
}
if (+shopInfo.shop_template_type === 2) { // 经典店铺
resData = yield this._getShopListData(channel, params, result);
} else {
resData = yield this._getBaseShopData(channel, params, shopInfo);
}
return Object.assign(resData, {templateType: +shopInfo.shop_template_type});
}).bind(this)();
}
function getShopGoodsData(shopId, channel, params) {
let gender = _getGender(channel);
let resData = {};
... ... @@ -543,9 +575,10 @@ module.exports = class extends global.yoho.BaseModel {
this._getShopData = _getShopData.bind(this);
this._getBaseShopData = _getBaseShopData.bind(this);
this._getShopListData = _getShopListData.bind(this);
this.getShopInfoAsync = getShopInfoAsync.bind(this);
this.getShopListInfoAsync = getShopListInfoAsync.bind(this);
this.getShopListAsync = getShopListAsync.bind(this); // 基础店铺&经典店铺共用列表
this.getShopGoodsData = getShopGoodsData.bind(this);
}
... ...
... ... @@ -136,7 +136,9 @@ router.post('/index/getAdnav', list.getAdnav); // 品牌页系列
router.get('/shop', shop.index); // 店铺首页
// router.get('/shop/:domain/:shopId.html', shop.index); // 店铺首页
router.get('/shop/:shopInfo.html', shop.index); // 店铺首页
router.get('/shoplist', shop.list); // 店铺列表页
router.get('/shop/:shopInfo', shop.list); // 店铺列表页
router.get('/shop/:shopInfo/:pathQs', paramParse, shop.list); // 店铺列表页
// router.get('/shoplist', shop.list); // 店铺列表页
router.get('/shop/article', shop.article); // 店铺推荐文章
router.post('/shop/togglecollect', favorite.collectShop); // 店铺收藏
router.post('/index/isFavoriteShop', favorite.isFavShop); // 判断用户是否收藏品牌
... ...
... ... @@ -13,9 +13,11 @@ const MOBILE_DOMAIN = '//guang.m.yohobuy.com';
module.exports = [
{
type: TYPE.redirect,
origin: /\/product\/sale\/\?channel=(.*)/,
target: (req, match, channel) => {
return helpers.urlFormat(`/product/${channel}-sale/`);
origin: /^\/product\/sale(\/|())\?channel=(.*)/,
target: (req) => {
let channel = req.query.channel || req.yoho.channel;
return helpers.urlFormat(`/${channel}-sale/`);
}
},
{
... ...
... ... @@ -26,6 +26,7 @@ const minToFullMap = {
lt: 'limit',
mi: 'misort',
ms: 'msort',
nb: 'navBar',
nw: 'new',
od: 'order',
ol: 'outlets',
... ...