...
|
...
|
@@ -13,6 +13,7 @@ const Fn = require('lodash/fp'); |
|
|
const cheerio = require('cheerio');
|
|
|
const url = require('url');
|
|
|
const helpers = global.yoho.helpers;
|
|
|
const config = global.yoho.config;
|
|
|
const crypto = global.yoho.crypto;
|
|
|
|
|
|
const videoPlayerTpl = require('../helper/video-player-tpl');
|
...
|
...
|
@@ -191,8 +192,10 @@ const _getVipDataByProductBaseInfo = (data, vipLevel, uid) => { |
|
|
const _getProductActivityBanner = (additionalData) => {
|
|
|
let data = additionalData.productBanner;
|
|
|
|
|
|
if (_.isEmpty(data) || _.get(data, 'code', 400) !== 200 || !_.get(data, 'data.bannerImg')) {
|
|
|
return {};
|
|
|
if (_.isEmpty(data) ||
|
|
|
_.get(data, 'code', 400) !== 200 ||
|
|
|
!_.get(data, 'data.bannerImg')) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return {
|
...
|
...
|
@@ -211,17 +214,11 @@ const _getBundleAsync = (result) => { |
|
|
};
|
|
|
|
|
|
const _getActivityDataByProductBaseInfo = (data) => {
|
|
|
let result = [];
|
|
|
|
|
|
_.get(data, 'data', []).forEach(value => {
|
|
|
result.push({
|
|
|
type: value.promotionType.replace(/¥/g, '¥'),
|
|
|
des: value.promotionTitle.replace(/¥/g, '¥'),
|
|
|
url: helpers.urlFormat('', {psp_id: value.id}, 'list')
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return result;
|
|
|
return _.get(data, 'data', []).map(value => ({
|
|
|
type: value.promotionType.replace(/¥/g, '¥'),
|
|
|
des: value.promotionTitle.replace(/¥/g, '¥'),
|
|
|
url: helpers.urlFormat('', {psp_id: value.id}, 'list')
|
|
|
}));
|
|
|
};
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -279,7 +276,7 @@ const _getSkuDataByProductBaseInfo = (data) => { |
|
|
let totalStorageNum = 0;
|
|
|
let skuGoods = null;// sku商品
|
|
|
let defaultImage = '';// 默认图
|
|
|
let chooseSkuFlag = false; // 选中状态
|
|
|
let defaultSkuFlag = false; // 选中状态
|
|
|
|
|
|
if (_.isEmpty(_.get(data, 'goods_list', []))) {
|
|
|
return {
|
...
|
...
|
@@ -289,33 +286,34 @@ const _getSkuDataByProductBaseInfo = (data) => { |
|
|
};
|
|
|
}
|
|
|
|
|
|
skuGoods = _.get(data, 'goods_list', []).reduce((acc, cur)=> {
|
|
|
skuGoods = _.get(data, 'goods_list', []).reduce((goodsDetailList, goods)=> {
|
|
|
|
|
|
// 如果status为0,即skc下架时就跳过该商品$value['status'] === 0
|
|
|
let goodsGroup = {};
|
|
|
let goodsDetail = {};
|
|
|
|
|
|
if (_.isEmpty(cur.color_image)) {
|
|
|
return acc;
|
|
|
if (_.isEmpty(goods.color_image)) {
|
|
|
return goodsDetailList;
|
|
|
}
|
|
|
|
|
|
if (cur.images_list) {
|
|
|
if (goods.images_list) {
|
|
|
// 商品列表
|
|
|
goodsGroup.productSkc = cur.product_skc;
|
|
|
goodsGroup.src = cur.color_image;
|
|
|
goodsGroup.title = `${_.trim(data.product_name)} ${cur.factory_goods_name}`;
|
|
|
goodsGroup.name = cur.factory_goods_name;
|
|
|
goodsGroup.focus = false;
|
|
|
goodsGroup.total = 0;
|
|
|
goodsGroup.thumbs = [];
|
|
|
goodsGroup.size = [];
|
|
|
if (goodsGroup.title.length > 20) {
|
|
|
goodsGroup.title = goodsGroup.title.substr(0, 20) + '...';
|
|
|
goodsDetail.productSkc = goods.product_skc;
|
|
|
goodsDetail.src = goods.color_image;
|
|
|
goodsDetail.title = `${_.trim(data.product_name)} ${goods.factory_goods_name}`;
|
|
|
goodsDetail.name = goods.factory_goods_name;
|
|
|
goodsDetail.focus = false;
|
|
|
goodsDetail.total = 0;
|
|
|
goodsDetail.thumbs = [];
|
|
|
goodsDetail.size = [];
|
|
|
|
|
|
if (goodsDetail.title.length > 20) {
|
|
|
goodsDetail.title = goodsDetail.title.substr(0, 20) + '...';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
_.get(cur, 'images_list', []).forEach((good) => {
|
|
|
_.get(goods, 'images_list', []).forEach((good) => {
|
|
|
if (good.image_url) {
|
|
|
goodsGroup.thumbs.push({
|
|
|
goodsDetail.thumbs.push({
|
|
|
url: '',
|
|
|
shower: good.image_url,
|
|
|
img: good.image_url
|
...
|
...
|
@@ -324,26 +322,27 @@ const _getSkuDataByProductBaseInfo = (data) => { |
|
|
});
|
|
|
|
|
|
// 缩略图空,不显示
|
|
|
if (_.isEmpty(goodsGroup.thumbs)) {
|
|
|
return acc;
|
|
|
if (_.isEmpty(goodsDetail.thumbs)) {
|
|
|
return goodsDetailList;
|
|
|
}
|
|
|
|
|
|
// 商品的尺码列表
|
|
|
_.get(cur, 'size_list', []).forEach((size) => {
|
|
|
_.get(goods, 'size_list', []).forEach((size) => {
|
|
|
if (data.attribute === 3) {
|
|
|
// 虚拟商品,门票默认最大为4,
|
|
|
size.storage_number = size.storage_number > 4 ? 4 : size.storage_number;
|
|
|
}
|
|
|
|
|
|
// 如果status为0,即skc下架时就跳过该商品
|
|
|
if (cur.status === 0) {
|
|
|
if (goods.status === 0) {
|
|
|
size.storage_number = 0;
|
|
|
}
|
|
|
|
|
|
// 是否显示到货通知
|
|
|
size.notify = size.isSuppled === 'Y' && size.storage_number === 0 ? 'Y' : 'N';
|
|
|
|
|
|
goodsGroup.size.push({
|
|
|
// 尺码信息
|
|
|
goodsDetail.size.push({
|
|
|
name: size.size_name,
|
|
|
sku: size.product_sku,
|
|
|
num: _.parseInt(size.storage_number),
|
...
|
...
|
@@ -354,22 +353,22 @@ const _getSkuDataByProductBaseInfo = (data) => { |
|
|
});
|
|
|
|
|
|
// 单个sku商品的总数
|
|
|
goodsGroup.total += _.parseInt(size.storage_number);
|
|
|
goodsDetail.total += _.parseInt(size.storage_number);
|
|
|
|
|
|
if (goodsGroup.total > 0 && !chooseSkuFlag) { // 默认选中该sku商品
|
|
|
goodsGroup.focus = true;
|
|
|
defaultImage = goodsGroup.src; // 默认为选中的skc
|
|
|
chooseSkuFlag = true;// 选中sku商品
|
|
|
if (goodsDetail.total > 0 && !defaultSkuFlag) { // 默认选中该sku商品
|
|
|
goodsDetail.focus = true;
|
|
|
defaultImage = goodsDetail.src; // 默认为选中的skc
|
|
|
defaultSkuFlag = true;// 选中sku商品
|
|
|
}
|
|
|
|
|
|
goodsGroup.disable = !goodsGroup.total > 0;
|
|
|
goodsDetail.disable = !goodsDetail.total > 0;
|
|
|
|
|
|
totalStorageNum += _.parseInt(size.storage_number);
|
|
|
|
|
|
});
|
|
|
|
|
|
if (goodsGroup.focus) {
|
|
|
_.some(goodsGroup.size, function(value) {
|
|
|
if (goodsDetail.focus) {
|
|
|
_.some(goodsDetail.size, function(value) {
|
|
|
if (value.num !== 0) {
|
|
|
value.focus = true;
|
|
|
return true;
|
...
|
...
|
@@ -378,11 +377,11 @@ const _getSkuDataByProductBaseInfo = (data) => { |
|
|
});
|
|
|
}
|
|
|
|
|
|
acc.push(goodsGroup);
|
|
|
return acc;
|
|
|
goodsDetailList.push(goodsDetail);
|
|
|
return goodsDetailList;
|
|
|
}, []);
|
|
|
|
|
|
if (!_.isEmpty(skuGoods) && !chooseSkuFlag) { // 没有选中一个sku商品,默认选中第一个sku商品
|
|
|
if (!_.isEmpty(skuGoods) && !defaultSkuFlag) { // 没有选中一个sku商品,默认选中第一个sku商品
|
|
|
// 所有商品都售罄
|
|
|
_.head(skuGoods).focus = true;
|
|
|
defaultImage = _.head(skuGoods).src;
|
...
|
...
|
@@ -510,16 +509,13 @@ function _getSortNavAsync(smallSortId, gender) { |
|
|
|
|
|
// 保存在 gids 和 skns ,最近流览功能
|
|
|
const saveRecentGoodInCookies = (oldSkns, res, addSkns) => {
|
|
|
|
|
|
oldSkns = oldSkns ? oldSkns.split(',') : [];
|
|
|
|
|
|
oldSkns = _.reject(oldSkns, old => old === String(addSkns) ? true : false);
|
|
|
|
|
|
oldSkns.unshift(addSkns);
|
|
|
|
|
|
res.cookie('_browseskn', oldSkns.splice(0, 30).join(','), {
|
|
|
res.cookie('_browseskn', _.take(oldSkns, 30).join(','), {
|
|
|
maxAge: 2000000000,
|
|
|
domain: '.yohobuy.com'
|
|
|
domain: config.cookieDomain
|
|
|
});
|
|
|
};
|
|
|
|
...
|
...
|
@@ -527,14 +523,13 @@ const saveRecentGoodInCookies = (oldSkns, res, addSkns) => { |
|
|
* 获取商品的舒适度
|
|
|
*/
|
|
|
const _getProductComfort = (data) => {
|
|
|
let result = [];
|
|
|
let comfort = data.productComfort;
|
|
|
|
|
|
if (_.isEmpty(comfort) || !comfort || !comfort.data) {
|
|
|
return result;
|
|
|
return [];
|
|
|
}
|
|
|
|
|
|
_.get(comfort, 'data', []).forEach(value => {
|
|
|
return _.get(comfort, 'data', []).reduce((all, value) => {
|
|
|
let blocks = [];
|
|
|
let flag = false;
|
|
|
|
...
|
...
|
@@ -551,19 +546,19 @@ const _getProductComfort = (data) => { |
|
|
|
|
|
// 不存在
|
|
|
if (!flag) {
|
|
|
return;
|
|
|
return all;
|
|
|
}
|
|
|
|
|
|
// 存在,添加
|
|
|
result.push({
|
|
|
all.push({
|
|
|
name: value.caption.caption,
|
|
|
minDes: value.caption.low,
|
|
|
blocks: blocks,
|
|
|
maxDes: value.caption.high
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return result;
|
|
|
return all;
|
|
|
}, []);
|
|
|
};
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -580,30 +575,26 @@ const _getBasicDescription = (productDescBo) => { |
|
|
}
|
|
|
}(productDescBo.gender));
|
|
|
|
|
|
let basic = [
|
|
|
{
|
|
|
key: '编号',
|
|
|
value: productDescBo.erpProductId
|
|
|
},
|
|
|
{
|
|
|
key: '颜色',
|
|
|
value: productDescBo.factoryGoodsName,
|
|
|
dColor: true
|
|
|
},
|
|
|
{
|
|
|
key: '性别',
|
|
|
value: sex
|
|
|
}
|
|
|
];
|
|
|
|
|
|
_.get(productDescBo, 'standardBos', []).forEach(value => {
|
|
|
basic.push({
|
|
|
const basic = [{
|
|
|
key: '编号',
|
|
|
value: productDescBo.erpProductId
|
|
|
}, {
|
|
|
key: '颜色',
|
|
|
value: productDescBo.factoryGoodsName,
|
|
|
dColor: true
|
|
|
}, {
|
|
|
key: '性别',
|
|
|
value: sex
|
|
|
}];
|
|
|
|
|
|
return _.get(productDescBo, 'standardBos', []).reduce((all, value) => {
|
|
|
all.push({
|
|
|
key: value.standardName,
|
|
|
value: value.standardVal
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return basic;
|
|
|
return all;
|
|
|
}, basic);
|
|
|
};
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -611,7 +602,7 @@ const _getBasicDescription = (productDescBo) => { |
|
|
*/
|
|
|
const _getDescriptionDataBySizeInfo = (sizeInfo, additionalData) => {
|
|
|
if (!sizeInfo.productDescBo || !sizeInfo.productDescBo.erpProductId) {
|
|
|
return {};
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return {
|
...
|
...
|
@@ -805,7 +796,7 @@ const _getProductModelCard = (sortId, sizeInfo) => { |
|
|
*/
|
|
|
const getReferenceDataBySizeInfo = (sizeInfo) => {
|
|
|
if (_.isEmpty(sizeInfo.modelBos)) {
|
|
|
return {};
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 模特试穿, 竖着输出排列显示
|
...
|
...
|
@@ -925,7 +916,7 @@ const _getProductModelTry = (data) => { |
|
|
let result = data.productModelTry;
|
|
|
|
|
|
if (_.isEmpty(result) || result.code !== 200 || _.isEmpty(result.data)) {
|
|
|
return {};
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
let modelTry = {
|
...
|
...
|
@@ -961,60 +952,6 @@ const _getProductModelTry = (data) => { |
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 根据最大分类ID获取尺寸属性
|
|
|
* @param maxSortId
|
|
|
* @param sizeInfoBo
|
|
|
*/
|
|
|
const _getSizeAttrByMaxSortId = (maxSortId, sizeList) => {
|
|
|
if (_.isEmpty(sizeList)) {
|
|
|
return [];
|
|
|
}
|
|
|
|
|
|
// 不同分类,取得属性值不同
|
|
|
let attributeIds = (function(id) {
|
|
|
if (id === 1 && id === 2) {
|
|
|
return [3, 4];
|
|
|
} else if (id === 3) {
|
|
|
return [6, 10];
|
|
|
} else if (id === 6) {
|
|
|
return [13];
|
|
|
} else {
|
|
|
return [];
|
|
|
}
|
|
|
}(maxSortId));
|
|
|
|
|
|
let sizeInfos = [];
|
|
|
let attributeNames = {};
|
|
|
|
|
|
// 获取属性名称
|
|
|
_.get(sizeList, 'sizeAttributeBos', []).forEach((size) => {
|
|
|
attributeNames[size.id] = size.attributeName;
|
|
|
});
|
|
|
|
|
|
_.get(sizeList, 'sizeBoList', []).forEach((size) => {
|
|
|
let sizeValues = [];
|
|
|
|
|
|
_.get(size, 'sortAttributes', []).forEach((sort) => {
|
|
|
if (_.includes(attributeIds, sort.id)) {
|
|
|
if (sort.sizeValue) {
|
|
|
sizeValues.push(
|
|
|
`${attributeNames[sort.id]} ${sort.sizeValue}cm`
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 获取尺寸属性
|
|
|
if (!_.isEmpty(sizeValues)) {
|
|
|
sizeInfos[size.sizeName] = sizeValues.join(' / ');
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return sizeInfos;
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 商品尺码信息
|
|
|
*
|
|
|
* @param productSkn
|
...
|
...
|
@@ -1041,21 +978,13 @@ const _getIntroInfo = (productSkn, maxSortId, additionalData)=> { |
|
|
result.modelCards = _getProductModelCard(maxSortId, sizeInfo);
|
|
|
|
|
|
// 试穿模特
|
|
|
let fittingReport = _getProductModelTry(additionalData);
|
|
|
|
|
|
if (!_.isEmpty(fittingReport)) {
|
|
|
result.fittingReport = fittingReport;
|
|
|
}
|
|
|
result.fittingReport = _getProductModelTry(additionalData);
|
|
|
|
|
|
// 尺寸数据
|
|
|
result.size = _getSizeData(sizeInfo);
|
|
|
|
|
|
// 模特数据
|
|
|
let reference = getReferenceDataBySizeInfo(sizeInfo);
|
|
|
|
|
|
if (!_.isEmpty(reference)) {
|
|
|
result.reference = reference;
|
|
|
}
|
|
|
result.reference = getReferenceDataBySizeInfo(sizeInfo);
|
|
|
|
|
|
// 洗涤材质
|
|
|
result.material = _getMaterialDataBySizeInfo(sizeInfo);
|
...
|
...
|
@@ -1063,10 +992,6 @@ const _getIntroInfo = (productSkn, maxSortId, additionalData)=> { |
|
|
// 商品详情页介绍
|
|
|
result.details = _getDetailDataBySizeInfo(sizeInfo);
|
|
|
|
|
|
// 获取尺寸说明
|
|
|
result.sizeTitleJson =
|
|
|
sizeInfo.sizeInfoBo ? JSON.stringify(_getSizeAttrByMaxSortId(maxSortId, sizeInfo.sizeInfoBo)) : '';
|
|
|
|
|
|
return result;
|
|
|
};
|
|
|
|
...
|
...
|
@@ -1663,7 +1588,7 @@ const recommendAsync = (skn, page, limit) => { |
|
|
}
|
|
|
|
|
|
const formatPrice = p => `¥${p}`;
|
|
|
const productUrl = (pid, gid, cn) => helpers.urlFormat(`/product/pro_${pid}_${gid}/${cn}.html`, null, 'item');
|
|
|
const productUrl = (pid, gid, cn) => helpers.getUrlBySkc(pid, gid, cn);
|
|
|
const productImageUrl = Fn.pipe(Fn.prop('default_images'), _.partial(helpers.image, _, 280, 382, 2, 70));
|
|
|
|
|
|
let products = _.get(recommendData, 'data.product_list', []).map((rp) => {
|
...
|
...
|
|