Merge branch 'feature/cart' of http://git.yoho.cn/fe/yohobuywap-node into feature/cart
Showing
22 changed files
with
1446 additions
and
124 deletions
@@ -6,6 +6,7 @@ const cartModel = require('../models/cart'); | @@ -6,6 +6,7 @@ const cartModel = require('../models/cart'); | ||
6 | const headerModel = require('../../../doraemon/models/header'); | 6 | const headerModel = require('../../../doraemon/models/header'); |
7 | const userModel = require('../../serverAPI/user'); | 7 | const userModel = require('../../serverAPI/user'); |
8 | const addressModel = require('../../serverAPI/user/address'); | 8 | const addressModel = require('../../serverAPI/user/address'); |
9 | +const orderModel = require('../models/order'); | ||
9 | 10 | ||
10 | 11 | ||
11 | exports.orderEnsure = (req, res, next) => { | 12 | exports.orderEnsure = (req, res, next) => { |
@@ -45,51 +46,46 @@ exports.orderEnsure = (req, res, next) => { | @@ -45,51 +46,46 @@ exports.orderEnsure = (req, res, next) => { | ||
45 | let userProfile = userModel.queryProfile(uid); | 46 | let userProfile = userModel.queryProfile(uid); |
46 | let address = addressModel.addressData(uid); | 47 | let address = addressModel.addressData(uid); |
47 | 48 | ||
48 | - return Promise.all([order, userProfile, address]) | ||
49 | - .then( | ||
50 | - result => { | ||
51 | - order = result[0]; | ||
52 | - userProfile = result[1]; | ||
53 | - address = result[2]; | ||
54 | - | ||
55 | - if (order.cartUrl) { // TODO? 普通或者预售商品为空时, BUT WHEN AJAX? | ||
56 | - return res.redirect(order.cartUrl); | ||
57 | - } | ||
58 | - | ||
59 | - if (req.xhr) { | ||
60 | - return res.json(order); | ||
61 | - } | ||
62 | - | ||
63 | - // 获取用户完整手机号 | ||
64 | - let mobile = _.get(userProfile, 'data.mobile', ''); | ||
65 | - let orderAddress = _.get(order, 'address', []); | ||
66 | - let addressList = _.get(address, 'data', []); | ||
67 | - | ||
68 | - orderAddress.length && addressList.forEach(address => { //eslint-disable-line | ||
69 | - if (address.address_id === orderAddress.address_id) { | ||
70 | - mobile = address.mobile; | ||
71 | - } | ||
72 | - }); | ||
73 | - | ||
74 | - let viewData = { | ||
75 | - orderEnsurePage: true, | ||
76 | - isOrdinaryCart: cartType !== 'advance', | ||
77 | - orderEnsure: order, | ||
78 | - userMobile: mobile | ||
79 | - }; | ||
80 | - | ||
81 | - viewData.pageHeader = headerData; | ||
82 | - viewData.pageFooter = true; | ||
83 | - viewData.module = 'cart'; | ||
84 | - viewData.page = 'order-ensure'; | ||
85 | - viewData.width750 = true; | ||
86 | - viewData.title = '确认订单'; | ||
87 | - | ||
88 | - res.render('order-ensure', viewData); | 49 | + return Promise.all([order, userProfile, address]).then(result => { |
50 | + order = result[0]; | ||
51 | + userProfile = result[1]; | ||
52 | + address = result[2]; | ||
53 | + | ||
54 | + if (order.cartUrl) { // TODO? 普通或者预售商品为空时, BUT WHEN AJAX? | ||
55 | + return res.redirect(order.cartUrl); | ||
56 | + } | ||
57 | + | ||
58 | + if (req.xhr) { | ||
59 | + return res.json(order); | ||
60 | + } | ||
61 | + | ||
62 | + // 获取用户完整手机号 | ||
63 | + let mobile = _.get(userProfile, 'data.mobile', ''); | ||
64 | + let orderAddress = _.get(order, 'address', []); | ||
65 | + let addressList = _.get(address, 'data', []); | ||
66 | + | ||
67 | + orderAddress.length && addressList.forEach(address => { //eslint-disable-line | ||
68 | + if (address.address_id === orderAddress.address_id) { | ||
69 | + mobile = address.mobile; | ||
89 | } | 70 | } |
90 | - ) | ||
91 | - .catch(next); | 71 | + }); |
92 | 72 | ||
73 | + let viewData = { | ||
74 | + orderEnsurePage: true, | ||
75 | + isOrdinaryCart: cartType !== 'advance', | ||
76 | + orderEnsure: order, | ||
77 | + userMobile: mobile | ||
78 | + }; | ||
79 | + | ||
80 | + viewData.pageHeader = headerData; | ||
81 | + viewData.pageFooter = true; | ||
82 | + viewData.module = 'cart'; | ||
83 | + viewData.page = 'order-ensure'; | ||
84 | + viewData.width750 = true; | ||
85 | + viewData.title = '确认订单'; | ||
86 | + | ||
87 | + res.render('order-ensure', viewData); | ||
88 | + }).catch(next); | ||
93 | }; | 89 | }; |
94 | 90 | ||
95 | /** | 91 | /** |
@@ -149,40 +145,42 @@ exports.couponSearch = (req, res, next) => { | @@ -149,40 +145,42 @@ exports.couponSearch = (req, res, next) => { | ||
149 | })(); | 145 | })(); |
150 | }; | 146 | }; |
151 | 147 | ||
148 | +/** | ||
149 | + * 选择地址 | ||
150 | + */ | ||
152 | exports.selectAddress = (req, res, next) => { | 151 | exports.selectAddress = (req, res, next) => { |
153 | let uid = req.user.uid; | 152 | let uid = req.user.uid; |
154 | 153 | ||
155 | - return addressModel.addressData(uid) | ||
156 | - .then(address => { | ||
157 | - let moreUrl = req.get('Referer') || '/cart/index/new/orderEnsure'; // 取跳过来的url | 154 | + return addressModel.addressData(uid).then(address => { |
155 | + let moreUrl = req.get('Referer') || '/cart/index/new/orderEnsure'; // 取跳过来的url | ||
158 | 156 | ||
159 | - address = address.data; | 157 | + address = address.data; |
160 | 158 | ||
161 | - // 购物车订单进来,秒杀进来 | ||
162 | - if ( | ||
163 | - moreUrl.indexOf('/cart/index/new/orderEnsure') !== -1 || | ||
164 | - moreUrl.indexOf('/cart/index/seckill') !== -1 | ||
165 | - ) { | ||
166 | - req.session.addressMore = moreUrl; // TODO: 注意cookie-session | ||
167 | - } | 159 | + // 购物车订单进来,秒杀进来 |
160 | + if ( | ||
161 | + moreUrl.indexOf('/cart/index/new/orderEnsure') !== -1 || | ||
162 | + moreUrl.indexOf('/cart/index/seckill') !== -1 | ||
163 | + ) { | ||
164 | + req.session.addressMore = moreUrl; // TODO: 注意cookie-session | ||
165 | + } | ||
168 | 166 | ||
169 | - moreUrl = req.session.addressMore; | 167 | + moreUrl = req.session.addressMore; |
170 | 168 | ||
171 | - let headerData = headerModel.setNav({ | ||
172 | - navTitle: '选择地址', | ||
173 | - navBtn: false, | ||
174 | - backUrl: moreUrl | ||
175 | - }); | 169 | + let headerData = headerModel.setNav({ |
170 | + navTitle: '选择地址', | ||
171 | + navBtn: false, | ||
172 | + backUrl: moreUrl | ||
173 | + }); | ||
176 | 174 | ||
177 | - res.render('select-address', { | ||
178 | - module: 'cart', | ||
179 | - page: 'select-address', | ||
180 | - pageHeader: headerData, | ||
181 | - pageFooter: true, | ||
182 | - moreUrl, | ||
183 | - address | ||
184 | - }); | 175 | + res.render('select-address', { |
176 | + module: 'cart', | ||
177 | + page: 'select-address', | ||
178 | + pageHeader: headerData, | ||
179 | + pageFooter: true, | ||
180 | + moreUrl, | ||
181 | + address | ||
185 | }); | 182 | }); |
183 | + }).catch(next); | ||
186 | }; | 184 | }; |
187 | 185 | ||
188 | /** | 186 | /** |
@@ -190,14 +188,23 @@ exports.selectAddress = (req, res, next) => { | @@ -190,14 +188,23 @@ exports.selectAddress = (req, res, next) => { | ||
190 | */ | 188 | */ |
191 | exports.invoiceInfo = (req, res, next) => { | 189 | exports.invoiceInfo = (req, res, next) => { |
192 | let uid = req.user.uid; | 190 | let uid = req.user.uid; |
191 | + let cookieData = req.cookies['order-info']; | ||
192 | + let orderInfo = JSON.parse(cookieData); | ||
193 | 193 | ||
194 | - let orderInfo = req.cookies.orderInfo; | ||
195 | - | ||
196 | - try { | ||
197 | - orderInfo = JSON.parse(orderInfo); | ||
198 | - } catch (e) { | ||
199 | - orderInfo = {}; | ||
200 | - } | ||
201 | - | 194 | + co(function* () { |
195 | + let userData = yield userModel.queryProfile(uid); | ||
196 | + let mobile = _.get(userData, 'data.mobile', ''); | ||
197 | + let addresslist = yield userModel.addressTextData(uid); | ||
198 | + let returnData = orderModel.processInvoiceData(orderInfo, mobile, addresslist); | ||
199 | + let headerData = headerModel.setNav({ | ||
200 | + navTitle: '发票信息', | ||
201 | + navBtn: false | ||
202 | + }); | ||
202 | 203 | ||
204 | + res.render('select-invoice', _.assign(returnData, { | ||
205 | + pageHeader: headerData, | ||
206 | + module: 'cart', | ||
207 | + page: 'select-invoice' | ||
208 | + })).catch(next); | ||
209 | + })(); | ||
203 | }; | 210 | }; |
1 | /** | 1 | /** |
2 | - * 支付成功页 | 2 | + * 支付 |
3 | * @author: jing.li<jing.li@yoho.cn> | 3 | * @author: jing.li<jing.li@yoho.cn> |
4 | * @date: 2016/10/25 | 4 | * @date: 2016/10/25 |
5 | */ | 5 | */ |
@@ -9,6 +9,9 @@ | @@ -9,6 +9,9 @@ | ||
9 | const mRoot = '../models'; | 9 | const mRoot = '../models'; |
10 | const payModel = require(`${mRoot}/pay`); | 10 | const payModel = require(`${mRoot}/pay`); |
11 | const headerModel = require('../../../doraemon/models/header'); // 头部model | 11 | const headerModel = require('../../../doraemon/models/header'); // 头部model |
12 | +const co = require('bluebird').coroutine; | ||
13 | +const helpers = global.yoho.helpers; | ||
14 | +const Payment = require('../helpers/payment'); | ||
12 | 15 | ||
13 | /** | 16 | /** |
14 | * 支付中心 | 17 | * 支付中心 |
@@ -17,6 +20,18 @@ const headerModel = require('../../../doraemon/models/header'); // 头部model | @@ -17,6 +20,18 @@ const headerModel = require('../../../doraemon/models/header'); // 头部model | ||
17 | * @param next | 20 | * @param next |
18 | */ | 21 | */ |
19 | const payCenter = (req, res, next) => { | 22 | const payCenter = (req, res, next) => { |
23 | + let orderCode = req.query.order_code; | ||
24 | + let uid = req.user.uid; | ||
25 | + let sessionKey = req.session.TOKEN; | ||
26 | + | ||
27 | + if (!orderCode || !uid) { | ||
28 | + res.redirect('/'); | ||
29 | + } | ||
30 | + | ||
31 | + if (sessionKey) { | ||
32 | + sessionKey = sessionKey.substr(0, sessionKey.length - 8); | ||
33 | + } | ||
34 | + | ||
20 | let headerData = headerModel.setNav({ | 35 | let headerData = headerModel.setNav({ |
21 | navTitle: '支付中心' | 36 | navTitle: '支付中心' |
22 | }); | 37 | }); |
@@ -29,16 +44,67 @@ const payCenter = (req, res, next) => { | @@ -29,16 +44,67 @@ const payCenter = (req, res, next) => { | ||
29 | }; | 44 | }; |
30 | 45 | ||
31 | payModel.payCenter({ | 46 | payModel.payCenter({ |
32 | - orderCode: req.query.order_code | 47 | + orderCode: orderCode, |
48 | + uid: uid, | ||
49 | + sessionKey: sessionKey | ||
33 | }).then(result => { | 50 | }).then(result => { |
34 | - res.render('pay/pay-center', Object.assign(responseData, { | ||
35 | - payAppInfo: result.payList | 51 | + res.render('pay/pay-center', Object.assign(responseData, result, { |
52 | + isOldUser: Boolean(req.cookies._isOldUser && req.cookies._isOldUser === '4'), | ||
36 | })); | 53 | })); |
37 | }).catch(next); | 54 | }).catch(next); |
38 | 55 | ||
39 | 56 | ||
40 | }; | 57 | }; |
41 | 58 | ||
59 | +/** | ||
60 | + * 支付宝跳转页 | ||
61 | + * @param req | ||
62 | + * @param res | ||
63 | + */ | ||
64 | +const goAlipay = (req, res, next) => { | ||
65 | + let orderCode = req.query.order_code; | ||
66 | + let user = req.user; | ||
67 | + let uid = req.user.uid; | ||
68 | + let sessionKey = req.session.TOKEN; | ||
69 | + let payment = req.query.payment; | ||
70 | + | ||
71 | + if (!orderCode || !uid || !sessionKey) { | ||
72 | + res.redirect('/'); | ||
73 | + } | ||
74 | + | ||
75 | + co(function*() { | ||
76 | + let orderDetail = yield payModel.getOtherDetail({ | ||
77 | + uid: uid, | ||
78 | + orderCode: orderCode, | ||
79 | + sessionKey: sessionKey | ||
80 | + }); | ||
81 | + | ||
82 | + if (!orderDetail || !orderDetail.data) { | ||
83 | + return res.json({ | ||
84 | + code: 400, | ||
85 | + msg: '没有找到该订单!' | ||
86 | + }); | ||
87 | + } | ||
88 | + | ||
89 | + if (orderDetail.data.is_cancel === 'Y') { | ||
90 | + let url = helpers.urlFormat('/home/orders/detail', { order_code: orderCode }); | ||
91 | + | ||
92 | + return res.json({ | ||
93 | + code: 400, | ||
94 | + msg: '订单已经取消' | ||
95 | + }).redirect(url); | ||
96 | + } | ||
97 | + | ||
98 | + Payment.pay(user, orderDetail.data, payment, req.protocol).then(result => { | ||
99 | + if (result && result.data && result.data.href) { | ||
100 | + res.redirect(result.data.href); | ||
101 | + } else { | ||
102 | + res.redirect('/'); | ||
103 | + } | ||
104 | + }).catch(next); | ||
105 | + })(); | ||
106 | +}; | ||
107 | + | ||
42 | // 货到付款 | 108 | // 货到付款 |
43 | const payCod = (req, res, next) => { | 109 | const payCod = (req, res, next) => { |
44 | let headerData = headerModel.setNav({ | 110 | let headerData = headerModel.setNav({ |
@@ -52,12 +118,16 @@ const payCod = (req, res, next) => { | @@ -52,12 +118,16 @@ const payCod = (req, res, next) => { | ||
52 | title: '支付中心 | Yoho!Buy有货 | 潮流购物逛不停' | 118 | title: '支付中心 | Yoho!Buy有货 | 潮流购物逛不停' |
53 | }; | 119 | }; |
54 | 120 | ||
121 | + let sessionKey = req.session.TOKEN; | ||
122 | + | ||
123 | + | ||
55 | let param = { | 124 | let param = { |
56 | uid: req.user.uid, | 125 | uid: req.user.uid, |
57 | udid: req.sessionID || require('md5')(req.ip) || 'yoho', | 126 | udid: req.sessionID || require('md5')(req.ip) || 'yoho', |
58 | orderCode: req.query.order_code, | 127 | orderCode: req.query.order_code, |
59 | contentCode: '05afedf76886d732573f10f7451a1703', | 128 | contentCode: '05afedf76886d732573f10f7451a1703', |
60 | - client_id: req.cookies._yasvd || '' | 129 | + client_id: req.cookies._yasvd || '', |
130 | + sessionKey: sessionKey && sessionKey.substr(0, sessionKey.length - 8) || '' | ||
61 | }; | 131 | }; |
62 | 132 | ||
63 | // 如果没有uid,跳转到首页 | 133 | // 如果没有uid,跳转到首页 |
@@ -76,7 +146,7 @@ const payCod = (req, res, next) => { | @@ -76,7 +146,7 @@ const payCod = (req, res, next) => { | ||
76 | }).catch(next); | 146 | }).catch(next); |
77 | }; | 147 | }; |
78 | 148 | ||
79 | -// 支付宝支付 | 149 | +// 支付宝支付结果页 |
80 | const payAli = (req, res, next) => { | 150 | const payAli = (req, res, next) => { |
81 | let headerData = headerModel.setNav({ | 151 | let headerData = headerModel.setNav({ |
82 | navTitle: '支付完成' | 152 | navTitle: '支付完成' |
@@ -114,6 +184,7 @@ const payAli = (req, res, next) => { | @@ -114,6 +184,7 @@ const payAli = (req, res, next) => { | ||
114 | 184 | ||
115 | module.exports = { | 185 | module.exports = { |
116 | payCenter, | 186 | payCenter, |
187 | + goAlipay, | ||
117 | payCod, | 188 | payCod, |
118 | payAli | 189 | payAli |
119 | }; | 190 | }; |
apps/cart/helpers/pay/alibank.js
0 → 100644
1 | +/** | ||
2 | + * TAR NOTE: 从 YOHO-BLK 项目复制,未针对本项目做适配 | ||
3 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
4 | + * @date: 16/7/22 | ||
5 | + */ | ||
6 | + | ||
7 | +'use strict'; | ||
8 | + | ||
9 | +const config = global.yoho.config; | ||
10 | +const helpers = global.yoho.helpers; | ||
11 | +const common = require('./common'); | ||
12 | +const sign = require('./sign'); | ||
13 | +const payHelpersBank = require('./bank'); | ||
14 | +const md5 = require('md5'); | ||
15 | +const logger = global.yoho.logger; | ||
16 | + | ||
17 | +const ALIPAY_URL = 'https://mapi.alipay.com/gateway.do'; | ||
18 | + | ||
19 | +const Alibank = { | ||
20 | + | ||
21 | + pay(user, order, param, protocol) { | ||
22 | + let payParams = JSON.parse(param.payParams); | ||
23 | + let extraParam = JSON.stringify({ | ||
24 | + sign_id_ext: user.uid, | ||
25 | + defaultbank: param.bankCode || '' | ||
26 | + }); | ||
27 | + | ||
28 | + let params = { | ||
29 | + service: 'create_direct_pay_by_user', | ||
30 | + partner: payParams.merchant_id, | ||
31 | + _input_charset: 'utf-8', | ||
32 | + notify_url: config.pay.serviceNotify + 'payment/alipay_notify', | ||
33 | + return_url: protocol + ':' + helpers.urlFormat('/shopping/pay/callback/alibank'), | ||
34 | + subject: 'BLK订单号:' + order.order_code, | ||
35 | + out_trade_no: order.order_code, | ||
36 | + it_b_pay: common.getPayExpireMin(order.pay_expire) + 'm', | ||
37 | + total_fee: order.payment_amount, | ||
38 | + payment_type: '1', | ||
39 | + defaultbank: param.bankCode, | ||
40 | + seller_email: payParams.merchant_other_code, | ||
41 | + extra_common_param: extraParam | ||
42 | + }; | ||
43 | + | ||
44 | + // TODO 防钓鱼配置,参考php | ||
45 | + | ||
46 | + let signStr = md5(sign.raw(params) + payParams.merchant_key); | ||
47 | + let body = sign.rawUncode(params) + '&sign=' + signStr + '&sign_type=MD5'; | ||
48 | + | ||
49 | + return { | ||
50 | + code: 200, | ||
51 | + data: { | ||
52 | + href: ALIPAY_URL + '?' + body | ||
53 | + } | ||
54 | + }; | ||
55 | + }, | ||
56 | + notify(data, param) { | ||
57 | + let payParams = param.payParams && JSON.parse(param.payParams) || {}; | ||
58 | + let orderCode = parseInt(data.out_trade_no, 10); | ||
59 | + let extraParam = data.extra_common_param && JSON.parse(data.extra_common_param) || {}; | ||
60 | + let bankName = payHelpersBank.getList()[extraParam.defaultbank] && | ||
61 | + payHelpersBank.getList()[extraParam.defaultbank].name || ''; | ||
62 | + | ||
63 | + logger.info(`Alibank notify, params = ${JSON.stringify(data)}`); | ||
64 | + | ||
65 | + if (!this.checkNotify(data, payParams)) { | ||
66 | + return {payResult: -1, bankName: bankName}; | ||
67 | + } else { | ||
68 | + return { | ||
69 | + bankName: bankName, | ||
70 | + orderCode: orderCode, | ||
71 | + payResult: data.trade_status === 'TRADE_SUCCESS' ? 200 : 400, | ||
72 | + payTime: data.gmt_payment || '', | ||
73 | + totalFee: data.total_fee, | ||
74 | + resultMsg: data.notify_type, | ||
75 | + payOrderCode: orderCode, | ||
76 | + tradeNo: data.trade_no, | ||
77 | + bankBillNo: data.bank_seq_no || '' | ||
78 | + }; | ||
79 | + } | ||
80 | + }, | ||
81 | + | ||
82 | + checkNotify(data, payParams) { | ||
83 | + let signValue = data.sign; | ||
84 | + | ||
85 | + if (!payParams || !data) { | ||
86 | + return false; | ||
87 | + } | ||
88 | + | ||
89 | + delete data.sign; | ||
90 | + delete data.sign_type; | ||
91 | + delete data.code; | ||
92 | + | ||
93 | + let signStr = md5(sign.raw(data) + payParams.merchant_key); | ||
94 | + | ||
95 | + return signValue === signStr; | ||
96 | + } | ||
97 | +}; | ||
98 | + | ||
99 | +module.exports = Alibank; |
apps/cart/helpers/pay/alipay.js
0 → 100644
1 | +/** | ||
2 | + * | ||
3 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
4 | + * @date: 16/7/22 | ||
5 | + */ | ||
6 | + | ||
7 | +'use strict'; | ||
8 | + | ||
9 | +const config = global.yoho.config; | ||
10 | +const helpers = global.yoho.helpers; | ||
11 | +const sign = require('./sign'); | ||
12 | +const md5 = require('md5'); | ||
13 | +const logger = global.yoho.logger; | ||
14 | +const AlipayConfig = config.alipayConfig; | ||
15 | + | ||
16 | +const Alipay = { | ||
17 | + | ||
18 | + pay(user, order, param, protocol) { | ||
19 | + let params = { | ||
20 | + service: AlipayConfig.service, | ||
21 | + partner: AlipayConfig.partner, | ||
22 | + _input_charset: AlipayConfig.inputCharset, | ||
23 | + notify_url: config.domains.service + 'payment/alipay_notify', | ||
24 | + return_url: protocol + ':' + helpers.urlFormat(AlipayConfig.returnUrl), | ||
25 | + subject: '有货订单号:' + order.order_code, | ||
26 | + out_trade_no: order.order_code, | ||
27 | + it_b_pay: order.pay_expire, | ||
28 | + total_fee: parseFloat(order.payment_amount), | ||
29 | + seller_id: AlipayConfig.partner, | ||
30 | + payment_type: '1', | ||
31 | + show_url: protocol + ':' + helpers.urlFormat('/home/orderdetail', { order_code: order.order_code }) | ||
32 | + }; | ||
33 | + | ||
34 | + // TODO 防钓鱼配置,参考php | ||
35 | + | ||
36 | + let signStr = md5(sign.raw(params) + AlipayConfig.alipayKey); | ||
37 | + let body = sign.rawUncode(params) + '&sign=' + signStr + '&sign_type=MD5'; | ||
38 | + | ||
39 | + return { | ||
40 | + code: 200, | ||
41 | + data: { | ||
42 | + href: AlipayConfig.payUrl + '?' + body | ||
43 | + } | ||
44 | + }; | ||
45 | + }, | ||
46 | + notify(data, param) { | ||
47 | + let payParams = JSON.parse(param.payParams); | ||
48 | + | ||
49 | + logger.info(`Alipay notify, params = ${JSON.stringify(data)}`); | ||
50 | + | ||
51 | + if (!this.checkNotify(data, payParams)) { | ||
52 | + return { payResult: -1 }; | ||
53 | + } else { | ||
54 | + let orderCode = parseInt(data.out_trade_no, 10); | ||
55 | + | ||
56 | + return { | ||
57 | + bankName: '', | ||
58 | + orderCode: orderCode, | ||
59 | + payResult: data.trade_status === 'TRADE_SUCCESS' ? 200 : 400, | ||
60 | + payTime: data.gmt_payment || '', | ||
61 | + totalFee: data.total_fee, | ||
62 | + resultMsg: data.notify_type, | ||
63 | + payOrderCode: orderCode, | ||
64 | + tradeNo: data.trade_no, | ||
65 | + bankBillNo: '' | ||
66 | + }; | ||
67 | + } | ||
68 | + }, | ||
69 | + | ||
70 | + checkNotify(data, payParams) { | ||
71 | + let signValue = data.sign; | ||
72 | + | ||
73 | + delete data.sign; | ||
74 | + delete data.sign_type; | ||
75 | + delete data.code; | ||
76 | + | ||
77 | + let signStr = md5(sign.raw(data) + payParams.merchant_key); | ||
78 | + | ||
79 | + return signValue === signStr; | ||
80 | + } | ||
81 | +}; | ||
82 | + | ||
83 | +module.exports = Alipay; |
apps/cart/helpers/pay/bank.js
0 → 100644
1 | +/** | ||
2 | + * Created by TaoHuang on 2016/7/18. | ||
3 | + */ | ||
4 | +'use strict'; | ||
5 | + | ||
6 | +const Bank = { | ||
7 | + getList() { | ||
8 | + return { | ||
9 | + BOCB2C: { | ||
10 | + name: '中国银行', | ||
11 | + ico: '//static.yohobuy.com/images/pay/icon/zhongguo.png' | ||
12 | + }, | ||
13 | + ABC: { | ||
14 | + name: '中国农业银行', | ||
15 | + ico: '//static.yohobuy.com/images/pay/icon/nongye.png' | ||
16 | + }, | ||
17 | + SPABANK: { | ||
18 | + name: '平安银行', | ||
19 | + ico: '//static.yohobuy.com/images/pay/icon/pingan.png' | ||
20 | + }, | ||
21 | + CMBC: { | ||
22 | + name: '中国民生银行', | ||
23 | + ico: '//static.yohobuy.com/images/pay/icon/minsheng.png' | ||
24 | + }, | ||
25 | + ICBCB2C: { | ||
26 | + name: '中国工商银行', | ||
27 | + ico: '//static.yohobuy.com/images/pay/icon/gongshang.png' | ||
28 | + }, | ||
29 | + SPDB: { | ||
30 | + name: '浦发银行', | ||
31 | + ico: '//static.yohobuy.com/images/pay/icon/pufa.png' | ||
32 | + }, | ||
33 | + BJRCB: { | ||
34 | + name: '北京农商银行', | ||
35 | + ico: '//static.yohobuy.com/images/pay/icon/beijingnongshang.png' | ||
36 | + }, | ||
37 | + HZCBB2C: { | ||
38 | + name: '杭州银行', | ||
39 | + ico: '//static.yohobuy.com/images/pay/icon/hangzhou.png' | ||
40 | + }, | ||
41 | + CMB: { | ||
42 | + name: '招商银行', | ||
43 | + ico: '//static.yohobuy.com/images/pay/icon/zhaoshang.png' | ||
44 | + }, | ||
45 | + CIB: { | ||
46 | + name: '兴业银行', | ||
47 | + ico: '//static.yohobuy.com/images/pay/icon/xingye.png' | ||
48 | + }, | ||
49 | + FDB: { | ||
50 | + name: '富滇银行', | ||
51 | + ico: '//static.yohobuy.com/images/pay/icon/fudian.png' | ||
52 | + }, | ||
53 | + CEBDEBIT: { | ||
54 | + name: '中国光大银行', | ||
55 | + ico: '//static.yohobuy.com/images/pay/icon/guangda.png' | ||
56 | + }, | ||
57 | + CCB: { | ||
58 | + name: '中国建设银行', | ||
59 | + ico: '//static.yohobuy.com/images/pay/icon/zhongguojianshe.png' | ||
60 | + }, | ||
61 | + GDB: { | ||
62 | + name: '广发银行', | ||
63 | + ico: '//static.yohobuy.com/images/pay/icon/guangfa.png' | ||
64 | + }, | ||
65 | + POSTGC: { | ||
66 | + name: '中国邮政储蓄', | ||
67 | + ico: '//static.yohobuy.com/images/pay/icon/zhongguoyouzhengchuxu.png' | ||
68 | + }, | ||
69 | + SHBANK: { | ||
70 | + name: '上海银行', | ||
71 | + ico: '//static.yohobuy.com/images/pay/icon/shanghai.png' | ||
72 | + }, | ||
73 | + NBBANK: { | ||
74 | + name: '宁波银行', | ||
75 | + ico: '//static.yohobuy.com/images/pay/icon/ningbo.png' | ||
76 | + } | ||
77 | + }; | ||
78 | + } | ||
79 | +}; | ||
80 | + | ||
81 | +module.exports = Bank; |
apps/cart/helpers/pay/common.js
0 → 100644
1 | +/** | ||
2 | + * | ||
3 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
4 | + * @date: 16/7/22 | ||
5 | + */ | ||
6 | +'use strict'; | ||
7 | +const moment = require('moment'); | ||
8 | +const xml2js = require('xml2js'); | ||
9 | + | ||
10 | +const common = { | ||
11 | + getPayExpireMin(expire) { | ||
12 | + let defaultValue = 120; | ||
13 | + | ||
14 | + if (expire) { | ||
15 | + let expireTime = moment(expire, 'YYYY-MM-DD HH:mm:ss'); | ||
16 | + let diff = expireTime.diff(moment()); | ||
17 | + | ||
18 | + return Math.floor(diff / 1000 / 60); | ||
19 | + | ||
20 | + // if (diff > 0) { | ||
21 | + // return Math.floor(diff / 1000 / 60); | ||
22 | + // } else { | ||
23 | + // return 0; | ||
24 | + // } | ||
25 | + | ||
26 | + } else { | ||
27 | + return defaultValue; | ||
28 | + } | ||
29 | + }, | ||
30 | + getPayExpireCouple(expire) { | ||
31 | + let start = expire ? moment(expire, 'YYYY-MM-DD HH:mm:ss') : moment(); | ||
32 | + let end = expire ? moment(expire, 'YYYY-MM-DD HH:mm:ss') : moment(); | ||
33 | + | ||
34 | + return { | ||
35 | + start: start.subtract(2, 'hours'), | ||
36 | + end: end.add(5, 'minutes') | ||
37 | + }; | ||
38 | + }, | ||
39 | + nonceStr(length) { | ||
40 | + length = length || 32; | ||
41 | + | ||
42 | + let chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; | ||
43 | + let str = ''; | ||
44 | + | ||
45 | + for (let i = 0; i < length; i++) { | ||
46 | + str += chars[parseInt(Math.random() * length, 10)]; | ||
47 | + } | ||
48 | + return str; | ||
49 | + }, | ||
50 | + toXml(obj, root) { | ||
51 | + let xmlBuilder = new xml2js.Builder({ | ||
52 | + rootName: root || 'xml' | ||
53 | + }); | ||
54 | + | ||
55 | + return xmlBuilder.buildObject(obj); | ||
56 | + }, | ||
57 | + xml2Obj(xml) { | ||
58 | + let xmlParser = new xml2js.Parser({ | ||
59 | + trim: true, | ||
60 | + explicitArray: false | ||
61 | + }); | ||
62 | + | ||
63 | + return new Promise((resolve, reject) => { | ||
64 | + xmlParser.parseString(xml, (err, result) => { | ||
65 | + if (err) { | ||
66 | + reject(err); | ||
67 | + } else { | ||
68 | + resolve(result); | ||
69 | + } | ||
70 | + }); | ||
71 | + }); | ||
72 | + } | ||
73 | +}; | ||
74 | + | ||
75 | +module.exports = common; |
apps/cart/helpers/pay/sign.js
0 → 100644
1 | +/** | ||
2 | + * | ||
3 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
4 | + * @date: 16/7/22 | ||
5 | + */ | ||
6 | +'use strict'; | ||
7 | + | ||
8 | +const Sign = { | ||
9 | + raw(args) { | ||
10 | + let keys = Object.keys(args); | ||
11 | + | ||
12 | + keys = keys.filter(k => { | ||
13 | + return args[k] === '' || args[k] === 'undefined' ? false : true; | ||
14 | + }).sort(); | ||
15 | + | ||
16 | + return keys.map(k => { | ||
17 | + return k + '=' + decodeURI(args[k]); | ||
18 | + }).join('&'); | ||
19 | + }, | ||
20 | + | ||
21 | + rawUncode(args) { | ||
22 | + let keys = Object.keys(args); | ||
23 | + | ||
24 | + keys = keys.filter(k => { | ||
25 | + return args[k] === '' || args[k] === 'undefined' ? false : true; | ||
26 | + }).sort(); | ||
27 | + | ||
28 | + return keys.map(k => { | ||
29 | + return k.toLowerCase() + '=' + args[k]; | ||
30 | + }).join('&'); | ||
31 | + } | ||
32 | +}; | ||
33 | + | ||
34 | +module.exports = Sign; |
apps/cart/helpers/pay/wechat.js
0 → 100644
1 | +/** | ||
2 | + * | ||
3 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
4 | + * @date: 16/9/8 | ||
5 | + */ | ||
6 | +'use strict'; | ||
7 | + | ||
8 | +const ServiceAPI = global.yoho.ServiceAPI; | ||
9 | +const helpers = global.yoho.helpers; | ||
10 | + | ||
11 | +const Wechat = { | ||
12 | + pay(user, order, info) { | ||
13 | + return ServiceAPI.get('payment/weixin_data', { | ||
14 | + order_code: order.order_code, | ||
15 | + payment_code: info.id, | ||
16 | + app_key: 'blkpc' | ||
17 | + }).then(result => { | ||
18 | + if (result && result.code === 200 && result.data) { | ||
19 | + let url = `/shopping/pay/online/weixin?url=${result.data.codeUrl}&code=${order.order_code}`; | ||
20 | + | ||
21 | + return { | ||
22 | + code: 200, | ||
23 | + data: { | ||
24 | + href: helpers.urlFormat(url) | ||
25 | + } | ||
26 | + }; | ||
27 | + } else { | ||
28 | + return { | ||
29 | + code: 400, | ||
30 | + message: result.message | ||
31 | + }; | ||
32 | + } | ||
33 | + }); | ||
34 | + } | ||
35 | +}; | ||
36 | + | ||
37 | +module.exports = Wechat; |
apps/cart/helpers/payment.js
0 → 100644
1 | +/** | ||
2 | + * 各种支付的入口 | ||
3 | + * TAR NOTE: 本项目中仅支持支付宝和微信支付,其他支付方式需调试 | ||
4 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
5 | + * @date: 16/7/22 | ||
6 | + */ | ||
7 | + | ||
8 | +'use strict'; | ||
9 | + | ||
10 | +const PayModel = require('../models/pay'); | ||
11 | +const Alipay = require('./pay/alipay'); | ||
12 | +const Alibank = require('./pay/alibank'); | ||
13 | +const Wechat = require('./pay/wechat'); | ||
14 | +const Promise = require('bluebird'); | ||
15 | +const co = Promise.coroutine; | ||
16 | +const logger = global.yoho.logger; | ||
17 | + | ||
18 | +const Payment = { | ||
19 | + pay(user, order, payType, protocol) { | ||
20 | + return co(function*() { | ||
21 | + let result = { | ||
22 | + code: 400, | ||
23 | + message: '获取支付方式信息失败' | ||
24 | + }; | ||
25 | + let paymentPars = payType.split('_'); | ||
26 | + let payInfo; | ||
27 | + let bankCode = ''; | ||
28 | + | ||
29 | + if (paymentPars.length !== 2) { | ||
30 | + return result; | ||
31 | + } | ||
32 | + | ||
33 | + if (!order.order_code) { | ||
34 | + result.message = '没有找到该订单'; | ||
35 | + return result; | ||
36 | + } | ||
37 | + | ||
38 | + if (order.is_cancel && order.is_cancel === 'Y') { | ||
39 | + result.message = '该订单已经取消'; | ||
40 | + return result; | ||
41 | + } | ||
42 | + | ||
43 | + // if (order.pay_expire && common.getPayExpireMin(order.pay_expire) <= 0) { | ||
44 | + // result.message = '当前订单不可支付'; // 该订单已超过2个小时 | ||
45 | + // return result; | ||
46 | + // } | ||
47 | + | ||
48 | + let method = paymentPars[0] * 1; | ||
49 | + | ||
50 | + if (method === PayModel.payments.wechat) { | ||
51 | + // 如果是微信支付,不需要调用获取支付方式详情接口 | ||
52 | + result = yield Wechat.pay(user, order, { id: PayModel.payments.wechat }); | ||
53 | + } else { | ||
54 | + payInfo = yield PayModel.getPaymentInfo(method); | ||
55 | + | ||
56 | + if (!payInfo.payParams) { | ||
57 | + return result; | ||
58 | + } | ||
59 | + | ||
60 | + switch (payInfo.id) { | ||
61 | + case PayModel.payments.alipay: | ||
62 | + result = Alipay.pay(user, order, payInfo, protocol); | ||
63 | + break; | ||
64 | + case PayModel.payments.alibank: | ||
65 | + bankCode = paymentPars[1]; | ||
66 | + payInfo.bankCode = bankCode; // 设置默认银行 | ||
67 | + result = Alibank.pay(user, order, payInfo, protocol); | ||
68 | + break; | ||
69 | + default: | ||
70 | + break; | ||
71 | + } | ||
72 | + } | ||
73 | + | ||
74 | + logger.info(`pay to url, params = ${JSON.stringify(result)}`); | ||
75 | + | ||
76 | + if (result.code === 200) { | ||
77 | + let updateInfo = yield Payment.beforePay(user, order, method, bankCode); | ||
78 | + | ||
79 | + if (updateInfo && updateInfo.code !== 200) { | ||
80 | + return updateInfo; | ||
81 | + } | ||
82 | + } | ||
83 | + | ||
84 | + return result; | ||
85 | + })(); | ||
86 | + }, | ||
87 | + | ||
88 | + beforePay(user, order, method, bankCode) { | ||
89 | + return Promise.all([ | ||
90 | + PayModel.updateOrderPayment(order.order_code, method, user.uid), | ||
91 | + PayModel.getBankByOrder(order.order_code) | ||
92 | + ]).then(result => { | ||
93 | + let paymentRecord = result[0]; | ||
94 | + let bankRecord = result[1]; | ||
95 | + | ||
96 | + if (!paymentRecord || paymentRecord.code !== 200) { | ||
97 | + let message = paymentRecord && paymentRecord.message ? paymentRecord.message : '系统繁忙,请稍后再试'; | ||
98 | + | ||
99 | + return { code: 400, message: message }; | ||
100 | + } | ||
101 | + | ||
102 | + if (bankRecord && bankRecord.bankCode) { | ||
103 | + return PayModel.updateOrderPayBank(order.order_code, method, bankCode); | ||
104 | + } else { | ||
105 | + return PayModel.setOrderPayBank(order.order_code, method, bankCode); | ||
106 | + } | ||
107 | + | ||
108 | + }).catch(e => { | ||
109 | + logger.error('update order pay info error.', e); | ||
110 | + | ||
111 | + return Promise.resolve({ | ||
112 | + code: 400, | ||
113 | + message: '更新订单支付信息失败' | ||
114 | + }); | ||
115 | + }); | ||
116 | + }, | ||
117 | + | ||
118 | + afterPay(query, payId, user, sessionKey) { | ||
119 | + return co(function*() { | ||
120 | + let payInfo = yield PayModel.getPaymentInfo(payId); | ||
121 | + let payResult = {}; | ||
122 | + let payData = {}; | ||
123 | + let payName = ''; | ||
124 | + | ||
125 | + if (payId === PayModel.payments.alipay) { | ||
126 | + payResult = Alipay.notify(query, payInfo); | ||
127 | + } else if (payId === PayModel.payments.alibank) { | ||
128 | + payResult = Alibank.notify(query, payInfo); | ||
129 | + } | ||
130 | + | ||
131 | + payResult.bankName = payName = payResult.bankName || payInfo.payName || ''; | ||
132 | + payResult.bankCode = payResult.bankCode || payInfo.pay_code || ''; | ||
133 | + | ||
134 | + // 记录日志 | ||
135 | + logger.info(`\r\n\r\n pay back confirm,req = ${JSON.stringify({ | ||
136 | + query: query, | ||
137 | + payId: payId, | ||
138 | + user: user, | ||
139 | + payResult: payResult | ||
140 | + })}`); | ||
141 | + | ||
142 | + if (payResult && payResult.payResult === 200) { | ||
143 | + if (payResult.orderCode) { | ||
144 | + logger.info('pay back confirm'); | ||
145 | + yield PayModel.sendPayConfirm(payResult.orderCode, payId, user.uid); | ||
146 | + } | ||
147 | + | ||
148 | + payData = yield PayModel.procOrderData(payResult, user.uid, sessionKey); | ||
149 | + } else { | ||
150 | + payData = { | ||
151 | + code: 500, | ||
152 | + message: '支付失败' | ||
153 | + }; | ||
154 | + } | ||
155 | + | ||
156 | + payData.payName = payName; | ||
157 | + | ||
158 | + return payData; | ||
159 | + })(); | ||
160 | + } | ||
161 | +}; | ||
162 | + | ||
163 | +module.exports = Payment; |
apps/cart/models/order.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +const _ = require('lodash'); | ||
4 | +const crypto = global.yoho.crypto; | ||
5 | + | ||
6 | +const processInvoiceData = (orderInfo, mobile, addresslist) => { | ||
7 | + let invoices_title = ''; | ||
8 | + let invoiceType = '7'; | ||
9 | + let invoices_type = '2'; | ||
10 | + let invoice_Top = '个人'; | ||
11 | + | ||
12 | + // 用户手机号处理 | ||
13 | + if (orderInfo.receiverMobile && orderInfo.isModifyTel) { | ||
14 | + mobile = orderInfo.receiverMobile; | ||
15 | + } else { | ||
16 | + _.forEach(addresslist, addressValue => { | ||
17 | + if (addressValue.address_id === crypto.encryption('', orderInfo.addressId)) { | ||
18 | + mobile = addressValue.mobile; | ||
19 | + } | ||
20 | + }); | ||
21 | + } | ||
22 | + | ||
23 | + // 发票信息处理 | ||
24 | + if (orderInfo.invoiceType && orderInfo.invoiceTitle) { | ||
25 | + invoices_title = orderInfo.invoiceText; | ||
26 | + invoiceType = orderInfo.invoiceType; | ||
27 | + invoices_type = orderInfo.invoicesType * 1; | ||
28 | + invoice_Top = orderInfo.invoiceTitle; | ||
29 | + } | ||
30 | + | ||
31 | + return { | ||
32 | + invoiceNotice: '发票须知', | ||
33 | + phone: mobile ? mobile : '', // TODO 字符串替换 **** | ||
34 | + completeTel: mobile, | ||
35 | + isCompany: invoice_Top !== '单位', | ||
36 | + companyName: invoices_title, | ||
37 | + isPaper: invoices_type === 1, | ||
38 | + invoicesType: [ | ||
39 | + { | ||
40 | + id: '2', | ||
41 | + type: '电子发票', | ||
42 | + choosed: !invoices_type || invoices_type === 2, | ||
43 | + }, | ||
44 | + { | ||
45 | + id: '1', | ||
46 | + type: '纸质发票', | ||
47 | + choosed: invoices_type === 1 | ||
48 | + } | ||
49 | + ], | ||
50 | + invoiceTitle: [ | ||
51 | + { | ||
52 | + type: '个人', | ||
53 | + choosed: invoice_Top === '个人' | ||
54 | + }, | ||
55 | + { | ||
56 | + type: '单位', | ||
57 | + choosed: invoice_Top === '单位' | ||
58 | + } | ||
59 | + ], | ||
60 | + content: [ | ||
61 | + { | ||
62 | + choosed: !invoiceType || invoiceType === 7, | ||
63 | + id: 7, | ||
64 | + text: '服装' | ||
65 | + }, | ||
66 | + { | ||
67 | + choosed: invoiceType === 9, | ||
68 | + id: 9, | ||
69 | + text: '配件' | ||
70 | + }, | ||
71 | + { | ||
72 | + choosed: invoiceType === 11, | ||
73 | + id: 11, | ||
74 | + text: '日用品' | ||
75 | + }, | ||
76 | + { | ||
77 | + choosed: invoiceType === 3, | ||
78 | + id: 3, | ||
79 | + text: '办公用品' | ||
80 | + }, | ||
81 | + { | ||
82 | + choosed: invoiceType === 6, | ||
83 | + id: 6, | ||
84 | + text: '体育用品' | ||
85 | + }, | ||
86 | + { | ||
87 | + choosed: invoiceType === 10, | ||
88 | + id: 10, | ||
89 | + text: '数码产品' | ||
90 | + }, | ||
91 | + ] | ||
92 | + }; | ||
93 | + | ||
94 | +}; | ||
95 | + | ||
96 | +module.exports = { | ||
97 | + processInvoiceData | ||
98 | +}; |
apps/cart/models/pay-api.js
0 → 100644
1 | +/** | ||
2 | + * 支付相关api调用 | ||
3 | + * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
4 | + * @date: 2016/07/18 | ||
5 | + */ | ||
6 | + | ||
7 | +'use strict'; | ||
8 | + | ||
9 | +const api = global.yoho.API; | ||
10 | + | ||
11 | +// 获取支付宝等平台支付方式列表 | ||
12 | +const getPayProvider = () => { | ||
13 | + return api.get('', { | ||
14 | + method: 'web.SpaceOrders.getPaymentList' | ||
15 | + }, {cache: true}); | ||
16 | +}; | ||
17 | + | ||
18 | +// 获取单个支付方式相关详细信息 | ||
19 | +const getPaymentInfo = (id) => { | ||
20 | + return api.get('', { | ||
21 | + method: 'web.SpaceOrders.getPaymentById', | ||
22 | + id: id | ||
23 | + }, {cache: true}); | ||
24 | +}; | ||
25 | + | ||
26 | +/* 获取上次使用的支付方式*/ | ||
27 | +const getBankByOrder = (code) => { | ||
28 | + return api.get('', { | ||
29 | + method: 'web.SpaceOrders.getOrderPayBank', | ||
30 | + orderCode: code | ||
31 | + }); | ||
32 | +}; | ||
33 | + | ||
34 | +/* 记录支付方式*/ | ||
35 | +const setOrderPayBank = (code, payment, bankCode) => { | ||
36 | + return api.get('', { | ||
37 | + method: 'web.SpaceOrders.addOrderPayBank', | ||
38 | + orderCode: code, | ||
39 | + payment: payment, | ||
40 | + bankCode: bankCode | ||
41 | + }); | ||
42 | +}; | ||
43 | + | ||
44 | +/* 更改支付方式*/ | ||
45 | +const updateOrderPayBank = (code, payment, bankCode) => { | ||
46 | + return api.get('', { | ||
47 | + method: 'web.SpaceOrders.modifyOrderPayBank', | ||
48 | + orderCode: code, | ||
49 | + payment: payment, | ||
50 | + bankCode: bankCode | ||
51 | + }); | ||
52 | +}; | ||
53 | + | ||
54 | +/* 发送支付确认*/ | ||
55 | +const sendPayConfirm = (code, payment, uid) => { | ||
56 | + return api.get('', { | ||
57 | + method: 'app.SpaceOrders.payConfirm', | ||
58 | + order_code: code, | ||
59 | + payment_id: payment, | ||
60 | + uid: uid | ||
61 | + }); | ||
62 | +}; | ||
63 | + | ||
64 | +const sendMessage = (mobile, template, codes) => { | ||
65 | + return api.get('', { | ||
66 | + method: 'app.message.sendMsg', | ||
67 | + mobile: mobile, | ||
68 | + template: template, | ||
69 | + codes: codes | ||
70 | + }); | ||
71 | +}; | ||
72 | + | ||
73 | +module.exports = { | ||
74 | + getPayProvider, | ||
75 | + getPaymentInfo, | ||
76 | + getBankByOrder, | ||
77 | + setOrderPayBank, | ||
78 | + updateOrderPayBank, | ||
79 | + sendPayConfirm, | ||
80 | + sendMessage | ||
81 | +}; |
1 | /** | 1 | /** |
2 | - * 支付成功页 | 2 | + * 支付 |
3 | * @author: jing.li<jing.li@yoho.cn> | 3 | * @author: jing.li<jing.li@yoho.cn> |
4 | * @date: 2016/10/25 | 4 | * @date: 2016/10/25 |
5 | */ | 5 | */ |
@@ -10,7 +10,18 @@ const api = global.yoho.API; | @@ -10,7 +10,18 @@ const api = global.yoho.API; | ||
10 | const serviceAPI = global.yoho.ServiceAPI; | 10 | const serviceAPI = global.yoho.ServiceAPI; |
11 | const utils = '../../../utils'; | 11 | const utils = '../../../utils'; |
12 | const productProcess = require(`${utils}/product-process`); | 12 | const productProcess = require(`${utils}/product-process`); |
13 | +const payApi = require('./pay-api'); | ||
13 | const helpers = global.yoho.helpers; | 14 | const helpers = global.yoho.helpers; |
15 | +const _ = require('lodash'); | ||
16 | +const co = require('bluebird').coroutine; | ||
17 | +const logger = global.yoho.logger; | ||
18 | + | ||
19 | +// 支付方式 | ||
20 | +const payments = { | ||
21 | + alipay: 33, | ||
22 | + wechat: 36, | ||
23 | + alibank: 42 | ||
24 | +}; | ||
14 | 25 | ||
15 | // 资源位 | 26 | // 资源位 |
16 | const _getBanner = (param) => { | 27 | const _getBanner = (param) => { |
@@ -51,7 +62,8 @@ const _getOtherDetail = (param) => { | @@ -51,7 +62,8 @@ const _getOtherDetail = (param) => { | ||
51 | return api.get('', { | 62 | return api.get('', { |
52 | method: 'app.SpaceOrders.detail', | 63 | method: 'app.SpaceOrders.detail', |
53 | uid: param.uid, | 64 | uid: param.uid, |
54 | - order_code: param.orderCode | 65 | + order_code: param.orderCode, |
66 | + session_key: param.sessionKey | ||
55 | }, { | 67 | }, { |
56 | code: 200 | 68 | code: 200 |
57 | }).then((result) => { | 69 | }).then((result) => { |
@@ -73,7 +85,7 @@ const _getOthersBuy = (param) => { | @@ -73,7 +85,7 @@ const _getOthersBuy = (param) => { | ||
73 | goodSkn = result[0].data.order_goods[0].product_skn; | 85 | goodSkn = result[0].data.order_goods[0].product_skn; |
74 | } | 86 | } |
75 | 87 | ||
76 | - return _getOthersBuy2(Object.assign(param, {skn: goodSkn})); | 88 | + return _getOthersBuy2(Object.assign(param, { skn: goodSkn })); |
77 | 89 | ||
78 | }).then((result) => { | 90 | }).then((result) => { |
79 | 91 | ||
@@ -82,29 +94,224 @@ const _getOthersBuy = (param) => { | @@ -82,29 +94,224 @@ const _getOthersBuy = (param) => { | ||
82 | }; | 94 | }; |
83 | 95 | ||
84 | /** | 96 | /** |
97 | + * 获取订单支付银行信息 | ||
98 | + * @param id | ||
99 | + */ | ||
100 | +const getBankByOrder = (id) => { | ||
101 | + return co(function*() { | ||
102 | + let result = yield payApi.getBankByOrder(id); | ||
103 | + | ||
104 | + if (result && result.code === 200 && result.data) { | ||
105 | + return result.data; | ||
106 | + } | ||
107 | + return {}; | ||
108 | + })(); | ||
109 | +}; | ||
110 | + | ||
111 | +/** | ||
112 | + * 设置订单支付银行 | ||
113 | + * @param code | ||
114 | + * @param payment | ||
115 | + * @param bankCode | ||
116 | + */ | ||
117 | +const setOrderPayBank = (code, payment, bankCode) => { | ||
118 | + return co(function*() { | ||
119 | + let data = yield payApi.setOrderPayBank(code, payment, bankCode); | ||
120 | + | ||
121 | + return data; | ||
122 | + })(); | ||
123 | +}; | ||
124 | + | ||
125 | +/** | ||
126 | + * 获取支付方式的相关参数, (密钥等信息) | ||
127 | + * @param id | ||
128 | + */ | ||
129 | +const getPaymentInfo = (id) => { | ||
130 | + return co(function*() { | ||
131 | + let result = yield payApi.getPaymentInfo(id); | ||
132 | + | ||
133 | + if (result && result.code === 200 && result.data) { | ||
134 | + return result.data; | ||
135 | + } | ||
136 | + return {}; | ||
137 | + })(); | ||
138 | +}; | ||
139 | + | ||
140 | +/** | ||
141 | + * 支付确认 | ||
142 | + * @param code | ||
143 | + * @param payment | ||
144 | + * @param uid | ||
145 | + */ | ||
146 | +const sendPayConfirm = (code, payment, uid) => { | ||
147 | + return co(function*() { | ||
148 | + let data = yield payApi.sendPayConfirm(code, payment, uid); | ||
149 | + | ||
150 | + return data; | ||
151 | + })(); | ||
152 | +}; | ||
153 | + | ||
154 | +/** | ||
155 | + * 更新订单支付方式 | ||
156 | + * @param code | ||
157 | + * @param payment | ||
158 | + * @param uid | ||
159 | + * @returns {*} | ||
160 | + */ | ||
161 | +const updateOrderPayment = (code, payment, uid) => { | ||
162 | + return api.get('', { | ||
163 | + method: 'app.SpaceOrders.updateOrdersPaymentByCode', | ||
164 | + order_code: code, | ||
165 | + payment: payment, | ||
166 | + uid: uid | ||
167 | + }); | ||
168 | +}; | ||
169 | + | ||
170 | +/** | ||
171 | + * 更新订单支付银行 | ||
172 | + * @param code | ||
173 | + * @param payment | ||
174 | + * @param bankCode | ||
175 | + */ | ||
176 | +const updateOrderPayBank = (code, payment, bankCode) => { | ||
177 | + return co(function*() { | ||
178 | + let data = yield payApi.updateOrderPayBank(code, payment, bankCode); | ||
179 | + | ||
180 | + return data; | ||
181 | + })(); | ||
182 | +}; | ||
183 | + | ||
184 | +/** | ||
185 | + * 支付成功,前端回调时,处理订单信息 | ||
186 | + * @param payResult | ||
187 | + * @param uid | ||
188 | + * @param sessionKey | ||
189 | + */ | ||
190 | +const procOrderData = (payResult, uid, sessionKey) => { | ||
191 | + return co(function*() { | ||
192 | + let orderCode = payResult.orderCode; | ||
193 | + let result = { code: 400, message: '' }; | ||
194 | + | ||
195 | + if (!orderCode) { | ||
196 | + result.message = '未查到订单信息,订单状态更新失败!'; | ||
197 | + return result; | ||
198 | + } else { | ||
199 | + let orderInfo = yield _getOtherDetail({ | ||
200 | + uid: uid, | ||
201 | + orderCode: orderCode, | ||
202 | + sessionKey: sessionKey | ||
203 | + }); | ||
204 | + | ||
205 | + if (orderInfo && orderInfo.data) { | ||
206 | + let order = orderInfo.data; | ||
207 | + let amount = order.payment_amount; | ||
208 | + | ||
209 | + if (order.is_cancel === 'Y') { | ||
210 | + logger.warn('front pay success but order is cancel.', { payResult: payResult, order: order }); | ||
211 | + | ||
212 | + payApi.sendMessage(order.mobile, 'error_sms', '支付成功,但订单已取消,订单号为' + orderCode); | ||
213 | + return { code: 417, message: '支付成功,但订单已取消,需联系客服!' }; | ||
214 | + } | ||
215 | + | ||
216 | + if (order.payment_status === 'N') { | ||
217 | + logger.warn('front pay success but may be notify fail'); | ||
218 | + } | ||
219 | + | ||
220 | + if (_.round(parseFloat(amount), 2) !== _.round(parseFloat(payResult.totalFee), 2)) { | ||
221 | + logger.warn('front pay success but the amount is not same.', { payResult: payResult, order: order }); | ||
222 | + return { | ||
223 | + code: 415, | ||
224 | + message: '支付金额与订单金额不一致,订单状态更新失败!' | ||
225 | + }; | ||
226 | + } | ||
227 | + | ||
228 | + return { | ||
229 | + code: 200, | ||
230 | + message: '支付成功,请等待发货', | ||
231 | + data: { | ||
232 | + order: order | ||
233 | + } | ||
234 | + }; | ||
235 | + | ||
236 | + } else { | ||
237 | + result.message = '未查到订单信息,订单状态更新失败!'; | ||
238 | + } | ||
239 | + } | ||
240 | + | ||
241 | + return result; | ||
242 | + })(); | ||
243 | +}; | ||
244 | + | ||
245 | +/** | ||
246 | + * 支付相关的数据处理函数 | ||
247 | + */ | ||
248 | +const payTool = { | ||
249 | + | ||
250 | + /** | ||
251 | + * 支持的支付方式列表 | ||
252 | + * @returns {[*,*]} | ||
253 | + */ | ||
254 | + payAppInfo(orderCode) { | ||
255 | + return [{ | ||
256 | + appIcon: '', | ||
257 | + payLink: helpers.urlFormat('/cart/index/new/pay/goalipay', { | ||
258 | + payment: payments.alipay + '_platform', | ||
259 | + order_code: orderCode | ||
260 | + }), | ||
261 | + appId: 'alipay', | ||
262 | + app: '支付宝支付', | ||
263 | + hint: '支付宝钱包支付', | ||
264 | + subHint: '推荐支付宝用户使用' | ||
265 | + }, { | ||
266 | + appIcon: '', | ||
267 | + payLink: '', | ||
268 | + appId: 'weixin', | ||
269 | + app: '微信支付', | ||
270 | + hint: '推荐使用', | ||
271 | + subHint: '' | ||
272 | + }]; | ||
273 | + }, | ||
274 | + | ||
275 | + /** | ||
276 | + * 计算购买商品总数量 | ||
277 | + * @param goodsArray | ||
278 | + * @returns {number} | ||
279 | + * @private | ||
280 | + */ | ||
281 | + calBuyNumCount(goodsArray) { | ||
282 | + let buyNumCount = 0; | ||
283 | + | ||
284 | + if (_.isArray(goodsArray)) { | ||
285 | + _.forEach(goodsArray, value => { | ||
286 | + buyNumCount = value.buy_number ? parseInt(value.buy_number, 10) : 0; | ||
287 | + }); | ||
288 | + } | ||
289 | + | ||
290 | + return buyNumCount; | ||
291 | + } | ||
292 | +}; | ||
293 | + | ||
294 | +/** | ||
85 | * 支付中心 | 295 | * 支付中心 |
86 | * @param params | 296 | * @param params |
87 | */ | 297 | */ |
88 | const payCenter = (params) => { | 298 | const payCenter = (params) => { |
89 | - return Promise.resolve({ | ||
90 | - payList: [ | ||
91 | - { | ||
92 | - appIcon: '', | ||
93 | - payLink: helpers.urlFormat('/shopping/pay/index'), | ||
94 | - appId: 'alipay', | ||
95 | - app: '支付宝支付', | ||
96 | - hint: '支付宝钱包支付', | ||
97 | - subHint: '推荐支付宝用户使用' | ||
98 | - }, | ||
99 | - { | ||
100 | - appIcon: '', | ||
101 | - payLink: '', | ||
102 | - appId: 'weixin', | ||
103 | - app: '微信支付', | ||
104 | - hint: '推荐使用', | ||
105 | - subHint: '' | ||
106 | - } | ||
107 | - ] | 299 | + |
300 | + return _getOtherDetail({ | ||
301 | + uid: params.uid, | ||
302 | + orderCode: params.orderCode | ||
303 | + }).then(result => { | ||
304 | + let resultData = _.get(result, 'data', {}); | ||
305 | + | ||
306 | + return { | ||
307 | + payAppInfo: payTool.payAppInfo(params.orderCode), | ||
308 | + orderCode: params.orderCode, | ||
309 | + hasWxShare: true, | ||
310 | + orderTotal: resultData.payment_amount || 0, | ||
311 | + orderTotalFormat: parseInt(resultData.payment_amount, 10), | ||
312 | + orderCount: payTool.calBuyNumCount(resultData.order_goods), | ||
313 | + uid: params.uid | ||
314 | + }; | ||
108 | }); | 315 | }); |
109 | }; | 316 | }; |
110 | 317 | ||
@@ -181,6 +388,15 @@ const getPayAli = (param) => { | @@ -181,6 +388,15 @@ const getPayAli = (param) => { | ||
181 | }; | 388 | }; |
182 | 389 | ||
183 | module.exports = { | 390 | module.exports = { |
391 | + payments, | ||
392 | + getOtherDetail: _getOtherDetail, | ||
393 | + updateOrderPayment, | ||
394 | + updateOrderPayBank, | ||
395 | + getBankByOrder, | ||
396 | + getPaymentInfo, | ||
397 | + setOrderPayBank, | ||
398 | + sendPayConfirm, | ||
399 | + procOrderData, | ||
184 | payCenter, | 400 | payCenter, |
185 | getPayCod, | 401 | getPayCod, |
186 | getPayAli | 402 | getPayAli |
@@ -25,8 +25,10 @@ router.post('/index/seckill/submit', seckill.submit); | @@ -25,8 +25,10 @@ router.post('/index/seckill/submit', seckill.submit); | ||
25 | 25 | ||
26 | router.get('/index/count', countController.cartCount); | 26 | router.get('/index/count', countController.cartCount); |
27 | router.get('/paySuccess/payCod', payController.payCod);// 支付成功,货到付款 | 27 | router.get('/paySuccess/payCod', payController.payCod);// 支付成功,货到付款 |
28 | -router.get('/index/new/pay/center', payController.payCenter);// 支付成功,支付宝付款 | ||
29 | -router.get('/index/new/pay/aliwapreturn', payController.payAli);// 支付成功,支付宝付款 | 28 | + |
29 | +router.get('/index/new/pay', authMW, payController.payCenter);// 支付中心 | ||
30 | +router.get('/index/new/pay/goalipay', authMW, payController.goAlipay);// 跳支付宝支付 | ||
31 | +router.get('/index/new/pay/aliwapreturn', authMW, payController.payAli);// 支付宝付款支付成功 | ||
30 | 32 | ||
31 | router.get('/index/new/orderEnsure', authMW, order.orderEnsure); // 订单结算 | 33 | router.get('/index/new/orderEnsure', authMW, order.orderEnsure); // 订单结算 |
32 | router.get('/index/new/selectCoupon', authMW, order.selectCoupon); // 选择优惠券 页面 | 34 | router.get('/index/new/selectCoupon', authMW, order.selectCoupon); // 选择优惠券 页面 |
@@ -132,7 +132,7 @@ | @@ -132,7 +132,7 @@ | ||
132 | <input type="hidden" class="user-mobile" value="{{userMobile}}" /> | 132 | <input type="hidden" class="user-mobile" value="{{userMobile}}" /> |
133 | <span class="title">发票</span> | 133 | <span class="title">发票</span> |
134 | <span class="iconfont checkbox {{#if needInvoice}}icon-cb-radio{{else}}icon-radio{{/if}}"></span> | 134 | <span class="iconfont checkbox {{#if needInvoice}}icon-cb-radio{{else}}icon-radio{{/if}}"></span> |
135 | - <a id="invoice" class="invoice-info" href="/cart/index/invoiceInfo"> | 135 | + <a id="invoice" class="invoice-info" href="/cart/index/new/invoiceInfo"> |
136 | <span class="title">发票信息</span> | 136 | <span class="title">发票信息</span> |
137 | <span class="invoice-type"><i class="iconfont"></i></span> | 137 | <span class="invoice-type"><i class="iconfont"></i></span> |
138 | </a> | 138 | </a> |
@@ -3,7 +3,6 @@ | @@ -3,7 +3,6 @@ | ||
3 | <input id='ordercode' type="hidden" value="{{orderCode}}"> | 3 | <input id='ordercode' type="hidden" value="{{orderCode}}"> |
4 | {{/if}} | 4 | {{/if}} |
5 | <div class="payapp-list"> | 5 | <div class="payapp-list"> |
6 | - {{log payAppInfo}} | ||
7 | {{# payAppInfo}} | 6 | {{# payAppInfo}} |
8 | {{#if payLink}} | 7 | {{#if payLink}} |
9 | <a href="{{payLink}}"> | 8 | <a href="{{payLink}}"> |
apps/cart/views/action/select-invoice.hbs
0 → 100644
1 | +<div class="invoice-info-page yoho-page"> | ||
2 | + <ul class="invoice-form"> | ||
3 | + <li> | ||
4 | + <span class="title">发票类型:</span> | ||
5 | + <div class="invoice-type"> | ||
6 | + {{#invoicesType}} | ||
7 | + <span {{#if choosed}}class="on"{{/if}} data-id="{{id}}">{{type}}</span> | ||
8 | + {{/invoicesType}} | ||
9 | + </div> | ||
10 | + </li> | ||
11 | + <li> | ||
12 | + <span class="title">发票抬头:</span> | ||
13 | + <div class="invoice-top"> | ||
14 | + {{#invoiceTitle}} | ||
15 | + <span {{#if choosed}}class="on"{{/if}}><i class="iconfont choose {{#if choosed}}icon-cb-radio{{else}}icon-radio{{/if}}"></i>{{type}}</span> | ||
16 | + {{/invoiceTitle}} | ||
17 | + </div> | ||
18 | + </li> | ||
19 | + <li {{#isPaper}}style="display: none;"{{/isPaper}} class="tel-area"> | ||
20 | + <span class="title"><i class="txt-point">*</i>发票人手机:</span> | ||
21 | + <span class="phone"> | ||
22 | + <input type="hidden" class="copy-tel" value="{{completeTel}}"> | ||
23 | + <input type="text" name="tel" data-tel="{{completeTel}}" class="tel {{#phone}}istel{{/phone}}" value="{{phone}}" placeholder="可通过手机号在发票服务平台查询"> | ||
24 | + </span> | ||
25 | + </li> | ||
26 | + | ||
27 | + <li class="company-area" {{#isCompany}}style="display: none;"{{/isCompany}}><input type="text" name="company" class="company" value="{{companyName}}" placeholder="填写单位名称" maxlength="30"></li> | ||
28 | + </ul> | ||
29 | + | ||
30 | + <ul class="invoice-cont"> | ||
31 | + <li class="cont-title"> | ||
32 | + <span>发票内容:</span> | ||
33 | + <span class="choose-cont" data-id=""></span> | ||
34 | + </li> | ||
35 | + {{#each content}} | ||
36 | + <li><span class="iconfont choose {{#if choosed}}icon-cb-radio{{else}}icon-radio{{/if}}" data-id="{{id}}"></span>{{text}}</li> | ||
37 | + {{/each}} | ||
38 | + </ul> | ||
39 | + | ||
40 | + <div class="btn-area"><span class="confirm-btn">确认</span></div> | ||
41 | + | ||
42 | + <div class="invoice-notice"> | ||
43 | + <div class="mask-bg"></div> | ||
44 | + <div class="notice-area"> | ||
45 | + <div class="notice-cont"> | ||
46 | + <h2>发票须知</h2> | ||
47 | + <p>1、发票金额不含优惠券/有货币/红包/优惠码/运费,只包含商品实付金额</p> | ||
48 | + <p>2、电子发票:是税局认可的有效收付款凭证,其法律效力、基本用途及使用规定同纸质发票,如需纸质发票可自行下载打印</p> | ||
49 | + </div> | ||
50 | + <div class="think-ok">我知道了</div> | ||
51 | + </div> | ||
52 | + </div> | ||
53 | + | ||
54 | + <input type="hidden" class="edit-flag" value="false" /> | ||
55 | + <input type="hidden" class="address-more" value="{{addressMore}}" /> | ||
56 | +</div> |
@@ -21,3 +21,10 @@ exports.queryProfile = (uid) => { | @@ -21,3 +21,10 @@ exports.queryProfile = (uid) => { | ||
21 | 21 | ||
22 | return api.get('', params, options); | 22 | return api.get('', params, options); |
23 | }; | 23 | }; |
24 | + | ||
25 | +exports.addressTextData = (uid) => { | ||
26 | + return api.get('', { | ||
27 | + method: 'app.address.get', | ||
28 | + uid: uid | ||
29 | + }); | ||
30 | +}; |
@@ -16,21 +16,29 @@ module.exports = { | @@ -16,21 +16,29 @@ module.exports = { | ||
16 | siteUrl: '//m.yohobuy.com', | 16 | siteUrl: '//m.yohobuy.com', |
17 | assetUrl: '//127.0.0.1:5001', | 17 | assetUrl: '//127.0.0.1:5001', |
18 | domains: { | 18 | domains: { |
19 | - // api: 'http://api-test3.yohops.com:9999/', | ||
20 | - // service: 'http://service-test3.yohops.com:9999/', | ||
21 | - // liveApi: 'http://testapi.live.yohops.com:9999/', | ||
22 | - // singleApi: 'http://api-test3.yohops.com:9999/', | ||
23 | - // imSocket: 'ws://im.yohobuy.com:10240', | ||
24 | - // imCs: 'http://im.yohobuy.com/api', | ||
25 | - // imServer: 'http://im.yohobuy.com/server' | 19 | + api: 'http://api-test3.yohops.com:9999/', |
20 | + service: 'http://service-test3.yohops.com:9999/', | ||
21 | + liveApi: 'http://testapi.live.yohops.com:9999/', | ||
22 | + singleApi: 'http://api-test3.yohops.com:9999/', | ||
23 | + imSocket: 'ws://im.yohobuy.com:10240', | ||
24 | + imCs: 'http://im.yohobuy.com/api', | ||
25 | + imServer: 'http://im.yohobuy.com/server', | ||
26 | 26 | ||
27 | - api: 'http://dev-api.yohops.com:9999/', | ||
28 | - service: 'http://service.yoho.cn/', | ||
29 | - liveApi: 'http://api.live.yoho.cn/', | ||
30 | - singleApi: 'http://single.yoho.cn/', | ||
31 | - imSocket: 'ws://imsocket.yohobuy.com:10000', | ||
32 | - imCs: 'http://imhttp.yohobuy.com/api', | ||
33 | - imServer: 'http://imhttp.yohobuy.com/server' | 27 | + // api: 'http://api.yoho.cn/', |
28 | + // service: 'http://service.yoho.cn/', | ||
29 | + // liveApi: 'http://api.live.yoho.cn/', | ||
30 | + // singleApi: 'http://single.yoho.cn/', | ||
31 | + // imSocket: 'ws://imsocket.yohobuy.com:10000', | ||
32 | + // imCs: 'http://imhttp.yohobuy.com/api', | ||
33 | + // imServer: 'http://imhttp.yohobuy.com/server' | ||
34 | + | ||
35 | + // api: 'http://dev-api.yohops.com:9999/', | ||
36 | + // service: 'http://service.yoho.cn/', | ||
37 | + // liveApi: 'http://api.live.yoho.cn/', | ||
38 | + // singleApi: 'http://single.yoho.cn/', | ||
39 | + // imSocket: 'ws://imsocket.yohobuy.com:10000', | ||
40 | + // imCs: 'http://imhttp.yohobuy.com/api', | ||
41 | + // imServer: 'http://imhttp.yohobuy.com/server' | ||
34 | }, | 42 | }, |
35 | subDomains: { | 43 | subDomains: { |
36 | host: '.m.yohobuy.com', | 44 | host: '.m.yohobuy.com', |
@@ -86,7 +94,20 @@ module.exports = { | @@ -86,7 +94,20 @@ module.exports = { | ||
86 | appSecret: 'ce21ae4a3f93852279175a167e54509b' | 94 | appSecret: 'ce21ae4a3f93852279175a167e54509b' |
87 | } | 95 | } |
88 | }, | 96 | }, |
89 | - zookeeperServer: '192.168.102.168:2188' | 97 | + zookeeperServer: '192.168.102.168:2188', |
98 | + alipayConfig: { | ||
99 | + payUrl: 'https://mapi.alipay.com/gateway.do', | ||
100 | + service: 'alipay.wap.create.direct.pay.by.user', | ||
101 | + partner: '2088701661478015', | ||
102 | + inputCharset: 'utf-8', | ||
103 | + notifyUrl: 'payment/alipay_notify', | ||
104 | + returnUrl: '/shopping/pay/aliwapreturn', | ||
105 | + signType: 'MD5', | ||
106 | + paymentType: '1', | ||
107 | + alipayKey: 'kcxawi9bb07mzh0aq2wcirsf9znusobw', | ||
108 | + sellerMail: 'zfb@yoho.cn', | ||
109 | + merchantUrl: 'http://m.yohobuy.com/home/orders/detail?order_code=' | ||
110 | + } | ||
90 | }; | 111 | }; |
91 | 112 | ||
92 | if (isProduction) { | 113 | if (isProduction) { |
@@ -43,6 +43,7 @@ | @@ -43,6 +43,7 @@ | ||
43 | "request-promise": "^3.0.0", | 43 | "request-promise": "^3.0.0", |
44 | "serve-favicon": "^2.3.2", | 44 | "serve-favicon": "^2.3.2", |
45 | "uuid": "^2.0.3", | 45 | "uuid": "^2.0.3", |
46 | + "xml2js": "^0.4.17", | ||
46 | "yoho-node-lib": "0.2.2", | 47 | "yoho-node-lib": "0.2.2", |
47 | "yoho-zookeeper": "^1.0.4" | 48 | "yoho-zookeeper": "^1.0.4" |
48 | }, | 49 | }, |
public/js/cart/select-invoice.page.js
0 → 100644
1 | +/** | ||
2 | + * 发票信息 | ||
3 | + * @author: wsl<shuiling.wang@yoho.cn> | ||
4 | + * @date: 2016/6/14 | ||
5 | + */ | ||
6 | + | ||
7 | +var $ = require('yoho-jquery'), | ||
8 | + tip = require('../plugin/tip'), | ||
9 | + dialog = require('../plugin/dialog'), | ||
10 | + order = require('./order-info'); | ||
11 | + | ||
12 | +var $invoiceNotice = $('.invoice-notice'), | ||
13 | + $companyArea = $('.company-area'), | ||
14 | + $editFlag = $('.edit-flag'), | ||
15 | + $chooseCont = $('.choose-cont'), | ||
16 | + $invoiceType = $('.invoice-type'), | ||
17 | + $tel = $('.tel'), | ||
18 | + $company = $('.company'), | ||
19 | + $telArea = $('.tel-area'), | ||
20 | + orderInfo = order.orderInfo, | ||
21 | + $chooseContLi = $('.invoice-cont').find('.icon-cb-radio').parent(), | ||
22 | + $copyTel = $('.copy-tel'), | ||
23 | + isModifyTel = false; | ||
24 | + | ||
25 | +var myreg = /^(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1}))+\d{8})$/, | ||
26 | + linkUrl = $('.address-more').val() || '/cart/index/orderEnsure?cartType=ordinary'; | ||
27 | + | ||
28 | +var C_ID = window._ChannelVary[window.cookie('_Channel')] || 1; | ||
29 | + | ||
30 | +require('../common'); | ||
31 | + | ||
32 | +if (window.getUid() !== orderInfo('uid')) { | ||
33 | + order.init(); | ||
34 | + window.location.reload(); | ||
35 | +} | ||
36 | + | ||
37 | +// 单选效果 | ||
38 | +function chooseAction(pDom, dom) { | ||
39 | + if (dom.hasClass('icon-cb-radio')) { | ||
40 | + return; | ||
41 | + } else { | ||
42 | + pDom.find('.choose').removeClass('icon-cb-radio icon-radio').addClass('icon-radio'); | ||
43 | + dom.removeClass('icon-radio').addClass('icon-cb-radio'); | ||
44 | + dom.parent().addClass('on'); | ||
45 | + dom.parent().siblings().removeClass('on'); | ||
46 | + $editFlag.val('true'); | ||
47 | + } | ||
48 | +} | ||
49 | + | ||
50 | +// 确认表单事件 | ||
51 | +function confirmAction() { | ||
52 | + var type = $invoiceType.find('.on').data('id'), | ||
53 | + title = $('.invoice-top').find('.on').text(), | ||
54 | + tel = $tel.attr('data-tel'), | ||
55 | + company = $company.val(), | ||
56 | + cont = $chooseCont.data('id'); | ||
57 | + | ||
58 | + if ($editFlag.val() === 'true') { | ||
59 | + if (type === 2 && !myreg.test($tel.attr('data-tel'))) { | ||
60 | + tip.show('请输入正确手机号'); | ||
61 | + $tel.focus(); | ||
62 | + return false; | ||
63 | + } else if (title === '单位' && company.length === 0) { | ||
64 | + tip.show('请填写发票抬头'); | ||
65 | + $company.focus(); | ||
66 | + return false; | ||
67 | + } else if (title === '单位' && company.length > 30) { | ||
68 | + tip.show('发票抬头不得超过30个汉字'); | ||
69 | + $company.focus(); | ||
70 | + return false; | ||
71 | + } else { | ||
72 | + dialog.showDialog({ | ||
73 | + dialogText: '确认保存修改内容?', | ||
74 | + hasFooter: { | ||
75 | + leftBtnText: '取消', | ||
76 | + rightBtnText: '确定' | ||
77 | + } | ||
78 | + }, function() { | ||
79 | + orderInfo('invoiceText', (title === '单位' ? company : '')); | ||
80 | + orderInfo('invoiceType', cont); | ||
81 | + orderInfo('receiverMobile', tel); | ||
82 | + orderInfo('invoicesType', type); | ||
83 | + orderInfo('invoiceTitle', title); | ||
84 | + | ||
85 | + if (isModifyTel && $copyTel !== tel) { | ||
86 | + orderInfo('isModifyTel', true); | ||
87 | + } else { | ||
88 | + orderInfo('isModifyTel', false); | ||
89 | + } | ||
90 | + | ||
91 | + dialog.showDialog({ | ||
92 | + dialogText: '保存成功', | ||
93 | + autoHide: true, | ||
94 | + fast: true | ||
95 | + }); | ||
96 | + window.location.href = linkUrl; | ||
97 | + }, function() { | ||
98 | + window.location.href = linkUrl; | ||
99 | + }); | ||
100 | + } | ||
101 | + } else { | ||
102 | + window.location.href = linkUrl; | ||
103 | + } | ||
104 | +} | ||
105 | + | ||
106 | +$chooseCont.html($chooseContLi.text()).attr('data-id', $chooseContLi.find('span').data('id')); | ||
107 | + | ||
108 | +// 发票抬头、发票内容选择 | ||
109 | +$('.invoice-top span, .invoice-cont li').not('.invoice-cont .cont-title').on('touchstart', function() { | ||
110 | + chooseAction($(this).parent(), $(this).find('.choose')); | ||
111 | + | ||
112 | + if ($(this).parent().hasClass('invoice-cont')) { | ||
113 | + $chooseCont.html($(this).text()).attr('data-id', $(this).find('span').data('id')); | ||
114 | + } | ||
115 | + | ||
116 | + if ($(this).text() === '单位') { | ||
117 | + $companyArea.slideDown(); | ||
118 | + } | ||
119 | + | ||
120 | + if ($(this).text() === '个人') { | ||
121 | + $companyArea.slideUp(); | ||
122 | + } | ||
123 | +}); | ||
124 | + | ||
125 | +// 发票类型选择 | ||
126 | +$('.invoice-type span').on('touchstart', function() { | ||
127 | + if ($(this).hasClass('on')) { | ||
128 | + return; | ||
129 | + } else { | ||
130 | + $(this).addClass('on').siblings().removeClass('on'); | ||
131 | + $editFlag.val('true'); | ||
132 | + | ||
133 | + // 纸质发票不显示手机号 | ||
134 | + if ($(this).index() === 1) { | ||
135 | + $telArea.slideUp(); | ||
136 | + } else { | ||
137 | + $telArea.slideDown(); | ||
138 | + } | ||
139 | + } | ||
140 | +}); | ||
141 | + | ||
142 | +// 发票须知 | ||
143 | +$('.invoice-btn').on('touchstart', function() { | ||
144 | + $invoiceNotice.fadeIn(); | ||
145 | + return false; | ||
146 | +}); | ||
147 | + | ||
148 | +// 关闭发票须知弹框 | ||
149 | +$('.think-ok, .mask-bg').on('touchstart', function() { | ||
150 | + $invoiceNotice.fadeOut(); | ||
151 | +}); | ||
152 | + | ||
153 | +// 电话清空 | ||
154 | +$('.istel').one('input', function() { | ||
155 | + $(this).val('').removeClass('istel'); | ||
156 | +}); | ||
157 | + | ||
158 | +$tel.on('input', function() { | ||
159 | + $(this).attr('data-tel', $(this).val()); | ||
160 | + $editFlag.val('true'); | ||
161 | + isModifyTel = true; | ||
162 | +}); | ||
163 | + | ||
164 | +$company.on('input', function() { | ||
165 | + $editFlag.val('true'); | ||
166 | +}); | ||
167 | + | ||
168 | +// 确认及返回事件 | ||
169 | +$('.confirm-btn, .nav-back').on('touchstart', function(e) { | ||
170 | + | ||
171 | + setTimeout(function() { | ||
172 | + if (window._yas && window._yas.sendCustomInfo) { | ||
173 | + window._yas.sendCustomInfo({ | ||
174 | + op: 'YB_SC_INVOICE_INFO_SAVE', | ||
175 | + param: JSON.stringify({ | ||
176 | + C_ID: C_ID, | ||
177 | + INVOICE_TYPE: $invoiceType.find('.on').data('id'), | ||
178 | + INVOICE_TITLE: $('.invoice-top').find('.on').text(), | ||
179 | + INVOICE_CONTENT: $chooseCont.data('id') | ||
180 | + }) | ||
181 | + }, true); | ||
182 | + } | ||
183 | + }, 200); | ||
184 | + | ||
185 | + e.preventDefault(); | ||
186 | + confirmAction(); | ||
187 | +}); | ||
188 | + | ||
189 | +// initData(); |
-
Please register or login to post a comment