Merge branch 'release/4.9.2'
Showing
36 changed files
with
1052 additions
and
78 deletions
@@ -29,16 +29,19 @@ exports.index = (req, res, next) => { | @@ -29,16 +29,19 @@ exports.index = (req, res, next) => { | ||
29 | exports.main = (req, res, next) => { | 29 | exports.main = (req, res, next) => { |
30 | const isReplay = /^\/live\/replay\//.test(req.path); | 30 | const isReplay = /^\/live\/replay\//.test(req.path); |
31 | const id = req.params.id; | 31 | const id = req.params.id; |
32 | + const goDownload = req.query.no; | ||
32 | 33 | ||
33 | res.locals.liveRoom = id; | 34 | res.locals.liveRoom = id; |
34 | res.locals.module = 'activity'; | 35 | res.locals.module = 'activity'; |
35 | res.locals.page = 'live-play'; | 36 | res.locals.page = 'live-play'; |
37 | + res.locals.enableFoot = goDownload !== 1; | ||
36 | 38 | ||
37 | model.fetchInfo(id, isReplay) | 39 | model.fetchInfo(id, isReplay) |
38 | .then(result => { | 40 | .then(result => { |
39 | if (!result.data) { | 41 | if (!result.data) { |
40 | return next(); | 42 | return next(); |
41 | } | 43 | } |
44 | + | ||
42 | res.render('live/play', result.data); | 45 | res.render('live/play', result.data); |
43 | }) | 46 | }) |
44 | .catch(next); | 47 | .catch(next); |
@@ -354,7 +354,7 @@ exports.verifystudent = (req, res, next) => { | @@ -354,7 +354,7 @@ exports.verifystudent = (req, res, next) => { | ||
354 | } | 354 | } |
355 | } else { | 355 | } else { |
356 | if (datas[2].code === 500) { | 356 | if (datas[2].code === 500) { |
357 | - prompt = '芝麻信用认证失败,稍后重试!'; | 357 | + prompt = '请重新认证!'; |
358 | } else { | 358 | } else { |
359 | prompt = datas[2].message; | 359 | prompt = datas[2].message; |
360 | } | 360 | } |
@@ -13,6 +13,9 @@ | @@ -13,6 +13,9 @@ | ||
13 | <p>加载中</p> | 13 | <p>加载中</p> |
14 | </div> | 14 | </div> |
15 | <div class="live-loading-cover" style="background-image: url('{{pic}}');"></div> | 15 | <div class="live-loading-cover" style="background-image: url('{{pic}}');"></div> |
16 | + <a href="javascript: history.back();" class="live-btn-close"> | ||
17 | + <i class="iconfont"></i> | ||
18 | + </a> | ||
16 | </div> | 19 | </div> |
17 | 20 | ||
18 | <div id="live_touch_layer"></div> | 21 | <div id="live_touch_layer"></div> |
@@ -65,9 +68,6 @@ | @@ -65,9 +68,6 @@ | ||
65 | <a href="javascript:;" class="live-btn-share"> | 68 | <a href="javascript:;" class="live-btn-share"> |
66 | <i class="iconfont"></i> | 69 | <i class="iconfont"></i> |
67 | </a> | 70 | </a> |
68 | - <a href="javascript: history.back();" class="live-btn-close"> | ||
69 | - <i class="iconfont"></i> | ||
70 | - </a> | ||
71 | </section> | 71 | </section> |
72 | </div> | 72 | </div> |
73 | {{/canPlay}} | 73 | {{/canPlay}} |
@@ -122,6 +122,7 @@ | @@ -122,6 +122,7 @@ | ||
122 | {{/notBegin}} | 122 | {{/notBegin}} |
123 | 123 | ||
124 | {{! footer}} | 124 | {{! footer}} |
125 | + {{#enableFoot}} | ||
125 | <div class="float-layer" id="float-layer-app"> | 126 | <div class="float-layer" id="float-layer-app"> |
126 | <div class="float-layer-left"> | 127 | <div class="float-layer-left"> |
127 | <span class="yoho-icon iconfont"></span> | 128 | <span class="yoho-icon iconfont"></span> |
@@ -135,6 +136,7 @@ | @@ -135,6 +136,7 @@ | ||
135 | 立即下载 | 136 | 立即下载 |
136 | </a> | 137 | </a> |
137 | </div> | 138 | </div> |
139 | + {{/enableFoot}} | ||
138 | </div> | 140 | </div> |
139 | <script> | 141 | <script> |
140 | var live_start_time = {{live_start_time}};//该直播开始时间 | 142 | var live_start_time = {{live_start_time}};//该直播开始时间 |
@@ -142,7 +144,6 @@ | @@ -142,7 +144,6 @@ | ||
142 | var live_room = {{liveRoom}};//房间id,资讯id | 144 | var live_room = {{liveRoom}};//房间id,资讯id |
143 | var replay_total_likes = {{like_num}};//重播总计点赞数,取的是直播最终点赞数 | 145 | var replay_total_likes = {{like_num}};//重播总计点赞数,取的是直播最终点赞数 |
144 | var replay_user_nums = {{audience_num}};//重播观看人数,取的是直播时最终观看人数 | 146 | var replay_user_nums = {{audience_num}};//重播观看人数,取的是直播时最终观看人数 |
145 | - var site_url = ''; | ||
146 | var site_domain = 'http://api.live.yoho.cn/'; | 147 | var site_domain = 'http://api.live.yoho.cn/'; |
147 | 148 | ||
148 | // share data | 149 | // share data |
1 | {{#unless isApp}} | 1 | {{#unless isApp}} |
2 | <header class="yoho-header"> | 2 | <header class="yoho-header"> |
3 | - <a href="javascript:history.go(-1);" class="iconfont nav-back"></a> | 3 | + <a href="//m.yohobuy.com/activity/student?openby:yohobuy={'action':'go.h5','params':{'islogin':'N','url':'{{http}}//m.yohobuy.com/activity/student'}}" class="iconfont nav-back"></a> |
4 | <p class="nav-title">学生身份认证</p> | 4 | <p class="nav-title">学生身份认证</p> |
5 | </header> | 5 | </header> |
6 | {{/unless}} | 6 | {{/unless}} |
@@ -134,6 +134,11 @@ const _getChannelResource = (params) => { | @@ -134,6 +134,11 @@ const _getChannelResource = (params) => { | ||
134 | cache: true | 134 | cache: true |
135 | }).then(result => { | 135 | }).then(result => { |
136 | if (result && result.code === 200) { | 136 | if (result && result.code === 200) { |
137 | + for (let item of result.data.list) { | ||
138 | + item.template_name === 'single_image' && | ||
139 | + item.data.length === 1 && | ||
140 | + (item.singleOne = true); | ||
141 | + } | ||
137 | return resourcesProcess(result.data.list); | 142 | return resourcesProcess(result.data.list); |
138 | } else { | 143 | } else { |
139 | logger.error('index resouce is not 200'); | 144 | logger.error('index resouce is not 200'); |
@@ -23,7 +23,7 @@ const indexEmailPage = (req, res) => { | @@ -23,7 +23,7 @@ const indexEmailPage = (req, res) => { | ||
23 | page: 'back-email', | 23 | page: 'back-email', |
24 | title: '找回密码-通过邮箱' | 24 | title: '找回密码-通过邮箱' |
25 | }, { | 25 | }, { |
26 | - backUrl: SIGN_IN, | 26 | + // backUrl: SIGN_IN, |
27 | headerText: '找回密码', | 27 | headerText: '找回密码', |
28 | isPassportPage: true, | 28 | isPassportPage: true, |
29 | backEmail: true | 29 | backEmail: true |
@@ -100,7 +100,7 @@ const backSuccessByEmailPage = (req, res) => { | @@ -100,7 +100,7 @@ const backSuccessByEmailPage = (req, res) => { | ||
100 | page: 'back-email-success', | 100 | page: 'back-email-success', |
101 | title: '找回密码-通过邮箱' | 101 | title: '找回密码-通过邮箱' |
102 | }, { | 102 | }, { |
103 | - backUrl: helpers.urlFormat('/passport/back/email'), | 103 | + // backUrl: helpers.urlFormat('/passport/back/email'), |
104 | headerText: '找回密码', | 104 | headerText: '找回密码', |
105 | isPassportPage: true, | 105 | isPassportPage: true, |
106 | backEmailSuccess: true, | 106 | backEmailSuccess: true, |
@@ -145,7 +145,7 @@ const indexMobilePage = (req, res, next) => { | @@ -145,7 +145,7 @@ const indexMobilePage = (req, res, next) => { | ||
145 | page: 'back-mobile', | 145 | page: 'back-mobile', |
146 | title: '找回密码-通过手机号' | 146 | title: '找回密码-通过手机号' |
147 | }, { | 147 | }, { |
148 | - backUrl: SIGN_IN, | 148 | + // backUrl: SIGN_IN, |
149 | headerText: '找回密码', | 149 | headerText: '找回密码', |
150 | isPassportPage: true, | 150 | isPassportPage: true, |
151 | backMobile: true, | 151 | backMobile: true, |
@@ -203,7 +203,7 @@ const verifyCodeByMobilePage = (req, res) => { | @@ -203,7 +203,7 @@ const verifyCodeByMobilePage = (req, res) => { | ||
203 | page: 'back-code', | 203 | page: 'back-code', |
204 | title: '找回密码-通过手机号' | 204 | title: '找回密码-通过手机号' |
205 | }, { | 205 | }, { |
206 | - backUrl: helpers.urlFormat('/passport/back/mobile'), | 206 | + // backUrl: helpers.urlFormat('/passport/back/mobile'), |
207 | headerText: '找回密码', | 207 | headerText: '找回密码', |
208 | isPassportPage: true, | 208 | isPassportPage: true, |
209 | backCode: true, | 209 | backCode: true, |
@@ -261,7 +261,7 @@ const setNewPasswordByMobilePage = (req, res) => { | @@ -261,7 +261,7 @@ const setNewPasswordByMobilePage = (req, res) => { | ||
261 | page: 'back-new-password', | 261 | page: 'back-new-password', |
262 | title: '找回密码-输入新密码' | 262 | title: '找回密码-输入新密码' |
263 | }, { | 263 | }, { |
264 | - backUrl: SIGN_IN, | 264 | + // backUrl: SIGN_IN, |
265 | headerText: '找回密码', | 265 | headerText: '找回密码', |
266 | isPassportPage: true, | 266 | isPassportPage: true, |
267 | backNewPwd: true, | 267 | backNewPwd: true, |
1 | +/* eslint no-unused-vars: ["error", { "args": "none" }] */ | ||
1 | /** | 2 | /** |
2 | * 登录 | 3 | * 登录 |
3 | * @author: Bi Kai<kai.bi@yoho.cn> | 4 | * @author: Bi Kai<kai.bi@yoho.cn> |
@@ -93,6 +94,7 @@ const local = { | @@ -93,6 +94,7 @@ const local = { | ||
93 | backUrl: 'javascript:history.go(-1)', // eslint-disable-line | 94 | backUrl: 'javascript:history.go(-1)', // eslint-disable-line |
94 | showHeaderImg: true, // 控制显示头部图片 | 95 | showHeaderImg: true, // 控制显示头部图片 |
95 | isPassportPage: true, // 模板中模块标识 | 96 | isPassportPage: true, // 模板中模块标识 |
97 | + smsLoginUrl: '/passport/sms_login', | ||
96 | registerUrl: '/passport/reg/index', // 注册的URL链接 | 98 | registerUrl: '/passport/reg/index', // 注册的URL链接 |
97 | aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接 | 99 | aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接 |
98 | weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接 | 100 | weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接 |
apps/passport/controllers/sms.js
0 → 100644
1 | +/* eslint no-unused-vars: ["error", { "args": "none" }] */ | ||
2 | +'use strict'; | ||
3 | +const helpers = global.yoho.helpers; | ||
4 | +const cookie = global.yoho.cookie; | ||
5 | +const RegService = require('../models/reg-service'); | ||
6 | +const PhoneService = require('../models/phone-service'); | ||
7 | +const AuthHelper = require('../models/auth-helper'); | ||
8 | + | ||
9 | +// constrant | ||
10 | +const CODE_REQUIRED = '请输入校验码'; | ||
11 | +const PASSWORD_REQUIRED = '请输入密码'; | ||
12 | +const PASSWORD_LENGTH_ERROR = '密码6-20位,请重新输入'; | ||
13 | +const BAD_PASSWORD = '密码格式不正确'; | ||
14 | +const TOO_MANY = '请求太频繁'; | ||
15 | +const LOGIN_SUCCSS = '登录成功'; | ||
16 | +const VERIFY_ERROR = '校验失败'; | ||
17 | + | ||
18 | +exports.beforeIn = (req, res, next) => { | ||
19 | + res.set({ | ||
20 | + 'Cache-Control': 'no-cache, no-store, must-revalidate', | ||
21 | + Pragma: 'no-cache', | ||
22 | + Expires: 0 | ||
23 | + }); | ||
24 | + | ||
25 | + if (!req.xhr && req.user.uid) { | ||
26 | + return res.redirect(req.cookies.refer); | ||
27 | + } | ||
28 | + | ||
29 | + next(); | ||
30 | +}; | ||
31 | + | ||
32 | +// 短信登录 第一步: 展现页面 | ||
33 | +const _step1 = (req, res, next) => { | ||
34 | + let template = 'sms/login'; | ||
35 | + let viewData = { | ||
36 | + module: 'passport', | ||
37 | + page: 'sms-login', | ||
38 | + title: '手机短信登录', | ||
39 | + isPassportPage: true, | ||
40 | + headerText: '手机号码快捷登录', | ||
41 | + areaCode: '+86', // 默认的区号 | ||
42 | + countrys: RegService.getAreaData() // 地区信息列表 | ||
43 | + }; | ||
44 | + | ||
45 | + res.render(template, viewData); | ||
46 | +}; | ||
47 | + | ||
48 | +// 短信登录 第二步: 输入 校验码 | ||
49 | +const _step2 = (req, res, next) => { | ||
50 | + const mobile = req.session.smsLogin.mobile; | ||
51 | + const area = req.session.smsLogin.area; | ||
52 | + const interval = req.session.smsLogin.interval; | ||
53 | + | ||
54 | + const template = 'sms/check'; | ||
55 | + const viewData = { | ||
56 | + module: 'passport', | ||
57 | + page: 'sms-check', | ||
58 | + title: '手机短信登录', | ||
59 | + isPassportPage: true, | ||
60 | + headerText: '手机号码快捷登录', | ||
61 | + canResend: interval < Date.now(), | ||
62 | + mobile, | ||
63 | + area | ||
64 | + }; | ||
65 | + | ||
66 | + res.render(template, viewData); | ||
67 | +}; | ||
68 | + | ||
69 | +// 短信登录 第三步: 设置密码 (针对 改手机未注册用户) | ||
70 | +const _step3 = (req, res, next) => { | ||
71 | + const template = 'sms/password'; | ||
72 | + const viewData = { | ||
73 | + module: 'passport', | ||
74 | + page: 'sms-password', | ||
75 | + title: '设置密码', | ||
76 | + isPassportPage: true, | ||
77 | + headerText: '设置密码' | ||
78 | + }; | ||
79 | + | ||
80 | + res.render(template, viewData); | ||
81 | +}; | ||
82 | + | ||
83 | +// 短信 登录 | ||
84 | +exports.loginPage = (req, res, next) => { | ||
85 | + let step = Number(req.query.step) || 1; | ||
86 | + let smsLoginStep = req.session.smsLoginStep || 1; | ||
87 | + | ||
88 | + if (step === 2 && smsLoginStep !== 2) { | ||
89 | + return res.redirect(req.path); | ||
90 | + } | ||
91 | + | ||
92 | + if (step === 3 && smsLoginStep !== 3) { | ||
93 | + return res.redirect(req.path); | ||
94 | + } | ||
95 | + | ||
96 | + switch (step) { | ||
97 | + case 2: | ||
98 | + _step2(req, res, next); | ||
99 | + break; | ||
100 | + case 3: | ||
101 | + _step3(req, res, next); | ||
102 | + break; | ||
103 | + case 1: | ||
104 | + default: | ||
105 | + _step1(req, res, next); | ||
106 | + } | ||
107 | +}; | ||
108 | + | ||
109 | +exports.tokenBefore = (req, res, next) => { | ||
110 | + let area = req.query.area = (req.query.area || '').trim(); | ||
111 | + let mobile = req.query.mobile = (req.query.mobile || '').trim(); | ||
112 | + | ||
113 | + if (!req.xhr) { | ||
114 | + return next(404); | ||
115 | + } | ||
116 | + | ||
117 | + if (req.session.smsLogin && req.session.smsLogin.interval > Date.now()) { | ||
118 | + return res.json({ | ||
119 | + code: 429, | ||
120 | + message: TOO_MANY | ||
121 | + }); | ||
122 | + } | ||
123 | + | ||
124 | + | ||
125 | + if ([area, mobile].some(val => val === '')) { | ||
126 | + return res.json({ | ||
127 | + code: 401, | ||
128 | + message: '请求参数,无法处理' | ||
129 | + }); | ||
130 | + } | ||
131 | + | ||
132 | + next(); | ||
133 | +}; | ||
134 | + | ||
135 | +// AJAX 获取验证码 | ||
136 | +exports.token = (req, res, next) => { | ||
137 | + let area = req.query.area; | ||
138 | + let mobile = req.query.mobile; | ||
139 | + | ||
140 | + PhoneService.sendSMS(mobile, area, 1).then(result => { | ||
141 | + if (result.code === 200) { | ||
142 | + req.session.smsLogin = { | ||
143 | + interval: Date.now() + 60 * 1000, // 重发验证码 间隔: 60s | ||
144 | + area, | ||
145 | + mobile | ||
146 | + }; | ||
147 | + req.session.smsLoginStep = 2; // 进入短信登录 step2 | ||
148 | + | ||
149 | + result.redirect = '/passport/sms_login?step=2'; | ||
150 | + res.json(result); | ||
151 | + return; | ||
152 | + } | ||
153 | + | ||
154 | + res.json(result); | ||
155 | + }); | ||
156 | +}; | ||
157 | + | ||
158 | +exports.checkBefore = (req, res, next) => { | ||
159 | + let code = req.query.code = (req.query.code || '').trim(); | ||
160 | + | ||
161 | + if (!req.xhr && req.session.smsLoginStep !== 2) { | ||
162 | + return next(404); | ||
163 | + } | ||
164 | + | ||
165 | + if (!code) { | ||
166 | + return res.json({ | ||
167 | + code: 404, | ||
168 | + message: CODE_REQUIRED | ||
169 | + }); | ||
170 | + } | ||
171 | + | ||
172 | + next(); | ||
173 | +}; | ||
174 | + | ||
175 | +// AJAX 校验验证码 in step2 | ||
176 | +exports.check = (req, res, next) => { | ||
177 | + const code = req.query.code; | ||
178 | + const mobile = req.session.smsLogin.mobile; | ||
179 | + const area = req.session.smsLogin.area; | ||
180 | + const shopping_key = cookie.getShoppingKey(req); // eslint-disable-line | ||
181 | + | ||
182 | + | ||
183 | + Promise.all([ | ||
184 | + PhoneService.checkUserPhoneExist(mobile, area), | ||
185 | + PhoneService.verifySMS(mobile, area, code, 1) | ||
186 | + ]) | ||
187 | + .then(result => { | ||
188 | + let r1 = result[0] || {}; | ||
189 | + let r2 = result[1] || {}; | ||
190 | + let redirect; | ||
191 | + | ||
192 | + // 验证码 校验异常 | ||
193 | + if (r2.code !== 200) { | ||
194 | + res.json(r2); | ||
195 | + return; | ||
196 | + } | ||
197 | + | ||
198 | + // 检测 手机号 是否注册 异常 | ||
199 | + if (r1.code !== 200) { | ||
200 | + res.json(r1); | ||
201 | + return; | ||
202 | + } | ||
203 | + | ||
204 | + // 校验失败 | ||
205 | + if (r2.data.is_pass !== 'Y') { | ||
206 | + res.json({ | ||
207 | + code: 401, | ||
208 | + message: VERIFY_ERROR | ||
209 | + }); | ||
210 | + | ||
211 | + return; | ||
212 | + } | ||
213 | + | ||
214 | + // 手机号码 没注册 | ||
215 | + if (r1.data.is_register !== 'Y') { | ||
216 | + redirect = '/passport/sms_login?step=3'; | ||
217 | + req.session.smsLoginStep = 3; | ||
218 | + | ||
219 | + res.json({ | ||
220 | + code: 200, | ||
221 | + redirect | ||
222 | + }); | ||
223 | + | ||
224 | + return; | ||
225 | + } | ||
226 | + | ||
227 | + // 手机号码已注册 --> 直接登录 | ||
228 | + PhoneService.autoSignin({ | ||
229 | + profile: mobile, | ||
230 | + code: r2.data.code, | ||
231 | + area, | ||
232 | + shopping_key | ||
233 | + }) | ||
234 | + .then(info => { | ||
235 | + if (info.code !== 200) { | ||
236 | + return Promise.reject(info); | ||
237 | + } | ||
238 | + | ||
239 | + return AuthHelper.syncUserSession(info.data.uid, req, res); | ||
240 | + }) | ||
241 | + .then(() => { | ||
242 | + res.json({ | ||
243 | + code: 200, | ||
244 | + message: LOGIN_SUCCSS, | ||
245 | + redirect: req.cookies.refer | ||
246 | + }); | ||
247 | + | ||
248 | + delete req.session.smsLogin; | ||
249 | + delete req.session.smsLoginStep; | ||
250 | + }) | ||
251 | + .catch(error => { | ||
252 | + res.json(error); | ||
253 | + }); | ||
254 | + | ||
255 | + }) | ||
256 | + .catch(next); | ||
257 | +}; | ||
258 | + | ||
259 | +// AJAX 短信登录 设置密码 in step3 | ||
260 | +exports.password = (req, res, next) => { | ||
261 | + if (req.session.smsLoginStep !== 3) { | ||
262 | + return next(); | ||
263 | + } | ||
264 | + | ||
265 | + | ||
266 | + let data = { | ||
267 | + code: '400', | ||
268 | + message: BAD_PASSWORD | ||
269 | + }; | ||
270 | + | ||
271 | + let smsLogin = req.session.smsLogin || {}; | ||
272 | + let mobile = smsLogin.mobile; | ||
273 | + let area = smsLogin.area; | ||
274 | + let password = (req.body.password || '').trim(); | ||
275 | + | ||
276 | + if (!password) { | ||
277 | + data.message = PASSWORD_REQUIRED; | ||
278 | + return res.json(data); | ||
279 | + } | ||
280 | + | ||
281 | + if (password.length < 6 || password.length > 20) { | ||
282 | + data.message = PASSWORD_LENGTH_ERROR; | ||
283 | + return res.json(data); | ||
284 | + } | ||
285 | + | ||
286 | + if (!helpers.verifyPassword(password)) { | ||
287 | + return res.json(data); | ||
288 | + } | ||
289 | + | ||
290 | + // 购物车key | ||
291 | + let shoppingKey = cookie.getShoppingKey(req); | ||
292 | + | ||
293 | + | ||
294 | + RegService.regMobileAes(area, mobile, password, shoppingKey).then(result => { | ||
295 | + if (!result.code || result.code !== 200) { | ||
296 | + return Promise.reject(result); | ||
297 | + } | ||
298 | + if (!result.data || !result.data.uid) { | ||
299 | + return Promise.reject(result); | ||
300 | + } | ||
301 | + | ||
302 | + return AuthHelper.syncUserSession(result.data.uid, req, res); | ||
303 | + }).then(() => { | ||
304 | + res.json({ | ||
305 | + code: 200, | ||
306 | + message: LOGIN_SUCCSS, | ||
307 | + redirect: req.cookies.refer | ||
308 | + }); | ||
309 | + delete req.session.smsLogin; | ||
310 | + delete req.session.smsLoginStep; | ||
311 | + }).catch(next); | ||
312 | + | ||
313 | + | ||
314 | +}; |
apps/passport/models/phone-service.js
0 → 100644
1 | +/* eslint no-unused-vars: ["error", { "args": "none" }] */ | ||
2 | +'use strict'; | ||
3 | +const API = global.yoho.API; | ||
4 | + | ||
5 | +class PhoneService { | ||
6 | + // 校验 手机 是否 已注册 | ||
7 | + // http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/个人中心/验证码登录/校验是否是注册用户.md | ||
8 | + static checkUserPhoneExist(mobile, area) { | ||
9 | + return API.get('', { | ||
10 | + method: 'app.passport.checkUserExist', | ||
11 | + mobile, | ||
12 | + area | ||
13 | + }); | ||
14 | + } | ||
15 | + | ||
16 | + // 手机号 自动登录 | ||
17 | + // http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/个人中心/验证码登录/手机号自动登录.md | ||
18 | + static autoSignin(param) { | ||
19 | + return API.get('', { | ||
20 | + method: 'app.passport.autoSignin', | ||
21 | + profile: param.profile, | ||
22 | + area: param.area, | ||
23 | + code: param.code, | ||
24 | + shopping_key: param.shopping_key | ||
25 | + }); | ||
26 | + } | ||
27 | + | ||
28 | + // 发送 验证码 | ||
29 | + // http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/个人中心/验证码登录/发送验证码.md | ||
30 | + static sendSMS(mobile, area, type) { | ||
31 | + if (process.env.NODE_ENV === 'development') { | ||
32 | + return new Promise((resolve, reject) => { | ||
33 | + return resolve({ | ||
34 | + alg: 'SALT_MD5', | ||
35 | + code: 200, | ||
36 | + data: {}, | ||
37 | + md5: '6d729d4b35f10fc73531210bd7ecff91', | ||
38 | + message: '发送成功.' | ||
39 | + }); | ||
40 | + }); | ||
41 | + } | ||
42 | + | ||
43 | + return API.get('', { | ||
44 | + method: 'app.message.sendSms', | ||
45 | + mobile, | ||
46 | + area, | ||
47 | + type | ||
48 | + }); | ||
49 | + } | ||
50 | + | ||
51 | + // 校验 验证码 | ||
52 | + // http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/个人中心/验证码登录/验证验证码.md | ||
53 | + static verifySMS(mobile, area, code, type) { | ||
54 | + if (process.env.NODE_ENV === 'development') { | ||
55 | + return new Promise((resolve, reject) => { | ||
56 | + return resolve({ | ||
57 | + alg: 'SALT_MD5', | ||
58 | + code: 200, | ||
59 | + data: { | ||
60 | + is_pass: 'Y' | ||
61 | + }, | ||
62 | + md5: '6d729d4b35f10fc73531210bd7ecff91', | ||
63 | + message: '发送成功.' | ||
64 | + }); | ||
65 | + }); | ||
66 | + } | ||
67 | + | ||
68 | + return API.get('', { | ||
69 | + method: 'app.message.verifySmsCode', | ||
70 | + mobile, | ||
71 | + area, | ||
72 | + code, | ||
73 | + type | ||
74 | + }); | ||
75 | + } | ||
76 | +} | ||
77 | + | ||
78 | +module.exports = PhoneService; |
@@ -12,6 +12,7 @@ const login = require(cRoot + '/login'); | @@ -12,6 +12,7 @@ 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 | ||
16 | 17 | ||
17 | const router = express.Router(); // eslint-disable-line | 18 | const router = express.Router(); // eslint-disable-line |
@@ -33,6 +34,17 @@ router.get('/passport/international', login.common.beforeLogin, login.local.inte | @@ -33,6 +34,17 @@ router.get('/passport/international', login.common.beforeLogin, login.local.inte | ||
33 | // 本地登录 | 34 | // 本地登录 |
34 | router.post('/passport/login/auth', login.local.login); | 35 | router.post('/passport/login/auth', login.local.login); |
35 | 36 | ||
37 | +// SMS 短信 | ||
38 | +router.use('/passport/sms_login', login.common.beforeLogin, smsLogin.beforeIn); | ||
39 | +router.get('/passport/sms_login', smsLogin.loginPage); | ||
40 | +router.get('/passport/sms_login/token.json', | ||
41 | + smsLogin.tokenBefore, | ||
42 | + smsLogin.token); // only ajax; | ||
43 | +router.get('/passport/sms_login/check.json', | ||
44 | + smsLogin.checkBefore, | ||
45 | + smsLogin.check); // only ajax | ||
46 | +router.post('/passport/sms_login/password.json', smsLogin.password); | ||
47 | + | ||
36 | // 微信登录 | 48 | // 微信登录 |
37 | router.get('/passport/login/wechat', login.common.beforeLogin, login.wechat.login); | 49 | router.get('/passport/login/wechat', login.common.beforeLogin, login.wechat.login); |
38 | router.get('/passport/login/wechat/callback', login.wechat.callback); | 50 | router.get('/passport/login/wechat/callback', login.wechat.callback); |
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | </div> | 10 | </div> |
11 | <span id="btn-login" class="btn btn-login disable">登录</span> | 11 | <span id="btn-login" class="btn btn-login disable">登录</span> |
12 | <p class="op-container"> | 12 | <p class="op-container"> |
13 | - <a class="go-register" href={{registerUrl}}>免费注册</a> | 13 | + <a class="sms-login" href={{smsLoginUrl}}>手机号码快捷登录</a> |
14 | <span id="forget-pwd" class="forget-pwd">忘记密码</span> | 14 | <span id="forget-pwd" class="forget-pwd">忘记密码</span> |
15 | </p> | 15 | </p> |
16 | <div class="third-party-login"> | 16 | <div class="third-party-login"> |
@@ -22,6 +22,10 @@ | @@ -22,6 +22,10 @@ | ||
22 | </div> | 22 | </div> |
23 | </div> | 23 | </div> |
24 | <a class="international" href={{internationalUrl}}>International Customer</a> | 24 | <a class="international" href={{internationalUrl}}>International Customer</a> |
25 | + <div class="go-register"> | ||
26 | + <i class="iconfont"></i> | ||
27 | + <a href={{registerUrl}}>注册Yoho!Family</a> | ||
28 | + </div> | ||
25 | <div class="login-tip"> | 29 | <div class="login-tip"> |
26 | <div class="info-icon"></div> | 30 | <div class="info-icon"></div> |
27 | Yoho!Family账号可登录Yoho!Buy有货 | 31 | Yoho!Family账号可登录Yoho!Buy有货 |
apps/passport/views/action/sms/check.hbs
0 → 100644
1 | +<div class="sms-login sms-login-check passport-page yoho-page"> | ||
2 | + {{> passport/header}} | ||
3 | + <div class="content"> | ||
4 | + <p class="sms-login-msg">验证码已发至 <span class="tel">+{{area}} {{mobile}}</span></p> | ||
5 | + <div class="input-container input-group sms-input row"> | ||
6 | + <input id="sms-code" class="input" type="text" placeholder="验证码"> | ||
7 | + <div class="input-addon"> | ||
8 | + <button type="button" id="resend-sms">重发验证码</button> | ||
9 | + </div> | ||
10 | + <button class="clear-input" type="button"></button> | ||
11 | + </div> | ||
12 | + <button id="btn-next" class="btn btn-next disable row" type="button">登录</button> | ||
13 | + </div> | ||
14 | + <input type="hidden" name="mobile" id="mobile" value="{{mobile}}"> | ||
15 | + <input type="hidden" name="area" id="area" value="{{area}}"> | ||
16 | +</div> | ||
17 | +<script> | ||
18 | + var canResend = {{canResend}}; | ||
19 | +</script> |
apps/passport/views/action/sms/login.hbs
0 → 100644
1 | +<div class="sms-login-page passport-page yoho-page"> | ||
2 | + {{> passport/header}} | ||
3 | + <div class="content"> | ||
4 | + {{> passport/country_list}} | ||
5 | + <div class="input-container phone-container row has-clear"> | ||
6 | + <span id="area-code" class="area-code">{{areaCode}}</span> | ||
7 | + <input id="phone-num" class="input phone-num" type="text" placeholder="手机号"> | ||
8 | + <button class="clear-input" type="button"></button> | ||
9 | + </div> | ||
10 | + <button id="btn-next" class="btn btn-next disable row" disabled>获取短信验证码</button> | ||
11 | + </div> | ||
12 | +</div> |
apps/passport/views/action/sms/password.hbs
0 → 100644
1 | +<div class="sms-login passport-page yoho-page"> | ||
2 | + {{> passport/header}} | ||
3 | + <div class="content"> | ||
4 | + <p class="sms-login-msg small">你以后还可以使用手机号码 + 密码的形式登录有货哦!</p> | ||
5 | + <div class="input-container row has-eye"> | ||
6 | + <input id="pwd" class="pwd input" type="text" placeholder="密码"> | ||
7 | + <div class="eye" id="eye"></div> | ||
8 | + </div> | ||
9 | + <span id="btn-next" class="btn btn-next disable row">确定</span> | ||
10 | + </div> | ||
11 | +</div> |
@@ -14,10 +14,8 @@ module.exports = { | @@ -14,10 +14,8 @@ module.exports = { | ||
14 | port: 6001, | 14 | port: 6001, |
15 | siteUrl: '//m.yohobuy.com', | 15 | siteUrl: '//m.yohobuy.com', |
16 | domains: { | 16 | domains: { |
17 | - // api: 'http://devapi.yoho.cn:58078/', | ||
18 | - // service: 'http://devservice.yoho.cn:58077/' | ||
19 | - api: 'http://api.yoho.cn/', | ||
20 | - service: 'http://service.yoho.cn/', | 17 | + api: 'http://api-test3.yohops.com:9999/', |
18 | + service: 'http://service-test3.yohops.com:9999/', | ||
21 | liveApi: 'http://testapi.live.yohops.com:9999/' | 19 | liveApi: 'http://testapi.live.yohops.com:9999/' |
22 | }, | 20 | }, |
23 | subDomains: { | 21 | subDomains: { |
@@ -93,7 +91,7 @@ if (isProduction) { | @@ -93,7 +91,7 @@ if (isProduction) { | ||
93 | useOneapm: true, | 91 | useOneapm: true, |
94 | useCache: true, | 92 | useCache: true, |
95 | interfaceShunt: { | 93 | interfaceShunt: { |
96 | - open: true, | 94 | + open: false, |
97 | url: 'http://123.206.2.55/strategy' | 95 | url: 'http://123.206.2.55/strategy' |
98 | } | 96 | } |
99 | }); | 97 | }); |
1 | -{{#data}} | ||
2 | - <div class="banner-center"> | 1 | +<div class="banner-center banner-center-swiper"> |
2 | + {{#if singleOne}} | ||
3 | + {{#data}} | ||
4 | + <div class="banner-list"> | ||
3 | <a href="{{url}}"> | 5 | <a href="{{url}}"> |
4 | - <img class="lazy" data-original="{{image src 640 200}}" alt=""> | 6 | + <img src="{{image src 640 200}}" alt=""> |
5 | </a> | 7 | </a> |
6 | </div> | 8 | </div> |
7 | -{{/data}} | ||
9 | + {{/data}} | ||
10 | + {{else}} | ||
11 | + <ul class="banner-list swiper-wrapper clearfix"> | ||
12 | + {{#data}} | ||
13 | + <li class="swiper-slide"> | ||
14 | + <a href="{{url}}"> | ||
15 | + <img src="{{image src 640 200}}" alt=""> | ||
16 | + </a> | ||
17 | + </li> | ||
18 | + {{/data}} | ||
19 | + </ul> | ||
20 | + {{/if}} | ||
21 | + <div class="swiper-pagination"> | ||
22 | + <div class="pagination-inner"> | ||
23 | + </div> | ||
24 | + </div> | ||
25 | +</div> |
@@ -17,6 +17,7 @@ var prefixes = 'webkit moz ms o'.split(' '); //各浏览器前缀 | @@ -17,6 +17,7 @@ var prefixes = 'webkit moz ms o'.split(' '); //各浏览器前缀 | ||
17 | var requestAnimationFrame = window.requestAnimationFrame; | 17 | var requestAnimationFrame = window.requestAnimationFrame; |
18 | var cancelAnimationFrame = window.cancelAnimationFrame; | 18 | var cancelAnimationFrame = window.cancelAnimationFrame; |
19 | 19 | ||
20 | +var site_url = STATIC_RESOURCE_PATH; | ||
20 | var $btn_play; | 21 | var $btn_play; |
21 | var video_width = 375; | 22 | var video_width = 375; |
22 | var video_height = 667; | 23 | var video_height = 667; |
@@ -284,9 +285,12 @@ function get_websocket_server(type) { | @@ -284,9 +285,12 @@ function get_websocket_server(type) { | ||
284 | var arr = data.data[0].split(':'); | 285 | var arr = data.data[0].split(':'); |
285 | var ip = arr[0]; | 286 | var ip = arr[0]; |
286 | var port = arr[1]; | 287 | var port = arr[1]; |
288 | + var protocol = 'ws' | ||
289 | + // var protocol = location.protocol === 'https:' ? 'wss' :'ws' | ||
287 | 290 | ||
288 | if (is_live) { | 291 | if (is_live) { |
289 | - ip = 'ws://' + ip; | 292 | + |
293 | + ip = protocol + '://' + ip; | ||
290 | link_to_websocket_server(ip, port); | 294 | link_to_websocket_server(ip, port); |
291 | } | 295 | } |
292 | } | 296 | } |
@@ -670,7 +674,7 @@ function insert_like(obj) { | @@ -670,7 +674,7 @@ function insert_like(obj) { | ||
670 | } | 674 | } |
671 | } | 675 | } |
672 | now_like_nums = num; | 676 | now_like_nums = num; |
673 | - if (now_like_nums > 100000) { | 677 | + if (now_like_nums > 10000) { |
674 | $('#like_num').text((now_like_nums / 10000).toFixed(1) + '万'); | 678 | $('#like_num').text((now_like_nums / 10000).toFixed(1) + '万'); |
675 | } else { | 679 | } else { |
676 | $('#like_num').text(now_like_nums); | 680 | $('#like_num').text(now_like_nums); |
@@ -391,19 +391,9 @@ $(document).on('click', '.s-footer .checkbox', function() { | @@ -391,19 +391,9 @@ $(document).on('click', '.s-footer .checkbox', function() { | ||
391 | /* | 391 | /* |
392 | * 数据提交 | 392 | * 数据提交 |
393 | */ | 393 | */ |
394 | -$('.s-submit').data('isClick', true); | ||
395 | $(document).on('click', '.s-submit', function() { | 394 | $(document).on('click', '.s-submit', function() { |
396 | var obj = changeSuccess(), | 395 | var obj = changeSuccess(), |
397 | FAILURE_CAUSE; | 396 | FAILURE_CAUSE; |
398 | - var $that = $(this); | ||
399 | - | ||
400 | - // 存cookie 记录状态 | ||
401 | - localStorage.setItem(STUDENTCOOKIES, JSON.stringify(obj.data)); | ||
402 | - | ||
403 | - if ($that.data('isClick') === false) { | ||
404 | - return; | ||
405 | - } | ||
406 | - $that.data('isClick', false); | ||
407 | 397 | ||
408 | if (!obj.msg) { | 398 | if (!obj.msg) { |
409 | $.ajax({ | 399 | $.ajax({ |
@@ -422,15 +412,15 @@ $(document).on('click', '.s-submit', function() { | @@ -422,15 +412,15 @@ $(document).on('click', '.s-submit', function() { | ||
422 | } | 412 | } |
423 | }, true); | 413 | }, true); |
424 | } | 414 | } |
415 | + | ||
425 | location.href = data.data; | 416 | location.href = data.data; |
426 | } else { | 417 | } else { |
427 | - $that.data('isClick', true); | ||
428 | tip.show(data.message); | 418 | tip.show(data.message); |
429 | } | 419 | } |
420 | + | ||
430 | }); | 421 | }); |
431 | } else { | 422 | } else { |
432 | tip.show(obj.msg); | 423 | tip.show(obj.msg); |
433 | - $that.data('isClick', true); | ||
434 | if (obj.msg.indexOf('字段为空') > -1) { | 424 | if (obj.msg.indexOf('字段为空') > -1) { |
435 | FAILURE_CAUSE = 1; | 425 | FAILURE_CAUSE = 1; |
436 | } else if (obj.msg.indexOf('认证协议') > -1) { | 426 | } else if (obj.msg.indexOf('认证协议') > -1) { |
@@ -108,6 +108,18 @@ if ($('.banner-swiper').find('li').size() > 1) { | @@ -108,6 +108,18 @@ if ($('.banner-swiper').find('li').size() > 1) { | ||
108 | }); | 108 | }); |
109 | } | 109 | } |
110 | 110 | ||
111 | +// single_image的轮播 | ||
112 | +if ($('.banner-center-swiper').find('li').size() > 1) { | ||
113 | + new Swiper('.banner-center-swiper', { | ||
114 | + loop: true, | ||
115 | + autoplay: 3000, | ||
116 | + autoplayDisableOnInteraction: false, | ||
117 | + paginationClickable: true, | ||
118 | + slideElement: 'li', | ||
119 | + pagination: '.banner-center .pagination-inner' | ||
120 | + }); | ||
121 | +} | ||
122 | + | ||
111 | // 热门品牌滑动 | 123 | // 热门品牌滑动 |
112 | new Swiper('.brands-swiper', { | 124 | new Swiper('.brands-swiper', { |
113 | grabCursor: true, | 125 | grabCursor: true, |
@@ -101,6 +101,7 @@ function bindAvatar(dom) { | @@ -101,6 +101,7 @@ function bindAvatar(dom) { | ||
101 | avatarKey = dom.index(); | 101 | avatarKey = dom.index(); |
102 | 102 | ||
103 | if (!dom.hasClass('swiper-slide-active')) { | 103 | if (!dom.hasClass('swiper-slide-active')) { |
104 | + | ||
104 | // if (avatarKey >= (2 * bannerLen + 1)) { | 105 | // if (avatarKey >= (2 * bannerLen + 1)) { |
105 | // avatarSwiperClone && avatarSwiperClone.slideTo(bannerLen + 1, 0); | 106 | // avatarSwiperClone && avatarSwiperClone.slideTo(bannerLen + 1, 0); |
106 | // avatarSwiper.slideTo(bannerLen + 1, 0); | 107 | // avatarSwiper.slideTo(bannerLen + 1, 0); |
@@ -109,8 +110,7 @@ function bindAvatar(dom) { | @@ -109,8 +110,7 @@ function bindAvatar(dom) { | ||
109 | // avatarSwiper.slideTo(2 * bannerLen - (bannerLen - avatarKey), 0); | 110 | // avatarSwiper.slideTo(2 * bannerLen - (bannerLen - avatarKey), 0); |
110 | // } else { | 111 | // } else { |
111 | // avatarSwiperClone && avatarSwiperClone.slideTo(avatarKey, 200); | 112 | // avatarSwiperClone && avatarSwiperClone.slideTo(avatarKey, 200); |
112 | - avatarSwiper.slideTo(avatarKey, 200); | ||
113 | - | 113 | + // avatarSwiper.slideTo(avatarKey, 200); |
114 | // } | 114 | // } |
115 | 115 | ||
116 | return false; | 116 | return false; |
public/js/passport/sms-check.page.js
0 → 100644
1 | +var tip = require('plugin/tip'); | ||
2 | + | ||
3 | +var $resendBtn, | ||
4 | + $nextBtn, | ||
5 | + $smsCode, | ||
6 | + $resetBtn, | ||
7 | + mobile, area; | ||
8 | + | ||
9 | +var page = { | ||
10 | + disableAjax: false, | ||
11 | + | ||
12 | + time: 60, | ||
13 | + resendText: '重发验证码', | ||
14 | + timerId: null, | ||
15 | + init: function() { | ||
16 | + this.domInit(); | ||
17 | + this.bindEvents(); | ||
18 | + if (!window.canResend) { | ||
19 | + this.countDown(); | ||
20 | + } | ||
21 | + }, | ||
22 | + | ||
23 | + | ||
24 | + domInit: function() { | ||
25 | + $resendBtn = $('#resend-sms'); | ||
26 | + $nextBtn = $('#btn-next'); | ||
27 | + $resetBtn = $('.clear-input'); | ||
28 | + $smsCode = $('#sms-code'); | ||
29 | + mobile = $('#mobile').val(); | ||
30 | + area = $('#area').val(); | ||
31 | + }, | ||
32 | + | ||
33 | + | ||
34 | + bindEvents: function() { | ||
35 | + var self = this; | ||
36 | + | ||
37 | + $resendBtn.on('click', function() { | ||
38 | + self.resendSMS(); | ||
39 | + }); | ||
40 | + | ||
41 | + $smsCode.on('input', function() { | ||
42 | + var hasVal = Boolean($.trim(this.value)); | ||
43 | + | ||
44 | + $nextBtn.trigger('toggleDisable', !hasVal); | ||
45 | + $resetBtn.toggle(hasVal); | ||
46 | + }); | ||
47 | + | ||
48 | + $nextBtn.on('click', function() { | ||
49 | + self.submit(); | ||
50 | + }); | ||
51 | + | ||
52 | + $resetBtn.on('click', function() { | ||
53 | + $smsCode.val(''); | ||
54 | + $resetBtn.hide(); | ||
55 | + $nextBtn.trigger('toggleDisable'); | ||
56 | + }); | ||
57 | + | ||
58 | + $nextBtn.on('toggleDisable', function(event, bool) { | ||
59 | + if (bool === void 0) { | ||
60 | + bool = true; | ||
61 | + } | ||
62 | + | ||
63 | + $nextBtn.toggleClass('disable', bool); | ||
64 | + $nextBtn.prop('disabled', bool); | ||
65 | + }); | ||
66 | + }, | ||
67 | + | ||
68 | + countDown: function() { | ||
69 | + var self = this; | ||
70 | + var second = this.time; | ||
71 | + | ||
72 | + if (this.timerId) { | ||
73 | + return; | ||
74 | + } | ||
75 | + | ||
76 | + $resendBtn.prop('disabled', true); | ||
77 | + $resendBtn.text('重新发送(' + second + ')'); | ||
78 | + this.timerId = setInterval(function() { | ||
79 | + var txt = self.resendText; | ||
80 | + | ||
81 | + second = second - 1; | ||
82 | + | ||
83 | + if (second < 0) { | ||
84 | + clearInterval(self.timerId); | ||
85 | + self.timerId = null; | ||
86 | + $resendBtn.prop('disabled', false); | ||
87 | + } else { | ||
88 | + txt = '重新发送(' + second + '秒)'; | ||
89 | + } | ||
90 | + | ||
91 | + $resendBtn.text(txt); | ||
92 | + }, 1000); | ||
93 | + | ||
94 | + }, | ||
95 | + | ||
96 | + | ||
97 | + resendSMS: function() { | ||
98 | + var self = this; | ||
99 | + | ||
100 | + if ($resendBtn.prop('disabled')) { | ||
101 | + return; | ||
102 | + } | ||
103 | + | ||
104 | + $.get('/passport/sms_login/token.json', { | ||
105 | + area: area, | ||
106 | + mobile: mobile, | ||
107 | + }) | ||
108 | + .done(function(res) { | ||
109 | + if (res.code === 200) { | ||
110 | + self.countDown(); | ||
111 | + return; | ||
112 | + } | ||
113 | + | ||
114 | + tip.show(res.message); | ||
115 | + }) | ||
116 | + .fail(function() { | ||
117 | + tip.show('出错啦~休息一下'); | ||
118 | + }); | ||
119 | + }, | ||
120 | + | ||
121 | + submit: function() { | ||
122 | + var code = $.trim($smsCode.val()); | ||
123 | + | ||
124 | + if ($nextBtn.prop('disabled')) { | ||
125 | + return; | ||
126 | + } | ||
127 | + | ||
128 | + $nextBtn.prop('disabled', true); | ||
129 | + $.get('/passport/sms_login/check.json', { | ||
130 | + code: code | ||
131 | + }) | ||
132 | + .done(function(res) { | ||
133 | + if (res.code === 200) { | ||
134 | + // $nextBtn.off(); | ||
135 | + location.href = res.redirect; | ||
136 | + return; | ||
137 | + } | ||
138 | + | ||
139 | + tip.show(res.message); | ||
140 | + }) | ||
141 | + .fail(function() { | ||
142 | + tip.show('出错了, 请重试'); | ||
143 | + }) | ||
144 | + .always(function() { | ||
145 | + $nextBtn.prop('disabled', false); | ||
146 | + }); | ||
147 | + } | ||
148 | +}; | ||
149 | + | ||
150 | +$(function() { | ||
151 | + page.init(); | ||
152 | +}); |
public/js/passport/sms-login.page.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +var tip = require('plugin/tip'); | ||
4 | +var api = require('./api'); | ||
5 | + | ||
6 | +var $countrySelect, | ||
7 | + $areaCode, | ||
8 | + $nextBtn, | ||
9 | + $resetBtn, | ||
10 | + $phoneNum; | ||
11 | + | ||
12 | +var page = { | ||
13 | + init: function() { | ||
14 | + this.domInit(); | ||
15 | + this.bindEvent(); | ||
16 | + }, | ||
17 | + domInit: function() { | ||
18 | + $countrySelect = $('#country-select'); | ||
19 | + $areaCode = $('#area-code'); | ||
20 | + $nextBtn = $('#btn-next'); | ||
21 | + $phoneNum = $('#phone-num'); | ||
22 | + $resetBtn = $('.clear-input'); | ||
23 | + }, | ||
24 | + bindEvent: function() { | ||
25 | + var self = this; | ||
26 | + | ||
27 | + $countrySelect.on('change', function() { | ||
28 | + $areaCode.text(this.value); | ||
29 | + }); | ||
30 | + $phoneNum.on('input', function() { | ||
31 | + self.toggleNextBtn(); | ||
32 | + }); | ||
33 | + | ||
34 | + $nextBtn.on('click', function() { | ||
35 | + self.goNext(); | ||
36 | + }); | ||
37 | + | ||
38 | + $resetBtn.on('click', function() { | ||
39 | + $phoneNum.val(''); | ||
40 | + $nextBtn | ||
41 | + .prop('disabled', true) | ||
42 | + .toggleClass('disable', true); | ||
43 | + $resetBtn.hide(); | ||
44 | + }); | ||
45 | + }, | ||
46 | + | ||
47 | + // 切换$nextBtn disable状态 | ||
48 | + toggleNextBtn: function() { | ||
49 | + var bool = Boolean($.trim($phoneNum.val())); | ||
50 | + | ||
51 | + $nextBtn | ||
52 | + .toggleClass('disable', !bool) | ||
53 | + .prop('disabled', !bool); | ||
54 | + | ||
55 | + $resetBtn.toggle(bool); | ||
56 | + }, | ||
57 | + | ||
58 | + // 提交按钮 | ||
59 | + goNext: function() { | ||
60 | + var areaCode = $countrySelect.val(); | ||
61 | + var phone = $.trim($phoneNum.val()); | ||
62 | + | ||
63 | + if ($nextBtn.prop('disabled')) { | ||
64 | + return; | ||
65 | + } | ||
66 | + | ||
67 | + if (!api.phoneRegx[areaCode].test(phone)) { | ||
68 | + tip.show('手机号码格式不正确, 请重新输入'); | ||
69 | + return; | ||
70 | + } | ||
71 | + | ||
72 | + $nextBtn.prop('disabled', true); | ||
73 | + $.get('/passport/sms_login/token.json', { | ||
74 | + area: areaCode.replace('+', ''), | ||
75 | + mobile: phone | ||
76 | + }) | ||
77 | + .done(function(data) { | ||
78 | + if (data.code === 200) { | ||
79 | + // $nextBtn.off(); | ||
80 | + location.href = data.redirect; | ||
81 | + } else { | ||
82 | + tip.show(data.message); | ||
83 | + } | ||
84 | + }) | ||
85 | + .fail(function() { | ||
86 | + tip.show('出错了, 请重试'); | ||
87 | + }) | ||
88 | + .always(function() { | ||
89 | + $nextBtn.prop('disabled', false); | ||
90 | + }); | ||
91 | + | ||
92 | + | ||
93 | + | ||
94 | + } | ||
95 | +}; | ||
96 | + | ||
97 | +$(function() { | ||
98 | + page.init(); | ||
99 | +}); |
public/js/passport/sms-password.page.js
0 → 100644
1 | +var tip = require('plugin/tip'); | ||
2 | + | ||
3 | +var $eyeBtn, | ||
4 | + $pwd, | ||
5 | + $nextBtn; | ||
6 | + | ||
7 | +var page = { | ||
8 | + init: function() { | ||
9 | + this.domInit(); | ||
10 | + this.bindEvent(); | ||
11 | + }, | ||
12 | + domInit: function() { | ||
13 | + $eyeBtn = $('#eye'); | ||
14 | + $pwd = $('#pwd'); | ||
15 | + $nextBtn = $('#btn-next'); | ||
16 | + }, | ||
17 | + bindEvent: function() { | ||
18 | + var self = this; | ||
19 | + | ||
20 | + $eyeBtn.on('click', function() { | ||
21 | + self.togglePassword(); | ||
22 | + }); | ||
23 | + | ||
24 | + $nextBtn.on('click', function() { | ||
25 | + self.setPasswordAndLogin(); | ||
26 | + }); | ||
27 | + | ||
28 | + $pwd.on('input', function() { | ||
29 | + var bool = Boolean($.trim(this.value)); | ||
30 | + | ||
31 | + $nextBtn | ||
32 | + .toggleClass('disable', !bool) | ||
33 | + .prop('disabled', !bool); | ||
34 | + }); | ||
35 | + }, | ||
36 | + | ||
37 | + togglePassword: function() { | ||
38 | + var bool = $eyeBtn.hasClass('close'); | ||
39 | + | ||
40 | + $eyeBtn.toggleClass(function() { | ||
41 | + $pwd.attr('type', !bool ? 'password' : 'text'); | ||
42 | + return 'close'; | ||
43 | + }, !bool); | ||
44 | + }, | ||
45 | + | ||
46 | + setPasswordAndLogin: function() { | ||
47 | + var password = $.trim($pwd.val()); | ||
48 | + | ||
49 | + if ($nextBtn.prop('disabled')) { | ||
50 | + return; | ||
51 | + } | ||
52 | + | ||
53 | + $nextBtn.prop('disabled', true); | ||
54 | + $.post('/passport/sms_login/password.json', { | ||
55 | + password: password | ||
56 | + }) | ||
57 | + .done(function(res) { | ||
58 | + if (res.code === 200) { | ||
59 | + // $nextBtn.off(); | ||
60 | + location.href = res.redirect; | ||
61 | + return; | ||
62 | + } | ||
63 | + | ||
64 | + tip.show(res.message); | ||
65 | + }) | ||
66 | + .fail(function() { | ||
67 | + tip.show('出错了, 请重试'); | ||
68 | + }) | ||
69 | + .always(function() { | ||
70 | + $nextBtn.prop('disabled', false); | ||
71 | + }); | ||
72 | + } | ||
73 | +}; | ||
74 | + | ||
75 | +$(function() { | ||
76 | + page.init(); | ||
77 | +}); |
@@ -33,28 +33,36 @@ $border: #e0e0e0; | @@ -33,28 +33,36 @@ $border: #e0e0e0; | ||
33 | position: absolute; | 33 | position: absolute; |
34 | top: 30px; | 34 | top: 30px; |
35 | left: 30px; | 35 | left: 30px; |
36 | - height: 35px; | ||
37 | - padding: 0 10px; | ||
38 | - border: 2px solid $white; | ||
39 | - border-radius: 20px; | 36 | + height: 70px; |
37 | + padding: 0 20px; | ||
38 | + border: 4px solid $white; | ||
39 | + border-radius: 40px; | ||
40 | color: $white; | 40 | color: $white; |
41 | - font-size: 22px; | 41 | + font-size: 44px; |
42 | text-align: center; | 42 | text-align: center; |
43 | - line-height: 1.5; | 43 | + line-height: 70px; |
44 | + -webkit-transform: scale(0.5); | ||
45 | + transform: scale(0.5); | ||
46 | + -webkit-transform-origin: 0 0; | ||
47 | + transform-origin: 0 0; | ||
44 | } | 48 | } |
45 | 49 | ||
46 | .living { | 50 | .living { |
47 | position: absolute; | 51 | position: absolute; |
48 | top: 30px; | 52 | top: 30px; |
49 | left: 30px; | 53 | left: 30px; |
50 | - height: 35px; | ||
51 | - width: 70px; | 54 | + height: 70px; |
55 | + width: 140px; | ||
52 | background: $red; | 56 | background: $red; |
53 | - border-radius: 15px; | 57 | + border-radius: 40px; |
54 | color: $white; | 58 | color: $white; |
55 | - font-size: 22px; | 59 | + font-size: 44px; |
56 | text-align: center; | 60 | text-align: center; |
57 | - line-height: 1.5; | 61 | + line-height: 70px; |
62 | + -webkit-transform: scale(0.5); | ||
63 | + transform: scale(0.5); | ||
64 | + -webkit-transform-origin: 0 0; | ||
65 | + transform-origin: 0 0; | ||
58 | } | 66 | } |
59 | 67 | ||
60 | &_tag { | 68 | &_tag { |
@@ -196,14 +204,18 @@ $border: #e0e0e0; | @@ -196,14 +204,18 @@ $border: #e0e0e0; | ||
196 | position: absolute; | 204 | position: absolute; |
197 | top: 30px; | 205 | top: 30px; |
198 | left: 30px; | 206 | left: 30px; |
199 | - height: 35px; | ||
200 | - width: 70px; | 207 | + height: 70px; |
208 | + width: 140px; | ||
201 | background: $red; | 209 | background: $red; |
202 | - border-radius: 20px; | 210 | + border-radius: 40px; |
203 | color: $white; | 211 | color: $white; |
204 | - font-size: 22px; | 212 | + font-size: 44px; |
205 | text-align: center; | 213 | text-align: center; |
206 | - line-height: 1.5; | 214 | + line-height: 70px; |
215 | + -webkit-transform: scale(0.5); | ||
216 | + transform: scale(0.5); | ||
217 | + -webkit-transform-origin: 0 0; | ||
218 | + transform-origin: 0 0; | ||
207 | } | 219 | } |
208 | 220 | ||
209 | .main-intro { | 221 | .main-intro { |
@@ -294,14 +306,18 @@ $border: #e0e0e0; | @@ -294,14 +306,18 @@ $border: #e0e0e0; | ||
294 | position: absolute; | 306 | position: absolute; |
295 | top: 20px; | 307 | top: 20px; |
296 | left: 220px; | 308 | left: 220px; |
297 | - height: 35px; | ||
298 | - width: 70px; | ||
299 | - border: 2px solid $black; | ||
300 | - border-radius: 20px; | ||
301 | - font-size: 22px; | ||
302 | - line-height: 1.5; | 309 | + height: 70px; |
310 | + width: 140px; | ||
311 | + border: 4px solid $black; | ||
312 | + border-radius: 40px; | ||
313 | + font-size: 44px; | ||
314 | + line-height: 70px; | ||
303 | text-align: center; | 315 | text-align: center; |
304 | color: $black; | 316 | color: $black; |
317 | + -webkit-transform: scale(0.5); | ||
318 | + transform: scale(0.5); | ||
319 | + -webkit-transform-origin: 0 0; | ||
320 | + transform-origin: 0 0; | ||
305 | } | 321 | } |
306 | 322 | ||
307 | .pre-time { | 323 | .pre-time { |
@@ -203,8 +203,6 @@ | @@ -203,8 +203,6 @@ | ||
203 | padding-left: 1.75rem; | 203 | padding-left: 1.75rem; |
204 | display: inline-block; | 204 | display: inline-block; |
205 | color: #ffffff; | 205 | color: #ffffff; |
206 | - border-radius: 0.3rem; | ||
207 | - background-color: rgba(0, 0, 0, 0.32); | ||
208 | font-size: 0.6rem; | 206 | font-size: 0.6rem; |
209 | 207 | ||
210 | } | 208 | } |
@@ -224,7 +222,9 @@ | @@ -224,7 +222,9 @@ | ||
224 | font-size: 22px; | 222 | font-size: 22px; |
225 | font-weight: lighter; | 223 | font-weight: lighter; |
226 | color: rgba(255,255,255,0.8); | 224 | color: rgba(255,255,255,0.8); |
225 | + background-color: rgba(0, 0, 0, 0.32); | ||
227 | overflow: hidden; | 226 | overflow: hidden; |
227 | + border-radius: 0.3rem; | ||
228 | } | 228 | } |
229 | 229 | ||
230 | .live-item2_2 { | 230 | .live-item2_2 { |
@@ -234,6 +234,7 @@ | @@ -234,6 +234,7 @@ | ||
234 | line-height: 1.2; | 234 | line-height: 1.2; |
235 | font-weight: normal; | 235 | font-weight: normal; |
236 | color: #FFFFFF; | 236 | color: #FFFFFF; |
237 | + border-radius: 0.3rem; | ||
237 | } | 238 | } |
238 | 239 | ||
239 | .live-item2 img { | 240 | .live-item2 img { |
@@ -242,7 +243,7 @@ | @@ -242,7 +243,7 @@ | ||
242 | top: 0; | 243 | top: 0; |
243 | display: inline-block; | 244 | display: inline-block; |
244 | width: 2.5rem; | 245 | width: 2.5rem; |
245 | - height: 100%; | 246 | + border-radius: 0.3rem; |
246 | } | 247 | } |
247 | 248 | ||
248 | .live-item2-head { | 249 | .live-item2-head { |
1 | .banner-center { | 1 | .banner-center { |
2 | + position: relative; | ||
2 | margin: 30px 0 0; | 3 | margin: 30px 0 0; |
3 | height: 200px; | 4 | height: 200px; |
4 | overflow: hidden; | 5 | overflow: hidden; |
6 | + | ||
5 | img { | 7 | img { |
6 | display: block; | 8 | display: block; |
7 | width: 100%; | 9 | width: 100%; |
8 | height: 100%; | 10 | height: 100%; |
9 | } | 11 | } |
12 | + | ||
13 | + .swiper-pagination { | ||
14 | + position: absolute; | ||
15 | + left: 0; | ||
16 | + right: 0; | ||
17 | + bottom: 20px; | ||
18 | + text-align: center; | ||
19 | + z-index: 1; | ||
20 | + | ||
21 | + .pagination-inner { | ||
22 | + display: inline-block; | ||
23 | + | ||
24 | + span { | ||
25 | + display: inline-block; | ||
26 | + width: 14px; | ||
27 | + height: 14px; | ||
28 | + background: #fff; | ||
29 | + opacity: 0.5; | ||
30 | + margin: 0 9px; | ||
31 | + border-radius: 50%; | ||
32 | + | ||
33 | + &.swiper-pagination-bullet-active { | ||
34 | + background: #fff; | ||
35 | + opacity: 1; | ||
36 | + } | ||
37 | + } | ||
38 | + } | ||
39 | + } | ||
40 | +} | ||
41 | + | ||
42 | +.banner-center-swiper { | ||
43 | + background: #fff; | ||
44 | + width: 100%; | ||
45 | + height: 200px; | ||
46 | + border-top: 1px solid #e0e0e0; | ||
47 | + overflow: hidden; | ||
48 | + | ||
49 | + .banner-list { | ||
50 | + position: relative; | ||
51 | + height: 200px; | ||
52 | + | ||
53 | + li { | ||
54 | + float: left; | ||
55 | + width: 100%; | ||
56 | + height: 200px; | ||
57 | + | ||
58 | + a { | ||
59 | + position: relative; | ||
60 | + display: block; | ||
61 | + width: 100%; | ||
62 | + height: 100%; | ||
63 | + line-height: 200px; | ||
64 | + font-size: 0; | ||
65 | + } | ||
66 | + | ||
67 | + img { | ||
68 | + display: inline-block; | ||
69 | + max-width: 100%; | ||
70 | + max-height: 100%; | ||
71 | + vertical-align: middle; | ||
72 | + } | ||
73 | + } | ||
74 | + } | ||
10 | } | 75 | } |
1 | @charset "utf-8"; | 1 | @charset "utf-8"; |
2 | + | ||
2 | @import "me/index"; | 3 | @import "me/index"; |
3 | @import "layout/reset"; | 4 | @import "layout/reset"; |
4 | @import "layout/common"; | 5 | @import "layout/common"; |
@@ -7,6 +8,7 @@ | @@ -7,6 +8,7 @@ | ||
7 | @import "layout/header"; | 8 | @import "layout/header"; |
8 | @import "layout/footer"; | 9 | @import "layout/footer"; |
9 | @import "layout/utils"; | 10 | @import "layout/utils"; |
11 | +@import "layout/form"; | ||
10 | @import "common/index"; | 12 | @import "common/index"; |
11 | @import "channel/index"; | 13 | @import "channel/index"; |
12 | @import "product/index"; | 14 | @import "product/index"; |
@@ -53,9 +53,9 @@ a { | @@ -53,9 +53,9 @@ a { | ||
53 | } | 53 | } |
54 | 54 | ||
55 | @font-face { | 55 | @font-face { |
56 | - font-family: 'iconfont'; | ||
57 | - src: resolve('iconfont.eot'); /* IE9 */ | ||
58 | - src: resolve('iconfont.eot?#iefix') format('embedded-opentype'), resolve('iconfont.woff') format('woff'), resolve('iconfont.ttf') format('truetype'), resolve('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */ | 56 | + font-family: "iconfont"; |
57 | + src: resolve("iconfont.eot"); /* IE9 */ | ||
58 | + src: resolve("iconfont.eot?#iefix") format("embedded-opentype"), resolve("iconfont.woff") format("woff"), resolve("iconfont.ttf") format("truetype"), resolve("iconfont.svg#iconfont") format("svg"); /* iOS 4.1- */ | ||
59 | } | 59 | } |
60 | 60 | ||
61 | .iconfont { | 61 | .iconfont { |
public/scss/layout/_form.css
0 → 100644
@@ -138,7 +138,10 @@ body.passport-body { | @@ -138,7 +138,10 @@ body.passport-body { | ||
138 | background-color: #36a74c; | 138 | background-color: #36a74c; |
139 | border-radius: 5PX; | 139 | border-radius: 5PX; |
140 | color: #fff; | 140 | color: #fff; |
141 | - &.disable { | 141 | + border: none; |
142 | + outline: none; | ||
143 | + | ||
144 | + &.disable, &:disabled { | ||
142 | background-color: #a2a2a2; | 145 | background-color: #a2a2a2; |
143 | } | 146 | } |
144 | } | 147 | } |
@@ -154,6 +157,9 @@ body.passport-body { | @@ -154,6 +157,9 @@ body.passport-body { | ||
154 | height: 16PX; | 157 | height: 16PX; |
155 | background: resolve('passport/clear-input.png') no-repeat; | 158 | background: resolve('passport/clear-input.png') no-repeat; |
156 | background-size: 100% 100%; | 159 | background-size: 100% 100%; |
160 | + outline: none; | ||
161 | + border: none; | ||
162 | + padding: 0; /* button has padding in default */ | ||
157 | } | 163 | } |
158 | .eye { | 164 | .eye { |
159 | position: absolute; | 165 | position: absolute; |
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | position: absolute; | 3 | position: absolute; |
4 | height: 31PX; | 4 | height: 31PX; |
5 | width: 26PX; | 5 | width: 26PX; |
6 | - background: resolve('passport/yoho.png'); | 6 | + background: resolve("passport/yoho.png"); |
7 | background-size: 100% 100%; | 7 | background-size: 100% 100%; |
8 | top: 10PX; | 8 | top: 10PX; |
9 | left: 15PX; | 9 | left: 15PX; |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | text-align: left; | 20 | text-align: left; |
21 | font-size: 16PX; | 21 | font-size: 16PX; |
22 | 22 | ||
23 | - .go-register { | 23 | + .sms-login { |
24 | text-decoration: underline; | 24 | text-decoration: underline; |
25 | color: #858585; | 25 | color: #858585; |
26 | } | 26 | } |
@@ -57,20 +57,20 @@ | @@ -57,20 +57,20 @@ | ||
57 | } | 57 | } |
58 | 58 | ||
59 | .alipay { | 59 | .alipay { |
60 | - background-image: resolve('passport/alipay.png'); | 60 | + background-image: resolve("passport/alipay.png"); |
61 | } | 61 | } |
62 | 62 | ||
63 | .weibo { | 63 | .weibo { |
64 | - background-image: resolve('passport/weibo.png'); | 64 | + background-image: resolve("passport/weibo.png"); |
65 | } | 65 | } |
66 | 66 | ||
67 | .qq { | 67 | .qq { |
68 | - background-image: resolve('passport/qq.png'); | 68 | + background-image: resolve("passport/qq.png"); |
69 | } | 69 | } |
70 | 70 | ||
71 | .wechat { | 71 | .wechat { |
72 | display: none; | 72 | display: none; |
73 | - background-image: resolve('passport/wechat.png'); | 73 | + background-image: resolve("passport/wechat.png"); |
74 | } | 74 | } |
75 | } | 75 | } |
76 | } | 76 | } |
@@ -82,11 +82,19 @@ | @@ -82,11 +82,19 @@ | ||
82 | background-color: #333; | 82 | background-color: #333; |
83 | border: none; | 83 | border: none; |
84 | border-radius: 20PX; | 84 | border-radius: 20PX; |
85 | - margin: 0 auto; | 85 | + margin: 0 auto 28px; |
86 | font-size: 16PX; | 86 | font-size: 16PX; |
87 | color: #d8d8d8; | 87 | color: #d8d8d8; |
88 | } | 88 | } |
89 | 89 | ||
90 | + .go-register { | ||
91 | + color: #858585; | ||
92 | + | ||
93 | + a { | ||
94 | + color: inherit; | ||
95 | + } | ||
96 | + } | ||
97 | + | ||
90 | .login-tip { | 98 | .login-tip { |
91 | font-size: 16PX; | 99 | font-size: 16PX; |
92 | position: relative; | 100 | position: relative; |
@@ -97,7 +105,7 @@ | @@ -97,7 +105,7 @@ | ||
97 | display: inline-block; | 105 | display: inline-block; |
98 | height: 12PX; | 106 | height: 12PX; |
99 | width: 12PX; | 107 | width: 12PX; |
100 | - background-image: resolve('passport/info.png'); | 108 | + background-image: resolve("passport/info.png"); |
101 | background-size: 100% 100%; | 109 | background-size: 100% 100%; |
102 | } | 110 | } |
103 | } | 111 | } |
public/scss/passport/_sms-login.css
0 → 100644
1 | +.sms-login { | ||
2 | + .sms-input { | ||
3 | + margin-top: 60px; | ||
4 | + } | ||
5 | + | ||
6 | + #resend-sms { | ||
7 | + background-color: transparent; | ||
8 | + width: 148PX; | ||
9 | + margin: 0 15PX 0 28PX; | ||
10 | + border: 1PX solid #36a74c; | ||
11 | + padding: 5PX 0; | ||
12 | + border-radius: 20PX; | ||
13 | + font-size: 16PX; | ||
14 | + color: #36a74c; | ||
15 | + | ||
16 | + &:disabled { | ||
17 | + color: #a2a2a2; | ||
18 | + border-color: #a2a2a2; | ||
19 | + } | ||
20 | + } | ||
21 | + | ||
22 | + button { | ||
23 | + border: none; | ||
24 | + } | ||
25 | +} | ||
26 | + | ||
27 | +.sms-login-check { | ||
28 | + .clear-input { | ||
29 | + right: 175PX; | ||
30 | + } | ||
31 | +} | ||
32 | + | ||
33 | +.sms-login-msg { | ||
34 | + font-size: 28px; | ||
35 | + color: #fff; | ||
36 | + margin-bottom: 20px; | ||
37 | + | ||
38 | + .tel { | ||
39 | + color: #41cbe7; | ||
40 | + } | ||
41 | + | ||
42 | + &.small { | ||
43 | + font-size: 22px; | ||
44 | + color: #858585; | ||
45 | + } | ||
46 | +} |
@@ -42,7 +42,7 @@ module.exports = { | @@ -42,7 +42,7 @@ module.exports = { | ||
42 | resolve: { | 42 | resolve: { |
43 | alias: { | 43 | alias: { |
44 | common: path.join(__dirname, 'js/common'), | 44 | common: path.join(__dirname, 'js/common'), |
45 | - plugin: path.join(__dirname, 'js/plugins') | 45 | + plugin: path.join(__dirname, 'js/plugin') |
46 | } | 46 | } |
47 | }, | 47 | }, |
48 | plugins: [ | 48 | plugins: [ |
-
Please register or login to post a comment