|
@ -1,11 +1,7 @@ |
|
|
<template> |
|
|
<template> |
|
|
<view class="login-bg"> |
|
|
<view class="login-bg"> |
|
|
<view class="login-welcome"> |
|
|
<view class="login-welcome"> |
|
|
<image |
|
|
<image class="login-bg-img" src="../../static/img/login-top.png" mode="aspectFill"></image> |
|
|
class="login-bg-img" |
|
|
|
|
|
src="../../static/img/login-top.png" |
|
|
|
|
|
mode="aspectFill" |
|
|
|
|
|
></image> |
|
|
|
|
|
<view class="login-welcome-content"> |
|
|
<view class="login-welcome-content"> |
|
|
<text class="login-title">您好!</text> |
|
|
<text class="login-title">您好!</text> |
|
|
<text class="login-title">欢迎使用</text> |
|
|
<text class="login-title">欢迎使用</text> |
|
@ -14,67 +10,45 @@ |
|
|
<view class="login-form-box"> |
|
|
<view class="login-form-box"> |
|
|
<view class="login-form-item"> |
|
|
<view class="login-form-item"> |
|
|
<text class="login-label">用户名</text> |
|
|
<text class="login-label">用户名</text> |
|
|
<u-input |
|
|
<u-input v-model="form.username" placeholder="请输入用户名" type="text" border="none" shape="circle" |
|
|
v-model="form.username" |
|
|
custom-style="background:#f6f6f6;padding:16rpx 0;padding-left:16px;" /> |
|
|
placeholder="请输入用户名" |
|
|
|
|
|
type="text" |
|
|
|
|
|
border="none" |
|
|
|
|
|
shape="circle" |
|
|
|
|
|
custom-style="background:#f6f6f6;padding:16rpx 0;padding-left:16px;" |
|
|
|
|
|
/> |
|
|
|
|
|
</view> |
|
|
</view> |
|
|
<view class="login-form-item"> |
|
|
<view class="login-form-item"> |
|
|
<text class="login-label">密码</text> |
|
|
<text class="login-label">密码</text> |
|
|
<u-input |
|
|
<u-input v-model="form.password" placeholder="请输入密码" type="password" border="none" shape="circle" |
|
|
v-model="form.password" |
|
|
custom-style="background:#f6f6f6;padding:16rpx 0;padding-left:16px;" /> |
|
|
placeholder="请输入密码" |
|
|
|
|
|
type="password" |
|
|
|
|
|
border="none" |
|
|
|
|
|
shape="circle" |
|
|
|
|
|
custom-style="background:#f6f6f6;padding:16rpx 0;padding-left:16px;" |
|
|
|
|
|
/> |
|
|
|
|
|
</view> |
|
|
</view> |
|
|
<view class="login-form-item captcha-row"> |
|
|
<view class="login-form-item captcha-row"> |
|
|
<text class="login-label">验证码</text> |
|
|
<text class="login-label">验证码</text> |
|
|
<view class="captcha-flex"> |
|
|
<view class="captcha-flex"> |
|
|
<u-input |
|
|
<u-input v-model="form.code" placeholder="验证码" border="none" shape="circle" |
|
|
v-model="form.code" |
|
|
custom-style="background:#f6f6f6;padding:16rpx 0;padding-left:16px;" /> |
|
|
placeholder="验证码" |
|
|
<image :src="codeUrl" class="captcha-img" mode="aspectFit" @click="getCaptcha" /> |
|
|
border="none" |
|
|
|
|
|
shape="circle" |
|
|
|
|
|
custom-style="background:#f6f6f6;padding:16rpx 0;padding-left:16px;" |
|
|
|
|
|
/> |
|
|
|
|
|
<image |
|
|
|
|
|
:src="codeUrl" |
|
|
|
|
|
class="captcha-img" |
|
|
|
|
|
mode="aspectFit" |
|
|
|
|
|
@click="getCaptcha" |
|
|
|
|
|
/> |
|
|
|
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
<view class="login-btn-box"> |
|
|
<view class="login-btn-box"> |
|
|
<u-button |
|
|
<u-button :hairline="false" shape="circle" :custom-style="btnStyle" @click="handleLogin" |
|
|
:hairline="false" |
|
|
color="#fff">登录</u-button> |
|
|
shape="circle" |
|
|
|
|
|
:custom-style="btnStyle" |
|
|
|
|
|
@click="handleLogin" |
|
|
|
|
|
color="#fff" |
|
|
|
|
|
>登录</u-button |
|
|
|
|
|
> |
|
|
|
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script> |
|
|
<script> |
|
|
import { login, getCodeImg } from "../api"; |
|
|
import { |
|
|
import { encrypt, decrypt } from "../../utils/jsencrypt"; |
|
|
login, |
|
|
export default { |
|
|
getCodeImg |
|
|
|
|
|
} from "../api"; |
|
|
|
|
|
import { |
|
|
|
|
|
encrypt, |
|
|
|
|
|
decrypt |
|
|
|
|
|
} from "../../utils/jsencrypt"; |
|
|
|
|
|
export default { |
|
|
data() { |
|
|
data() { |
|
|
return { |
|
|
return { |
|
|
form: { |
|
|
form: { |
|
|
username: "",//admin |
|
|
username: "", //admin |
|
|
password: "",//!Aa12345 |
|
|
password: "", //!Aa12345 |
|
|
code: "", |
|
|
code: "", |
|
|
uuid: "", |
|
|
uuid: "", |
|
|
rememberMe: false, |
|
|
rememberMe: false, |
|
@ -104,6 +78,24 @@ export default { |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
async handleLogin() { |
|
|
async handleLogin() { |
|
|
|
|
|
// 调用uni.login方法获取code |
|
|
|
|
|
uni.login({ |
|
|
|
|
|
provider: 'weixin', |
|
|
|
|
|
success: function(loginRes) { |
|
|
|
|
|
// 打印获取到的code |
|
|
|
|
|
console.log('获取的用户code是:' + loginRes.code); |
|
|
|
|
|
// uni.request({ |
|
|
|
|
|
// url: '', |
|
|
|
|
|
// method: 'POST' |
|
|
|
|
|
// }).then(res => { |
|
|
|
|
|
// console.log(res, 'res') |
|
|
|
|
|
// }) |
|
|
|
|
|
}, |
|
|
|
|
|
fail: function(error) { |
|
|
|
|
|
// 登录失败的回调 |
|
|
|
|
|
console.error('登录失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
const username = String(this.form.username); // 强制转为字符串 |
|
|
const username = String(this.form.username); // 强制转为字符串 |
|
|
// 1. 检查锁定 |
|
|
// 1. 检查锁定 |
|
|
const lockInfo = JSON.parse( |
|
|
const lockInfo = JSON.parse( |
|
@ -126,7 +118,10 @@ export default { |
|
|
} |
|
|
} |
|
|
// 2. 校验表单 |
|
|
// 2. 校验表单 |
|
|
if (!this.form.username || !this.form.password || !this.form.code) { |
|
|
if (!this.form.username || !this.form.password || !this.form.code) { |
|
|
uni.showToast({ title: "请填写完整信息", icon: "none" }); |
|
|
uni.showToast({ |
|
|
|
|
|
title: "请填写完整信息", |
|
|
|
|
|
icon: "none" |
|
|
|
|
|
}); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
this.loading = true; |
|
|
this.loading = true; |
|
@ -153,9 +148,14 @@ export default { |
|
|
if (res.code === 200) { |
|
|
if (res.code === 200) { |
|
|
this.loginFailCounts[username] = 0; |
|
|
this.loginFailCounts[username] = 0; |
|
|
uni.setStorageSync("token", res.token); |
|
|
uni.setStorageSync("token", res.token); |
|
|
uni.switchTab({ url: "/pages/tabBar/work/index" }); |
|
|
uni.switchTab({ |
|
|
|
|
|
url: "/pages/tabBar/work/index" |
|
|
|
|
|
}); |
|
|
} else { |
|
|
} else { |
|
|
uni.showToast({ title: res.msg, icon: "none" }); |
|
|
uni.showToast({ |
|
|
|
|
|
title: res.msg, |
|
|
|
|
|
icon: "none" |
|
|
|
|
|
}); |
|
|
// 失败计数 |
|
|
// 失败计数 |
|
|
this.loginFailCounts[username] = |
|
|
this.loginFailCounts[username] = |
|
|
(this.loginFailCounts[username] || 0) + 1; |
|
|
(this.loginFailCounts[username] || 0) + 1; |
|
@ -164,14 +164,20 @@ export default { |
|
|
this.accountLockTimes[username] = lockEndTime; |
|
|
this.accountLockTimes[username] = lockEndTime; |
|
|
uni.setStorageSync( |
|
|
uni.setStorageSync( |
|
|
`lock_${username}`, |
|
|
`lock_${username}`, |
|
|
JSON.stringify({ lockEndTime, username }) |
|
|
JSON.stringify({ |
|
|
|
|
|
lockEndTime, |
|
|
|
|
|
username |
|
|
|
|
|
}) |
|
|
); |
|
|
); |
|
|
uni.showToast({ |
|
|
uni.showToast({ |
|
|
title: "账号登录失败次数过多,已锁定10分钟", |
|
|
title: "账号登录失败次数过多,已锁定10分钟", |
|
|
icon: "none", |
|
|
icon: "none", |
|
|
}); |
|
|
}); |
|
|
} else { |
|
|
} else { |
|
|
uni.showToast({ title: res[1].data.msg || "登录失败", icon: "none" }); |
|
|
uni.showToast({ |
|
|
|
|
|
title: res[1].data.msg || "登录失败", |
|
|
|
|
|
icon: "none" |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
this.getCaptcha(); |
|
|
this.getCaptcha(); |
|
|
} |
|
|
} |
|
@ -180,32 +186,35 @@ export default { |
|
|
mounted() { |
|
|
mounted() { |
|
|
this.getCaptcha(); |
|
|
this.getCaptcha(); |
|
|
}, |
|
|
}, |
|
|
}; |
|
|
}; |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style scoped> |
|
|
<style scoped> |
|
|
.login-bg { |
|
|
.login-bg { |
|
|
display: flex; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
background: #f7fafd; |
|
|
background: #f7fafd; |
|
|
height: 100vh; |
|
|
height: 100vh; |
|
|
} |
|
|
} |
|
|
.login-welcome { |
|
|
|
|
|
|
|
|
.login-welcome { |
|
|
position: relative; |
|
|
position: relative; |
|
|
width: 100vw; |
|
|
width: 100vw; |
|
|
padding-top: 244rpx; |
|
|
padding-top: 244rpx; |
|
|
overflow: hidden; |
|
|
overflow: hidden; |
|
|
} |
|
|
} |
|
|
.login-bg-img { |
|
|
|
|
|
|
|
|
.login-bg-img { |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
left: 0; |
|
|
left: 0; |
|
|
top: 0; |
|
|
top: 0; |
|
|
width: 100vw; |
|
|
width: 100vw; |
|
|
height: 526px; |
|
|
height: 526px; |
|
|
z-index: 1; |
|
|
z-index: 1; |
|
|
} |
|
|
} |
|
|
.login-welcome-content { |
|
|
|
|
|
|
|
|
.login-welcome-content { |
|
|
position: relative; |
|
|
position: relative; |
|
|
z-index: 2; |
|
|
z-index: 2; |
|
|
width: 100%; |
|
|
width: 100%; |
|
@ -215,46 +224,53 @@ export default { |
|
|
justify-content: center; |
|
|
justify-content: center; |
|
|
padding-left: 60rpx; |
|
|
padding-left: 60rpx; |
|
|
margin-bottom: 70rpx; |
|
|
margin-bottom: 70rpx; |
|
|
} |
|
|
} |
|
|
.login-title { |
|
|
|
|
|
|
|
|
.login-title { |
|
|
font-size: 36rpx; |
|
|
font-size: 36rpx; |
|
|
font-weight: bold; |
|
|
font-weight: bold; |
|
|
color: #222; |
|
|
color: #222; |
|
|
margin-bottom: 10rpx; |
|
|
margin-bottom: 10rpx; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.login-form-box { |
|
|
.login-form-box { |
|
|
width: 85%; |
|
|
width: 85%; |
|
|
background: #fff; |
|
|
background: #fff; |
|
|
border-radius: 24rpx; |
|
|
border-radius: 24rpx; |
|
|
box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06); |
|
|
box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06); |
|
|
padding: 40rpx 30rpx 30rpx 30rpx; |
|
|
padding: 40rpx 30rpx 30rpx 30rpx; |
|
|
margin-bottom: -46rpx; |
|
|
margin-bottom: -46rpx; |
|
|
} |
|
|
} |
|
|
.login-form-item { |
|
|
|
|
|
|
|
|
.login-form-item { |
|
|
margin-bottom: 36rpx; |
|
|
margin-bottom: 36rpx; |
|
|
} |
|
|
} |
|
|
.login-label { |
|
|
|
|
|
|
|
|
.login-label { |
|
|
font-size: 28rpx; |
|
|
font-size: 28rpx; |
|
|
font-weight: bold; |
|
|
font-weight: bold; |
|
|
color: #222; |
|
|
color: #222; |
|
|
margin-bottom: 12rpx; |
|
|
margin-bottom: 12rpx; |
|
|
display: block; |
|
|
display: block; |
|
|
} |
|
|
} |
|
|
.login-btn-box { |
|
|
|
|
|
|
|
|
.login-btn-box { |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
justify-content: center; |
|
|
} |
|
|
} |
|
|
.captcha-row { |
|
|
|
|
|
|
|
|
.captcha-row { |
|
|
display: flex; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
flex-direction: column; |
|
|
} |
|
|
} |
|
|
.captcha-flex { |
|
|
|
|
|
|
|
|
.captcha-flex { |
|
|
display: flex; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
} |
|
|
} |
|
|
.captcha-img { |
|
|
|
|
|
|
|
|
.captcha-img { |
|
|
width: 160rpx; |
|
|
width: 160rpx; |
|
|
height: 60rpx; |
|
|
height: 60rpx; |
|
|
margin-left: 16rpx; |
|
|
margin-left: 16rpx; |
|
@ -262,5 +278,5 @@ export default { |
|
|
border-radius: 8rpx; |
|
|
border-radius: 8rpx; |
|
|
background: #fff; |
|
|
background: #fff; |
|
|
box-sizing: border-box; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</style> |