'use strict';
const helpers = global.yoho.helpers;
const Promise = require('bluebird');
const _ = require('lodash');
const sm = require('sitemap');
const staticUrls = require('../../../config/staticUrls');
const api = global.yoho.API;
const Service = global.yoho.ServiceAPI;
const headerModel = require('../../../doraemon/models/header');
const getStaticUrls = (currentStatics) => {
let urls = [];
_.forEach(_.get(currentStatics, 'loc', []), url => {
urls.push({
url: url,
changefreq: currentStatics.changefreq,
priority: currentStatics.priority
});
});
_.forEach(currentStatics, (value) => {
_.forEach(value.loc, url => {
urls.push({
url: url,
changefreq: value.changefreq,
priority: value.priority
});
});
});
return Promise.resolve(urls);
};
// www 地图数据
const wwwXmlData = () => {// eslint-disable-line
return getStaticUrls(_.get(staticUrls, 'www'));
};
// list 地图数据
const listXmlData = () => {// eslint-disable-line
return Promise.all([getStaticUrls(_.get(staticUrls, 'list')), headerModel.requestHeaderData()]).then(result => {
// 获取导航中的列表链接
let listNav = [],
listPatten = /list\.yohobuy\.com/;
_.forEach(_.get(result[1], 'headerData.subNavGroup'), val => {
_.forEach(val.subNav, sub => {
if (listPatten.test(sub.link)) {
listNav.push({url: sub.link, changefreq: 'daily', priority: 0.3});
}
_.forEach(_.get(sub, 'thirdNav'), third => {
if (listPatten.test(third.link)) {
listNav.push({url: third.link, changefreq: 'daily', priority: 0.3});
}
});
});
});
return _.union(result[0], _.uniqBy(listNav, 'url'));
});
};
// item 地图数据
const itemXmlData = () => {// eslint-disable-line
let urls = [];
return api.get('', {method: 'web.product.bdPromotion'}, {cache: 86400}).then(res => {
_.forEach(_.get(res, 'data', ''), val => {
urls.push({
url: `https:${helpers.getUrlBySkc(val.id)}`,
changefreq: 'daily',
priority: 0.3
});
});
return urls;
});
};
const getArticleUrls = () => {
let urls = [];
return Service.get('/guang/api/v2/article/getLastArticleList', {limit: 1000}, {cache: 86400}).then(res => {
_.forEach(_.get(res, 'data.artList', ''), val => {
urls.push({
url: `https:${helpers.urlFormat(`/${val.articleId}.html`, '', 'guang')}`,
changefreq: 'daily',
priority: 0.3
});
});
return urls;
});
};
// guang 地图数据
const guangXmlData = () => {// eslint-disable-line
return Promise.all([getStaticUrls(_.get(staticUrls, 'guang')), getArticleUrls()]).then(res => {
return _.union(res[0], res[1]);
});
};
// 站点地图
const siteMap = (req, res, next) => {
let siteList = ['www', 'list', 'item', 'guang'],
subdomain = req.subdomains[0] || 'www';
if (_.find(siteList, subdomain)) {
res.end('end');
return;
}
eval(subdomain + 'XmlData')().then(urls => {// eslint-disable-line
sm.createSitemap({
hostname: `https://${subdomain}.yohobuy.com`,
xmlNs: ' ',
urls: urls
}).toXML(function(err, xml) {
if (err) {
return res.status(500).end();
}
res.header('Content-Type', 'application/xml');
res.send(xml);
});
}).catch(next);
};
module.exports = {
siteMap
};
... ...
... ... @@ -31,5 +31,4 @@ router.get('/material/getRecommendlist', auth, materialController.getRecommendli
router.get('/activate-count', auth, activate.index);
router.get('/activate-count/getList', auth, activate.getList);
router.get('/questionnaire/:id', auth, questionnaire.getQuestionnaire);
module.exports = router;
... ...
... ... @@ -10,20 +10,7 @@
s0.parentNode.insertBefore(s, s0);
})(document);
</script>
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{event: "setAccount", account: 16184},
{event: "setCustomerId", id: "{{uid}}"},
{event: "setSiteType", type: "d"},
{event: "viewBasket", item: [
{{# cart.criteo}}
{"id":"{{id}}","quantity":"{{quantity}}","price":"{{price}}"},
{{/ cart.criteo}}
]}
);
</script>
<!-- 聚效 -->
<script type="text/javascript">
var _mvq = window._mvq || [];
... ...
... ... @@ -11,6 +11,8 @@ const cRoot = './controllers';
// Your controller here
const channelController = require(`${cRoot}/index`);
const sitemap = require('../3party/controllers/sitemap');
// 频道页路由
router.get('/', channelController.index);
... ... @@ -27,4 +29,7 @@ router.get('/channel/isNewUserAjax', channelController.hasNewUserFloor);
router.post('/common/getNewArrival', channelController.getNewArrival);
router.get('/guide', channelController.getIndexGuide);
// www站点地图
router.get('/sitemap.xml', sitemap.siteMap);
module.exports = router;
... ...
<script>
window.onload = function() {
var hm = document.createElement("script");
hm.src = "//static.criteo.net/js/ld/ld.js";
hm.async = 1;
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
var u = _ozuid || "";
u = (u == 0) ? "" : u;
window.criteo_q = window.criteo_q || [];
window.criteo_q.push({event: "setAccount", account: 16184 },{event: "setCustomerId", id: u},{event: "setSiteType", type: "d" },{event: "viewHome" });
};
</script>
... ...
... ... @@ -10,6 +10,7 @@ const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const guangController = require(`${cRoot}/index`);
const sitemap = require('../3party/controllers/sitemap');
router.get(['/', '/index/index'], guangController.index);
router.get(['/detail/:id', '/info/index'], guangController.detail); // guang/info/index
... ... @@ -28,4 +29,7 @@ router.get('/info/detailData', guangController.detailDynamicData);
// router.get('/info/commentData', guangController.detailCommentData);
// guang站点地图
router.get('/sitemap.xml', sitemap.siteMap);
module.exports = router;
... ...
... ... @@ -22,14 +22,7 @@ const config = global.yoho.config;
*/
const index = (req, res, next) => {
let params = req.query;
let resData = {
title: '潮流商品搜索 | YOHO!BUY 有货',
keywords: 'Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,' +
'品牌服饰,男士护肤,黑框眼镜,匡威,板鞋,i.t,izzue,5cm,eastpak,vans,lylescott,g-shock,' +
'new balance,lacoste,melissa,casio,卡西欧手表,舒雅,jasonwood,odm,AAAA,香港购物,日本潮流',
description: '潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜'
};
let resData = {};
search.getKeyActivity(params.query).then(activityUrl => {
if (activityUrl) {
... ... @@ -40,12 +33,20 @@ const index = (req, res, next) => {
return search.getSearchData(Object.assign(params, {uid: req.user.uid, prid: req.user.prid}),
req.yoho.channel).then(result => {
let queryKey = req.query.query;
Object.assign(resData, result);
if (!_.get(resData, 'search.goods') || !_.get(resData, 'search.goods').length) {
_.set(resData, 'search.keyWord', req.query.query);
_.set(resData, 'search.keyWord', queryKey);
return res.render('search/no-result', resData);
}
Object.assign(resData, {
title: `${queryKey}价格_图片_品牌_怎么样-YOHO!BUY有货`,
keywords: `${queryKey},${queryKey}价格,${queryKey}图片,${queryKey}怎么样,${queryKey}品牌,YOHO!BUY有货`,
description: `YOHO!BUY有货网yohobuy.com是国内专业的${queryKey}网上潮流购物商城,为您找到${_.get(resData, 'search.totalCount', 0)}${queryKey}、产品的详细参数,实时报价,价格行情,图片、评价、品牌等信息。买${queryKey},就上YOHO!BUY有货` // eslint-disable-line
});
res.render('search/index', resData);
});
... ...
... ... @@ -151,8 +151,6 @@ const getListData = (params, channel) => {
Object.assign(finalResult.list.leftContent, searchHandler.handleSortAds(result[4].data));
}
finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.list, 'goods'))};
let seo = searchHandler.getListSeo(channel,
_.get(finalResult, 'list.leftContent.allSort.list'),
_.get(finalResult, 'list.filters.checkedConditions.conditions'));
... ... @@ -360,8 +358,6 @@ const getBrandData = (params, extra, channel) => {
_.get(result[3], 'data.coupons', []), {brandId: extra.brandId});
}
finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.brand, 'goods'))};
let seo = searchHandler.getBrandShopSeo(channel, extra, params);
return Object.assign({}, seo, finalResult);
... ...
... ... @@ -336,7 +336,7 @@ exports.handleOptsData = (params, total, extra) => {
};
// 用来标记是否是折扣专场,折扣专场只需要前三个排序参数
let count = (extra === 'discont') ? 3 : 4;
let count = (extra === 'discont') ? 4 : 5;
for (let i = 0; i < count; i++) {
let opt = {};
... ... @@ -361,6 +361,16 @@ exports.handleOptsData = (params, total, extra) => {
}
break;
case 1:
opt.name = '人气';
opt.href = handleFilterUrl(params, {order: 'h_v_desc'}, {page: true});
if (params.order === 'h_v_desc') {
opt.active = true;
} else {
opt.active = false;
}
break;
case 2:
if (params.order !== 's_t_desc' && params.order !== 's_t_asc') {
opt.href = handleFilterUrl(params, {order: 's_t_desc'}, {page: true});
opt.hasSortOrient = true;
... ... @@ -378,7 +388,7 @@ exports.handleOptsData = (params, total, extra) => {
opt.name = '最新';
break;
case 2:
case 3:
if (params.order !== 's_p_desc' && params.order !== 's_p_asc') {
opt.href = handleFilterUrl(params, {order: 's_p_desc'}, {page: true});
opt.hasSortOrient = true;
... ... @@ -396,7 +406,7 @@ exports.handleOptsData = (params, total, extra) => {
opt.name = '价格';
break;
case 3:
case 4:
if (params.order !== 'p_d_desc' && params.order !== 'p_d_asc') {
opt.href = handleFilterUrl(params, {order: 'p_d_desc'}, {page: true});
opt.hasSortOrient = true;
... ...
... ... @@ -10,6 +10,7 @@ const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const auth = require(`${global.middleware}/auth`);
const gbk2utf = require(`${global.middleware}/gbk2utf`);
const sitemap = require('../3party/controllers/sitemap');
// 商品详情controller
const detail = require(`${cRoot}/detail`);
... ... @@ -134,4 +135,8 @@ router.get('/students/list', students.list); // 获取优惠券领取状态
// 新品到着改版
router.get('/newArrive', newArrive.index); // 获取优惠券领取状态
// list&item 站点地图
router.get('/sitemap.xml', sitemap.siteMap);
module.exports = router;
... ...
... ... @@ -2,5 +2,4 @@
{{# brand}}
{{> list/list}}
{{/brand}}
{{> common/criteo}}
</div>
... ...
... ... @@ -8,5 +8,4 @@
{{> list/list}}
{{/list}}
{{> common/criteo}}
</div>
... ...
... ... @@ -30,4 +30,3 @@
</div>
</div>
</div>
{{> common/criteo}}
... ...
... ... @@ -11,5 +11,4 @@
{{/ saleList}}
</div>
</div>
{{> common/criteo}}
{{/ result}}
... ...
... ... @@ -4,5 +4,4 @@
{{> list/list}}
{{/search}}
{{> common/criteo}}
</div>
... ...
{{# criteo}}
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{ event: "setAccount", account: [16184] },
{ event: "setSiteType", type: "d" },
{ event: "viewList", item: [{{#each skn}}"{{.}}"{{#unless @last}},{{/unless}}{{/each}}]}
);
</script>
{{/ criteo}}
\ No newline at end of file
{{# brandBanner}}
<div class="brand-banner">
<div class="banner-img" style="height: {{bannerHeight}}px;background: url({{image2 banner}})"></div>
<div class="banner-img" style="height: {{bannerHeight}}px;background: url({{image2 banner q=100}})"></div>
<div class="opt-wrap">
<p class="opt center-content">
<a href="{{brandHome}}">
... ... @@ -22,7 +22,7 @@
{{# shopBanner}}
<div class="brand-banner base-shop-banner">
<div class="banner-img" style="height: {{bannerHeight}}px;background: url({{image2 banner}})"></div>
<div class="banner-img" style="height: {{bannerHeight}}px;background: url({{image2 banner q=100}})"></div>
<div class="opt-wrap">
<div class="opt center-content">
{{#if showShopName}}
... ...
{{# statGoodsInfo}}
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{event: "setAccount", account: 16184},
{event: "setCustomerId", id: "{{uid}}"},
{event: "setSiteType", type: "d"},
{event: "viewItem", item: "{{skn}}"}
);
</script>
<script type="text/javascript">
var _mvq = _mvq || [];
_mvq.push(['$setAccount', 'm-23428-1']);
... ...
{{# criteo}}
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{ event: "setAccount", account: [16184] },
{ event: "setSiteType", type: "d" },
{ event: "trackTransaction" , id: "{{order_code}}", item: [
{{#each items}}
{ id: "{{product_skn}}", price: "{{goods_price}}", quantity: "{{buy_number}}"}
{{#unless @last}}
,
{{/unless}}
{{/each}}
]}
);
</script>
{{/ criteo}}
... ...
/**
* pc/wap站静态url 用于站点地图
*
*/
const moment = require('moment');
const today = moment().format('Y-M-D');
module.exports = {
www: {
// 频道
channel: {
loc: ['https://www.yohobuy.com/', 'https://www.yohobuy.com/girls/', 'https://www.yohobuy.com/kids/', 'https://www.yohobuy.com/lifestyle/'],
lastmod: today,
changefreq: 'daily',
priority: 0.8
},
// 品牌一览
brands: {
loc: ['https://www.yohobuy.com/boys-brands/', 'https://www.yohobuy.com/girls-brands/', 'https://www.yohobuy.com/kids-brands/', 'https://www.yohobuy.com/lifestyle-brands/'],
lastmod: today,
changefreq: 'daily',
priority: 0.5
},
// 领券中心
coupon: {
loc: ['https://www.yohobuy.com/coupon/'],
lastmod: today,
changefreq: 'weekly',
priority: 0.3
},
// sale
salse: {
loc: ['https://www.yohobuy.com/product/boys-sale/', 'https://www.yohobuy.com/product/girls-sale/', 'https://www.yohobuy.com/product/kids-sale/', 'https://www.yohobuy.com/product/lifestyle-sale/'],
lastmod: today,
changefreq: 'daily',
priority: 0.3
}
},
list: {
// 新品到着
new: {
loc: ['https://list.yohobuy.com/boys-new/', 'https://list.yohobuy.com/girls-new/', 'https://list.yohobuy.com/kids-new/', 'https://list.yohobuy.com/lifestyle-new/'],
lastmod: today,
changefreq: 'daily',
priority: 0.5
},
// 分类列表
category: {
loc: [],
lastmod: today,
changefreq: 'daily',
priority: 0.3
}
},
// 搜索列表
search: {
loc: ['https://search.yohobuy.com/'],
lastmod: today,
changefreq: 'daily',
priority: 0.3
},
// 逛 编辑列表/标签列表/逛详情动态添加
guang: {
loc: ['https://guang.yohobuy.com/boys/', 'https://guang.yohobuy.com/girls/', 'https://guang.yohobuy.com/kids/', 'https://guang.yohobuy.com/lifestyle/'],
lastmod: today,
changefreq: 'daily',
priority: 0.3
},
// 商品详情动态添加
item: {
loc: [],
lastmod: today,
changefreq: 'daily',
priority: 0.3
}
};
... ...
... ... @@ -31,6 +31,7 @@ module.exports = [
origin: '/new?order=s_t_desc&msort=10',
target: helpers.urlFormat('/lifestyle-new/', null, 'list')
},
// 男生销售类目一级菜单
{
type: TYPE.redirect,
... ... @@ -52,6 +53,7 @@ module.exports = [
origin: '/?gender=1,3&msort=8',
target: helpers.urlFormat('/?category_id=17&gender=1,3', null, 'list')
},
// 女生销售类目一级菜单
{
type: TYPE.redirect,
... ... @@ -73,12 +75,14 @@ module.exports = [
origin: '/?gender=2,3&msort=8,10,241',
target: helpers.urlFormat('/?category_id=76&gender=2,3', null, 'list')
},
// 潮童销售类目一级菜单
{
type: TYPE.redirect,
origin: '/?gender=1,2,3&misort=382,368,372,448,392,388,384,414,429,390,425,464&msort=365',
target: helpers.urlFormat('/?category_id=13,16,15&gender=1,2,3', null, 'list')
},
// 创意生活销售类目一级菜单
{
type: TYPE.redirect,
... ...
{
"name": "yohobuy-node",
"version": "5.7.1",
"version": "5.7.2",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ... @@ -48,6 +48,7 @@
"request-ip": "^1.2.2",
"request-promise": "^3.0.0",
"serve-favicon": "^2.3.0",
"sitemap": "^1.12.0",
"urlencode": "^1.1.0",
"uuid": "^2.0.2",
"yoho-express-session": "^2.0.0",
... ...
... ... @@ -61,7 +61,7 @@ module.exports = function(imageUrl, opts) {
} else {
query = 'imageView2/2/interlace/1/q/' + (params.q || 75);
}
return uri + '?' + query + '|imageslim';
return uri + '?' + query;
} else {
return imageUrl;
}
... ...
... ... @@ -61,7 +61,7 @@ module.exports = {
} else {
query = 'imageView2/2/interlace/1/q/' + (params.q || 75);
}
return uri + '?' + query + '|imageslim';
return uri + '?' + query;
} else {
return '';
}
... ...