Merge branch 'release/5.2' of git.yoho.cn:fe/yohobuywap-node into release/5.2
Showing
24 changed files
with
440 additions
and
70 deletions
@@ -55,7 +55,6 @@ const getRssArticle = (gender) => { | @@ -55,7 +55,6 @@ const getRssArticle = (gender) => { | ||
55 | resolve(result); | 55 | resolve(result); |
56 | } | 56 | } |
57 | }; | 57 | }; |
58 | - | ||
59 | return new Promise((resolve) => { | 58 | return new Promise((resolve) => { |
60 | artListFunc(0, article.data.list.artList.length, resolve); | 59 | artListFunc(0, article.data.list.artList.length, resolve); |
61 | }); | 60 | }); |
@@ -96,4 +95,4 @@ const _genIntro = (id) => { | @@ -96,4 +95,4 @@ const _genIntro = (id) => { | ||
96 | 95 | ||
97 | module.exports = { | 96 | module.exports = { |
98 | getRssArticle | 97 | getRssArticle |
99 | -}; | 98 | +}; |
@@ -11,11 +11,11 @@ const headerModel = require('../../../doraemon/models/header'); // 头部model | @@ -11,11 +11,11 @@ const headerModel = require('../../../doraemon/models/header'); // 头部model | ||
11 | const _ = require('lodash'); | 11 | const _ = require('lodash'); |
12 | 12 | ||
13 | const suggestData = (req, res, next) => { | 13 | const suggestData = (req, res, next) => { |
14 | + let uid = req.user.uid; | ||
14 | let udid = req.sessionID || 'yoho'; | 15 | let udid = req.sessionID || 'yoho'; |
15 | let page = req.query.page || 1; | 16 | let page = req.query.page || 1; |
16 | let limit = 10; | 17 | let limit = 10; |
17 | - | ||
18 | - suggestModel.suggestData(udid, page, limit).then((result) => { | 18 | + suggestModel.suggestData(uid, udid, page, limit).then((result) => { |
19 | 19 | ||
20 | res.render('suggest', { | 20 | res.render('suggest', { |
21 | module: 'home', | 21 | module: 'home', |
@@ -11,14 +11,13 @@ const serviceAPI = global.yoho.ServiceAPI; | @@ -11,14 +11,13 @@ const serviceAPI = global.yoho.ServiceAPI; | ||
11 | const camelCase = global.yoho.camelCase; | 11 | const camelCase = global.yoho.camelCase; |
12 | const _ = require('lodash'); | 12 | const _ = require('lodash'); |
13 | 13 | ||
14 | -const suggestData = (udid, page, limit) => { | 14 | +const suggestData = (uid, udid, page, limit) => { |
15 | 15 | ||
16 | return serviceAPI.get('suggest/api/v1/suggest/getList', { | 16 | return serviceAPI.get('suggest/api/v1/suggest/getList', { |
17 | udid: udid, | 17 | udid: udid, |
18 | page: page, | 18 | page: page, |
19 | limit: limit | 19 | limit: limit |
20 | }).then((result) => { | 20 | }).then((result) => { |
21 | - | ||
22 | if (result && result.code === 200 && result.data) { | 21 | if (result && result.code === 200 && result.data) { |
23 | _.forEach(result.data.list, function(data) { | 22 | _.forEach(result.data.list, function(data) { |
24 | 23 | ||
@@ -36,7 +35,6 @@ const suggestData = (udid, page, limit) => { | @@ -36,7 +35,6 @@ const suggestData = (udid, page, limit) => { | ||
36 | }; | 35 | }; |
37 | 36 | ||
38 | const upAndDown = (uid, udid, reliable, suggestId) => { | 37 | const upAndDown = (uid, udid, reliable, suggestId) => { |
39 | - | ||
40 | return serviceAPI.get('suggest/api/v1/suggest/is_reliable', { | 38 | return serviceAPI.get('suggest/api/v1/suggest/is_reliable', { |
41 | uid: uid, | 39 | uid: uid, |
42 | udid: udid, | 40 | udid: udid, |
@@ -10,6 +10,7 @@ const _ = require('lodash'); | @@ -10,6 +10,7 @@ const _ = require('lodash'); | ||
10 | const helpers = global.yoho.helpers; | 10 | const helpers = global.yoho.helpers; |
11 | 11 | ||
12 | const service = require('../models/back-service'); | 12 | const service = require('../models/back-service'); |
13 | +const captchaService = require('../models/captcha-service'); | ||
13 | 14 | ||
14 | const SIGN_IN = helpers.urlFormat('/passport/login'); | 15 | const SIGN_IN = helpers.urlFormat('/passport/login'); |
15 | 16 | ||
@@ -150,18 +151,93 @@ const indexMobilePage = (req, res, next) => { | @@ -150,18 +151,93 @@ const indexMobilePage = (req, res, next) => { | ||
150 | isPassportPage: true, | 151 | isPassportPage: true, |
151 | backMobile: true, | 152 | backMobile: true, |
152 | countrys: result.data, | 153 | countrys: result.data, |
153 | - areaCode: '+86' | 154 | + areaCode: '+86', |
155 | + verifySrc: helpers.urlFormat('/passport/back/generatecodeimg.png', {t: Date.now()}) | ||
154 | })); | 156 | })); |
155 | }) | 157 | }) |
156 | .catch(next); | 158 | .catch(next); |
157 | }; | 159 | }; |
158 | 160 | ||
159 | /** | 161 | /** |
162 | + * 生成验证码 | ||
163 | + * @param req | ||
164 | + * @param res | ||
165 | + */ | ||
166 | +const generateCodeImg = (req, res) => { | ||
167 | + let verifyCodeImg = captchaService.generateCaptcha(109, 50, 4); | ||
168 | + | ||
169 | + if (verifyCodeImg) { | ||
170 | + | ||
171 | + if (req.session.backupCaptch) { | ||
172 | + req.session.backupCaptch.code = verifyCodeImg.text; | ||
173 | + req.session.backupCaptch.verifyResult = false; | ||
174 | + } else { | ||
175 | + req.session.backupCaptch = { | ||
176 | + code: verifyCodeImg.text, | ||
177 | + verifyResult: false | ||
178 | + }; | ||
179 | + } | ||
180 | + | ||
181 | + res.set('Cache-Control', 'no-cache').send(verifyCodeImg.image); | ||
182 | + } | ||
183 | +}; | ||
184 | + | ||
185 | +/** | ||
160 | * 发送手机验证码 | 186 | * 发送手机验证码 |
161 | */ | 187 | */ |
162 | const sendCodeToMobileAPI = (req, res, next) => { | 188 | const sendCodeToMobileAPI = (req, res, next) => { |
189 | + let verifyCode = req.body.verifyCode || ''; | ||
163 | let phoneNum = req.body.phoneNum || ''; | 190 | let phoneNum = req.body.phoneNum || ''; |
164 | let areaCode = req.body.areaCode || '86'; | 191 | let areaCode = req.body.areaCode || '86'; |
192 | + | ||
193 | + /* 如果设置了冻结时间,验证 */ | ||
194 | + if (_.has(req.session, 'backupCaptch.timeout')) { | ||
195 | + let untilTime = (parseInt(req.session.backupCaptch.timeout, 10) - | ||
196 | + parseInt(Date.now(), 10)) / 1000 / 60; | ||
197 | + | ||
198 | + if (parseInt(Date.now(), 10) < parseInt(req.session.backupCaptch.timeout, 10)) { | ||
199 | + return res.json({ | ||
200 | + code: 401, | ||
201 | + message: '请' + (parseInt(untilTime, 10) + 1) + '分钟后尝试!' | ||
202 | + }); | ||
203 | + } | ||
204 | + } | ||
205 | + | ||
206 | + /* 如果设置了验证次数,验证是否合法,验证次数减 1;没有,设置验证次数 */ | ||
207 | + if (_.has(req.session, 'backupCaptch.useTime')) { | ||
208 | + if (parseInt(req.session.backupCaptch.useTime, 10) <= 0) { | ||
209 | + | ||
210 | + /* 如果超过验证次数,冻结 5 分钟,更新验证次数 */ | ||
211 | + req.session.backupCaptch.timeout = Date.now() + 5 * 60 * 1000; | ||
212 | + req.session.backupCaptch.useTime = 5; | ||
213 | + return res.json({ | ||
214 | + code: 401, | ||
215 | + message: '请5分钟后尝试!' | ||
216 | + }); | ||
217 | + } | ||
218 | + req.session.backupCaptch.useTime = req.session.backupCaptch.useTime - 1; | ||
219 | + } else { | ||
220 | + req.session.backupCaptch.useTime = 5; | ||
221 | + } | ||
222 | + | ||
223 | + if (verifyCode) { | ||
224 | + if (verifyCode.toString() === _.get(req, 'session.backupCaptch.code', '').toString()) { | ||
225 | + req.session.backupCaptch.verifyResult = true; | ||
226 | + } else { | ||
227 | + return res.json({ | ||
228 | + code: 400, | ||
229 | + message: '验证码输入错误' | ||
230 | + }); | ||
231 | + } | ||
232 | + } else if (!req.session.backupCaptch.verifyResult) { | ||
233 | + | ||
234 | + return res.json({ | ||
235 | + code: 409, | ||
236 | + message: '非法请求!', | ||
237 | + refer: helpers.urlFormat('/') | ||
238 | + }); | ||
239 | + } | ||
240 | + | ||
165 | let ERR = { | 241 | let ERR = { |
166 | code: 400, | 242 | code: 400, |
167 | message: '输入手机号码出错' | 243 | message: '输入手机号码出错' |
@@ -198,6 +274,11 @@ const verifyCodeByMobilePage = (req, res) => { | @@ -198,6 +274,11 @@ const verifyCodeByMobilePage = (req, res) => { | ||
198 | let phoneNum = req.query.phoneNum || ''; | 274 | let phoneNum = req.query.phoneNum || ''; |
199 | let areaCode = req.query.areaCode || '86'; | 275 | let areaCode = req.query.areaCode || '86'; |
200 | 276 | ||
277 | + /* 用户直接进入第二个页面的情况 */ | ||
278 | + if (!_.get(req, 'session.backupCaptch.verifyResult')) { | ||
279 | + return res.redirect(helpers.urlFormat('/')); | ||
280 | + } | ||
281 | + | ||
201 | res.render('back/mobile-code', Object.assign({ | 282 | res.render('back/mobile-code', Object.assign({ |
202 | module: 'passport', | 283 | module: 'passport', |
203 | page: 'back-code', | 284 | page: 'back-code', |
@@ -208,8 +289,8 @@ const verifyCodeByMobilePage = (req, res) => { | @@ -208,8 +289,8 @@ const verifyCodeByMobilePage = (req, res) => { | ||
208 | isPassportPage: true, | 289 | isPassportPage: true, |
209 | backCode: true, | 290 | backCode: true, |
210 | areaCode: areaCode, | 291 | areaCode: areaCode, |
211 | - phoneNum: phoneNum | ||
212 | - | 292 | + phoneNum: phoneNum, |
293 | + verifySrc: helpers.urlFormat('/passport/back/generatecodeimg.png', {t: Date.now()}) | ||
213 | })); | 294 | })); |
214 | }; | 295 | }; |
215 | 296 | ||
@@ -309,5 +390,6 @@ module.exports = { | @@ -309,5 +390,6 @@ module.exports = { | ||
309 | verifyCodeByMobilePage, | 390 | verifyCodeByMobilePage, |
310 | verifyCodeByMobileAPI, | 391 | verifyCodeByMobileAPI, |
311 | setNewPasswordByMobilePage, | 392 | setNewPasswordByMobilePage, |
312 | - setNewPasswordByMobileAPI | 393 | + setNewPasswordByMobileAPI, |
394 | + generateCodeImg | ||
313 | }; | 395 | }; |
@@ -13,8 +13,49 @@ const sign = global.yoho.sign; | @@ -13,8 +13,49 @@ const sign = global.yoho.sign; | ||
13 | const cookie = global.yoho.cookie; | 13 | const cookie = global.yoho.cookie; |
14 | const RegService = require('../models/reg-service'); | 14 | const RegService = require('../models/reg-service'); |
15 | const AuthHelper = require('../models/auth-helper'); | 15 | const AuthHelper = require('../models/auth-helper'); |
16 | +const captchaService = require('../models/captcha-service'); | ||
17 | + | ||
18 | +/* | ||
19 | + session 结构 | ||
20 | + phoneReg: { | ||
21 | + step //当前步骤 | ||
22 | + captcha // step1 的校验码 | ||
23 | + count: 5 // 默认可以重发5次, 当count: 0, 冻结30min,之后解冻 | ||
24 | + expire // 解冻时间 | ||
25 | + } | ||
26 | +*/ | ||
27 | + | ||
28 | +/** | ||
29 | + * 步骤校验 | ||
30 | + * step: 预期步骤 | ||
31 | + */ | ||
32 | +let guardStep = function(step) { | ||
33 | + return (req, res, next) => { | ||
34 | + let curStep = _.get(req.session, 'phoneReg.step'); | ||
35 | + | ||
36 | + if (curStep !== step) { | ||
37 | + if (req.xhr) { | ||
38 | + return res.json({ | ||
39 | + code: 400, | ||
40 | + refer: '/reg.html' | ||
41 | + }); | ||
42 | + } else { | ||
43 | + return res.redirect('/reg.html'); | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + return next(); | ||
48 | + }; | ||
49 | +}; | ||
16 | 50 | ||
51 | +/** | ||
52 | + * Step1: 输入手机号码 + 验证码 | ||
53 | + */ | ||
17 | let index = (req, res) => { | 54 | let index = (req, res) => { |
55 | + if (req.user.uid) { | ||
56 | + return res.redirect(req.get('refer') || '/'); | ||
57 | + } | ||
58 | + | ||
18 | // 设置注册有效时间30分钟, 防机器刷 | 59 | // 设置注册有效时间30分钟, 防机器刷 |
19 | // req.session.REG_EXPIRE = Date.now() + 1800000; | 60 | // req.session.REG_EXPIRE = Date.now() + 1800000; |
20 | let refer = req.query.refer; | 61 | let refer = req.query.refer; |
@@ -23,17 +64,27 @@ let index = (req, res) => { | @@ -23,17 +64,27 @@ let index = (req, res) => { | ||
23 | domain: 'yohobuy.com' | 64 | domain: 'yohobuy.com' |
24 | }); | 65 | }); |
25 | 66 | ||
67 | + // session init | ||
68 | + _.set(req.session, 'phoneReg.step', 1); | ||
69 | + | ||
70 | + if (req.session.phoneReg.count == null) { // eslint-disable-line | ||
71 | + req.session.phoneReg.count = 5; | ||
72 | + } | ||
73 | + | ||
26 | res.render('reg/index', { | 74 | res.render('reg/index', { |
27 | module: 'passport', | 75 | module: 'passport', |
28 | page: 'reg', | 76 | page: 'reg', |
29 | title: '注册', | 77 | title: '注册', |
30 | backUrl: 'javascript:history.go(-1)', // eslint-disable-line | 78 | backUrl: 'javascript:history.go(-1)', // eslint-disable-line |
79 | + captchaUrl: helpers.urlFormat('/passport/reg/captcha.png', {t: Date.now()}), | ||
31 | headerText: '注册', // 头部信息 | 80 | headerText: '注册', // 头部信息 |
32 | isPassportPage: true, // 模板中模块标识 | 81 | isPassportPage: true, // 模板中模块标识 |
33 | areaCode: '+86', // 默认的区号 | 82 | areaCode: '+86', // 默认的区号 |
34 | countrys: RegService.getAreaData() // 地区信息列表 | 83 | countrys: RegService.getAreaData() // 地区信息列表 |
35 | }); | 84 | }); |
36 | }; | 85 | }; |
86 | + | ||
87 | + | ||
37 | let verifyMobile = (req, res, next) => { | 88 | let verifyMobile = (req, res, next) => { |
38 | let data = { | 89 | let data = { |
39 | code: 400, | 90 | code: 400, |
@@ -43,6 +94,15 @@ let verifyMobile = (req, res, next) => { | @@ -43,6 +94,15 @@ let verifyMobile = (req, res, next) => { | ||
43 | 94 | ||
44 | let mobile = +req.body.phoneNum; | 95 | let mobile = +req.body.phoneNum; |
45 | let area = +(req.body.areaCode || 86); | 96 | let area = +(req.body.areaCode || 86); |
97 | + let captcha = (req.body.captcha || '').trim(); | ||
98 | + | ||
99 | + if (captcha !== _.get(req.session, 'phoneReg.captcha')) { | ||
100 | + return res.json({ | ||
101 | + code: 400, | ||
102 | + message: '校验码不正确', | ||
103 | + refreshCaptcha: true | ||
104 | + }); | ||
105 | + } | ||
46 | 106 | ||
47 | // 判断参数是否合法 | 107 | // 判断参数是否合法 |
48 | if (!_.isNumber(mobile) || !_.isNumber(area)) { | 108 | if (!_.isNumber(mobile) || !_.isNumber(area)) { |
@@ -58,6 +118,7 @@ let verifyMobile = (req, res, next) => { | @@ -58,6 +118,7 @@ let verifyMobile = (req, res, next) => { | ||
58 | // return res.json(data); | 118 | // return res.json(data); |
59 | // } | 119 | // } |
60 | 120 | ||
121 | + | ||
61 | // 向手机发送注册验证码 | 122 | // 向手机发送注册验证码 |
62 | RegService.sendCodeToMobile(area, mobile).then((result) => { | 123 | RegService.sendCodeToMobile(area, mobile).then((result) => { |
63 | if (!result.code) { | 124 | if (!result.code) { |
@@ -68,6 +129,8 @@ let verifyMobile = (req, res, next) => { | @@ -68,6 +129,8 @@ let verifyMobile = (req, res, next) => { | ||
68 | if (result.code === 200) { | 129 | if (result.code === 200) { |
69 | let token = sign.makeToken(mobile); | 130 | let token = sign.makeToken(mobile); |
70 | 131 | ||
132 | + _.set(req.session, 'phoneReg.step', 2); // go step 2 | ||
133 | + | ||
71 | result.data = helpers.urlFormat('/passport/reg/code', { | 134 | result.data = helpers.urlFormat('/passport/reg/code', { |
72 | token: token, | 135 | token: token, |
73 | phoneNum: mobile, | 136 | phoneNum: mobile, |
@@ -78,6 +141,11 @@ let verifyMobile = (req, res, next) => { | @@ -78,6 +141,11 @@ let verifyMobile = (req, res, next) => { | ||
78 | return res.json(result); | 141 | return res.json(result); |
79 | }).catch(next); | 142 | }).catch(next); |
80 | }; | 143 | }; |
144 | + | ||
145 | + | ||
146 | +/** | ||
147 | + * Step2: 校验 手机验证码 | ||
148 | + */ | ||
81 | let codeAction = (req, res, next) => { | 149 | let codeAction = (req, res, next) => { |
82 | let token = req.query.token; | 150 | let token = req.query.token; |
83 | let mobile = +req.query.phoneNum; | 151 | let mobile = +req.query.phoneNum; |
@@ -103,6 +171,36 @@ let codeAction = (req, res, next) => { | @@ -103,6 +171,36 @@ let codeAction = (req, res, next) => { | ||
103 | serviceUrl: 'http://chat8.live800.com/live800/chatClient/chatbox.jsp?companyID=620092&configID=149091&jid=8732423409&info=' // 在线客服 | 171 | serviceUrl: 'http://chat8.live800.com/live800/chatClient/chatbox.jsp?companyID=620092&configID=149091&jid=8732423409&info=' // 在线客服 |
104 | }); | 172 | }); |
105 | }; | 173 | }; |
174 | + | ||
175 | +let sendCodeBusyBoy = (req, res, next) => { | ||
176 | + let count = _.get(req.session, 'phoneReg.count'); | ||
177 | + let expire = _.get(req.session, 'phoneReg.expire'); | ||
178 | + | ||
179 | + if (count) { | ||
180 | + return next(); | ||
181 | + } else { | ||
182 | + | ||
183 | + /* | ||
184 | + 如果 count === 0 | ||
185 | + 1. 没过解冻期 | ||
186 | + 2. 过了解冻期, count reset to 5 | ||
187 | + */ | ||
188 | + let now = Date.now(); | ||
189 | + | ||
190 | + if (now > expire) { | ||
191 | + _.set(req.session, 'phoneReg.count', 5); | ||
192 | + return next(); | ||
193 | + | ||
194 | + } else { | ||
195 | + return res.json({ | ||
196 | + code: 400, | ||
197 | + message: '错误次数太多, 5分钟稍后再试' | ||
198 | + }); | ||
199 | + } | ||
200 | + | ||
201 | + } | ||
202 | +}; | ||
203 | + | ||
106 | let sendCode = (req, res, next) => { | 204 | let sendCode = (req, res, next) => { |
107 | let data = { | 205 | let data = { |
108 | code: 400, | 206 | code: 400, |
@@ -129,10 +227,21 @@ let sendCode = (req, res, next) => { | @@ -129,10 +227,21 @@ let sendCode = (req, res, next) => { | ||
129 | 227 | ||
130 | // 向手机发送注册验证码 | 228 | // 向手机发送注册验证码 |
131 | RegService.sendCodeToMobile(area, mobile).then((result) => { | 229 | RegService.sendCodeToMobile(area, mobile).then((result) => { |
132 | - return result.code ? res.json(result) : res.json(data); | 230 | + let code = _.get(result, 'code'); |
231 | + | ||
232 | + if (code) { | ||
233 | + --req.session.phoneReg.count; | ||
234 | + | ||
235 | + // count is 0, will freeze; | ||
236 | + if (!req.session.phoneReg.count) { | ||
237 | + _.set(req.session, 'phoneReg.expire', Date.now() + 5 * 60 * 1000); | ||
238 | + } | ||
239 | + return res.json(result); | ||
240 | + } else { | ||
241 | + return res.json(data); | ||
242 | + } | ||
133 | }).catch(next); | 243 | }).catch(next); |
134 | }; | 244 | }; |
135 | - | ||
136 | let verifyCode = (req, res, next) => { | 245 | let verifyCode = (req, res, next) => { |
137 | let data = { | 246 | let data = { |
138 | code: 400, | 247 | code: 400, |
@@ -164,26 +273,33 @@ let verifyCode = (req, res, next) => { | @@ -164,26 +273,33 @@ let verifyCode = (req, res, next) => { | ||
164 | return res.json(data); | 273 | return res.json(data); |
165 | } | 274 | } |
166 | 275 | ||
167 | - // 返回跳转到设置密码的链接 | ||
168 | - if (result.code === 200) { | ||
169 | - let token = sign.makeToken(mobile); | ||
170 | - | ||
171 | - result.data = helpers.urlFormat('/passport/reg/password', { | ||
172 | - token: token, | ||
173 | - phoneNum: mobile, | ||
174 | - areaCode: area, | ||
175 | - smsCode: code | ||
176 | - }); | ||
177 | - } else if (result.code === 404) { | ||
178 | - result.message = '验证码错误'; // 统一验证提示 | 276 | + let resultCode = _.get(result, 'code'); |
277 | + let token = sign.makeToken(mobile); | ||
278 | + | ||
279 | + switch (resultCode) { | ||
280 | + case 200: | ||
281 | + _.set(req.session, 'phoneReg.step', 3); // go step 3 | ||
282 | + result.data = helpers.urlFormat('/passport/reg/password', { | ||
283 | + token: token, | ||
284 | + phoneNum: mobile, | ||
285 | + areaCode: area, | ||
286 | + smsCode: code | ||
287 | + }); | ||
288 | + break; | ||
289 | + case 404: | ||
290 | + default: | ||
291 | + result = data; | ||
179 | } | 292 | } |
180 | 293 | ||
181 | return res.json(result); | 294 | return res.json(result); |
182 | }).catch(next); | 295 | }).catch(next); |
183 | }; | 296 | }; |
184 | 297 | ||
298 | +/** | ||
299 | + * Step3: set Password | ||
300 | + */ | ||
185 | 301 | ||
186 | -let passwordAction = (req, res, next) => { | 302 | +let passwordAction = (req, res) => { |
187 | let token = req.query.token; | 303 | let token = req.query.token; |
188 | let mobile = +req.query.phoneNum; | 304 | let mobile = +req.query.phoneNum; |
189 | let area = +(req.query.areaCode || 86); | 305 | let area = +(req.query.areaCode || 86); |
@@ -210,7 +326,6 @@ let passwordAction = (req, res, next) => { | @@ -210,7 +326,6 @@ let passwordAction = (req, res, next) => { | ||
210 | }); | 326 | }); |
211 | }; | 327 | }; |
212 | 328 | ||
213 | - | ||
214 | let setPassword = (req, res, next) => { | 329 | let setPassword = (req, res, next) => { |
215 | let data = { | 330 | let data = { |
216 | code: 400, | 331 | code: 400, |
@@ -267,6 +382,8 @@ let setPassword = (req, res, next) => { | @@ -267,6 +382,8 @@ let setPassword = (req, res, next) => { | ||
267 | refer = '/home'; | 382 | refer = '/home'; |
268 | } | 383 | } |
269 | 384 | ||
385 | + delete req.session.phoneNum; | ||
386 | + | ||
270 | return res.json({ | 387 | return res.json({ |
271 | code: 200, | 388 | code: 200, |
272 | message: '注册成功', | 389 | message: '注册成功', |
@@ -278,12 +395,29 @@ let setPassword = (req, res, next) => { | @@ -278,12 +395,29 @@ let setPassword = (req, res, next) => { | ||
278 | }).catch(next); | 395 | }).catch(next); |
279 | }; | 396 | }; |
280 | 397 | ||
398 | +/** | ||
399 | + * 生成 校验码 | ||
400 | + */ | ||
401 | +const genCaptcha = (req, res) => { | ||
402 | + let captcha = captchaService.generateCaptcha(90, 52, 4); | ||
403 | + | ||
404 | + _.set(req.session, 'phoneReg.captcha', captcha.text); | ||
405 | + | ||
406 | + res.type('png') | ||
407 | + .set('Cache-Control', 'no-cache') | ||
408 | + .status(200) | ||
409 | + .send(captcha.image); | ||
410 | +}; | ||
411 | + | ||
281 | module.exports = { | 412 | module.exports = { |
413 | + guardStep, | ||
414 | + sendCodeBusyBoy, | ||
282 | index, | 415 | index, |
283 | verifyMobile, | 416 | verifyMobile, |
284 | code: codeAction, | 417 | code: codeAction, |
285 | sendCode, | 418 | sendCode, |
286 | verifyCode, | 419 | verifyCode, |
287 | password: passwordAction, | 420 | password: passwordAction, |
288 | - setPassword | 421 | + setPassword, |
422 | + genCaptcha | ||
289 | }; | 423 | }; |
apps/passport/models/captcha-service.js
0 → 100644
1 | +/** | ||
2 | + * Created by TaoHuang on 2016/7/1. | ||
3 | + */ | ||
4 | + | ||
5 | +'use strict'; | ||
6 | + | ||
7 | +const _ = require('lodash'); | ||
8 | +const Captchapng = require('captchapng'); | ||
9 | + | ||
10 | +exports.generateCaptcha = (width, height, length) => { | ||
11 | + let min = Math.pow(10, (length - 1 || 1)); | ||
12 | + let max = Math.pow(10, (length - 1 || 1)) * 9; | ||
13 | + let token = '' + _.random(min, max); | ||
14 | + | ||
15 | + let png = new Captchapng(width, height, token);// | ||
16 | + | ||
17 | + png.color(0, 0, 0, 0); // First color: background (red, green, blue, alpha) | ||
18 | + png.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha) | ||
19 | + | ||
20 | + return { | ||
21 | + image: new Buffer(png.getBase64(), 'base64'), | ||
22 | + text: token | ||
23 | + }; | ||
24 | +}; |
@@ -12,7 +12,8 @@ const login = require(cRoot + '/login'); | @@ -12,7 +12,8 @@ const login = require(cRoot + '/login'); | ||
12 | const back = require(cRoot + '/back'); | 12 | const back = require(cRoot + '/back'); |
13 | const bind = require(cRoot + '/bind'); | 13 | const bind = require(cRoot + '/bind'); |
14 | const reg = require(cRoot + '/reg'); | 14 | const reg = require(cRoot + '/reg'); |
15 | -const smsLogin = require(cRoot + '/sms'); | 15 | + |
16 | +// const smsLogin = require(cRoot + '/sms'); | ||
16 | const update = require(cRoot + '/update'); | 17 | const update = require(cRoot + '/update'); |
17 | const agreement = require(cRoot + '/app-agreement'); | 18 | const agreement = require(cRoot + '/app-agreement'); |
18 | 19 | ||
@@ -84,12 +85,13 @@ router.post('/passport/bind/changeMobile', bind.changeMobile); | @@ -84,12 +85,13 @@ router.post('/passport/bind/changeMobile', bind.changeMobile); | ||
84 | * 注册 | 85 | * 注册 |
85 | */ | 86 | */ |
86 | router.get('/passport/reg/index', reg.index); | 87 | router.get('/passport/reg/index', reg.index); |
87 | -router.post('/passport/reg/verifymobile', reg.verifyMobile); | ||
88 | -router.get('/passport/reg/code', reg.code); | ||
89 | -router.post('/passport/reg/sendcode', reg.sendCode); | ||
90 | -router.post('/passport/reg/verifycode', reg.verifyCode); | ||
91 | -router.get('/passport/reg/password', reg.password); | ||
92 | -router.post('/passport/reg/setpassword', reg.setPassword); | 88 | +router.get('/passport/reg/captcha.png', reg.genCaptcha); |
89 | +router.post('/passport/reg/verifymobile', reg.sendCodeBusyBoy, reg.verifyMobile); | ||
90 | +router.get('/passport/reg/code', reg.guardStep(2), reg.code); | ||
91 | +router.post('/passport/reg/sendcode', reg.guardStep(2), reg.sendCodeBusyBoy, reg.sendCode); | ||
92 | +router.post('/passport/reg/verifycode', reg.guardStep(2), reg.verifyCode); | ||
93 | +router.get('/passport/reg/password', reg.guardStep(3), reg.password); | ||
94 | +router.post('/passport/reg/setpassword', reg.guardStep(3), reg.setPassword); | ||
93 | 95 | ||
94 | /** | 96 | /** |
95 | * 密码找回 | 97 | * 密码找回 |
@@ -101,6 +103,7 @@ router.get('/passport/back/success', back.backSuccessByEmailPage);// 邮箱找 | @@ -101,6 +103,7 @@ router.get('/passport/back/success', back.backSuccessByEmailPage);// 邮箱找 | ||
101 | 103 | ||
102 | router.get('/passport/back/mobile', back.indexMobilePage);// 输入手机号找回密码页面 | 104 | router.get('/passport/back/mobile', back.indexMobilePage);// 输入手机号找回密码页面 |
103 | router.get('/passport/back/mobilecode', back.verifyCodeByMobilePage);// 输入手机验证码页面 | 105 | router.get('/passport/back/mobilecode', back.verifyCodeByMobilePage);// 输入手机验证码页面 |
106 | +router.get('/passport/back/generatecodeimg.png', back.generateCodeImg);// 生成图片验证码 | ||
104 | router.post('/passport/back/sendcode', back.sendCodeToMobileAPI);// 发送手机验证码 | 107 | router.post('/passport/back/sendcode', back.sendCodeToMobileAPI);// 发送手机验证码 |
105 | router.post('/passport/back/verifycode', back.verifyCodeByMobileAPI);// 校验手机验证码 | 108 | router.post('/passport/back/verifycode', back.verifyCodeByMobileAPI);// 校验手机验证码 |
106 | 109 |
@@ -6,6 +6,10 @@ | @@ -6,6 +6,10 @@ | ||
6 | <span id="area-code" class="area-code">{{areaCode}}</span> | 6 | <span id="area-code" class="area-code">{{areaCode}}</span> |
7 | <input id="phone-num" class="input phone-num" type="text" placeholder="手机号"> | 7 | <input id="phone-num" class="input phone-num" type="text" placeholder="手机号"> |
8 | </div> | 8 | </div> |
9 | + <div class="passport-captcha row"> | ||
10 | + <input id="verify-code" type="text" placeholder="验证码"> | ||
11 | + <div class="passport-captcha-img"><img id="verify-code-img" src="{{verifySrc}}" alt="verify code"></div> | ||
12 | + </div> | ||
9 | <span id="btn-next" class="btn btn-next disable row">下一步</span> | 13 | <span id="btn-next" class="btn btn-next disable row">下一步</span> |
10 | </div> | 14 | </div> |
11 | </div> | 15 | </div> |
@@ -6,7 +6,15 @@ | @@ -6,7 +6,15 @@ | ||
6 | <span id="area-code" class="area-code">{{areaCode}}</span> | 6 | <span id="area-code" class="area-code">{{areaCode}}</span> |
7 | <input id="phone-num" class="input phone-num" type="text" placeholder="手机号"> | 7 | <input id="phone-num" class="input phone-num" type="text" placeholder="手机号"> |
8 | </div> | 8 | </div> |
9 | + <!-- 验证码: start--> | ||
10 | + <div class="passport-captcha row"> | ||
11 | + <input id="js-captcha" type="text" placeholder="验证码"> | ||
12 | + <div class="passport-captcha-img"> | ||
13 | + <img class="passport-captcha-png" src="{{captchaUrl}}"> | ||
14 | + </div> | ||
15 | + </div> | ||
16 | + <!-- 验证码: end--> | ||
9 | <span id="btn-next" class="btn btn-next disable row">下一步</span> | 17 | <span id="btn-next" class="btn btn-next disable row">下一步</span> |
10 | <p class="register-tip">Yoho!Family账号可登录Yoho!Buy有货、Yoho!Now、mars及SHOW</p> | 18 | <p class="register-tip">Yoho!Family账号可登录Yoho!Buy有货、Yoho!Now、mars及SHOW</p> |
11 | </div> | 19 | </div> |
12 | -</div> | 20 | +</div> |
@@ -176,12 +176,12 @@ exports.consults = (req, res, next) => { | @@ -176,12 +176,12 @@ exports.consults = (req, res, next) => { | ||
176 | if (!req.query.product_id) { | 176 | if (!req.query.product_id) { |
177 | return next(); | 177 | return next(); |
178 | } | 178 | } |
179 | - | 179 | + let uid = req.user.uid || 0; |
180 | let headerData = headerModel.setNav({ | 180 | let headerData = headerModel.setNav({ |
181 | navTitle: '购买咨询' | 181 | navTitle: '购买咨询' |
182 | }); | 182 | }); |
183 | 183 | ||
184 | - detailRelated.consults(req.query).then((result) => { | 184 | + detailRelated.consults(req.query, uid).then((result) => { |
185 | res.render('detail/consults', Object.assign({ | 185 | res.render('detail/consults', Object.assign({ |
186 | title: '购买咨询', | 186 | title: '购买咨询', |
187 | pageHeader: headerData, | 187 | pageHeader: headerData, |
@@ -253,8 +253,7 @@ exports.consultsubmit = (req, res, next) => { | @@ -253,8 +253,7 @@ exports.consultsubmit = (req, res, next) => { | ||
253 | return res.json(data); | 253 | return res.json(data); |
254 | } | 254 | } |
255 | 255 | ||
256 | - detailRelated.addConsult(req.user.uid, req.body.product_id, req.body.content).then((result) => { | ||
257 | - | 256 | + return detailRelated.addConsult(req.user.uid, req.body.product_id, req.body.content).then((result) => { |
258 | if (result) { | 257 | if (result) { |
259 | Object.assign(data, result); | 258 | Object.assign(data, result); |
260 | } | 259 | } |
@@ -64,12 +64,13 @@ const _formatConsultsList = (data) => { | @@ -64,12 +64,13 @@ const _formatConsultsList = (data) => { | ||
64 | * @limit {[number]} 每页咨询数量 | 64 | * @limit {[number]} 每页咨询数量 |
65 | * @return {[object]} | 65 | * @return {[object]} |
66 | */ | 66 | */ |
67 | -const getConsults = (id, page, limit) => { | 67 | +const getConsults = (id, page, limit, uid) => { |
68 | let params = { | 68 | let params = { |
69 | method: 'app.consult.li', | 69 | method: 'app.consult.li', |
70 | product_id: id, | 70 | product_id: id, |
71 | page: page ? page : 1, | 71 | page: page ? page : 1, |
72 | - limit: limit ? limit : 300 | 72 | + limit: limit ? limit : 300, |
73 | + uid | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | return api.get('', params, { | 76 | return api.get('', params, { |
@@ -160,10 +161,10 @@ let comments = (params) => { | @@ -160,10 +161,10 @@ let comments = (params) => { | ||
160 | * @params {[object]} 查询参数 | 161 | * @params {[object]} 查询参数 |
161 | * @return {[object]} | 162 | * @return {[object]} |
162 | */ | 163 | */ |
163 | -let consults = (params) => { | 164 | +let consults = (params, uid) => { |
164 | return api.all([ | 165 | return api.all([ |
165 | _getCommonConsult(), | 166 | _getCommonConsult(), |
166 | - getConsults(params.product_id, 1, 60) | 167 | + getConsults(params.product_id, 1, 60, uid) |
167 | ]).then(result => { | 168 | ]).then(result => { |
168 | let data = { | 169 | let data = { |
169 | link: `/product/detail/consultform?product_id=${params.product_id}` | 170 | link: `/product/detail/consultform?product_id=${params.product_id}` |
@@ -515,6 +515,7 @@ const getShopData = (req, shopId, uid, isApp) => { | @@ -515,6 +515,7 @@ const getShopData = (req, shopId, uid, isApp) => { | ||
515 | return Promise.all([ | 515 | return Promise.all([ |
516 | searchModel.getFilterSearchData({ | 516 | searchModel.getFilterSearchData({ |
517 | shop_id: shopId, | 517 | shop_id: shopId, |
518 | + type: 'default',//默认 | ||
518 | brand: brandData.join(','), | 519 | brand: brandData.join(','), |
519 | order: '0', | 520 | order: '0', |
520 | channel: channel | 521 | channel: channel |
@@ -121,9 +121,9 @@ | @@ -121,9 +121,9 @@ | ||
121 | 121 | ||
122 | <div class="discount-area first" id="navlist2"> | 122 | <div class="discount-area first" id="navlist2"> |
123 | <ul id="list-nav" class="home-sub-nav list-nav pos-list clearfix"> | 123 | <ul id="list-nav" class="home-sub-nav list-nav pos-list clearfix"> |
124 | - <li data-bp-id="shop_listnav_new_1" class="new active buriedpoint first-li-more"> | 124 | + <li data-bp-id="shop_listnav_default_1" class="default active buriedpoint first-li-more"> |
125 | <a href="javascript:void(0);"> | 125 | <a href="javascript:void(0);"> |
126 | - <span class="spanTest">最新</span> | 126 | + <span class="spanTest">默认</span> |
127 | <span class="iconfont up cur hide"></span> | 127 | <span class="iconfont up cur hide"></span> |
128 | <span class="iconfont down cur"></span> | 128 | <span class="iconfont down cur"></span> |
129 | </a> | 129 | </a> |
@@ -191,9 +191,9 @@ | @@ -191,9 +191,9 @@ | ||
191 | </ul> | 191 | </ul> |
192 | <div id="pos-list" class='hide'> | 192 | <div id="pos-list" class='hide'> |
193 | <ul class="home-sub-nav pos-list"> | 193 | <ul class="home-sub-nav pos-list"> |
194 | - <li class="new active buriedpoint first-li-more" data-bp-id="shop_poslist_new_1"> | 194 | + <li class="default active buriedpoint first-li-more" data-bp-id="shop_listnav_default_1"> |
195 | <a href="javascript:void(0);"> | 195 | <a href="javascript:void(0);"> |
196 | - <span class="spanTest">最新</span> | 196 | + <span class="spanTest">默认</span> |
197 | <span class="iconfont cur"></span> | 197 | <span class="iconfont cur"></span> |
198 | <b></b> | 198 | <b></b> |
199 | </a> | 199 | </a> |
@@ -230,7 +230,6 @@ | @@ -230,7 +230,6 @@ | ||
230 | <ul> | 230 | <ul> |
231 | <li class='active default' data-bp-id='shop_listnav_default_1'>默认</li> | 231 | <li class='active default' data-bp-id='shop_listnav_default_1'>默认</li> |
232 | <li class='new' data-bp-id='shop_listnav_new_1'>最新</li> | 232 | <li class='new' data-bp-id='shop_listnav_new_1'>最新</li> |
233 | - <li class='sale' data-bp-id='shop_listnav_sale_1'>销量</li> | ||
234 | </ul> | 233 | </ul> |
235 | </div> | 234 | </div> |
236 | </div> | 235 | </div> |
@@ -92,9 +92,9 @@ | @@ -92,9 +92,9 @@ | ||
92 | 92 | ||
93 | <div> | 93 | <div> |
94 | <ul id="list-nav" class="list-nav clearfix"> | 94 | <ul id="list-nav" class="list-nav clearfix"> |
95 | - <li class="new active buriedpoint first-li-more" data-bp-id="shop_listnav_new_1"> | 95 | + <li class="default active buriedpoint first-li-more" data-bp-id="shop_listnav_default_1"> |
96 | <a href="javascript:void(0);"> | 96 | <a href="javascript:void(0);"> |
97 | - <span class="nav-txt">最新</span> | 97 | + <span class="nav-txt">默认</span> |
98 | <span class="iconfont up cur hide"></span> | 98 | <span class="iconfont up cur hide"></span> |
99 | <span class="iconfont down cur"></span> | 99 | <span class="iconfont down cur"></span> |
100 | </a> | 100 | </a> |
@@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
20 | "dependencies": { | 20 | "dependencies": { |
21 | "bluebird": "^3.4.6", | 21 | "bluebird": "^3.4.6", |
22 | "body-parser": "^1.15.2", | 22 | "body-parser": "^1.15.2", |
23 | + "captchapng": "0.0.1", | ||
23 | "cheerio": "^0.22.0", | 24 | "cheerio": "^0.22.0", |
24 | "compression": "^1.6.2", | 25 | "compression": "^1.6.2", |
25 | "connect-multiparty": "^2.0.0", | 26 | "connect-multiparty": "^2.0.0", |
@@ -196,7 +196,7 @@ getChannel = function functionName() { | @@ -196,7 +196,7 @@ getChannel = function functionName() { | ||
196 | C_ID = getChannel(); | 196 | C_ID = getChannel(); |
197 | 197 | ||
198 | $('.floor-focus').find('li').on('click', function() { | 198 | $('.floor-focus').find('li').on('click', function() { |
199 | - event.preventDefault(); | 199 | + // event.preventDefault(); |
200 | var foId = $(this).parents('.floor-focus').data('id'), | 200 | var foId = $(this).parents('.floor-focus').data('id'), |
201 | foName = $(this).parents('.floor-focus').data('floor-name'), | 201 | foName = $(this).parents('.floor-focus').data('floor-name'), |
202 | foindex = $(this).parents('.floor-focus').index() + 1, | 202 | foindex = $(this).parents('.floor-focus').index() + 1, |
@@ -9,6 +9,8 @@ var $ = require('yoho-jquery'); | @@ -9,6 +9,8 @@ var $ = require('yoho-jquery'); | ||
9 | var $phoneNum = $('#phone-num'), | 9 | var $phoneNum = $('#phone-num'), |
10 | $countrySelect = $('#country-select'), | 10 | $countrySelect = $('#country-select'), |
11 | $areaCode = $('#area-code'), | 11 | $areaCode = $('#area-code'), |
12 | + $verifyCode = $('#verify-code'), | ||
13 | + $verifyCodeImg = $('#verify-code-img'), | ||
12 | $btnNext = $('#btn-next'); | 14 | $btnNext = $('#btn-next'); |
13 | 15 | ||
14 | var api = require('../api'); | 16 | var api = require('../api'); |
@@ -33,25 +35,36 @@ $countrySelect.change(function() { | @@ -33,25 +35,36 @@ $countrySelect.change(function() { | ||
33 | $areaCode.text($countrySelect.val()); | 35 | $areaCode.text($countrySelect.val()); |
34 | }); | 36 | }); |
35 | 37 | ||
38 | +$verifyCodeImg.on('touchstart', function() { | ||
39 | + var oldSrc = $verifyCodeImg.attr('src').split('='); | ||
40 | + | ||
41 | + $verifyCodeImg.attr('src', oldSrc[0] + '=' + Date.now()); | ||
42 | +}); | ||
43 | + | ||
36 | $btnNext.on('touchstart', function() { | 44 | $btnNext.on('touchstart', function() { |
37 | var pn = trim($phoneNum.val()), | 45 | var pn = trim($phoneNum.val()), |
38 | - area = trim($countrySelect.val()); | 46 | + area = trim($countrySelect.val()), |
47 | + verify = trim($verifyCode.val()); | ||
39 | 48 | ||
40 | if ($btnNext.hasClass('disable')) { | 49 | if ($btnNext.hasClass('disable')) { |
41 | return; | 50 | return; |
42 | } | 51 | } |
43 | 52 | ||
44 | - if (area && pn && api.phoneRegx[area].test(pn)) { | 53 | + if (verify && area && pn && api.phoneRegx[area].test(pn)) { |
45 | $.ajax({ | 54 | $.ajax({ |
46 | url: '/passport/back/sendcode', | 55 | url: '/passport/back/sendcode', |
47 | type: 'POST', | 56 | type: 'POST', |
48 | data: { | 57 | data: { |
49 | areaCode: area.replace('+', ''), | 58 | areaCode: area.replace('+', ''), |
50 | - phoneNum: pn | 59 | + phoneNum: pn, |
60 | + verifyCode: verify | ||
51 | }, | 61 | }, |
52 | success: function(data) { | 62 | success: function(data) { |
53 | if (data.code === 200) { | 63 | if (data.code === 200) { |
54 | location.href = data.data; | 64 | location.href = data.data; |
65 | + } else if (data.code === 409) { | ||
66 | + showErrTip(data.message); | ||
67 | + location.href = data.refer; | ||
55 | } else { | 68 | } else { |
56 | showErrTip(data.message); | 69 | showErrTip(data.message); |
57 | } | 70 | } |
@@ -59,6 +72,8 @@ $btnNext.on('touchstart', function() { | @@ -59,6 +72,8 @@ $btnNext.on('touchstart', function() { | ||
59 | }); | 72 | }); |
60 | } else if (!area) { | 73 | } else if (!area) { |
61 | showErrTip('出错了,请重新刷新页面'); | 74 | showErrTip('出错了,请重新刷新页面'); |
75 | + } else if (!verify) { | ||
76 | + showErrTip('请输入验证码'); | ||
62 | } else { | 77 | } else { |
63 | showErrTip('手机号格式不正确,请重新输入'); | 78 | showErrTip('手机号格式不正确,请重新输入'); |
64 | } | 79 | } |
@@ -8,6 +8,8 @@ var $ = require('yoho-jquery'); | @@ -8,6 +8,8 @@ var $ = require('yoho-jquery'); | ||
8 | var $phoneNum = $('#phone-num'), | 8 | var $phoneNum = $('#phone-num'), |
9 | $countrySelect = $('#country-select'), | 9 | $countrySelect = $('#country-select'), |
10 | $areaCode = $('#area-code'), | 10 | $areaCode = $('#area-code'), |
11 | + $captcha = $('#js-captcha'), | ||
12 | + $captchaPNG = $('.passport-captcha-png'), | ||
11 | $btnNext = $('#btn-next'); | 13 | $btnNext = $('#btn-next'); |
12 | 14 | ||
13 | var api = require('../api'); | 15 | var api = require('../api'); |
@@ -22,13 +24,44 @@ api.selectCssHack($('#country-select')); | @@ -22,13 +24,44 @@ api.selectCssHack($('#country-select')); | ||
22 | 24 | ||
23 | api.bindClearEvt(); | 25 | api.bindClearEvt(); |
24 | 26 | ||
25 | -$phoneNum.bind('input', function() { | ||
26 | - if (trim($phoneNum.val()) === '') { | ||
27 | - $btnNext.addClass('disable'); | ||
28 | - } else { | ||
29 | - $btnNext.removeClass('disable'); | ||
30 | - } | ||
31 | -}); | 27 | +/** |
28 | + * 必填校验 | ||
29 | + */ | ||
30 | +function checkEnableNext() { | ||
31 | + var phone = trim($phoneNum.val()); | ||
32 | + var area = trim($countrySelect.val()); | ||
33 | + var captcha = trim($captcha.val()); | ||
34 | + | ||
35 | + var ret = true; | ||
36 | + | ||
37 | + $.each([phone, area, captcha], function(i, val) { | ||
38 | + if (!val) { | ||
39 | + ret = false; | ||
40 | + return ret; | ||
41 | + } | ||
42 | + }); | ||
43 | + | ||
44 | + return ret; | ||
45 | +} | ||
46 | + | ||
47 | + | ||
48 | +/** | ||
49 | + * 刷新 校验码 | ||
50 | + */ | ||
51 | +function refreshCaptcha() { | ||
52 | + $captcha.val('').focus(); | ||
53 | + $captchaPNG.attr('src', ['//m.yohobuy.com/passport/reg/captcha.png', '?t=', Date.now()].join('')); | ||
54 | +} | ||
55 | + | ||
56 | + | ||
57 | +/* | ||
58 | + Event bind | ||
59 | +*/ | ||
60 | +$('.reg-page') | ||
61 | + .on('input', '.phone-num, #js-captcha', function() { | ||
62 | + $btnNext.toggleClass('disable', !checkEnableNext()); | ||
63 | + }) | ||
64 | + .on('click', '.passport-captcha-png', refreshCaptcha); | ||
32 | 65 | ||
33 | $countrySelect.change(function() { | 66 | $countrySelect.change(function() { |
34 | $areaCode.text($countrySelect.val()); | 67 | $areaCode.text($countrySelect.val()); |
@@ -36,7 +69,13 @@ $countrySelect.change(function() { | @@ -36,7 +69,13 @@ $countrySelect.change(function() { | ||
36 | 69 | ||
37 | $btnNext.on('touchstart', function() { | 70 | $btnNext.on('touchstart', function() { |
38 | var pn = trim($phoneNum.val()), | 71 | var pn = trim($phoneNum.val()), |
39 | - areaCode = $countrySelect.val(); | 72 | + areaCode = $countrySelect.val(), |
73 | + captcha = $captcha.val().trim(); | ||
74 | + | ||
75 | + if (!captcha) { | ||
76 | + tip.show('请输入验证码'); | ||
77 | + return false; | ||
78 | + } | ||
40 | 79 | ||
41 | if ($btnNext.hasClass('disable')) { | 80 | if ($btnNext.hasClass('disable')) { |
42 | return; | 81 | return; |
@@ -56,12 +95,15 @@ $btnNext.on('touchstart', function() { | @@ -56,12 +95,15 @@ $btnNext.on('touchstart', function() { | ||
56 | type: 'POST', | 95 | type: 'POST', |
57 | data: { | 96 | data: { |
58 | areaCode: areaCode.replace('+', ''), | 97 | areaCode: areaCode.replace('+', ''), |
59 | - phoneNum: pn | 98 | + phoneNum: pn, |
99 | + captcha: captcha | ||
60 | }, | 100 | }, |
61 | success: function(data) { | 101 | success: function(data) { |
62 | if (data.code === 200) { | 102 | if (data.code === 200) { |
63 | location.href = data.data; | 103 | location.href = data.data; |
64 | } else { | 104 | } else { |
105 | + data.refreshCaptcha && refreshCaptcha(); | ||
106 | + | ||
65 | showErrTip(data.message); | 107 | showErrTip(data.message); |
66 | requested = false; | 108 | requested = false; |
67 | } | 109 | } |
@@ -76,7 +76,9 @@ if (navtabHammer) { | @@ -76,7 +76,9 @@ if (navtabHammer) { | ||
76 | 76 | ||
77 | if (gotoConsultHammer) { | 77 | if (gotoConsultHammer) { |
78 | gotoConsultHammer.on('tap', function() { | 78 | gotoConsultHammer.on('tap', function() { |
79 | - location.href = $(gotoConsultEle).find('a').attr('href'); | 79 | + var link = $(gotoConsultEle).find('a').attr('href'); |
80 | + link += (link.indexOf('?') >=0 ? '&' : '?') + 'from=' + encodeURIComponent(location.href); | ||
81 | + location.href = link; | ||
80 | }); | 82 | }); |
81 | } | 83 | } |
82 | 84 |
@@ -32,6 +32,11 @@ $content.on('focus', function() { | @@ -32,6 +32,11 @@ $content.on('focus', function() { | ||
32 | $content.val('请输入咨询内容'); | 32 | $content.val('请输入咨询内容'); |
33 | } | 33 | } |
34 | }); | 34 | }); |
35 | +var getUrlParam = function (paramName) { | ||
36 | + var reg = "[\\?|\\&]+" + paramName + "=([^&]*)[^&]?"; | ||
37 | + var exp = (window.location.href + "").match(reg); | ||
38 | + return exp ? exp[1] : ""; | ||
39 | +} | ||
35 | 40 | ||
36 | // 提交表单请求 | 41 | // 提交表单请求 |
37 | $consultForm.on('submit', function() { | 42 | $consultForm.on('submit', function() { |
@@ -68,7 +73,12 @@ $consultForm.on('submit', function() { | @@ -68,7 +73,12 @@ $consultForm.on('submit', function() { | ||
68 | } else { | 73 | } else { |
69 | tip.show('提交成功~'); | 74 | tip.show('提交成功~'); |
70 | setTimeout(function() { | 75 | setTimeout(function() { |
71 | - window.history.go(-1); | 76 | + var from = getUrlParam('from'); |
77 | + if (from) { | ||
78 | + window.location = decodeURIComponent(from); | ||
79 | + } else { | ||
80 | + window.history.go(-1); | ||
81 | + } | ||
72 | }, 3000); | 82 | }, 3000); |
73 | } | 83 | } |
74 | }).fail(function() { | 84 | }).fail(function() { |
@@ -127,7 +127,7 @@ function render(data) { | @@ -127,7 +127,7 @@ function render(data) { | ||
127 | $('#limitProductCode').val(data.cartInfo.limitProductCode).removeClass(dbClass); | 127 | $('#limitProductCode').val(data.cartInfo.limitProductCode).removeClass(dbClass); |
128 | } | 128 | } |
129 | } | 129 | } |
130 | - if (data.isCollect) { | 130 | + if (data.isCollect === true) { |
131 | $('#likeBtn').addClass('liked'); | 131 | $('#likeBtn').addClass('liked'); |
132 | } | 132 | } |
133 | if (data.tickets) { | 133 | if (data.tickets) { |
public/scss/passport/_passport-captcha.css
0 → 100644
1 | +/* 验证码 css | ||
2 | +----------------------------------- | ||
3 | +结构: | ||
4 | +div.passport-captch | ||
5 | + input | ||
6 | + div.passport-captcha-img | ||
7 | + img | ||
8 | + | ||
9 | +emmet: | ||
10 | +div.passport-captcha>input+div.passport-captcha-img>img | ||
11 | + | ||
12 | +*/ | ||
13 | + | ||
14 | +.passport-captcha { | ||
15 | + text-align: left; | ||
16 | + | ||
17 | + input { | ||
18 | + position: relative; | ||
19 | + padding-left: 15px; | ||
20 | + height: 52PX; | ||
21 | + font-size: 20PX; | ||
22 | + background-color: #575757; | ||
23 | + border: 1px solid #606060; | ||
24 | + border-radius: 5PX; | ||
25 | + color: #fff; | ||
26 | + } | ||
27 | +} | ||
28 | + | ||
29 | +.passport-captcha-img { | ||
30 | + float: right; | ||
31 | + text-align: right; | ||
32 | + | ||
33 | + img { | ||
34 | + display: inline-block; | ||
35 | + background-color: #fff; | ||
36 | + height: 52PX; | ||
37 | + width: 90PX; | ||
38 | + vertical-align: bottom; | ||
39 | + } | ||
40 | +} |
@@ -40,6 +40,11 @@ $basicBtnC: #eb0313; | @@ -40,6 +40,11 @@ $basicBtnC: #eb0313; | ||
40 | margin-bottom: 20px; | 40 | margin-bottom: 20px; |
41 | } | 41 | } |
42 | 42 | ||
43 | + video { | ||
44 | + width: 100%; | ||
45 | + height: auto; | ||
46 | + } | ||
47 | + | ||
43 | .detail { | 48 | .detail { |
44 | margin-top: 20px; | 49 | margin-top: 20px; |
45 | margin-bottom: 20px; | 50 | margin-bottom: 20px; |
@@ -313,7 +318,7 @@ $basicBtnC: #eb0313; | @@ -313,7 +318,7 @@ $basicBtnC: #eb0313; | ||
313 | margin-right: 20px; | 318 | margin-right: 20px; |
314 | } | 319 | } |
315 | 320 | ||
316 | - .font-right{ | 321 | + .font-right { |
317 | color: $subFontC; | 322 | color: $subFontC; |
318 | } | 323 | } |
319 | 324 | ||
@@ -428,8 +433,8 @@ $basicBtnC: #eb0313; | @@ -428,8 +433,8 @@ $basicBtnC: #eb0313; | ||
428 | 433 | ||
429 | .seckill-chose { | 434 | .seckill-chose { |
430 | position: absolute; | 435 | position: absolute; |
431 | - bottom: 0px; | ||
432 | - right: 0px; | 436 | + bottom: 0; |
437 | + right: 0; | ||
433 | } | 438 | } |
434 | 439 | ||
435 | .limit-num-text { | 440 | .limit-num-text { |
@@ -792,6 +797,7 @@ $basicBtnC: #eb0313; | @@ -792,6 +797,7 @@ $basicBtnC: #eb0313; | ||
792 | } | 797 | } |
793 | } | 798 | } |
794 | } | 799 | } |
800 | + | ||
795 | /* | 801 | /* |
796 | 秒杀倒计时栏 | 802 | 秒杀倒计时栏 |
797 | */ | 803 | */ |
@@ -827,6 +833,7 @@ $basicBtnC: #eb0313; | @@ -827,6 +833,7 @@ $basicBtnC: #eb0313; | ||
827 | font-size: 28px; | 833 | font-size: 28px; |
828 | } | 834 | } |
829 | } | 835 | } |
836 | + | ||
830 | /* | 837 | /* |
831 | 底部固定栏 | 838 | 底部固定栏 |
832 | */ | 839 | */ |
-
Please register or login to post a comment