|
|
/**
|
|
|
* 商品详情models
|
|
|
* @author: xuqi<qi.xu@yoho.cn>
|
|
|
* @date: 2016/5/6
|
|
|
*/
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
const library = '../../../library';
|
|
|
const API = require(`${library}/api`);
|
|
|
const sign = require(`${library}/sign`);
|
|
|
const _ = require('lodash');
|
|
|
const HELPERS = require(`${library}/helpers`);
|
|
|
|
|
|
var api = new API();
|
|
|
var helpers = new HELPERS();
|
|
|
|
|
|
/**
|
|
|
* 处理品牌关联店铺信息
|
|
|
* @param {array}
|
|
|
* @return {array}
|
|
|
*/
|
|
|
const getShopsInfo = (data) => {
|
|
|
var enterStore = {};
|
|
|
|
|
|
_.forEach(data, function(value, key) {
|
|
|
enterStore[key] = {};
|
|
|
enterStore[key].img = helpers.getImageUrl(value.brand_ico, 47, 47);
|
|
|
enterStore[key].storeName = value.brand_name;
|
|
|
|
|
|
if (value.shop_id !== null && value.shop_id !== undefined) {
|
|
|
let params = {};
|
|
|
|
|
|
params.shop_id = value.shop_id;
|
|
|
enterStore[key].url =
|
|
|
helpers.url('/product/index/brand', params);
|
|
|
} else {
|
|
|
enterStore[key].url =
|
|
|
helpers.url('', null, value.brand_domain);
|
|
|
}
|
|
|
});
|
|
|
return enterStore;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 处理限购商品的有关按钮状态(或取现购买以及底部商品购买按钮)
|
|
|
* @param {array} 需要处理的数据
|
|
|
* @param {int} 限购商品的关联状态
|
|
|
* @param {Boolean} 限购商品是否已开售
|
|
|
* @return {array}
|
|
|
*/
|
|
|
const procShowStatus = (data, showStatus, isBeginSale) => {
|
|
|
switch (showStatus) {
|
|
|
case 1:// 开售前/后,立即分享获得限购码(用户未领取限购码)
|
|
|
// 显示获取限购码按钮
|
|
|
data.canGetLimitCode = true;
|
|
|
|
|
|
if (isBeginSale) { // 开售后
|
|
|
data.cartInfo.noLimitCode = true;
|
|
|
} else {
|
|
|
data.cartInfo.limitNotForSale = true;
|
|
|
}
|
|
|
break;
|
|
|
case 2: // 开售后,限购码已抢光(用户未领取限购码)
|
|
|
data.codeEmpty = true;
|
|
|
data.cartInfo.noLimitCode = true;
|
|
|
break;
|
|
|
case 3: // 开售后,商品已经售罄
|
|
|
data.noLimitGoodsBtn = true;
|
|
|
data.cartInfo.soldOut = true;
|
|
|
break;
|
|
|
case 4: // 开售后,立即购买(用户已领取限购码)
|
|
|
data.gotCode = true;
|
|
|
data.cartInfo.canBuyLimit = true;
|
|
|
break;
|
|
|
case 5: // 开售前,限购码已被抢光(用户未领取限购码)
|
|
|
data.codeEmpty = true;
|
|
|
data.cartInfo.limitNotForSale = true;
|
|
|
break;
|
|
|
case 6: // 开售前,即将开售(用户已领取限购码)
|
|
|
data.gotCode = true;
|
|
|
data.cartInfo.limitNotForSale = true;
|
|
|
break;
|
|
|
case 7: // 开售后,用户已经用获得的限购码购买过商品
|
|
|
data.gotCode = true;
|
|
|
data.cartInfo.noLimitCode = true;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 根据设备类型获得限购商品跳转app的url 待处理
|
|
|
* @param {[string]} productCode 限购商品码
|
|
|
* @param {[string]} skn 限购商品skn
|
|
|
* @return {[string]} 限购商品跳转url
|
|
|
*/
|
|
|
const getLimitCodeUrl = (productCode, skn, ua) => {
|
|
|
var url = 'yohoapp://yoho.app/openwith?limit_product_code=' + productCode +
|
|
|
'&product_skn=' + skn;
|
|
|
|
|
|
let isIphone = String(ua).indexOf('iPhone') >= 0;
|
|
|
let isIpad = ua.indexOf('iPad') >= 0;
|
|
|
|
|
|
if (isIphone || isIpad) {
|
|
|
let params = {};
|
|
|
|
|
|
params.lp = productCode;
|
|
|
url = 'yohobuy://' + helpers.url('/limitpurchase', params);
|
|
|
}
|
|
|
return url;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 详情页数据格式化
|
|
|
* @param origin Object 原始数据
|
|
|
* @return dest Object 格式化数据
|
|
|
*/
|
|
|
const detailDataPkg = (origin, uid, vipLevel, ua) => {
|
|
|
var dest = {}, // 结果输出
|
|
|
colorGroup = {},
|
|
|
thumbImageList = {},
|
|
|
sizeGroup = {},
|
|
|
totalStorageNum = 0;
|
|
|
|
|
|
// 商品名称
|
|
|
if (origin.productName === null || origin.productName === undefined) {
|
|
|
return dest;
|
|
|
}
|
|
|
|
|
|
dest.goodsName = origin.productName;
|
|
|
|
|
|
// 用户未登录时 待处理
|
|
|
if (uid === null || uid === undefined) {
|
|
|
let params = {};
|
|
|
|
|
|
params.refer = helpers.url('/product/show_' + origin.erpProductId + '.html');
|
|
|
dest.loginUrl = helpers.url('/signin.html', params);
|
|
|
}
|
|
|
|
|
|
// 商品促销短语
|
|
|
if (origin.salesPhrase !== null && origin.salesPhrase !== undefined) {
|
|
|
dest.goodsSubtitle = origin.salesPhrase;
|
|
|
}
|
|
|
|
|
|
// 商品标签
|
|
|
if (origin.productTagBoList !== null && origin.productTagBoList !== undefined) {
|
|
|
_.forEach(origin.productTagBoList, function(value) {
|
|
|
switch (value.tagLabel) {
|
|
|
case 'is_soon_sold_out':
|
|
|
dest.tags.is_soon_sold_out = true;
|
|
|
break;
|
|
|
case 'is_new':
|
|
|
dest.tags.is_new = true;
|
|
|
break;
|
|
|
case 'is_discount':
|
|
|
dest.tags.is_discount = true;
|
|
|
break;
|
|
|
case 'is_limited':
|
|
|
dest.tags.is_limited = true;
|
|
|
break;
|
|
|
case 'is_yohood':
|
|
|
dest.tags.is_yohood = true;
|
|
|
break;
|
|
|
case 'is_advance':
|
|
|
dest.tags.is_advance = true;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 商品价格
|
|
|
dest.goodsPrice = {};
|
|
|
|
|
|
if (origin.productPriceBo !== null && origin.productPriceBo !== undefined) {
|
|
|
dest.goodsPrice.currentPrice = origin.productPriceBo.formatSalesPrice;
|
|
|
if (origin.productPriceBo.formatMarketPrice !== origin.productPriceBo.formatSalesPrice) {
|
|
|
dest.goodsPrice.previousPrice = origin.productPriceBo.formatMarketPrice;
|
|
|
}
|
|
|
|
|
|
// 商品返回 YOHO 币
|
|
|
if (origin.productPriceBo.yohoCoinNum !== null && origin.productPriceBo.yohoCoinNum !== 0) {
|
|
|
dest.commodityReturn = dest.productPriceBo.yohoCoinNum;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// VIP 商品价格
|
|
|
dest.vipLevel = {};
|
|
|
dest.vipLevel.list = {};
|
|
|
|
|
|
if (origin.productPriceBo.vipPrices !== null && origin.productPriceBo.vipPrices !== undefined) {
|
|
|
_.forEach(origin.productPriceBo.vipPrices, function(value, key) {
|
|
|
dest.vipLevel.list[key] = {};
|
|
|
dest.vipLevel.list[key].level = value.vipLevel;
|
|
|
dest.vipLevel.list[key].text = value.vipPrice;
|
|
|
dest.vipLevel.list[key].currentLevel = (value.vipLevel === vipLevel) ? true : false;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 上市期
|
|
|
if (origin.expectArrivalTime !== null && origin.expectArrivalTime !== undefined) {
|
|
|
dest.periodOfMarket = origin.expectArrivalTime + '月';
|
|
|
}
|
|
|
|
|
|
// 促销信息
|
|
|
dest.goodsDiscount = {};
|
|
|
dest.goodsDiscount.list = {};
|
|
|
|
|
|
if (origin.promotionBoList !== null && origin.promotionBoList !== undefined) {
|
|
|
_.forEach(origin.promotionBoList, function(value, key) {
|
|
|
dest.goodsDiscount.list[key] = {};
|
|
|
dest.goodsDiscount.list[key].text = '【' + value.promotionType + '】' +
|
|
|
value.promotionTitle;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 商品咨询
|
|
|
dest.feedbacks = {};
|
|
|
dest.feedbacks.consults = {};
|
|
|
dest.feedbacks.consultsNum = 0;
|
|
|
|
|
|
if (origin.consultBoWrapper !== null && origin.consultBoWrapper !== undefined) {
|
|
|
dest.feedbacks.consultsNum = origin.consultBoWrapper.consultTotal;
|
|
|
_.forEach(origin.consultBoWrapper.consultBoList, function(value, key) {
|
|
|
dest.feedbacks.consults[key] = {};
|
|
|
dest.feedbacks.consults[key].question = value.ask;
|
|
|
dest.feedbacks.consults[key].time = value.askTime;
|
|
|
dest.feedbacks.consults[key].answer = value.answer;
|
|
|
});
|
|
|
|
|
|
let params = {};
|
|
|
|
|
|
params.product_id = origin.id;
|
|
|
params.total = dest.feedbacks.consultsNum;
|
|
|
|
|
|
dest.feedbacks.consultsUrl = helpers.url('/product/detail/consults', params);
|
|
|
|
|
|
} else { // 暂无咨询
|
|
|
|
|
|
let params = {};
|
|
|
|
|
|
params.product_id = origin.id;
|
|
|
|
|
|
dest.feedbacks.consultsUrl = helpers.url('/product/detail/consultform', params);
|
|
|
}
|
|
|
|
|
|
// 商品评价
|
|
|
dest.feedbacks.commentsNum = 0;
|
|
|
if (origin.commentBoWrapper !== null && origin.commentBoWrapper !== undefined) {
|
|
|
dest.feedbacks.commentsNum = origin.commentBoWrapper.commentTotal;
|
|
|
dest.feedbacks.comments = {};
|
|
|
|
|
|
_.forEach(origin.commentBoWrapper.commentBoList, function(value, key) {
|
|
|
dest.feedbacks.comments[key] = {};
|
|
|
dest.feedbacks.comments[key].userName = value.nickName;
|
|
|
dest.feedbacks.comments[key].desc = value.colorName +
|
|
|
'/' + value.sizeName;
|
|
|
dest.feedbacks.comments[key].content = (value.content !== null &&
|
|
|
value.content !== undefined) ? value.content : '';
|
|
|
dest.feedbacks.comments[key].time = value.createTime;
|
|
|
});
|
|
|
|
|
|
let params = {};
|
|
|
|
|
|
params.product_id = origin.id;
|
|
|
params.total = dest.feedbacks.commentsNum;
|
|
|
|
|
|
dest.feedbacks.commentsUrl = helpers.url('/product/detail/comments', params);
|
|
|
}
|
|
|
|
|
|
// 品牌信息
|
|
|
if (origin.brand !== null && origin.brand !== undefined) {
|
|
|
|
|
|
// dest.enterStore[0] = {};
|
|
|
// dest.enterStore[0].img =
|
|
|
// helpers.getImageUrl(origin.brand.brandIco, 47, 47);
|
|
|
// dest.enterStore[0].storeName = origin.brand.brandName;
|
|
|
// dest.enterStore[0].url = helpers.url('', null, origin.brand.brandDomain);
|
|
|
|
|
|
// 为你优选的链接
|
|
|
let params = {};
|
|
|
|
|
|
params.productSkn = origin.erpProductId;
|
|
|
params.brandId = origin.brand.id;
|
|
|
dest.preferenceUrl = helpers.url('/product/detail/preference', params, '');
|
|
|
}
|
|
|
|
|
|
dest.productSkn = origin.erpProductId;
|
|
|
|
|
|
// 商品信息
|
|
|
if (origin.goodsList !== null && origin.goodsList !== undefined) {
|
|
|
let goodsGroup = {},
|
|
|
sizeName = '',
|
|
|
colorList = {},
|
|
|
sizeList = {},
|
|
|
allSizeList = {},
|
|
|
colorStorageGroup = {},
|
|
|
colorStorageNum = 0;
|
|
|
|
|
|
_.forEach(origin.goodsList, function(value, key) {
|
|
|
if (value.status === 0) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
colorStorageNum = 0;
|
|
|
|
|
|
// 商品分组
|
|
|
if (value.goodsImagesList !== null && value.goodsImagesList !== undefined) {
|
|
|
_.forEach(value.goodsImagesList, function(good, keyForGood) {
|
|
|
goodsGroup[keyForGood] = {};
|
|
|
goodsGroup[keyForGood].goodsId = good.goodsId;
|
|
|
goodsGroup[keyForGood].img = good.imageUrl;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 商品的尺码列表
|
|
|
colorStorageGroup[value.productSkc] = {};
|
|
|
if (value.goodsSizeBoList !== null && value.goodsSizeBoList !== undefined) {
|
|
|
|
|
|
_.forEach(value.goodsSizeBoList, function(size, keyForSize) {
|
|
|
sizeList[value.productSkc] = {};
|
|
|
sizeList[value.productSkc][keyForSize] = {};
|
|
|
sizeList[value.productSkc][keyForSize].id = size.id;
|
|
|
sizeList[value.productSkc][keyForSize].skuId = size.goodsSizeSkuId;
|
|
|
sizeList[value.productSkc][keyForSize].goodsId = size.goodsId;
|
|
|
sizeList[value.productSkc][keyForSize].colorId = size.colorId;
|
|
|
sizeList[value.productSkc][keyForSize].name = size.sizeName;
|
|
|
sizeList[value.productSkc][keyForSize].sizeNum = size.goodsSizeStorageNum;
|
|
|
|
|
|
sizeName = size.sizeName;
|
|
|
|
|
|
// 所有尺码列表,赋值用于前端展示默认尺码的时候
|
|
|
// 判断出没有库存则显示灰色
|
|
|
let build = {};
|
|
|
|
|
|
build.storage = size.goodsSizeStorageNum;
|
|
|
build.id = size.id;
|
|
|
allSizeList[sizeName] = (allSizeList[sizeName] === null ||
|
|
|
allSizeList[sizeName] === undefined) ? build :
|
|
|
allSizeList[sizeName];
|
|
|
|
|
|
colorStorageNum += parseInt(size.goodsSizeStorageNum);
|
|
|
colorStorageGroup[value.productSkc][sizeName] = parseInt(size.goodsSizeStorageNum);
|
|
|
});
|
|
|
|
|
|
// 颜色分组
|
|
|
colorList[key] = {};
|
|
|
colorList[key].id = value.colorId;
|
|
|
colorList[key].skcId = value.productSkc;
|
|
|
colorList[key].name = value.colorName;
|
|
|
colorList[key].goodsName = value.goodsName;
|
|
|
colorList[key].colorNum = colorStorageNum;
|
|
|
}
|
|
|
|
|
|
// 缩略图
|
|
|
let params = {};
|
|
|
|
|
|
params.img = helpers.getImageUrl(value.colorImage, 60, 60);
|
|
|
thumbImageList[key] = params;
|
|
|
|
|
|
// 商品库存总数
|
|
|
totalStorageNum += colorStorageNum;
|
|
|
});
|
|
|
|
|
|
// 遍历所有尺码,构建颜色显示数据
|
|
|
let i = 1;
|
|
|
|
|
|
_.forEach(allSizeList, function(value, key) {
|
|
|
|
|
|
// 默认尺码
|
|
|
sizeGroup[0] = {};
|
|
|
|
|
|
sizeGroup[0].size = {};
|
|
|
sizeGroup[0].size[key] = {};
|
|
|
sizeGroup[0].size[key].name = sizeName;
|
|
|
sizeGroup[0].size[key].sizeNum = (value.storage === undefined || value.storage === null) ? false : true;
|
|
|
sizeGroup[0].size[key].id = value.id;
|
|
|
|
|
|
// 各个颜色的尺码, 每行显示一个尺码对应的颜色
|
|
|
_.forEach(colorList, function(colorArr, keyForColorArr) {
|
|
|
colorGroup[i] = {};
|
|
|
colorGroup[i].color = {};
|
|
|
colorGroup[i].color[keyForColorArr] = {};
|
|
|
colorGroup[i].color[keyForColorArr].colorNum =
|
|
|
(colorStorageGroup[colorArr.skcId][sizeName] !== null &&
|
|
|
colorStorageGroup[colorArr.skcId][sizeName] !== undefined) ?
|
|
|
colorStorageGroup[colorArr.skcId][sizeName] : 0;
|
|
|
});
|
|
|
colorGroup[i].id = value.id;
|
|
|
|
|
|
++i;
|
|
|
});
|
|
|
|
|
|
// 遍历所有颜色, 构建尺码显示数据
|
|
|
|
|
|
i = 1;
|
|
|
_.forEach(colorList, function(value, key) {
|
|
|
// 各个尺码的颜色, 每行显示一个颜色的对应尺码
|
|
|
sizeGroup[i] = {};
|
|
|
sizeGroup[i].size = sizeList[value.skcId];
|
|
|
sizeGroup[i].colorId = value.skcId;
|
|
|
|
|
|
// 默认颜色
|
|
|
colorGroup[0] = {};
|
|
|
colorGroup[0].color = {};
|
|
|
colorGroup[0].color[key] = value;
|
|
|
|
|
|
++i;
|
|
|
});
|
|
|
|
|
|
// 商品图:多个
|
|
|
if (goodsGroup[1] !== null && goodsGroup[1] !== undefined) {
|
|
|
_.forEach(goodsGroup, function(value, key) {
|
|
|
dest.bannerTop = {};
|
|
|
|
|
|
dest.bannerTop.list = {};
|
|
|
let params = {};
|
|
|
|
|
|
params.img = helpers.getImageUrl(value.img, 450, 600);
|
|
|
dest.bannerTop.list[key] = params;
|
|
|
});
|
|
|
} else if (goodsGroup[0] !== null && goodsGroup[0] !== undefined) {
|
|
|
dest.bannerTop = {};
|
|
|
dest.bannerTop.img = helpers.getImageUrl(goodsGroup[0].img, 450, 600);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 悬浮的购物车信息
|
|
|
dest.cartInfo = {};
|
|
|
dest.cartInfo.cartUrl = helpers.url('/cart/index/index', null);
|
|
|
dest.cartInfo.numInCart = 0;
|
|
|
dest.cartInfo.goodsInstore = origin.storage;
|
|
|
|
|
|
let soldOut = (origin.storage === 0) || (origin.status === 0 || totalStorageNum === 0);
|
|
|
let notForSale = origin.attribute === 2;
|
|
|
|
|
|
// 显示加入购物车链接
|
|
|
if (!soldOut && !notForSale) {
|
|
|
_.orderBy(colorGroup);
|
|
|
|
|
|
dest.cartInfo = {};
|
|
|
dest.cartInfo.productId = origin.id;
|
|
|
dest.cartInfo.thumbs = thumbImageList;
|
|
|
dest.cartInfo.name = (dest.goodsName !== null && dest.goodsName !== undefined) ? dest.goodsName : '';
|
|
|
dest.cartInfo.price = (dest.goodsPrice.previousPrice !== null &&
|
|
|
dest.goodsPrice.previousPrice !== undefined) ? dest.goodsPrice.previousPrice : '';
|
|
|
dest.cartInfo.salePrice = (dest.goodsPrice.currentPrice !== null &&
|
|
|
dest.goodsPrice.currentPrice !== undefined) ? dest.goodsPrice.currentPrice : '';
|
|
|
dest.cartInfo.totalNum = totalStorageNum;
|
|
|
dest.cartInfo.colors = colorGroup;
|
|
|
dest.cartInfo.sizes = sizeGroup;
|
|
|
|
|
|
// 限购商品
|
|
|
if (origin.isLimitBuy === 'Y') {
|
|
|
// 是否开售
|
|
|
let isBeginSale = (origin.saleStatus !== null && origin.saleStatus !== undefined &&
|
|
|
origin.saleStatus === 1);
|
|
|
|
|
|
// 限购商品有关的展示状态
|
|
|
let showStatus = 1;
|
|
|
|
|
|
if (origin.showStatus !== null && origin.showStatus !== undefined) {
|
|
|
showStatus = parseInt(origin.showStatus);
|
|
|
}
|
|
|
|
|
|
// 处理限购商品有关的按钮状态
|
|
|
dest = procShowStatus(dest, showStatus, isBeginSale);
|
|
|
dest.cartInfo.limitProductCode = origin.limitProductCode;
|
|
|
dest.cartInfo.limitCodeUrl = getLimitCodeUrl(origin.limitProductCode, origin.erpProductId, ua);
|
|
|
dest.cartInfo.limitProductPay = helpers.url('/cart/index/orderEnsure');
|
|
|
} else {
|
|
|
dest.cartInfo.addToCartUrl = helpers.url('/product/buy_' + origin.id + '_' +
|
|
|
origin.goodsList.id + '.html'); // 待处理 确认 goodsId 的含义
|
|
|
}
|
|
|
} else if (notForSale) {
|
|
|
dest.cartInfo.notForSale = true;
|
|
|
} else if (soldOut) {
|
|
|
dest.cartInfo.soldOut = true;
|
|
|
}
|
|
|
|
|
|
// 是否收藏
|
|
|
|
|
|
dest.isCollect = false;
|
|
|
if (origin.isCollect !== null && origin.isCollect !== undefined && origin.isCollect === 'Y') {
|
|
|
dest.isCollect = true;
|
|
|
}
|
|
|
|
|
|
// 底部简介的URL链接
|
|
|
dest.introUrl = helpers.url('/product/intro_' + origin.erpProductId + '/' + origin.cnAlphabet + '.html', null, '');
|
|
|
dest.id = origin.id;
|
|
|
|
|
|
return dest;
|
|
|
};
|
|
|
|
|
|
module.exports = (data) => {
|
|
|
var finalResult;
|
|
|
|
|
|
return api.get('', sign.apiSign({
|
|
|
productId: data.id,
|
|
|
uid: data.uid,
|
|
|
vipLevel: data.vipLevel,
|
|
|
method: 'h5.product.data'
|
|
|
})).then(result => {
|
|
|
finalResult = detailDataPkg(result, data.uid, data.vipLevel, data.ua);
|
|
|
|
|
|
return api.get('', sign.apiSign({
|
|
|
method: 'app.shop.queryShopsByBrandId',
|
|
|
brand_id: result.brand.id
|
|
|
})).then(shops => {
|
|
|
if (shops.code === 200) {
|
|
|
finalResult.enterStore = getShopsInfo(shops.data);
|
|
|
}
|
|
|
return finalResult;
|
|
|
});
|
|
|
});
|
|
|
}; |