Authored by shijian

tdk

... ... @@ -35,6 +35,9 @@ const pkg = require('./package.json');
const app = express();
const helpers = global.yoho.helpers;
global.yoho.redis = require('./doraemon/middleware/redis').client;
const tdk = require('./utils/getTDK');
// NOTE: 这里修改了图片质量的参数
helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90'));
... ... @@ -163,6 +166,18 @@ app.use((req, res, next) => {
next();
});
// redis seo
app.use((req, res, next) => {
if (!req.xhr) {
tdk('url', req.originalUrl).then(TDKObj =>{
if (TDKObj[0]) {
req.tdk = TDKObj;
}
next();
});
}
});
const logger = global.yoho.logger;
// dispatcher
... ...
... ... @@ -13,6 +13,7 @@ const headerModel = require('../../../doraemon/models/header');
const ghelper = require('../models/guang-helper');
const urlHelper = require('../models/url-helper');
const querystring = require('querystring');
const tdk = require('../../../utils/getTDK');
/**
* 首页文章列表 类型列表
... ... @@ -252,7 +253,8 @@ exports.detail = (req, res, next) => {
reqCtx.getArticleBaseInfo(id, uid, udid),
reqCtx.getArticleRelateBrand(id),
reqCtx.getRecoArticles(gender, 1, 10, channel),
reqCtx.getAds(channel, isAdDegrade)
reqCtx.getAds(channel, isAdDegrade),
tdk('article', id)
];
if (info.authorId) {
... ... @@ -275,6 +277,22 @@ exports.detail = (req, res, next) => {
res.set('Cache-Control', 'no-cache');
}
let title, keywords, description;
if (ret[8][0]) {
title = ret[8][1];
keywords = ret[8][2];
description = ret[8][3];
} else {
title = `${info.title} | YOHO!BUY有货`;
keywords = info.tag.length > 0 ? `${info.tag}` :
['Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,品牌服饰,男士护肤,',
'黑框眼镜,匡威,板鞋,i.t,izzue,5cm,eastpak,vans,lylescott,g-shock,new balance,lacoste,melissa,',
'casio,卡西欧手表,舒雅,jasonwood,odm,AAAA,香港购物,日本潮流'].join('');
description = info.desc.length > 0 ? `${info.desc}` :
'潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜';
}
res.render('guang/detail', Object.assign({
module: 'guang',
page: 'detail',
... ... @@ -305,13 +323,9 @@ exports.detail = (req, res, next) => {
commentFirstPageUrl: '?pageSize=10'
}
}, {
title: `${info.title} | YOHO!BUY有货`,
keywords: info.tag.length > 0 ? `${info.tag}` :
['Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,品牌服饰,男士护肤,',
'黑框眼镜,匡威,板鞋,i.t,izzue,5cm,eastpak,vans,lylescott,g-shock,new balance,lacoste,melissa,',
'casio,卡西欧手表,舒雅,jasonwood,odm,AAAA,香港购物,日本潮流'].join(''),
description: info.desc.length > 0 ? `${info.desc}` :
'潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜',
title: title,
keywords: keywords,
description: description,
webNavHeader: channel
}));
});
... ...
... ... @@ -9,6 +9,7 @@ const list = require(`${mRoot}/list`);
const listSeoMap = require(`${global.middleware}/seo/listSeoMap`);
const helpers = global.yoho.helpers;
const _ = require('lodash');
const tdk = require('../../../utils/getTDK');
// 搜索相关接口
const searchApi = require(`${mRoot}/search-api`);
... ... @@ -22,58 +23,81 @@ const shop = (shopId, req, res, next, brandInfo) => {
shopId = parseInt(shopId, 10);
Object.assign(params, {shopId: shopId});
list.getShopInfo(shopId, req.user.uid).then(shopInfo => {
let pjax = params._pjax;
tdk('shop', shopId).then(TDKObj => {
let seoObj;
// 获取不到店铺信息跳转至首页
if (!shopInfo || _.isEmpty(shopInfo)) {
return res.redirect(helpers.urlFormat('', null, ''));
if (TDKObj[0]) {
seoObj = {
title: TDKObj[1],
keywords: TDKObj[2],
description: TDKObj[3]
};
}
return list.getShopInfo(shopId, req.user.uid).then(shopInfo => {
let pjax = params._pjax;
// 比较品牌域名与店铺域名是否一致,不一致跳转至店铺域名
if (!pjax && shopInfo.domain && domain && domain !== _.toLower(shopInfo.domain)) {
res.redirect(helpers.urlFormat('', params, shopInfo.domain));
return;
}
if (+shopInfo.shopTemplateType === 2) { // 经典模板
// 获取不到店铺信息跳转至首页
if (!shopInfo || _.isEmpty(shopInfo)) {
return res.redirect(helpers.urlFormat('', null, ''));
}
if (pjax) {
list.getShopGoodsData(shopId, req.yoho.channel, params, shopInfo).then(result => {
Object.assign(result, {
shopId: shopId,
layout: false
});
res.render('list/goods-list', result);
}).catch(next);
// 比较品牌域名与店铺域名是否一致,不一致跳转至店铺域名
if (!pjax && shopInfo.domain && domain && domain !== _.toLower(shopInfo.domain)) {
res.redirect(helpers.urlFormat('', params, shopInfo.domain));
return;
}
list.getShopData(shopId, req.yoho.channel, params, shopInfo).then(result => {
Object.assign(result, {
page: 'shop',
shopId: shopId
});
// 店铺装修为空则不cache
if (!result.shopTopBanner) {
res.set('Cache-Control', 'no-cache');
if (+shopInfo.shopTemplateType === 2) { // 经典模板
if (pjax) {
list.getShopGoodsData(shopId, req.yoho.channel, params, shopInfo).then(result => {
Object.assign(result, {
shopId: shopId,
layout: false
});
res.render('list/goods-list', result);
}).catch(next);
return;
}
res.render('list/shop-index', result);
}).catch(next);
} else { // 基础模板
list.getBaseShopData(params, Object.assign({uid: req.user.uid}, brandInfo),
req.yoho.channel, shopId).then(result => {
Object.assign(result, {page: 'list'});
// 基础店铺装修为空则不cache
if (!result.brand || !result.brand.shopBanner) {
list.getShopData(shopId, req.yoho.channel, params, shopInfo).then(result => {
Object.assign(result, {
page: 'shop',
shopId: shopId
});
// 店铺装修为空则不cache
if (!result.shopTopBanner) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/brand', result);
if (seoObj) {
Object.assign(result, seoObj);
}
res.render('list/shop-index', result);
}).catch(next);
}
} else { // 基础模板
list.getBaseShopData(params, Object.assign({uid: req.user.uid}, brandInfo),
req.yoho.channel, shopId).then(result => {
Object.assign(result, {page: 'list'});
// 基础店铺装修为空则不cache
if (!result.brand || !result.brand.shopBanner) {
res.set('Cache-Control', 'no-cache');
}
if (seoObj) {
Object.assign(result, seoObj);
}
res.render('list/brand', result);
}).catch(next);
}
});
}).catch(next);
};
/**
... ...
... ... @@ -35,6 +35,7 @@ const HeaderModel = require('../../../doraemon/models/header');
const BLANK_STR = ' ';
const BUNDLE_PRODUCE = 2; // 量贩
const BUNDLE_PACKAGE = 1; // 套餐
const tdk = require('../../../utils/getTDK');
// 展览票
const YOHOOD_TICKET = 51335912;
... ... @@ -1019,39 +1020,49 @@ const _getIntroInfo = (productSkn, maxSortId, additionalData)=> {
* @return array
*/
const _getSeoByGoodsInfo = (goodsInfo, navs) => {
let title = '';
let brandName = '';
let sortName = '';
return co(function*() {
let title, keywords, description;
let redisSeo = yield tdk('skn', goodsInfo.skn);
goodsInfo = goodsInfo || {};
navs = navs || [];
if (redisSeo[0]) {
title = redisSeo[1];
keywords = redisSeo[2];
description = redisSeo[3];
} else {
let brandName = '';
let sortName = '';
if (goodsInfo.brandName) {
title = goodsInfo.brandName + ' ';
brandName = goodsInfo.brandName;
}
goodsInfo = goodsInfo || {};
navs = navs || [];
if (_.get(navs, '[1].name')) {
sortName = navs[1].name;
title += navs[1].name + '|';
}
if (goodsInfo.brandName) {
title = goodsInfo.brandName + ' ';
brandName = goodsInfo.brandName;
}
title += goodsInfo.name + '正品 | YOHO!BUY 有货';
if (_.get(navs, '[1].name')) {
sortName = navs[1].name;
title += navs[1].name + '|';
}
let keywords = brandName + sortName + ',' + brandName + '官网专卖店,' + brandName + '官方授权店,' +
brandName + '正品,' + brandName + '打折,' + brandName + '折扣店,' + brandName + '真品,' + brandName + '代购';
title += goodsInfo.name + '正品 | YOHO!BUY 有货';
let description = `YOHO!BUY 有货-${brandName}官方授权店,${goodsInfo.name}图片、报价、介绍。` +
`YOHO!BUY 有货${brandName}官网专卖店提供${brandName}正品、${brandName}真品、 ${brandName}打折、${brandName}代购等。`;
keywords = brandName + sortName + ',' + brandName + '官网专卖店,' + brandName + '官方授权店,' +
brandName + '正品,' + brandName + '打折,' + brandName + '折扣店,' + brandName + '真品,' + brandName + '代购';
let cononicalURL = goodsInfo.productUrl;
description = `YOHO!BUY 有货-${brandName}官方授权店,${goodsInfo.name}图片、报价、介绍。` +
`YOHO!BUY 有货${brandName}官网专卖店提供${brandName}正品、${brandName}真品、 ${brandName}打折、${brandName}代购等。`;
}
return {
title: title,
keywords: keywords.replace(/~+/, ''),
description: description,
cononicalURL: cononicalURL
};
let cononicalURL = goodsInfo.productUrl;
return {
title: title,
keywords: keywords.replace(/~+/, ''),
description: description,
cononicalURL: cononicalURL
};
})();
};
// 优惠券
... ... @@ -1558,7 +1569,7 @@ const showMainAsync = (data) => {
result.deatil = Object.assign(result.detail, intro);
// seo
result.seo = _getSeoByGoodsInfo(productInfo.goodsInfo, smallSortNavigator);
result.seo = yield _getSeoByGoodsInfo(productInfo.goodsInfo, smallSortNavigator);
// 商品页面统计
result.statGoodsInfo = Object.assign({fullSortName: smallSortNavigator.map(x => x.name).join('-')},
... ...
const redis = require('redis');
const bluebird = require('bluebird');
const config = require('../../config/common');
const client = redis.createClient(config.redis.connect);
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
module.exports = {
client
};
... ...
... ... @@ -11,7 +11,18 @@ const seoMap = require('./seoConfig');
module.exports = () => {
return (req, res, next) => {
if (!req.xhr) {
Object.assign(res.locals, seoMap[req.path] || seoMap['/']);
let seo;
if (req.tdk) {
seo = {
title: req.tdk[1],
keywords: req.tdk[2],
description: req.tdk[3]
};
} else {
seo = seoMap[req.path] || seoMap['/'];
}
Object.assign(res.locals, seo);
}
next();
};
... ...
... ... @@ -44,6 +44,7 @@
"passport-sina": "^0.1.0",
"passport-strategy": "1.x.x",
"passport-weixin": "^0.1.0",
"redis": "^2.7.1",
"request": "^2.81.0",
"request-ip": "^1.2.2",
"request-promise": "^3.0.0",
... ...
const md5 = require('md5');
const redis = global.yoho.redis;
module.exports = (type, query) => {
query = type === 'url' ? md5(query) : query;
return redis.multi([
['exists', `tdk:${type}:${query}`],
['hmget', `tdk:${type}:${query}`, 'key', 'title', 'keywords', 'description']
]).execAsync().then(function(res) {
return res[1];
});
};
... ...