mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-01 22:53:29 +08:00
后端:用户登录、退出登录、获取用户状态相关功能完成;引入SessionManager;数据库:user_identity改为group;前端:添加登录页面、后台管理页面框架,axios POST请求Content-Type问题修复,引入md5、sha1 js库;小问题调整
This commit is contained in:
@@ -1,9 +1,19 @@
|
||||
// 请求头 Content-Type
|
||||
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
// 带参数的post请求
|
||||
function postRequest(url, params) {
|
||||
var data = [];
|
||||
for (var key in params) {
|
||||
data.push(key + '=' + encodeURIComponent(params[key]));
|
||||
}
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: params,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
data: data.join('&'),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -12,15 +22,18 @@ function getRequest(url, params) {
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
params: params,
|
||||
})
|
||||
}
|
||||
|
||||
// 带参数的put请求
|
||||
function putRequest(url, params) {
|
||||
return axios({
|
||||
method: 'put',
|
||||
url: url,
|
||||
data: params
|
||||
})
|
||||
}
|
||||
// // 带参数的put请求
|
||||
// function putRequest(url, params) {
|
||||
// return axios({
|
||||
// method: 'put',
|
||||
// url: url,
|
||||
// data: params
|
||||
// })
|
||||
// }
|
9
bookshelfplus-frontend/public/assets/lib/cryptography/2.2/md5-min.js
vendored
Normal file
9
bookshelfplus-frontend/public/assets/lib/cryptography/2.2/md5-min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
* Distributed under the BSD License
|
||||
* See http://pajhome.org.uk/crypt/md5 for more info.
|
||||
*/
|
||||
var hexcase=0;function hex_md5(a){return rstr2hex(rstr_md5(str2rstr_utf8(a)))}function hex_hmac_md5(a,b){return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a),str2rstr_utf8(b)))}function md5_vm_test(){return hex_md5("abc").toLowerCase()=="900150983cd24fb0d6963f7d28e17f72"}function rstr_md5(a){return binl2rstr(binl_md5(rstr2binl(a),a.length*8))}function rstr_hmac_md5(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_md5(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binl_md5(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_md5(d.concat(g),512+128))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}return a}function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}return a}function binl_md5(p,k){p[k>>5]|=128<<((k)%32);p[(((k+64)>>>9)<<4)+14]=k;var o=1732584193;var n=-271733879;var m=-1732584194;var l=271733878;for(var g=0;g<p.length;g+=16){var j=o;var h=n;var f=m;var e=l;o=md5_ff(o,n,m,l,p[g+0],7,-680876936);l=md5_ff(l,o,n,m,p[g+1],12,-389564586);m=md5_ff(m,l,o,n,p[g+2],17,606105819);n=md5_ff(n,m,l,o,p[g+3],22,-1044525330);o=md5_ff(o,n,m,l,p[g+4],7,-176418897);l=md5_ff(l,o,n,m,p[g+5],12,1200080426);m=md5_ff(m,l,o,n,p[g+6],17,-1473231341);n=md5_ff(n,m,l,o,p[g+7],22,-45705983);o=md5_ff(o,n,m,l,p[g+8],7,1770035416);l=md5_ff(l,o,n,m,p[g+9],12,-1958414417);m=md5_ff(m,l,o,n,p[g+10],17,-42063);n=md5_ff(n,m,l,o,p[g+11],22,-1990404162);o=md5_ff(o,n,m,l,p[g+12],7,1804603682);l=md5_ff(l,o,n,m,p[g+13],12,-40341101);m=md5_ff(m,l,o,n,p[g+14],17,-1502002290);n=md5_ff(n,m,l,o,p[g+15],22,1236535329);o=md5_gg(o,n,m,l,p[g+1],5,-165796510);l=md5_gg(l,o,n,m,p[g+6],9,-1069501632);m=md5_gg(m,l,o,n,p[g+11],14,643717713);n=md5_gg(n,m,l,o,p[g+0],20,-373897302);o=md5_gg(o,n,m,l,p[g+5],5,-701558691);l=md5_gg(l,o,n,m,p[g+10],9,38016083);m=md5_gg(m,l,o,n,p[g+15],14,-660478335);n=md5_gg(n,m,l,o,p[g+4],20,-405537848);o=md5_gg(o,n,m,l,p[g+9],5,568446438);l=md5_gg(l,o,n,m,p[g+14],9,-1019803690);m=md5_gg(m,l,o,n,p[g+3],14,-187363961);n=md5_gg(n,m,l,o,p[g+8],20,1163531501);o=md5_gg(o,n,m,l,p[g+13],5,-1444681467);l=md5_gg(l,o,n,m,p[g+2],9,-51403784);m=md5_gg(m,l,o,n,p[g+7],14,1735328473);n=md5_gg(n,m,l,o,p[g+12],20,-1926607734);o=md5_hh(o,n,m,l,p[g+5],4,-378558);l=md5_hh(l,o,n,m,p[g+8],11,-2022574463);m=md5_hh(m,l,o,n,p[g+11],16,1839030562);n=md5_hh(n,m,l,o,p[g+14],23,-35309556);o=md5_hh(o,n,m,l,p[g+1],4,-1530992060);l=md5_hh(l,o,n,m,p[g+4],11,1272893353);m=md5_hh(m,l,o,n,p[g+7],16,-155497632);n=md5_hh(n,m,l,o,p[g+10],23,-1094730640);o=md5_hh(o,n,m,l,p[g+13],4,681279174);l=md5_hh(l,o,n,m,p[g+0],11,-358537222);m=md5_hh(m,l,o,n,p[g+3],16,-722521979);n=md5_hh(n,m,l,o,p[g+6],23,76029189);o=md5_hh(o,n,m,l,p[g+9],4,-640364487);l=md5_hh(l,o,n,m,p[g+12],11,-421815835);m=md5_hh(m,l,o,n,p[g+15],16,530742520);n=md5_hh(n,m,l,o,p[g+2],23,-995338651);o=md5_ii(o,n,m,l,p[g+0],6,-198630844);l=md5_ii(l,o,n,m,p[g+7],10,1126891415);m=md5_ii(m,l,o,n,p[g+14],15,-1416354905);n=md5_ii(n,m,l,o,p[g+5],21,-57434055);o=md5_ii(o,n,m,l,p[g+12],6,1700485571);l=md5_ii(l,o,n,m,p[g+3],10,-1894986606);m=md5_ii(m,l,o,n,p[g+10],15,-1051523);n=md5_ii(n,m,l,o,p[g+1],21,-2054922799);o=md5_ii(o,n,m,l,p[g+8],6,1873313359);l=md5_ii(l,o,n,m,p[g+15],10,-30611744);m=md5_ii(m,l,o,n,p[g+6],15,-1560198380);n=md5_ii(n,m,l,o,p[g+13],21,1309151649);o=md5_ii(o,n,m,l,p[g+4],6,-145523070);l=md5_ii(l,o,n,m,p[g+11],10,-1120210379);m=md5_ii(m,l,o,n,p[g+2],15,718787259);n=md5_ii(n,m,l,o,p[g+9],21,-343485551);o=safe_add(o,j);n=safe_add(n,h);m=safe_add(m,f);l=safe_add(l,e)}return Array(o,n,m,l)}function md5_cmn(h,e,d,c,g,f){return safe_add(bit_rol(safe_add(safe_add(e,h),safe_add(c,f)),g),d)}function md5_ff(g,f,k,j,e,i,h){return md5_cmn((f&k)|((~f)&j),g,f,e,i,h)}function md5_gg(g,f,k,j,e,i,h){return md5_cmn((f&j)|(k&(~j)),g,f,e,i,h)}function md5_hh(g,f,k,j,e,i,h){return md5_cmn(f^k^j,g,f,e,i,h)}function md5_ii(g,f,k,j,e,i,h){return md5_cmn(k^(f|(~j)),g,f,e,i,h)}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};
|
9
bookshelfplus-frontend/public/assets/lib/cryptography/2.2/sha1-min.js
vendored
Normal file
9
bookshelfplus-frontend/public/assets/lib/cryptography/2.2/sha1-min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS 180-1
|
||||
* Version 2.2 Copyright Paul Johnston 2000 - 2009.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
* Distributed under the BSD License
|
||||
* See http://pajhome.org.uk/crypt/md5 for details.
|
||||
*/
|
||||
var hexcase=0;var b64pad="";function hex_sha1(a){return rstr2hex(rstr_sha1(str2rstr_utf8(a)))}function hex_hmac_sha1(a,b){return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha1_vm_test(){return hex_sha1("abc").toLowerCase()=="a9993e364706816aba3e25717850c26c9cd0d89d"}function rstr_sha1(a){return binb2rstr(binb_sha1(rstr2binb(a),a.length*8))}function rstr_hmac_sha1(c,f){var e=rstr2binb(c);if(e.length>16){e=binb_sha1(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha1(a.concat(rstr2binb(f)),512+f.length*8);return binb2rstr(binb_sha1(d.concat(g),512+160))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}function binb_sha1(v,o){v[o>>5]|=128<<(24-o%32);v[((o+64>>9)<<4)+15]=o;var y=Array(80);var u=1732584193;var s=-271733879;var r=-1732584194;var q=271733878;var p=-1009589776;for(var l=0;l<v.length;l+=16){var n=u;var m=s;var k=r;var h=q;var f=p;for(var g=0;g<80;g++){if(g<16){y[g]=v[l+g]}else{y[g]=bit_rol(y[g-3]^y[g-8]^y[g-14]^y[g-16],1)}var z=safe_add(safe_add(bit_rol(u,5),sha1_ft(g,s,r,q)),safe_add(safe_add(p,y[g]),sha1_kt(g)));p=q;q=r;r=bit_rol(s,30);s=u;u=z}u=safe_add(u,n);s=safe_add(s,m);r=safe_add(r,k);q=safe_add(q,h);p=safe_add(p,f)}return Array(u,s,r,q,p)}function sha1_ft(e,a,g,f){if(e<20){return(a&g)|((~a)&f)}if(e<40){return a^g^f}if(e<60){return(a&g)|(a&f)|(g&f)}return a^g^f}function sha1_kt(a){return(a<20)?1518500249:(a<40)?1859775393:(a<60)?-1894007588:-899497514}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};
|
@@ -32,6 +32,18 @@ router.get('/about', function (req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/login', function (req, res) {
|
||||
res.render('login', {
|
||||
title: "用户登录"
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/admin/index', function (req, res) { // '/admin(/index)?'
|
||||
res.render('admin/index', {
|
||||
title: "后台管理"
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/status', function (req, res) {
|
||||
res.render('status', {
|
||||
title: "网站状态检测"
|
||||
|
6
bookshelfplus-frontend/views/admin/component/footer.html
Normal file
6
bookshelfplus-frontend/views/admin/component/footer.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="footer" style="margin-top: 10vh;">
|
||||
<hr>
|
||||
<p>
|
||||
<a href="/status">网站状态检测</a>
|
||||
</p>
|
||||
</div>
|
16
bookshelfplus-frontend/views/admin/component/header.html
Normal file
16
bookshelfplus-frontend/views/admin/component/header.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
<title><%= typeof title !=='undefined' ? title : "前端服务出现异常"; %></title>
|
||||
|
||||
<link rel="stylesheet" href="/assets/stylesheets/style.css">
|
||||
<script src="/assets/lib/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script src="/assets/lib/axios/0.26.1/axios.min.js"></script>
|
||||
|
||||
<script src="/assets/javascripts/httpRequest.js"></script>
|
||||
<script>
|
||||
// API地址
|
||||
const APIHOST = '<%= global.site.api.prefix %>';
|
||||
axios.defaults.baseURL = APIHOST;
|
||||
</script>
|
43
bookshelfplus-frontend/views/admin/component/navbar.html
Normal file
43
bookshelfplus-frontend/views/admin/component/navbar.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<div class="navbar">
|
||||
<div class="navbar-grid">
|
||||
<div class="grid-item"></div>
|
||||
<div class="grid-item">
|
||||
<nobr>
|
||||
<h1 onclick="location.href='/'" style="cursor: pointer;">书栖网</h1>
|
||||
</nobr>
|
||||
</div>
|
||||
<div class="grid-item exnarrowHide" style="text-align: right; color: white;">
|
||||
<a href="/">首页</a>
|
||||
<a href="/admin/manage">管理</a>
|
||||
<a style="color: grey;" href="javascript:logout();">退出登录</a>
|
||||
</div>
|
||||
<div class="grid-item"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function logout() {
|
||||
getRequest("/user/logout", {})
|
||||
.then(function (response) {
|
||||
var axiosData = response.data;
|
||||
var status = axiosData.status;
|
||||
var data = axiosData.data;
|
||||
|
||||
if (status === "success") {
|
||||
console.log(data);
|
||||
if(data) {
|
||||
alert("退出登录成功");
|
||||
// window.location.href = "/";
|
||||
location.reload();
|
||||
} else {
|
||||
alert("退出登录失败");
|
||||
}
|
||||
} else {
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
alert("退出登录失败");
|
||||
});
|
||||
}
|
||||
</script>
|
41
bookshelfplus-frontend/views/admin/index.html
Normal file
41
bookshelfplus-frontend/views/admin/index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<%- include("./component/header.html"); %>
|
||||
</head>
|
||||
<body>
|
||||
<%- include("./component/navbar.html"); %>
|
||||
<main class="main">
|
||||
<h1><%= title %></h1>
|
||||
<div id="container">
|
||||
|
||||
</div>
|
||||
</main>
|
||||
<%- include("./component/footer.html"); %>
|
||||
|
||||
<!-- 获取参数 -->
|
||||
<script src="../assets/javascripts/getParams.js"></script>
|
||||
<script>
|
||||
var requestParams = getParams();
|
||||
function getUserStatus() {
|
||||
getRequest("/user/getUserStatus", { })
|
||||
.then(function (responseData) {
|
||||
var axiosData = responseData.data;
|
||||
var status = axiosData.status;
|
||||
var data = axiosData.data;
|
||||
if (status === "success") {
|
||||
console.log(data)
|
||||
if(data) {
|
||||
|
||||
} else {
|
||||
window.location.href = "/login";
|
||||
}
|
||||
} else {
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
}
|
||||
});
|
||||
}
|
||||
getUserStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -77,7 +77,7 @@
|
||||
// 渲染后重新获取一次字体
|
||||
fontmin(getPageText());
|
||||
} else {
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
|
@@ -51,7 +51,7 @@
|
||||
// 渲染后重新获取一次字体
|
||||
fontmin(getPageText());
|
||||
} else {
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
|
@@ -14,9 +14,6 @@
|
||||
const APIHOST = '<%= global.site.api.prefix %>';
|
||||
axios.defaults.baseURL = APIHOST;
|
||||
|
||||
// 请求头 Content-Type
|
||||
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
// 字体加载前先隐藏,不然文字会闪一下
|
||||
$("html,body").css("opacity", "0");
|
||||
</script>
|
82
bookshelfplus-frontend/views/login.html
Normal file
82
bookshelfplus-frontend/views/login.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<%- include("./component/header.html"); %>
|
||||
<style>
|
||||
.main {
|
||||
width: 80vw !important;
|
||||
max-width: initial !important;
|
||||
}
|
||||
|
||||
#bookImage {
|
||||
/* width: 100%; */
|
||||
height: auto;
|
||||
max-height: 300px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<%- include("./component/navbar.html"); %>
|
||||
<main class="main">
|
||||
<h1><%= title %></h1>
|
||||
<div id="container">
|
||||
<div>
|
||||
<!-- 用户登录 输入用户名和密码的文本框 -->
|
||||
<div class="form">
|
||||
<div class="form-group">
|
||||
<label for="username">用户名</label>
|
||||
<input type="text" id="username" placeholder="用户名">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">密码</label>
|
||||
<input type="password" id="password" placeholder="密码">
|
||||
</div>
|
||||
<button class="btn-submit">登录</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<%- include("./component/footer.html"); %>
|
||||
|
||||
<script src="./assets/lib/cryptography/2.2/md5-min.js"></script>
|
||||
<!-- <script src="./assets/lib/cryptography/2.2/sha1-min.js"></script> -->
|
||||
<script>
|
||||
$("#username").val("xiaomo");
|
||||
$("#password").val("123456");
|
||||
$(".btn-submit").click(function() {
|
||||
var username = $("#username").val();
|
||||
var password = $("#password").val();
|
||||
// var encryptpwd = hex_sha1(password);
|
||||
var encryptpwd = hex_md5(password);
|
||||
|
||||
console.log(password, encryptpwd);
|
||||
|
||||
postRequest("/user/login", { username: username, encryptpwd: encryptpwd })
|
||||
.then(function (response) {
|
||||
var axiosData = response.data;
|
||||
var status = axiosData.status;
|
||||
var data = axiosData.data;
|
||||
|
||||
if (status === "success") {
|
||||
console.log(data);
|
||||
if(data) {
|
||||
alert("登录成功");
|
||||
if(data.group === "ADMIN") {
|
||||
window.location.href = "/admin/index";
|
||||
} else {
|
||||
window.location.href = "/user/index";
|
||||
}
|
||||
} else {
|
||||
alert("用户名或密码错误");
|
||||
}
|
||||
} else {
|
||||
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -36,6 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<%- include("./component/footer.html"); %>
|
||||
|
||||
<!-- 获取参数 -->
|
||||
<script src="./assets/javascripts/getParams.js"></script>
|
||||
<!-- 渲染表格 -->
|
||||
|
@@ -0,0 +1,48 @@
|
||||
package plus.bookshelf.Common.SessionManager;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class LocalSessionManager implements SessionManager {
|
||||
|
||||
/**
|
||||
* 私有化构造函数
|
||||
*/
|
||||
private LocalSessionManager(HttpServletRequest httpServletRequest) {
|
||||
this.httpServletRequest = httpServletRequest;
|
||||
}
|
||||
|
||||
static SessionManager sessionManager = null;
|
||||
// static SessionManager sessionManager = new LocalSessionManager();
|
||||
|
||||
/**
|
||||
* 通过此方法获取当前类的实例
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static SessionManager getInstance(HttpServletRequest httpServletRequest) {
|
||||
if (sessionManager == null)
|
||||
sessionManager = new LocalSessionManager(httpServletRequest);
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
HttpServletRequest httpServletRequest;
|
||||
|
||||
@Override
|
||||
public Object getValue(String key) {
|
||||
try {
|
||||
return httpServletRequest.getSession().getAttribute(key);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String key, Object value) {
|
||||
httpServletRequest.getSession().setAttribute(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String key) {
|
||||
httpServletRequest.getSession().removeAttribute(key);
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package plus.bookshelf.Common.SessionManager;
|
||||
|
||||
public abstract interface SessionManager {
|
||||
/**
|
||||
* 获取 Session
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
Object getValue(String key);
|
||||
|
||||
/**
|
||||
* 设置 Session
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setValue(String key, Object value);
|
||||
|
||||
/**
|
||||
* 移除 Session
|
||||
* @param key
|
||||
*/
|
||||
void remove(String key);
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package plus.bookshelf.Controller.Controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@@ -10,14 +9,18 @@ import plus.bookshelf.Common.Error.BusinessErrorCode;
|
||||
import plus.bookshelf.Common.Error.BusinessException;
|
||||
import plus.bookshelf.Common.Response.CommonReturnType;
|
||||
import plus.bookshelf.Common.Response.CommonReturnTypeStatus;
|
||||
import plus.bookshelf.Common.SessionManager.LocalSessionManager;
|
||||
import plus.bookshelf.Common.SessionManager.SessionManager;
|
||||
import plus.bookshelf.Service.Model.UserModel;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BaseController {
|
||||
|
||||
@Autowired
|
||||
HttpServletRequest httpServletRequest;
|
||||
|
||||
// content-type 常量
|
||||
public static final String CONTENT_TYPE_FORMED = "application/x-www-form-urlencoded";
|
||||
|
||||
@@ -25,9 +28,6 @@ public class BaseController {
|
||||
public static final Integer COMMON_START_PAGE = 1;
|
||||
public static final Integer COMMON_PAGE_SIZE = 10;
|
||||
|
||||
@Autowired
|
||||
HttpServletRequest httpServletRequest;
|
||||
|
||||
// @Autowired
|
||||
// private RedisTemplate redisTemplate;
|
||||
|
||||
@@ -35,7 +35,8 @@ public class BaseController {
|
||||
* 获取用户登陆状态
|
||||
*/
|
||||
public Boolean isLogin() {
|
||||
return (Boolean) httpServletRequest.getSession().getAttribute("IS_LOGIN");
|
||||
SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
return (Boolean) sessionManager.getValue("IS_LOGIN");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,32 +44,47 @@ public class BaseController {
|
||||
*
|
||||
* @return String uuidToken
|
||||
*/
|
||||
public String onLogin(UserModel userModel) {
|
||||
String uuidToken = UUID.randomUUID().toString();
|
||||
public void onLogin(UserModel userModel) {
|
||||
// String uuidToken = UUID.randomUUID().toString();
|
||||
// redisTemplate.expire(uuidToken, 1, TimeUnit.HOURS);
|
||||
|
||||
// // 建立token和用户登录态之间的联系
|
||||
// redisTemplate.opsForValue().set(uuidToken, userModel);
|
||||
return uuidToken;
|
||||
// return uuidToken;
|
||||
|
||||
SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
sessionManager.setValue("IS_LOGIN", true);
|
||||
sessionManager.setValue("user", userModel);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户退出登录
|
||||
*/
|
||||
public void onLogout() {
|
||||
SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
sessionManager.setValue("IS_LOGIN", false);
|
||||
sessionManager.remove("user");
|
||||
return;
|
||||
}
|
||||
|
||||
// 定义ExceptionHandler解决未被Controller层吸收的Exception
|
||||
// @ExceptionHandler(Exception.class)
|
||||
// @ResponseStatus(HttpStatus.OK)
|
||||
// @ResponseBody
|
||||
// public Object handlerException(HttpServletRequest request, Exception ex) {
|
||||
// HashMap<Object, Object> responseData = new HashMap<>();
|
||||
//
|
||||
// if (ex instanceof BusinessException) {
|
||||
// BusinessException businessException = (BusinessException) ex;
|
||||
// responseData.put("errCode", businessException.getErrCode());
|
||||
// responseData.put("errMsg", businessException.getErrMsg());
|
||||
// } else {
|
||||
// // 生产环境输出格式化信息
|
||||
// responseData.put("errCode", BusinessErrorCode.UNKNOWN_ERROR.getErrCode());
|
||||
// responseData.put("errMsg", BusinessErrorCode.UNKNOWN_ERROR.getErrMsg());
|
||||
// }
|
||||
//
|
||||
// return CommonReturnType.create(responseData, CommonReturnTypeStatus.FAILED);
|
||||
// }
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ResponseBody
|
||||
public Object handlerException(HttpServletRequest request, Exception ex) {
|
||||
HashMap<Object, Object> responseData = new HashMap<>();
|
||||
|
||||
if (ex instanceof BusinessException) {
|
||||
BusinessException businessException = (BusinessException) ex;
|
||||
responseData.put("errCode", businessException.getErrCode());
|
||||
responseData.put("errMsg", businessException.getErrMsg());
|
||||
} else {
|
||||
// 生产环境输出格式化信息
|
||||
responseData.put("errCode", BusinessErrorCode.UNKNOWN_ERROR.getErrCode());
|
||||
responseData.put("errMsg", BusinessErrorCode.UNKNOWN_ERROR.getErrMsg());
|
||||
}
|
||||
|
||||
return CommonReturnType.create(responseData, CommonReturnTypeStatus.FAILED);
|
||||
}
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ import plus.bookshelf.Service.Service.CategoryService;
|
||||
@Api(value = "书籍分类")
|
||||
@Controller("category")
|
||||
@RequestMapping("/category")
|
||||
public class CategoryController {
|
||||
public class CategoryController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
CategoryService categoryService;
|
||||
|
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
@Api(value = "状态检测")
|
||||
@Controller("status")
|
||||
@RequestMapping("/status")
|
||||
public class StatusController {
|
||||
public class StatusController extends BaseController {
|
||||
|
||||
// @ApiOperation(value = "线程CPU占用时间", notes = "获取服务器当前线程CPU占用时间。此方法通过统计线程CPU占用时间来统计当前进程占用CPU情况。")
|
||||
// @RequestMapping(value = "getProcessCpu", method = {RequestMethod.GET})
|
||||
|
@@ -10,27 +10,70 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import plus.bookshelf.Common.Response.CommonReturnType;
|
||||
import plus.bookshelf.Common.SessionManager.LocalSessionManager;
|
||||
import plus.bookshelf.Common.SessionManager.SessionManager;
|
||||
import plus.bookshelf.Controller.VO.UserVO;
|
||||
import plus.bookshelf.Service.Impl.UserServiceImpl;
|
||||
import plus.bookshelf.Service.Model.UserModel;
|
||||
|
||||
import static plus.bookshelf.Controller.Controller.BaseController.CONTENT_TYPE_FORMED;
|
||||
|
||||
@Api(value = "用户")
|
||||
@Controller
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
public class UserController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
UserServiceImpl userService;
|
||||
|
||||
@ApiOperation(value = "用户登录",notes = "传入用户名,以及密码的MD5值,进行登录")
|
||||
@ApiOperation(value = "用户登录", notes = "传入用户名,以及密码的MD5值,进行登录")
|
||||
@RequestMapping(value = "login", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
|
||||
@ResponseBody
|
||||
public CommonReturnType login(@RequestParam(value = "username") String username,
|
||||
@RequestParam(value = "encryptpwd") String encryptPwd) {
|
||||
@RequestParam(value = "encryptpwd") String encryptPwd) {
|
||||
if (username == null || encryptPwd == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserModel userModel = userService.userLogin(username, encryptPwd);
|
||||
UserVO userVO = convertFromService(userModel);
|
||||
|
||||
if (userModel != null) {
|
||||
onLogin(userModel);
|
||||
}
|
||||
return CommonReturnType.create(userVO);
|
||||
}
|
||||
|
||||
// @ApiOperation(value = "用户注册", notes = "传入用户名,以及密码的MD5值,进行注册")
|
||||
// @RequestMapping(value = "register", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
|
||||
// @ResponseBody
|
||||
// public CommonReturnType register(@RequestParam(value = "username") String username,
|
||||
// @RequestParam(value = "encryptpwd") String encryptPwd) {
|
||||
// if (username == null || encryptPwd == null) {
|
||||
// return null;
|
||||
// }
|
||||
// UserModel userModel = userService.userRegister(username, encryptPwd);
|
||||
// UserVO userVO = convertFromService(userModel);
|
||||
// return CommonReturnType.create(userVO);
|
||||
// }
|
||||
|
||||
@ApiOperation(value = "用户登出", notes = "用户退出登录")
|
||||
@RequestMapping(value = "logout", method = {RequestMethod.GET})
|
||||
@ResponseBody
|
||||
public CommonReturnType logout() {
|
||||
onLogout();
|
||||
return CommonReturnType.create("success");
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取用户登录状态", notes = "获取用户登录状态")
|
||||
@RequestMapping(value = "getUserStatus", method = {RequestMethod.GET})
|
||||
@ResponseBody
|
||||
public CommonReturnType getUserStatus() {
|
||||
Object userModelObject = LocalSessionManager.getInstance(httpServletRequest).getValue("user");
|
||||
if (userModelObject == null) {
|
||||
return CommonReturnType.create(null);
|
||||
}
|
||||
|
||||
UserModel userModel = (UserModel) userModelObject;
|
||||
UserVO userVO = convertFromService(userModel);
|
||||
return CommonReturnType.create(userVO);
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@ public class UserVO {
|
||||
String nickname;
|
||||
|
||||
// 用户身份 NOT_LOGIN, ADMIN, LOGIN_USER;
|
||||
String userIdentity;
|
||||
String group;
|
||||
|
||||
// 用户头像
|
||||
String avatar;
|
||||
|
@@ -40,11 +40,11 @@ public class UserDO {
|
||||
/**
|
||||
*
|
||||
* This field was generated by MyBatis Generator.
|
||||
* This field corresponds to the database column user_info.user_identity
|
||||
* This field corresponds to the database column user_info.group
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
private String userIdentity;
|
||||
private String group;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -180,26 +180,26 @@ public class UserDO {
|
||||
|
||||
/**
|
||||
* This method was generated by MyBatis Generator.
|
||||
* This method returns the value of the database column user_info.user_identity
|
||||
* This method returns the value of the database column user_info.group
|
||||
*
|
||||
* @return the value of user_info.user_identity
|
||||
* @return the value of user_info.group
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
public String getUserIdentity() {
|
||||
return userIdentity;
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was generated by MyBatis Generator.
|
||||
* This method sets the value of the database column user_info.user_identity
|
||||
* This method sets the value of the database column user_info.group
|
||||
*
|
||||
* @param userIdentity the value for user_info.user_identity
|
||||
* @param group the value for user_info.group
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setUserIdentity(String userIdentity) {
|
||||
this.userIdentity = userIdentity == null ? null : userIdentity.trim();
|
||||
public void setGroup(String group) {
|
||||
this.group = group == null ? null : group.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -30,7 +30,7 @@ public class UserServiceImpl implements UserService {
|
||||
userModel.setUsername(userDO.getUsername());
|
||||
userModel.setEncriptPwd(userDO.getEncriptPwd());
|
||||
userModel.setNickname(userDO.getNickname());
|
||||
userModel.setUserIdentity(userDO.getUserIdentity());
|
||||
userModel.setGroup(userDO.getGroup());
|
||||
userModel.setAvatar(userDO.getAvatar());
|
||||
userModel.setPhone(userDO.getPhone());
|
||||
userModel.setWeixinThirdPartyAuthCode(userDO.getWeixinThirdPartyAuthCode());
|
||||
|
@@ -2,6 +2,8 @@ package plus.bookshelf.Service.Model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
public class UserModel {
|
||||
|
||||
@@ -9,6 +11,7 @@ public class UserModel {
|
||||
Integer id;
|
||||
|
||||
// 用户名
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
String username;
|
||||
|
||||
// 用户加密后的密码
|
||||
@@ -18,7 +21,7 @@ public class UserModel {
|
||||
String nickname;
|
||||
|
||||
// 用户身份 NOT_LOGIN, ADMIN, LOGIN_USER;
|
||||
String userIdentity;
|
||||
String group;
|
||||
|
||||
// 用户头像
|
||||
String avatar;
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<result column="username" jdbcType="VARCHAR" property="username" />
|
||||
<result column="encript_pwd" jdbcType="VARCHAR" property="encriptPwd" />
|
||||
<result column="nickname" jdbcType="VARCHAR" property="nickname" />
|
||||
<result column="user_identity" jdbcType="VARCHAR" property="userIdentity" />
|
||||
<result column="group" jdbcType="VARCHAR" property="group" />
|
||||
<result column="avatar" jdbcType="VARCHAR" property="avatar" />
|
||||
<result column="phone" jdbcType="VARCHAR" property="phone" />
|
||||
<result column="weixin_third_party_auth_code" jdbcType="VARCHAR" property="weixinThirdPartyAuthCode" />
|
||||
@@ -21,7 +21,7 @@
|
||||
WARNING - @mbg.generated
|
||||
This element is automatically generated by MyBatis Generator, do not modify.
|
||||
-->
|
||||
id, username, encript_pwd, nickname, user_identity, avatar, phone, weixin_third_party_auth_code,
|
||||
id, username, encript_pwd, nickname, `group`, avatar, phone, weixin_third_party_auth_code,
|
||||
qq_third_party_auth_code
|
||||
</sql>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
|
||||
@@ -48,11 +48,11 @@
|
||||
This element is automatically generated by MyBatis Generator, do not modify.
|
||||
-->
|
||||
insert into user_info (id, username, encript_pwd,
|
||||
nickname, user_identity, avatar,
|
||||
nickname, `group`, avatar,
|
||||
phone, weixin_third_party_auth_code, qq_third_party_auth_code
|
||||
)
|
||||
values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{encriptPwd,jdbcType=VARCHAR},
|
||||
#{nickname,jdbcType=VARCHAR}, #{userIdentity,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR},
|
||||
#{nickname,jdbcType=VARCHAR}, #{group,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR},
|
||||
#{phone,jdbcType=VARCHAR}, #{weixinThirdPartyAuthCode,jdbcType=VARCHAR}, #{qqThirdPartyAuthCode,jdbcType=VARCHAR}
|
||||
)
|
||||
</insert>
|
||||
@@ -75,8 +75,8 @@
|
||||
<if test="nickname != null">
|
||||
nickname,
|
||||
</if>
|
||||
<if test="userIdentity != null">
|
||||
user_identity,
|
||||
<if test="group != null">
|
||||
`group`,
|
||||
</if>
|
||||
<if test="avatar != null">
|
||||
avatar,
|
||||
@@ -104,8 +104,8 @@
|
||||
<if test="nickname != null">
|
||||
#{nickname,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="userIdentity != null">
|
||||
#{userIdentity,jdbcType=VARCHAR},
|
||||
<if test="group != null">
|
||||
#{group,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="avatar != null">
|
||||
#{avatar,jdbcType=VARCHAR},
|
||||
@@ -137,8 +137,8 @@
|
||||
<if test="nickname != null">
|
||||
nickname = #{nickname,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="userIdentity != null">
|
||||
user_identity = #{userIdentity,jdbcType=VARCHAR},
|
||||
<if test="group != null">
|
||||
`group` = #{group,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="avatar != null">
|
||||
avatar = #{avatar,jdbcType=VARCHAR},
|
||||
@@ -164,7 +164,7 @@
|
||||
set username = #{username,jdbcType=VARCHAR},
|
||||
encript_pwd = #{encriptPwd,jdbcType=VARCHAR},
|
||||
nickname = #{nickname,jdbcType=VARCHAR},
|
||||
user_identity = #{userIdentity,jdbcType=VARCHAR},
|
||||
`group` = #{group,jdbcType=VARCHAR},
|
||||
avatar = #{avatar,jdbcType=VARCHAR},
|
||||
phone = #{phone,jdbcType=VARCHAR},
|
||||
weixin_third_party_auth_code = #{weixinThirdPartyAuthCode,jdbcType=VARCHAR},
|
||||
|
@@ -27,7 +27,8 @@
|
||||
},
|
||||
"<hr>",
|
||||
{
|
||||
url: 'http://localhost/api/swagger-ui.html',
|
||||
// url: 'http://localhost/api/swagger-ui.html',
|
||||
url: 'http://localhost/api/swagger-ui/index.html',
|
||||
title: 'Swagger'
|
||||
},
|
||||
{
|
||||
|
3
run.bat
3
run.bat
@@ -1,4 +1,7 @@
|
||||
@echo off
|
||||
:: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MySQL<51><4C><EFBFBD>ݿ<EFBFBD>
|
||||
:: skip ...
|
||||
|
||||
:: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SpringBoot
|
||||
cd ./bookshelfplus/
|
||||
:: refer: https://blog.csdn.net/abc86319253/article/details/44019881
|
||||
|
Reference in New Issue
Block a user