Showing 42 changed files with 2712 additions and 1528 deletions

Too many changes to show.

To preserve performance only 42 of 42+ files are displayed.

... ... @@ -143,6 +143,7 @@ public/bundle/*
.vscode/
.DS_Store
.devhost
library
### foreman ###
Procfile
... ...
web: npm run dev
gulp: gulp --cwd=public
proxy: d:\dev\traefik\traefik.exe -c d:\dev\traefik\conf.toml
mem: d:\dev\memcached\memcached.exe
... ...
... ... @@ -360,9 +360,9 @@ const getRecommendProductAction = (req, res) => {
co(function * () {
let channel = req.yoho.channel;
let channelNum = req.yoho.channelNum;
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let page = Number(req.query.page || 1);
let ret;
... ... @@ -370,7 +370,7 @@ const getRecommendProductAction = (req, res) => {
page = 1;
}
ret = yield service.getRecommendProduct(channel, uid, udid, page);
ret = yield service.getRecommendProduct(channelNum, uid, udid, page);
res.send(ret);
})();
};
... ...
... ... @@ -23,13 +23,15 @@ const index = (req, res, next) => {
result.stepper = stepper;
if (params.limitcode) { // 限定发售不支持优惠券
result.couponUnsupport = true;
result.notUseCoupon = true;
}
res.render('order-ensure', {
page: 'easypay',
res.render('order-ensure2016', {
title: '填写订单 | ' + (res.locals.title || ''),
page: 'ensure',
content: result,
simpleHeader: header
simpleHeader: header,
pageClass: 'order-easypay-page'
});
}).catch(next);
};
... ...
... ... @@ -12,6 +12,7 @@ const logger = global.yoho.logger;
const authcode = require(`${global.utils}/authcode`);
const headerModel = require('../../../doraemon/models/simple-header');
const oeModel = require('../models/order-ensure');
const easypayModel = require('../models/easypay');
const stepper = [
{name: '查看购物车', focus: true},
... ... @@ -55,18 +56,28 @@ const compute = (req, res, next) => {
let params = req.body;
let cartType = params.cartType === '2' ? 'advance' : 'ordinary';
oeModel.compute(req.user.uid, cartType, params).then(data => {
res.send(data);
}).catch(next);
if (params.sku) { // 快捷结算
easypayModel.getOrderComputeData(req.user.uid, 'ordinary', params).then(result => {
res.json(result);
}).catch(next);
} else {
oeModel.compute(req.user.uid, cartType, params).then(data => {
res.send(data);
}).catch(next);
}
};
// 提交订单
const submit = (req, res, next) => {
let cartType = req.body.cartType === '2' ? 'advance' : 'ordinary';
let params = req.body;
let cartType = params.cartType === '2' ? 'advance' : 'ordinary';
let uid = req.user.uid;
let remoteIp = req.ip;
if (!req.body.addressId || !req.body.paymentType || !req.body.deliveryWay) {
if (!params.addressId || !params.paymentType || !params.deliveryWay) {
res.send({
code: 500,
message: '订单参数不完整'
... ... @@ -127,20 +138,26 @@ const submit = (req, res, next) => {
userAgent = clientId ? 'YOHO!Buy/3.8.2.259(Model/PC;Channel/' + clientId + ';uid/' + uid + ')' : null;
}
Object.assign(req.body, {
Object.assign(params, {
qhyUnion: unionKey,
userAgent: userAgent
});
oeModel.submit(uid, cartType, req.body, remoteIp).then(data => {
if (data && data.code === 200 && unionKey) {
data.data.unionKey = {
client_id: clientId
};
}
if (params.sku) { // 快捷结算
easypayModel.easypayOrderSubmit(uid, 'ordinary', params, remoteIp).then(result => {
res.json(result);
}).catch(next);
} else {
oeModel.submit(uid, cartType, params, remoteIp).then(data => {
if (data && data.code === 200 && unionKey) {
data.data.unionKey = {
client_id: clientId
};
}
res.send(data);
}).catch(next);
res.send(data);
}).catch(next);
}
};
module.exports = {
... ...
... ... @@ -592,7 +592,10 @@ const formatCart = (cartDataRet, uid, shoppingKey, cartDelList) => {
promotionInfos: formatPromotionInfos(_.get(ordCartData, 'promotion_info'), goodsList),
stat: formatShoppingCartData(_.get(ordCartData, 'shopping_cart_data')),
ensureUrl: helpers.urlFormat('/cart/ensure')
ensureUrl: helpers.urlFormat('/cart/ensure'),
// 免运费提示
tips: _.get(ordCartData, 'shipping_cost_prompt.shipping_cost_tips', '')
};
let advStat = result.advanceCart.stat;
... ...
... ... @@ -701,7 +701,7 @@ const checkUserIsFav = (uid, skuList) => {
* @internal param $rec_pos
* @internal param $limit
*/
const getRecommendProduct = (channel, uid, udid, page) => {
const getRecommendProduct = (channelNum, uid, udid, page) => {
return co(function * () {
... ... @@ -715,29 +715,11 @@ const getRecommendProduct = (channel, uid, udid, page) => {
item: null
}
};
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');
... ...
... ... @@ -11,119 +11,10 @@ const helper = global.yoho.helpers;
const crypto = global.yoho.crypto;
const easypayApi = require('./easypay-api');
const addressApi = require('./address-api');
const ensureApi = require('./order-ensure-api');
const _handelViewPrice = list => {
if (list) {
_.forEach(list, val => {
if (val.promotion === '商品金额') {
val.promotion = '商品总价';
val.promotion_amount = `+ ${val.promotion_amount}`;
} else {
val.promotion_amount = _.replace(val.promotion_amount, '+', '+ ');
val.promotion_amount = _.replace(val.promotion_amount, '-', '- ');
}
});
}
};
const _handelUseYohoCoin = (info) => {
let resData = {};
let limitCoin = _.get(info, 'yoho_coin_pay_rule.num_limit', 0);
if (info) {
Object.assign(resData, {
yoho_coin: info.yoho_coin.toFixed(2),
use_yoho_coin: info.use_yoho_coin,
total_yoho_coin_num: info.total_yoho_coin_num,
yoho_coin_pay_rule: info.yoho_coin_pay_rule,
canUseCoinNum: _.round(info.yoho_coin * 100),
usedCoinNum: _.round(info.use_yoho_coin * 100)
});
if (!resData.canUseCoinNum) {
let coinErrorTip = '';
if (info.total_yoho_coin_num > limitCoin) {
coinErrorTip = '抱歉,您的订单实付款不满足有货币使用条件';
} else {
coinErrorTip = `抱歉,您的有货币不足,有货币满${limitCoin}个方可使用`;
}
resData.coinErrorTip = coinErrorTip;
}
}
return resData;
};
const _handelPaymentInfo = (d) => {
let resData = {};
if (d.delivery_address) {
// 地址信息加密
d.delivery_address.id = crypto.encryption('', `${d.delivery_address.address_id}`);
delete d.delivery_address.address_id;
resData.deliveryAddress = d.delivery_address;
}
d.shopping_cart_data.hasCoin = _.round(d.yoho_coin * 100); // 有货币稀释
let supportLine = [];
_.forEach(['zhifubao', 'zaixianzhifu', 'weixinzhifu', 'wangyinzaixian',
'caifutong', 'shengfutong', 'tonglianzhifu'], sl => {
supportLine.push(`//static.yohobuy.com/images/pay/icon/${sl}.png`);
}
);
resData.supportLine = supportLine;
let supportBank = [];
_.forEach(
['BOC', 'ICBC', 'CMB', 'CCB', 'ABC', 'SPDB', 'CIB', 'GDB', 'SDB', 'CMBC',
'COMM', 'CITIC', 'HZCBB2C', 'CEB', 'SHBANK', 'NBBANK', 'SZPAB', 'BJRCB', 'FDB', 'PSBC'],
sb => {
supportBank.push(`//static.yohobuy.com/images/bankico/${sb}.gif`);
}
);
resData.supportBank = supportBank;
_.forEach(d.goods_list, g => {
// link to goods
g.linkToGoods = helper.getUrlBySkc(g.product_id, g.goods_id, g.cn_alphabet);
});
resData.goodsList = d.goods_list;
_.remove(d.payment_way, function(n) {
return n.is_support === 'N';
});
let dPw = _.find(d.payment_way, {default: 'Y'});
let dDt = _.find(d.delivery_time, {default: 'Y'});
resData.defaultPayDelivery = {
paymentTypeName: dPw ? dPw.payment_type_name : '在线支付(推荐)',
paymentType: dPw ? dPw.payment_type : 1,
paymentTypeId: dPw ? dPw.payment_id : 15,
deliveryTimeStr: dDt ? dDt.delivery_time_string : '送货时间不限',
deliveryTimeId: dDt ? dDt.delivery_time_id : 2,
contractMe: false
};
if (d.shopping_cart_data && d.shopping_cart_data.promotion_formula_list) {
_handelViewPrice(d.shopping_cart_data.promotion_formula_list);
}
Object.assign(resData, {
paymentWay: d.payment_way,
deliveryTime: d.delivery_time,
deliveryWay: d.delivery_way,
shoppingCartData: Object.assign(d.shopping_cart_data, _handelUseYohoCoin(d)),
invoices: d.invoices
});
return resData;
};
const ensureHandle = require('./order-ensure-handle');
const _getLimitProductData = (params) => {
let resList = [];
... ... @@ -151,17 +42,25 @@ const _getLimitProductData = (params) => {
return resList.length ? JSON.stringify(resList) : false;
};
// 获取结算信息
const getEasypayOrderData = (params, uid) => {
let resData = {};
let strInfo = _getLimitProductData(params);
let bundle = params.bundle ? parseInt(params.bundle, 10) : false;
return easypayApi.getEasyPaymentAsync(uid, strInfo, bundle).then(result => {
let d = _.get(result, 'data', false);
if (d) {
Object.assign(resData, _handelPaymentInfo(d), {
productSkuList: crypto.encryption('', strInfo)
return Promise.all([
easypayApi.getEasyPaymentAsync(uid, strInfo, bundle),
addressApi.getAddressListAsync(uid),
ensureApi.getUserProfileAsync(uid)
]).then(result => {
let data = _.get(result, '[0].data', false);
let address = _.get(result, '[1].data', []);
let receiver = _.get(result, '[2].data.mobile', '');
if (data) {
Object.assign(resData, ensureHandle.handlePaymentInfo(data, address), {
receiverMobile: receiver,
hideReceiverMobile: _.replace(receiver, /(\d{3})\d{4}(\d{4,9})/, '$1****$2')
});
}
... ... @@ -169,7 +68,7 @@ const getEasypayOrderData = (params, uid) => {
});
};
// 价格计算
const getOrderComputeData = (uid, cartType, params) => {
params.productSkuList = _getLimitProductData(params);
... ... @@ -180,10 +79,10 @@ const getOrderComputeData = (uid, cartType, params) => {
}
if (_.has(result, 'data.promotion_formula_list')) {
_handelViewPrice(result.data.promotion_formula_list);
ensureHandle.handleViewPrice(result.data.promotion_formula_list);
}
result.data = Object.assign(result.data, _handelUseYohoCoin(result.data));
result.data = Object.assign(result.data, ensureHandle.handleUseYohoCoin(result.data));
}
return result;
});
... ...
<div class="order-ensure-page yoho-page {{pageClass}}">
{{# content}}
<div class="order-ensure-title">
{{> shopping-step}}
</div>
<div class="basic-info">
<h2 class="title">
请填写并核对以下信息
</h2>
<div class="info-block-wrap">
<div class="address-info info-block">
<p class="name">
收货地址:
<em id="address-modify" class="info-status address-status">[修改]</em>
<em id="abort-address-modify" class="info-status address-status hide">[不保存并关闭]</em>
</p>
{{# deliveryAddress}}
<p id="address-used" class="address-used" data-id="{{id}}" data-mobile="{{mobile}}">
<em class="consignee">{{consignee}}</em>
<em class="address-text">{{area}} {{address}} {{zip_code}} {{mobile}} {{phone}}</em>
</p>
{{/ deliveryAddress}}
<div id="address-editor-wrap" class="address-editor-wrap hide">
<ul id="address-list" class="address-list">
<li class="address-item use-new-address">
<input type="radio" name="address-item-radio">使用新地址
</li>
</ul>
<ul id="address-form" class="address-form hide">
<li>
<span class="editor-legend">
<em class="star">*</em>收货人姓名:
</span>
<input class="editor-consignee editor" type="text" data-attr="consignee">
请填写您的真实姓名,最多5个汉字
</li>
<li>
<span class="editor-legend">
<em class="star">*</em>省市:
</span>
<select id="editor-province" class="editor-province"></select>
<select id="editor-city" class="editor-city">
<option value="0">请选择城市</option>
</select>
<select id="editor-area" class="editor-area">
<option value="0">请选择区县</option>
</select>
<input class="editor-address editor" type="text" data-attr="address">
标*的为支持加急送的地区,请输入收货的详细地址
</li>
<li>
<span class="editor-legend">
<em class="star">*</em>手机号码:
</span>
<input class="editor-mobile editor" type="text" data-attr="mobile">
填写正确手机号便于接受发货和收货通知
</li>
<li>
<span class="editor-legend">固定电话:</span>
<input class="editor-phonecode editor" type="text">
<input class="editor-phone editor" type="text" data-attr="phone">
如:010-12345678,固话和手机号至少填一项
</li>
<li>
<span class="editor-legend">电子邮件:</span>
<input class="editor-email editor" type="text" data-attr="email">
用来接收订单提醒邮件,便于您及时了解订单状态
</li>
<li>
<span class="editor-legend">邮编:</span>
<input class="editor-zipcode editor" type="text" data-attr="zipCode">
请填写准确的邮编,以确保商品尽快送达
</li>
</ul>
<span id="save-set-address" class="save-set-address">保存并送到这个地址</span>
</div>
</div>
<div id="pay-delivery-info" class="pay-delivery-info info-block">
<p class="name">
支付及送货时间:
<em id="pd-modify" class="info-status pd-status">[修改]</em>
<em id="abort-pd-modify" class="info-status pd-status hide">[不保存并关闭]</em>
</p>
{{# defaultPayDelivery}}
<ul id="pay-delivery-used" class="pay-delivery-used">
<li>
付款方式:<em id="payment-way" data-id="{{paymentTypeId}}" data-type="{{paymentType}}">{{paymentTypeName}}</em>
</li>
<li>
送货时间:<em id="delivery-time" data-id="{{deliveryTimeId}}">{{deliveryTimeStr}}</em>
</li>
<li>
送货前联系我:<em id="contract-me">{{#if contractMe}}{{^}}{{/if}}</em>
</li>
</ul>
{{/ defaultPayDelivery}}
<div id="pay-delivery-choice" class="pay-delivery-choice hide">
<p class="sub-title payment-sub-title">支付方式</p>
<ul class="payment-type">
{{#each paymentWay}}
<li>
<input type="radio" name="pay-type-radio"{{#isY default}} checked{{/isY}} data-id="{{payment_id}}" data-type="{{payment_type}}" data-name="{{payment_type_name}}">{{payment_type_name}}
{{#isEqual payment_type 1}}
<span class="check-banks">
查看支持在线支付的银行和平台
</span>
<div class="supports hide">
<p>支持以下支付平台在线支付</p>
<div class="online-support">
{{#each ../../supportLine}}
<img src="{{image2 .}}">
{{/each}}
</div>
<p>支持以下银行在线支付</p>
<div class="bank-support">
{{#each ../../supportBank}}
<img src="{{image2 .}}">
{{/each}}
</div>
</div>
{{/isEqual}}
</li>
{{/each}}
</ul>
<p class="sub-title">送货时间</p>
<ul class="delivery-time">
<li class="delivery-time-tip">温馨提示:快递公司会尽力按您选择的送货时间配送,如遇特殊情况(天气、环境等)无法按您要求的时间配送,还请您谅解。</li>
{{# deliveryTime}}
<li>
<input type="radio" name="delivery-time-radio"{{#isY default}} checked{{/isY}} data-id="{{delivery_time_id}}" data-name="{{delivery_time_string}}">{{delivery_time_string}}
</li>
{{/ deliveryTime}}
<li class="contract-me">
送货前是否联系:
<input type="radio" name="contract-me-radio" value="1">
<input type="radio" name="contract-me-radio" checked value="0">
</li>
</ul>
<span id="pay-delivery-sure" class="btn pay-delivery-btn">确定</span>
</div>
</div>
<div class="fregit-info info-block">
<p class="name">选择快递:</p>
<ul class="delivery-way">
{{# deliveryWay}}
<li>
<input type="radio" name="delivery-way-radio"{{#isY default}} checked{{/isY}} value="{{delivery_way_id}}">
{{delivery_way_name}}:运费¥{{delivery_way_cost}}
</li>
{{/ deliveryWay}}
<li class="delivery-way-tip">注:配送会由于天气,交通等不可抗拒的客观因素造成您收货时间延迟,请您知悉。</li>
<li class="delivery-way-warn">如您购买的商品为航空禁运品顺丰会用陆运的方式给你派送,预计3-5天送达,请您见谅</li>
</ul>
</div>
</div>
</div>
{{#with shopping_cart_data}}
{{#isY is_multi_package}}
<div class="multi-package-row">
温馨提示:您购买的商品<em class="red">分属不同仓库</em>,需要调拨,将被拆分成多个包裹送达
<span class="iconfont show-package">&#xe628;</span>
<div class="package-list hide">
<div class="package-up-icon"></div>
{{#each ../package_list}}
<div class="package-item">
<p class="package-title bold">包裹{{math @index '+' 1}}:{{#if @first}}总仓发货{{^}}异地调拨{{/if}}</p>
{{#if showToggle}}
<span class="iconfont toggle-icon left-icon">&#xe609;</span>
<span class="iconfont toggle-icon right-icon">&#xe608;</span>
{{/if}}
<div class="package-goods-wrap">
<ul class="package-goods clearfix">
{{#each goods_list}}
<li class="left">
<img class="lazy package-goods-img" data-original="{{image2 goods_images w=90 h=90}}">
</li>
{{/each}}
</ul>
</div>
<p class="package-shipping">运费:¥{{shopping_cost}}</p>
</div>
{{/each}}
</div>
</div>
{{/isY}}
{{/with}}
<table class="goods-table">
<thead>
<tr>
<th width="40%">商品信息</th>
<th width="10%">单价(元)</th>
<th width="10%">返YOHO币</th>
<th width="10%">数量</th>
<th width="10%">小计(元)</th>
<th width="20%">商品金额(元)</th>
</tr>
</thead>
<tbody>
{{#each goodsList}}
<tr>
<td>
<a class="image" href="{{linkToGoods}}">
<img src="{{image2 goods_images w=60 h=60}}">
</a>
<p class="name-size-color">
<a href="{{linkToGoods}}">{{product_name}}</a>
<span>颜色:{{color_name}} 尺码:{{size_name}}</span>
</p>
</td>
<td>
¥{{round last_vip_price 2}}
</td>
<td>
{{yoho_coin_num}}
</td>
<td>
{{buy_number}}
</td>
<td>
{{str_subtotal}}
</td>
{{#if @first}}
{{#with ../shoppingCartData}}
<td rowspan="{{selected_goods_count}}">{{str_order_amount}}</td>
{{/with}}
{{/if}}
</tr>
{{/each}}
</tbody>
</table>
<div class="invoice-wrap">
<p class="title">发票信息</p>
<div class="content">
<div id="without-invoice" class="without-invoice invoice-label">
<input id="invoice-radio" class="invoice-radio" type="radio">
<label for="invoice-radio">发票开具</label>
</div>
<div id="with-invoice" class="with-invoice invoice-label hide">
<input id="invoice-radio-checked" type="radio" checked>
<label for="invoice-radio-checked">发票开具</i>
<em></em>
<span id="modify-invoice" class="modify-invoice">修改</span>
</div>
</div>
</div>
{{# shoppingCartData}}
<div class="balance-wrap clearfix">
<div class="remark left">
<span id="remark-btn" class="remark-btn">添加备注信息</span>
<div class="remark-content hide">
<textarea id="remark" class="remark-text"></textarea>
<p class="remark-tip">声明:备注中有关收货人信息、支付方式、配送方式、发票信息等购买要求一律以上面的选择为准,备注无效。</p>
是否打印价格:
<input type="radio" name="print-price" value="Y" checked>
<input type="radio" name="print-price" value="N"> 否(如:送朋友的商品可不打印价格哦!)
</div>
</div>
<ul id="balance-detail" class="balance-detail right">
<li class="gain-coin">
<a class="gain-coin-tip" href="/help/detail?id=105" target="_blank"></a>
共返YOHO币:{{gain_yoho_coin}}
</li>
{{#each promotion_formula_list}}
<li class="promotion-item{{#isEqual promotion '运费'}} fregit-promotion{{/isEqual}}">
<span class="promotion-name">{{promotion}}</span>
<em class="promotion-val">{{promotion_amount}}</em>
</li>
{{/each}}
<li>
{{#if ../couponUnsupport}}
<span class="use-coupons not-support">该商品不可使用优惠券</span>
{{^}}
<span id="use-coupons" class="use-coupons coupons-trigger">使用优惠券支付</span>
<div class="using-coupon coupons-trigger hide">
<p>请选择您要使用的优惠券:</p>
<p class="orange">(OUTLET商品除免邮券外不可使用优惠券)</p>
<p class="orange">(订单中使用优惠券将不赠送商品返还的YOHO币)</p>
<ul id="coupon-list" class="coupon-list">
<li>
<input type="radio" name="coupons" checked> 直接输入优惠券码:
<input id="coupon-code" class="coupon-code" type="text">
</li>
</ul>
<p class="btns">
<span id="coupons-sure" class="coupons-sure sure-btn">确定</span>
<span id="coupons-cancel" class="coupons-cancel cancel-btn">取消</span>
</p>
</div>
{{/if}}
</li>
<li>
<span id="use-coin" class="use-coin coin-trigger">使用有货币支付</span>
<div class="using-coin coin-trigger hide">
<ul id="using-coin-cont">
{{#if coinErrorTip}}
<li><span class="red">{{coinErrorTip}}</span></li>
{{/if}}
<li>
有货币满<span class="red">{{yoho_coin_pay_rule.num_limit}}</span>个即可使用,每次使用有货币为<span class="red">{{yoho_coin_pay_rule.num_limit}}</span>的整数倍
<i class="iconfont help-icon">&#xe628;</i>
<div class="coin-tip-help">
<p>有货币使用提示:</p>
<p>
1.订单金额大于20元(含20元)<br>
2.有货币数量大于{{yoho_coin_pay_rule.num_limit}}个(含{{yoho_coin_pay_rule.num_limit}}个) <br>
3.有货币支付上限为每笔订单应付金额的{{yoho_coin_pay_rule.max_pay_rate_desc}}
</p>
<p class="rs-text">备注:使用有货币数量为{{yoho_coin_pay_rule.num_limit}}的整数倍,100有货币抵1元</p>
</div>
</li>
<li>您当前共有有货币 <span class="red">{{total_yoho_coin_num}}</span> 个,可用 <span class="red">{{canUseCoinNum}}</span></li>
<li>
<p{{#if coinErrorTip}} class="coin-use-hide"{{/if}}>本次使用有货币<span class="red">{{canUseCoinNum}}</span>个,抵扣 <span class="red">¥{{yoho_coin}}</span></p>
</li>
</ul>
<p class="btns">
<span id="coin-sure" class="coin-sure sure-btn">确定</span>
<span id="coin-cancel" class="coin-cancel cancel-btn">取消</span>
<a href="/help/detail?id=105" class="coin-help" target="_blank">有货币使用规则?</a>
</p>
</div>
<input id="coin-used" type="hidden" data-coin="{{usedCoinNum}}" data-max={{canUseCoinNum}}>
</li>
</ul>
</div>
<p id="sum-row" class="sum-row" data-amount="{{order_amount}}">您需要实际支付金额:<em>{{round last_order_amount 2}}</em></p>
{{/ shoppingCartData}}
<p class="go-pay-row">
<span id="go-pay" class="go-pay">去付款</span>
</p>
{{> order-tpl}}
{{/ content}}
</div>
... ... @@ -75,13 +75,12 @@
{{#with shoppingCartData}}
{{#isY is_multi_package}}
<div class="multi-package-row">
温馨提示:您购买的商品<em class="red">分属不同仓库</em>需要调拨,将被拆分成多个包裹送达
温馨提示:您购买的商品<em class="red">分属不同仓库</em>{{../package_title}}<em class="red">预计3-5天内发货给您</em>
<span class="show-package"></span>
<div class="package-list hide">
<div class="package-up-icon"></div>
{{#each ../package_list}}
<div class="package-item">
<p class="package-title bold">包裹{{math @index '+' 1}}:{{#if @first}}总仓发货{{^}}异地调拨{{/if}}</p>
<p class="package-title bold">包裹{{math @index '+' 1}}:{{#isEqual supplier_id '0'}}总仓发货{{^}}异地调拨 <em class="red">预计3-5天内发货给您</em>{{/isEqual}}</p>
<div class="toggle-btns">
<span class="toggle-icon left-icon"></span>
<span class="toggle-icon right-icon"></span>
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
let CouponsModel = require('../models/coupons-model');
const helpers = global.yoho.helpers;
let couponsModel = require('../models/coupons-model');
const index = (req, res, next)=>{
let uid = '8041246';
let type = req.query.type || CouponsModel.UNUSED;
let page = '';
let limit = '';
co(function*() {
let coupons = yield CouponsModel.getCouponsList(uid, type, page, limit);
let data = {};
data.pager = {
hasCheckAll: false,
count: coupons.pager.total || 0,
curPage: coupons.pager.page || 0,
totalPages: coupons.pager.pageTotal || 0
};
if (type === CouponsModel.UNUSED) {
if (!coupons.list.length) {
data.unUseCoupons = {empty: '您没有优惠券'};
} else {
data.unUseCoupons = coupons.list;
}
data.unUse = true;
} else if (type === CouponsModel.USED) {
if (!coupons.list.length) {
data.usedCoupons = {empty: '您没有优惠券'};
} else {
data.usedCoupons = coupons.list;
}
data.used = true;
}
else if (type === CouponsModel.INVALID) {
if (!coupons.list.length) {
data.noValidCoupons = {empty: '您没有优惠券'};
} else {
data.noValidCoupons = coupons.list;
}
data.noValid = true;
}
let uid = req.user.uid;
data.tabs = [
{
active: type === CouponsModel.UNUSED ? true : false,
url: helpers.urlFormat('/home/coupons', {type: CouponsModel.UNUSED}),
name: '未使用优惠券'
},
{
ctive: type === CouponsModel.USED ? true : false,
url: helpers.urlFormat('/home/coupons', {type: CouponsModel.USED}),
name: '已使用优惠券'
},
{
ctive: type === CouponsModel.INVALID ? true : false,
url: helpers.urlFormat('/home/coupons', {type: CouponsModel.INVALID}),
name: '已失效优惠券'
}
];
res.render('coupons', data);
})();
couponsModel.couponsData(uid, req.query).then(result => {
res.render('coupons', result);
}).catch(next);
};
module.exports = {
... ...
/**
* 个人中心二维码 controller
* 个人中心我的有货币 controller
* @author: weiqingting<qingting.wei@yoho.cn>
* @date: 2016/05/16
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const CurrencyModel = require('../models/currency-model');
const moment = require('moment');
const convertUnitTime = (src) => {
return moment.unix(src).format('YYYY-MM-DD');
};
const currencyModel = require('../models/currency-model');
const index = (req, res, next)=>{
let $uid = '8041246';
let $condition = {
page: req.query.page || 1,
queryType: req.query.type || 0,
beginTime: req.query.beginTime || convertUnitTime(new Date() / 1000 - 3600 * 24 * 90)
};
co(function*() {
let data = yield CurrencyModel.currencyData($uid, $condition);
let uid = req.user.uid;
currencyModel.currencyData(uid, req.query).then(result => {
res.render('currency', {
content: data
content: result
});
})().catch(next);
}).catch(next);
};
module.exports = {
... ...
... ... @@ -6,50 +6,127 @@
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const favoriteService = require('../models/favorite-service');
const TABS = {
product: 'product',
brand: 'brand',
article: 'article'
};
const index = (req, res, next)=> {
let uid = '8041246';
let udid = '8041246';
let uid = req.user.uid;
let udid = req.yoho.udid;
let page = +req.query.page || 1;
let type = req.query.type || TABS.product;
let selectedSort = +req.query.sort_id || 0;
let reduction = req.query.is_reduction || 'N';
let promotion = req.query.is_promotion || 'N';
let limit = +req.query.limit || 10;
co(function*() {
let page = req.query.page || 1;
let type = req.query.type || 'article';
let sort = req.query.sort_id || 0;
let reduction = req.query.is_reduction || 'N';
let promotion = req.query.is_promotion || 'N';
let limit = 10;
let data = {};
data.tabs = favoriteService.getFavoriteTabs('product');
data.tabs = favoriteService.getFavoriteTabs(type);
switch (type) {
case 'brand':
data.favBrands = yield favoriteService.favoriteBrandList(uid, page, limit, type);
case TABS.brand:
data.favBrands = yield favoriteService.favoriteBrandListAsync(uid, page, limit, type);
break;
case 'article':
data.favArticles = yield favoriteService.favoriteArticleListAsync(uid, udid, page, limit);
case TABS.article:
data.favArticles = yield favoriteService.favoriteArticleListAsync(uid, udid, page, limit, type);
break;
default:
data.favProducts = yield favoriteService.favoriteProductList(uid, page, limit, type, sort, 'N', reduction, promotion);
data.favProducts = yield favoriteService.favoriteProductListAsync(
uid, page, limit, selectedSort, 'N', reduction, promotion, req.query
);
break;
}
res.render('favorite', {
return data;
})().then((result) => {
return res.render('favorite', {
meFavoritePage: true,
meFavorite: data
meFavorite: result
});
}).catch(next);
};
const newProduct = (req, res, next) => {
let uid = req.user.uid;
let page = +req.query.page || 1;
let limit = +req.query.limit || 10;
let id = +req.query.id || 0;
if (!id) {
return res.json({
code: 400,
message: '缺少参数'
});
}
favoriteService.newProductAsync(uid, page, limit, id).then((result) => {
return res.json({
code: 200,
data: result
});
})().then(next);
}).catch(next);
};
const reductionAction = ()=> {
const reduction = (req, res, next) => {
let uid = req.user.uid;
let page = +req.query.page || 1;
let type = req.query.type || '';
let limit = 10;
favoriteService.reductionAsync(uid, page, limit, type, 0, 'Y').then((result) => {
return res.render('home/favorite/reduction', result);
}).catch(next);
};
const notice = (req, res, next) => {
let uid = req.user.uid;
let id = req.query.id;
let mobile = req.query.mobile;
favoriteService.enableNoticeAsync(uid, mobile, id).then((result) => {
return res.json(result);
}).catch(next);
};
const cancelNotice = (req, res, next) => {
let uid = req.user.uid;
let id = req.query.id;
favoriteService.disableNoticeAsync(uid, id).then((result) => {
return res.json(result);
}).catch(next);
};
const cancel = (req, res, next) => {
let uid = req.user.uid;
let id = req.query.id;
let type = req.query.type || 'product';
if (!uid || !id) {
return res.json({
code: 400,
message: '缺少参数'
});
}
favoriteService.cancelAsync(uid, id, type).then((result) => {
return res.json(result);
}).catch(next);
};
module.exports = {
index
index,
newProduct,
reduction,
notice,
cancelNotice,
cancel
};
... ...
'use strict';
const _ = require('lodash');
const headerService = require('../models/general-tabs-service');
const getCommonHeader = (req, res, next) => {
let channel = req.query.channel;
let uid = req.user.uid;
let clientService = _.get(req.app.locals.pc, 'clientService.new', false);
headerService.getHomeNav(uid, channel, req.originalUrl, clientService).then((result)=>{
_.merge(res.locals, result);
next();
});
};
module.exports = {
getCommonHeader
};
... ...
/**
* 个人中心---兑换礼品卡
* @author gaohongwei <hongwei.gao@yoho.cn>
* @date: 2016/9/7
*/
'use strict';
const mRoot = '../models';
const giftService = require(`${mRoot}/gift-service`); // user model
/**
* 礼品卡页面
*/
exports.index = (req, res, next) => {
let uid = req.user.uid;
let responseData = {
module: 'home',
page: 'gift'
};
// 真实数据输出
giftService.index(req.query, uid).then(result => {
responseData.meGiftPage = true;
Object.assign(responseData, result);
res.render('gift', responseData);
}).catch(next);
};
/**
* 个人中心-兑换礼品卡提交返回信息
*/
exports.exchange = (req, res, next) => {
let uid = req.user.uid;
// 真实数据输出
giftService.exchange(req, req.body, uid).then(result => {
res.json(result);
}).catch(next);
};
... ...
/**
* 个人中心二维码 controller
* @author: weiqingting<qingting.wei@yoho.cn>
* @date: 2016/05/16
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const OrderData = require('../models/order-data');
const IndexModel = require('../models/index-model');
const indexService = require('../models/index-service');
const index = (req, res, next)=>{
let $uid = '8041246';// req.user.uid;
let $udid = 'abcdrf';// req.sessionID;
co(function*() {
let items = yield Promise.all([OrderData.closeReasons(),
IndexModel.getInfoNumData($uid, $udid),
IndexModel.getFooterBanner(),
IndexModel.latestOrders($uid),
IndexModel.homeData()]);
let cancelReason = items[0].data ? items[0].data : '';
res.render('index', {
cancelReason: cancelReason,
content: [
{messages: items[1]},
{
latestOrders: items[3],
favBrand: {
more: '/brands',
brands: items[4].brand
},
newArrival: items[4].new,
banner: items[2]
}
],
helpUsUrl: ''
let uid = req.user.uid;
let udid = req.user.uid + req.yoho.udid;
let channel = req.yoho.channel;
let isStudent = req.user.isStudent;
indexService.index(uid, udid, channel, isStudent).then((result) => {
return res.render('index', {
module: 'home',
page: 'index',
meIndexPage: true,
me: result
});
})().catch(next);
}).catch(next);
};
module.exports = {
... ...
'use strict';
const _ = require('lodash');
const ordersService = require('../models/orders-service');
const index = (req, res, next) => {
let uid = req.user.uid;
let page = _.parseInt(req.query.page) || 1;
let type = _.parseInt(req.query.type) || ordersService.ORDER_TYPE.all;
let limit = _.parseInt(req.query.limit) || 10;
ordersService.index(uid, page, limit, type).then((result) => {
return res.render('home/orders/orders', {
meOrdersPage: true,
meOrders: result
});
}).catch(next);
};
const reBuy = (req, res, next) => {
let uid = req.user.uid;
let orderId = req.body.orderCode || '';
if (!orderId) {
return res.json({
code: 400,
message: '缺少参数'
});
}
ordersService.reBuy(uid, orderId).then((result) => {
return res.json(result);
}).catch(next);
};
const del = (req, res, next) => {
let uid = req.user.uid;
let orderId = req.body.orderCode || '';
let channel = req.yoho.channel;
let gender = req.yoho.gender;
if (!orderId) {
return res.json({
code: 400,
message: '缺失必填项'
});
}
ordersService.del(uid, gender, channel, orderId).then((result) => {
return res.json(result);
}).catch(next);
};
const modifyAddress = (req, res, next) => {
let uid = req.user.uid;
let orderId = req.body.orderCode || ''; // 订单号
let userName = req.body.userName || ''; // 收货人
let areaCode = req.body.areaCode || ''; // 区号
let address = req.body.address || ''; // 地址
let mobile = req.body.mobile || ''; // 手机号码
let phoneNum = req.body.phoneNum || ''; // 固定电话
let phoneCode = req.body.phoneCode || ''; // 电话编号
let phone = (function() {
if (phoneNum) {
if (phoneCode) {
return `${phoneCode}-${phoneNum}`;
} else {
return phoneNum;
}
} else {
return '';
}
}());
if (!orderId || !userName || !areaCode || !address) {
return res.json({
code: 400,
message: '缺失必镇项'
});
}
ordersService.updateDeliveryAddress(orderId, userName, areaCode, address, mobile, phone, uid)
.then(result => res.json(result))
.catch(next);
};
const confirm = (req, res, next) => {
let uid = req.user.uid;
let orderId = req.body.orderCode || '';
if (!orderId) {
return res.json({
code: 400,
message: '参数缺失'
});
}
ordersService.confirm(uid, orderId).then((result) => {
return res.json(result);
}).catch(next);
};
const cancel = (req, res, next) => {
let uid = req.user.uid;
let orderId = req.body.orderCode || '';
let reason = req.body.reason || '';
let reasonId = req.body.reasonId || '';
ordersService.cancel(uid, orderId, reason, reasonId)
.then(result => res.json(result))
.catch(next);
};
const detail = (req, res, next) => {
let orderId = req.query.orderCode || req.query.order_code;
let uid = req.user.uid;
if (!orderId) {
return res.redirect('/home');
}
ordersService.detail(uid, orderId).then((result) => {
if (_.isEmpty(result)) {
return res.redirect('/home');
}
return res.render('home/orders/order-detail', {
meOrderPage: true,
meOrderDetail: result.detail,
packages: result.package,
cancelReason: result.cancelReason
});
}).catch(next);
};
const express = (req, res, next) => {
let orderId = req.query.orderId || '';
let uid = req.user.uid;
let payType = req.query.payType;
let time = req.query.time;
if (!orderId) {
return res.json({
code: 400,
message: '参数出错'
});
}
ordersService.express(orderId, uid, payType, time).then((result) => {
return res.json(result);
}).catch(next);
};
const refund = (req, res, next) => {
let uid = req.user.uid;
let orderId = req.query.orderId;
let reasonId = req.query.reasonId;
if (!orderId || !reasonId) {
return res.json({
code: 400,
message: '参数错误'
});
}
ordersService.refund(uid, orderId, reasonId).then((result) => {
return res.json(result);
}).catch(next);
};
const refundReason = (req, res, next) => {
ordersService.refundReason().then((result) => {
return res.json({
code: 200,
data: result
});
}).catch(next);
};
module.exports = {
index,
reBuy,
del,
modifyAddress,
confirm,
cancel,
detail,
express,
refund,
refundReason
};
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const RedenvelopesModel = require('../models/redenvelopes-model');
const redenvelopesModel = require('../models/redenvelopes-model');
const index = (req, res, next)=>{
let $uid = '8041246';// req.user.uid;
let $udid = 'abcdrf';// req.sessionID;
let uid = req.user.uid;
co(function*() {
let result = yield RedenvelopesModel.redenvelopesList($uid);
res.render('Redenvelopes', {
redenvelopesModel.redenvelopesList(uid).then(result => {
res.render('redenvelopes', {
meRedEnvelopes: result
});
})().catch(next);
}).catch(next);
};
module.exports = {
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const UserData = require('../models/user-data');
const moment = require('moment');
const helpers = global.yoho.helpers;
const vipModel = require('../models/vip-service');
const index = (req, res, next)=>{
let uid = '8041246';// req.user.uid;
co(function*() {
let vipInfo = yield UserData.getVIPInfoByUid(uid);
let data = vipInfo.data, proportion = '0%';
if (+data.next_need_cost != 0) {
proportion = data.current_year_cost * 100 / data.next_need_cost;
proportion = proportion > 100 ? 100 : proportion;
proportion = proportion + '%';
}
let remainDays = Math.floor((Date.now() - (+data.vip_end_time) * 1000) / 86400);
// let preferences={};
// enjoyPreferences=data.enjoy_preferential;
if (data.enjoy_preferential) {
data.enjoy_preferential = data.enjoy_preferential.map(function(item, inex) {
return {
id: item.id,
favTxt: item.title,
imgType: helpers.https(item.pic),
description: item.description
};
});
}
let vip = {
title: data.current_vip_title,
level: data.current_vip_level,
totalCost: (+data.current_total_cost).toFixed(2),
nextTitle: data.next_vip_title,
nextLevel: data.next_vip_level,
nextCost: data.next_need_cost,
enjoyPreferences: data.enjoy_preferential,
yearCost: data.current_year_cost,
upgradeCost: data.upgrade_need_cost,
proportion: proportion,
reach: moment(data.vip_reach_time * 1000).format('YYYY-MM-DD'),
start: moment(data.vip_start_time * 1000).format('YYYY-MM-DD'),
end: moment(data.vip_end_time * 1000).format('YYYY-MM-DD'),
remainDays: remainDays,
platinum: data.upgrade_need_cost > 0 ? false : true,
isVip: data.current_vip_level > 0 ? true : false
};
res.render('vip', vip);
let uid = req.user.uid;
})().catch(next);
vipModel.vipIndex(uid).then(result => {
res.render('vip', result);
}).catch(next);
};
module.exports = {
... ...
/**
* @author: weiqingting<qingting.wei@yoho.cn>
*/
const exchangeDay = 15;
const refundDay = 7;
module.exports = {
exchangeDay,
refundDay
};
'use strict';
module.exports.xchangeDay = 15;
module.exports.refundDay = 7;
module.exports.payType = {
1: '在线支付',
2: '货到付款',
3: '刷卡支付'
};
module.exports.orderTagArr = {
gift: {
name: '赠品',
classname: 'freebie-tag'
},
price_gift: {
name: '加价购',
classname: 'advance-buy-tag'
},
advance: {
name: '预售',
classname: 'presall-tag'
},
ticket: {
name: '虚拟商品',
classname: 'virtual-good-tag'
}
};
... ...
... ... @@ -4,19 +4,17 @@
*/
'use strict';
const path = require('path');
const Promise = require('bluebird');
const moment = require('moment');
const _ = require('lodash');
const imgUtils = require(path.join(global.utils, 'images'));
const api = global.yoho.API;
const searchApi = global.yoho.SearchAPI;
const helpers = global.yoho.helpers;
const co = Promise.coroutine;
// 分页 函数
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
const pager = require(pagerPath).handlePagerData;
const pager = require(`${global.utils}/pager`).setPager;
const imgUtils = require(`${global.utils}/images`);
const NO_CONSULT = '您尚未咨询任何内容';
... ... @@ -27,12 +25,13 @@ const NO_CONSULT = '您尚未咨询任何内容';
* @return array
*/
function getProductGoodsInfo(skns) {
const query = skns.join(',');
const query = _.join(_.uniq(skns), ',');
return searchApi.get('/search.json', {
data: {
query: query
}
return api.get('', {
method: 'h5.product.batch',
limit: skns.length,
productSkn: query,
contain_all: 'Y'
}).then(result => {
let resData = {};
... ... @@ -84,20 +83,18 @@ exports.consultList = (uid, page, limit) => {
let goodInfos = yield getProductGoodsInfo(skns);
origin.consult_list.forEach(consult => {
let goodInfo = goodInfos[consult.skn];
if (!goodInfo) {
return;
}
let info = {
href: helpers.getUrlBySkc(goodInfo.productId, goodInfo.goodsId, goodInfo.cn_alphabet),
thumb: imgUtils.getImageUrl(goodInfo.images_url, 60, 60, 1),
href: helpers.getUrlBySkc(consult.productId),
name: consult.productName,
question: consult.ask || '',
consultTime: moment(consult.askTime).format('YYYY-MM-DD H:m:s')
consultTime: moment(consult.askTime * 1000).format('YYYY-MM-DD HH:mm:ss')
};
let goodInfo = goodInfos[consult.skn];
if (goodInfo) {
info.thumb = imgUtils.getImageUrl(goodInfo.default_images, 60, 60);
}
if (consult.answer) {
info.reply = consult.answer;
... ... @@ -106,11 +103,11 @@ exports.consultList = (uid, page, limit) => {
result.consults.push(info);
});
result.pager = pager(origin.total, {
page: origin.page,
limit: limit
});
result.pager = Object.assign({
count: origin.total,
curPage: page,
totalPages: origin.page_total
}, pager(origin.page_total, {page: page}));
}
if (!result.consults.length) {
result.empty = NO_CONSULT;
... ... @@ -119,6 +116,5 @@ exports.consultList = (uid, page, limit) => {
return result;
});
return fetchConsults(data).then(processData);
};
... ...
... ... @@ -6,7 +6,13 @@ const co = Promise.coroutine;
const UserData = require('./user-data');
const helpers = global.yoho.helpers;
const path = require('path');
const _ = require('lodash');
const moment = require('moment');
// 使用 product中的分页逻辑
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
const pager = require(pagerPath).handlePagerData;
const UNUSED = 'notuse';
const USED = 'use';
... ... @@ -15,11 +21,15 @@ const INVALID = 'overtime';
const getCouponsList = (uid, type, page, limit)=>{
return co(function*() {
let couponsInfo = yield UserData.getCouponsList(uid, type, page, limit);
let result = [];
if (!couponsInfo.data.couponList) {
return result;
let result = [],
coupons = _.get(couponsInfo, 'data.couponList');
if (!coupons) {
return {
list: result
};
}
let coupons = couponsInfo.data.couponList;
if (coupons) {
coupons.forEach(function(item, i) {
result[i] = {};
... ... @@ -27,36 +37,53 @@ const getCouponsList = (uid, type, page, limit)=>{
result[i].code = item.couponCode;
// 格式化有效日期 "couponValidity": "2016.03.15-2016.03.31"
let dates = item.couponValidity.split('-');
let dates = item.couponValidity.split('-'),
extra = ['秒杀', '限定', '境外', '预售'],
limits = _.get(item, 'shopPriceLimits', '');
result[i].beginTime = dates[0].replace('.', '-');
result[i].endTime = dates[1].replace('.', '-');
result[i].beginTime = dates[0];
result[i].endTime = dates[1];
if (!item.couponImageUrl) {
result[i].img = '//static.yohobuy.com/images/v2/activity/default_coupon.jpg';
} else {
result[i].img = item.couponImageUrl;
}
if ((item.overTime - Date.now()) < 259200) {
result[i].endSoon = true;
} else {
result[i].endSoon = false;
}
result[i].value = item.couponValue.toFixed(2);
result[i].value = item.couponValue;
result[i].validity = item.couponValidity;
result[i].useRemark = item.couponDetailInfomation;
if (!_.isEmpty(item.sortNameLimit)) {
result[i].categorys = item.sortNameLimit.join('、');
}
if (!_.isEmpty(item.brandNameLimit)) {
result[i].brands = item.brandNameLimit.join('、');
}
if (limits.indexOf('1') >= 0) {
extra.push('3折以下');
}
if (limits.indexOf('2') >= 0) {
extra.push('限量');
}
result[i].extraPro = extra.join('、');
result[i].isNoLimit = item.isNoLimit === 'true' ? true : false;
result[i].explains = _.isEmpty(item.explains) ? false : item.explains;
result[i].proListUrl = helpers.urlFormat('', {cpc_id: item.couponId,
phrase: encodeURIComponent('以下商品可使用 【' + item.couponDetailInfomation + '】优惠券')}, 'list');
result[i].rule = item.rule4ShortName || '';
result[i].overState = item.overState || '';
if (type === USED) {
result[i].orderNum = item.orderCode ? item.orderCode : '';
result[i].orderDetailUrl = helpers.urlFormat('/home/orders/detail', {orderCode: item.orderCode || ''});
result[i].orderSum = item.orderPrice.toFixed(2) ? item.orderPrice : 0;
result[i].payment = item.actuallyPaid.toFixed(2) ? item.actuallyPaid : 0;
let data = result[i].usedTime ? moment(result[i].usedTime).format('YYYY-MM-DD') : 0;
if (data) {
result[i].useTime = new Date(date).getTime();
result[i].orderNum = _.get(item, 'orderCode', '');
result[i].orderDetailUrl = helpers.urlFormat('/home/orders/detail',
{orderCode: item.orderCode || ''});
result[i].orderSum = _.get(item, 'orderPrice', 0).toFixed(2);
result[i].payment = _.get(item, 'actuallyPaid', 0).toFixed(2);
let date = item.usedTime ? moment(item.usedTime).format('YYYY-MM-DD H:m') : 0;
if (date) {
result[i].useTime = date;
} else {
result[i].useTime = '';
}
... ... @@ -65,23 +92,74 @@ const getCouponsList = (uid, type, page, limit)=>{
}
if (item.couponType) {
result[i].type = item.couponType;
if (item.couponType == 5) {
if (Number(item.couponType) === 5) {
result[i].value = '免邮';
}
}
});
}
return {list: result, pager: {
total: couponsInfo.data.total,
pageTotal: couponsInfo.data.totalPageNum,
page: page
}};
let pageNum = pager(couponsInfo.data.total, {
page: page,
limit: limit,
type: type
});
return {
list: result,
pager: Object.assign({
count: couponsInfo.data.total || 0,
curPage: page,
totalPages: couponsInfo.data.totalPageNum
}, pageNum)
};
})();
};
const couponsData = (uid, params)=>{
let type = params.type || UNUSED;
let page = params.page || 1;
let limit = params.limit || 10;
return co(function*() {
let coupons = yield getCouponsList(uid, type, page, limit);
let data = {};
if (type === UNUSED) {
data.unUseCoupons = !coupons.list.length ? {empty: '您没有优惠券'} : coupons.list;
data.unUse = true;
} else if (type === USED) {
data.usedCoupons = !coupons.list.length ? {empty: '您没有优惠券'} : coupons.list;
data.used = true;
} else if (type === INVALID) {
data.noValidCoupons = !coupons.list.length ? {empty: '您没有优惠券'} : coupons.list;
data.noValid = true;
}
data.tabs = [
{
active: type === UNUSED ? true : false,
url: helpers.urlFormat('/home/coupons', {type: UNUSED}),
name: '未使用优惠券'
},
{
active: type === USED ? true : false,
url: helpers.urlFormat('/home/coupons', {type: USED}),
name: '已使用优惠券'
},
{
active: type === INVALID ? true : false,
url: helpers.urlFormat('/home/coupons', {type: INVALID}),
name: '已失效优惠券'
}
];
data.pager = coupons.pager;
return data;
})();
};
module.exports = {
getCouponsList,
UNUSED,
USED,
INVALID
couponsData
};
... ...
... ... @@ -2,8 +2,6 @@
* @author: weiqingting<qingting.wei@yoho.cn>
*/
'use strict';
const helpers = global.yoho.helpers;
const api = global.yoho.API;
const yohoCoinList = (uid, condition)=>{
... ... @@ -14,6 +12,7 @@ const yohoCoinList = (uid, condition)=>{
page: 1,
limit: 15
};
Object.assign(options, condition);
return api.get('', options);
};
... ... @@ -23,10 +22,22 @@ const yohoCoinTotal = uid=>{
method: 'app.yoho.yohocoin',
uid: uid
};
return api.get('', options);
};
const getProduct = (skn, limit)=>{
let options = {
method: 'h5.product.batch',
productSkn: skn,
limit: limit
};
return api.get('', options);
};
module.exports = {
yohoCoinList,
yohoCoinTotal
yohoCoinTotal,
getProduct
};
... ...
... ... @@ -8,11 +8,8 @@ const co = Promise.coroutine;
const path = require('path');
const helpers = global.yoho.helpers;
const api = global.yoho.API;
const _ = require('lodash');
const Image = require('../../../utils/images');
const CurrencyData = require('./currency-data');
const SearchData = require('./SearchData');
const currencyApi = require('./currency-api');
// 使用 product中的分页逻辑
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
... ... @@ -24,109 +21,132 @@ const convertUnitTime = (src) => {
return moment.unix(src).format('YYYY-MM-DD');
};
const currencyData = (uid, condition)=>{
return co(function*() {
let result = {};
let yohoCoinInfo = yield CurrencyData.yohoCoinTotal(uid);
console.log(yohoCoinInfo);
if (yohoCoinInfo.code && yohoCoinInfo.code == 200) {
let yohoCoinInfoData = yohoCoinInfo.data;
result.myCurrency = yohoCoinInfoData.yohocoin_num ? yohoCoinInfoData.yohocoin_num : 0;
if (yohoCoinInfoData.nearExpCoinNum && yohoCoinInfoData.nearExpCoinNum > 0) {
result.tip.count = yohoCoinInfoData.nearExpCoinNum;
result.tip.date = 'Y年12月31日';
}
const currencyTabs = (type)=>{
let tabs = ['全部明细', '全部收入', '全部支出'],
result = [];
tabs.forEach(function(val, key) {
result.push({
active: key === parseInt(type, 10) ? true : false,
url: helpers.urlFormat('/home/currency', {type: key}),
name: val
});
});
return result;
};
const currencyOptions = (condition)=>{
let result = [], paramUrl = {};
let tabs = {90: '最近3个月明细', 180: '最近半年明细', 360: '最近一年明细'};
for (let name in tabs) {
if (condition.queryType) {
paramUrl.type = condition.queryType;
}
let currency = yield currencyList(uid, condition);
result.currency = currency.list;
result.pager = currency.pager;
result.coinHelperUrl = '//www.yohobuy.com/help/detail?id=105';// yoho币帮助
result.tabs = currencyTabs(condition.queryType);
result.options = currencyOptions(condition);
return result;
})();
paramUrl.beginTime = convertUnitTime(new Date() / 1000 - parseInt(name, 10) * 3600 * 24);
result.push({
url: helpers.urlFormat('/home/currency', paramUrl),
name: tabs[name],
selected: condition.beginTime && paramUrl.beginTime === condition.beginTime ? true : false
});
}
return result;
};
const currencyList = (uid, condition)=>{
return co(function*() {
let result = {'list': [], 'pager': []};
let result = {list: [], pager: []};
condition.limit = condition.limit || 15;
let data = yield CurrencyData.yohoCoinList(uid, condition);
let data = yield currencyApi.yohoCoinList(uid, condition);
if (_.get(data, 'code') === 200 && data.data.coinlist && !_.isEmpty(data.data.coinlist)) {
if (data.code && data.code == 200 && data.data.coinlist && !_.isEmpty(data.data.coinlist)) {
// data.data.coinlist.forEach(function(val,key){
for (let key = 0; key < data.data.coinlist.length; key++) {
let val = data.data.coinlist[key];
result.list[key] = {
date: val['date'],
desc: val['message'],
date: val.date,
desc: val.message,
isIncome: true
};
// 2:订单取消退还,9:下单使用,10:退货退还
if ([2, 9, 10].indexOf(val.type) > -1 && val.key) {
result.list[key].detailUrl = helpers.urlFormat('/home/orders/detail', {orderCode: val['key']});
}
result.list[key].detailUrl = helpers.urlFormat('/home/orders/detail', {orderCode: val.key});
} else if (Number(val.type) === 14 && val.key) { // 晒单奖励
let product = yield currencyApi.getProduct(Number(val.key), 1);
// 晒单奖励
else if (val.type == 14 && val.key) {
let product = yield SearchData.searchAll({query: Number(val.key), viewNum: 1});
if (product.code && product.code == 200 && !_.isEmpty(product.data.product_list) && !_.isEmpty(product.data.product_list[0].goods_list)) {
productId = product.data.product_list[0].product_id;
goodsId = product.data.product_list[0].goods_list[0].goods_id;
result.list[key].detailUrl = helpers.getUrlBySkc(productId, goodsId, product.data.product_list[0].cn_alphabet);
if (_.get(product, 'code') === 200 &&
!_.isEmpty(product.data.product_list) &&
!_.isEmpty(product.data.product_list[0].goods_list)) {
let productId = _.get(product, 'data.product_list[0].product_id');
let goodsId = _.get(product, 'data.product_list[0].goods_list[0].goods_id');
let alphabet = _.get(product, 'data.product_list[0].cn_alphabet');
result.list[key].detailUrl = helpers.getUrlBySkc(productId, goodsId, alphabet);
}
}
if (Number(val['num']) < 0) {
if (Number(val.num) < 0) {
result.list[key].isIncome = false;
}
result.list[key].value = val['num'] > 0 ? '+' + val['num'] : val['num'];
result.list[key].value = val.num > 0 ? '+' + val.num : val.num;
}
// 分页
let total = data.data.total;
let pagerObj = pager(total, {
page: data['data']['page'],
limit: condition['limit']
});
// result['pager']={};
// result['pager']['hasCheckAll'] = false;
// result['pager']['count'] = data['data']['total'];
// result['pager']['curPage'] = data['data']['page'];
// result['pager']['totalPages'] = Math.ceil(data['data']['total'] / condition['limit']);
// result['pager']['pagerHtml'] = HelperSearch::pager(data['data']['total'], condition['limit']);
result.pager = Object.assign({
count: data.data.total,
curPage: data.data.page,
totalPages: Math.ceil(data.data.total / condition.limit)
}, pager(data.data.total, {
page: condition.page,
limit: condition.limit,
type: condition.queryType,
beginTime: condition.beginTime
}));
}
return result;
})();
};
const currencyTabs = (type)=>{
let result = ['全部明细', '全部收入', '全部支出'];
result = result.forEach(function(val, key) {
return {
active: key == type ? true : false,
url: helpers.urlFormat('/home/currency', {type: key})
};
});
return result;
};
const currencyOptions = (condition)=>{
let result = [], paramUrl = {};
let tabs = {'90': '最近3个月明细', '180': '最近半年明细', '360': '最近一年明细'};
for (let name in tabs) {
if (condition.queryType) {
paramUrl.type = condition.queryType;
const currencyData = (uid, prama)=>{
let condition = {
page: prama.page || 1,
queryType: prama.type || 0,
beginTime: prama.beginTime || convertUnitTime(new Date() / 1000 - 3600 * 24 * 90)
};
return co(function*() {
let result = {};
let yohoCoinInfo = yield currencyApi.yohoCoinTotal(uid);
if (_.get(yohoCoinInfo, 'code') === 200) {
let yohoCoinInfoData = yohoCoinInfo.data;
result.myCurrency = yohoCoinInfoData.yohocoin_num ? yohoCoinInfoData.yohocoin_num : 0;
if (_.get(yohoCoinInfoData, 'nearExpCoinNum') > 0) {
result.tip = {
count: yohoCoinInfoData.nearExpCoinNum,
date: new Date().getFullYear() + '年12月31日'
};
}
}
paramUrl.beginTime = convertUnitTime(new Date() / 1000 - 3600 * 24);
result.push({
url: helpers.urlFormat('/home/currency', paramUrl),
name: tabs[name],
selected: condition.beginTime && paramUrl.beginTime == condition.beginTime ? true : false
let currency = yield currencyList(uid, condition);
Object.assign(result, {
currency: currency.list,
pager: currency.pager,
coinHelperUrl: '//www.yohobuy.com/help/detail?id=105', // yoho币帮助
tabs: currencyTabs(condition.queryType),
options: currencyOptions(condition)
});
}
return result;
return result;
})();
};
module.exports = {
... ...
... ... @@ -2,12 +2,12 @@
const api = global.yoho.API;
const service = global.yoho.ServiceAPI;
const _ = require('lodash');
const URL_PRODUCT_FAVORITE = 'shops/service/v1/favorite/';
const URL_ARTICLE_FAVORITE = '/guang/api/v1/favorite/';
const URL_ARTICLE_FAVORITE_BRAND = '/guang/service/v2/favorite/toggleBrand';
// apiS.get(self::URL_ARTICLE_FAVORITE. 'getUserFavArticleList',{})
/**
* 根据uid和商品的id查询是否被用户收藏
* @param int $uid
... ... @@ -38,29 +38,78 @@ const favoriteArticleData = (uid, udid, page, limit)=> {
return service.get(URL_ARTICLE_FAVORITE + 'getUserFavArticleList', options);
};
const getFavoriteProductList = (uid, limit)=> {
limit = limit || 500;
const cancelArticle = (uid, id) => {
return service.get(URL_ARTICLE_FAVORITE + 'cancelFavorite', {
uid: uid,
article_id: id
});
};
const getFavoriteProductList = (uid, page, limit)=> {
let options = {
method: 'web.favorite.product',
uid: uid,
limit: limit
page: 0,
limit: limit || 10
};
return api.get('', options);
};
const redutionCount = (uid)=> {
let options = {
return api.get('', {
method: 'web.redution.count',
uid: uid
};
});
};
return api.get('', options);
const favoriteBrandData = (uid, page, limit) => {
return api.get('', {
method: 'app.favorite.brand',
uid: uid,
page: page || 1,
limit: limit || 10
});
};
const redutionAdd = (uid, mobile, pid) => {
return api.get('', {
method: 'web.redution.add',
uid: uid,
mobile: mobile,
productId: pid
});
};
const redutionCancel = (uid, pid) => {
return api.get('', {
method: 'web.redution.cancel',
uid: uid,
productIds: pid
});
};
const _cancel = (type, uid, ids) => {
return api.get('', {
method: 'web.favorite.cancel',
favIds: ids,
uid: uid,
type: type
});
};
module.exports = {
getUidProductFav,
getFavoriteProductList,
favoriteArticleData,
redutionCount
favoriteBrandData,
redutionCount,
redutionAdd,
redutionCancel,
cancel: {
product: _.partial(_cancel, 'product', _, _),
shop: _.partial(_cancel, 'shop', _, _),
brand: _.partial(_cancel, 'brand', _, _),
article: cancelArticle
}
};
... ...
... ... @@ -2,12 +2,10 @@
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const path = require('path');
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
const pager = require(pagerPath).handlePagerData;
const pager = require('./pager').handlePagerData;
const favoriteApi = require('./favorite-api');
const TABS = [
... ... @@ -26,10 +24,104 @@ const getFavoriteTabs = (type) => {
});
};
const favoriteProductList = (uid, page, limit, type, sort, subscribe, reduction, promotion) => {
const _getSortInfo = (categoryList, sort)=> {
if (_.isEmpty(categoryList)) {
return false;
}
let result = {};
result.all = categoryList.map((category) => {
return {
name: category.category_name,
url: helpers.urlFormat('/home/favorite', {sort_id: category.category_id}),
count: category.num,
focus: category.category_id === sort
};
});
let defaultCategory = {
name: '全部',
url: helpers.urlFormat('/home/favorite'),
count: _.sumBy(categoryList, category => category.num),
focus: sort === 0
};
result.all.unshift(defaultCategory);
result.default = result.all.slice(0, 7);
return result;
};
const _getPager = (page, total, totalPage)=> {
let result = {};
if (page && total && totalPage) {
result = {
count: total,
curPage: page,
totalPages: totalPage,
hasCheckAll: true
};
}
return result;
};
const getGoodsInfo = (data, page, limit)=> {
let result = data.slice((page - 1) * limit, page * limit).map((item) => {
return {
skn: item.product_id,
img: helpers.image(item.image, 100, 100),
name: item.product_name,
url: helpers.getUrlBySkc(item.product_id, item.goodsId, item.cnAlphabet),
price: item.sales_price,
priceDown: item.price_down,
buyNow: helpers.getUrlBySkc(item.product_id, item.goodsId, item.cnAlphabet),
soldOut: item.storage === 0 ? true : '',
hadNoticed: item.is_subscribe_reduction === 'Y' ? true : '',
activites: {
count: item.promotion_list ? item.promotion_list.length : 0,
list: _.get(item, 'promotion_list', []).map((val) => {
return {
type: val.promotion_type,
name: val.promotion_title
};
})
}
};
});
if (_.isEmpty(result)) {
return {
empty: '您没有收藏商品'
};
}
return result;
};
/**
* 降价提醒
*/
const _redutionCount = (uid)=> {
return co(function*() {
let data = yield favoriteApi.redutionCount(uid);
let result = {
count: 0,
phone: '',
url: '/home/favorite/reduction'
};
if (data.data.num) {
result.count = +data.data.num;
result.phone = data.data.mobile;
}
return result;
})();
};
const favoriteProductListAsync = (uid, page, limit, selectedSort, subscribe, reduction, promotion, query) => {
return co(function*() {
let data = {};
let product = {};
let result = {
sort: {},
reduction: {},
... ... @@ -38,68 +130,80 @@ const favoriteProductList = (uid, page, limit, type, sort, subscribe, reduction,
pager: {}
};
product = yield favoriteApi.getFavoriteProductList(uid);
if (product.data.category_list) {
result.sort = getSortInfo(product.data.category_list, sort);
}
result.reduction = yield redutionCount(uid);
let productList = [];
if (product.data.product_list) {
product.data.product_list.forEach(function(product) {
if (
(reduction === 'Y' && promotion === 'Y' && product.is_price_down === 'Y' && promotion === 'Y') ||
(sort && product.category_id === sort) ||
(subscribe && product.is_subscribe_reduction === 'Y') ||
(reduction === 'Y' && product.is_price_down === 'Y') ||
(promotion === 'Y' && product.is_join_promotion === 'Y')
) {
productList.push(product);
}
});
productList = product.data.product_list;
}
if (reduction === 'N' && promotion === 'N') {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y'}),
activityChecked: ''
};
} else if (reduction === 'N' && promotion === 'Y') {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y'}),
activityChecked: ''
};
} else if (reduction === 'Y' && promotion === 'N') {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y', is_promotion: 'Y'}),
activityChecked: ''
};
} else {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y', is_promotion: 'Y'}),
activityChecked: ''
};
}
let product = yield favoriteApi.getFavoriteProductList(uid, 1, 500);
result.sort = _getSortInfo(_.get(product, 'data.category_list'), selectedSort);
result.reduction = yield _redutionCount(uid);
let productList = (function() {
let products = _.get(product, 'data.product_list', []);
if (reduction === 'Y' && promotion === 'Y') {
// 参加活动的降价商品
return products.filter(pro => pro.is_price_down === 'Y' && pro.is_join_promotion === 'Y');
} else if (selectedSort) {
// 商品分类过滤
return products.filter(pro => pro.category_id === selectedSort);
} else if (subscribe === 'Y') {
// 订阅降价通知过滤
return products.filter(pro => pro.is_subscribe_reduction === 'Y');
} else if (reduction === 'Y') {
// 降价商品过滤
return products.filter(pro => pro.is_price_down === 'Y');
} else if (promotion === 'Y') {
// 参加活动商品过滤
return products.filter(pro => pro.is_join_promotion === 'Y');
} else {
return products;
}
}());
result.filter = (function() {
if (reduction === 'N' && promotion === 'N') {
return {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y'}),
activityChecked: ''
};
} else if (reduction === 'N' && promotion === 'Y') {
return {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite'),
activityChecked: ''
};
} else if (reduction === 'Y' && promotion === 'N') {
return {
reductionUrl: helpers.urlFormat('/home/favorite'),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
activityChecked: ''
};
} else {
return {
reductionUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y'}),
activityChecked: ''
};
}
}());
let total = productList;
let total = productList.length;
let pageTotal = Math.ceil(total / limit);
result.pager = getPager(page, total, pageTotal);
page = page > pageTotal ? pageTotal : page;
result.goods = getGoodsInfo(productList, page, limit);
result.pager = pager(total, query);
result.pager.hasCheckAll = true;
return result;
})();
};
const favoriteBrandList = (uid, page, limit, type)=> {
const favoriteBrandListAsync = (uid, page, limit, type)=> {
return co(function*() {
let result = {
brands: {
... ... @@ -113,19 +217,12 @@ const favoriteBrandList = (uid, page, limit, type)=> {
return result;
}
if (brand.data.page_total < page) {
page = brand.data.page_total;
brand = yield favoriteApi.favoriteBrandData(uid, page, limit);
}
if (!brand.data.brand_list) {
return result;
}
let brands = [];
brand.data.brand_list.forEach((item, i)=> {
brands.push({
result.brands = _.get(brand, 'data.brand_list', []).map((item) => {
return {
id: item.brand_id,
brandOrShopType: item.brandOrShopType || '',
shop_id: item.shop_id || '',
... ... @@ -134,130 +231,152 @@ const favoriteBrandList = (uid, page, limit, type)=> {
name: item.brand_name,
naCount: item.new_product_num,
colCount: item.brand_favorite_num
});
};
});
result.brands = brands;
let total = brand.data.total || 0;
let pageTotal = brand.data.page_total || 0;
page = brand.data.page || 0;
result.pager = getPager(page, total, pageTotal);
result.pager = pager(total, {page, limit, type});
return result;
})();
};
const favoriteArticleListAsync = (uid, udid, page, limit)=> {
const favoriteArticleListAsync = (uid, udid, page, limit, type)=> {
return co(function*() {
let result = {articles: [], pager: {}};
let result = {};
let articles = yield favoriteApi.favoriteArticleData(uid, udid, page, limit);
if (!articles.data && !articles.data.data) {
articles.data.data.forEach((item)=> {
result.articles.push({
id: item.id,
name: item.title,
img: helpers.image(item.src, 146, 96),
desc: item.intro,
url: helpers.urlFormat('/' + item.id + '.html', '', 'guang')
});
});
let total = articles.data.total || 0;
let pageTotal = articles.data.totalPage || 0;
let pageNum = articles.data.page || 0;
result.pager = getPager(pageNum, total, pageTotal);
} else {
result.articles = {empty: '你尚未收藏任何文章!'};
result.articles = _.get(articles, 'data.data', []).map((item) => {
return {
id: item.id,
name: item.title,
img: helpers.image(item.src, 146, 96),
desc: item.intro,
url: helpers.urlFormat('/' + item.id + '.html', '', 'guang')
};
});
let total = articles.data.total || 0;
result.pager = pager(total, {page, limit, type});
if (_.isEmpty(result.articles)) {
result.articles = {
empty: '你尚未收藏任何文章!'
};
}
return result;
})();
};
const getPager = (page, total, totalPage, size, type)=> {
const newProductAsync = (uid, page, limit, id) => {
return co(function * () {
let products = yield favoriteApi.favoriteBrandData(uid, page, limit);
return _.get(products, 'data.brand_list', []).reduce((total, cur) => {
if (id !== cur.brand_id) {
return total;
}
if (cur.new_product_num === 0) {
return total;
}
total = _.concat(total, _.take(_.get(cur, 'new_product', []), 20).map((pro) => {
return {
img: pro.default_images,
url: helpers.getUrlBySkc(pro.product_id, _.get(pro, 'goods[0].id', ''), _.get(pro, 'cnAlphabet')),
name: pro.product_name,
salePrice: pro.sales_price === pro.market_price ? '' : pro.sales_price,
marketPrice: pro.market_price
};
}));
return total;
}, []);
})();
};
const reductionAsync = (uid, page, limit) =>{
let result = {};
if (page && total && totalPage) {
result = {
count: total,
curPage: page,
totalPages: totalPage,
hasCheckAll: true
result.tabs = getFavoriteTabs('product');
return favoriteProductListAsync(uid, page, limit, 0, 'Y').then((products) => {
result.goods = products.goods;
result.reductionUrl = helpers.urlFormat('/home/fovorite');
return {
meFavoritePage: true,
meFavorite: result
};
}
return result;
});
};
const getGoodsInfo = (data, page, limit)=> {
let result = [];
let begin = (page - 1) * limit;
if (!data) {
data = data.slice(begin, limit);
data.forEach((item, i)=> {
let obj = {
skn: item.product_id,
img: helpers.img(item.image, 100, 100),
name: item.product_name,
url: helpers.getUrlBySkc(item.product_id, item.goodsId, item.cnAlphabet),
price: item.sales_price,
priceDown: item.price_down,
buyNow: helpers.getUrlBySkc(item.product_id, item.goodsId, item.cnAlphabet),
soldOut: item.storage === 0 ? true : '',
hadNoticed: item.is_subscribe_reduction === 'Y' ? true : '',
count: item.promotion_list ? item.promotion_list.length : 0
};
const enableNoticeAsync = (uid, mobile, id) => {
return co(function *() {
let result = {
code: 400,
message: '订阅失败'
};
if (item.promotion_list) {
item.promotion_list.forEach(function(item1) {
obj.activites.list.push({
type: item1.promotion_type,
name: item1.promotion_title
});
});
}
result.push(obj);
});
} else {
result = {empty: '您没有收藏商品'};
}
return result;
};
if (!uid || !mobile || !id) {
return result;
}
const redutionCount = (uid)=> {
return co(function*() {
let result = {count: 0, url: '/home/favorite/reduction', phone: ''};
let data = yield favoriteApi.redutionCount(uid);
if (data.data.num) {
result.count = +data.data.num;
result.phone = data.data.mobile;
let data = yield favoriteApi.redutionAdd(uid, mobile, id);
if (data.code === 200) {
result.code = 200;
return data;
}
if (data.code === 500) {
result.code = 500;
switch (data.message) {
case 'count must be lt 5':
result.message = '您的订阅数已经到达上限';
break;
case 'mobile must bu not null':
result.message = '请填写手机号';
break;
default:
result.message = '订阅失败';
break;
}
}
return result;
})();
};
const getSortInfo = (categoryList, sort)=> {
let result = {default: {}, all: []};
let defaultCategory = {name: '全部', url: helpers.urlFormat('/home/favorite'), count: 0, focus: ''};
const disableNoticeAsync = (uid, id) => {
return co(function * () {
if (!uid || !id) {
return {
code: 400,
message: '取消失败'
};
}
categoryList.forEach(function(category) {
result.all.push({
name: category.category_name,
url: helpers.urlFormat('/home/favorite', {sort_id: category.category_id}),
count: category.num,
focus: category.category_id === sort ? true : ''
});
defaultCategory.count += category.num;
defaultCategory.focus = sort === 0 ? true : '';
});
result.all.unshift(defaultCategory);
result.default = result.all.slice(result.all, 0, 7);
return result;
return yield favoriteApi.redutionCancel(uid, id);
})();
};
const cancelAsync = (uid, id, type) => {
return favoriteApi.cancel[type](uid, id);
};
module.exports = {
getFavoriteTabs,
favoriteProductList,
favoriteArticleListAsync
favoriteBrandListAsync,
favoriteProductListAsync,
favoriteArticleListAsync,
newProductAsync,
reductionAsync,
enableNoticeAsync,
disableNoticeAsync,
cancelAsync
};
... ...
'use strict';
const _ = require('lodash');
const userApi = require('./user-api');
const headerModel = require('../../../doraemon/models/header');
const msgModel = require('./message');
const helpers = global.yoho.helpers;
const defaultAvatar = '//img10.static.yhbimg.com/headimg/' +
'2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100';
const _homeNav = (switcher) => {
return [
{
title: '交易管理',
subNav: [
{name: '我的订单', href: '/home/orders', catchs: ['/home/orders', '/home/index', '/home/orders/detail']},
{name: '我的收藏', href: '/home/favorite', catchs: ['/home/favorite/reduction']},
{name: '我的有货币', href: '/home/currency'},
{name: '我的红包', href: '/home/redenvelopes'},
{name: '我的优惠券', href: '/home/coupons'},
{name: '我的VIP', href: '/home/vip'}
]
},
{
title: '服务中心',
subNav: [
{name: '我的退/换货', href: '/home/returns'},
{name: '我的咨询', href: '/home/consult'},
{name: '我的评论', href: '/home/comment'},
// {name: '我的投诉', href: '/home/complaints'},
{name: '我的信息', href: '/home/message', count: 0},
{
name: '在线客服',
href: switcher ?
'/service/client' : 'http://chat8.live800.com/live800/chatClient/chatbox.jsp?companyID=620092&amp;configID=149091&amp;jid=8732423409',
isBlank: true
}
]
},
{
title: '个人信息管理',
subNav: [
{name: '编辑个人资料', href: '/home/user'},
{name: '账号安全', href: '/home/account', catchs: [
'/home/account/userpwd',
'/home/account/email',
'/home/account/mobile',
'/home/account/checkverifycode',
'/home/account/checkpassword',
'/home/account/verifypassword',
'/home/account/modifypwd',
'/home/account/sendemail',
'/home/account/checkemail',
'/home/account/modifyemail',
'/home/account/sendemailsuccess',
'/home/account/mailresult',
'/home/account/checkmobile',
'/home/account/checkmobilemsg',
'/home/account/sendmobilemsg',
'/home/account/modifymobile'
]},
{name: '地址管理', href: '/home/address'},
{name: '兑换礼品卡', href: '/home/gift'}
]
}
];
};
const _getActiveNav = (url, switcher, count) =>{
let mHomeNav = _.cloneDeep(_homeNav(switcher));
let activeNav = null;
mHomeNav = mHomeNav.map((item) => {
item.subNav = item.subNav.map((nav) => {
let curMatchPath = url;
if (!nav.matchQuery && curMatchPath.indexOf('?') >= 0) { // 严格的路径匹配,包含后面的参数
curMatchPath = curMatchPath.substr(0, curMatchPath.indexOf('?'));
}
if (curMatchPath === nav.href) {
nav.active = true;
}
if (nav.name === '我的信息') {
nav.count = +count;
}
if (nav.catchs) {
let index = nav.catchs.indexOf(curMatchPath);
if (index > -1) {
nav.active = true;
nav.curHref = nav.catchs[index];
}
}
if (nav.active) {
activeNav = nav;
}
nav.href = nav.href.indexOf('http://') > -1 ? nav.href : helpers.urlFormat(nav.href);
return nav;
});
return item;
});
return {
homeNav: mHomeNav,
activeNav: activeNav
};
};
const _getAvatar = (uid) => {
return userApi.getUserInfo(uid).then((result) => {
return _.get(result, 'data.head_ico', '') || defaultAvatar;
});
};
const _msgCount = (uid) => {
return msgModel.unreadTotal(uid).then(result => _.get(result, 'data.total', 0));
};
const _getTabsData = (uid, channel) => {
return Promise.props({
msg: _msgCount(uid),
header: headerModel.requestHeaderData(channel),
avatar: _getAvatar(uid)
});
};
const getHomeNav = (uid, channel, url, clientSwitcher) => {
return _getTabsData(uid, channel).then((result) => {
let navs = _getActiveNav(url, clientSwitcher, result.msg);
let activeNav = navs.activeNav;
let bread = [{href: helpers.urlFormat('/'), name: 'YOHO!BUY 有货首页'}];
if (activeNav) {
bread.push({
name: '个人中心',
href: helpers.urlFormat('/home')
});
bread.push({
name: activeNav.name
});
// 订单详情
if (activeNav.curHref === '/home/orders/detail') {
Object.assign(_.last(bread), {
href: helpers.urlFormat('/home/orders')
});
bread.push({
name: '订单详情'
});
}
} else {
bread.push({
name: '个人中心'
});
}
return Object.assign({
path: bread,
homeNav: navs.homeNav,
userThumb: result.avatar
}, result.header);
});
};
module.exports = {
getHomeNav
};
... ...
/**
* 个人中心---兑换礼品卡
* @author gaohongwei <hongwei.gao@yoho.cn>
* @date: 2016/9/7
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const userApi = require('./user-api');
const currencyApi = require('./currency-api');
/**
* 礼品卡页面
*/
exports.index = (params, uid) => {
return co(function*() {
let respData = {},
type = params.type || '',
yohoCoinResult;
if (type !== '') {
yohoCoinResult = yield currencyApi.yohoCoinTotal(uid);
let yohoCoinInfo = yohoCoinResult.data;
if (yohoCoinInfo) {
respData.gift = {
resultInfo: {
success: (Number(type) === 1) ? true : false,
yohoCoin: yohoCoinInfo.yohocoin_num ? yohoCoinInfo.yohocoin_num : 0
}
};
}
} else {
respData.gift = {
resultInfo: false
};
}
return respData;
})();
};
/**
* 个人中心-兑换礼品卡提交返回信息
*/
exports.exchange = (req, params, uid) => {
return co(function*() {
let data = {};
data.giftCardCode1 = _.trim(params.giftCardCode1 || '');
data.giftCardCode2 = _.trim(params.giftCardCode2 || '');
data.giftCardCode3 = _.trim(params.giftCardCode3 || '');
let respData = yield userApi.exchangeGift(data, uid);
return respData;
})();
};
... ...
'use strict';
const api = global.yoho.API;
const pendingOrderCount = (uid) => {
return api.get('', {
method: 'web.SpaceOrders.getPendingOrderCount',
uid: uid
});
};
const unreadMessageCount = (uid, udid)=>{
return api.get('', {
method: 'app.home.getInfoNum',
uid: uid,
udid: udid
});
};
const needCommentCount = (uid) =>{
return api.get('', {
method: 'show.notCommentRecordCount',
uid: uid
});
};
const guessBrand = () => {
return api.get('', {
method: 'web.search.favorBrand'
});
};
const newArrival = () => {
return api.get('', {
method: 'web.search.search',
sales: 'Y',
outlets: 2,
stocknumber: 1,
new: 'Y',
order: 's_t_desc',
viewNum: 0
});
};
/**
* 优选新品
*
* @param int $channel 频道,1代表男生,2代表女生,3代表潮童,4代表创意生活
* @param $uid 用户ID
* @param $udid 设备ID
* @param $rec_pos 位置码
* @param $limit 数量限制
* @return array 接口返回的数据
*/
const recommend = (channelNum, uid, udid, pos, limit) => {
return api.get('', {
method: 'app.home.newPreference',
yh_channel: channelNum,
uid: uid,
udid: udid,
rec_pos: pos,
limit: limit
});
};
/**
* 根据节点和运行模式选择静态内容
* @param $node 20141219-100447
* @param string $mode
* @return mixed
*/
const getByNodeContent = (node, mode) => {
return api.get('', {
method: 'web.html.content',
mode: mode,
node: node
});
};
module.exports = {
pendingOrderCount,
unreadMessageCount,
needCommentCount,
guessBrand,
newArrival,
recommend,
getByNodeContent
};
... ...
/**
* @author: weiqingting<qingting.wei@yoho.cn>
*/
'use strict';
const api = global.yoho.API;
const getPendingOrderCount = uid=>{
let options = {
method: 'web.SpaceOrders.getPendingOrderCount',
uid: uid
};
return api.get('', options);
};
const infoNum = (uid, udid)=>{
let options = {
method: 'app.home.getInfoNum',
uid: uid,
udid: udid
};
return api.get('', options);
};
const notCommentRecordCount = uid=>{
let options = {
method: 'show.notCommentRecordCount',
uid: uid
};
return api.get('', options);
};
module.exports = {
getPendingOrderCount,
infoNum,
notCommentRecordCount
};
/**
* @author: weiqingting<qingting.wei@yoho.cn>
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const OrderData = require('./order-data');
const OrderModel = require('./order-model');
const helpers = global.yoho.helpers;
const api = global.yoho.API;
const searchApi = global.yoho.SearchAPI;
const BrandData = require('./BrandData');
const IndexData = require('./index-data');
const SearchData = require('./SearchData');
const HelperHome = require('./HelperHome');
const _ = require('lodash');
/**
* 个人中心——消息提示
* @param type uid
* @param type udid
* @return array
*/
const getInfoNumData = (uid, udid)=>{
let result = [
{href: helpers.urlFormat('/home/orders'), name: '待处理订单', 'count': 0},
{href: helpers.urlFormat('/home/message'), name: '未读消息', 'count': 0},
{href: helpers.urlFormat('/home/comment'), name: '待评论商品', 'count': 0}
];
return co(function * () {
let getPendingOrderCount = yield IndexData.getPendingOrderCount(uid);// 待处理订单
let infoNumData = yield IndexData.infoNum(uid, udid); // 未读消息
let notCommentRecordCount = yield IndexData.notCommentRecordCount(uid);// 待评论商品
result[0]['count'] = getPendingOrderCount.data.count ? getPendingOrderCount.data.count : 0;
result[1]['count'] = infoNumData.data.inbox_total ? infoNumData.data.inbox_total : 0;
result[2]['count'] = notCommentRecordCount.data ? notCommentRecordCount.data : 0;
return result;
})();
};
/**
* 个人中心——最新订单
* @param type uid
* @return array
*/
const latestOrders = (uid)=>{
return co(function *() {
let orders = yield OrderModel.getOrders(uid, 1, 2, 1);
return {
more: helpers.urlFormat('/home/orders'),
orders: orders
};
})();
};
const homeData = ()=>{
return co(function * () {
let result = {};
let url = {};
url.fav_brand = SearchData.getBrandListUrl();
url.new = SearchData.getProductUrl({new: 'Y', viewNum: 10});
let data = yield Promise.all([searchApi.get(url.fav_brand, {}, {cache: true}), searchApi.get(url.new, {}, {cache: true})]);
// 格式化数据
result['brand'] = data[0].data && data[0].data.length > 0 ? HelperHome.formatFavBrand(data[0].data, 6) : [];
result['new'] = data[1].data['product_list'] && data[1].data['product_list'].length > 0 ? HelperHome.formatNew(data[1].data['product_list']) : {};
return result;
})();
};
/**
* 底部banner
* @param string code
* @return mixed
*/
const getFooterBanner = (code)=>{
code = code || '20110609-152143';
return co(function *() {
let result = '';
let banner = yield BrandData.getByNodeContent(code);
if (banner.code && banner.data) {
result = banner.data.replace('http://', '//');
}
return result;
})();
};
module.exports = {
getInfoNumData,
getFooterBanner,
latestOrders,
homeData
};
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const Fn = require('lodash/fp');
const helpers = global.yoho.helpers;
const orderService = require('./orders-service');
const indexApi = require('./index-api');
const CHANNEL_NUM = {
boys: 1,
girls: 2,
kids: 3,
lifestyle: 4
};
const IMG_DOMAIN = {
'01': [
'img10.static.yhbimg.com',
'img11.static.yhbimg.com'
],
'02': [
'img12.static.yhbimg.com',
'img13.static.yhbimg.com'
]
};
/**
* 处理品牌的图片
*/
const _handleBrandLogo = (url) => {
if (_.startsWith(url, 'http://') || !url) {
return url;
}
let node = url.substr(15, 2);
return `//${IMG_DOMAIN[node][(url.length % 2)]}/brandLogo${url}`;
};
const _channelNum = channel => CHANNEL_NUM[channel] || CHANNEL_NUM.boys;
/**
* 处理品牌
*/
const _handleBrand = (brands, needNum) => {
const handle = Fn.pipe(Fn.filter({is_hot: 'Y'}), Fn.take(needNum), Fn.map((brand) => ({
href: helpers.urlFormat('', null, brand.brand_domain),
logo: _handleBrandLogo(brand.brand_ico, 'brandLogo'),
name: brand.brand_name
})));
return handle(brands);
};
/**
* 处理商品
*/
const _handleProduct = (products) => {
return products.map((product) => {
let img = helpers.image(_.get(product, 'default_images', ''), 100, 100);
if (img.indexOf('imageView') !== -1) {
img = img.split('imageView', 1) +
'imageMogr2/thumbnail/100x100/extent/100x100/background/d2hpdGU=/position/center/quality/90';
}
return {
href: helpers.getUrlBySkc(product.product_id,
_.get(product, 'goods_list[0].product_skc', ''),
product.cn_alphabet
),
thumb: img,
name: product.product_name,
price: product.sales_price,
productId: product.product_id
};
});
};
/**
* 消息数量提示
*/
const _msgNumber = co(function * (uid, udid) {
let result = [
{href: helpers.urlFormat('/home/orders'), name: '待处理订单', count: 0},
{href: helpers.urlFormat('/home/message'), name: '未读消息', count: 0},
{href: helpers.urlFormat('/home/comment'), name: '待评论商品', count: 0}
];
let reqData = yield Promise.props({
pending: indexApi.pendingOrderCount(uid), // 待处理订单
unread: indexApi.unreadMessageCount(uid, udid), // 未读消息
needComment: indexApi.needCommentCount(uid) // 待评论商品
});
result[0].count = _.get(reqData, 'pending.data.count', 0);
result[1].count = _.get(reqData, 'unread.data.inbox_total', 0);
result[2].count = _.get(reqData, 'needComment.data', 0);
return result;
});
/**
* 最新订单
*/
const _recentOrder = co(function * (uid) {
let latestOrder = yield orderService.getOrders(uid, 1, 2, orderService.ORDER_TYPE.all);
return {
more: helpers.urlFormat('/home/orders'),
orders: latestOrder
};
});
/**
* 你喜欢的品牌
*/
const _guessYouLikeBrand = co(function * () {
let brand = yield indexApi.guessBrand();
const NEED_BRAND_NUM = 6;
return _handleBrand(_.get(brand, 'data', []), NEED_BRAND_NUM);
});
/**
* 新品
*/
const _newProduct = co(function * () {
let newProduct = yield indexApi.newArrival();
return _handleProduct(_.get(newProduct, 'data.product_list', []));
});
/**
* 为你优选
*/
const _recommend = co(function * (channelNum, uid, udid) {
let resData = yield indexApi.recommend(channelNum, uid, udid, '100004', 30);
return _handleProduct(_.get(resData, 'data.product_list', []));
});
/**
* 底部banner
*/
const _footerBanner = co(function * () {
const CODE = '20110609-152143';
let banner = yield indexApi.getByNodeContent(CODE);
return _.get(banner, 'data', '').replace('http://', '//');
});
/**
* 取消订单
*/
const _cancelReason = orderService.closeReason;
const index = co(function * (uid, udid, channel, isStudent) {
let reqData = yield Promise.props({
msgNumber: _msgNumber(uid, udid),
recentOrder: _recentOrder(uid),
guessBrand: _guessYouLikeBrand(),
newProduct: _newProduct(),
recommendProduct: _recommend(_channelNum(channel), uid, udid),
footerBanner: _footerBanner(),
reason: _cancelReason()
});
return {
content: {
certifiedName: +isStudent ? '学生身份已验证' : '身份验证',
certifiedUrl: helpers.urlFormat('/product/students/'),
messages: reqData.msgNumber,
latestOrders: Object.assign(reqData.recentOrder, {cancelReason: reqData.reason}),
favBrand: {
more: '/brands',
brands: reqData.guessBrand
},
newArrival: reqData.newProduct
},
recommend: reqData.recommendProduct,
banner: reqData.footerBanner
};
});
module.exports = {
index
};
... ...
/**
* @author: weiqingting<qingting.wei@yoho.cn>
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const OrderData = require('./order-data');
const ChannelConfig = require('./ChannelConfig');
const helpers = global.yoho.helpers;
const api = global.yoho.API;
const _ = require('lodash');
const Image = require('../../../utils/images');
/**
* 获取我的订单列表数据-分页
* @param type uid
* @param type page
* @param type limit
* @param type type 获取订单类型 type=1全部,type=2待付款,type=3待发货,type=4待收货,type=5待评论(已成功) 7取消
*/
const getOrders = (uid, page, limit, type, isPage)=>{
return co(function *() {
isPage = isPage || false;
let getOrderDescStr = {
1: '您还没有任何订单',
5: '您目前还没有成功的订单',
7: '您还没有任何取消的订单'
};
let descStr = getOrderDescStr[type] || '';
let orders = {empty: descStr};
let orderInfo = yield OrderData.getUserOrders(uid, page, limit, type);
if (orderInfo.data && orderInfo.data.order_list) {
orders = {};
orderInfo.data.order_list.forEach(function(orderV, orderK) {
orders[orderK] = {};
orders[orderK]['orderNum'] = orderV['order_code']; // 订单标识
orders[orderK]['orderTime'] = new Date(orderV['create_time']);
let statusInfo = getOrderStatus(orderV['is_cancel'], orderV['status'], orderV['payment_type'], orderV['payment_status']);
// 订单状态
if (statusInfo['cancel']) {
orders[orderK]['cancel'] = statusInfo['cancel'];
}
else {
if (statusInfo['keyName']) {
orders[orderK][statusInfo['keyName']] = true;
// 已发货,物流信息
if (statusInfo['keyName'] == 'shipped') {
let expressInfo = getExpressInfo(orderV['order_code'], uid, orderV['payment_type'], orderV['create_time']);
orders[orderK]['logistics'] = expressInfo['logistics'];
}
}
}
// 订单商品相关信息
let opRefundStatus = true; // 订单不可操作退换货
if (orderV['order_goods'] && orderV['order_goods']) {
let goods = {}, refundFlag = {};
orderV['order_goods'].forEach(function(goval, gokey) {
goods[gokey] = {};
goods[gokey]['href'] = helpers.getUrlBySkc(goval['product_id'], goval['goods_id'], goval['cn_alphabet']);
goods[gokey]['thumb'] = goval['goods_image'] && goval['goods_image'] ? Image.getImageUrl(goval['goods_image'], 100, 100) : '';
goods[gokey]['name'] = goval['product_name'];
goods[gokey]['color'] = goval['color_name'];
goods[gokey]['size'] = goval['size_name'];
goods[gokey]['price'] = goval['goods_price'];
let buyNum = Number(goval['buy_number']);
let refundNum = Number(goval['refund_num']);
goods[gokey]['count'] = buyNum;
let refundStatus = (refundNum > 0) ? true : false; // 只要发生一件退换,退换过的标记
goods[gokey]['refundStatus'] = refundStatus;
refundFlag = ((buyNum == refundNum) && refundNum > 0) ? 'finished' : 'unfinished'; // 某一件商品全部退换结束
goods[gokey]['arrivalDate'] = goval['expect_arrival_time'];
let goodsTagName = getGoodsTag(orderV['attribute'], goval['goods_type']);
if (goodsTagName) {
goods[gokey][goodsTagName] = true;
}
orders[orderK]['goods'] = goods;
});
if (refundFlag.indexOf('unfinished')) {
opRefundStatus = false;
}
orders[orderK]['pay'] = orderV['amount']; // 付款数
orders[orderK]['fregit'] = orderV['shipping_cost']; // 邮费
}
// 操作
orders[orderK]['operation'] = getOperateInfo(orderV['attribute'], orderV['is_cancel'], orderV['status'], orderV['payment_status'], orderV['update_time'], orderV['order_type'], orderV['refund_status'], orderV['payment_type'], orderV['order_code'], opRefundStatus);
});
if (isPage) {
orders['pager']['total'] = orderInfo['data']['total'];
orders['pager']['pageTotal'] = orderInfo['data']['page_total'];
orders['pager']['page'] = orderInfo['data']['page'];
}
return orders;
}
})();
};
const getOrderStatus = (isCancel, status, payType, payStatus)=>{
// 初始化:未取消,待付款
let ret = {cancel: false, keyName: 'noPay', statusStr: '待付款'};
if (isCancel == 'Y') {
ret = {cancel: true, statusStr: '已取消'};
} else {
switch (status) {
case 0:
// '订单已成功,等待付款'
if (payType != 2 && payStatus == 'N') {
ret['keyName'] = 'noPay';
ret['statusStr'] = '待付款';
}
// '订单已付款,等待备货中'
else if (payType != 2 && payStatus == 'Y') {
ret['keyName'] = 'paid';
ret['statusStr'] = '备货中';
}
// '订单已成功,等待备货中'-货到付款
else if (payType == 2 && payStatus == 'N') {
ret['keyName'] = 'complete';
ret['statusStr'] = '备货中';
}
break;
case 1:
case 2:
case 3:
// '订单已付款,等待备货中'
ret['keyName'] = 'paid';
ret['statusStr'] = '备货中';
break;
case 4:
case 5:
// '订单已发货'
ret['keyName'] = 'shipped';
ret['statusStr'] = '待收货';
break;
case 6:
// '交易完成';
ret['keyName'] = 'reback';
ret['statusStr'] = '交易完成';
break;
}
}
return ret;
};
const getExpressInfo = (orderCode, uid, paymetType, createTime, isDetail)=>{
return co(function * () {
isDetail = isDetail || false;
let result = {};
result['logisticsUrl'] = '';
result['logisticsImg'] = '';
result['logisticsCompany'] = '';
result['courierNumbe'] = '';
if (paymetType == 1) {
if (isDetail) {
result['logistics'] = [new Date(createTime), ' ', '您的订单已提交,等待付款'];
}
else {
result['logistics'] = new Date(createTime) + ' ' + '您的订单已提交,等待付款';
}
}
if (paymetType == 2) {
if (isDetail) {
result['logistics'] = [new Date(createTime), ' ', '您的订单已提交,等待审核'];
}
else {
result['logistics'] = new Date(createTime) + ' ' + '您的订单已提交,等待审核';
}
}
// 有物流
if (orderCode && _.isNumber(uid)) {
let logistics = yield OrderData.getLogisticsData(orderCode, uid);
if (logistics['data']) {
result['logisticsUrl'] = logistics['data']['url'] ? helper.getUrlSafe(logistics['data']['url']) : '';
result['logisticsImg'] = logistics['data']['logo'] ? logistics['data']['logo'] : '';
result['logisticsCompany'] = logistics['data']['caption'] ? logistics['data']['caption'] : '';
result['courierNumbe'] = logistics['data']['express_number'] ? logistics['data']['express_number'] : '';
let expressDetail = logistics['data']['express_detail'] ? logistics['data']['express_detail'] : {};
if (expressDetail) {
let logisticsTmp = result['logistics'][0]; // 暂存
result['logistics'] = {};
expressDetail.forEach(function(value) {
let pos = value['accept_address'].indexOf(' ') / 3;
let city = value['accept_address'].substr(0, pos);
let exInfo = value['accept_address'].substr(pos);
if (isDetail) {
result['logistics'] = [value['acceptTime'], city, exInfo];
}
else {
result['logistics'] = value['acceptTime'] + city + exInfo;
}
});
// 把最初的处理放最后
result['logistics'] = logisticsTmp;
}
}
}
return result;
})();
};
const getGoodsTag = (attribute, goodsType)=>{
let goodsTagName = '';
switch (goodsType) {
// 赠品
case 'gift':
goodsTagName = 'freebie';
break;
// 加价购
case 'price_gift':
goodsTagName = 'advanceBuy';
break;
// 预售
case 'advance':
goodsTagName = 'preSaleGood';
break;
// outlet
case 'outlet':
goodsTagName = '';
break;
// 免单
case 'free':
goodsTagName = '';
break;
// 电子
case 'ticket':
goodsTagName = '';
break;
default:
break;
}
// 虚拟
if (attribute == 3) {
goodsTagName = 'virtualGood';
}
return goodsTagName;
};
const getOperateInfo = (attribute, isCancel, status, payStatus, updateTime, orderType, refundStatus, paymentType, orderCode, opRefundStatus)=>{
// 查看订单
let orderDetailUrl = helpers.urlFormat('/home/orders/detail', {orderCode: orderCode});
// 查看二维码
let ticketUrl = helpers.urlFormat('/home/orders/tickets', {orderCode: orderCode});
// 立即付款
let payUrl = helpers.urlFormat('/shopping/pay', {orderCode: orderCode});
// 取消订单
let cancelOrderUrl = 'javascript:void(0)';
// 确认订单
let confirmOrderUrl = 'javascript:void(0)';
// 申请换货
let exchangeUrl = helpers.urlFormat('/home/returns/exchangeRequest', {orderCode: orderCode});
// 申请退货
let refundUrl = helpers.urlFormat('/home/returns/refundrequest', {orderCode: orderCode});
let operation = {};
// 立即付款
if (payStatus == 'N' && paymentType != 2 && isCancel == 'N') {
operation = {payNow: true, href: payUrl};
}
operation = {href: orderDetailUrl, name: '查看订单'};
// 查看订单,虚拟订单查看二维码
if (attribute == 3) {
if (payStatus == 'Y') {
operation = {href: ticketUrl, name: '查看二维码'};
}
}
// 取消订单
if (status < 3 && isCancel == 'N' && orderType != 5 && payStatus == 'N') {
operation = {href: cancelOrderUrl, name: '取消订单', cancelOrder: true};
}
// 确认收货
if (status >= 4 && status < 6 && refundStatus == 0 && attribute != 3 && isCancel == 'N') {
operation = {href: confirmOrderUrl, name: '确认收货', confirmReceived: true};
}
// 换货
let time = (Date.now() - updateTime);
let orderExchangeLimitTime = ChannelConfig.exchangeDay;
if (status >= 6 && time < 86400 * orderExchangeLimitTime && attribute != 3 && isCancel == 'N') {
operation = {href: exchangeUrl, name: '申请换货', optDis: opRefundStatus};
}
// 退货
let orderRefundLimitTime = ChannelConfig.refundDay;
if (status >= 6 && time < 86400 * orderRefundLimitTime && attribute != 3 && isCancel == 'N') {
operation = {href: refundUrl, name: '申请退货', optDis: opRefundStatus};
}
return operation;
};
module.exports = {
getOrders
};
... ... @@ -14,17 +14,13 @@ const api = global.yoho.API;
* @return type
*/
exports.getUserOrders = (uid, page, limit, type)=>{
page = page || 1;
limit = limit || 1;
type = type || 1;
let options = {
return api.get('', {
method: 'app.SpaceOrders.get',
uid: uid,
type: type,
page: page,
limit: limit
};
return api.get('', options);
});
};
/**
... ... @@ -34,12 +30,11 @@ exports.getUserOrders = (uid, page, limit, type)=>{
* @return type
*/
exports.getOrderDetail = (uid, orderCode)=>{
let options = {
return api.get('', {
method: 'app.SpaceOrders.detail',
uid: uid,
order_code: orderCode
};
return api.get('', options);
});
};
... ... @@ -50,14 +45,12 @@ exports.getOrderDetail = (uid, orderCode)=>{
* @return type
*/
exports.cancelUserOrder = (uid, orderCode, reason, reasonId)=>{
reason = reason || false;
reasonId = reasonId || false;
let options = {
method: 'app.SpaceOrders.close',
uid: uid,
order_code: orderCode
};
if (reasonId) {
Object.assign(options, {
reasonId: reasonId,
... ... @@ -74,12 +67,11 @@ exports.cancelUserOrder = (uid, orderCode, reason, reasonId)=>{
* @return type
*/
exports.confirmUserOrder = (uid, orderCode)=>{
let options = {
return api.get('', {
method: 'app.SpaceOrders.confirm',
uid: uid,
order_code: orderCode
};
return api.get('', options);
});
};
/**
... ... @@ -103,12 +95,11 @@ exports.getTicketCode = (orderCode)=>{
* @return array
*/
exports.getLogisticsData = (orderCode, uid)=>{
let options = {
return api.get('', {
method: 'app.express.li',
order_code: orderCode,
uid: uid
};
return api.get('', options);
});
};
/**
... ... @@ -118,15 +109,12 @@ exports.getLogisticsData = (orderCode, uid)=>{
* @param type limit
*/
exports.getHistoryOrders = (uid, page, limit)=>{
page = page || 1;
limit = limit || 10;
let options = {
return api.get('', {
method: 'app.SpaceOrders.history',
uid: uid,
page: page,
limit: limit
};
return api.get('', options);
});
};
/**
... ... @@ -152,10 +140,9 @@ exports.updateOrderPayment = (orderCode, payment, uid)=>{
* @return type
*/
exports.closeReasons = ()=>{
let options = {
return api.get('', {
method: 'app.SpaceOrders.closeReasons'
};
return api.get('', options);
});
};
/**
... ... @@ -164,18 +151,24 @@ exports.closeReasons = ()=>{
* @param type address_id
* @return type
*/
exports.updateDeliveryAddress = (order_code, user_name, area_code, address, mobile, phone)=>{
exports.updateDeliveryAddress = (orderId, userName, areaCode, address, mobile, phone, uid)=>{
let options = {
method: 'app.SpaceOrders.updateDeliveryAddress',
order_code: order_code,
user_name: user_name,
area_code: area_code,
order_code: orderId,
user_name: userName,
area_code: areaCode,
address: address,
mobile: mobile
uid: uid
};
if (mobile) {
Object.assign(options, {mobile: mobile});
}
if (phone) {
Object.assign(options, {phone: phone});
}
return api.get('', options);
};
... ... @@ -188,11 +181,66 @@ exports.updateDeliveryAddress = (order_code, user_name, area_code, address, mobi
* @return array
*/
exports.viewOrderData = (orderCode, uid, sessionKey)=>{
let options = {
return api.get('', {
method: 'app.SpaceOrders.info',
order_code: order_code,
order_code: orderCode,
uid: uid,
session_key: sessionKey
});
};
/**
* 重新加入购物车
*/
exports.reBuy = (uid, orderId) => {
return api.get('', {
method: 'app.Shopping.readd',
uid: uid,
order_code: orderId
});
};
/**
* 删除订单数据
*/
exports.del = (uid, gender, channel, orderId) => {
return api.get('', {
method: 'app.SpaceOrders.delOrderByCode',
uid: uid,
gender: gender,
yh_channel: channel,
order_code: orderId
});
};
/**
* 申请退款
*/
exports.refund = (uid, orderId, reasonId, reason) => {
let params = {
uid: uid,
order_code: orderId
};
return api.get('', options);
if (reasonId) {
params.reason_id = reasonId;
}
if (reason) {
params.reason = reason;
}
return api.get('', Object.assign({
method: 'app.SpaceOrders.refundApply'
}, params));
};
/**
* 申请退款原因
*/
exports.refundReason = () => {
return api.get('', {
method: 'app.SpaceOrders.refundApplyReasons'
});
};
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const moment = require('moment');
const helpers = global.yoho.helpers;
const pager = require('./pager').handlePagerData;
const orderApi = require('./orders-api');
const ChannelConfig = require('./channel-config');
const ORDER_TYPE = {
all: 1, // 全部
waitingForPay: 2, // 待付款
waitingForSend: 3, // 待发货
waitingForReceive: 4, // 待收货
completed: 5, // 已完成
canceled: 7 // 已取取消
};
const ORDER_EMPTY_DESC = {
1: '您还没有任何订单',
5: '您目前还没有成功的订单',
7: '您还没有任何取消的订单'
};
const TABS = [
{type: 1, name: '现有订单'},
{type: 5, name: '成功订单'},
{type: 7, name: '已取消订单'}
];
const ORDER_OP_ALL = [
{
type: 'closeOrder',
name: '取消订单',
cancelOrder: true,
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'buyNow',
name: '立即付款',
payNow: true,
hrefFun: it => helpers.urlFormat('/shopping/pay', {ordercode: it})
},
{
type: 'getExpress',
name: '查看物流',
express: true,
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'confirm',
name: '确认订单',
confirmReceived: true,
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'delOrder',
name: '删除订单',
delOrder: true,
hrefFun: () => ''
},
{
type: 'lookQrcode',
name: '查看二维码',
qrcode: true,
hrefFun: it => helpers.urlFormat('/home/orders/detail', {orderCode: it})
},
{
type: 'afterService',
name: '售后服务',
afterService: true,
hrefFun: () => ''
},
{
type: 'exchange',
name: '申请换货',
optDis: true,
hrefFun: it => helpers.urlFormat('/home/returns/exchangerequest', {orderCode: it})
},
{
type: 'refund',
name: '申请退货',
optDis: true,
hrefFun: it => helpers.urlFormat('/home/returns/refundrequest', {orderCode: it})
},
{
type: 'shareOrder',
name: '晒单评价',
comment: true,
hrefFun: it => helpers.urlFormat('/home/comment/order', {orderId: it})
},
{
type: 'readd',
name: '再次购买',
reBuy: true,
hrefFun: () => ''
},
{
type: 'showDetail',
name: '查看订单',
showDetail: true,
hrefFun: it => helpers.urlFormat('/home/orders/detail', {orderCode: it})
},
{
type: 'refundApply',
name: '申请退款',
refund: true,
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'deposit',
name: '定金预售商品只能在APP端操作',
deposit: true,
hrefFun: () => ''
}
];
const _getTabs = (type) => {
type = type || 1;
return TABS.map((tab) => {
tab.active = tab.type === type;
tab.url = helpers.urlFormat('/home/orders', {page: 1, type: tab.type});
return tab;
});
};
const _getOrderStatus = (isCancel, status, payType, payStatus, statusStr) => {
// 初始化:未取消,待付款
let ret = {
cancel: false,
keyName: 'noPay'
};
if (isCancel === 'Y') {
ret = {cancel: true, statusStr: '已取消'};
} else {
switch (status) {
case 0:
// '订单已成功,等待付款'
if (payType !== 2 && payStatus === 'N') {
ret.keyName = 'noPay';
} else if (payType !== 2 && payStatus === 'Y') {
// '订单已付款,等待备货中'
ret.keyName = 'paid';
} else if (payType === 2 && payStatus === 'N') {
// '订单已成功,等待备货中'-货到付款
ret.keyName = 'complete';
}
break;
case 1:
case 2:
case 3:
// '订单已付款,等待备货中'
ret.keyName = 'paid';
break;
case 4:
case 5:
// '订单已发货'
ret.keyName = 'shipped';
break;
case 6:
// '交易完成';
ret.keyName = 'reback';
break;
default:
ret.keyName = 'unknown';
}
}
ret.statusStr = statusStr;
return ret;
};
const _getOperateInfo = (orderCode, operators) => {
return _.flatten(operators.map(it => ORDER_OP_ALL.filter(op => op.type === it).map((op) => {
return Object.assign({}, op, {
href: op.hrefFun(orderCode)
});
})));
};
const _getGoodsTag = (attribute, goodsType) => {
let goodsTagName = '';
switch (goodsType) {
// 赠品
case 'gift':
goodsTagName = 'freebie';
break;
// 加价购
case 'price_gift':
goodsTagName = 'advanceBuy';
break;
// 预售
case 'advance':
goodsTagName = 'preSaleGood';
break;
// outlet
case 'outlet':
goodsTagName = '';
break;
// 免单
case 'free':
goodsTagName = '';
break;
// 电子
case 'ticket':
goodsTagName = '';
break;
default:
break;
}
// 虚拟
if (attribute === 3) {
goodsTagName = 'virtualGood';
}
return goodsTagName;
};
const _getUrlSafe = (url) => {
if (!url) {
return '';
}
const WhiteList = ['/special_', '/special/'];
if (_.some(WhiteList, (val) => _.includes(url, val))) {
return url;
}
return url.replace('http://', '//');
};
const _getExpressInfo = (orderCode, uid, paymentType, createTime, isDetail) => {
return co(function * () {
isDetail = isDetail || false;
let result = {};
result.logisticsUrl = '';
result.logisticsImg = '';
result.logisticsCompany = '';
result.courierNumbe = '';
result.logistics = [];
if (paymentType === 1) {
if (isDetail) {
result.logistics.push('');
} else {
result.logistics.push(moment.unix(createTime).format('YYYY.MM.DD HH:mm:ss') + ' 您的订单已提交,等待付款');
}
}
if (paymentType === 2) {
if (isDetail) {
result.logistics = result.logistics.concat([
moment.unix(createTime).format('YYYY-M-D H:m:s'),
' ',
'您的订单已提交,等待审核'
]);
} else {
result.logistics.push(moment.unix(createTime).format('YYYY.MM.DD HH:mm:ss') + ' 您的订单已提交,等待审核');
}
}
// 有物流
if (orderCode) {
let logistics = yield orderApi.getLogisticsData(orderCode, uid);
if (_.has(logistics, 'data')) {
result.logisticsUrl = _getUrlSafe(logistics.data.url);
result.logisticsImg = logistics.data.logo || '';
result.logisticsCompany = logistics.data.caption || '';
result.courierNumbe = logistics.data.express_number || '';
let expressDetail = logistics.data.express_detail || [];
if (!_.isEmpty(expressDetail)) {
let logisticsTmp = result.logistics[0]; // 暂存
result.logistics = [];
expressDetail.forEach((value) => {
let pos = value.accept_address.indexOf(' ');
pos = pos === -1 ? 0 : pos;
let city = value.accept_address.substr(0, pos);
let exInfo = value.accept_address.substr(pos);
if (isDetail) {
result.logistics.push([value.acceptTime, city, exInfo]);
} else {
result.logistics.push(value.acceptTime + city + exInfo);
}
});
// 把最初的处理放最后
result.logistics.push(logisticsTmp);
}
}
}
return result;
})();
};
/**
* 获取我的订单列表数据
*/
const getOrders = (uid, page, limit, type, isPage)=> {
return co(function *() {
isPage = isPage || false;
let orderInfo = yield orderApi.getUserOrders(uid, page, limit, type).then(res => _.get(res, 'data', {}));
if (_.isEmpty(_.get(orderInfo, 'order_list', []))) {
return {
empty: ORDER_EMPTY_DESC[type] || '',
list: []
};
}
let result = {};
const handleOrder = function(order) {
order.payment_type = +order.payment_type;
let newOrder = {};
newOrder.orderNum = order.order_code; // 订单标识
newOrder.orderTime = moment.unix(_.get(order, 'create_time')).format('YYYY-MM-DD HH:mm:ss');
newOrder.time = _.get(order, 'create_time');
newOrder.payType = _.get(order, 'payment_type');
if (order.is_cancel === 'Y' || order.status === 6) {
newOrder.canDelete = true; // 删除订单
}
let statusInfo = _getOrderStatus(order.is_cancel, order.status, order.payment_type,
order.payment_status, order.status_str
);
// 订单状态
if (statusInfo.cancel) {
newOrder.cancel = statusInfo.cancel;
} else {
if (statusInfo.keyName) {
newOrder[statusInfo.keyName] = true;
}
}
newOrder.statusStr = statusInfo.statusStr;
newOrder.goods = _.get(order, 'order_goods', []).map((good) => {
let newGood = {};
newGood.href = helpers.getUrlBySkc(good.product_id, good.goods_id, good.cn_alphabet);
newGood.thumb = helpers.image(good.goods_image, 100, 100);
newGood.name = good.product_name;
newGood.color = good.color_name;
newGood.size = good.size_name;
newGood.price = good.goods_price;
let buyNum = _.parseInt(good.buy_number);
let refundNum = _.parseInt(good.refund_num);
newGood.count = buyNum;
newGood.refundStatus = refundNum > 0;// 只要发生一件退换,退换过的标记
newGood.goRefundUrl = helpers.urlFormat('/home/returns');
newGood.arrivalDate = good.expect_arrival_time;
let goodsTagName = _getGoodsTag(order.attribute, good.goods_type);
if (goodsTagName) {
newGood[goodsTagName] = true;
}
return newGood;
});
newOrder.pay = order.amount; // 付款数
newOrder.fregit = order.shipping_cost; // 邮费
// 操作
let op = _.get(order, 'links', []);
// 新增加一些操作
op.unshift('showDetail');
if (_.get(order, 'is_support_exchange', 'N') === 'Y') {
op.push('exchange');
}
if (_.get(order, 'is_support_refund', 'N') === 'Y') {
op.push('refund');
}
if (order.attribute === 9) {
op = ['deposit'];
}
newOrder.operation = _getOperateInfo(order.order_code, op);
return newOrder;
};
result.list = _.get(orderInfo, 'order_list', []).map(handleOrder);
if (isPage) {
result.pager = {
total: orderInfo.total,
pageTotal: orderInfo.page_total,
page: orderInfo.page
};
}
return result;
})();
};
const index = (uid, page, limit, type) => {
return co(function * () {
let result = yield Promise.props({
orders: getOrders(uid, page, limit, type, true),
cancelReason: orderApi.closeReasons().then(res => _.get(res, 'data', ''))
});
result.pager = pager(_.get(result, 'orders.pager.total', 0), {page, limit, type});
return Object.assign(result, {
tabs: _getTabs(type)
});
})();
};
const reBuy = (uid, orderId) => {
return co(function * () {
let newOrder = yield orderApi.reBuy(uid, orderId);
if (newOrder.code !== 200) {
return {
code: 400,
message: '商品加入购物车失败'
};
}
return {
code: 200,
message: '商品已重新加入购物车',
data: newOrder.data
};
})();
};
const del = co(function * (uid, gender, channel, orderId) {
let orderInfo = yield orderApi.del(uid, gender, channel, orderId);
if (!_.has(orderInfo, 'code')) {
return {
code: 400,
message: '删除失败'
};
}
return orderInfo;
});
const _getVirtualPro = (isCancel, status, createTime) => {
let process = {
middleStatus: [
{
name: '1. 提交订单',
date: moment.unix(createTime).format('YYYY.MM.DD HH:mm:ss')
},
{
name: '2. 已发货'
},
{
name: '3. 交易完成'
}
]
};
if (isCancel === 'N') {
if (status === 0) {
process.percent = '30%';
process.middleStatus[0].cur = true;
} else if (status > 0 && status < 6) {
process.percent = '80%';
process.middleStatus[1].cur = true;
} else if (status === 6) {
process.percent = '100%';
process.middleStatus[3].cur = true;
}
}
return process;
};
const _getNormalPro = (isCancel, status, createTime) => {
let process = {
middleStatus: [
{
name: '1. 提交订单',
date: moment.unix(createTime).format('YYYY.MM.DD HH:mm:ss')
},
{
name: '2. 商品出库'
},
{
name: '3. 等待收货'
},
{
name: '4. 交易完成'
}
]
};
if (isCancel === 'N') {
if (status === 0) {
process.percent = '25%';
process.middleStatus[0].cur = true;
} else if (status > 0 && status < 4) {
process.percent = '50%';
process.middleStatus[1].cur = true;
} else if (status >= 4 && status < 6) {
process.percent = '75%';
process.middleStatus[2].cur = true;
} else if (status === 6) {
process.percent = '100%';
process.middleStatus[3].cur = true;
}
}
return process;
};
const _getOrderDetailOp = (orderId, payment, status,
isCancel, paymentStatus, paymentType,
orderType, attribute, refundStatus) => {
let operation = {};
// 立刻付款
if (paymentType === 1 && paymentStatus === 'N' && isCancel === 'N' && payment !== 19) {
Object.assign(operation, {
goPay: helpers.urlFormat('/shopping/pay', {ordercode: orderId})
});
}
// 取消订单
if (status < 3 && isCancel === 'N' && paymentStatus === 'N' && orderType !== 5) {
Object.assign(operation, {
cancelOrder: true
});
}
// 订单已支付
if (paymentType === 1 && paymentStatus === 'Y' && status < 6) {
Object.assign(operation, {
paid: true
});
}
// 确认收货
if (status >= 4 && status < 6 && refundStatus === 0 && attribute !== 3 && isCancel === 'N') {
Object.assign(operation, {
shipped: true
});
}
// 订单已取消
if (isCancel === 'Y') {
Object.assign(operation, {
cancel: true
});
}
// 虚拟查看二维码
if (attribute === 3) {
Object.assign(operation, {
checkQrCode: helpers.urlFormat('/home/orders/ticket', {orderCode: orderId})
});
}
return operation;
};
const _getPackageInfo = (cartInfo) => {
// 是否拆单
if (cartInfo.is_multi_package !== 'Y') {
return [];
}
return _.get(cartInfo, 'package_list', []).map((pack) => {
let newPack = {
supplierId: pack.supplier_id,
fee: pack.shopping_cost === '0.00' ? '' : pack.shopping_cost,
orign: pack.shopping_orig_cost,
count: pack.shopping_cut_cost
};
newPack.goodlist = _.get(pack, 'goods_list', []).map((good) => {
let tagInfo = ChannelConfig.orderTagArr[good.goods_type] || '';
return {
src: helpers.image(good.goods_images, 90, 90),
goodsType: tagInfo.name || '',
classname: tagInfo.classname || '',
link: 'javascritp:void(0)'
};
});
return newPack;
});
};
const _getOrderDetail = co(function * (uid, orderId) {
let orderInfo = yield orderApi.getOrderDetail(uid, orderId);
let detail = {};
if (orderInfo.code === 400) {
return orderInfo;
}
if (orderInfo.data) {
let orderDetail = orderInfo.data;
orderDetail.payment_type = +orderDetail.payment_type;
detail.orderNum = orderDetail.order_code;
// 订单状态
let statusInfo = _getOrderStatus(
orderDetail.is_cancel, +orderDetail.status,
orderDetail.payment_type, orderDetail.payment_status, orderDetail.status_str
);
detail.statusStr = statusInfo.statusStr;
// 订单是否已完成
detail.complete = +orderDetail.status === 6;
detail.progress = statusInfo.cancel ? false : (function() {
// 未取消订单,进度
if (orderDetail.attribute === 3) {
return _getVirtualPro(orderDetail.is_cancel, +orderDetail.status, orderDetail.create_time);
} else {
return _getNormalPro(orderDetail.is_cancel, +orderDetail.status, orderDetail.create_time);
}
}());
// 物流信息
detail.traceOrder = {};
detail.traceOrder.orderDate = moment.unix(orderDetail.create_time).format('YYYY.MM.DD HH:mm:ss');
let expressInfo = yield _getExpressInfo(orderId, uid, +orderDetail.payment_type, orderDetail.create_time, true);
detail.traceOrder.logistics = expressInfo.logistics;
if (_.get(expressInfo, 'logistics[0]')) {
detail.hastrace = true;
} else {
detail.hastrace = false;
}
detail.traceOrder.logisticsCompany = expressInfo.logisticsCompany;
detail.traceOrder.courierNumbe = expressInfo.courierNumbe;
// 虚拟商品
if (orderDetail.attribute === 3) {
detail.virtualGoods = true;
detail.virtualPayMode = {
payMode: ChannelConfig.payType[orderDetail.payment_type],
phone: _.fill(orderDetail.mobile.split(''), '*', 3, 4).join('')
};
} else {
detail.virtualGoods = false;
detail.noramlPayMode = {
payMode: ChannelConfig.payType[orderDetail.payment_type],
payWay: orderDetail.payment_name,
deliverTime: orderDetail.delivery_time || ''
};
// 配送信息
detail.orderInfo = {
receiver: orderDetail.user_name,
address: orderDetail.area + orderDetail.address,
phone: _.fill(orderDetail.mobile.split(''), '*', 3, 4).join('') +
(orderDetail.phone ? ',' + _.fill(orderDetail.phone.split(''), '*', 3, 5).join('') : '')
};
detail.editInfo = {
userName: orderDetail.user_name,
address: orderDetail.address,
areaCode: orderDetail.area_code,
mobile: orderDetail.mobile,
phoneNum: _.nth(_.split(orderDetail.phone), 0) || '',
phoneCode: _.nth(_.split(orderDetail.phone), 1) || ''
};
}
// 商品信息
if (orderDetail.order_goods) {
detail.goods = _.get(orderDetail, 'order_goods', []).map((good) => {
return {
url: helpers.getUrlBySkc(good.product_id, good.goods_id, good.cn_alphabet),
img: helpers.image(good.goods_image, 60, 60),
name: good.product_name,
color: good.factory_color_name,
size: good.size_name,
price: good.goods_price,
coin: good.yoho_give_coin,
num: good.buy_number,
sum: good.goods_amount,
sku: good.product_sku,
[_getGoodsTag(good.attribute, good.goods_type)]: true
};
});
}
// 详情页-订单付费详情
if (orderDetail.promotion_formulas) {
detail.orderBalance = _.get(orderDetail, 'promotion_formulas', []).map((promotion) => {
return {
promotion: promotion.promotion,
account: promotion.promotion_amount
};
});
detail.orderBalance.push({
promotion: '实际应支付',
account: orderDetail.amount
});
}
// 发票
if (orderDetail.invoice) {
detail.invoiceMode = true;
detail.invoiceType = _.get(orderDetail, 'invoice.type') === 2 ? '电子发票' : '纸质发票';
detail.showInvoice = _.get(orderDetail, 'invoice.showInvoice');
detail.pdfUrl = detail.showInvoice ? _.get(orderDetail, 'invoice.pdfUrl') : '';
detail.title = _.get(orderDetail, 'invoice.title') || '';
detail.contentValue = _.get(orderDetail, 'invoice.contentValue') || '个人';
}
detail.totalYoho = orderDetail.yoho_give_coin;
detail.yohoCoinUrl = helpers.urlFormat('/help/detail', {id: 105}); // 有货币介绍
detail.remark = orderDetail.remark;
detail.operation = _getOrderDetailOp(orderDetail.order_cde, orderDetail.payment, +orderDetail.status,
orderDetail.is_cancel, orderDetail.payment_status, orderDetail.payment_type,
orderDetail.order_type, orderDetail.attribute, orderDetail.refund_status);
detail.packageTitle = orderDetail.package_title;
detail.packages = _getPackageInfo(orderDetail);
// 判断是否可以修改地址
if (orderDetail.can_update_delivery_address === 'Y') {
detail.changeable = true;
}
// 判断是否可以修改省份
if (orderDetail.is_support_change_province === 'N') {
detail.changeProvince = true;
}
return detail;
}
});
const updateDeliveryAddress = orderApi.updateDeliveryAddress;
const confirm = orderApi.confirmUserOrder;
const cancel = orderApi.cancelUserOrder;
const closeReason = () => {
return orderApi.closeReasons().then((result) => {
return _.get(result, 'data', []);
});
};
const refundReason = () => {
return orderApi.refundReason().then((result) => {
return _.get(result, 'data', []);
});
};
const refund = orderApi.refund;
const detail = co(function * (uid, orderId) {
let apiData = yield Promise.props({
detailData: _getOrderDetail(uid, orderId),
reason: closeReason()
});
if (apiData.detailData.code === 400) {
return {};
}
return {
detail: apiData.detailData,
package: apiData.detailData.package,
cancelReason: apiData.reason
};
});
const express = _.partial(_getExpressInfo, _, _, _, _, true);
module.exports = {
index,
ORDER_TYPE,
reBuy,
del,
updateDeliveryAddress,
confirm,
cancel,
detail,
getOrders,
closeReason,
express,
refund,
refundReason
};
... ...
'use strict';
const _ = require('lodash');
const handleFilterUrl = (originParam, newParam, delParam) => {
let dest = '?';
let tempOriginParam = {};
delParam = delParam || {};
tempOriginParam = Object.assign(tempOriginParam, originParam, newParam);
delete tempOriginParam.uid;
_.forEach(tempOriginParam, function(value, key) {
if (!delParam[key] && value) {
dest += `${key}=${value}&`;
}
});
return _.trim(dest, '&');
};
exports.handlePagerData = (total, params) => {
let result = {
prePage: {
url: ''
},
nextPage: {
url: ''
},
pages: []
};
let currentPage = parseInt(_.get(params, 'page', 1), 10); // 当前页
let perPageCount = parseInt(_.get(params, 'limit', 10), 10); // 每页商品数
let totalPage = _.ceil(total / perPageCount); // 总页数
result.count = total;
result.curPage = currentPage;
result.totalPages = totalPage;
if (currentPage === 1) {
// 当前页为 1,一定没有上一页
delete result.prePage;
} else {
result.prePage.url = handleFilterUrl(params, {page: currentPage - 1});
}
if (currentPage === totalPage) {
// 当前页为最后一页,一定没有下一页
delete result.nextPage;
} else {
result.nextPage.url = handleFilterUrl(params, {page: currentPage + 1});
}
if (totalPage === 0) {
return {
count: 0,
curPage: 0,
totalPages: 0
};
}
if (totalPage === 1) {
return result;
}
// 页码临时数据
let pages = [];
if (currentPage > 2 && currentPage <= totalPage - 2) {
for (let i = currentPage - 2; i <= ((currentPage + 2) > totalPage ? totalPage : (currentPage + 2)); i++) {
pages.push({
url: handleFilterUrl(params, {page: i}),
num: i,
cur: currentPage === i
});
}
// 处理页码小于等于 2 的情况
} else if (currentPage <= 2) {
for (let i = 1; i <= (totalPage < 5 ? totalPage : 5); i++) {
pages.push({
url: handleFilterUrl(params, {page: i}),
num: i,
cur: currentPage === i
});
}
} else if (currentPage > totalPage - 2) {
for (let i = totalPage; i >= totalPage - 4; i--) {
if (i > 0) {
pages.push({
url: handleFilterUrl(params, {page: i}),
num: i,
cur: currentPage === i
});
}
}
pages = _.sortBy(pages, ['num']);
}
let prevPages = [];
let nextPages = [];
if (_.size(pages) === 5) {
if (currentPage > 4) {
prevPages.push({
url: handleFilterUrl(params, {page: 1}),
num: 1
});
prevPages.push({
num: '...'
});
}
if (currentPage < totalPage - 2 && totalPage > 5) {
nextPages.push({
num: '...'
});
nextPages.push({
url: handleFilterUrl(params, {page: totalPage}),
num: totalPage
});
}
}
result.pages = _.concat(prevPages, pages, nextPages);
return result;
};
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const RedenvelopesData = require('./redenvelopes-data.js');
const _ = require('lodash');
const redenvelopesData = require('./redenvelopes-api.js');
const redenvelopesList = uid=>{
return co(function*() {
let result = {};
let data = yield RedenvelopesData.getRedenvelopesTotal(uid);
if (data.code && data.code == 200 && data.data.redpacket_num) {
result.money = data.data.redpacket_num;
result.termOfValidity = data.data.useable_time;
let data = yield redenvelopesData.getRedenvelopesTotal(uid);
if (_.get(data, 'code') === 200 && _.get(data, 'data.redpacket_num')) {
result.money = _.get(data, 'data.redpacket_num');
result.termOfValidity = _.get(data, 'data.useable_time');
}
result.useRemark = '1.红包活动,全场通用(预售商品除外);<br>2.结算时折抵现金使用,可以和优惠券叠加使用;<br>3.限有效期内使用,过期清零';
return [result];
result.useRemark = '1.红包活动,全场通用(预售商品除外);<br>' +
'2.结算时折抵现金使用,可以和优惠券叠加使用;<br>' +
'3.限有效期内使用,过期清零';
return {redEnvelopes: [result]};
})();
};
... ...
... ... @@ -130,8 +130,7 @@ const exchangeGift = (params, uid) => {
uid: uid,
giftCardCode1: params.giftCardCode1,
giftCardCode2: params.giftCardCode2,
giftCardCode3: params.giftCardCode3,
captchaCode: params.captchaCode
giftCardCode3: params.giftCardCode3
});
};
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const userData = require('./user-data');
const moment = require('moment');
const helpers = global.yoho.helpers;
const vipIndex = (uid)=>{
return co(function*() {
let vipInfo = yield userData.getVIPInfoByUid(uid);
let data = vipInfo.data, proportion = '0%';
if (+data.next_need_cost !== 0) {
proportion = data.current_year_cost * 100 / data.next_need_cost;
proportion = proportion > 100 ? 100 : proportion;
proportion = proportion + '%';
}
let remainDays = Math.ceil(((data.vip_end_time) * 1000 - Date.now()) / 86400000);
let preferences = [];
if (data.enjoy_preferential) {
preferences = data.enjoy_preferential.map(function(item) {
return {
id: item.id,
favTxt: item.title,
imgType: helpers.https(item.pic),
description: item.description
};
});
}
let isVip = data.current_vip_level > 0 ? true : false;
let vip = {
title: data.current_vip_title,
nextTitle: data.next_vip_title,
nextLevel: data.next_vip_level,
yearCost: Number(data.current_year_cost).toFixed(2),
totalCost: (+data.current_total_cost).toFixed(2),
list: preferences,
level: data.current_vip_level,
platinum: data.upgrade_need_cost > 0 ? false : true,
nextCost: Number(data.next_need_cost).toFixed(2),
balan: Number(data.upgrade_need_cost).toFixed(2),
proportion: proportion,
vipLevel: data.next_vip_title,
reach: moment(data.vip_reach_time * 1000).format('YYYY.MM.DD'),
valid: moment(data.vip_start_time * 1000).format('YYYY.MM.DD'),
end: moment(data.vip_end_time * 1000).format('YYYY.MM.DD'),
remainDays: remainDays,
doubtLevel: isVip,
commonVip: !isVip,
morePreferences: helpers.urlFormat('/help/detail', {id: 7})
};
return vip;
})();
};
module.exports = {
vipIndex
};
... ...