Showing 74 changed files with 1560 additions and 2071 deletions

Too many changes to show.

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

... ... @@ -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 index = (req, res, next)=>{
let uid = '8041246';
let uid = req.user.uid;
couponsModel.couponsData(uid, req.query).then(result => {
res.render('coupons', result);
... ...
'use strict';
const headerModel = require('../../../doraemon/models/header');
const msgModel = require('../models/message');
const helpers = global.yoho.helpers;
const _ = require('lodash');
const homeNav = (req) => {
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: _.get(req.app.locals.pc, 'clientService.new', false) ?
'/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 = (req, count)=>{
let mHomeNav = _.cloneDeep(homeNav(req));
let activeNav = null;
mHomeNav = mHomeNav.map((item) => {
item.subNav = item.subNav.map((nav) => {
let curMatchPath = req.originalUrl;
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 getHomeNav = (req, res, next) => {
msgModel.unreadTotal(req.user.uid).then(result => {
let navs = getActiveNav(req, _.get(result, 'data.total', 0));
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: '个人中心'
});
}
res.locals.path = bread; // [{href: helpers.urlFormat('/'), name: 'YOHO!BUY 有货首页'}, {name: '个人中心'}];
res.locals.homeNav = navs.homeNav;
res.locals.userThumb = '//img10.static.yhbimg.com/headimg/' +
'2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100';
next();
});
};
const headerService = require('../models/general-tabs-service');
const getCommonHeader = (req, res, next) => {
let channel = req.query.channel ? req.query.channel : 'boys';
let channel = req.query.channel;
let uid = req.user.uid;
let clientService = _.get(req.app.locals.pc, 'clientService.new', false);
headerModel.requestHeaderData(channel).then((result)=>{
headerService.getHomeNav(uid, channel, req.originalUrl, clientService).then((result)=>{
_.merge(res.locals, result);
next();
});
};
module.exports = {
homeNav,
getActiveNav,
getHomeNav,
getCommonHeader
};
... ...
... ... @@ -53,14 +53,24 @@ const del = (req, res, 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 = phoneNum ? `${phoneCode}-${phoneNum}` : '';
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({
... ... @@ -141,6 +151,32 @@ const express = (req, res, next) => {
}).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,
... ... @@ -149,5 +185,7 @@ module.exports = {
confirm,
cancel,
detail,
express
express,
refund,
refundReason
};
... ...
... ... @@ -37,10 +37,12 @@ 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 = _.replace(dates[0], /\./g, '-');
result[i].endTime = _.replace(dates[1], /\./g, '-');
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';
... ... @@ -48,16 +50,29 @@ const getCouponsList = (uid, type, page, limit)=>{
result[i].img = item.couponImageUrl;
}
// 3天之内即将要过期
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 = _.get(item, 'orderCode', '');
... ... @@ -66,7 +81,7 @@ const getCouponsList = (uid, type, page, limit)=>{
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 {
... ...
'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
};
... ...
... ... @@ -158,13 +158,17 @@ exports.updateDeliveryAddress = (orderId, userName, areaCode, address, mobile, p
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);
};
... ... @@ -209,3 +213,34 @@ exports.del = (uid, gender, channel, orderId) => {
});
};
/**
* 申请退款
*/
exports.refund = (uid, orderId, reasonId, reason) => {
let params = {
uid: uid,
order_code: orderId
};
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'
});
};
... ...
... ... @@ -36,7 +36,7 @@ const ORDER_OP_ALL = [
type: 'closeOrder',
name: '取消订单',
cancelOrder: true,
hrefFun: () => 'javascript:void(0)'
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'buyNow',
... ... @@ -48,13 +48,13 @@ const ORDER_OP_ALL = [
type: 'getExpress',
name: '查看物流',
express: true,
hrefFun: () => 'javascript:void(0)'
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'confirm',
name: '确认订单',
confirmReceived: true,
hrefFun: () => 'javascript:void(0)'
hrefFun: () => 'javascript:void(0)' // eslint-disable-line
},
{
type: 'delOrder',
... ... @@ -78,7 +78,7 @@ const ORDER_OP_ALL = [
type: 'exchange',
name: '申请换货',
optDis: true,
hrefFun: it => helpers.urlFormat('/home/returns/exchangeRequest', {orderCode: it})
hrefFun: it => helpers.urlFormat('/home/returns/exchangerequest', {orderCode: it})
},
{
type: 'refund',
... ... @@ -105,6 +105,12 @@ const ORDER_OP_ALL = [
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,
... ... @@ -387,13 +393,23 @@ const getOrders = (uid, page, limit, type, isPage)=> {
// 操作
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;
};
... ... @@ -533,42 +549,42 @@ const _getOrderDetailOp = (orderId, payment, status,
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})
... ... @@ -584,10 +600,13 @@ const _getPackageInfo = (cartInfo) => {
return [];
}
return _.get(cartInfo, 'package_list', []).map((pack, i) => {
let newPack = {};
newPack.title = (pack.supplier_id === 0) ? `包裹${i}:总仓发货` : `包裹${i}:异地调拨`;
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] || '';
... ... @@ -600,10 +619,6 @@ const _getPackageInfo = (cartInfo) => {
};
});
newPack.fee = pack.shopping_cost === '0.00' ? '' : pack.shopping_cost;
newPack.orign = pack.shopping_orig_cost;
newPack.count = pack.shopping_cut_cost;
return newPack;
});
};
... ... @@ -633,7 +648,7 @@ const _getOrderDetail = co(function * (uid, orderId) {
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 {
... ... @@ -657,7 +672,7 @@ const _getOrderDetail = co(function * (uid, orderId) {
detail.traceOrder.logisticsCompany = expressInfo.logisticsCompany;
detail.traceOrder.courierNumbe = expressInfo.courierNumbe;
//虚拟商品
// 虚拟商品
if (orderDetail.attribute === 3) {
detail.virtualGoods = true;
detail.virtualPayMode = {
... ... @@ -672,7 +687,7 @@ const _getOrderDetail = co(function * (uid, orderId) {
deliverTime: orderDetail.delivery_time || ''
};
//配送信息
// 配送信息
detail.orderInfo = {
receiver: orderDetail.user_name,
address: orderDetail.area + orderDetail.address,
... ... @@ -709,7 +724,7 @@ const _getOrderDetail = co(function * (uid, orderId) {
});
}
//详情页-订单付费详情
// 详情页-订单付费详情
if (orderDetail.promotion_formulas) {
detail.orderBalance = _.get(orderDetail, 'promotion_formulas', []).map((promotion) => {
return {
... ... @@ -724,7 +739,7 @@ const _getOrderDetail = co(function * (uid, orderId) {
});
}
//发票
// 发票
if (orderDetail.invoice) {
detail.invoiceMode = true;
detail.invoiceType = _.get(orderDetail, 'invoice.type') === 2 ? '电子发票' : '纸质发票';
... ... @@ -740,14 +755,20 @@ const _getOrderDetail = co(function * (uid, orderId) {
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.package = _getPackageInfo(orderDetail);
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;
}
});
... ... @@ -764,6 +785,14 @@ const closeReason = () => {
});
};
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),
... ... @@ -794,5 +823,7 @@ module.exports = {
detail,
getOrders,
closeReason,
express
express,
refund,
refundReason
};
... ...
... ... @@ -9,11 +9,14 @@ const express = require('express');
const router = express.Router(); // eslint-disable-line
const cRoot = './controllers';
const newUserController = require(`${cRoot}/new-user`);
const tabsMiddleware = require(`${cRoot}/general-tabs`);
const indexController = require(`${cRoot}/index`);
const commentController = require(`${cRoot}/comment`);
const consultController = require(`${cRoot}/consult`);
// const complaintsController = require(`${cRoot}/complaints`);
const messageController = require(`${cRoot}/message`);
... ... @@ -41,19 +44,20 @@ const giftController = require(`${cRoot}/gift`);
// 首页
router.get(['/index', '/'], [tabsMiddleware.getHomeNav, tabsMiddleware.getCommonHeader], indexController.index);
router.get(['/index', '/'], tabsMiddleware.getCommonHeader, indexController.index);
// 查看二维码
router.get('/QRcode', [tabsMiddleware.getHomeNav, tabsMiddleware.getCommonHeader], personalController.QRcode);
router.get('/QRcode', tabsMiddleware.getCommonHeader, personalController.QRcode);
// 我的评论
router.get('/comment', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], commentController.index);
router.get('/comment', tabsMiddleware.getCommonHeader, commentController.index);
router.post('/comment/saveComment', commentController.saveComment);
router.get('/comment/order', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], commentController.commentList4Order);
router.get('/comment/order', tabsMiddleware.getCommonHeader, commentController.commentList4Order);
// 我的咨询
router.get('/consult', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], consultController.index);
router.get('/consult', tabsMiddleware.getCommonHeader, consultController.index);
// 我的投诉
// router.get('/complaints', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], complaintsController.index);
... ... @@ -61,8 +65,10 @@ router.get('/consult', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNa
// router.post('/complaints/cancel', complaintsController.cancel);
// 我的消息
router.get('/message', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], messageController.index);
router.get('/message/detail', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], messageController.detail);
router.get('/message', tabsMiddleware.getCommonHeader, messageController.index);
router.get('/message/detail', tabsMiddleware.getCommonHeader, messageController.detail);
router.get('/message/del', messageController.delMsg);
router.get('/message/read', messageController.readMsg);
router.get('/message/pickCoupon', messageController.pickCoupon);
... ... @@ -78,26 +84,26 @@ router.get('/message/pickCoupon', messageController.pickCoupon);
// router.get('/index', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], IndexController.index);
/* 我的YOHO币 */
router.get('/currency', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], currencyController.index);
router.get('/currency', tabsMiddleware.getCommonHeader, currencyController.index);
/* 我的红包 */
router.get('/redenvelopes', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], redenvelopesController.index);
router.get('/redenvelopes', tabsMiddleware.getCommonHeader, redenvelopesController.index);
/* 我的VIP */
router.get('/vip', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], vipController.index);
router.get('/vip', tabsMiddleware.getCommonHeader, vipController.index);
/* 我的优惠卷 */
router.get('/coupons', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], couponsController.index);
router.get('/coupons', tabsMiddleware.getCommonHeader, couponsController.index);
/********************************* 我的收藏开始 *****************************************/
/** ******************************* 我的收藏开始 *****************************************/
// 我的收藏
router.get('/favorite', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], favoriteController.index);
router.get('/favorite', tabsMiddleware.getCommonHeader, favoriteController.index);
// 品牌页新品到着
router.get('/favorite/newproduct', favoriteController.newProduct);
// 降价提醒
router.get('/favorite/reduction', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], favoriteController.reduction);
router.get('/favorite/reduction', tabsMiddleware.getCommonHeader, favoriteController.reduction);
// 设置降价提醒
router.get('/favorite/notice', favoriteController.notice);
... ... @@ -108,10 +114,10 @@ router.get('/favorite/cancelnotice', favoriteController.cancelNotice);
// 取消收藏
router.get('/favorite/cancel', favoriteController.cancel);
/********************************* 我的收藏结束 *****************************************/
/** ******************************* 我的收藏结束 *****************************************/
/********************************* 我的订单开始 *****************************************/
router.get('/orders', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], ordersController.index);
/** ******************************* 我的订单开始 *****************************************/
router.get('/orders', tabsMiddleware.getCommonHeader, ordersController.index);
// 重新加入购物车
router.post('/orders/readd', ordersController.reBuy);
... ... @@ -129,17 +135,22 @@ router.post('/orders/confirmOrder', ordersController.confirm);
router.post('/orders/cancelOrder', ordersController.cancel);
// 订单详情
router.get('/orders/detail', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], ordersController.detail);
router.get('/orders/detail', tabsMiddleware.getCommonHeader, ordersController.detail);
// 物流信息
router.get('/orders/express', ordersController.express);
/********************************* 我的订单结束 *****************************************/
// 申请退款
router.get('/orders/refund', ordersController.refund);
// 申请退款原因
router.get('/orders/refundreason', ordersController.refundReason);
// router.get('/coupons', CouponsController.index);
/** ******************************* 我的订单结束 *****************************************/
router.get('/user', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], UserController.index);
// router.get('/coupons', CouponsController.index);
router.get('/user', tabsMiddleware.getCommonHeader, UserController.index);
router.post('/user/edituserinfo', UserController.editUserInfo);
... ... @@ -183,31 +194,31 @@ router.get('/bind/renren/callback', bindController.renren.callback);
router.post('/cancelbind/:type', bindController.cancelBind);
// 账号安全
router.get('/account', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.index);
router.get('/account', tabsMiddleware.getCommonHeader, AccountController.index);
router.get('/account/userpwd', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.userPwd);
router.get('/account/userpwd', tabsMiddleware.getCommonHeader, AccountController.userPwd);
router.get('/account/email', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.userEmail);
router.get('/account/email', tabsMiddleware.getCommonHeader, AccountController.userEmail);
router.get('/account/mobile', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.userMobile);
router.get('/account/mobile', tabsMiddleware.getCommonHeader, AccountController.userMobile);
router.post('/account/checkverifycode', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.checkVerifyCode);
router.post('/account/checkverifycode', tabsMiddleware.getCommonHeader, AccountController.checkVerifyCode);
router.post('/account/checkpassword', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.checkPassword);
router.post('/account/checkpassword', tabsMiddleware.getCommonHeader, AccountController.checkPassword);
router.post('/account/verifypassword', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.verifyPassword);
router.post('/account/verifypassword', tabsMiddleware.getCommonHeader, AccountController.verifyPassword);
router.post('/account/modifypwd', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.modifyPwd);
router.post('/account/modifypwd', tabsMiddleware.getCommonHeader, AccountController.modifyPwd);
router.post('/account/sendemail', AccountController.sendEmail);
router.post('/account/checkemail', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.checkEmail);
router.post('/account/checkemail', tabsMiddleware.getCommonHeader, AccountController.checkEmail);
router.post('/account/modifyemail', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.modifyEmail);
router.post('/account/modifyemail', tabsMiddleware.getCommonHeader, AccountController.modifyEmail);
router.get('/account/sendemailsuccess', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.sendEmailSuccess);
router.get('/account/sendemailsuccess', tabsMiddleware.getCommonHeader, AccountController.sendEmailSuccess);
router.get('/account/mailresult', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AccountController.mailResult);
router.get('/account/mailresult', tabsMiddleware.getCommonHeader, AccountController.mailResult);
router.post('/account/checkmobile', AccountController.checkMobile);
... ... @@ -219,7 +230,7 @@ router.post('/account/modifymobile', AccountController.modifyMobile);
// 地址管理
router.get('/address', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], AddressController.index);
router.get('/address', tabsMiddleware.getCommonHeader, AddressController.index);
router.get('/address/area', UserController.getProviceList);
... ... @@ -233,8 +244,11 @@ router.get('/address/defaultAddress', AddressController.defaultAddress);
// 兑换礼品卡
router.get('/gift', [tabsMiddleware.getCommonHeader, tabsMiddleware.getHomeNav], giftController.index);
router.get('/gift', tabsMiddleware.getCommonHeader, giftController.index);
router.post('/gift/exchange', giftController.exchange);
// 是否新客(仅操作cookie)
router.get('/newuser', newUserController.check);
module.exports = router;
... ...
... ... @@ -6,87 +6,124 @@
<h2 class="title">优惠券</h2>
{{> tabs}}
<div class="coupons-wrap">
<p class="coupons-header clearfix">
<span class="coupons-name">优惠券名称</span>
<span class="coupons-info">详细说明</span>
{{#if unUse}}
<span class="coupons-opt">操作</span>
{{/if}}
{{#if used}}
<span class="coupons-opt">订单号</span>
{{/if}}
{{#if noValid}}
<span class="coupons-opt">状态</span>
{{/if}}
</p>
<p class="coupons-header clearfix">
{{#if unUse}}
<span class="coupons-img">优惠券图片</span>
<span class="value">面值</span>
<span class="term-of-validity">有效期</span>
<span class="use-remark">适用说明</span>
<span class="status">状态</span>
{{/if}}
{{#if used}}
<span class="coupons-img">优惠券图片</span>
<span class="value">面值</span>
<span class="order-num">订单编号</span>
<span class="order-sum">订单金额</span>
<span class="payment">实付金额</span>
<span class="use-time">使用时间</span>
{{/if}}
{{#if noValid}}
<span class="coupons-img">优惠券图片</span>
<span class="value">面值</span>
<span class="term-of-validity">有效期</span>
<span class="use-remark">适用说明</span>
{{/if}}
</p>
{{# unUseCoupons}}
{{#unless empty}}
<div class="coupon">
<div class="coupons-img">
<img src="{{image2 img}}">
{{# unUseCoupons}}
{{#unless empty}}
<div class="coupon">
<div class="coupons-name">
<div class="coupons-card coupons-notuse">
<div class="coupons-date clearfix">
<p class="left">{{beginTime}} - {{endTime}}</p>
<p class="right">{{overState}}</p>
</div>
<div class="coupons-num clearfix">
<div class="left coupons-sht">
<p class="coupons-price">{{value}}</p>
<p class="coupons-full">{{rule}}</p>
</div>
<div class="left coupons-dtl">{{useRemark}}</div>
</div>
</div>
</div>
<div class="coupons-info">
<div class="coupons-text">
{{#categorys}}<p>限品类:{{.}}</p>{{/categorys}}
{{#brands}}<p>限品牌:{{.}}</p>{{/brands}}
{{#if isNoLimit}}<p>全场通用</p>{{/if}}
<p>特例商品({{extraPro}}等特例商品)暂不支持使用优惠券。</p>
{{#explains}}<p>说明:{{.}}</p>{{/explains}}
</div>
</div>
<div class="coupons-opt">
<a class="btn use-btn" href="{{proListUrl}}" target="_black">立即使用</a>
</div>
</div>
<span class="value">{{value}}</span>
<div class="term-of-validity{{#if endSoon}} end-soon{{/if}}">
{{beginTime}}
-
<br>
{{endTime}}&nbsp;&nbsp;
<br>
<span>即将过期</span>
</div>
<span class="use-remark">{{useRemark}}</span>
<span class="status">{{status}}</span>
</div>
{{/unless}}
{{/ unUseCoupons}}
{{/unless}}
{{/ unUseCoupons}}
{{# usedCoupons}}
{{#unless empty}}
<div class="coupon">
<div class="coupons-img">
<img src="{{image2 img}}">
{{# usedCoupons}}
{{#unless empty}}
<div class="coupon">
<div class="coupons-name">
<div class="coupons-card coupons-use">
<div class="coupons-date clearfix">
<p class="left">{{beginTime}} - {{endTime}}</p>
</div>
<div class="coupons-num clearfix">
<div class="left coupons-sht">
<p class="coupons-price">{{value}}</p>
<p class="coupons-full">{{rule}}</p>
</div>
<div class="left coupons-dtl">{{useRemark}}</div>
</div>
</div>
</div>
<div class="coupons-info">
<div class="coupons-text">
{{#categorys}}<p>限品类:{{.}}</p>{{/categorys}}
{{#brands}}<p>限品牌:{{.}}</p>{{/brands}}
{{#if isNoLimit}}<p>全场通用</p>{{/if}}
<p>特例商品({{extraPro}}等特例商品)暂不支持使用优惠券。</p>
{{#explains}}<p>说明:{{.}}</p>{{/explains}}
</div>
</div>
<div class="coupons-opt">
<a href="{{orderDetailUrl}}">
<p>{{orderNum}}</p>
<p>{{useTime}}</p>
</a>
</div>
</div>
<span class="value">{{value}}</span>
<span class="order-num"><a href="{{orderDetailUrl}}">{{orderNum}}</a></span>
<span class="order-sum">{{orderSum}}</span>
<span class="payment">{{payment}}</span>
<span class="use-time">{{useTime}}</span>
</div>
{{/unless}}
{{/ usedCoupons}}
{{/unless}}
{{/ usedCoupons}}
{{# noValidCoupons}}
{{#unless empty}}
<div class="coupon">
<div class="coupons-img">
<img src="{{image2 img}}">
</div>
<span class="value">{{value}}</span>
<div class="term-of-validity{{#if endSoon}} end-soon{{/if}}">
{{beginTime}}
-
<br>
{{endTime}}&nbsp;&nbsp;&nbsp;
{{# noValidCoupons}}
{{#unless empty}}
<div class="coupon">
<div class="coupons-name">
<div class="coupons-card coupons-overtime">
<div class="coupons-date clearfix">
<p class="left">{{beginTime}} - {{endTime}}</p>
</div>
<div class="coupons-num clearfix">
<div class="left coupons-sht">
<p class="coupons-price">{{value}}</p>
<p class="coupons-full">{{rule}}</p>
</div>
<div class="left coupons-dtl">{{useRemark}}</div>
</div>
</div>
</div>
<div class="coupons-info">
<div class="coupons-text">
{{#categorys}}<p>限品类:{{.}}</p>{{/categorys}}
{{#brands}}<p>限品牌:{{.}}</p>{{/brands}}
{{#if isNoLimit}}<p>全场通用</p>{{/if}}
<p>特例商品({{extraPro}}等特例商品)暂不支持使用优惠券。</p>
{{#explains}}<p>说明:{{.}}</p>{{/explains}}
</div>
</div>
<div class="coupons-opt">
<a class="btn overtime-btn">过期</a>
</div>
</div>
<span class="use-remark">{{useRemark}}</span>
</div>
{{/unless}}
{{/ noValidCoupons}}
{{/unless}}
{{/ noValidCoupons}}
</div>
{{#if unUseCoupons}}
{{#unless unUseCoupons.empty}}
{{> pager}}
... ...
... ... @@ -20,7 +20,7 @@
{{#unless virtualGoods}}
<!--虚拟商品-->
{{#if changeable}}
<span class="edit-order oo-btn">修改订单</span>
<span class="edit-order oo-btn">修改地址</span>
{{/if}}
{{/unless}}
{{#if operation.cancelOrder}}
... ... @@ -161,16 +161,13 @@
{{#if packages}}
<div id="differentOrder" class="differentOrder">
<p class="warn">
温馨提示:您购买的商品<span class="red">分属不同的仓库</span>,需要调拨,将被拆分为多个包裹送达
<span class="why">
</span>
温馨提示:您购买的商品<span class="red">分属不同仓库</span>{{packageTitle}}<span class="red">预计3-5天内发货给您</span>
<span class="why"></span>
</p>
<div id="differentBag" class="differentBag">
{{#each packages}}
<div class="bag">
<h3>
{{title}}
</h3>
<h3>包裹{{math @index '+' 1}}:{{#isEqual supplierId '0'}}总仓发货{{^}}异地调拨 <em class="red">预计3-5天内发货给您</em>{{/isEqual}}</h3>
<p class="pre">
</p>
<div class="bagDetil">
... ...
... ... @@ -145,6 +145,10 @@
<a class="op-item" href="{{href}}" target="_blank">{{name}}</a>
{{/if}}
{{#if refund}}
<a class="refund-apply op-item" href="{{href}}" target="_blank">{{name}}</a>
{{/if}}
{{#if express}}
<a class="check-logistics op-item"
data-id="{{../orderNum}}" data-time="{{../time}}"
... ...
<script id="edit-dialog-tpl" type="text/html">
<header>订单修改</header>
<header>修改地址</header>
<p class="tip">修改收货信息:</p>
<ul class="edit-order-info">
<li>
... ... @@ -9,13 +9,15 @@
</li>
<li>
<label><i class="form-required">*</i>所在区域:</label>
<select name="province" class="ml10" data-areacode="{{editInfo.areaCode}}">
</select>
<select name="city">
</select>
<select name="county">
</select>
<select name="province" class="ml10" {{#if changeProvince}}disabled{{/if}} data-areacode="{{editInfo.areaCode}}"></select>
<select name="city"> </select>
<select name="county"> </select>
<select name="street"> </select>
<span class="error"><i class="order-icon icon-error"></i><b>请填写完整的省市区信息</b></span>
{{#if changeProvince}}
{{#if changeProvince}}<div class="no-change-province">由于库房原因,目前暂不支持省地址的修改,请您原谅</div>{{/if}}
{{/if}}
</li>
<li>
<label><i class="form-required">*</i>详细地址:</label>
... ... @@ -25,6 +27,7 @@
<li>
<label><i class="form-required">*</i>手机号码:</label>
<input type="text" class="inp" placeholder="请输入手机号码(重要必填)" name="phone" maxlength="11" value="{{editInfo.mobile}}">
<input type="hidden" class="origin-user-mobile" value="{{editInfo.mobile}}">
<span class="error"><i class="order-icon icon-error"></i><b>请输入手机号码(重要必填)</b></span>
</li>
<li>
... ... @@ -34,4 +37,4 @@
<span class="error"><i class="order-icon icon-error"></i><b>只能包含数字、- 组合</b></span>
</li>
</ul>
</script>
\ No newline at end of file
</script>
... ...
... ... @@ -6,7 +6,7 @@
const _ = require('lodash');
const CAPTCHA = require('../data/captcha.json');
const length = CAPTCHA.length || -1;
const length = CAPTCHA.length - 1 || -1;
exports.gen = () => {
if (length !== -1) {
... ...
... ... @@ -15,46 +15,13 @@ const moment = require('moment');
const DEFAULT_AVATAR_ICO = 'http://static.yohobuy.com/images/v3/boy.jpg';
const _ = require('lodash');
const CHANNEL = {
boys: 'boys',
girls: 'girls',
kids: 'kids',
lifestyle: 'lifestyle'
};
const _getChannel = (req, res) => {
let channel = req.cookies._Channel;
if (!channel) {
res.cookie('_Channel', CHANNEL.boys, {
domain: '.yohobuy.com',
maxAge: moment.duration(300, 'days').seconds()
});
channel = 'boys'; // 设置默认值
}
return channel;
};
const _getGender = (channel) => {
switch (channel) {
case 'boys':
return '1,3';
case 'girls':
return '2,3';
default:
return '1,2,3';
}
};
/**
* 首屏渲染商品详情
*/
const showMain = (req, res, next) => {
let pid = req.params[0];
let channel = _getChannel(req, res);
let gender = _getGender(channel);
let channel = req.yoho.channel;
let gender = req.yoho.gender;
const nullUserInfo = {
uid: null,
... ...
... ... @@ -8,6 +8,9 @@
const mRoot = '../models';
const search = require(`${mRoot}/search`);
const _ = require('lodash');
const helpers = global.yoho.helpers;
const config = global.yoho.config;
/**
* search 首页
... ... @@ -15,8 +18,9 @@ const _ = require('lodash');
* @param {[type]} res [description]
* @return {[type]} [description]
*/
exports.index = (req, res, next) => {
const index = (req, res, next) => {
let params = req.query;
let resData = {
title: '潮流商品搜索 | YOHO!BUY 有货',
keywords: 'Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,' +
... ... @@ -40,6 +44,7 @@ exports.index = (req, res, next) => {
return res.render('search/no-result', resData);
}
res.render('search/index', resData);
});
}).catch(next);
};
... ... @@ -50,7 +55,7 @@ exports.index = (req, res, next) => {
* @param {[type]} res [description]
* @return {[type]} [description]
*/
exports.suggest = (req, res, next) => {
const suggest = (req, res, next) => {
search.getSuggest(req.query).then(result => {
let dest = {
code: 200,
... ... @@ -64,7 +69,7 @@ exports.suggest = (req, res, next) => {
}).catch(next);
};
exports.suggest4Old = (req, res, next) => {
const suggest4Old = (req, res, next) => {
search.getSuggest(Object.assign({}, req.query, { keyword: req.query.query })).then(result => {
let dest = {
code: 200,
... ... @@ -92,7 +97,7 @@ exports.suggest4Old = (req, res, next) => {
}).catch(next);
};
exports.serachFilterBrands = (req, res, next) => {
const searchFilterBrands = (req, res, next) => {
search.getBrands4Filter(Object.assign({}, req.query, {
keyword: req.query.query || ''
})).then(result => {
... ... @@ -105,3 +110,64 @@ exports.serachFilterBrands = (req, res, next) => {
res.send(req.query.callback + '(' + JSON.stringify(dest) + ')');
}).catch(next);
};
/**
* search 历史记录提示
* @param {[type]} req [description]
* @param {[type]} res [description]
* @return {[type]} [description]
*/
const searchHistory = (req, res) => {
let history = req.cookies['_History'] || ''; //eslint-disable-line
let q = req.query.query ? _.trim(decodeURIComponent(req.query.query)) : '';
history = _.filter(history.split(','), old => old && old !== q);
if (q) {
history.unshift(q);
res.cookie('_History', _.take(history, 9).join(','), {
domain: config.cookieDomain,
maxAge: 60 * 60 * 24 * 1000 * 30 // 一月
});
}
let data = _.map(history, (item) => {
return {
keyword: item,
href: helpers.urlFormat('', {query: item}, 'search')
};
});
res.type('text/javascript');
res.send(req.query.callback + '(' + JSON.stringify({ data }) + ')');
};
/**
* 搜索少或无 有可能喜欢
**/
const searchLessRecommend = (req, res, next) => {
let channelNum = req.yoho.channelNum;
let uid = req.user.uid;
let udid = req.yoho.udid;
let page = Number(req.query.page || 1);
if (page <= 0 || page >= 6) {
page = 1;
}
search.getSearchLessProduct(channelNum, uid, udid, page).then(result => {
return res.send(result);
}).catch(next);
};
module.exports = {
index,
suggest,
suggest4Old,
searchFilterBrands,
searchHistory, // 搜索历史记录
searchLessRecommend
};
... ...
... ... @@ -62,3 +62,5 @@ exports.escapeLength = function(value) {
return strs.join('');
};
... ...
... ... @@ -132,7 +132,7 @@ const getShopRecommendAsync = (skn, page, limit) => {
*/
const getBundleAsync = (skn) => {
return api.get('', {
method: 'web.query.bundleSkn',
method: 'app.query.bundleSkn',
product_skn: skn
});
};
... ...
... ... @@ -220,7 +220,7 @@ const _getActivityDataByProductBaseInfo = (data) => {
return {
type: value.promotionType.replace(/¥/g, '¥'),
des: des,
url: value.id && helpers.urlFormat('', {psp_id: value.id, phrase: encodeURIComponent(des)}, 'list')
url: value.id && helpers.urlFormat('', {psp_id: value.id, phrase: encodeURIComponent('以下商品参加 ' + des)}, 'list')
};
});
};
... ... @@ -1319,7 +1319,7 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
}
// 量贩商品
if (bundle) {
if (bundle && !_.isEmpty(_.get(bundle, 'data', {}))) {
result.bundle = _getBundleAsync(bundle);
result.activity.unshift({
... ... @@ -1629,53 +1629,62 @@ const recommendAsync = (skn, page, limit) => {
})();
};
/**
* 获取套餐
* 处理单个套餐
*/
const getPackage = (skn) => {
const isPackage = (type) => type === BUNDLE_PACKAGE;
function handlePackage(pack, index) {
const isPackage = type => type === BUNDLE_PACKAGE;
return co(function * () {
let data = yield productAPI.getBundleAsync(skn);
let resData = {code: data.code},
packageList = [];
if (data.code === 200 && !_.isEmpty(data.data) && isPackage(_.get(data, 'data.bundleInfo.discountType'))) {
let bundleInfo = data.data.bundleInfo || {};
let productList = data.data.productList || {};
resData.data = {
bundleId: bundleInfo.bundleId,
salesPrice: bundleInfo.salesPriceStr,
pkgPrice: bundleInfo.discountPriceStr,
savePrice: bundleInfo.subPrice
};
_.forEach(productList, function(value) {
// sku商品信息
let skuData = _getSkuDataByProductBaseInfo(value);
let pkgData = {
skn: value.product_skn,
url: helpers.urlFormat(url.parse(value.product_url).pathname, null, 'item'),
src: value.default_images,
productName: value.product_name,
productPrice: value.format_sales_price,
colors: skuData.skuGoods
};
let bundleInfo = pack.bundleInfo || {};
let productList = pack.productList || [];
packageList.push(pkgData);
});
if (!isPackage(bundleInfo.discountType)) {
return {};
}
resData.data.packageData = packageList;
} else {
resData.code = 400;
resData.message = '没有数据';
}
let item = {
index: index,
name: bundleInfo.tabName,
bundleId: bundleInfo.bundleId,
salesPrice: bundleInfo.salesPriceStr,
pkgPrice: bundleInfo.discountPriceStr,
savePrice: bundleInfo.subPrice
};
return resData;
})();
};
item.productList = _.map(productList, function(value) {
// sku商品信息
let skuData = _getSkuDataByProductBaseInfo(value);
return {
id: value.product_id,
skn: value.product_skn,
url: helpers.getUrlBySkc(value.product_id),
src: value.default_images,
productName: value.product_name,
productPrice: value.format_sales_price,
colors: skuData.skuGoods
};
});
return item;
}
/**
* 获取套餐
*/
const getPackage = co(function * (skn) {
let reqData = yield productAPI.getBundleAsync(skn);
let resData = {code: reqData.code};
if (reqData.code === 200 && !_.isEmpty(reqData.data)) {
resData.data = _.map(reqData.data, handlePackage);
} else {
resData.code = 400;
resData.message = '没有数据';
}
return resData;
});
module.exports = {
... ...
... ... @@ -420,6 +420,33 @@ const getBrands4Filter = (params) => {
}, params));
};
/**
* 有可能喜欢的商品
* @param int $channel 频道,1代表男生,2代表女生,3代表潮童,4代表创意生活
* @param $uid 用户ID
* @param $udid 设备ID
* @param $rec_pos 位置码
* @param $limit 数量限制
* @return array 接口返回的数据
* */
const lessRecommend = (channelNum, uid, udid, recPos, limit) => {
let param = {
method: 'app.search.newLast7day',
yh_channel: channelNum,
udid: udid,
rec_pos: recPos,
limit: limit
};
if (uid) {
param.uid = uid;
}
return api.get('', param);
};
module.exports = {
getSortByConditionAsync,
getKeyActivityAsync,
... ... @@ -443,5 +470,6 @@ module.exports = {
getShopList,
getBrands4Filter,
getProductListOrig,
getSearchCacheKey
getSearchCacheKey,
lessRecommend
};
... ...
... ... @@ -1631,6 +1631,16 @@ exports.getSearchParams = params => {
});
}
// 优惠券商品列表
if (params && params.cpc_id) {
Object.assign(nparams, {
coupon_id: params.cpc_id,
method: 'app.search.coupon'
});
}
/** 查询参数再处理 **/
// 对可能有中文的情况进行处理
if (params.query) {
... ... @@ -1676,3 +1686,5 @@ exports.handleBrandShopCoupons = (data, params) => {
return false;
};
... ...
... ... @@ -6,6 +6,10 @@
'use strict';
const utils = '../../../utils';
const api = global.yoho.API;
const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const saleApi = require('./sale-api');
const searchApi = require('./search-api');
const headerModel = require('../../../doraemon/models/header');
... ... @@ -21,11 +25,22 @@ exports.getKeyActivity = (query) => {
};
/**
* 转换价格
*
* @param float|string $price 价格
* @return float|string 转换之后的价格
*/
const transPrice = (price) => {
return price ? (price * 1).toFixed(2) : '0.00';
};
/**
* 获取搜索数据
* @param {[type]} origin [description]
* @return {[type]} [description]
*/
exports.getSearchData = (params, channel) => {
let searchParams = searchHandler.getSearchParams(params);
switch (channel) {
... ... @@ -72,7 +87,8 @@ exports.getSearchData = (params, channel) => {
});
finalResult.search = {
leftContent: searchHandler.handleSortData(result[1].data.sort, dps, params)
leftContent: searchHandler.handleSortData(result[1].data.sort, dps, params),
isSearch: true
};
}
... ... @@ -81,6 +97,7 @@ exports.getSearchData = (params, channel) => {
let filters = Object.assign(searchHandler.handleFilterDataAll(result[2].data, params),
finalResult.search.leftContent.sort);
let termsSuggestion = _.get(result[2], 'data.suggestion.terms_suggestion', []);
filters.checkedConditions.conditions = _.concat(filters.checkedConditions.conditions,
finalResult.search.leftContent.checked);
... ... @@ -96,9 +113,20 @@ exports.getSearchData = (params, channel) => {
Object.assign({showDiscount: false, from: {type: 'search', params: params}}, params)),
latestWalk: 6,
hasNextPage: searchHandler.handleNextPage(params, result[2].data.total),
shopEntry: result[3]
shopEntry: result[3],
name: params.query,
suggest: (termsSuggestion.length !== 0) ? termsSuggestion.slice(0, 3) : false,
changedQuery: result[2].data.isChangedQuery === 'Y',
suggestFirst: finalResult.search.suggestFirst,
suggestSecond: finalResult.search.suggestSecond
});
if (finalResult.search.changedQuery) {
finalResult.search.suggestFirst = finalResult.search.suggest[0];
finalResult.search.suggestSecond = _.slice(termsSuggestion, 1, termsSuggestion.length).splice(0, 3);
}
finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.search, 'goods'))};
}
return finalResult;
... ... @@ -183,5 +211,93 @@ exports.getBrands4Filter = (params) => {
});
}
// 优惠券商品列表
if (params && params.cpc_id) {
Object.assign(nparams, {
coupon_id: params.cpc_id,
method: 'app.coupon.aggBrand'
});
}
return this.getListBrandsFilter(params, nparams);
};
/**
* 搜索少或无 可能喜欢
* @param int $page 分页页码
* @return array
* */
exports.getSearchLessProduct = (channelNum, uid, udid, page) => {
return co(function * () {
let result = {
code: 200,
message: '',
data: {
header: '可能喜欢的商品',
hasPrev: false,
hasNext: false,
item: null
}
};
if (!_.isNumber(page)) {
return result;
}
let together = yield searchApi.lessRecommend(channelNum, uid, udid, '100003', 20);
if (page > 5) {
page = 1;
}
if (!_.get(together, 'data.product_list')) {
return result;
}
result.data.hasPrev = true;
result.data.hasNext = true;
result.data.item = _.map(together.data.product_list, it => {
let item = {
id: it.product_id,
skn: it.product_skn,
title: it.product_name,
img: it.default_images ? helpers.image(it.default_images, 180, 240) : '',
alt: it.product_name,
price: '¥' + transPrice(it.sales_price),
marketPrice: '¥' + transPrice(it.market_price)
};
let firstGoods = it.goods_list && it.goods_list[0];
let productSkc = firstGoods && firstGoods.product_skc;
item.href = helpers.getUrlBySkc(it.product_id, productSkc, it.cn_alphabet);
return item;
});
// 当数据量不足6个时,判定为没有下一页
if (page === 1) {
result.data.hasPrev = false;
}
if (!result.data.item || result.data.item.length < 6) {
result.data.hasNext = false;
}
return result;
})();
};
... ...
... ... @@ -85,9 +85,11 @@ router.post('/detail/notify/cancel', auth, notify.cancel); // 删é™
// 搜索
router.get('/search/index', gbk2utf, search.index);
router.get('/search/filter/brands', search.serachFilterBrands);
router.get('/search/filter/brands', search.searchFilterBrands);
router.get('/search/suggest', search.suggest); // 搜索提示
router.get('/api/suggest', search.suggest4Old);
router.get('/search/history', search.searchHistory); // 搜索历史提示
router.get('/search/less/recommend', search.searchLessRecommend);// 搜索少或无 有可能喜欢
// 商品分类列表页
router.get('/list/index', gbk2utf, list.index);
... ...
... ... @@ -21,7 +21,7 @@
</div>
{{/if}}
<div id="package" class="package-box clearfix"></div>
<div id="package" class="package-box clearfix hide"></div>
<div class="total-content">
<div class="other-infos">
... ...
<div class="product-search-page product-page yoho-page center-content">
<div class="product-search-page {{#if search.isSearch}}search-page{{/if}} product-page yoho-page center-content">
{{# search}}
{{> common/path-nav}}
{{> product/no-result}}
... ...
... ... @@ -64,8 +64,28 @@
<div class="list-left pull-left">
{{> product/left-content}}
</div>
<div class="list-right pull-right">
{{#if_cond goods.length '<' 20 }}
{{#if suggest}}
{{#unless changedQuery}}
<div class="search-suggest-less">
"<em>{{name}}</em>"&nbsp;搜索结果太少了,试试{{#suggest}}&nbsp;"<a href="/?query={{.}}">{{.}}</a>"&nbsp;{{/suggest}}关键词搜索
</div>
{{/unless}}
{{/if}}
{{/if_cond}}
{{#if changedQuery}}
<div class="search-suggest-less">
没有找到&nbsp;"<em>{{name}}</em>"&nbsp;相关的商品,
为您推荐&nbsp;"<a href="/?query={{suggestFirst}}">{{suggestFirst}}</a>"&nbsp;的搜索结果。{{#if suggestSecond}}或者试试{{#suggestSecond}}&nbsp;"<a href="/?query={{.}}">{{.}}</a>"&nbsp;{{/suggestSecond}}{{/if}}
</div>
{{/if}}
{{> list/top-coupon}}
{{# sortIntro}}
... ... @@ -88,8 +108,30 @@
{{> product/standard-content}}
{{#if @root.search.isSearch}}
{{#if_cond goods.length '<' 20 }}
<div>
<textarea class="lazy-load-object-2" style="visibility: hidden;">
<script>getSearchRecommend();</script>
</textarea>
</div>
<div class="bottom-tab-line">
<span class="bottom-title" data-type="recommend" data-role="recommend-tab">你可能喜欢</span>
</div>
<div class="goods-slide">
<div data-role="recommend-slide" class="slide-panel"></div>
</div>
{{/if_cond}}
{{/if}}
{{> product/latest-walk}}
</div>
{{/ brandAbout}}
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -26,7 +26,7 @@
<div class="pull-left">
<ul class="activity">
{{#each activity}}
<li class="promotion-item {{#if_cond @index '>' 3}}hide{{/if_cond}}">
<li class="promotion-item {{#if_cond @index '>' 2}}hide{{/if_cond}}">
<span class="ac-type">{{type}}</span>
<span class="ac-des {{#if_cond ../activity.length '>' 3}}small{{/if_cond}}">
{{#if url}}
... ...
'use strict';
const logger = global.yoho.logger;
const logger = global.yoho.logger; // eslint-disable-line
const cache = global.yoho.cache.master;
const ONE_DAY = 60 * 60 * 24;
module.exports = (limiter, policy) => {
const req = limiter.req,
res = limiter.res,
next = limiter.next;
next = limiter.next; // eslint-disable-line
const key = `pc:limiter:faker:${limiter.remoteIp}`;
... ...
... ... @@ -27,6 +27,13 @@ const CHANNEL = {
lifestyle: 'lifestyle'
};
const CHANNEL_NUM = {
boys: 1,
girls: 2,
kids: 3,
lifestyle: 4
};
module.exports = () => {
return (req, res, next) => {
let yoho = {
... ... @@ -45,6 +52,9 @@ module.exports = () => {
// 当前频道设置
yoho.channel = channel;
// 当前频道数
yoho.channelNum = CHANNEL_NUM[channel] || CHANNEL_NUM.boys;
// 当前性别
yoho.gender = _getGender(channel);
... ...
... ... @@ -10,6 +10,7 @@ const _ = require('lodash');
const api = global.yoho.API;
const serviceApi = global.yoho.ServiceAPI;
const helpers = global.yoho.helpers;
/**
* 获取菜单
... ... @@ -191,11 +192,14 @@ const setHeaderData = (resData, type) => (
);
const getHotSearchAsync = () => {
return api.get('', {method: 'app.search.getTerms'}, {
const getHotSearchAsync = (channel) => {
return api.get('', {method: 'app.search.getTerms', yh_channel: channel}, {
cache: 600,
code: 200
});
};
const getHeaderNavAsync = () => {
... ... @@ -215,9 +219,25 @@ exports.requestHeaderData = (type) => {
type = type || 'boys';
let channelNum = (function() {
switch (type) {
case 'boys':
return 1;
case 'girls':
return 2;
case 'kids':
return 3;
case 'lifestyle':
return 4;
default:
return 1;
}
}());
return Promise.all([
getHeaderNavAsync(),
getHotSearchAsync()
getHotSearchAsync(channelNum)
]).then(res => {
resData.headerData = {};
... ... @@ -227,6 +247,15 @@ exports.requestHeaderData = (type) => {
if (res[1] && res[1].data) {
resData.headerData.defaultSearch = _.get(res[1], 'data.defaultTerms[0].content', '');
resData.headerData.hotTerms = _.map(_.get(res[1], 'data.hotTerms', []), (value) => {
return {
href: helpers.urlFormat('', {query: value.content}, 'search'),
content: value.content,
sort: value.sort,
status: value.status,
type: value.type
};
});
}
return resData;
... ...
... ... @@ -16,12 +16,11 @@
{{/dnsPrefetch.hosts}}
{{#if devEnv}}
<link rel="stylesheet" href="//{{devHost}}:5002/css/index.css">
<link rel="stylesheet" href="//{{devHost}}:5002/css/cart.index.css">
<link rel="stylesheet" href="//{{devHost}}:5002/css/base.css">
<link rel="stylesheet" href="//{{devHost}}:5002/css/{{#if cssModule}}{{cssModule}}.css{{^}}{{module}}.css{{/if}}">
{{^}}
<link rel="stylesheet" href="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/index.css">
<link rel="stylesheet" href="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/cart.index.css">
<link rel="stylesheet" href="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/base.css">
<link rel="stylesheet" href="//{{#isEqual cdn 'qcloud'}}qcdn.yoho.cn{{^}}cdn.yoho.cn{{/isEqual}}/yohobuy-node/{{version}}/{{#if cssModule}}{{cssModule}}.css{{^}}{{module}}.css{{/if}}">
{{/if}}
</head>
<body>
... ...
... ... @@ -93,13 +93,25 @@
{{#unless @root.pc.common.disSearchAssociation}}
<ul class="search-suggest"></ul>
{{/unless}}
<ul class="search-suggest-history"></ul>
<div class="search-2016">
<form action="//search.yohobuy.com" method="get" id="search-form">
<input type="hidden" id="defaultsearch" value="{{defaultSearch}}">
<input class="search-key" type="text" name="query" id="query-key" autocomplete="off" x-webkit-speech="" lang="zh-CN" x-webkit-grammar="builtin:translate" value="" maxlength="30">
<a class="search-btn" href="javascript:submitSearch();"></a>
</form>
<ul class="search-hot">
{{#hotTerms}}
<li>
<a style="display: block;" href="{{href}}" title="{{content}}"
act="{{href}}" target="_blank">
<span class="searchvalue">{{content}}</span>
</a>
</li>
{{/hotTerms}}
</ul>
</div>
<div class="go-cart">
<a href="//www.yohobuy.com/cart/cart">
<span class="iconfont ">&#xe600;</span>
... ... @@ -235,6 +247,18 @@
</li>
\{{/data}}
</script>
<script type="text/html" id="search-suggest-history">
\{{#if data}}<p class="search-suggest-title">最近搜过<a class="searchDel" href="#">清空</a></p>
\{{#data}}
<li>
<a style="display: block;" href="\{{href}}" class="clearfix clear search-item" title="\{{keyword}}"
act="\{{href}}">
<span class="searchvalue">\{{keyword}}</span>
</a>
</li>
\{{/data}}
\{{/if}}
</script>
</div>
<input id="api-domain" type="hidden" value="{{apiDomain}}">
... ...
{{> goood-slide-tpl}}
<div class="lazy-load-object">
<textarea class="latest-walk-datalazyload" style="visibility: hidden;">
<script> fetchLatestWalk(); </script>
</textarea>
</div>
... ...
<div class="individual-slide">
<ul class="goods clearfix img-list">
{{#each item}}
<li class="good img-item" data-id="id" data-skn="skn">
<a href="{{href}}" target="_blank">
<img class="lazy" data-original="{{img}}"/>
</a>
<a class="name" href="{{href}}" target="_blank">{{title}}</a>
<p class="price">
<span class="sale-price {{#if marketPrice}}sale-price-new{{/if}}">{{price}}</span>
{{#if marketPrice}}
<span class="market-price">{{marketPrice}}</span>
{{/if}}
</p>
</li>
{{/each}}
</ul>
<div class="img-brand-switch">
{{#hasPrev}}
<a class="prev iconfont" href="javascript:;"></a>
{{/hasPrev}}
{{#hasNext}}
<a class="next iconfont" href="javascript:;"></a>
{{/hasNext}}
</div>
</div>
\ No newline at end of file
... ...
<div class="no-result">
<div class="no-result-icon">
<i class="iconfont icon-noResult"></i>
</div>
<p class="no-title">
抱歉!没有找到{{#if keyWord}}与"<b class="keyword">{{keyWord}}</b>"{{/if}}相关的商品
抱歉!未找到{{#if keyWord}}与"<b class="keyword">{{keyWord}}</b>"{{/if}}相关商品
</p>
<div class="search-again clearfix">
<form method="GET" action="{{searchActionUrl}}">
... ... @@ -12,3 +15,18 @@
</div>
<p class="no-tip">建议您:看看输入的文字是否有误 / 减少分类条件限制 / 重新搜索</p>
</div>
{{#if isSearch}}<div class="center-content clearfix">
<div class="bottom-tab-line">
<span class="bottom-title" data-type="recommend" data-role="recommend-tab">你可能喜欢</span>
</div>
<div class="goods-slide">
<div data-role="recommend-slide" class="slide-panel"></div>
</div>
<div>
<textarea class="lazy-load-object-2" style="visibility: hidden;">
<script>getSearchRecommend();</script>
</textarea>
</div>
</div>{{/if}}
\ No newline at end of file
... ...
... ... @@ -5,7 +5,7 @@
{{#if phrase}}
<div class="phrase">
以下商品参加 {{phrase}}
{{phrase}}
</div>
{{/if}}
... ...
... ... @@ -8,7 +8,7 @@
</div>
{{^}}
<!-- 购物车商品列表 -->
<div class="pay-wapper">
<div class="pay-wapper" data-role="order-cart">
<div class="cart-title">
<p class="left" style="width:6%;">
<i class="cart-item-check-title cart-item-check iconfont"></i>&nbsp;&nbsp;全选
... ... @@ -21,9 +21,10 @@
</div>
{{#advanceCart}}
<div class="mb40" data-role="advance">
<div class="mb20" data-role="advance">
<!-- 预售商品 -->
<div class="pre-sell">
<div class="pre-sell pre-sell-title">
<i class="cart-item-check iconfont {{#isChecked}}cart-item-checked{{/isChecked}}" data-role="cart-item-check"></i>
<code>预售商品</code>预售商品不参加活动,不可使用优惠券,不同上市期的商品我们将为您先到先发。
</div>
... ... @@ -73,6 +74,12 @@
{{#ordinaryCart}}
<div data-role="ordinary">
<!-- 普通商品 -->
<div class="pre-sell ord-sell-title">
<i class="cart-item-check iconfont {{#isChecked}}cart-item-checked{{/isChecked}}" data-role="cart-item-check"></i>
<code>普通商品</code> {{tips}}
</div>
{{#pools}}
<div class="promotion-pool {{#unless @first}}mt20{{/unless}}" data-role="promotion-pool">
{{#if promotionInfos}}
... ...
... ... @@ -16,7 +16,8 @@
"lint-css": "stylelint --config .stylelintrc public/scss/**/*.css",
"precommit": "node lint.js",
"test": "NODE_ENV=test nyc ./node_modules/.bin/ava",
"posttest": "nyc report --reporter=html"
"posttest": "nyc report --reporter=html",
"prod": "git pull && gulp --cwd=public ge && pm2 reload yohobuy-node"
},
"ava": {
"tap": true,
... ... @@ -78,6 +79,7 @@
"gulp-cssnano": "^2.1.2",
"gulp-ftp": "^1.1.0",
"gulp-postcss": "^6.1.0",
"gulp-rename": "^1.2.2",
"gulp-sourcemaps": "^2.0.0-alpha",
"gulp-util": "^3.0.7",
"handlebars-loader": "^1.4.0",
... ...
No preview for this file type
... ... @@ -2,7 +2,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>
Created by FontForge 20120731 at Thu Feb 16 19:45:08 2017
Created by FontForge 20120731 at Mon Mar 6 13:49:44 2017
By admin
</metadata>
<defs>
... ... @@ -343,5 +343,8 @@ d="M512 446l-196 -202l-39 39l196 202l39 39l39 -39l196 -202l-39 -39z" />
d="M512 306l-196 201l-39 -45l235 -235l235 235l-39 45z" />
<glyph glyph-name="weibiaoti-5" unicode="&#xe6f2;"
d="M512 384zM32 384q0 -130 64.5 -240.5t175 -175t240.5 -64.5t240.5 64.5t175 175t64.5 240.5t-64.5 240.5t-175 175t-240.5 64.5t-240.5 -64.5t-175 -175t-64.5 -240.5z" />
<glyph glyph-name="weibiaoti-7" unicode="&#xe6f9;"
d="M1017 -106l-278 278q55 58 85.5 133t30.5 158q0 115 -57 212.5t-154.5 154.5t-212 57t-212 -57t-154 -154.5t-56.5 -212.5t56.5 -212.5t154 -154t212.5 -56.5q83 0 158 30.5t133 85.5l279 -279zM432 62q-109 0 -201 54t-146 146t-54 201t54 201.5t146 146t201 53.5
t201.5 -53.5t146 -146t53.5 -201.5t-53.5 -201t-146 -146t-201.5 -54z" />
</font>
</defs></svg>
... ...
No preview for this file type
No preview for this file type
... ... @@ -6,13 +6,17 @@
'use strict';
const path = require('path');
const gulp = require('gulp');
const _ = require('lodash');
const gutil = require('gulp-util');
const ftp = require('gulp-ftp');
const postcss = require('gulp-postcss');
const sourcemaps = require('gulp-sourcemaps');
const cssnano = require('gulp-cssnano');
const rename = require('gulp-rename');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
... ... @@ -48,9 +52,8 @@ const postcssPlugin = (et) => {
padding: 2
},
groupBy(file) {
var group = file.url.split('/')[1];
group = group === '' ? 'yo' : group;
var dir = _.last(path.parse(file.styleFilePath).dir.split(path.sep));
var group = dir === 'scss' ? path.basename(file.styleFilePath, '.css') : dir;
return group ? Promise.resolve(group) : Promise.reject(group);
}
... ... @@ -125,13 +128,21 @@ gulp.task('dist', ['ge'], () => {
// postcss compile in dev
gulp.task('postcss-dev', () => {
return gulp.src(['scss/index.css', 'scss/cart.index.css'])
return gulp.src(['scss/base.css', 'scss/*/_index.css', '!scss/plugin/*', '!scss/common/*'])
.pipe(sourcemaps.init())
.pipe(postcss(postcssPlugin(env.dev)))
.on('error', function(err) {
gutil.log(err);
this.emit('end');
})
.pipe(rename((cssPath) => {
if (cssPath.dirname === '.') {
return;
}
cssPath.basename = `${cssPath.dirname}`;
cssPath.dirname = './';
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('css/'));
});
... ... @@ -158,9 +169,17 @@ gulp.task('font', () => {
// postcss compile in pro
gulp.task('postcss', ['assets'], () => {
return gulp.src(['scss/index.css', 'scss/cart.index.css'])
return gulp.src(['scss/base.css', 'scss/*/_index.css', '!scss/plugin/*', '!scss/common/*'])
.pipe(postcss(postcssPlugin(env.pro)))
.pipe(cssnano())
.pipe(cssnano({zindex: false }))
.pipe(rename((cssPath) => {
if (cssPath.dirname === '.') {
return;
}
cssPath.basename = `${cssPath.dirname}`;
cssPath.dirname = './';
}))
.pipe(gulp.dest(dist.css));
});
... ...
<header>申请退款</header>
<p class="tip">您取消订单的原因是:</p>
<ul class="cancel-reason clearfix">
{{# refundReason}}
<li {{#if @last}}style="width:100%;"{{/if}}>
<input id="cancel-radio-{{id}}" type="radio" name="cancel-reason" value="{{id}}">
<label for="cancel-radio-{{id}}">{{reason}}</label>
{{#if @last}}<input type="text" id="reason_other" placeholder="50字以内" maxlength="50">{{/if}}
</li>
{{/refundReason}}
</ul>
<p class="tip reminder">温馨提示:</p>
<ul class="info-prompt">
<li><i>*</i>申请退款后,本单享有的优惠可能会一并取消。</li>
<li><i>*</i>该订单已付金额将原路返回,请您耐心等待。</li>
</ul>
<p class="cancel-tip"></p>
... ...
<div class="goods-slide-item">
<ul class="goods clearfix img-list">
{{#each item}}
<li class="good img-item" data-id="id" data-skn="skn">
<a href="{{href}}" target="_blank" class="good-img">
<img class="lazy" data-original="{{img}}"/>
</a>
<a class="name" href="{{href}}" target="_blank">{{title}}</a>
<p class="price">
<span class="sale-price {{#if marketPrice}}sale-price-new{{/if}}">{{price}}</span>
{{#if marketPrice}}<span class="market-price">{{marketPrice}}</span>{{/if}}
</p>
</li>
{{/each}}
</ul>
<div class="img-brand-switch">
{{#hasPrev}}
<a class="prev iconfont" href="javascript:;"></a>
{{/hasPrev}}
{{#hasNext}}
<a class="next iconfont" href="javascript:;"></a>
{{/hasNext}}
</div>
</div>
... ...
<div class="pkgDg-header">
<p class="left">优惠套装</p>
<p class="left">{{name}}</p>
<span class="pkg-close close right"><i class="iconfont"></i></span>
</div>
<div class="pkgDg-prodetal">
{{#packageData}}
<div class="pkg-product clearfix">
<a href="{{url}}" class="pkg-proImg"><img src="{{image2 src w=85 h=109}}" class="pro-img"/></a>
<div class="pkgDg-prodetal" data-index="{{index}}">
{{#productList}}
<div class="pkg-product clearfix" data-id="{{id}}" >
<a href="{{url}}" class="pkg-proImg">
<img src="{{image2 src w=85 h=109}}" class="pro-img"/>
</a>
<div class="type-chose">
<div class="chose-color row clearfix">
<span class="title pull-left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;色:</span>
... ... @@ -41,11 +44,12 @@
</div>
</div>
</div>
{{/packageData}}
{{/productList}}
</div>
<div class="pkgDg-footer clearfix">
<p class="totalMoney left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;计:<em>{{pkgPrice}}</em></p>
<span id="pay-pkg" class="buy-product red-color right">
<span class="pay-pkg buy-product red-color right" data-bundleid="{{bundleId}}">
<em>立即购买</em>
</span>
</div>
... ...
<div class="title-header">优惠套装</div>
<div id="package-pro" class="package-pro clearfix" data-bundleid="{{bundleId}}">
{{#packageData}}
<div class="good-info" data-skn="{{skn}}">
<div class="good-detail-img">
<a class="good-thumb" href="{{url}}" target="_blank">
<img class="lazy" src="{{image src 100 135}}" style="display: block;">
</a>
</div>
<div class="good-detail-text stu-good-detail ">
<a href="{{url}}" target="_blank">{{productName}}</a>
<p class="price ">
<span class="sale-price red-color">
{{productPrice}}
</span>
</p>
<div class="title-header">
{{# packageList}}
<span class="{{#if_cond @index '==' 0}}active{{/if_cond}}" data-index="{{index}}">{{name}}</span>
{{/packageList}}
</div>
<div class="package-list">
{{# packageList}}
<div class="package-pro clearfix {{#if_cond @index '>=' 1}}hide{{/if_cond}}"
data-bundleid="{{bundleId}}"
data-index="{{index}}">
{{#productList}}
<div class="good-info" data-skn="{{skn}}" data-id="{{id}}">
<div class="good-detail-img">
<a class="good-thumb" href="{{url}}" target="_blank">
<img class="lazy" src="{{image src 100 135}}" style="display: block;">
</a>
</div>
<div class="good-detail-text stu-good-detail ">
<a href="{{url}}" target="_blank">{{productName}}</a>
<p class="price ">
<span class="sale-price red-color">
{{productPrice}}
</span>
</p>
</div>
</div>
<div class="spliter">
{{#if @last}}={{/if}}{{#unless @last}}+{{/unless}}
</div>
{{/productList}}
<div class="package-priceList">
<p>销售价:<em class="sale-price">{{salesPrice}}</em></p>
<p>套餐价:<em class="package-price red-color">{{pkgPrice}}</em></p>
{{#if saveFlag}}<p class="save-text red-color">立省<em class="save-price">{{savePrice}}</em></p>{{/if}}
<span id="buy-detail" class="buy-product red-color">
<em>立即购买</em>
</span>
</div>
</div>
<div class="spliter">{{#if @last}}={{/if}}{{#unless @last}}+{{/unless}}</div>
{{/packageData}}
<div class="package-priceList">
<p>销售价:<em class="sale-price">{{salesPrice}}</em></p>
<p>套餐价:<em class="package-price red-color">{{pkgPrice}}</em></p>
{{#if saveFlag}}<p class="save-text red-color">立省<em class="save-price">{{savePrice}}</em></p>{{/if}}
<span id="buy-detail" class="buy-product red-color">
<em>立即购买</em>
</span>
</div>
{{/packageList}}
</div>
... ...

42.6 KB | W: 0px | H: 0px

43.1 KB | W: 0px | H: 0px

  • 2-up
  • Swipe
  • Onion skin

1.91 KB | W: | H:

4.41 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
... ... @@ -55,6 +55,44 @@ function submitPoint(type) {
yas.givePoint('YB_SC_TOBUY_CLICK', {PRD_ID: productId.join(',')});
}
function toggleAll(obj, roleType) {
var $this = obj;
var selected;
var selectArray = [];
var $noStores = $cartListWrap.find('[data-role=' + roleType + '] [data-role=cart-item-check][data-tipnostore]');
$this.toggleClass('cart-item-checked');
selected = $this.hasClass('cart-item-checked') ? 'Y' : 'N';
$cartListWrap.find('[data-role=' + roleType + '] li[data-role=pitem]').each(function() {
var $t = $(this);
if ($t.data('id')) {
selectArray.push({
product_sku: $t.data('id'),
selected: selected,
buy_number: $t.data('productnum'),
goods_type: $t.data('goodstype'),
promotion_id: $t.data('promotionid') || 0
});
}
});
if (selected === 'Y' && $noStores && $noStores.length > 0) { // 无库存提示
$('html,body').animate({scrollTop: $noStores.eq(0).offset().top - 50 + 'px'}, 500);
$noStores.each(function() {
toastNoStore($(this).closest('li[data-role=pitem]'), '您全选的商品中存在库存不足商品,已帮您自动取消勾选');
});
setTimeout(function() {
capi.choiceOut(selectArray);
}, 2000);
} else {
capi.choiceOut(selectArray);
}
}
Cart = {
toggleSelectOne: function() { // 单选
... ... @@ -80,44 +118,15 @@ Cart = {
return capi.choiceOut(item);
},
toggleSelectAll: function() { // 全选
var $this = $(this);
var selected;
var selectArray = [];
var $noStores = $cartListWrap.find('[data-role=cart-item-check][data-tipnostore]');
$this.toggleClass('cart-item-checked');
selected = $this.hasClass('cart-item-checked') ? 'Y' : 'N';
$cartListWrap.find('li[data-role=pitem]').each(function() {
var $t = $(this);
if ($t.data('id')) {
selectArray.push({
product_sku: $t.data('id'),
selected: selected,
buy_number: $t.data('productnum'),
goods_type: $t.data('goodstype'),
promotion_id: $t.data('promotionid') || 0
});
}
});
if (selected === 'Y' && $noStores && $noStores.length > 0) { // 无库存提示
$('html,body').animate({scrollTop: $noStores.eq(0).offset().top - 50 + 'px'}, 500);
$noStores.each(function() {
toastNoStore($(this).closest('li[data-role=pitem]'), '您全选的商品中存在库存不足商品,已帮您自动取消勾选');
});
setTimeout(function() {
capi.choiceOut(selectArray);
}, 2000);
} else {
capi.choiceOut(selectArray);
}
toggleSelectAll: function() { // 全部
toggleAll($(this), 'order-cart');
},
togglePreAll: function() { // 预售全选
toggleAll($(this), 'advance');
},
toggleOrdAll: function() { // 普通全选
toggleAll($(this), 'ordinary');
},
del: function() {
... ... @@ -395,6 +404,8 @@ $cartListWrap.on('click', '[data-role=cart-mov2fav-btn]', Cart.toFav); // 移
$cartListWrap.on('click', '.minus, .plus', Cart.modNum); // 修改购物车数量
$cartListWrap.on('click', '.cart-title .cart-item-check', Cart.toggleSelectAll); // 全选
$cartListWrap.on('click', '.cartnew-sum .cart-item-check', Cart.toggleSelectAll); // 全选
$cartListWrap.on('click', '.pre-sell-title .cart-item-check', Cart.togglePreAll); // 预售全选
$cartListWrap.on('click', '.ord-sell-title .cart-item-check', Cart.toggleOrdAll); // 预售全选
$cartListWrap.on('click', '.cartnew-sum .delete-all-sel', Cart.delAll); // 批量删除商品
$cartListWrap.on('click', '.cartnew-sum .remove-all-2fav', Cart.toFavAll); // 批量移入收藏夹商品
$cartListWrap.on('click', '.cartnew-sum .clean-all-disable', Cart.cleanAllDisable);
... ...
... ... @@ -35,6 +35,47 @@ function isCheckAll() {
}
}
// 预售商品是否全选
function isPreCheckAll() {
var isAllCheck = true;
$('[data-role=advance] [data-role=pitem] [data-role=cart-item-check]').each(function() {
var $chk = $(this);
// 有一个没选中,跳出循环
if (!$(this).hasClass('cart-item-checked') && !$chk.data('tipnostore')) {
isAllCheck = false;
return false;
}
});
if (isAllCheck) {
// 头部全选
$('.pre-sell-title .cart-item-check').addClass('cart-item-checked');
}
}
// 普通商品是否全选
function isOrdCheckAll() {
var isAllCheck = true;
$('[data-role=ordinary] [data-role=pitem] [data-role=cart-item-check]').each(function() {
var $chk = $(this);
// 有一个没选中,跳出循环
if (!$(this).hasClass('cart-item-checked') && !$chk.data('tipnostore')) {
isAllCheck = false;
return false;
}
});
if (isAllCheck) {
$('.ord-sell-title .cart-item-check').addClass('cart-item-checked');
}
}
// 判断商品是否已收藏,是否全选
function isCheckFav() {
var pidArray = [];
... ... @@ -86,6 +127,8 @@ function cartInit() {
});
isCheckAll();
isPreCheckAll();
isOrdCheckAll();
isCheckFav();
}
... ...
/**
* 订单结算页
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/8/29
*/
var $ = require('yoho-jquery');
var Hbs = require('yoho-handlebars');
var $pdStatus = $('.pd-status');
var $pdUsed = $('#pay-delivery-used');
var $balance = $('#balance-detail');
var couponsTpl = Hbs.compile($('#coupons-tpl').html());
var coinTpl = Hbs.compile($('#yoho-coin-tpl').html());
var promotionTpl = Hbs.compile($('#promotion-list-tpl').html());
var $coin = $('#coin-used');
var $coinSure = $('#coin-sure');
var queryInfo;
var pkgCache = {};
var $pkgList;
var invoice = require('./order/invoice');
require('./order/address');
require('../common');
queryInfo = window.queryString();
// FE Helper
Hbs.registerHelper('isEqual', function(v1, v2, options) {
if (v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
// 支付及送货时间编辑/展示状态切换
function togglePdStatus() {
$pdStatus.toggleClass('hide');
$('#pay-delivery-used, #pay-delivery-choice').toggleClass('hide');
}
// 更新使用的支付及送货时间
function updateUsedPdShow(info) {
$('#payment-way', $pdUsed).data({
id: info.paymentTypeId,
type: info.paymentType
}).text(info.paymentTypeName);
$('#delivery-time', $pdUsed).data('id', info.deliveryTimeId).text(info.deliveryTimeStr);
$('#contract-me', $pdUsed).text(info.contractMe);
}
// 订单计算
// 传有货币数量则使用有货币,否者不使用,更改订单总价有货币使用数量重置为0
function compute(coin) {
var d = {
cartType: window.queryString().type,
deliveryWay: $('input[name="delivery-way-radio"]:checked').val(),
paymentType: $('#payment-way').data('id'),
coin: coin ? parseInt(coin, 10) : 0
};
var couponCode = $('#coupons-sure').data('coupons');
$coin.data('coin', d.coin);
if (couponCode) {
d.couponCode = couponCode;
}
if (queryInfo) {
if (queryInfo.sku) {
d.sku = queryInfo.sku;
}
if (queryInfo.skn) {
d.skn = queryInfo.skn;
}
if (queryInfo.limitcode) {
d.limitcode = queryInfo.limitcode;
}
if (queryInfo.bundle) {
d.bundle = queryInfo.bundle;
}
}
$.ajax({
type: 'POST',
url: '/cart/easypay/compute',
data: d
}).then(function(data) {
var res;
if (data.code === 200) {
res = data.data;
// update yoho coin max use num
$coin.data('max', res.canUseCoinNum);
// update yoho coin using
$('#using-coin-cont').html(coinTpl(res));
// update last order amount
$('#sum-row em').html(res.last_order_amount);
// update promotion formula list
$('.promotion-item', $balance).remove();
$('.gain-coin', $balance).after(promotionTpl(res));
}
});
}
$('.pd-status').click(togglePdStatus);
$('#pay-delivery-sure').click(function() {
var $dt = $('.delivery-time input:checked');
var $dw = $('.payment-type input:checked');
updateUsedPdShow({
paymentTypeId: $dw.data('id'),
paymentTypeName: $dw.data('name'),
paymentType: $dw.data('type'),
deliveryTimeId: $dt.data('id'),
deliveryTimeStr: $dt.data('name'),
contractMe: $('.contract-me input:checked').val() === '1' ? '是' : '否'
});
togglePdStatus();
});
// 备注信息
$('#remark-btn').click(function() {
var $this = $(this);
$this.toggleClass('shrink');
$this.siblings('.remark-content').toggleClass('hide');
});
if ($('#use-coupons').length) {
// 优惠券
$.ajax({
type: 'GET',
url: '/cart/coupon/list'
}).then(function(data) {
if (data.code === 200) {
$('#coupon-list').prepend(couponsTpl({
coupons: data.data
}));
}
});
$('#use-coupons, #coupons-sure, #coupons-cancel').click(function() {
$('.coupons-trigger').toggleClass('hide');
});
// 使用优惠券
$('#coupons-sure').click(function() {
var coupons = $('input[name="coupons"]:checked').data('code');
if (!coupons) {
coupons = $('#coupon-code').val(); // 手动输入优惠券码
}
$(this).data('coupons', coupons);
// coupons code change trigger compute
compute();
});
}
// 有货币
if ($coin) {
$coin.data($coin.data()); // 防止人为页面更改有货币使用数量
}
$('#use-coin, #coin-sure, #coin-cancel').click(function() {
$('.coin-trigger').toggleClass('hide');
});
$coinSure.click(function() {
var data = $coin.data();
if ($coinSure.hasClass('disable') ||
data.coin === data.max) {
return;
}
// coin change trigger compute
compute(data.max);
});
$('#coin-cancel').click(function() {
var data = $coin.data();
if (data.coin * 1 === 0) {
return;
}
// coin cancel trigger compute
compute();
});
// 结算信息列表中修改有货币按钮
$('.balance-detail').on('click', '.modify-coin', function() {
$('#use-coin').trigger('click');
});
// delivery way change trigger compute
$('input[name="delivery-way-radio"]').change(function() {
compute();
});
// 去支付
$('#go-pay').click(function() {
var coinUsed = $coin.data('coin');
var $paymentWay = $('#payment-way');
var d = {
cartType: window.queryString().type,
addressId: $('#address-used').data('id'),
deliveryTime: $('#delivery-time').data('id'),
deliveryWay: $('input[name="delivery-way-radio"]:checked').val(),
paymentType: $paymentWay.data('type'),
paymentId: $paymentWay.data('id'),
coin: coinUsed ? parseInt(coinUsed, 10) : 0,
printPrice: $('input[name="print-price"]:checked').val()
};
var couponCode = $('#coupons-sure').data('coupons');
var remark = $.trim($('#remark').val());
var invoiceInfo = invoice.getInvoice();
if (couponCode) {
d.couponCode = couponCode;
}
// 备注
if (remark) {
d.remark = remark;
}
// 发票信息
if (invoiceInfo) {
$.extend(d, invoiceInfo);
}
if (queryInfo) {
if (queryInfo.sku) {
d.sku = queryInfo.sku;
}
if (queryInfo.skn) {
d.skn = queryInfo.skn;
}
if (queryInfo.limitcode) {
d.limitcode = queryInfo.limitcode;
}
if (queryInfo.bundle) {
d.bundle = queryInfo.bundle;
}
}
$.ajax({
type: 'POST',
url: '/cart/easypay/submit',
data: d
}).then(function(data) {
if (data.code === 200) {
location.href = data.data.url;
}
});
});
// 查看支持的在线支付的银行和平台
$('.check-banks').click(function() {
$(this).toggleClass('shrink');
$('.supports').toggleClass('hide');
});
// 拆单
function pkgPageControl($el, flag) {
var id = $el.index(),
$ul = $el.find('.package-goods'),
theCache = pkgCache[id],
curPage = theCache.cur ? theCache.cur : 1,
page = Math.ceil(theCache.total / 5);
curPage += flag;
// 第一页或最后一页
if (curPage < 1 || curPage > page) {
return;
}
$ul.animate({
marginLeft: -(curPage - 1) * $ul.parent('.package-goods-wrap').width()
}, 200);
theCache.cur = curPage;
}
// JIT拆单
if ($('.multi-package-row').length > 0) {
$pkgList = $('.package-list');
// 显示拆单详情面板
$('.show-package').click(function(e) {
$pkgList.toggleClass('hide');
e.stopPropagation();
});
// 绑定document事件,去触发面板关闭
$(document).on('click', function(e) {
if ($pkgList.hasClass('hide') || $(e.target).closest('.package-list').length > 0) {
return;
}
$pkgList.addClass('hide');
});
// 设置左右切换
$('.package-goods').each(function() {
$(this).width($(this).children('li').length * 120);
});
// 初始化cache
$('.package-item').each(function() {
pkgCache[$(this).index()] = {
total: $(this).find('li').length
};
});
$('.package-list').on('click', '.toggle-icon', function() {
var $this = $(this);
var flag = $this.hasClass('left-icon') ? -1 : 1;
pkgPageControl($this.closest('.package-item'), flag);
});
}
... ... @@ -24,11 +24,14 @@ var payWay,
yohoCoin;
var address = require('./order-new/address'),
invoice = require('./order-new/invoice');
invoice = require('./order-new/invoice'),
esaypayInfo = require('./order-new/easypay');
var coinTpl = Hbs.compile($('#yoho-coin-tpl').html());
var promotionTpl = Hbs.compile($('#promotion-list-tpl').html());
$.extend(order, esaypayInfo);
$('#hide-count-data').remove();
require('../common');
... ... @@ -93,6 +96,24 @@ function compute(coin, cb) {
reqData.redEnvelopes = order.redEnvelopes;
}
if (esaypayInfo) {
if (order.sku) {
reqData.sku = order.sku;
}
if (order.skn) {
reqData.skn = order.skn;
}
if (order.limitcode) {
reqData.limitcode = order.limitcode;
}
if (order.bundle) {
reqData.bundle = order.bundle;
}
}
$.ajax({
type: 'POST',
url: '/cart/ensure/compute',
... ... @@ -408,6 +429,7 @@ multiPackage = {
this.$el.on('click', '.show-package', function(e) {
that.$pkgList.toggleClass('hide');
$(this).toggleClass('on');
e.stopPropagation();
}).on('click', '.toggle-icon', function() {
... ... @@ -423,7 +445,7 @@ multiPackage = {
return;
}
that.$pkgList.addClass('hide');
that.$pkgList.addClass('hide').prev().removeClass('on');
});
},
pkgPageControl: function($el, flag) {
... ...
/**
* 简易结算页特殊数据
* @author: yyq<yanqing.yang@yoho.cn>
* @date: 2017/3/2
*/
var $ = require('yoho-jquery');
var queryInfo = {},
qs;
require('../../common');
if ($('.order-easypay-page').length) {
qs = window.queryString();
if (qs.sku && qs.skn && qs.limitcode) { // sku,skn,limitcode 同时存在时为限定商品
queryInfo = {
sku: qs.sku,
skn: qs.skn,
limitcode: qs.limitcode
};
} else if (qs.sku && qs.bundle) { // sku,bundle 同时存在时为套餐商品
queryInfo = {
sku: qs.sku,
bundle: qs.bundle
};
}
// 移除返回购物车
$('#go-cart-btn').click(function(e) {
// 阻止事件冒泡
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancelBubble = true;
}
window.history.go(-1);
});
}
module.exports = queryInfo;
... ...
/**
* 订单确认页地址
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/8/30
*/
var $ = require('yoho-jquery');
var hbs = require('yoho-handlebars');
var dialog = require('../../common/dialog');
var Confirm = dialog.Confirm;
var Alert = dialog.Alert;
var addressListTpl = hbs.compile($('#address-list-tpl').html());
var $addressUsed = $('#address-used');
var $addressList = $('#address-list');
var $addressStatus = $('.address-status');
var $addressForm = $('#address-form');
var provinceLoaded;
function addAddressToPage(data) {
if (!this.$useNew) {
this.$useNew = $addressList.find('.use-new-address');
}
this.$useNew.before(addressListTpl({
address: data
}));
}
// init address list
$.ajax({
type: 'GET',
url: '/cart/address/list'
}).then(function(data) {
if (data.code === 200) {
addAddressToPage(data.data);
}
});
// address validate
function validateAddress($el) {
var regx = {
name: /^[\u4e00-\u9fa5]{2,5}$/,
areacode: /^[0-9]{6}$/,
mobile: /^\d{3}(\d{4}|\*{4})\d{4}$/,
telcode: /^[0-9]{3,5}$/,
tel: /^[0-9]{1,6}(\d{4}|\*{4})$/,
email: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
zipcode: /^[0-9]{6}$/
};
var values = {
name: $.trim($('.editor-consignee', $el).val()),
area: $('.editor-area', $el).val(),
address: $.trim($('.editor-address', $el).val()),
mobile: $.trim($('.editor-mobile', $el).val()),
telcode: $.trim($('.editor-phonecode', $el).val()),
tel: $.trim($('.editor-phone', $el).val()),
email: $.trim($('.editor-email', $el).val()),
zipcode: $.trim($('.editor-zipcode', $el).val())
};
if (!regx.name.test(values.name)) {
new Alert('真实姓名至少2个中文,最多5个中文').show();
return;
}
if (!regx.areacode.test(values.area) || values.address === '') {
new Alert('您输入的地址格式不正确').show();
return;
}
if (!regx.mobile.test(values.mobile)) {
new Alert('您输入的手机号码格式不正确').show();
return;
}
if ((values.telcode !== '' || values.tel !== '') &&
(!regx.telcode.test(values.telcode) || !regx.tel.test(values.tel))) {
new Alert('您输入的电话格式不正确').show();
return;
}
if (values.email && !regx.email.test(values.email)) {
new Alert('您输入的邮箱格式不正确').show();
return;
}
if (values.zipcode && !regx.zipcode.test(values.zipcode)) {
new Alert('您输入的邮编格式不正确').show();
return;
}
return true;
}
/**
* 获取地区列表
* @param id [Number] id
* @param select [Number] 初始化选择项
* @param subselect [Number] 子集初始化选中
*/
function getAreaList(id, select, subselect) {
if (id === 0 && provinceLoaded) {
return;
}
$.ajax({
type: 'GET',
url: '/cart/address/area',
data: {
id: id
}
}).then(function(data) {
var emptyfix = '省份',
domfix = 'province';
var idString;
var html,
res,
i;
if (id === 0) {
provinceLoaded = true;
}
if (id !== 0 && !id) {
return;
}
idString = id.toString();
if (idString.length === 2) {
emptyfix = '城市';
domfix = 'city';
} else if (idString.length === 4) {
emptyfix = '区县';
domfix = 'area';
}
if (data.code === 200) {
html = '<option value="0">请选择' + emptyfix + '</option>';
res = data.data;
for (i = 0; i < res.length; i++) {
html += '<option value="' + res[i].id + '">' +
(res[i].is_support_express === 'Y' ? '*' : '') + res[i].caption + '</option>';
}
$('#editor-' + domfix).html(html).val(select ? select : select = 0);
if (subselect) {
getAreaList(select, subselect);
}
}
});
}
$('#editor-province, #editor-city').change(function() {
// 变化后自动加载下级数据
getAreaList($(this).val());
if ($(this).hasClass('editor-province')) {
$('#editor-area').html('<option value="0">请选择区县</option>');
}
});
// init area select
getAreaList(0);
function toggleStatus() {
$addressStatus.toggleClass('hide');
$('#address-editor-wrap, #address-used').toggleClass('hide');
// 如果是放弃修改,隐藏掉编辑的form
if ($('#abort-address-modify').hasClass('hide')) {
$addressForm.addClass('hide');
}
}
/**
* 初始化地址信息
* @param area 6位地址码
*/
function initArea(area) {
var province,
city;
area = area.toString();
province = area.substring(0, 2);
city = area.substring(0, 4);
$('#editor-province').val(province);
getAreaList(province, city, area);
}
/**
* 新建/编辑地址信息
* @param option [object] 需要绑定的信息,新建则为undefined
*/
function newEdit(option) {
var prop;
$addressForm.removeClass('hide');
if (option) {
for (prop in option) {
if (option.hasOwnProperty(prop)) {
if (prop === 'area') {
// 地址选择初始化
initArea(option[prop]);
} else {
$addressForm.find('.editor-' + prop).val(option[prop]);
}
}
}
} else {
$addressForm.find('.editor').val('');
$('#editor-province').val(0);
getAreaList(0);
}
}
function resetNewEdit() {
$addressForm.addClass('hide');
}
/**
* 切换地址选中状态
* @param $item [jquery object] $address-item
*/
function foucsAddress($item) {
$item.siblings('.focus').removeClass('focus').find('input[type="radio"]').prop('checked', false);
$item.addClass('focus').find('input[type="radio"]').prop('checked', true);
}
/**
* 格式化地址数据
* @param $item [Jquery Obecjt] addres-item
*/
function buildAddressData($item) {
var phone = $item.data('phone');
var code = '';
var phoneWithoutCode = '';
if (typeof phone !== 'undefined') {
if (phone.indexOf('-') > -1) {
code = phone.split('-')[0];
phoneWithoutCode = phone.split('-')[1];
} else {
code = '';
phoneWithoutCode = phone;
}
}
return {
consignee: $item.data('consignee'),
address: $item.data('address'),
area: $item.data('area'),
mobile: $item.data('mobile'),
phonecode: code,
phone: phoneWithoutCode,
email: $item.data('email'),
zipcode: $item.data('zipcode')
};
}
/**
* 获取当前focus的地址id.For:地址编辑、删除、新建
* @return id [String]
*/
function getCurAddressId() {
return $addressList.find('.focus').data('id');
}
// 地址修改/不保存关闭
$addressStatus.click(toggleStatus);
// 地址列表点击切换
$addressList.on('click', '.address-item', function() {
var $this = $(this);
if ($this.hasClass('focus')) {
return;
}
foucsAddress($this);
if (!$this.data('id')) {
// new address
newEdit();
} else {
resetNewEdit();
}
}).on('click', '.modify-address', function(e) {
var $this = $(this);
var $item = $this.closest('.address-item');
e.stopPropagation();
if (!$item.hasClass('focus')) {
foucsAddress($item);
}
resetNewEdit();
newEdit(buildAddressData($item));
}).on('click', '.del-address', function(e) {
var $this = $(this);
var $item = $this.closest('.address-item');
var dc;
if (!$item.hasClass('focus')) {
foucsAddress($item);
}
if ($item.hasClass('default')) {
new Alert('默认地址不能删除').show();
return;
}
e.stopPropagation();
resetNewEdit();
// del address
dc = new Confirm({
className: 'addres-del-confirm',
content: '<p class="main">删除地址</p><p class="sub">您确定要删除该收货地址吗?</p>',
cb: function() {
$.ajax({
type: 'POST',
url: '/cart/address/delete',
data: {
id: getCurAddressId()
}
}).then(function(data) {
if (data.code === 200) {
$item.remove();
dc.close();
}
});
}
}).show();
}).on('click', '.set-default', function(e) {
var $this = $(this);
var $item = $this.closest('.address-item');
if (!$item.hasClass('focus')) {
foucsAddress($item);
}
e.stopPropagation();
$.ajax({
type: 'POST',
url: '/cart/address/setdefault',
data: {
id: $item.data('id')
}
}).then(function(data) {
if (data.code === 200) {
$item.siblings('.default').removeClass('default').end().addClass('default');
}
});
});
function pkgAddress() {
var $f = $addressForm;
var re = {};
$f.find('.editor').each(function() {
var $this = $(this);
var attr = $this.data('attr');
if (!attr) {
return;
}
re[attr] = (attr === 'phone' ? ($f.find('.editor-phonecode').val() + '-') : '') + $this.val();
});
re.areaCode = $('#editor-area', $f).val();
return re;
}
function useTheAddress(ad) {
var $u = $addressUsed;
var addressStr = ad.area + ' ' + ad.address;
if (ad.zip_code || ad.zipCode) {
addressStr += (' ' + (ad.zip_code ? ad.zip_code : ad.zipCode));
}
addressStr += (' ' + ad.mobile);
if (ad.phone) {
addressStr += (' ' + ad.phone);
}
$u.data({
id: ad.id,
mobile: ad.mobile
}).find('.consignee').text(ad.consignee).end().find('.address-text').text(addressStr);
}
// 构造地址区域字符串
function getAreaText() {
var $f = $addressForm;
return ($('#editor-province option:selected', $f).text() + ' ' +
$('#editor-city option:selected', $f).text() + ' ' +
$('#editor-area option:selected', $f).text()).replace('*', '');
}
$('#save-set-address').click(function() {
var $cur = $addressList.find('.focus');
var id = getCurAddressId();
var pkg;
if ($addressForm.hasClass('hide')) {
// 使用地址,未编辑
useTheAddress({
id: id,
consignee: $cur.data('consignee'),
address: $cur.data('address'),
area: $cur.data('areaname'),
mobile: $cur.data('mobile'),
phone: $cur.data('phone'),
email: $cur.data('email'),
zipcode: $cur.data('zipcode')
});
toggleStatus();
} else {
if (!validateAddress($addressForm)) {
return;
}
pkg = $.extend(pkgAddress(), {
id: id
});
// 编辑后使用
$.ajax({
type: 'POST',
url: '/cart/address/save',
data: pkg
}).then(function(data) {
if (data.code === 200) {
if (id) {
// Edit
useTheAddress($.extend(pkg, {
area: getAreaText()
}));
// 更新address list的data状态
$cur.data(pkg);
} else {
// Add
addAddressToPage([data.data]);
useTheAddress(data.data);
}
toggleStatus();
}
});
}
});
/**
* 发票
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/9/6
*/
var $ = require('yoho-jquery');
var Dialog = require('../../common/dialog').Dialog;
var invoiceTpl = $('#invoice-chose-tpl').html();
var $withInvoice = $('#with-invoice');
var $withoutInvoice = $('#without-invoice');
// 发票信息验证
function validateInvoice($el) {
var pass = true;
var name = $.trim($('#company-name', $el).val());
var $receiverTip;
var mobile;
// 发票抬头为单位
if ($('input[name="invoice-title"]:checked', $el).val() === '2' && name === '') {
pass = false;
$('.invoice-title-tip', $el).removeClass('hide');
} else {
$('.invoice-title-tip', $el).addClass('hide');
}
// 收票人手机号
if ($('.el-invoice', $el).hasClass('focus')) {
$receiverTip = $('.receiver-tip', $el);
mobile = $.trim($('#receiver-phone', $el).val());
if (mobile === '') {
$receiverTip.removeClass('hide').find('em').html('请填写手机号码');
pass = false;
} else if (!/^[0-9]{11}$/.test(mobile)) {
$receiverTip.removeClass('hide').find('em').html('手机号码不正确');
pass = false;
} else {
$receiverTip.addClass('hide');
}
}
return pass;
}
function pkgInvoice() {
var $contentChecked = $('input[name="invoice-content"]:checked');
var pkg = {
invocesType: $('.el-invoice').hasClass('focus') ? '2' : '1',
invoicesTitle: $('input[name="invoice-title"]').prop('checked') ? '个人' : $('#company-name').val(),
invoicesContent: $contentChecked.val(),
invoicesContentName: $contentChecked.data('name')
};
if (pkg.invocesType === '1') {
pkg.receiver = $('#receiver-phone').val();
}
return pkg;
}
function bindInvoiceInfo(info) {
if (info) {
// 发票类型
if (info.invocesType === '2') {
$('.pa-invoice, .el-invoice').toggleClass('focus');
$('.invoice-content').removeClass('el-content');
} else {
// 电子发票
$('#receiver-phone').val(info.receiver);
}
// 发票抬头
if (!info.invoicesTitle || info.invoicesTitle === '个人') {
$('input[name="invoice-title"][value="1"]').prop('checked', true);
} else {
$('input[name="invoice-title"][value="2"]').prop('checked', true);
$('.company-row').removeClass('hide').find('.company-name').val(info.invoicesTitle);
}
// 发票内容
$('input[name="invoice-content"][value="' + info.invoicesContent + '"]').prop('checked', true);
}
}
function bindInvoiceEvent() {
var $invoiceTypes = $('.invoice-type li');
var $companyRow = $('.company-row');
// 发票类型切换
$invoiceTypes.click(function() {
var $this = $(this);
if ($this.hasClass('focus')) {
return;
}
$invoiceTypes.toggleClass('focus');
$('.invoice-content').toggleClass('el-content');
});
// 发票抬头
$('input[name="invoice-title"]').change(function() {
if ($(this).val() === '2') {
$companyRow.removeClass('hide');
} else {
$companyRow.addClass('hide');
}
});
}
function invoiceFactory(info) {
var invoice = new Dialog({
content: invoiceTpl,
closeIcon: false,
className: 'invoice',
btns: [
{
id: 'save-invoice',
name: '保存发票信息',
btnClass: ['save-invoice'],
cb: function() {
var pkg;
var p;
if (validateInvoice(invoice.$el)) {
pkg = pkgInvoice();
$withInvoice.removeClass('hide').find('em').html(
'<i>' + (pkg.invocesType === '1' ? '电子发票' : '纸质发票') +
'</i><i>' + pkg.invoicesTitle + '</i><i>' + pkg.invoicesContentName + '</i>'
);
$withoutInvoice.addClass('hide');
for (p in pkg) {
if (pkg.hasOwnProperty(p)) {
$withInvoice.data(p, pkg[p]);
}
}
invoice.close();
}
}
},
{
id: 'cancel-invoice',
name: '取消',
btnClass: ['cancel-invoice'],
cb: function() {
invoice.close();
}
}
]
});
bindInvoiceEvent();
bindInvoiceInfo($.extend({
receiver: $('#address-used').data('mobile')
}, info));
return invoice;
}
$('#invoice-radio').click(function(e) {
e.preventDefault();
invoiceFactory().show();
});
$('#modify-invoice').click(function() {
invoiceFactory({
invocesType: $withInvoice.data('invocesType'),
invoicesTitle: $withInvoice.data('invoicesTitle'),
invoicesContent: $withInvoice.data('invoicesContent'),
receiver: $withInvoice.data('receiver')
}).show();
});
// 获取发票信息
exports.getInvoice = function() {
if ($withInvoice.hasClass('hide')) {
return;
}
return {
invoicesType: $withInvoice.data('invocesType'),
invoicesTitle: $withInvoice.data('invoicesTitle'),
invoicesContent: $withInvoice.data('invoicesContent'),
receiver: $withInvoice.data('receiver')
};
};
/**
* 公共头部
* @author: gxh<xuhui.ge@yoho.cn>
* @date: 2017/02/27
*/
var $ = require('yoho-jquery'),
handlebars = require('yoho-handlebars');
var $head = $('.head-wrapper'),
$searchForm = $('#search-form'), // 头部搜索栏
$searchKey = $searchForm.find('.search-key'),
$searchSug = $head.find('.search-suggest');
var defaultSearch = $('#defaultsearch').val() || '';
// 搜索历史提示
function searchSuggest(key) {
var param = {
return_type: 'jsonp',
keyword: key
};
$.getJSON('//search.yohobuy.com/product/search/suggest?callback=?', param, function(jsonData) {
var searchSuggestHtml;
if (jsonData.code === 200) {
if (jsonData.data && jsonData.data.length) {
searchSuggestHtml = handlebars.compile($('#search-suggest-tml').html() || '');
$searchSug.html(searchSuggestHtml(jsonData)).show();
} else {
$searchSug.hide();
}
}
});
}
function submitSearch() {
var searchKey = $searchKey.val();
searchKey = $.trim(searchKey.toLowerCase());
if (reg.test(searchKey) && searchKey !== '') {
location.href = 'http://search.yohobuy.com/error?query=' + searchKey;
} else {
if (searchKey === '') {
$('#query-key').val(defaultSearch);
}
$searchForm.submit();
}
}
$searchKey.keyup(function(e) {
var val = $.trim($(this).val()),
$child = $searchSug.find('li'),
$act = $searchSug.find('.action'),
$focus;
if (e.which > 36 && e.which < 41) {
if (e.which === 38) {
$focus = $act.prev();
if (!$act.length || !$focus.length) {
$focus = $child.eq($child.length - 1);
}
} else if (e.which === 40) {
$focus = $act.next();
if (!$act.length || !$focus.length) {
$focus = $child.eq(0);
}
} else {
return;
}
$child.removeClass('action');
$focus.addClass('action');
$(this).val($focus.find('.searchvalue').text());
} else if (e.which === 13) {
submitSearch();
} else {
if ($searchSug && $searchSug.length) {
val = val.replace(new RegExp('\'', 'gm'), ''); // 去掉特殊字符
searchSuggest(val);
}
}
}).focus(function() {
var val = $.trim($(this).val());
if (val === defaultSearch) {
$(this).val('');
}
$(this).css('color', '#333');
}).blur(function() {
var val = $.trim($(this).val());
if (val === '') {
$(this).val(defaultSearch).css('color', '#999');
}
setTimeout(function() {
$searchSug.hide();
}, 200);
});
... ...
... ... @@ -15,6 +15,8 @@ var $head = $('.head-wrapper'),
$searchKey = $searchForm.find('.search-key'),
$logotrans = $head.find('.main-logo'),
$searchSug = $head.find('.search-suggest'),
$searchHistory = $head.find('.search-suggest-history'),
$searchHistoryHbs = $('#search-suggest-history'),
$goCart = $head.find('.go-cart'),
$myYohoBox = $('#myYohoBox'),
$goodsNum = $goCart.find('.goods-num-tip'),
... ... @@ -158,6 +160,8 @@ function setTopBanner(data) {
// cookie集合
function exeCookieMap() {
var cookies = document.cookie;
// console.log(cookies);
var cookiearr = cookies.split(';');
var i;
var temparr;
... ... @@ -327,8 +331,12 @@ function submitSearch() {
if (searchKey === '') {
$('#query-key').val(defaultSearch);
}
$searchKey.val(searchKey);
$searchForm.submit();
}
// 触发历史搜索保存
searchSuggestHistory(); //eslint-disable-line
}
// 同步mini购物车数据
... ... @@ -666,6 +674,14 @@ $searchKey.keyup(function(e) {
searchSuggest(val);
}
}
if ($searchKey.val() === '') {
// 查询历史记录
searchSuggestHistory(); //eslint-disable-line
} else {
$searchHistory.hide();
}
}).focus(function() {
var val = $.trim($(this).val());
... ... @@ -674,14 +690,26 @@ $searchKey.keyup(function(e) {
}
$(this).css('color', '#333');
setTimeout(function() {
if ($searchKey.val() === '') {
// 查询历史记录
searchSuggestHistory(); //eslint-disable-line
}
}, 10000);
}).blur(function() {
var val = $.trim($(this).val());
if (val === '') {
$(this).val(defaultSearch).css('color', '#999');
}
setTimeout(function() {
$searchSug.hide();
$searchHistory.hide();
}, 200);
});
... ... @@ -689,6 +717,8 @@ if ($miniCart && $miniCart.length) {
$goCart.hover(function() {
var data, _html = '';
$searchHistory.hide();
if ($goCart.hasClass('on-hover')) {
return;
}
... ... @@ -711,6 +741,8 @@ if ($miniCart && $miniCart.length) {
data = $dom.data(),
callback;
$searchHistory.hide();
if (data) {
callback = function() {
$dom.closest('.goods-item').remove();
... ... @@ -861,6 +893,17 @@ function actionCover() {
window.submitSearch = submitSearch;
function emailUserCertTip() {
return $.getJSON('//www.yohobuy.com/passport/cert/headerTip?callback=?', function(jsonData) {
if (jsonData && jsonData.data === 'Y') {
$('#yoho-header .yoho-cert-tip').html(
'<i class="iconfont left">&#xe63f;</i> ' +
'您的账号安全等级较低,建议您立即<a href="//www.yohobuy.com/passport/cert/index">绑定手机号</a>');
}
});
}
/**
* 查询跳转后保留关键字
* @return {[type]} [description]
... ... @@ -880,17 +923,66 @@ function actionAddKeyWords() {
});
}
function emailUserCertTip() {
/**
* 历史记录 搜索提示 api
* @return {[type]} [description]
*/
function searchSuggestHistory() {
var param = {
return_type: 'jsonp',
query: encodeURIComponent((window.queryString().query || '').replace(/\+/ig, ' '))
};
if ($searchKey.attr('alt')) {
param.query = '';
$searchKey.attr('alt', false);
}
$.getJSON('//search.yohobuy.com/product/search/history?callback=?', param, function(jsonData) {
if ($searchKey.val() === '') {
var searchSuggestHistoryHtml; //eslint-disable-line
searchSuggestHistoryHtml = handlebars.compile($searchHistoryHbs.html() || '');
$searchHistory.html(searchSuggestHistoryHtml(jsonData)).show();
if ($searchHistory.find('li').length === 0) {
$searchHistory.hide();
} else {
$searchHistory.show();
}
// 历史记录清空
$('.search-suggest-title .searchDel').click(function() {
window.setCookie('_History', '', {domain: '.yohobuy.com'});
$(this).closest('.search-suggest-history').hide();
$searchKey.attr('alt', true);
return false;
});
return $.getJSON('//www.yohobuy.com/passport/cert/headerTip?callback=?', function(jsonData) {
if (jsonData && jsonData.data === 'Y') {
$('#yoho-header .yoho-cert-tip').html(
'<i class="iconfont left">&#xe63f;</i> ' +
'您的账号安全等级较低,建议您立即<a href="//www.yohobuy.com/passport/cert/index">绑定手机号</a>');
}
});
}
/**
* 搜索 历史记录 dom
* @return {[type]} [description]
*/
$searchKey.focus(function() {
var val = $.trim($(this).val());
if (val === '') {
searchSuggestHistory();
} else {
$searchHistory.hide();
}
});
actionCover();
actionAddKeyWords();
setTimeout(emailUserCertTip, 0);
... ...
... ... @@ -86,7 +86,7 @@ function refreshCaptcha() {
$('#sub-gift').on('click', function() {
Gift.checkForm().then(function () {
Gift.checkForm().then(function() {
$.post('/home/gift/exchange', $('#giftCardForm').serialize(), function(data) {
if (data.code === 200) {
window.location.href = '/home/gift?type=1';
... ... @@ -98,7 +98,7 @@ $('#sub-gift').on('click', function() {
window.location.href = '/home/gift?type=2';
}
}, 'json');
})
});
});
$(document).on('click', '#imgcode,.check-img', function() {
... ...