Authored by 毕凯

Merge branch 'gray' of git.yoho.cn:fe/yohobuywap-node into gray

Showing 51 changed files with 316 additions and 133 deletions
... ... @@ -5,7 +5,7 @@
{{# list}}
<li class="swiper-slide">
<a href="{{url}}">
<img src="{{image2 img q=60}}" alt="">
<img src="{{image2 img q=60}}" alt="{{textCn}}">
</a>
<span class="brands-title">{{textCn}}</span>
</li>
... ...
... ... @@ -270,12 +270,21 @@ const index = (req, res, next) => {
let shareInfo = _shareInfo(id, detail.getArticle);
Object.assign(guang, shareInfo);
data.title = detail.getArticle.article_title + ' | Yoho!Buy有货 | 潮流购物逛不停';
data.title = detail.getArticle.article_title + '-YOHO!BUY 有货网';
data.title_more = true;
data.description = detail.getArticle.article_summary;
data.description = detail.getArticle.descriptionText;
data.description_more = true;
}
if (detail.getArticle.article_title) {
parameter.tltle = detail.getArticle.article_title + '-YOHO!BUY 有货网';
parameter.keywords = detail.getArticle.article_title;
}
if (detail.getArticle.descriptionText) {
parameter.description = detail.getArticle.descriptionText;
}
// 标识有微信分享
data.hasWxShare = true;
... ...
... ... @@ -21,6 +21,34 @@ const channels = {
lifestyle: 4
};
const listTDK = {
0: {
title: '最新潮流文章,逛最新潮流资讯-YOHO!BUY 有货网',
keywords: '最新潮流文章,潮流资讯,逛潮流',
description: '有货网每天提供全球最新最潮的潮流文章资讯,宣传潮流商品,潮流文化,潮流品牌等信息,想更多了解潮流最新资讯就来有货网!'
}, // 最新
1001: {
title: '高人气潮流文章,逛人气潮流资讯-YOHO!BUY 有货网',
keywords: '人气潮流文章,潮流人气,逛潮流人气',
description: '有货网每天提供全球人气最高的潮流文章资讯,宣传潮流商品,潮流文化,潮流品牌等信息,想更多了解高人气潮流资讯就来有货网!'
}, // 人气
2: {
title: '各种潮流搭配,逛潮流搭配资讯-YOHO!BUY 有货网',
keywords: '搭配潮流文章,潮流搭配',
description: '有货网每天提供全球最新最潮的潮流搭配文章资讯,宣传潮流商品,潮流文化,潮流品牌等信息,想更多了解学习潮流搭配资讯就来有货网!'
}, // 搭配
4: {
title: '潮流品牌,逛各种潮流品牌资讯-YOHO!BUY 有货网',
keywords: '逛潮品,潮流潮品,潮品资讯',
description: '有货网每天提供全球最新最潮的潮流潮品文章资讯,宣传潮流商品,潮流文化,潮流品牌等信息,想更多了解学习潮流潮品资讯就来有货网!'
}, // 潮品
22: {
title: '潮流视频,欣赏最新最好玩的潮流视频-YOHO!BUY 有货网',
keywords: '潮流视频,看潮流',
description: '有货网每天提供全球最新最潮最精彩的潮流视频,宣传潮流商品,潮流文化,潮流品牌等信息,想更多欣赏潮流视频就来有货网!'
} // 视频
};
/**
* [编辑页面]
*/
... ... @@ -68,9 +96,9 @@ const editor = (req, res, next) => {
res.render('index/list', Object.assign({
page: 'index-editor',
title: `潮流编辑${name}|YOHO!BUY有货`,
keywords: `潮流编辑${name}`,
description: `YOHO!BUY有货潮流编辑${name}!`,
title: `【${name}】潮流编辑${name}-YOHO!BUY 有货网`,
keywords: `${name},潮流编辑${name},潮流编辑`,
description: `有货逛潮流,潮流编辑${name}分享大量原创潮流资讯,掌握大量不同类别的潮流文化知识信息,尽在有货逛潮流。`,
guangList: true,
gender: gender,
guang: {
... ... @@ -196,9 +224,9 @@ const index = (req, res, next) => {
let responseData = {
module: 'guang',
page: 'index',
title: '逛|逛潮流,逛购物,官方授权正品潮流购物中心|YOHO!BUY有货',
keywords: '逛,逛潮流,逛购物',
description: 'YOHO!BUY有货逛频道,来YOHO!玩潮流!潮搭大解析!年轻人潮流购物中心,中国潮流购物风向标,吴亦凡重磅代言!YOHO!BUY有货100%正品保证,支持货到付款。',
title: '逛潮流,最新原创潮流资讯 |YOHO!BUY有货',
keywords: '潮流资讯,潮流文章,有货潮流分享',
description: '来有货玩潮流,潮流资讯大分享!年轻人潮流购物中心,了解潮流趋势、掌握潮流文化知识信息,尽在有货逛潮流!',
showFooterTab: footerModel.getUrlData('guang')
};
... ... @@ -209,6 +237,8 @@ const index = (req, res, next) => {
gender: req.query.gender || req.query.channel && typeLib.gender[req.query.channel] || '1,3'
};
responseData = Object.assign(responseData, listTDK[param.type]);
req.ctx(IndexModel).getArticle(param).then(result => {
if (result && result.guang && result.guang.infos) {
if (!result.guang.infos.length) {
... ... @@ -243,9 +273,9 @@ const tag = (req, res, next) => {
pageHeader: headerData,
module: 'guang',
page: 'index-editor',
title: tagTitle + ' | Yoho!Buy有货 | 潮流购物逛不停',
keywords: tagTitle,
description: 'YOHO!BUY有货潮流' + tagTitle + '!'
title: '【' + tagTitle + '】' + tagTitle + '潮流资讯-YOHO!BUY 有货网',
keywords: tagTitle + ',' + tagTitle + '潮流资讯,' + tagTitle + '文章',
description: '来有货逛潮流,' + tagTitle + '潮流资讯大分享!了解' + tagTitle + '潮流趋势,掌握' + tagTitle + '潮流文化知识信息,尽在有货逛潮流。'
};
let param = {
... ...
... ... @@ -7,6 +7,7 @@
const serviceAPI = global.yoho.ServiceAPI;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const redis = require('../../../utils/redis');
const URI_PACKAGE_ARTICLE = 'guang/service/v2/article/';
const URI_PACKAGE_AUTHOR = 'guang/service/v1/author/';
... ... @@ -204,6 +205,21 @@ class DetailModel extends global.yoho.BaseModel {
});
}
// 获取逛文章分词内容
_getGuangArticleKeyword(id) {
return redis.all([
['get', `global:yoho:guang:detail:${id}`]
]).then(redisData => {
redisData = JSON.parse(redisData[0] || '{}');
if (!redisData.data) {
return this._getArticleContent(id);
}
return redisData;
});
}
/**
* [逛资讯详情页数据封装]
* @param {[int]} id [内容ID]
... ... @@ -229,7 +245,7 @@ class DetailModel extends global.yoho.BaseModel {
let article = result.getArticle = data && data.data || {};
let promises = [
this._getAuthor(article.author_id),
this._getArticleContent(id),
this._getGuangArticleKeyword(id),
this._getBrand(id)
];
... ... @@ -260,7 +276,19 @@ class DetailModel extends global.yoho.BaseModel {
}
if (datas[1]) {
let textPosition = 1,
descriptionText;
result.getArticleContent = getArticleContent = datas[1].data;
for (let i = 0; i < getArticleContent.length; i++) {
if (getArticleContent[i].text && textPosition === 1) {
descriptionText = getArticleContent[i].text.data.text;
result.getArticle.descriptionText = descriptionText.replace(/<\/?[^>]*>/g, '');
textPosition++;
}
}
}
if (isApp && datas[4] && datas[4].data) {
... ... @@ -330,6 +358,10 @@ class DetailModel extends global.yoho.BaseModel {
if (datas[2]) {
result.getBrand = datas[2].data;
_.forEach(result.getBrand, function(val) {
val.url = `//m.yohobuy.com/shop?domain=${val.brandDomain}`;
});
}
if (isShare && datas[4]) {
... ...
... ... @@ -7,6 +7,9 @@
{{type}}
</li>
{{/ navs}}
<li class="guang-nav-item news-jump" data-type=-1>
<a href='//m.yohobuy.com/guang/news' title='资讯'>资讯</a>
</li>
</ul>
<div id="info-list" class="info-list-container">
... ...
... ... @@ -17,7 +17,7 @@
{{# detail}}
<div class="detail" data-id="{{id}}">
<div class="post-title">
<p class="title">{{title}}</p>
<h1 class="title">{{title}}</h1>
{{> index/tvls}}
</div>
<div class="post-content">
... ... @@ -31,9 +31,9 @@
{{#if bigImage}}
<div class="post-block big-img-block">
{{#if noLazy}}
<img src={{image2 bigImage q=60}}>
<img src={{image2 bigImage q=60}} alt="{{@root.guang.detail.title}}">
{{else}}
<img class="lazy" data-original={{image2 bigImage q=60}}>
<img class="lazy" data-original={{image2 bigImage q=60}} alt="{{@root.guang.detail.title}}">
{{/if}}
{{#if tagList}}
<div class="tag-list-box">
... ... @@ -49,11 +49,11 @@
<div class="post-block small-img-block clearfix">
{{#if noLazy}}
{{# smallImage}}
<img src={{image2 src q=60}}>
<img src={{image2 src q=60}} alt="{{@root.guang.detail.title}}">
{{/ smallImage}}
{{else}}
{{# smallImage}}
<img class="lazy" data-original={{image2 src q=60}}>
<img class="lazy" data-original={{image2 src q=60}} alt="{{@root.guang.detail.title}}">
{{/ smallImage}}
{{/if}}
... ... @@ -153,7 +153,7 @@
<li class="brand buriedpoint" data-bp-id="guang_brand_{{name}}_0">
<a href={{url}}>
<div class="brand-logo">
<img class="lazy" data-original="{{image2 thumb q=60}}">
<img class="lazy" data-original="{{image2 thumb q=60}}" alt="{{name}}">
</div>
<p class="brand-name">{{name}}</p>
</a>
... ...
... ... @@ -19,9 +19,9 @@ exports.index = (req, res, next) => {
}
return res.render('news-index', Object.assign({
title: '新闻 | ' + (res.locals.title || ''),
title: '资讯 | ' + (res.locals.title || ''),
pageHeader: headerModel.setNav({
navTitle: '新闻'
navTitle: '资讯'
}),
module: 'news',
localCss: true,
... ... @@ -51,13 +51,13 @@ exports.detail = (req, res, next) => {
req.ctx(newsService).detail(channel, query).then(result => {
return res.render('news-detail', Object.assign({
pageHeader: headerModel.setNav({
navTitle: result.header && result.header.title || '新闻详情页'
navTitle: result.header && result.header.title || '资讯详情页'
}),
module: 'news',
localCss: true,
pageFooter: true,
page: 'detail',
cononical: {
canonical: {
currentHref: `//www.yohobuy.com${req.originalUrl}`
}
}, result));
... ...
... ... @@ -2,8 +2,10 @@
const _ = require('lodash');
const helpers = global.yoho.helpers;
const utils = '../../../utils';
const redis = require(`${utils}/redis`);
const NewsAPi = require('./news-api');
const utils = require('./utils');
const newsUtils = require('./utils');
const moment = require('moment');
const ATYPE = 'yohobuy4008899646,yohogroup,YOHO_GIRL,mars-app';
... ... @@ -24,7 +26,7 @@ module.exports = class extends global.yoho.BaseModel {
lresult = {
id: articleData.id,
url: helpers.urlFormat(`/news/${articleData.id}_${articleData.cid}.html`),
url: helpers.urlFormat(`/guang/news/${articleData.id}_${articleData.cid}.html`),
img: helpers.image(articleData.image, width, height, 1),
title: articleData.title,
publishTime: articleData.update_time && moment(articleData.update_time * 1000).format('MM月DD HH:mm'),
... ... @@ -80,15 +82,21 @@ module.exports = class extends global.yoho.BaseModel {
title: contents.title,
summary: contents.summary,
tag: contents.tag,
syncTypeName: contents.syncTypeName || 'YOHO潮流志',
publishTime: contents.update_time && moment(contents.update_time * 1000).format('MM月DD HH:mm'),
};
let content = utils.filterPhtml(contents.content, [
'阅读原文',
'点击这里',
'点这里'
]);
return {header: header, content: utils.filterAhtml(content)};
let content = newsUtils.filterPhtml(
contents.content.replace(/www.yohobuy.com\/chanpin\//ig, 'm.yohobuy.com/chanpin/'),
[
'阅读原文',
'点击这里',
'点这里'
]
);
content = newsUtils.filterAhtml(content);
return {header: header, content: newsUtils.imgAlt(content, contents.title, 5)};
}
detail(channel, param) {
... ... @@ -96,16 +104,25 @@ module.exports = class extends global.yoho.BaseModel {
id: param.id,
cid: param.cid
};
let newsAPi = new NewsAPi(this.ctx);
return newsAPi.getContentDetail(params).then(result => {
return redis.all([
['get', `global:yoho:news:detail:${params.id}-${params.cid}`]
]).then(redisData => {
redisData = JSON.parse(redisData[0] || '{}');
if (!redisData.data) {
return new NewsAPi(this.ctx).getContentDetail(params);
}
return redisData;
}).then(result => {
let responseData = {};
// 详情页数据
Object.assign(responseData, this._formatDetail(result, params));
// seo
let title = _.get(responseData, 'header.title', '新闻详情页');
let title = _.get(responseData, 'header.title', '资讯详情页');
let keywords = [];
let tags = _.compact(_.get(responseData, 'header.tag', []).map(el => {
return el.tag_name;
... ...
... ... @@ -23,7 +23,10 @@ const util = {
});
return $.html();
html = $.html();
$ = '';
return html;
},
// 过滤 a标签连接和删除html标签中的script和link脚本
... ... @@ -34,9 +37,33 @@ const util = {
let $ = cheerio.load(html, {decodeEntities: false});
$('a').attr('href', 'javascript:void(0);').css({cursor: 'text'});// eslint-disable-line
$('a').removeAttr('style').not('.a-anchor').attr('href', 'javascript:void(0);').css({cursor: 'text'});// eslint-disable-line
$('script,link').remove();
return $.html();
html = $.html();
$ = '';
return html;
},
// 过滤 a标签连接和删除html标签中的script和link脚本
imgAlt: (html, alt, num) => {
if (!html) {
return html;
}
let $ = cheerio.load(html, {decodeEntities: false});
_.each($('img').slice(0, num), item => {
let $dom = $(item);
$dom.attr('alt', $dom.attr('alt') || alt);
});
html = $.html();
$ = '';
return html;
}
};
... ...
... ... @@ -2,7 +2,7 @@
<div class="detail" data-id="{{id}}">
{{# header}}
<div class="post-title">
<p class="title">{{title}}</p>
<h1 class="title">{{title}}</h1>
{{> news-index/tvls}}
</div>
{{/header}}
... ...
<div class="time-view-like-share clearfix">
<i class="iconfont">&#xe603;</i>
{{publishTime}}&nbsp;&nbsp;&nbsp;&nbsp;
{{#if pageView}}
<i class="iconfont">&#xe602;</i>
<span class="page-view">{{pageView}}</span>
{{#if syncTypeName}}
<span class="page-view">来源于微信公众号:{{syncTypeName}}</span>
{{/if}}
<div class="like-share-container">
<i class="iconfont">&#xe603;</i>
{{publishTime}}&nbsp;&nbsp;&nbsp;&nbsp;
{{#if pageView}}
<i class="iconfont">&#xe602;</i>
<span class="page-view">{{pageView}}</span>
{{/if}}
{{#like}}
<i class="iconfont like-btn{{#isLiked}} like{{/isLiked}}">&#xe601;</i>
<span class="like-count">{{count}}</span>
... ...
... ... @@ -83,7 +83,7 @@ const keyId = (req, res, next) => {
description: `YOHO!BUY有货网yohobuy.com是国内专业的${queryKey}网上潮流购物商城,为您找到${_.get(result,
'total', 0)}${queryKey}、产品的详细参数,实时报价,价格行情,图片、评价、品牌等信息。买${queryKey},就上YOHO!BUY有货`,
pageFooter: true,
cononical: {
canonical: {
currentHref: `//www.yohobuy.com${req.originalUrl}`
}
});
... ...
... ... @@ -313,8 +313,8 @@ exports.index = (req, res, next) => {
title: result.goodsName,
pageFooter: true,
localCss: true,
cononical: {
currentHref: result.cononical
canonical: {
currentHref: result.canonical
}
});
}).catch(next);
... ...
... ... @@ -2,6 +2,7 @@
const headerModel = require('../../../doraemon/models/header');
const model = require('../models/global');
const _ = require('lodash');
const list = (req, res, next) => {
let brand = req.query.brand;
... ... @@ -84,6 +85,13 @@ const detail = (req, res, next) => {
let appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.globalpurchase","params":${JSON.stringify(appParams)}}`;
res.render('global/detail', {
title: (_.get(result, 'brand_info.brand_name', '') ? '【' + result.brand_info.brand_name + '】' : '') +
_.get(result, 'product_name', '') + '|YOHO!BUY 有货',
keywords: _.get(result, 'brand_info.brand_name', '') + ',' + _.get(result, 'brand_info.brand_name', '') +
'价格,' + _.get(result, 'brand_info.brand_name', '') + '图片,',
description: _.get(result, 'product_name', '') + ' 有货网仅售' + _.get(result, 'sales_price', '') + '元,购买' +
_.get(result, 'brand_info.brand_name', '') + ',了解' + _.get(result, 'brand_info.brand_name', '') +
'商品信息就上有货网!',
module: 'product',
page: 'global-detail',
pageHeader: headerModel.setNav({
... ...
... ... @@ -248,6 +248,9 @@ const category = (req, res, next) => {
_noLazy: true, // 首屏不使用lazyload
module: 'product',
page: 'search-list',
canonical: {
currentHref: 'https://www.yohobuy.com/list?' // TODO
},
pageHeader: headerModel.setNav({
navTitle: req.query.title || req.query.sort_name
}),
... ...
... ... @@ -62,13 +62,14 @@ const newDetail = {
pageHeader: headerData,
result: result,
page: 'new-detail',
title: `${result.brandName}|${result.sortName}|${result.goodsName}|YOHO!BUY 有货`,
keywords: result.brandName + result.sortName + ',' + result.brandName + '官网专卖店,' +
result.brandName + '官方授权店,' + result.brandName + '正品,' + result.brandName + '打折,' +
result.brandName + '折扣店,' +
result.brandName + '真品,' + result.brandName + '代购',
description: `YOHO!BUY 有货-${result.brandName}官方授权店,${result.goodsName}图片、报价、介绍。` +
`YOHO!BUY 有货${result.brandName}官网专卖店提供${result.brandName}正品、${result.brandName}真品、 ${result.brandName}打折、${result.brandName}代购等。`, // eslint-disable-line
canonical: {
currentHref: `//www.yohobuy.com${req.originalUrl}`
},
title: `【${result.brandName}${result.sortName}${result.goodsName}|YOHO!BUY 有货`,
keywords: result.brandName + result.sortName + ',' + result.brandName + result.sortName + '价格,' +
result.brandName + result.sortName + '图片,',
description: result.goodsName + ' 有货网仅售' + result.goodsPrice.currentPrice + '元,购买' +
result.brandName + result.sortName + ',了解' + result.brandName + result.sortName + '商品信息就上有货网!',
pageFooter: true,
localCss: true,
appPath: appPath,
... ...
... ... @@ -17,6 +17,18 @@ const stringProcess = require(`${utils}/string-process`);
const shopPrcs = require(`${utils}/shop-process`);
const co = require('bluebird').coroutine;
/**
* SEO 优化,页面 TDK
* @param {*} keyword
*/
const _tdkProcess = (keyword) => {
return {
title: `${keyword}| ${keyword}品牌旗舰店 |正品保证, YOHO!BUY 有货`,
keywords: `${keyword}${keyword}品牌旗舰店,${keyword}正品`,
description: `有货网${keyword}旗舰店销售${keyword}正品商品,100%质量保证,支持货到付款,想了解${keyword}价格、图片、评价等信息,就上YOHO!BUY 有货中国最大的潮流商品购物网站!`, // eslint-disable-line
};
};
const shop = {
/**
... ... @@ -199,7 +211,7 @@ const shop = {
let goodsList = productProcess.processProductList(_.get(goodsListApi, 'data.product_list', []));
res.render('newshop/shop-brand', {
res.render('newshop/shop-brand', _.assign({
module: 'product',
page: 'shop-brand',
pageHeader: headerModel.setNav({
... ... @@ -207,15 +219,12 @@ const shop = {
}),
showDownloadApp: true,
pageFooter: true,
title: title + '|' + title + '潮流服装服饰-Yoho!Buy有货',
keywords: title + ',' + title + '服装服饰,' + title + '潮流服装服饰',
description: title + '|Yoho!Buy有货' + title + '潮流服饰官方授权店!100%品牌正品保证,支持货到付款。',
brandId: brandId,
goodsList: goodsList,
shopPage: true,
_noLazy: true,
localCss: true
});
}, _tdkProcess(title)));
})().catch(next);
},
... ... @@ -253,10 +262,6 @@ const shop = {
shopInfo.shop_intro_link = helpers.urlFormat('/product/index/intro', { shop_id: shopId });
let finalResult = {
title: shopInfo.shop_name + '|' + shopInfo.shop_name + '潮流服装服饰-Yoho!Buy有货',
keywords: shopInfo.shop_name + ',' + shopInfo.shop_name + '服装服饰,' + shopInfo.shop_name + '潮流服装服饰',
description: shopInfo.shop_name + '|Yoho!Buy有货' + shopInfo.shop_name +
'潮流服饰官方授权店!100%品牌正品保证,支持货到付款。',
pageHeader: _.assign({
shopPage: {
text: '分类',
... ... @@ -288,7 +293,7 @@ const shop = {
if (domain) {
_.assign(finalResult, {
cononical: {
canonical: {
currentHref: `https://${domain}.m.yohobuy.com`
}
});
... ... @@ -299,7 +304,7 @@ const shop = {
res.render('newshop/shop-reds', _.assign(finalResult, {
shppFavHide: shppFavHide
}));
}, _tdkProcess(shopInfo.shop_name)));
})().catch(next);
},
... ... @@ -339,7 +344,7 @@ const shop = {
let appPath = 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.shop","params":{"shop_template_type":"1","shop_id":"' +
shopId + '","shop_name":"' + shopInfo.shop_name + '"}}';
res.render('newshop/shop-list', {
res.render('newshop/shop-list', _.assign({
module: 'product',
page: 'shop-list',
pageHeader: headerModel.setNav({
... ... @@ -347,9 +352,6 @@ const shop = {
}),
showDownloadApp: true,
pageFooter: true,
title: title + '|' + title + '潮流服装服饰-Yoho!Buy有货',
keywords: title + ',' + title + '服装服饰,' + title + '潮流服装服饰',
description: title + '|Yoho!Buy有货' + title + '潮流服饰官方授权店!100%品牌正品保证,支持货到付款。',
shopId: shopId,
shopInfo: shopInfo,
goodsList: goodsList,
... ... @@ -358,7 +360,7 @@ const shop = {
_noLazy: true,
localCss: true,
couponData
});
}, _tdkProcess(title)));
})().catch(next);
},
... ...
... ... @@ -145,6 +145,9 @@ let breakingYards = (req, res, next) => {
}).then((result) => {
res.render('sale/break-code', Object.assign(params.renderData, result, {
title: '断码商品|断码折扣商品|YOHO!BUY有货',
keywords: '断码商品、断码专区、断码折扣',
description: '有货网为您带断码专区精选商品,大量断码商品,价格优惠幅度大,支持货到付款,让您全面了解潮流断码商品价格、品牌、图片、折扣等方面信息,想网购潮流断码区商品就上有货网!',
localCss: true
}));
}).catch(next);
... ... @@ -185,6 +188,9 @@ let discountDetail = (req, res, next) => {
res.locals.appPath = result.activity && result.activity.cover_url ? `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.discountmarketpro","params":{"id":"${id}","cover_url":"${result.activity.cover_url.split('?')[0]}","title":"${result.title}"}}` : '';
res.render('sale/discount-detail', Object.assign(params.renderData, result, {
title: `【${result.title}】潮流折扣商品|YOHO!BUY 有货`,
keywords: `${result.title}`,
description: `有货网为您提供大量${result.title}商品,支持货到付款,质量保证,让您全面了解${result.title}商品价格、品牌、图片、折扣等方面信息,想网购${result.title}商品就上有货网!`, // eslint-disable-line
localCss: true
}));
}).catch(next);
... ... @@ -209,6 +215,9 @@ let vip = (req, res, next) => {
saleModel.getVipData(params.channel).then((result) => {
res.render('sale/vip', Object.assign(params.renderData, {
title: 'VIP会员专享|会员专享|YOHO!BUY有货',
keywords: '会员专享,VIP专享,专享商品',
description: '有货网为您带VIP会员专享精选商品,大量潮流品牌商品,VIP价格优惠幅度大,支持货到付款,让您全面了解VIP会员专享商品价格、品牌、图片、折扣等方面信息,想网购VIP会员专享商品就上有货网!', // eslint-disable-line
content: result,
localCss: true
}));
... ...
... ... @@ -292,7 +292,7 @@ module.exports = class extends global.yoho.BaseModel {
}
/* tar add 161129 SEO 优化使用 */
finalResult.cononical = result.product_url;
finalResult.canonical = result.product_url;
return finalResult;
});
... ...
... ... @@ -4,6 +4,7 @@ const utils = '../../../utils';
const productProcess = require(`${utils}/product-process`);
const globalapi = global.yoho.GlobalAPI;
const $ = require('cheerio');
const _ = require('lodash');
exports.list = (param) => {
return globalapi.get('product/api/v2/detail/getlist', param).then((result) => {
... ... @@ -46,13 +47,15 @@ exports.detail = (param) => {
if (goods.length === 1) {
result.bannerTop = {
img: (goods[0].images_list[0] || {}).image_url
img: (goods[0].images_list[0] || {}).image_url,
imgAlt: _.get(result, 'brand_info.brand_name', '') + '|' + _.get(result, 'product_name', '')
};
} else {
result.bannerTop = {
list: goods.map((g) => {
return {
img: (g.images_list[0] || {}).image_url
img: (g.images_list[0] || {}).image_url,
imgAlt: _.get(result, 'brand_info', 'brand_name', '') + '|' + _.get(result, 'product_name', '')
};
})
};
... ...
... ... @@ -31,32 +31,33 @@
{{/ bannerTop}}
</div>
<h2 class="goods-name">
<div class="goods-name">
{{# marketPhrase}}
<span class="activity-phrase">{{.}}</span>
{{/ marketPhrase}}
{{# goodsName}}
<span class="name">{{.}}</span>
<h1 class="name">{{.}}</h1>
{{/ goodsName}}
</h2>
</div>
{{# goodsSubtitle}}
<h1 class="goods-subtitle"><span>{{.}}</span></h1>
<h2 class="goods-subtitle"><span>{{.}}</span></h2>
{{/ goodsSubtitle}}
<div class="price-date">
<div class="goods-price">
<h1 class="current-price">{{goodsPrice.currentPrice}}</h1>
<h1 class="previous-price">{{goodsPrice.previousPrice}}</h1>
<h2 class="current-price">{{goodsPrice.currentPrice}}</h2>
<h2 class="previous-price">{{goodsPrice.previousPrice}}</h2>
</div>
<button class="limit-sale data-can-get-limit-code data-bind" id='limit-sale'>获取限购码</button>
<button class="got-limit-sale data-code-empty data-bind">限购码已被抢光</button>
<button class="got-limit-sale data-got-code data-bind">已获取限购码</button>
</div>
{{#if periodOfMarket}}
<div class="period-of-market">
<h1>上市期:</h1>
<h1 >{{periodOfMarket}}</h1>
<h2>上市期:</h2>
<h2>{{periodOfMarket}}</h2>
</div>
{{/if}}
... ... @@ -85,7 +86,7 @@
{{!--占位: 购物车部分--}}
<div id="placeholder-infodata">
<div class="cart-bar">
<a href="javascript:;" class="new-foot-ico">
<a href="javascript:;" class="new-foot-ico" rel="nofollow">
<div class="num-incart iconfont">
<span class="num-tag {{#unless @root.cartCount}}hide{{/unless}}">{{@root.cartCount}}</span>
&#xe62c;
... ...
... ... @@ -20,7 +20,7 @@
{{/ bannerTop}}
</div>
<div class="goods-name"><span class="name">{{product_name}}</span></div>
<div class="goods-name"><h1 class="name">{{product_name}}</h1></div>
<div class="price-date">
<div>
... ...
... ... @@ -6,9 +6,9 @@
<li class="swiper-slide">
<a href="javascript:;">
{{#if @first}}
<img src="{{image2 img w=450 h=600 q=60}}" alt="">
<img src="{{image2 img w=450 h=600 q=60}}" alt="{{imgAlt}}">
{{else}}
<img class="swiper-lazy" data-src="{{image2 img w=450 h=600 q=60}}" alt="">
<img class="swiper-lazy" data-src="{{image2 img w=450 h=600 q=60}}" alt="{{imgAlt}}">
{{/if}}
</a>
</li>
... ... @@ -27,10 +27,10 @@
<div class="banner-top-single">
{{#if url}}
<a href="{{url}}">
<img class="img" src="{{image2 img w=450 h=600 q=60}}">
<img class="img" src="{{image2 img w=450 h=600 q=60}}" alt="{{imgAlt}}">
</a>
{{^}}
<img class="img" src="{{image2 img w=450 h=600 q=60}}">
<img class="img" src="{{image2 img w=450 h=600 q=60}}" alt="{{imgAlt}}">
{{/if}}
</div>
... ...
<div class="item">
<a {{#if link}}href="{{link}}"{{/if}}>
<a {{#if link}}href="{{link}}"{{/if}}{{#if isGood}} title="{{alt}}"{{/if}}>
{{#if isGood}}
{{#ifor triple double single}}
{{#within index 3}}
<img class="item-pic" src="{{image2 src w=235 h=314}}">
<img class="item-pic" src="{{image2 src w=235 h=314}}" alt="{{alt}}">
{{^}}
<img class="item-pic lazy" data-original="{{image2 src w=235 h=314}}">
<img class="item-pic lazy" data-original="{{image2 src w=235 h=314}}" alt="{{alt}}">
{{/within}}
{{/ifor}}
{{^}}
{{#within index 3}}
<img class="item-pic" src="{{image2 src}}" alt="">
<img class="item-pic" src="{{image2 src}}" alt="{{@root.title}}">
{{^}}
<img class="item-pic lazy" data-original="{{image2 src}}">
{{/within}}
... ...
... ... @@ -17,7 +17,7 @@
<li class="swiper-slide">
<a{{#if link}} href="{{link}}"{{/if}}>
{{#within @../index 3}}
<img src="{{image2 src}}" alt="">
<img src="{{image2 src}}" alt="{{@root.title}}">
{{^}}
<img class="lazy" data-original="{{image2 src}}" alt="">
{{/within}}
... ...
... ... @@ -74,7 +74,7 @@ module.exports = {
maxFiles: 7
},
console: {
level: 'info',
level: 'debug',
colorize: 'all',
prettyPrint: true
}
... ...
... ... @@ -15,8 +15,8 @@ module.exports = app => {
// 业务模块
app.use('/product', require('./apps/product'));
app.use('/guang/news', require('./apps/news'));// seo-潮流资讯页
app.use('/guang', require('./apps/guang'));
app.use('/news', require('./apps/news'));
app.use('/activity', require('./apps/activity'));
app.use('/cart', require('./apps/cart'));
... ...
... ... @@ -21,11 +21,11 @@ module.exports = () => {
}
} else if (req.subdomains.length) {
switch (req.subdomains[0]) {
case 'guang': // 逛
case 'guang':
case 'cdnsrcguang': // CDN 逛 回源地址
req.url = req.url.replace('/guang', '');
req.url = `/guang${req.url}`;
break;
req.url = `//m.yohobuy.com/guang${req.url}`;
return res.redirect(301, req.url);
case 'list': // list
case 'cdnsrclist':// CDN list 回源域名
if (req.path === '/') {
... ...
/**
* URL 重写(主要用于兼容原来PHP的连接)
*/
const querystring = require('querystring');
const helpers = global.yoho.helpers;
module.exports = () => {
... ... @@ -71,6 +72,11 @@ module.exports = () => {
req.url = `/product/${req.url}`;
}
if (/^\/list/.test(req.url)) {
// 列表页路由重写 新路由
req.url = `/product/index/index?${querystring.stringify(req.query)}`;
}
next();
};
};
... ...
... ... @@ -12,7 +12,7 @@ exports.getUrlData = function(type, gender) {
const urlData = {
indexUrl: helpers.urlFormat('/?go=1'), // 首页
categoryUrl: helpers.urlFormat('/cate'), // 分类
guangUrl: helpers.urlFormat('', gender ? {gender: gender} : null, 'guang'), // 逛首页
guangUrl: helpers.urlFormat('/guang', gender ? {gender: gender} : null), // 逛首页
shoppingCartUrl: helpers.urlFormat('/cart/index/index'), // 购物车
mineUrl: helpers.urlFormat('/home') // 个人中心
};
... ...
... ... @@ -11,10 +11,10 @@
<meta content="telephone=no" name="format-detection" />
<meta content="email=no" name="format-detection" />
<meta name="referrer" content="always">
{{# cononical}}
{{# canonical}}
<meta name="applicable-device" content="mobile">
<link rel="cononical" href="{{currentHref}}">
{{/ cononical}}
<link rel="canonical" href="{{currentHref}}">
{{/ canonical}}
{{#if miphtml}}
<link rel="miphtml" href="{{miphtml}}">
{{/if}}
... ...
... ... @@ -34,9 +34,9 @@
<div class="good-detail-img">
<a class="good-thumb" href="{{url}}">
{{#if @root._noLazy}}
<img src="{{image2 default_images w=235 h=314 q=60}}"/>
<img src="{{image2 default_images w=235 h=314 q=60}}" alt="{{imgAlt}}"/>
{{else}}
<img class="lazy" data-original="{{image2 default_images w=235 h=314 q=60}}"/>
<img class="lazy" data-original="{{image2 default_images w=235 h=314 q=60}}" alt="{{imgAlt}}"/>
{{/if}}
</a>
{{# is_soon_sold_out}}
... ...
... ... @@ -77,13 +77,13 @@
</a>
</li>
<li>
<a href="{{ shoppingCartUrl }}">
<a href="{{ shoppingCartUrl }}" rel="nofollow">
<i class="iconfont">&#xe62c;</i>
<span>购物车</span>
</a>
</li>
<li>
<a href="{{ mineUrl }}">
<a href="{{ mineUrl }}" rel="nofollow">
<i class="iconfont">&#xe62b;</i>
<span>我的</span>
</a>
... ...
... ... @@ -7,9 +7,9 @@
<li>
<a href="/product/sale/discount/detail?id={{id}}&channel={{@root.channel}}">
{{#within @index 3}}
<img src="{{image2 cover_url w=640 h=250 q=60}}"/>
<img src="{{image2 cover_url w=640 h=250 q=60}}" alt="{{title}}"/>
{{^}}
<img class="lazy" data-original="{{image2 cover_url w=640 h=250 q=60}}"/>
<img class="lazy" data-original="{{image2 cover_url w=640 h=250 q=60}}" alt="{{title}}"/>
{{/within}}
<p class="discount-cont">
<span class="discount-title">{{title}}</span>
... ...
... ... @@ -24,7 +24,7 @@
{{# list}}
<div class="brand-wall-box">
<a href="{{url}}">
<img class="lazy" data-original="{{img}}"></img>
<img class="lazy" data-original="{{img}}" alt="{{brandName}}"></img>
<div class="brand-name">{{brandName}}</div>
</a>
</div>
... ... @@ -37,7 +37,7 @@
{{# list}}
<div class="brand-wall-box">
<a href="{{url}}">
<img class="lazy" data-original="{{img}}"></img>
<img class="lazy" data-original="{{img}}" alt="{{brandName}}"></img>
<div class="brand-name">{{brandName}}</div>
</a>
</div>
... ...
... ... @@ -57,7 +57,7 @@
</div>
{{/ consults}}
</div>
<a class="consult-content-footer tap-hightlight" href="{{consultsUrl}}">
<a class="consult-content-footer tap-hightlight" href="{{consultsUrl}}" rel="nofollow">
查看更多
<span class="iconfont">&#xe604;</span>
</a>
... ...
... ... @@ -3,7 +3,7 @@
{{#unless @root.wap.common.removeCartCount}}
<input type="hidden" id="remove-cart-count" value="1">
{{/unless}}
<a class="new-foot-ico" href="{{cartUrl}}">
<a class="new-foot-ico" href="{{cartUrl}}" rel="nofollow">
<div class="num-incart iconfont">
<span class="num-tag {{#unless @root.cartCount}}hide{{/unless}}">{{@root.cartCount}}</span>
&#xe62c;
... ...
... ... @@ -3,10 +3,10 @@
<div class="goods-discount" id="goodsDiscount">
{{#each promotion}}
{{#if @first}}
<h1 class="first-item short-text tap-hightlight"><span class="promotion-icon"></span>{{promotionTitle}}<span class="icon-down iconfont dropdown">&#xe609;</span></h1>
<h2 class="first-item short-text tap-hightlight"><span class="promotion-icon"></span>{{promotionTitle}}<span class="icon-down iconfont dropdown">&#xe609;</span></h2>
{{else}}
<div class="discount-folder">
<h1 class="folder-item tap-hightlight"><span class="promotion-icon"></span>{{promotionTitle}}</h1>
<h2 class="folder-item tap-hightlight"><span class="promotion-icon"></span>{{promotionTitle}}</h2>
</div>
{{/if}}
{{/each}}
... ...
... ... @@ -206,9 +206,9 @@ $.extend({
// 未登录
$op.prepend(
'<a href="/signin.html?refer=' + location.href + '">登录</a>' +
'<a href="/signin.html?refer=' + location.href + '" rel="nofollow">登录</a>' +
'<span class="sep-line">|</span>' +
'<a href="/reg.html">注册</a>'
'<a href="/reg.html" rel="nofollow">注册</a>'
);
} else {
... ...
... ... @@ -29,7 +29,7 @@ const getComments = () => {
$.ajax({
type: 'get',
url: '//guang.m.yohobuy.com/guang/info/getComments',
url: '//m.yohobuy.com/guang/info/getComments',
data: {
article_id: article_id,
page: page++
... ...
... ... @@ -63,6 +63,10 @@ $nav.bind('contextmenu', function() {
});
$nav.on('touchend touchcancel', function(e) {
if ($(e.target).closest('.news-jump').length > 0) {
return true;
}
let $this = $(e.target).closest('.guang-nav-item'),
$content,
index;
... ...
... ... @@ -62,7 +62,7 @@ export class IndexView extends View {
this.indexModel.loadMoreAjax({
type: 'GET',
url: '/news/index/page',
url: '/guang/news/index/page',
dataType: 'html',
data: that.navState[index]
}).then(rdata => {
... ...
... ... @@ -873,6 +873,11 @@ $focus-size: 42px;
overflow: visible;
}
}
.a-anchor {
color: #93b4c5;
text-decoration: underline;
}
}
.guang-detail-page.menu-open {
... ...
... ... @@ -75,6 +75,10 @@
&.focus {
color: #000;
}
&.news-jump a {
color: inherit;
}
}
.bytouch {
... ...
... ... @@ -87,6 +87,9 @@ $focus-size: 42px;
img {
height: auto;
width: auto;
max-width: 100%;
color: #fff;
}
}
... ... @@ -877,6 +880,11 @@ $focus-size: 42px;
overflow: visible;
}
}
.a-anchor {
color: #93b4c5;
text-decoration: underline;
}
}
.news-detail-page.menu-open {
... ...
... ... @@ -560,7 +560,7 @@ $basicBtnC: #eb0313;
float: left;
font-size: 34.59px;
h1 {
h2 {
display: inline-block;
line-height: 88px;
}
... ... @@ -603,7 +603,7 @@ $basicBtnC: #eb0313;
font-size: 24px;
border-bottom: 1px solid #e0e0e0;
h1 {
h2 {
display: inline-block;
line-height: 88px;
}
... ... @@ -729,7 +729,7 @@ $basicBtnC: #eb0313;
color: $mainFontC;
font-size: 28px;
h1 {
h2 {
position: relative;
padding: 30px 60px 30px 30px;
line-height: 36px;
... ...
... ... @@ -111,7 +111,10 @@ class DetailProcess {
value.img = _.replace(value.img, '/quality/80', '/quality/70');
bannerList.push({
img: value.img
img: value.img,
imgAlt: _.compact([origin.brand_info.brand_name_en, origin.brand_info.brand_name_cn,
(_.get(origin, 'gender', '1') === '1' ? '男' : '女'), origin.small_sort_name,
origin.product_name]).join('|')
});
});
... ...
... ... @@ -83,7 +83,7 @@ const formatArticle = (articleData, showTag, isApp, showAuthor, uid, top) => {
id: articleData.id,
showTags: showTag,
img: articleData.src ? helpers.image(articleData.src, 640, 640) : '',
url: isApp ? `${helpers.https(articleData.url)}&openby:yohobuy={"action":"go.h5","params":{"param":{"id":"${articleData.id}"},"shareparam":{"id":"${articleData.id}"},"share":"/guang/api/v1/share/guang","id":${articleData.id},"type":1,"url":"http:${helpers.urlFormat('/info/index', null, 'guang')}","islogin":"N"}}` : articleData.url, //eslint-disable-line
url: isApp ? `//m.yohobuy.com/guang/info/${articleData.id}.html?openby:yohobuy={"action":"go.h5","params":{"param":{"id":"${articleData.id}"},"shareparam":{"id":"${articleData.id}"},"share":"/guang/api/v1/share/guang","id":${articleData.id},"type":1,"url":"http://m.yohobuy.com/guang/info/${articleData.id}.html","islogin":"N"}}` : `//m.yohobuy.com/guang/info/${articleData.id}.html`, //eslint-disable-line
title: articleData.title,
text: articleData.intro,
publishTime: articleData.publish_time,
... ... @@ -246,7 +246,7 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW
newText = value.text.data.text;
}
finalDetail.push({
text: newText
text: newText.replace(/www.yohobuy.com\/chanpin\//ig, 'm.yohobuy.com/chanpin/')
});
}
... ...
... ... @@ -237,6 +237,8 @@ exports.processProductList = (list, options) => {
product.seoTitle = `${product.brand_name}|${seoGender}${product.small_sort_name}|${product.product_name}|YOHO!BUY有货`; // eslint-disable-line
product.imgAlt = _.compact([product.brand_name, (product.gender ? GENDER[product.gender] : false), product.small_sort_name, product.product_name]).join('|');
pruductList.push(product);
});
... ...
... ... @@ -4,12 +4,6 @@
* @date: 2016/7/29
*/
const _getGender = {
'1,3': '男生',
'2,3': '女生',
'1,2,3': '',
};
/**
* 根据频道判断出性别
*/
... ... @@ -86,9 +80,9 @@ const getListSeoData = (gender, sort_name) => {
if (gender && sort_name) {
seoData = {
title: `${sort_name}|新款${sort_name}${_getGender[gender]}|品牌正品|YOHO!BUY有货`,
keywords: `新款${sort_name},${_getGender[gender]}${sort_name},品牌正品`,
description: `正品网购!YOHO!BUY有货提供新款${sort_name}${_getGender[gender]}${sort_name}100%品牌正品保证,支持货到付款。`
title: `${sort_name}|新款${sort_name},${sort_name}品牌正品|YOHO!BUY有货`,
keywords: `${sort_name},新款${sort_name}${sort_name}品牌正品`,
description: `有货网${sort_name}专卖店销售正品新款${sort_name},支持货到付款。了解新款${sort_name}${sort_name}品牌价格、评价、图片等信息,网购超低折扣新款${sort_name}就上有货网。` // eslint-disable-line
};
}
return seoData;
... ...
... ... @@ -2,7 +2,6 @@
* @Author: Targaryen
* @Date: 2017-03-23 11:02:31
* @Last Modified by: Targaryen
* @Last Modified time: 2017-08-11 11:40:02
*/
/* 红人店铺数据处理 */
... ... @@ -11,6 +10,11 @@
const _ = require('lodash');
const helpers = global.yoho.helpers;
const productPrcs = require('./product-process');
const GENDER = {
1: '男',
2: '女',
3: '男|女'
};
let countCarouselImage = 0; // 轮播图模块统计
... ... @@ -343,10 +347,15 @@ const pushGoodsInfo = (decorators, goodsList) => {
if (salesPrice === 0) {
decorators[key].noShowProductInfo = true;
}
decorators[key].pics[subKey].name = _.get(goodsObj, `${subValue.skn}.product_name`, '');
decorators[key].pics[subKey].salesPrice = salesPrice ? '¥' + salesPrice : '';
decorators[key].pics[subKey].marketPrice = marketPrice ? '¥' + marketPrice : '';
decorators[key].pics[subKey].isGood = true;
decorators[key].pics[subKey].alt = _.get(goodsObj, `${subValue.skn}.brand_name`, '') +
'|' + GENDER[_.get(goodsObj, `${subValue.skn}.gender`, '3')] +
'|' + _.get(goodsObj, `${subValue.skn}.small_sort_name`, '') +
'|' + _.get(goodsObj, `${subValue.skn}.product_name`, '');
if (value.module_type === 'TripleImage' ||
value.module_type === 'DoubleImage' ||
... ...