Authored by 刘传洋

m

... ... @@ -73,28 +73,28 @@ const cart = (req, res, next) => {
/**
* 加入购物车
*/
const cartAdd = () => {
const cartAdd = (req, res) => {
co(function * (){
co(function * () {
let uid = req.user.uid;
let shoppingKey = helper.getShoppingKeyByCookie(req);
let productSku = req.body.productSku;
let buyNumber = req.body.buyNumber || 1;
let goodsType = req.body.goodsType || 0;
let promotionId = req.body.promotionId || 0
let promotionId = req.body.promotionId || 0;
let isEdit = req.body.isEdit || 0;
let result = yield service.addToCart(productSku, buyNumber, goodsType, isEdit, promotionId, uid, shoppingKey);
// 设置加入购物车凭证到客户端浏览器
if(!shoppingKey && result && result.data && result.data.shopping_key) {
if (!shoppingKey && result && result.data && result.data.shopping_key) {
// req.cookies['_SPK'] = result.data.shopping_key
//$this->setCookie('_SPK', $result['data']['shopping_key'], time() + 86400 * 360);
// $this->setCookie('_SPK', $result['data']['shopping_key'], time() + 86400 * 360);
}
// 老站购物车需要的COOKIE
if (result && result.data && result.data.shopping_key) {
/*$this->setCookie('_g', json_encode(array(
/* $this->setCookie('_g', json_encode(array(
'_k' => $result['data']['shopping_key'],
'_nac' => $result['data']['goods_count'],
'_ac' => 0,
... ... @@ -109,9 +109,9 @@ const cartAdd = () => {
/**
* 获取购物车商品总数
*/
const cartTotal = () => {
const cartTotal = (req, res) => {
co(function * (){
co(function * () {
let uid = req.user.uid;
let shoppingKey = helper.getShoppingKeyByCookie(req);
... ... @@ -145,7 +145,7 @@ const selectProduct = (req, res) => {
/**
* 修改购物车商品数量
*/
const modifyProduct = (req, res) => {
const modifyProduct = (req, res, next) => {
let uid = req.user.uid;
let shoppingKey = helper.getShoppingKeyByCookie(req);
... ... @@ -169,7 +169,7 @@ const modifyProduct = (req, res) => {
*/
const removeProduct = (req, res) => {
co(function * (){
co(function * () {
let uid = req.user.uid;
let shoppingKey = helper.getShoppingKeyByCookie(req);
let skuList = req.body.skuList;
... ... @@ -177,7 +177,7 @@ const removeProduct = (req, res) => {
let ret = yield service.removeFromCart(uid, shoppingKey, skuList, hasPromotion);
if(ret && ret.code === 200) {
if (ret && ret.code === 200) {
yield setShoppingCookie();
}
... ... @@ -191,15 +191,16 @@ const removeProduct = (req, res) => {
*/
const moveToFav = (req, res) => {
co(function * (){
co(function * () {
let uid = req.user.uid;
// let shoppingKey = helper.getShoppingKeyByCookie(req);
let skuList = req.body.skuList;
let hasPromotion = req.body.hasPromotion || false;
let ret = yield service.addToFav(uid, skuList, hasPromotion);
if(ret && ret.code === 200) {
if (ret && ret.code === 200) {
yield setShoppingCookie();
}
... ... @@ -212,7 +213,7 @@ const moveToFav = (req, res) => {
*/
const checkFav = (req, res) => {
co(function * (){
co(function * () {
let uid = req.user.uid;
let pids = req.body.pidList;
... ... @@ -233,15 +234,16 @@ const checkFav = (req, res) => {
*/
const getTogetherProduct = (req, res) => {
co(function * (){
co(function * () {
let page = req.query.page;
/*let ret = {
/* let ret = {
code: 200,
message: '凑单商品'
};*/
ret = yield service.getTogetherProduct(page);
let ret = yield service.getTogetherProduct(page);
return res.send(ret);
});
... ... @@ -252,14 +254,14 @@ const getTogetherProduct = (req, res) => {
*/
const getRecommendProductAction = (req, res) => {
co(function * (){
co(function * () {
let channel = req.yoho.channel;
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let page = req.query.page;
if(page === '6') {
if (page === '6') {
page = 1;
}
... ...
/**
* cart api
* @author: lcy<chuanyang.liu@yoho.cn>
* @date: 2016/12/26
*/
'use strict';
const api = global.yoho.API;
const _ = require('lodash');
/**
* 获取购物车数据
* @param uid
* @param shoppingKey
* @returns {*}
*/
const cartData = (uid, shoppingKey) => {
let param = {
method: 'app.Shopping.queryCart' // old: 'app.Shopping.cart'
};
if (!uid) {
param.uid = uid;
}
if (!shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 加入购物车接口
*
* @param int $productSku 商品SKU
* @param int $buyNumber 购买数量
* @param int $goodsType 商品类型,0表示普通商品,1表示加价购商品
* @param int $isEdit 是否是编辑商品SKU,0表示不是编辑
* @param null|int $promotionId 促销id,默认null(加价购有关)
* @param null|int $uid 用户UID,可以不传
* @param string $shoppingKey 未登录用户唯一识别码,可以不传
* @return array 加入购物车接口返回的数据
*/
const addToCart = (productSku, buyNumber,
goodsType, isEdit,
promotionId, uid, shoppingKey) => {
let param = {
method: 'app.Shopping.add',
product_sku: productSku,
buy_number: Number(buyNumber),
goods_type: goodsType,
edit_product_sku: isEdit || 0,
selected: 'Y',
promotion_id: promotionId || null
};
if (uid) {
param.uid = uid;
}
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 购物车商品选择与取消接口
*
* @param int $uid 用户ID
* @param string $sku 商品sku列表
* @param string $shoppingKey 未登录用户唯一识别码
* @param bool $hasPromotion 是否有促销ID
* @return array 购物车接口返回的数据
*/
const selectGoods = (uid, sku, shoppingKey, hasPromotion) => {
let param = {
method: hasPromotion ? 'app.Shopping.selectedAndCart' : 'app.Shopping.selected',
product_sku_list: sku
};
if (uid) {
param.uid = uid;
}
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 移出购物车
*
* @param int $uid 用户ID
* @param string $sku 商品sku列表
* @param string $shoppingKey 未登录用户唯一识别码
* @param bool $hasPromotion 是否有促销ID
* @return array 接口返回的数据
*/
const removeFromCart = (uid, shoppingKey, skuList, hasPromotion) =>{
let param = {
method: hasPromotion ? 'app.Shopping.removeAndCart' : 'app.Shopping.remove',
product_sku_list: skuList
};
if (uid) {
param.uid = uid;
}
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 移入收藏夹
*
* @param int $uid 用户ID
* @param string $sku 商品sku列表
* @param bool $hasPromotion 是否有促销ID
* @return array 接口返回的数据
*/
const addToFav = (uid, skuList, hasPromotion) =>{
let param = {
method: hasPromotion ? 'app.Shopping.addfavoriteAndCart' : 'app.Shopping.addfavorite',
product_sku_list: skuList,
uid: uid
};
return api.get('', param);
};
/**
* 获取购物车商品详情数据
*
* @param int $uid 用户ID
* @param int $skn 商品skn
* @return array 接口返回的数据
*/
const cartProductData = (uid, skn) => {
let param = {
method: 'app.product.data',
product_skn: skn,
showcomment: 'N',
uid: uid
};
return api.get('', param);
};
/**
* 获取加价购商品详情数据
*
* @param int $skn 商品skn
* @param int $promotionId 加价购商品促销ID
* @return array 接口返回的数据
*/
const giftProductData = (skn, promotionId) => {
let param = {
method: 'app.product.gift',
product_skn: skn,
promotion_id: promotionId
};
return api.get('', param);
};
/**
* 增减购物车商品数量
*
* @param int $uid 用户ID
* @param string $sku 商品SKU
* @param int $increaseNum 增加的数目
* @param int $decreaseNum 减少的数目
* @param string $shoppingKey 未登录用户唯一识别码
* @return array 接口返回的数据
*/
const modifyProductNum = (uid, sku, increaseNum, decreaseNum, shoppingKey) => {
let param = {
product_sku: sku
};
// 增加
if (increaseNum) {
param.method = 'app.Shopping.increase';
param.increase_number = Number(increaseNum);
}
// 减少
if (decreaseNum) {
param.method = 'app.Shopping.decrease';
param.decrease_number = Number(decreaseNum);
}
if (uid) {
param.uid = uid;
}
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 修改购物车商品数据
*
* @param int $uid 用户ID
* @param string $swapData 商品数据
* @param string $shoppingKey 未登录用户唯一识别码
* @return array 接口返回的数据
*/
const modifyCartProduct = (uid, swapData, shoppingKey) => {
let param = {};
param.method = 'app.Shopping.swap';
param.swap_data = swapData;
if (uid) {
param.uid = uid;
}
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 购物车结算
*
* @param int $uid 用户ID
* @param string $cartType 购物车类型,ordinary表示普通, advance表示预售
* @param int $isUseYohoCoin 是否使用有货币,默认0不使用, 1使用
* @return array 接口返回的数据
*/
const cartPay = (uid, cartType, isUseYohoCoin) => {
let param = {
method: 'app.Shopping.payment',
cart_type: cartType,
yoho_coin_mode: isUseYohoCoin || 0,
uid: uid
};
if (_.indexOf(['ordinary', 'advance'], cartType) === -1) {
return {
code: 400,
message: '购物车参数类型有误!',
data: {}
};
}
return api.get('', param);
};
/**
* 购物车结算--支付方式和配送方式选择
*
* @param int $uid 用户ID
* @param string $cartType 购物车类型,ordinary表示普通, advance表示预售
* @param int $deliveryWay 配送方式,1表示普通快递,2表示顺丰速运
* @param int $paymentType 支付方式,1表示在线支付,2表示货到付款
* @param string $couponCode 优惠券码
* @param string $promotionCode 优惠码
* @param mixed $yohoCoin 使用的有货币数量
* @param int $redEnvelopes 红包
* @return array 接口返回的数据
*/
const orderCompute = (uid, cartType, deliveryWay, paymentType, couponCode, promotionCode, yohoCoin, redEnvelopes) =>{
let param = {
method: 'app.Shopping.compute',
cart_type: cartType,
delivery_way: deliveryWay,
payment_type: paymentType,
check_yohocoin_amount: 'Y', // 控制是否判断有货币超出订单金额
uid: uid
};
if (_.indexOf(['ordinary', 'advance'], cartType) === -1) {
return {
code: 400,
message: '购物车参数类型有误!',
data: {}
};
}
if (couponCode) {
param.coupon_code = couponCode;
}
if (promotionCode) {
param.promotion_code = promotionCode;
}
if (yohoCoin) {
param.use_yoho_coin = yohoCoin;
}
if (redEnvelopes) {
param.use_red_envelopes = redEnvelopes;
}
return api.get('', param);
};
/**
* 购物车结算--使用优惠券
*
* @param int $uid 用户ID
* @param string $couponCode 优惠券代码
* @return array 接口返回的数据
*/
const searchCoupon = (uid, couponCode) => {
let param = {
method: 'app.Shopping.useCoupon',
coupon_code: couponCode,
uid: uid
};
return api.get('', param);
};
/**
* 购物车结算--获取优惠券列表
*
* @param int $uid 用户ID
* @return array 接口返回的数据
*/
const getCouponList = (uid, limit) => {
let param = {
method: 'app.coupons.lists',
type: 'notuse',
page: 1,
limit: limit || 10,
uid: uid
};
return api.get('', param);
};
/**
* 购物车结算--获取用户可用和不可用的优惠券列表
*
* @param int $uid 用户ID
* @return array 接口返回的数据
*/
const getListCoupon = (uid) => {
let param = {
method: 'app.Shopping.listCoupon',
uid: uid
};
return api.get('', param);
};
/**
* 购物车数量
*
* @param int $uid 用户ID
* @param string $shoppingKey 未登录用户唯一识别码
* @return array 购物车接口返回的数据
*/
const cartCount = (uid, shoppingKey) => {
let param = {
method: 'app.Shopping.count'
};
if (uid) {
param.uid = uid;
}
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
/**
* 凑单商品
*
* @param int $page 分页页码
* @return array
*/
const togetherProduct = (page) => {
let param = {
method: 'web.product.together',
client_type: 'web',
// private_key: Yohobuy::$privateKeyList['web'];
page: page
};
return api.get('', param);
};
/**
* 浏览记录数据
*
* @param int $uid 用户ID
* @param int $udid 客户端唯一标识
* @param int $page 第几页,默认为1
* @param int $limit 限制多少条,默认100
* @return array 接口返回的数据
*/
const browseRecord = (uid, udid, page, limit) => {
let param = {
method: 'app.browse.product',
uid: uid,
udid: udid,
page: page || 1,
limit: limit || 10
};
return api.get('', param);
};
/**
* 通过搜索查询商品信息
*
* 备注:因默认的搜索方法会有过滤, 浏览记录不需要过滤
*
* @param string $query 查询的条件
* @param int $limit 查询的限制数
* @return array
*/
const browseRecordFromSearch = (query, limit) => {
let param = {
method: 'web.search.search',
order: 'shelve_time:desc',
page: 1,
viewNum: limit || 10,
query: query
};
return api.get('', param);
};
/**
* 选择支付,校验时间间隔,插入数据
* @param string $uid
* @param string $orderCode
* @param int $payment 14:银联手机支付 15:支付宝手机 18:支付宝wap(wap) 19:微信支付 22:微信wap(wap) 26:QQ钱包手机支付
* @return type
*/
const savePrePayInfo = (uid, orderCode, payment) => {
let param = {
method: 'app.order.savePrePayInfo',
uid: uid,
orderCode: orderCode,
payment: payment
};
return api.get('', param);
};
/**
* 电子票添加和查询
* @param int $uid 用户ID
* @param type int $productSku 产品sku
* @param type int $buyNumber 购买数量,范围1-4
* @param type int $yohoCoin 有货币
* @return type []
*/
const addTicket = (uid, productSku, buyNumber, yohoCoin) => {
let param = {
method: 'app.shopping.ticket',
uid: Number(uid),
product_sku: Number(productSku),
buy_number: Number(buyNumber)
};
// 有货币转换成元,1有货币等于一分钱
if (yohoCoin && yohoCoin > 0) {
param.use_yoho_coin = yohoCoin / 100;
}
return api.get('', param).then(ret => {
// 展览票不显示区域,上面要求的。@高扬、@徐洪云,2016/7/6
if (ret && ret.data && ret.data.goods_list) {
_.forEach(() => {
// it.size_name = it.product_skn * 1 === EXHIBITION_TICKET ? '' : it.size_name;
// ret.data.goods_list[key] = it;
});
}
return ret;
});
};
const checkUserIsFavProductList = (uid, pidList) => {
pidList = _.isArray(pidList) ? pidList : [];
let promises = _.map(pidList, pid => {
return api.get('', {
method: 'app.favorite.isFavorite',
id: pid,
uid: uid,
type: 'product'
});
});
return Promise.all(promises)
.then(ret => {
let result = {};
_.forEach(pidList, (pid, index) => {
result[pid] = ret[index];
});
return result;
});
};
/**
* 个人中心页面优选新品数据
*
* @param int $channel 频道,1代表男生,2代表女生,3代表潮童,4代表创意生活
* @param $uid 用户ID
* @param $udid 设备ID
* @param $rec_pos 位置码
* @param $limit 数量限制
* @return array 接口返回的数据
*/
const newPreference = (channel, uid, udid, recPos, limit) => {
let param = {
method: 'app.home.newPreference',
yh_channel: channel,
udid: udid,
rec_pos: recPos,
limit: limit
};
if (uid) {
param.uid = uid;
}
return api.get('', param);
};
module.exports = {
cartData,
addToCart,
selectGoods,
removeFromCart,
addToFav,
cartProductData,
giftProductData,
modifyProductNum,
modifyCartProduct,
cartPay,
orderCompute,
searchCoupon,
getCouponList,
getListCoupon,
cartCount,
togetherProduct,
browseRecord,
browseRecordFromSearch,
savePrePayInfo,
addTicket,
checkUserIsFavProductList,
newPreference
};
... ...
... ... @@ -3,6 +3,20 @@
*/
'use strict';
const _ = require('lodash');
const helpers = global.yoho.helpers;
const md5 = require('md5');
const PROMOTION_TYPE_TAG_MAP = {
Cashreduce: '满减', // 满减
Degressdiscount: '折扣', // 分件折扣
Cheapestfree: '满减', // 满X免1
Discount: '折扣', // 打折
Gift: '赠品',
Needpaygift: '加价购',
SpecifiedAmount: '满减' // X件X元
};
/**
* 从用户加入购物车的COOKIE取出购物车凭证
*/
... ... @@ -11,6 +25,349 @@ const getShoppingKeyByCookie = (req) => {
return req.cookies._SPK || '';
};
/**
* 转换价格
*
* @param float|string $price 价格
* @return float|string 转换之后的价格
*/
const transPrice = (price) => {
return price ? (price * 1).toFixed(2) : '0.00';
};
/**
* 生成公开的TOKEN凭证
*
* @param string $string 字符串
* @return string
*/
const makeToken = (str) => {
return md5(md5(str + '#@!@#'));
};
/**
* 购物车商品
* @param array cartGoods 购物车商品列表
* @param bool isAdvanceCart 是否是预售购物车(和上市期有关)
* @param bool inValid 是否是不可用商品(失效商品),默认不是(有效商品)
* @param bool isOffShelves 是否卖光了, 默认否
* @param array analysis 第三方数据分析用的
* @return array 处理之后的购物车商品数据
*/
const formatCartGoods = (cartGoods, isAdvanceCart, inValid, isOffShelves, analysis) => {
return _.map(cartGoods, (it) => {
let goods = {
id: it.product_sku,
skn: it.product_skn,
pid: it.product_id,
isChecked: it.selected === 'Y',
productTitle: it.product_name,
imgCover: it.goods_images ? helpers.image(it.goods_images, 60, 60) : '',
productColor: it.factory_goods_name,
productSize: it.size_name,
productPrice: transPrice(it.last_vip_price), // self::transPrice($value['real_price']);
productNum: it.buy_number,
isVipPrice: it.sales_price !== it.last_vip_price && it.discount_tag === 'V',
isStuPrice: it.sales_price !== it.last_vip_price && it.discount_tag === 'S',
yohoIcon: it.get_yoho_coin || 0,
productSubtotal: transPrice(it.last_vip_price * it.buy_number),
promotionId: it.promotion_id || 0,
isLimitSkn: it.is_limit_skn === 'Y' // is_limit_skn=Y 不支持7天无理由退货
};
// 已下架
if (isOffShelves) {
goods.isTipNoStore = true;
goods.tipMessage = '库存不足';
} else if (!inValid) { // 有效
if (it.buy_number > it.storage_number) {
goods.isTipNoStore = true; // 是否在结算时候显示库存不足
goods.tipMessage = '库存不足';
} else if (it.storage_number <= 2) {
goods.tipMessage = '余量有限';
}
} else { // 失效商品
goods.inValid = true;
}
// advanceBuy=>是否加价购,soldOut=>失效商品;
if (!it.goods_type) {
goods.inValid = true;
} else if (it.goods_type === 'gift' && it.isAdvanceBuy) { // gift=>是否赠品
goods.isGift = true;
goods.productPrice = transPrice(it.last_price);
goods.productSubtotal = it.subtotal ? transPrice(it.subtotal) : goods.productPrice;
} else if (it.goods_type === 'price_gift') { // price_gift=>是否加价购
goods.isPriceGift = true;
goods.productPrice = transPrice(it.last_price);
goods.productSubtotal = it.subtotal ? transPrice(it.subtotal) : goods.productPrice;
} else if (it.real_price === 0) { // 免单
goods.productPrice = transPrice(it.sales_price);
goods.xForOne = true;
// 分析用: 商品ID列表
analysis.ids.push(it.product_id);
// 分析用: CRITEO
analysis.criteo.push({
id: it.product_skn,
quantity: Number(it.buy_number),
price: it.last_vip_price
});
} else {
// 分析用: 商品ID列表
analysis.ids.push(it.product_id);
// 分析用: CRITEO
analysis.criteo.push({
id: it.product_skn,
quantity: Number(it.buy_number),
price: it.last_vip_price
});
}
// 商品类型:预售或普通
goods.goodsType = isAdvanceCart ? 'advance' : 'ordinary';
// 上市期
if (isAdvanceCart && it.expect_arrival_time) {
goods.preSellDate = it.expect_arrival_time;
}
// 商品链接
let cnAlphaBet = it.cn_alphabet ? it.cn_alphabet : md5(it.product_name);
goods.link = helpers.url(`/product/pro_${it.product_id}_${it.goods_id}/${cnAlphaBet}.html`, null, 'item');
return goods;
});
};
/**
* 购物车统计
*/
const formatShoppingCartData = (sc) => {
return {
discountAmount: sc.discount_amount, // 活动价
fastShoppingCost: sc.fast_shopping_cost,
gainYohoCoin: sc.gain_yoho_coin, // 获赠有货币个数
goodsCount: sc.goods_count,
isMultiPackage: sc.is_multi_package,
lastOrderAmount: sc.last_order_amount, // 商品金额总计
orderAmount: sc.order_amount, // 商品总价
// package_list,[],
promotionFormula: sc.promotion_formula,
promotionFormulaList: _.map(sc.promotion_formula_list, it => {
return {
promotion: it.promotion,
promotionAmount: it.promotion_amount
};
}),
selectedGoodsCount: sc.selected_goods_count,
shippingCost: sc.shipping_cost,
strDiscountAmount: sc.str_discount_amount,
strOrderAmount: sc.str_order_amount
};
};
/**
* 全局优惠头部信息
*/
const formatPromotionInfos = (infoList) => {
return _.map(infoList, it => {
return {
cutdownAmount: it.cutdown_amount,
promotionId: it.promotion_id,
promotionTitle: it.promotion_title,
promotionType: it.promotion_type,
tag: PROMOTION_TYPE_TAG_MAP[it.promotion_type]
};
});
};
/**
* 过时商品
* offShelvesList 过时商品列表
*
*/
const formatOffShelves = (offShelvesList, isAdvanceCart, analysis) => {
return formatCartGoods(offShelvesList, isAdvanceCart, false, true, analysis);
};
/**
* 售罄商品
*/
const formatSoldOuts = (soldOutsList, isAdvanceCart, analysis) => {
return formatCartGoods(soldOutsList, isAdvanceCart, false, false, analysis);
};
/**
* 可选加价购
* isGift 是否是赠品:true-赠品
*/
const formatPriceGifts = (giftList, isGift) => {
return _.map(giftList, (it) => {
let gift = {
isShowGift: isGift, // 控制是否显示赠品
isFold: true, // 控制是否[展开]
promotionId: it.promotion_id,
promotionTitle: it.promotion_title.replace('¥', '¥') + '(注:您看到的以下商品可能因为下单时间差已售完)', // subjoinType
maxSelectNumber: it.max_select_number,
promotionType: it.promotion_type
};
gift.goodsList = _.map(it.goods_list, (g) => {
let goods = {
id: g.product_id,
skn: g.product_skn,
subjoinTitle: g.product_name,
imgCover: it.goods_images ? helpers.image(it.goods_images, 60, 60) : '',
subjoinPrice: transPrice(g.last_price),
marketPrice: isGift ? '' : transPrice(g.market_price),
yohoIcon: 0
};
// 商品链接
if (g.goods_id) {
let cnAlphaBet = g.cn_alphabet ? g.cn_alphabet : md5(g.product_name);
goods.subjoinLink = helpers.url(`/product/pro_${g.product_id}_${g.goods_id}/${cnAlphaBet}.html`,
null, 'item');
} else {
let uri = `/product/show_${g.product_id}_${g.product_skn}/${makeToken(g.product_skn)}.html`;
goods.subjoinLink = helpers.url(uri, null, 'item');
}
// 赠品
if (isGift) {
goods.isGift = true;
} else { // 加价购
goods.isPriceGift = true;
}
return goods;
});
});
};
/**
* 购物车赠品
*/
const formatGifts = (giftList) => {
return formatPriceGifts(giftList, true);
};
/**
* 优惠池头部优惠信息列表
*/
const formatPoolPromotionInfos = (infoList) => {
return _.map(infoList, it => {
let status = Number(it.status);
let info = {
status: status,
// "status": 0, // 状态 0 未满足 10 已满足 [20 售光 30 更换 ]
conditionUnit: it.condition_unit, // 0满足,1 件,2金额
condition_value: it.condition_value,
giftPrice: it.gift_price, // 赠品或加价购商品价格
goodsList: formatCartGoods(it.goods_list), // 可供选择的赠品或加价购商品列表
promotionId: it.promotion_id, // 促销id
promotionTitle: it.promotion_title, // "已满足[满30减10-dev30]",
promotionType: it.promotion_type, // 促销类型
tag: PROMOTION_TYPE_TAG_MAP[it.promotion_type],
isGift: it.promotion_type === 'Gift',
isPriceGift: it.promotion_type === 'Needpaygift',
isNotReach: status === 0, // 未满足
isReach: status === 10, // 满足条件
isEmpty: status === 20, // 已售完
isSelected: status === 30 // 已选择,可更换
};
if (status === 0) {
let tipTxt = `差${info.conditionValue}`;
if (info.conditionUnit === 1) {
tipTxt += '件';
} else if (info.conditionUnit === 2) {
tipTxt += '元';
}
info.promotionTitle = tipTxt + info.promotionTitle;
}
return info;
});
};
/**
* 格式化子优惠池信息,返回商品列表,子优惠列表放在每个商品中
*/
const formatSubPromotionPools = (pools) => {
let goodsListPool = _.map(pools, p => {
let pool = {
goodsList: formatCartGoods(p.goods_list),
promotionInfos: formatPoolPromotionInfos(p.promotion_list)
};
let goodsList = pool.goodsList;
if (goodsList && goodsList.length) {
return _.map(goodsList, g => {
g.promotionInfos = pool.promotionInfos;
return g;
});
}
return [];
});
// [ [goods, goods], [goods, ..], [] ] => [goods, goods ]
return goodsListPool.flatten(goodsListPool);
};
/**
* 优惠池
*/
const formatPromotionPools = (pools) => {
return _.map(pools, p => {
let pool = {
goodsList: formatCartGoods(p.goods_list),
promotionInfos: formatPoolPromotionInfos(p.promotion_list)
};
if (p.sub_promotion_list) {
let goodsWithPromotion = formatSubPromotionPools(p.sub_promotion_list);
if (_.isArray(goodsWithPromotion) && goodsWithPromotion.length) {
pool.goodsList = goodsWithPromotion.concat(pool.goodsList);
}
}
return pool;
});
};
module.exports = {
getShoppingKeyByCookie
transPrice,
getShoppingKeyByCookie,
formatCartGoods,
formatGifts,
formatPriceGifts,
formatShoppingCartData,
formatPromotionPools,
formatPromotionInfos,
formatOffShelves,
formatSoldOuts
};
... ...
... ... @@ -10,8 +10,12 @@ const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const md5 = require('md5');
const ERROR_400_MESSAGE = '系统繁忙,请稍候再试!';
const productAPI = require('./product-api');
const cartApi = require('./cart-api');
const chelper = require('./cart-helper');
const _getProductIntroAsync = (productSkn) => {
return co(function * () {
... ... @@ -293,7 +297,6 @@ const _detailDataPkg = (origin) => {
}
let result = {};
let propOrigin = _.partial(_.get, origin);
// 商品名称
... ... @@ -360,7 +363,6 @@ const getProductInfoAsync = (pid) => {
}
let productSkn = _.get(productData, 'data.product_skn');
let requestData = yield Promise.all([
_getProductIntroAsync(productSkn), // 商品详细介绍
_detailDataPkg(productData.data) // 商品详细价格
... ... @@ -368,7 +370,6 @@ const getProductInfoAsync = (pid) => {
let productDescription = requestData[0];
let productInfo = requestData[1];
let intro = _getIntroInfo(productSkn, productDescription);
return Object.assign(productInfo, intro);
... ... @@ -377,87 +378,434 @@ const getProductInfoAsync = (pid) => {
const getCartData = (uid, shoppingKey, cartDelList) => {
return Promise.resolve({
uid,
shoppingKey,
cartDelList
let analysisData = {
ids: [],
criteo: []
}; // 存放分析用的数据
return co(function * () {
let result = {
isEmpty: false,
searchUrl: helpers.urlFormat('', null, 'search'), // 搜索链接(再逛逛)
listUrl: helpers.urlFormat('', null, 'list'),
viewOrderUrl: helpers.urlFormat('/home/orders', {
t: new Date().getTime()
})
};
// 未登录
if (!uid) {
result.loginUrl = helpers.urlFormat('/signin.html', {
refer: helpers.urlFormat('/shopping/cart')
});
}
// 调用接口,获取购物车数据
let cartDataRet = yield cartApi.cartData(uid, shoppingKey);
let cartData = cartDataRet && cartDataRet.data;
// 接口异常时,购物车置为空
if (!cartData) {
result.isEmpty = true;
// UdpLog::info('【购物车】校验参数传递auth', 'uid:' . $uid . 'shoppingKey:' . $shoppingKey);
return result;
}
result.advanceCart = {
goodsList: chelper.formatCartGoods(_.get(cartData, 'advance_cart_data.goods_list'),
true, false, false, analysisData), // 未参加活动的商品
offShelves: chelper.formatOffShelves(_.get(cartData, 'advance_cart_data.off_shelves_goods_list'),
true, analysisData),
soldOuts: chelper.formatSoldOuts(_.get(cartData, 'advance_cart_data.sold_out_goods_list'),
true, analysisData),
stat: chelper.formatShoppingCartData(_.get(cartData, 'advance_cart_data.shopping_cart_data'))
};
result.ordinaryCart = {
gifts: chelper.formatGifts(_.get(cartData, 'ordinary_cart_data.gift_list')),
goodsList: chelper.formatCartGoods(_.get(cartData, 'ordinary_cart_data.goods_list'),
false, false, false, analysisData), // 未参加活动的商品
promotionPools: chelper.formatPromotionPools(_.get(cartData, 'ordinary_cart_data.promotion_pool_list')),
offShelves: chelper.formatOffShelves(_.get(cartData, 'ordinary_cart_data.off_shelves_goods_list'),
false, analysisData),
soldOuts: chelper.formatSoldOuts(_.get(cartData, 'ordinary_cart_data.sold_out_goods_list'),
false, analysisData),
priceGifts: chelper.formatPriceGifts(_.get(cartData, 'ordinary_cart_data.price_gift')),
promotionInfos: chelper.formatPromotionInfos(_.get(cartData, 'ordinary_cart_data.promotion_info')),
stat: chelper.formatShoppingCartData(_.get(cartData, 'ordinary_cart_data.shopping_cart_data'))
};
result.stat = {
orderAmount: _.get(result, 'advanceCart.stat.orderAmount', 0) +
_.get(result, 'ordinaryCart.stat.orderAmount', 0),
discountAmount: _.get(result, 'advanceCart.stat.discountAmount', 0) +
_.get(result, 'ordinaryCart.stat.discountAmount', 0),
lastOrderAmount: _.get(result, 'advanceCart.stat.lastOrderAmount', 0) +
_.get(result, 'ordinaryCart.stat.lastOrderAmount', 0),
gainYohoCoin: _.get(result, 'advanceCart.stat.gainYohoCoin', 0) +
_.get(result, 'ordinaryCart.stat.gainYohoCoin', 0),
goodsCount: _.get(result, 'advanceCart.stat.goodsCount', 0) +
_.get(result, 'ordinaryCart.stat.goodsCount', 0)
};
/* 移除的商品列表 */
if (cartDelList) {
result.deleteShop = cartDelList;
}
// 普通购物车和预售购物车都为空
/* if (ordinaryCount === 0 && advanceCount === 0 && ordinarySoldOut && advanceSoldOut) {
result.isEmpty = true;
return result;
}*/
return result;
}).then(ret => {
// 增加第三方分析用的数据
// ret['ids'] = empty($analysisData['ids']) ? '' : implode(',', $analysisData['ids']);
// $result['criteo'] = empty($analysisData['criteo']) ? "''" : json_encode($analysisData['criteo']);
return Object.assign(ret, {
ids: _.isArray(analysisData.ids) ? analysisData.ids.join(',') : '',
criteo: analysisData.criteo || ''
// empty($analysisData['criteo']) ? "''" : json_encode($analysisData['criteo']);
});
});
};
/**
* 获取购物车总数
*
* @param int $uid 用户ID
* @param string $shoppingKey 客户端购物标识
* @return array
*/
const getCartCount = (uid, shoppingKey) => {
return Promise.resolve({
uid,
shoppingKey
});
return cartApi.cartCount(uid, shoppingKey);
};
/**
* 加入购物车
*
* @param int $productSku 商品SKU
* @param int $buyNumber 购买数量
* @param int $goodsType 商品类型,0表示普通商品,1表示加价购商品
* @param int $isEdit 是否是编辑商品SKU,0表示不是编辑
* @param null|int $promotionId 促销id,默认null(加价购有关)
* @param null|int $uid 用户UID,可以不传
* @param string $shoppingKey 购物车在浏览器的唯一识别码,可以不传
* @return array 加入购物车接口返回的数据
*/
const addToCart = (productSku, buyNumber, goodsType, isEdit, promotionId, uid, shoppingKey) => {
return Promise.resolve({
productSku,
buyNumber,
goodsType,
isEdit,
promotionId,
uid,
shoppingKey
return co(function * () {
let result = {
code: 400,
message: ERROR_400_MESSAGE
};
if (!productSku) {
return result;
}
let ret = yield cartApi.addToCart(productSku, buyNumber, goodsType, isEdit, promotionId, uid, shoppingKey);
if (ret && ret.code) {
result = ret;
}
/* if (empty($addCart) || (isset($addCart['code']) && $addCart['code'] !== 200) ) {
UdpLog::info('【购物车】校验参数传递auth','productSku:'.$productSku.'buyNumber:'.$buyNumber.
'goodsType:'.$goodsType,'isEdit:'.$isEdit.'promotionId:'.$promotionId.'uid:'.$uid.'shoppingKey:'.$shoppingKey);
}*/
return result;
});
};
const selectGoods = (uid, productId, shoppingKey, hasPromotion) => {
/**
* 购物车商品选择与取消接口返回的数据处理
*
* @param int $uid 用户ID
* @param string $skuList 商品sku列表json格式, 如{"744403":1}
* @param string $shoppingKey 未登录用户唯一识别码
* @param bool hasPromotion 标识是不是有promotion_id参数, 后端会去调用不同的接口
* @return array 处理之后的数据的数据
*/
const selectGoods = (uid, skuList, shoppingKey, hasPromotion) => {
return co(function * () {
let result = {
code: 400,
message: ERROR_400_MESSAGE
};
if (!skuList) {
// UdpLog::info('【购物车】校验参数传递auth', 'skuList:' . $skuList);
return result;
}
let select = yield cartApi.selectGoods(uid, skuList, shoppingKey, hasPromotion);
if (select && select.code) {
result = select;
}/* else {
UdpLog::info('【购物车】校验参数传递auth', 'uid:' . $uid . 'skuList:'
. $skuList . 'shoppingKey:' . $shoppingKey . 'hasPromotion:' . $hasPromotion);
}*/
return Promise.resolve({
uid,
productId,
shoppingKey,
hasPromotion
return result;
});
};
/**
* 修改购物车商品数量
*
* @param int $uid 用户ID
* @param string $sku 商品SKU
* @param int $increaseNum 增加的数目
* @param int $decreaseNum 减少的数目
* @param string $shoppingKey 未登录用户唯一识别码
* @return array 接口返回的数据
*/
const modifyProductNum = (uid, sku, increaseNum, decreaseNum, shoppingKey) => {
return Promise.resolve({
uid,
sku,
increaseNum,
decreaseNum,
shoppingKey
return co(function * () {
let result = {
code: 400,
message: ERROR_400_MESSAGE
};
if (!sku) {
// UdpLog::info('【购物车】校验参数传递auth', 'sku:' . $sku);
return result;
}
let modify = cartApi.modifyProductNum(uid, sku, increaseNum, decreaseNum, shoppingKey);
if (modify && modify.code) {
result = modify;
}/* else {
UdpLog::info('【购物车】校验参数传递auth', 'uid:' . $uid . 'sku:' . $sku, 'increaseNum:'
. $increaseNum . 'decreaseNum:' . $decreaseNum . 'shoppingKey:' . $shoppingKey);
}*/
return result;
});
};
/**
* 移出购物车
*
* @param int $uid 用户ID
* @param string $skuList 商品sku列表json格式, 如{"744403":1}
* @param string $count 要删除的数目
* @param string $shoppingKey 未登录用户唯一识别码
* @param bool hasPromotion 标识是不是有promotion_id参数, 后端会去调用不同的接口
* @return array 接口返回的数据
*/
const removeFromCart = (uid, shoppingKey, skuList, hasPromotion) => {
return Promise.resolve({
uid,
shoppingKey,
skuList,
hasPromotion
return co(function * () {
let result = {
code: 400,
message: ERROR_400_MESSAGE
};
if (!skuList) {
// UdpLog::info('【购物车】校验参数传递auth', 'skuList:' . $skuList);
return result;
}
let remove = cartApi.removeFromCart(uid, shoppingKey, skuList, hasPromotion);
if (remove && remove.code) {
result.code = remove.code;
result.message = remove.message;
if (remove.data && remove.data.goods_count) {
result.totalGoodsNum = remove.data.goods_count;
}
}/* else {
UdpLog::info('【购物车】校验参数传递auth', 'uid:' . $uid . 'skuList:' .
$skuList . 'shoppingKey:' . $shoppingKey . 'hasPromotion:' . $hasPromotion);
}*/
return result;
});
};
/**
* 移入收藏夹
*
* @param int $uid 用户ID
* @param string $skuList 商品sku列表
* @param bool hasPromotion 标识是不是有promotion_id参数, 后端会去调用不同的接口
* @return array 接口返回的数据
*/
const addToFav = (uid, skuList, hasPromotion) => {
return Promise.resolve({
uid,
skuList,
hasPromotion
return co(function * () {
let result = {
code: 400,
message: ERROR_400_MESSAGE
};
if (!uid) {
return {
code: 403,
message: '请先登录!',
data: {
url: helpers.urlFormat('/signin.html', {
refer: helpers.urlFormat('/shopping/cart')
})
}
};
}
if (!skuList) {
// UdpLog::info('【购物车】校验参数传递auth', 'skuList:' . $skuList);
return result;
}
let add = cartApi.addToFav(uid, skuList, hasPromotion);
if (add && add.code) {
result = add;
}/* else {
UdpLog::info('【购物车】校验参数传递auth', 'uid:' . $uid . 'skuList:' . $skuList . 'hasPromotion:' . $hasPromotion);
}*/
return result;
});
};
const checkUserIsFav = (uid, pids) => {
return Promise.resolve({
uid,
pids
/**
* 检查用户是否收藏这一批商品
*
* @param int $uid 用户ID
* @param array $skuList 商品SKU列表
* @return array
*/
const checkUserIsFav = (uid, skuList) => {
return co(function * () {
let result = {};
if (!skuList) {
return result;
}
if (!uid || !_.isNumber(uid)) {
_.forEach(skuList, it => {
result[it] = false;
});
return result;
}
return cartApi.checkUserIsFavProductList(uid, skuList);
});
};
/**
* 获取为你优选商品 待处理
*
* @param $channel 频道
* @param $uid 用户id
* @param $udid 设备id
* @param int $page 分页页码
* @return array
* @internal param $rec_pos
* @internal param $limit
*/
const getRecommendProduct = (channel, uid, udid, page) => {
return Promise.resolve({
channel,
uid,
udid,
page
return co(function * () {
let result = {
code: 200,
message: '',
data: {
header: '为您优选',
hasPrev: false,
hasNext: false,
item: {}
}
};
let channelNum = 1;
if (!_.isNumber(page)) {
return result;
}
switch (channel) {
case 'boys':
channelNum = 1;
break;
case 'girls':
channelNum = 2;
break;
case 'kids':
channelNum = 3;
break;
case 'lifestyle':
channelNum = 3;
break;
default:
break;
}
let together = yield cartApi.newPreference(channelNum, uid, udid, '100003', 30);
let plist = _.get(together, 'data.product_list');
if (!plist || !plist.length) {
return result;
}
if (page > 5) {
page = 1;
}
let begin = (page - 1) * 6;
let end = begin + 7;
let items = _.map(_.slice(plist, begin, end), it => {
let item = {
id: it.product_id,
skn: it.product_skn,
// href: Helpers::getUrlBySkc($value['product_id'],
// $value['goods_list'][0]['product_skc'], $value['cn_alphabet']),
title: it.product_name,
img: it.default_images ? helpers.image(it.default_images, 100, 100) : '',
alt: it.product_name,
price: chelper.transPrice(it.sales_price)
};
// 商品链接
let cnAlphaBet = it.cn_alphabet ? it.cn_alphabet : md5(it.product_name);
let firstGoods = it.goods_list && it.goods_list[0];
let productSkc = firstGoods && firstGoods.product_skc;
item.href = helpers.url(`/product/pro_${it.product_id}_${productSkc}/${cnAlphaBet}.html`, null, 'item');
if (it.sales_price !== it.market_price) {
it.marketPrice = chelper.transPrice(it.market_price);
}
return item;
});
Object.assign(result.data, {
hasPrev: page > 1,
hasNext: plist.length >= end,
item: items
});
return result;
});
};
... ...