Authored by htoooth

add newproduct and articles

... ... @@ -6,70 +6,129 @@
const config = global.yoho.config;
const redis = global.yoho.redis;
const cache = global.yoho.cache;
const logger = global.yoho.logger;
const SearchServiceModel = require('./search-api');
const GuangServiceModel = require('../../guang/models/guang-service');
const productProcess = require('../../../utils/product-process');
const _ = require('lodash');
const uuid = require('uuid');
function _cacheGet(key) {
return cache.get(key).then((data) => {
if (data) {
return JSON.parse(data);
}
return Promise.reject();
});
}
// 半个月
const HALF_MONTH = 60 * 60 * 24 * 15;
function _cacheSave(key, value) {
return cache.set(key, value, HALF_MONTH)
.catch(err => logger.error(`save cache data fail:${err.toString()}`));
}
function _cached(fn, ctx) {
const pre = (fn.name || 'random:' + uuid.v4()) + ':';
return function() {
const args = Array.prototype.slice.call(arguments);
const key = pre + JSON.stringify(args || '[]');
return _cacheGet(key).catch(() => {
return fn.apply(ctx, args).then(result => {
_cacheSave(key, result);
return result;
});
});
};
}
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.searchApi = new SearchServiceModel(ctx);
this.guangService = new GuangServiceModel(ctx);
this.getNewProduct = _cached(this._getNewProduct, this);
this.getGuangArticles = _cached(this._getGuangArticles, this);
}
/**
* 商品的 banner
*/
getProductBannerAsync(pid) {
return this.get({data: {
method: 'web.productBanner.data',
product_id: pid
}, params: {
cache: config.apiCache
}});
return this.get({
data: {
method: 'web.productBanner.data',
product_id: pid
}, params: {
cache: config.apiCache
}
});
}
/**
* 商品尺寸
*/
sizeInfoAsync(skn) {
return this.get({data: {
method: 'h5.product.intro',
productskn: skn
}, params: {
cache: config.apiCache
}});
return this.get({
data: {
method: 'h5.product.intro',
productskn: skn
}, params: {
cache: config.apiCache
}
});
}
/**
* 特殊商品退换货
*/
isSupportReturnedSale(skn) {
return this.get({data: {
method: 'web.product.refundExchange',
product_skn: skn
}, params: {
cache: config.apiCache
}});
return this.get({
data: {
method: 'web.product.refundExchange',
product_skn: skn
}, params: {
cache: config.apiCache
}
});
}
/**
* 商品舒适度
*/
getProductComfortAsync(pid) {
return this.get({data: {
method: 'web.productComfort.data',
product_id: pid
}, params: {
cache: config.apiCache
}});
return this.get({
data: {
method: 'web.productComfort.data',
product_id: pid
}, params: {
cache: config.apiCache
}
});
}
/**
* 模特试穿
*/
getProductModelTryAsync(skn) {
return this.get({data: {
method: 'web.productModelTry.data',
product_skn: skn
}, params: {
cache: config.apiCache
}});
return this.get({
data: {
method: 'web.productModelTry.data',
product_skn: skn
}, params: {
cache: config.apiCache
}
});
}
/**
... ... @@ -101,9 +160,11 @@ module.exports = class extends global.yoho.BaseModel {
data.current_vip_level = vipLevel;
}
return this.get({data, params: {
cache: config.apiCache
}});
return this.get({
data, params: {
cache: config.apiCache
}
});
}
/**
... ... @@ -115,9 +176,11 @@ module.exports = class extends global.yoho.BaseModel {
product_skn: skn
};
return this.get({data, params: {
cache: config.apiCache
}});
return this.get({
data, params: {
cache: config.apiCache
}
});
}
/**
... ... @@ -137,44 +200,52 @@ module.exports = class extends global.yoho.BaseModel {
data.product_skn = skn;
}
return this.get({data, params: {
cache: config.apiCache
}});
return this.get({
data, params: {
cache: config.apiCache
}
});
}
/**
* 店铺推荐
*/
getShopRecommendAsync(skn, page, limit) {
return this.get({data: {
method: 'web.product.shopRecommend',
product_skn: skn,
page: page || 1,
limit: limit || 20
}});
return this.get({
data: {
method: 'web.product.shopRecommend',
product_skn: skn,
page: page || 1,
limit: limit || 20
}
});
}
/**
* 套餐和量贩
*/
getBundleAsync(skn) {
return this.get({data: {
method: 'app.query.bundleSkn',
product_skn: skn
}});
return this.get({
data: {
method: 'app.query.bundleSkn',
product_skn: skn
}
});
}
/**
* 找相似
*/
getLikeAsync(skn, limit) {
return this.get({data: {
method: 'app.search.findLike',
limit: limit || 10,
product_skn: skn
}, params: {
cache: 86400
}});
return this.get({
data: {
method: 'app.search.findLike',
limit: limit || 10,
product_skn: skn
}, params: {
cache: 86400
}
});
}
// 根据small_sort从redis获取分类下的关键词
... ... @@ -183,4 +254,37 @@ module.exports = class extends global.yoho.BaseModel {
return res[0];
});
}
_getNewProduct(sort) {
return this.searchApi.getProductList({
limit: 10,
sort: sort,
order: 's_t_desc'
}).then(result => {
if (result.code === 200) {
return productProcess.processProductList(result.data.product_list);
}
return [];
}).then(productList => {
return productList.map((it) => ({
url: it.url,
name: it.product_name
}));
});
}
_getGuangArticles(skn) { //eslint-disable-line
return this.guangService.getArticleList(
3, null, null, null, _.random(1, 700), null, null, 10, null, null
).then(result => {
return _.get(result, 'msgs', []).map((article) => ({
url: article.url,
name: article.title
}));
});
}
};
... ...
... ... @@ -37,7 +37,7 @@ const tdk = require('../../../utils/getTDK');
const productProcess = require('../../../utils/product-process');
function _getProductAdditionInfoAsync(data) {
return co(function * () {
return co(function* () {
let productId = _.get(data, 'product_id', 0);
let brandId = _.get(data, 'brand_info.brand_id', 0);
... ... @@ -54,7 +54,7 @@ function _getProductAdditionInfoAsync(data) {
}
function _getProductIntroAsync(productId, productSkn) {
return co(function * () {
return co(function* () {
let result = yield Promise.props({
sizeInfo: this.productAPI.sizeInfoAsync(productSkn),
productComfort: this.productAPI.getProductComfortAsync(productId),
... ... @@ -71,7 +71,7 @@ function _getProductIntroAsync(productId, productSkn) {
* bid : brand id
*/
function _getProductFavoriteDataAsync(uid, pid) {
return co(function*() {
return co(function* () {
let result = {
product: false,
brand: false
... ... @@ -241,7 +241,7 @@ function _getSkuDataByProductBaseInfo(data) {
};
}
skuGoods = _.get(data, 'goods_list', []).reduce((goodsDetailList, goods)=> {
skuGoods = _.get(data, 'goods_list', []).reduce((goodsDetailList, goods) => {
// 如果status为0,即skc下架时就跳过该商品$value['status'] === 0
let goodsDetail = {};
... ... @@ -579,7 +579,7 @@ function _sizeInfoBoSort(sizeInfoBo) {
return {};
}
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek)=> {
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek) => {
let sortAttr = {};
sizeBoList.sortAttributes.forEach(sortAttributes => {
... ... @@ -589,7 +589,7 @@ function _sizeInfoBoSort(sizeInfoBo) {
sizeInfoBo.sizeBoList[sizek].sortAttributes = sortAttr;
});
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek)=> {
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek) => {
let sortAttr = [];
sizeInfoBo.sizeAttributeBos.forEach(val => {
... ... @@ -991,7 +991,7 @@ function _getCoupon(coupons) {
let pickProp = Fn.pick(['couponName', 'amount', 'couponId', 'acquireStatus', 'rule4ShortName']);
let encodeId = Fn.update('couponId', (cid) => crypto.encryption(null, cid + ''));
let replace = Fn.update('rule4ShortName', (r)=> r.replace(/¥/g, '¥'));
let replace = Fn.update('rule4ShortName', (r) => r.replace(/¥/g, '¥'));
return Fn.map(Fn.pipe(pickProp, encodeId, replace))(couponList);
}
... ... @@ -1020,7 +1020,7 @@ function _isOfflineSell(status) {
* @return result Object 格式化数据
*/
function _detailDataPkg(origin, uid, vipLevel, cookies) {
return co(function*() {
return co(function* () {
if (_.isEmpty(origin) || _.isEmpty(origin.data)) {
return {};
}
... ... @@ -1101,6 +1101,12 @@ function _detailDataPkg(origin, uid, vipLevel, cookies) {
// 店铺推荐直出(seo需要)
requestApi.shopRecommend = this.productAPI.getShopRecommendAsync(result.skn);
// 新品推荐
requestApi.newProduct = this.productAPI.getNewProduct(result.smallSortId);
// 文章推荐
requestApi.articles = this.productAPI.getGuangArticles(result.skn);
let requestData = yield Promise.props(requestApi);
let additionalData = requestData.addition;
... ... @@ -1112,6 +1118,14 @@ function _detailDataPkg(origin, uid, vipLevel, cookies) {
let recommendKeywords = JSON.parse(requestData.recommendAsync || '[]');
let shopRecommend = requestData.shopRecommend;
let alike = requestData.alike;
let newProduct = requestData.newProduct;
let articles = requestData.articles;
// 文章推荐
result.recommendArticles = articles;
// 推荐最新商品
result.recommendNewProducts = newProduct;
// 处理相似商品
result.alike = productProcess.processProductList(
... ... @@ -1405,8 +1419,8 @@ function _detailDataPkg(origin, uid, vipLevel, cookies) {
statGoodsInfo.productName = result.name.replace('\'', '’');
statGoodsInfo.brandName = (result.brandName || '').replace('\'', '’');
statGoodsInfo.marketPrice = (result.marketPrice ?
result.marketPrice :
result.presalePrice).replace('¥', ''); // 数字
result.marketPrice :
result.presalePrice).replace('¥', ''); // 数字
statGoodsInfo.salePrice = (result.salePrice ?
result.salePrice :
(result.marketPrice || result.presalePrice)).replace('¥', ''); // 数字
... ... @@ -1497,7 +1511,7 @@ function _removeSalePrice(productInfo) {
* 获取某一个商品详情主页面
*/
function showMainAsync(req, data) {
return co(function * () {
return co(function* () {
// 获取商品基本信息
let productData = yield this.productAPI.getProductAsync(
{skn: data.skn}, data.uid, data.isStudent, data.vipLevel
... ... @@ -1519,10 +1533,10 @@ function showMainAsync(req, data) {
);
let requestData = yield Promise.all([
HeaderModel.requestHeaderData(data.channel), // 通用头部数据
HeaderModel.requestHeaderData(data.channel), // 通用头部数据
_getProductIntroAsync.call(this, productId, productSkn), // 商品详细介绍
curUserProduct.call(this, productData), // 商品详细价格
tdk('skn', data.skn, req) // seo
curUserProduct.call(this, productData), // 商品详细价格
tdk('skn', data.skn, req) // seo
]);
let navigatorHeader = requestData[0];
... ... @@ -1589,7 +1603,7 @@ function showMainAsync(req, data) {
* 获取某一个商品详情主页面
*/
function showMainBackAsync(data) {
return co(function * () {
return co(function* () {
// 获取商品基本信息
let productData = yield this.productAPI.getProductAsync({pid: data.pid});
... ... @@ -1600,7 +1614,7 @@ function showMainBackAsync(data) {
function recommendAsync(skn, page, limit) {
return co(function * () {
return co(function* () {
let recommendData = yield this.productAPI.getShopRecommendAsync(skn, page, limit);
if (_.get(recommendData, 'code', 400) !== 200) {
... ... @@ -1705,7 +1719,6 @@ function getPackage(skn) {
}).bind(this)();
}
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
... ...
... ... @@ -8,3 +8,25 @@
</p>
</div>
{{/if}}
{{#if goodsInfo.recommendNewProducts}}
<div class="recommend-keywords">
<h3>新品推荐</h3>
<p>
{{# goodsInfo.recommendNewProducts}}
<a href="{{url}}" title="{{name}}" target="_blank">{{name}}</a>
{{/ goodsInfo.recommendNewProducts}}
</p>
</div>
{{/if}}
{{#if goodsInfo.recommendArticles}}
<div class="recommend-keywords">
<h3>文章推荐</h3>
<p>
{{# goodsInfo.recommendArticles}}
<a href="{{url}}" title="{{name}}" target="_blank">{{name}}</a>
{{/ goodsInfo.recommendArticles}}
</p>
</div>
{{/if}}
... ...