Commit 7e9002af by 周志凯

[feat]: add auth

1 parent a846ef09
......@@ -156,10 +156,6 @@ html, body, #app {
transition: width 0.1s linear;
}
.move-animate {
/* animation: move 2s ease-in-out infinite; */
}
.result-progress__text {
display: inline-block;
margin: 0 5px;
......@@ -200,6 +196,41 @@ html, body, #app {
border-radius: 20px;
}
/* login */
#loginApp {
width: 100%;
height: 100%;
}
.login-container {
width: 100%;
height: 100%;
background: url(../image/login_bg.png) no-repeat;
background-size: 100% 100%;
text-align: right;
}
.login-form {
display: inline-block;
width: 20%;
padding-top: 30vh;
margin-right: 10%;
color: #fff;
box-sizing: border-box;
}
.login-title {
text-align: left;
}
input::-webkit-autofill {
background-color: transparent;
box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0) inset !important;
-webkit-box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0) inset !important;
-webkit-text-fill-color: #fff !important;
transition: background-clor 5000s ease-in-out 0s;
}
@keyframes move {
0% {
background-position: 0 0;
......
const API = {
Login: '/users/login',
Accounts: '/accounts',
Malls: '/malls',
Gates: '/gates',
Devices: '/devices',
Channels: '/channels',
Mall: '/mall/',
FaceRecognitionsCount: '/faceRecognitions/count',
SimulationFaceRecognition: '/simulation/faceRecognition',
SimulationCountData: '/simulation/countData',
PreviewCountData: '/preview/countData',
mallStaffFeature: '/mall/staffFeature',
MallFeature: '/mall/feature',
MallStaffPool: '/mall/staffPool',
MallCustomPool: '/mall/customPool',
MallStaff: '/mall/staff',
MallCustom: '/mall/custom'
}
const WSAPI = {
RecalSchedule: '/recal/schedule/'
}
window.apiUrl = ''
window.webSockUrl = ''
\ No newline at end of file
window._CONF_ = {
reportApiUrl: 'https://store.keliuyun.com/report',
apiUrl: 'http://192.168.9.146:8080',
webSockUrl: ''
}
/**
* [MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie#Syntax)
*/
const Cookies = {
get: function (sKey) {
return decodeURIComponent(
document.cookie.replace(
new RegExp(
"(?:(?:^|.*;)\\s*" +
encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") +
"\\s*\\=\\s*([^;]*).*$)|^.*$"
), "$1"
)
) || null
},
/**
* 写入
* @param {string} sKey necessary
* @param {string} sValue necessary
* @param {number|null|date|object|Infinity|string} vEnd optional
* @param {string|null} sPath optional
* @param {string|null} sDomain optional
* @param {boolean|null} bSecure optional
*/
set: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey ||
/^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)
) {
return false
}
let sExpires = ''
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity
? '; expires=Fri, 31 Dec 9999 23:59:59 GMT'
: '; max-age=' + vEnd
break;
case String:
sExpires = '; expires=' + vEnd
break;
case Date:
sExpires = '; expires=' + vEnd.toUTCString()
break;
}
}
document.cookie = encodeURIComponent(sKey) + '=' +
encodeURIComponent(sValue) + sExpires +
(sDomain ? '; domain=' + sDomain : '') +
(sPath ? '; path=' + sPath : '') +
(bSecure ? '; secure' : '')
return true
},
remove: function (sKey, sPath, sDomain) {
if (!sKey || !this.has(sKey)) return false
document.cookie = encodeURIComponent(sKey) +
'=; expires=Thu, 01 Jan 1970 00:00:00 GMT' +
(sDomain ? '; domain=' + sDomain : '') +
(sPath ? '; path=' + sPath : '')
return true
},
has: function (sKey) {
return (
new RegExp('(?:^|;\\s*)' +
encodeURIComponent(sKey).replace(/[-.+*]/g, '\\$&') +
'\\s*\\='
)
).test(document.cookie)
},
keys: function () {
let aKeys = document.cookie.replace(
/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g,
''
).split(/\s*(?:\=[^;]*)?;\s*/)
for (let nIdx = 0;nIdx < aKeys.length;nIdx++) {
aKeys[nIdx] = decodeURIComponent(aKeys[nIdx])
}
return aKeys
}
}
(function() {
console.log('location', location, Cookies.get('atoken'))
if (!Cookies.get('atoken')) {
window.location.replace(window.location.href + 'login.html')
}
})()
\ No newline at end of file
const Axios = axios.create({
baseURL: window._CONF_.apiUrl,
timeout: 0,
withCredentials: true,
headers: {
"Content-Type": "application/json;charset=UTF-8"
}
})
Axios.interceptors.request.use(
config => {
const atoken = Cookies.get('atoken')
console.log('atoken', atoken)
atoken && (config.headers.Authorization = atoken)
return config
},
error => {
return Promise.reject(error)
}
)
Axios.interceptors.response.use(
res => {
console.log(res)
if (res.data.enote || res.data.code === 401) {
ELEMENT.MessageBox.alert('授权到期, 请重新登录', '提示', {
confirmButtonText: '确定',
callback: action => {
console.log('action', action)
window.location.replace(window.location.href + 'login.html')
}
});
} else {
return Promise.resolve(res.data)
}
},
error => {
console.log(error)
return Promise.reject(error)
}
)
function get(url, params = {}, config = {}) {
params['s'] = +new Date()
console.log('params', params)
return Axios.get(url, { ...config, params })
}
function post(url, params, config = {}) {
return Axios.post(url, params, config)
}
function deletes(url, params, config = {}) {
return Axios.delete(url, params, config)
}
function put(url, params, config = {}) {
return Axios.put(url, params, config)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./css/index.css" />
<link rel="stylesheet" href="./css/common.css">
<link rel="stylesheet" href="./css/page.css">
<script src="./js/browser.min.js"></script>
</head>
<body>
<!-- <div id="loginApp" v-cloak> -->
<div id="loginApp">
<div class="login-container">
<el-form :model="loginForm" :rules="rules" ref="loginForm" class="login-form">
<div class="login-header">
<h3 class="login-title">Login Form</h3>
</div>
<el-form-item prop="loginName">
<el-input ref="username" v-model.trim="loginForm.loginName"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input ref="password" type="password" v-model.trim="loginForm.password">
</el-input>
</el-form-item>
<el-button type="primary" style="width: 100%;" @click="submitForm">登 录</el-button>
</el-form>
</div>
</div>
<!-- import Vue before Element -->
<script src="./js/vue.js"></script>
<!-- import JavaScript -->
<script src="./js/index.js"></script>
<script src="./js/axios.js"></script>
<script src="./js/common.js" type="text/javascript" charset="utf-8"></script>
<script src="./js/cookie.js"></script>
<script src="./js/request.js"></script>
<script>
new Vue({
el: '#loginApp',
data() {
const validateUsername = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入用户名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
const regexp = /^(?![A-Z]+$)(?![a-z]+$)(?!\d+$)(?![\W_]+$)\S{6,16}$/
if (!value) {
callback(new Error('请输入密码'))
} else if (!regexp.test(value)) {
callback(new Error('请输入不小于六位包含字母数字的密码!'))
} else {
callback()
}
}
return {
loginForm: {
loginName: '',
password: ''
},
// paswordType: 'password',
rules: {
loginName: [
{ required: true, trigger: 'blur', validator: validateUsername }
],
password: [
{ required: true, trigger: 'blur', validator: validatePassword }
]
}
}
},
mounted() {
// console.log({ get, post })
// if (this.loginForm.name === '') {
// this.$refs.username.focus()
// } else if (this.loginForm.password === '') {
// this.$refs.password.focus()
// }
},
methods: {
submitForm() {
this.$refs.loginForm.validate(valid => {
if (valid) {
post(
window._CONF_.reportApiUrl + '/users/login',
this.loginForm
).then(res => {
const { data, code } = res
if (code === 200) {
Cookies.set('atoken', data.atoken)
const currentPath = window.location.href
window.location.replace(currentPath.substr(0, currentPath.lastIndexOf('/') + 1))
}
})
.catch(err => {
console.log(err)
})
}
})
},
resetForm() {
this.loginForm.name = ''
this.loginForm.password = ''
this.$refs.loginForm.resetFields()
},
}
})
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!