Showing
12 changed files
with
307 additions
and
46 deletions
This diff could not be displayed because it is too large.
1 | webpackJsonp([0],[ | 1 | webpackJsonp([0],[ |
2 | /* 0 */ | 2 | /* 0 */ |
3 | -/***/ function(module, exports) { | 3 | +/***/ function(module, exports, __webpack_require__) { |
4 | 4 | ||
5 | - | 5 | + 'use strict'; |
6 | + var $ = __webpack_require__(1); | ||
7 | + | ||
8 | + // 图像验证码URL | ||
9 | + var CAPTCHA_IMG_URL = 'captcha?t=', | ||
10 | + $captchaImgInput = $('#captcha'), | ||
11 | + $captchaImgWrapper = $('.captcha-wrap'), | ||
12 | + $captchaImgPic = $captchaImgWrapper.find('#captcha-img'), | ||
13 | + $captchaImgTip = $captchaImgInput.siblings('.err-tip'); | ||
14 | + | ||
15 | + // click登录 | ||
16 | + $('#login-btn').on('click', loginAsync); | ||
17 | + | ||
18 | + /** ************************************************************************/ | ||
19 | + /* 登录函数 */ | ||
20 | + /** ************************************************************************/ | ||
21 | + | ||
22 | + function loginAsync() { | ||
23 | + return validateCaptchaImg().then(function() { | ||
24 | + return $.ajax({ | ||
25 | + url: 'login/', | ||
26 | + type: 'POST', | ||
27 | + dataType: 'json', | ||
28 | + data: { | ||
29 | + user: $('#user').val(), | ||
30 | + password: $('#password').val() | ||
31 | + } | ||
32 | + }); | ||
33 | + }).then(function(res) { | ||
34 | + if (res.code === 200) { | ||
35 | + location.href = '/'; | ||
36 | + } else if (res.code === 400){ | ||
37 | + if (res.data.needCaptcha) { | ||
38 | + $captchaImgTip.removeClass('hide') | ||
39 | + .children('em'); | ||
40 | + | ||
41 | + $captchaImgInput.val(''); | ||
42 | + showCaptchaImgPic(); | ||
43 | + } else { | ||
44 | + location.href = '/'; | ||
45 | + } | ||
46 | + } | ||
47 | + }); | ||
48 | + } | ||
49 | + | ||
50 | + /** ************************************************************************/ | ||
51 | + /* 验证码刷新 */ | ||
52 | + /** ************************************************************************/ | ||
53 | + $captchaImgWrapper.on('click', '.change-captcha, .captcha-img', function() { | ||
54 | + $captchaImgPic.attr('src', CAPTCHA_IMG_URL + $.now()); | ||
55 | + }); | ||
56 | + | ||
57 | + /** ************************************************************************/ | ||
58 | + /* 显示验证码 */ | ||
59 | + /** ************************************************************************/ | ||
60 | + function showCaptchaImgPic() { | ||
61 | + $captchaImgPic.attr('src', CAPTCHA_IMG_URL + $.now()); | ||
62 | + $captchaImgInput.val(''); | ||
63 | + $captchaImgWrapper.removeClass('hide'); | ||
64 | + } | ||
65 | + | ||
66 | + /** ************************************************************************/ | ||
67 | + /* 验证验证码是否正确 */ | ||
68 | + /** ************************************************************************/ | ||
69 | + // 图像验证码输入框事件 | ||
70 | + $captchaImgInput.on('blur', validateCaptchaImg); | ||
71 | + | ||
72 | + function validateCaptchaImg() { | ||
73 | + // 验证码不可见的时候验证通过 | ||
74 | + if ($captchaImgWrapper.is(':hidden')) { | ||
75 | + return $.Deferred().resolve().promise(); //eslint-disable-line | ||
76 | + } | ||
77 | + | ||
78 | + return validateCaptchaImgLocal() | ||
79 | + .then(validateCaptchaImgAsync); | ||
80 | + } | ||
81 | + | ||
82 | + function validateCaptchaImgAsync() { | ||
83 | + return $.ajax({ | ||
84 | + url: 'checkCaptchaImg/', | ||
85 | + type: 'POST', | ||
86 | + dataType: 'json', | ||
87 | + data: { | ||
88 | + verifyCode: getCaptchaImgVal() | ||
89 | + } | ||
90 | + }).then(function(result) { | ||
91 | + var defer = $.Deferred(); // eslint-disable-line | ||
92 | + | ||
93 | + if (result.code === 200) { | ||
94 | + hideCaptchaImgTip(); | ||
95 | + | ||
96 | + defer.resolve(); | ||
97 | + } else { | ||
98 | + showCaptchaImgTip('验证码不正确'); | ||
99 | + | ||
100 | + defer.reject(); | ||
101 | + } | ||
102 | + | ||
103 | + return defer.promise(); | ||
104 | + }); | ||
105 | + } | ||
106 | + | ||
107 | + function validateCaptchaImgLocal() { | ||
108 | + var captcha = getCaptchaImgVal(), | ||
109 | + err; | ||
110 | + | ||
111 | + var defer = $.Deferred(); // eslint-disable-line | ||
112 | + | ||
113 | + if (captcha !== '') { | ||
114 | + if (captcha.length !== 4) { | ||
115 | + err = '请输入长度为4字符的验证码'; | ||
116 | + | ||
117 | + defer.reject(); | ||
118 | + } else { | ||
119 | + | ||
120 | + defer.resolve(); | ||
121 | + } | ||
122 | + } else { | ||
123 | + err = '请输入验证码'; | ||
124 | + | ||
125 | + defer.reject(); | ||
126 | + } | ||
127 | + | ||
128 | + if (defer.state() === 'resolved') { | ||
129 | + hideCaptchaImgTip(); | ||
130 | + } else { | ||
131 | + showCaptchaImgTip(err); | ||
132 | + } | ||
133 | + | ||
134 | + return defer.promise(); | ||
135 | + } | ||
136 | + | ||
137 | + function getCaptchaImgVal() { | ||
138 | + return $.trim($captchaImgInput.val()); | ||
139 | + } | ||
140 | + | ||
141 | + function hideCaptchaImgTip() { | ||
142 | + return errTipHide($captchaImgTip, $captchaImgInput); | ||
143 | + } | ||
144 | + | ||
145 | + function showCaptchaImgTip(msg) { | ||
146 | + return errTipShow($captchaImgTip, $captchaImgInput, msg); | ||
147 | + } | ||
148 | + | ||
149 | + function errTipHide($tip, $input) { | ||
150 | + $tip.addClass('hide'); | ||
151 | + //$input.removeClass('error'); | ||
152 | + } | ||
153 | + | ||
154 | + function errTipShow($tip, $input, msg) { | ||
155 | + $tip.removeClass('hide').children('em').empty().html(msg); | ||
156 | + //$input.addClass('error'); | ||
157 | + } | ||
6 | 158 | ||
7 | /***/ } | 159 | /***/ } |
8 | ]); | 160 | ]); |
@@ -319,7 +319,7 @@ webpackJsonp([13],[ | @@ -319,7 +319,7 @@ webpackJsonp([13],[ | ||
319 | //Ajax查询店铺下销售类目 | 319 | //Ajax查询店铺下销售类目 |
320 | function findShopCategory() { | 320 | function findShopCategory() { |
321 | common.util.__ajax({ | 321 | common.util.__ajax({ |
322 | - url:'/shops/shopCategory/list', | 322 | + url:'/shops/shopCategory/categoryList', |
323 | data: { | 323 | data: { |
324 | shopId: jsonMain.shopsId | 324 | shopId: jsonMain.shopsId |
325 | } | 325 | } |
server/controllers/common.captcha.js
0 → 100644
1 | + | ||
2 | +module.exports=function(app) { | ||
3 | + | ||
4 | + app.get("/captcha", "captcha_create", function (captcha, req, res){ | ||
5 | + res.writeHead(200, { | ||
6 | + 'Content-Type': 'image/png' | ||
7 | + }); | ||
8 | + res.end(captcha); | ||
9 | + }); | ||
10 | + | ||
11 | + app.post("/checkCaptchaImg", "captcha_checkCaptchaImg", function (captcha, req, res){ | ||
12 | + return res.json(captcha); | ||
13 | + }); | ||
14 | +} | ||
15 | + | ||
16 | + |
@@ -9,9 +9,18 @@ module.exports=function(app) { | @@ -9,9 +9,18 @@ module.exports=function(app) { | ||
9 | 9 | ||
10 | app.post("/login", "common_login", function (login, req, res){ | 10 | app.post("/login", "common_login", function (login, req, res){ |
11 | if (login.code == 200) { | 11 | if (login.code == 200) { |
12 | - res.myRedirect('/'); | ||
13 | - } else { | ||
14 | - res.myRedirect('/login'); | 12 | + return res.json({ |
13 | + code: 200, | ||
14 | + message: login.message | ||
15 | + }); | ||
16 | + } else if(login.code == 400){ | ||
17 | + return res.json({ | ||
18 | + code: 400, | ||
19 | + message: login.message, | ||
20 | + data: { | ||
21 | + needCaptcha: login.needCaptcha | ||
22 | + } | ||
23 | + }); | ||
15 | } | 24 | } |
16 | }); | 25 | }); |
17 | 26 |
@@ -25,6 +25,9 @@ module.exports = function (app){ | @@ -25,6 +25,9 @@ module.exports = function (app){ | ||
25 | //店铺销售类目列表 | 25 | //店铺销售类目列表 |
26 | app.post("/shops/shopCategory/list","shopCategory_shopsCategoryList"); | 26 | app.post("/shops/shopCategory/list","shopCategory_shopsCategoryList"); |
27 | 27 | ||
28 | + //店铺商品分类列表,仅用于装修页面,下拉选择商品分类的场景 | ||
29 | + app.post("/shops/shopCategory/categoryList", "shopCategory_selectCategoryList"); | ||
30 | + | ||
28 | //新增店铺销售类目 | 31 | //新增店铺销售类目 |
29 | app.post("/shops/shopCategory/add","shopCategory_insertShopsAndLinkCategory"); | 32 | app.post("/shops/shopCategory/add","shopCategory_insertShopsAndLinkCategory"); |
30 | 33 |
1 | module.exports=function(Filter){ | 1 | module.exports=function(Filter){ |
2 | - Filter.define("/!(login)", ["get","post"], "common_gray", function (gray, req, res, next){ | 2 | + Filter.define("/!(login|captcha|checkCaptchaImg)", ["get","post"], "common_gray", function (gray, req, res, next){ |
3 | if(gray.code==200){ | 3 | if(gray.code==200){ |
4 | next(); | 4 | next(); |
5 | }else{ | 5 | }else{ |
server/interfaces/common.captcha.js
0 → 100644
1 | + | ||
2 | +'use strict'; | ||
3 | + | ||
4 | +var _ = require('lodash'); | ||
5 | +var Captchapng = require('captchapng'); | ||
6 | + | ||
7 | +var Utils = { | ||
8 | + generateCaptcha: function (width, height, length) { | ||
9 | + var min = Math.pow(10, (length - 1 || 1)); | ||
10 | + var max = Math.pow(10, (length - 1 || 1)) * 9; | ||
11 | + var token = '' + _.random(min, max); | ||
12 | + var png = new Captchapng(width, height, token);// | ||
13 | + png.color(0, 0, 0, 0); // First color: background (red, green, blue, alpha) | ||
14 | + png.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha) | ||
15 | + | ||
16 | + return { | ||
17 | + image: new Buffer(png.getBase64(), 'base64'), | ||
18 | + text: token | ||
19 | + }; | ||
20 | + } | ||
21 | +}; | ||
22 | + | ||
23 | +module.exports = { | ||
24 | + namespace: "captcha", | ||
25 | + apis: { | ||
26 | + create: function (req, callback) { | ||
27 | + var width = req.query.w || 150; | ||
28 | + var height = req.query.h || 50; | ||
29 | + var length = +(req.query.l || 4); | ||
30 | + var captcha = Utils.generateCaptcha(width, height, length); | ||
31 | + req.session.captcha = captcha.text; | ||
32 | + return callback(null, captcha.image); | ||
33 | + }, | ||
34 | + checkCaptchaImg: function (req, callback) { | ||
35 | + var captchaToken = req.body.verifyCode || ''; | ||
36 | + if (captchaToken === req.session.captcha) { | ||
37 | + return callback(null, { | ||
38 | + code: 200, | ||
39 | + message: '验证成功' | ||
40 | + }); | ||
41 | + } else { | ||
42 | + return callback(null, { | ||
43 | + code: 400, | ||
44 | + message: '您输入的验证码不正确!' | ||
45 | + }); | ||
46 | + } | ||
47 | + } | ||
48 | + | ||
49 | + | ||
50 | + } | ||
51 | +}; |
@@ -83,47 +83,60 @@ module.exports = { | @@ -83,47 +83,60 @@ module.exports = { | ||
83 | var userInfo = {},result = { code: 400, message: "登录失败" },isSuccess=false; | 83 | var userInfo = {},result = { code: 400, message: "登录失败" },isSuccess=false; |
84 | var user = req.body.user; | 84 | var user = req.body.user; |
85 | var password = req.body.password; | 85 | var password = req.body.password; |
86 | - var errcallback = function (err) { | 86 | + var errcallback = function (err) { |
87 | return callback(err, result); | 87 | return callback(err, result); |
88 | - } | 88 | + }; |
89 | + var loginErrcallback = function (err) { | ||
90 | + result.needCaptcha = true; | ||
91 | + return callback(null, result); | ||
92 | + }; | ||
89 | //promise.all(Ilogin,allRight,sessionAsync).then(a,b,c); | 93 | //promise.all(Ilogin,allRight,sessionAsync).then(a,b,c); |
90 | 94 | ||
91 | - common.Ilogin(user, password).allRight().sessionAsync(user, password).done(function (IloginRes,allRes,sesRes) { | ||
92 | - var userData = IloginRes.data, cookie = sesRes.caseless.dict["set-cookie"]; | 95 | + common.Ilogin(user, password).done(function (IloginRes) { |
96 | + var userData = IloginRes.data; | ||
93 | userInfo = { auth: userData, uid: userData.pid, name: userData.truename, right: {},shopList:[]}; | 97 | userInfo = { auth: userData, uid: userData.pid, name: userData.truename, right: {},shopList:[]}; |
94 | - allRes.data.forEach(function (data) { | ||
95 | - if (data.platform_id == Iaccount.WEBSITE) { | ||
96 | - userInfo.right[data.path] = true; | ||
97 | - } | ||
98 | - }); | ||
99 | - common.getResourceByPid(userData.pid, userData.role_id) | ||
100 | - .getShopList({ "@x-user-id": userInfo.uid }).done(function (getRRes, shopRes) { | ||
101 | - userInfo.menu = Utils.createrMenus(getRRes.data); | ||
102 | - if (shopRes.data) { | ||
103 | - shopRes.data.forEach(function (data, index) { | ||
104 | - if (!index) { | ||
105 | - userInfo.auth.shopName = data.shopName; | ||
106 | - userInfo.auth.shopId = data.shopsId; | ||
107 | - } | ||
108 | - userInfo.shopList.push({ | ||
109 | - name: data.shopName, | ||
110 | - id: data.shopsId | ||
111 | - }); | ||
112 | - }); | ||
113 | - req.session.user = userInfo; | ||
114 | - if (cookie && cookie.length > 0) { | ||
115 | - req.session.gray = cookie[0]; | ||
116 | - result = { code: 200, message: "登录成功" }; | 98 | + |
99 | + common.allRight().sessionAsync(user, password).done(function (allRes,sesRes) { | ||
100 | + var cookie = sesRes.caseless.dict["set-cookie"]; | ||
101 | + allRes.data.forEach(function (data) { | ||
102 | + if (data.platform_id == Iaccount.WEBSITE) { | ||
103 | + userInfo.right[data.path] = true; | ||
117 | } | 104 | } |
118 | - console.log(result); | 105 | + }); |
106 | + | ||
107 | + common.getResourceByPid(userData.pid, userData.role_id) | ||
108 | + .getShopList({ "@x-user-id": userInfo.uid }).done(function (getRRes, shopRes) { | ||
109 | + userInfo.menu = Utils.createrMenus(getRRes.data); | ||
110 | + if (shopRes.data) { | ||
111 | + shopRes.data.forEach(function (data, index) { | ||
112 | + if (!index) { | ||
113 | + userInfo.auth.shopName = data.shopName; | ||
114 | + userInfo.auth.shopId = data.shopsId; | ||
115 | + } | ||
116 | + userInfo.shopList.push({ | ||
117 | + name: data.shopName, | ||
118 | + id: data.shopsId | ||
119 | + }); | ||
120 | + }); | ||
121 | + req.session.user = userInfo; | ||
122 | + if (cookie && cookie.length > 0) { | ||
123 | + req.session.gray = cookie[0]; | ||
124 | + result = { code: 200, message: "登录成功" }; | ||
125 | + } | ||
126 | + console.log(result); | ||
127 | + | ||
128 | + } else { | ||
129 | + result = { code: 400, message: "该用户没有店铺" }; | ||
130 | + } | ||
131 | + return callback(null, result); | ||
132 | + },errcallback); | ||
133 | + | ||
134 | + }, errcallback); | ||
135 | + | ||
136 | + }, loginErrcallback); | ||
119 | 137 | ||
120 | - } else { | ||
121 | - result = { code: 400, message: "该用户没有店铺" }; | ||
122 | - } | ||
123 | - return callback(null, result); | ||
124 | - },errcallback); | ||
125 | - }, errcallback); | ||
126 | }, | 138 | }, |
139 | + | ||
127 | isUsedMenuAuth:{ | 140 | isUsedMenuAuth:{ |
128 | title:'检查有没有权限', | 141 | title:'检查有没有权限', |
129 | url:Iaccount.isUsedMenuAuth, | 142 | url:Iaccount.isUsedMenuAuth, |
@@ -15,6 +15,14 @@ module.exports={ | @@ -15,6 +15,14 @@ module.exports={ | ||
15 | params:[] | 15 | params:[] |
16 | }, | 16 | }, |
17 | 17 | ||
18 | + selectCategoryList:{ | ||
19 | + title:"店铺商品分类列表,仅用于装修页面,下拉选择商品分类场景", | ||
20 | + url:"/ShopsSalesCategoryRest/selectCategoryList", | ||
21 | + params:[ | ||
22 | + {name:"shopId",type:"Number"} | ||
23 | + ] | ||
24 | + }, | ||
25 | + | ||
18 | insertShopsAndLinkCategory:{ | 26 | insertShopsAndLinkCategory:{ |
19 | title:"新增店铺商品分类", | 27 | title:"新增店铺商品分类", |
20 | url:"/ShopsSalesCategoryRest/insertShopsAndLinkCategory", | 28 | url:"/ShopsSalesCategoryRest/insertShopsAndLinkCategory", |
1 | -{"name":"yohobuy-shops-fe","version":"4.8.3","description":"Construction of the presentation layer solution is based on express, handlebars","main":"app.js","scripts":{"code":"set NODE_ENV=coding&& gulp start","build":"set NODE_ENV=production && gulp && gulp mvc","server":"set NODE_ENV=server&& gulp start"},"dependencies":{"art-template":"^3.0.3","async":"^2.0.0-rc.3","body-parser":"^1.15.0","connect-multiparty":"^2.0.0","connect-redis":"^3.0.2","cookie-parser":"^1.4.1","express":"^4.13.4","express-session":"^1.13.0","lodash":"^4.11.1","md5":"^2.1.0","mkdirp":"^0.5.1","request":"^2.72.0","winston":"^2.2.0","glob":"^7.0.3"}} | ||
1 | +{"name":"yohobuy-shops-fe","version":"4.8.3","description":"Construction of the presentation layer solution is based on express, handlebars","main":"app.js","scripts":{"code":"set NODE_ENV=coding&& gulp start","build":"set NODE_ENV=production && gulp && gulp mvc","server":"set NODE_ENV=server&& gulp start"},"dependencies":{"art-template":"^3.0.3","async":"^2.0.0-rc.3","body-parser":"^1.15.0","connect-multiparty":"^2.0.0","connect-redis":"^3.0.2","cookie-parser":"^1.4.1","express":"^4.13.4","express-session":"^1.13.0","lodash":"^4.11.1","md5":"^2.1.0","mkdirp":"^0.5.1","request":"^2.72.0","winston":"^2.2.0","glob":"^7.0.3","captchapng":"0.0.1"}} |
@@ -20,16 +20,25 @@ | @@ -20,16 +20,25 @@ | ||
20 | </div> | 20 | </div> |
21 | </div> | 21 | </div> |
22 | <div class="login-content"> | 22 | <div class="login-content"> |
23 | - <form action="/login" method="POST" class="margin-bottom-0"> | 23 | + <form class="margin-bottom-0" onsubmit='return false;'> |
24 | <input type="hidden" name="refer" value="%2F"> | 24 | <input type="hidden" name="refer" value="%2F"> |
25 | <div class="form-group m-b-20"> | 25 | <div class="form-group m-b-20"> |
26 | - <input type="text" class="form-control input-lg" name="user" placeholder="用户名" autocomplete="off" /> | 26 | + <input type="text" class="form-control input-lg" id="user" name="user" placeholder="用户名" autocomplete="off" /> |
27 | </div> | 27 | </div> |
28 | <div class="form-group m-b-20"> | 28 | <div class="form-group m-b-20"> |
29 | - <input type="password" class="form-control input-lg" name="password" placeholder="密码" autocomplete="off" /> | 29 | + <input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码" autocomplete="off" /> |
30 | + </div> | ||
31 | + <div class="input-group mb15 captcha-wrap hide"> | ||
32 | + <input type="text" name="captcha" id="captcha" class="form-control" placeholder="图形验证码" autocomplete="off" maxlength="4"> | ||
33 | + <img id="captcha-img" class="captcha-img" alt=""> | ||
34 | + <a class="link change-captcha">换一张</a> | ||
35 | + <span class="err-tip hide"> | ||
36 | + <i></i> | ||
37 | + <em></em> | ||
38 | + </span> | ||
30 | </div> | 39 | </div> |
31 | <div class="login-buttons"> | 40 | <div class="login-buttons"> |
32 | - <button type="submit" class="btn btn-success btn-block btn-lg">登 录</button> | 41 | + <button id="login-btn" type="submit" class="btn btn-success btn-block btn-lg">登 录</button> |
33 | </div> | 42 | </div> |
34 | </form> | 43 | </form> |
35 | </div> | 44 | </div> |
-
Please register or login to post a comment