Authored by 徐炜

商品搜索结果列表页优化

... ... @@ -215,8 +215,17 @@ const shopFav = (req, res) => {
const category = (req, res, next) => {
let params = Object.assign({}, req.query);
// 获取第一页数据
searchModel.getSearchData(Object.assign({page: 1, limit: 6}, params)).then((firstPageGoodsList) => {
// 获取第一页数据做服务端渲染
let initialData = {
gender: params.gender,
sort: parseInt(params.sort),
type: 'default',
order: '0',
page: 1,
limit: 6,
};
searchModel.getSearchData(initialData).then((firstScreenGoodsList) => {
res.render('search/goods-list', {
_noLazy: true, // 首屏不使用lazyload
module: 'product',
... ... @@ -225,7 +234,7 @@ const category = (req, res, next) => {
navTitle: req.query.title || req.query.sort_name
}),
goodList: params,
firstPageGoodsList: firstPageGoodsList,
firstPageGoodsList: firstScreenGoodsList,
showDownloadApp: true,
pageFooter: true
});
... ... @@ -408,7 +417,6 @@ const favoriteBrand = (req, res, next) => {
let url = helpers.urlFormat('/signin.html') + '?refer=' + refer;
if (appVersion && appVersion !== 'false') {
uid = req.query.uid ? crypto.decrypt('', req.query.uid) : req.cookies.appUid;
uid = parseInt(uid, 10);
... ...
... ... @@ -37,30 +37,25 @@ const list = (req, res, next) => {
params.shopId = params.shop_id;
}
// 获取第一页数据做服务端渲染
let initialData = {
query: query,
type: 'default',
order: '0',
page: 1,
limit: 6,
};
/* 判断是不是品牌, 是品牌跳到品牌列表页(显示搜索框),判断是不是品类, 是品类加导航标题(不显示搜索框) */
Promise.all([
searchModel.getAllBrandNames(),
searchModel.getClassNames()
searchModel.getBrandDomain(query),
searchModel.getClassNames(),
searchModel.getSearchData(initialData)
]).then(result => {
if (query) {
query = query.toLowerCase();
_.forEach(result[0], obj => {
if (query === obj.brandDomain) { // 精确查品牌域名
domain = query;
return false;
}
if (query === obj.brandName || query === obj.brandName || query === obj.brandName) { // 精确查品牌名称
domain = obj.brandDomain;
return false;
}
// if (obj.brandDomain.indexOf(query) > 0) { // 模糊查品牌域名
// domain = obj.brandDomain;
// return false;
// }
});
domain = result[0];
// 跳转到品牌商品列表页
if (domain !== null && !params.shop_id) {
... ... @@ -115,6 +110,7 @@ const list = (req, res, next) => {
title = params.title ? params.title : title;
res.render('search/list', {
_noLazy: true,
module: 'product',
page: 'search-list',
pageHeader: headerModel.setNav({
... ... @@ -122,6 +118,7 @@ const list = (req, res, next) => {
}),
title: title,
goodList: params,
firstPageGoodsList: result[2] || [],
pageFooter: true
});
}).catch(next);
... ... @@ -183,6 +180,11 @@ const search = (req, res, next) => {
params.isApp = req.yoho.isApp;
searchModel.getSearchData(params).then((result) => {
if (params.page === 1 && params.start > 0) {
// 首屏渲染时,使用 'start' 参数裁减已渲染数据
result = result.slice(params.start || 0);
}
res.render('search/page', {
layout: false,
new: result
... ...
... ... @@ -11,6 +11,8 @@ const _ = require('lodash');
const logger = global.yoho.logger;
const api = global.yoho.API;
const camelCase = global.yoho.camelCase;
const cache = require('memory-cache');
/**
* 封面图
... ... @@ -28,6 +30,8 @@ const _coverChannel = {
*/
const _processBrandNames = (list) => {
const formatData = [];
const brandDomainMap = {}, brandNameMap = {};
const ttl = 60000; // 默认缓存一分钟
list = list || [];
list = camelCase(list);
... ... @@ -38,9 +42,15 @@ const _processBrandNames = (list) => {
brandDomain: obj.brandDomain && obj.brandDomain.toLowerCase(),
brandName: obj.brandDomain && obj.brandName.toLowerCase()
});
brandDomainMap[obj.brandDomain] = obj.brandDomain;
brandNameMap[obj.brandName] = obj.brandDomain;
});
});
cache.put('brandDomainMap', brandDomainMap, ttl);
cache.put('brandNameMap', brandNameMap, ttl);
return formatData;
};
... ... @@ -284,6 +294,39 @@ const searchKeyActivity = (params) => {
});
};
/**
* 检查字符串是否是品牌域/品牌名称
*
* @param query
* @returns {*|Promise.<TResult>}
*/
const getBrandDomain = (query) => {
const brandDomainMap = cache.get('brandDomainMap');
const brandNameMap = cache.get('brandNameMap');
const fn = () => {
let ret = null;
if (!_.isEmpty(brandDomainMap) && brandDomainMap.hasOwnProperty(query)) {
ret = brandDomainMap[query] || null;
}
if (!_.isEmpty(brandNameMap) && brandNameMap.hasOwnProperty(query)) {
ret = brandNameMap[query] || null;
}
return Promise.resolve(ret);
};
if (brandDomainMap && brandNameMap) {
logger.debug('Using cached brand data.');
return fn();
} else {
logger.debug('Reloading brand data...');
return getAllBrandNames().then(fn);
}
};
module.exports = {
getSearchData,
getFilterData,
... ... @@ -292,5 +335,6 @@ module.exports = {
getClassNames,
getSearchIndex,
getFuzzyDatas,
searchKeyActivity
searchKeyActivity,
getBrandDomain
};
... ...
<div class="good-list-page yoho-page">
{{#firstPageGoodsList}}
{{> common/goods}}
{{/firstPageGoodsList}}
{{> search/list}}
</div>
... ...
... ... @@ -133,6 +133,11 @@
</div>
<div id="goods-container" class="goods-container">
<div class="firstscreen-goods container clearfix">
{{#@root.firstPageGoodsList}}
{{> common/goods}}
{{/@root.firstPageGoodsList}}
</div>
<div class="default-goods container clearfix"></div>
<div class="new-goods container clearfix"></div>
<div class="sale-goods container clearfix"></div>
... ...
... ... @@ -29,7 +29,7 @@
<div class="good-detail-img">
<a class="good-thumb" href="{{url}}">
{{#if @root._noLazy}}
<img src="{{image default_images 235 314}}" width="470" height="628"/>
<img src="{{image default_images 235 314}}"/>
{{else}}
<img class="lazy" data-original="{{image default_images 235 314}}"/>
{{/if}}
... ...
... ... @@ -39,7 +39,7 @@
"request-promise": "^3.0.0",
"serve-favicon": "^2.3.0",
"uuid": "^2.0.3",
"yoho-node-lib": "0.1.30",
"yoho-node-lib": "^0.2.0",
"yoho-zookeeper": "^1.0.4"
},
"devDependencies": {
... ... @@ -97,4 +97,4 @@
"yoho-qs": "^1.0.1",
"yoho-swiper": "^3.3.1"
}
}
\ No newline at end of file
}
... ...
... ... @@ -9,7 +9,6 @@ var $ = require('yoho-jquery'),
ellipsis = require('yoho-mlellipsis'),
lazyLoad = require('yoho-jquery-lazyload');
// 品牌页参数
var $brandHeader = $('#brand-header'),
$introBox = $('#intro-box');
... ... @@ -43,6 +42,9 @@ var size, color, style, standard, gender, price, p_d, query, limited, specialoff
// 默认筛选条件
var defaultOpt = require('../../common/query-param');
// 首屏加载标志
var firstScreen = $('.firstscreen-goods').children().size() > 0;
var $listNav = $('#list-nav'),
// 导航数据信息
... ... @@ -201,7 +203,7 @@ function getQueryString(name) {
var r = window.location.search.substr(1).match(reg);
if (r !== null) {
return window.unescape(r[2]);
return decodeURIComponent(r[2]);
}
return null;
}
... ... @@ -441,6 +443,11 @@ function search(opt) {
params.promotion = promotion;
}
if (firstScreen) {
// 如果首屏加载了,则去掉6条记录
params.start = 6;
}
$.extend(setting, defaultOpt, params);
searching = true;
loading.showLoadingMask();
... ... @@ -539,6 +546,9 @@ function search(opt) {
}
});
// 还原参数
params.start = 0;
firstScreen = false;
}
require('../../common/suspend-cart'); // 悬浮购物车
... ...