Commit f2a2970a authored by 谢子梦's avatar 谢子梦

短信验证-重新获取验证码

parent 0af2fe65
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="login"> <div class="login">
<!-- 页面的名称 --> <!-- 页面的名称 -->
<img class="loginTitleStyle" src="../assets/images/login-title.png" alt=""> <img class="loginTitleStyle" src="../assets/images/login-title.png" alt="">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" v-if="textMessageShow">
<h3 class="title">账号登录</h3> <h3 class="title">账号登录</h3>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号"> <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
...@@ -11,20 +11,20 @@ ...@@ -11,20 +11,20 @@
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" <el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
@keyup.enter.native="handleLogin"> @keyup.enter.native="getSmsCode">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaEnabled"> <el-form-item prop="code" v-if="captchaEnabled">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="数字验证码" style="width: 63%;" <el-input v-model="loginForm.code" auto-complete="off" placeholder="数字验证码" style="width: 63%;"
@keyup.enter.native="handleLogin"> @keyup.enter.native="getSmsCode">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input> </el-input>
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" /> <img :src="codeUrl" @click="getCode" class="login-code-img" />
</div> </div>
</el-form-item> </el-form-item>
<el-form-item prop="smsCode" v-if="captchaEnabled" class="textMessage"> <!-- <el-form-item prop="smsCode" v-if="captchaEnabled" class="textMessage">
<el-input style="width: 63%;" v-model="loginForm.smsCode" placeholder="短信验证码"> <el-input style="width: 63%;" v-model="loginForm.smsCode" placeholder="短信验证码">
<i slot="prefix" @keyup.enter.native="handleLogin" style="margin-left: 2px;margin-top:12px" <i slot="prefix" @keyup.enter.native="handleLogin" style="margin-left: 2px;margin-top:12px"
class="el-icon-mobile-phone" /> class="el-icon-mobile-phone" />
...@@ -32,12 +32,12 @@ ...@@ -32,12 +32,12 @@
<el-button :disabled="VerificationCodeTime > 0 || VerificationCodeShow" @click="getSmsCode" <el-button :disabled="VerificationCodeTime > 0 || VerificationCodeShow" @click="getSmsCode"
style="width:33%;margin-left:4%;font-size:11px;" type="success">{{ style="width:33%;margin-left:4%;font-size:11px;" type="success">{{
VerificationCodeTitle }}</el-button> VerificationCodeTitle }}</el-button>
</el-form-item> </el-form-item> -->
<div style="color: red; font-size: 12px;margin-top:-10px;">获取短信验证码前必须同时填写账号、密码、数字验证码</div> <!-- <div style="color: red; font-size: 12px;margin-top:-10px;">获取短信验证码前必须同时填写账号、密码、数字验证码</div> -->
<el-checkbox v-model="loginForm.rememberMe" style="margin:12px 0px 25px 0px;">记住密码</el-checkbox> <el-checkbox v-model="loginForm.rememberMe" style="margin:12px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;"> <el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin"> @click.native.prevent="getSmsCode">
<span v-if="!loading">登 录</span> <span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span> <span v-else>登 录 中...</span>
</el-button> </el-button>
...@@ -46,11 +46,57 @@ ...@@ -46,11 +46,57 @@
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="SMSVerificationMain" v-else>
<div class="roundLogoMain">
<img class="roundLogo" src="../assets/images/roundLogo.png" alt="">
</div>
<h3 style="text-align: center;">短信验证</h3>
<p class="promptConter">数字验证码已通过短信发送至 +86 {{ mobile }},有效期 1 分钟,如未收到,请尝试重新获取。</p>
<div class="verificationCodeConter">
<p class="g-remove-check-code_tip">请输入六位数验证码</p>
<div class="g-remove-check-code_content" @keyup="fnCheckCodeKeyup" @keydown="fnCheckCodeKeydown"
@paste="fnCheckCodeKeyPaste" @input="fnCheckCodeInputEvent">
<input :class="{ 'g-code-input_color': aCheckCodeInputComputed[0] !== '' }" max="9" min="0" maxlength="1"
data-index="0" v-model.trim.number="aCheckCodeInputComputed[0]" type="number" ref="firstInputRef" />
<input :class="{ 'g-code-input_color': aCheckCodeInputComputed[1] !== '' }" max="9" min="0" maxlength="1"
data-index="1" v-model.trim.number="aCheckCodeInputComputed[1]" type="number" />
<input :class="{ 'g-code-input_color': aCheckCodeInputComputed[2] !== '' }" max="9" min="0" maxlength="1"
data-index="2" v-model.trim.number="aCheckCodeInputComputed[2]" type="number" />
<input :class="{ 'g-code-input_color': aCheckCodeInputComputed[3] !== '' }" max="9" min="0" maxlength="1"
data-index="3" v-model.trim.number="aCheckCodeInputComputed[3]" type="number" />
<input :class="{ 'g-code-input_color': aCheckCodeInputComputed[4] !== '' }" max="9" min="0" maxlength="1"
data-index="4" v-model.trim.number="aCheckCodeInputComputed[4]" type="number" />
<input :class="{ 'g-code-input_color': aCheckCodeInputComputed[5] !== '' }" max="9" min="0" maxlength="1"
data-index="5" v-model.trim.number="aCheckCodeInputComputed[5]" type="number" />
</div>
<div class="againVerificationCode">
<el-button @click="reactText" type="text" :disabled="VerificationCodeTime != 60">{{ VerificationCodeTitle
}}</el-button>
</div>
</div>
</div>
<!-- 底部 --> <!-- 底部 -->
<div class="el-login-footer"> <div class="el-login-footer">
<a class="text-color" href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank"> <span <a class="text-color" href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank"> <span
style="color: #00afff">备案号:冀ICP备2024097706号-1</span></a> style="color: #00afff">备案号:冀ICP备2024097706号-1</span></a>
</div> </div>
<!-- 重新获取验证码弹窗 -->
<el-dialog title="请选完成数字验证" :visible.sync="dialogVisible" width="30%" center top="26vh !important">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form-dialog" @submit.native.prevent>
<el-form-item prop="code">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="数字验证码" style="width: 63%;"
@keyup.enter.native="reactTextMessage">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" />
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="reactTextMessage">确 定</el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
...@@ -88,10 +134,16 @@ export default { ...@@ -88,10 +134,16 @@ export default {
// 注册开关 // 注册开关
register: false, register: false,
redirect: undefined, redirect: undefined,
// 显示验证码部分
textMessageShow: true,
// 短信验证码部分参数 // 短信验证码部分参数
VerificationCodeTitle: '发送验证码', mobile: null,
VerificationCodeTime: 0, aCheckCodeInput: ['', '', '', '', '', ''],
VerificationCodeShow: true aCheckCodeInputComputed: [],
VerificationCodeTime: 60,
VerificationCodeTitle: null,
// 重新发送验证码弹窗
dialogVisible: false
}; };
}, },
watch: { watch: {
...@@ -112,13 +164,49 @@ export default { ...@@ -112,13 +164,49 @@ export default {
}, },
deep: true, deep: true,
immediate: false, immediate: false,
} },
aCheckCodeInput: {
handler(newValue, oldValue) {
this.aCheckCodeInputComputed = newValue
// console.log(newValue);
let code = ''
newValue.forEach((element, index) => {
const regex = /^(0|[1-9]|10)$/;
if (regex.test(element)) {
code += element
} else {
code = ''
return
}
});
if (code.length == 6) {
this.handleLogin(code)
}
this.$forceUpdate()
},
deep: true
},
}, },
created() { created() {
this.getCode(); this.getCode();
this.getCookie(); this.getCookie();
}, },
methods: { methods: {
// 点击重新发送按钮方法
reactText() {
this.getCode()
this.loginForm.code = ''
this.dialogVisible = true
},
// 重新获取验证码方法-确认
reactTextMessage() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.getSmsCode()
this.dialogVisible = false
}
})
},
getCode() { getCode() {
getCodeImg().then(res => { getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled; this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
...@@ -138,30 +226,31 @@ export default { ...@@ -138,30 +226,31 @@ export default {
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
}; };
}, },
handleLogin() { handleLogin(code) {
this.loginRules.smsCode = [{ required: true, trigger: "change", message: "请输入短信验证码" }] // this.loginRules.smsCode = [{ required: true, trigger: "change", message: "请输入短信验证码" }]
this.$refs.loginForm.validate(valid => { // this.$refs.loginForm.validate(valid => {
if (valid) { // if (valid) {
this.loading = true; this.loginForm.smsCode = code
if (this.loginForm.rememberMe) { this.loading = true;
Cookies.set("username", this.loginForm.username, { expires: 30 }); if (this.loginForm.rememberMe) {
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
} else { Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
Cookies.remove("username"); } else {
Cookies.remove("password"); Cookies.remove("username");
Cookies.remove('rememberMe'); Cookies.remove("password");
} Cookies.remove('rememberMe');
this.$store.dispatch("Login", this.loginForm).then(() => { }
this.$router.push({ path: this.redirect || "/" }).catch(() => { }); this.$store.dispatch("Login", this.loginForm).then(() => {
}).catch(() => { this.$router.push({ path: this.redirect || "/" }).catch(() => { });
this.loading = false; }).catch(() => {
if (this.captchaEnabled) { this.loading = false;
this.getCode(); if (this.captchaEnabled) {
} this.getCode();
});
} }
}); });
// }
// });
}, },
getSmsCode() { getSmsCode() {
delete this.loginRules.smsCode delete this.loginRules.smsCode
...@@ -169,22 +258,103 @@ export default { ...@@ -169,22 +258,103 @@ export default {
if (valid) { if (valid) {
getLoginSmsCode(this.loginForm).then(resp => { getLoginSmsCode(this.loginForm).then(resp => {
if (200 === resp.code) { if (200 === resp.code) {
this.VerificationCodeTime = 60 this.$modal.msgSuccess(`验证码已发送至${resp.data.mobile}`);
const timer = setInterval(() => { this.mobile = resp.data.mobile
this.VerificationCodeTime--; this.textMessageShow = false
if (this.VerificationCodeTime > 0) { this.countdownMethod()
this.VerificationCodeTitle = `${this.VerificationCodeTime}秒后重新发送`; this.$forceUpdate()
} else {
clearInterval(timer);
this.VerificationCodeTitle = '发送验证码';
this.VerificationCodeTime = 60;
}
}, 1000);
} }
}) })
} }
}); });
} },
// 倒计时方法
countdownMethod() {
this.VerificationCodeTime = 60
const timer = setInterval(() => {
this.VerificationCodeTime--;
if (this.VerificationCodeTime > 0) {
this.VerificationCodeTitle = `${this.VerificationCodeTime}秒后重新发送`;
} else {
clearInterval(timer);
this.VerificationCodeTitle = '点击重新发送验证码';
this.VerificationCodeTime = 60;
}
}, 1000);
},
// 输入验证码,更新验证码数据
fnCheckCodeKeyup(e) {
let index = e.target.dataset.index * 1;
let el = e.target;
// 解决输入e的问题
el.value = el.value
.replace(/Digit|Numpad/i, "")
.slice(0, 1);
if (/Digit|Numpad/i.test(e.code)) {
// 必须在这里赋值,否则输入框会是空值
this.aCheckCodeInput.splice(index, 1, e.code.replace(/Digit|Numpad/i, ""));
el.nextElementSibling && el.nextElementSibling.focus();
if (index === 5) {
if (this.aCheckCodeInput.join("").length === 6) document.activeElement.blur();
}
}
},
// 输入验证码,检测位置变化
fnCheckCodeKeydown(e) {
let index = e.target.dataset.index * 1;
let el = e.target;
if (e.key === "Backspace") {
if (this.aCheckCodeInput[index].length > 0) {
this.aCheckCodeInput.splice(index, 1, '');
} else {
if (el.previousElementSibling) {
el.previousElementSibling.focus();
this.aCheckCodeInput[index - 1] = '';
}
}
} else if (e.key === 'Delete') {
if (this.aCheckCodeInput[index].length > 0) {
this.aCheckCodeInput.splice(index, 1, '');
} else {
if (el.nextElementSibling) {
el.nextElementSibling.focus();
this.aCheckCodeInput[++index] = '';
}
}
} else if (e.key === "Home") {
el.parentElement.children[0] && el.parentElement.children[0].focus();
} else if (e.key === "End") {
el.parentElement.children[this.aCheckCodeInput.length - 1] &&
el.parentElement.children[this.aCheckCodeInput.length - 1].focus();
} else if (e.key === "ArrowLeft") {
if (el.previousElementSibling) el.previousElementSibling.focus();
} else if (e.key === "ArrowRight") {
if (el.nextElementSibling) el.nextElementSibling.focus();
}
},
// 输入验证码,解决一个输入框输入多个字符的问题
fnCheckCodeInputEvent(e) {
let index = e.target.dataset.index * 1;
let el = e.target;
el.value = el.value
.replace(/Digit|Numpad/i, "")
.slice(0, 1);
this.aCheckCodeInput[index] = el.value;
},
// 验证码粘贴
fnCheckCodeKeyPaste(e) {
e.clipboardData.items[0].getAsString((str) => {
if (str.toString().length === 6) {
this.aCheckCodePasteResult = str.split("");
document.activeElement.blur();
this.aCheckCodeInput = this.aCheckCodeInputComputed;
this.aCheckCodePasteResult = [];
} else {
// 如果粘贴内容不合规,清除所有内容
this.aCheckCodeInput = ['', '', '', '', '', ''];
}
});
},
} }
}; };
...@@ -227,6 +397,22 @@ export default { ...@@ -227,6 +397,22 @@ export default {
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-form-dialog {
.el-input { .el-input {
height: 38px; height: 38px;
...@@ -275,4 +461,82 @@ export default { ...@@ -275,4 +461,82 @@ export default {
.login-code-img { .login-code-img {
height: 38px; height: 38px;
} }
// 短信验证主题内容部分
.SMSVerificationMain {
margin-top: 50px;
margin-left: 35vw;
border-radius: 6px;
background: rgba(255, 255, 255, 0.75);
width: 600px;
padding: 75px 45px 75px 35px;
// 圆Logo
.roundLogoMain {
display: flex;
align-items: center;
justify-content: center;
.roundLogo {
width: 50px;
height: 50px;
}
}
.promptConter {
padding: 0px 50px;
color: #666;
}
.verificationCodeConter {
width: 100%;
padding: 4px 0 8px 0;
.g-remove-check-code_content {
display: flex;
justify-content: space-between;
align-items: center;
width: 400px;
padding: 8px 0 18px 0;
margin: 0 auto;
}
.g-remove-check-code_content input {
width: 50px;
height: 50px;
font-size: 36px;
text-align: center;
border: none;
outline: none;
border: solid 1px rgba(187, 187, 187, 100);
border-radius: 4px;
-moz-appearance: textfield;
}
.g-remove-check-code_content input.g-code-input_color {
border-color: #5290FF;
}
.g-remove-check-code_content input::-webkit-outer-spin-button,
.g-remove-check-code_content input::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
.g-remove-check-code_tip {
font-size: 14px;
color: #666;
text-align: center;
}
// 重新发送验证码
.againVerificationCode {
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 50px;
}
}
}
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment