源文件
This commit is contained in:
520
jeepay-ui-agent/src/views/user/Forget.vue
Normal file
520
jeepay-ui-agent/src/views/user/Forget.vue
Normal file
@@ -0,0 +1,520 @@
|
||||
<template>
|
||||
<div id="userLayout" :class="['user-layout-wrapper']">
|
||||
<div class="top">
|
||||
<div class="header">
|
||||
<img :src="oemSiteInfo.sysLogoUrl" style="height: 30px">
|
||||
</div>
|
||||
<!-- <a class="mch-url" href="#">
|
||||
<span>商户登录</span>
|
||||
<i class="bi bi-arrow-right-short" />
|
||||
</a> -->
|
||||
</div>
|
||||
<div class="container" :style="[{background: 'url(' + oemSiteInfo.mgr.loginPageBGImgUrl + ')'}, {backgroundSize:'cover' }, {backgroundPosition: 'center top'}, {backgroundRepeat:'no-repeat'}]">
|
||||
<div class="user-layout-lang" />
|
||||
<div class="user-layout-content">
|
||||
<!-- 错误提示信息 -->
|
||||
<a-alert v-if="showLoginErrorInfo" type="error" showIcon style="margin-bottom: 24px;" :message="showLoginErrorInfo" />
|
||||
<div class="main">
|
||||
<div class="desc">找回密码</div>
|
||||
<a-form ref="formLogin" class="user-layout-login" :model="formState" :rules="vdata.rules" @submit="handleSubmit">
|
||||
<a-form-item name="phone" class="input-item">
|
||||
<login-text-up v-model:value="formState.phone" :isLogin="true" placeholder="手机号" />
|
||||
</a-form-item>
|
||||
<div class="code-body" >
|
||||
<div class="code code-layout-item" style="display: flex;justify-content:center">
|
||||
<a-form-item name="vercode" class="input-item">
|
||||
<login-text-up v-model:value="formState.vercode" :isLogin="true" placeholder="图形验证码" />
|
||||
</a-form-item>
|
||||
|
||||
<div class="code-img" style="position: relative;">
|
||||
<img v-show="vercodeImgSrc" :src="vercodeImgSrc" @click="refVercode()">
|
||||
<div v-show="isOverdue" class="vercode-mask" @click="refVercode()">
|
||||
已过期 请刷新
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="code">
|
||||
<a-form-item name="code" class="input-item">
|
||||
<login-text-up v-model:value="formState.code" :isLogin="true" placeholder="请输入验证码" />
|
||||
</a-form-item>
|
||||
|
||||
<div>
|
||||
<a-button type="primary" :disabled="vdata.isDisabled" style="height: 40px;margin-left: 10px" @click="sendSMS()">{{ vdata.codeBtnText }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<a-form-item name="newPwd" class="input-item">
|
||||
<login-text-up v-model:value="formState.newPwd" :isLogin="true" placeholder="请输入新密码" isPassword="password" />
|
||||
</a-form-item>
|
||||
<a-form-item name="confirmPwd" class="input-item">
|
||||
<login-text-up v-model:value="formState.confirmPwd" :isLogin="true" placeholder="请确认新密码" isPassword="password" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item style="margin-bottom: 30px;">
|
||||
<!-- 忘记密码 -->
|
||||
<a class="forge-password" style="float: right;" @click="toLogin">去登录 >></a>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-button
|
||||
size="large"
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
class="login-button submit"
|
||||
:loading="loginBtnLoadingFlag"
|
||||
style="width: 100%"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
确认
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="footer" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { sendSmsCode, retrieve } from '@/api/login'
|
||||
import { $getPasswordRules } from '@/api/manage'
|
||||
import router from '@/router'
|
||||
import { vercode } from '@/api/login'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { useOem } from '@/store/modules/oem'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
let loginBtnLoadingFlag = false // 登录按钮是否显示 加载状态
|
||||
let showLoginErrorInfo = ref('') // 是否显示登录错误面板信息
|
||||
let timer: number = -1
|
||||
|
||||
let formLogin = ref()
|
||||
// 获取网站信息
|
||||
const oemSiteInfo = useOem().getSiteInfo()
|
||||
let isOverdue = ref(false) // 设置过期样式
|
||||
let vercodeImgSrc = ref('') // 验证码图片
|
||||
let vercodeToken = ref('') // 验证码验证token
|
||||
let formState = reactive({
|
||||
vercode:'',
|
||||
phone: '',
|
||||
code: '',
|
||||
newPwd: '',
|
||||
confirmPwd: '',
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
visibleCode:false,
|
||||
codeBtnText : '发送短信验证码',
|
||||
isDisabled : false,
|
||||
passwordRules: /^$/, //密码规则
|
||||
passwordRulesText: '', //密码规则提示文字
|
||||
rules : {
|
||||
phone: [{ required: true, pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
|
||||
newPwd: [
|
||||
{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.passwordRules.test(formState.newPwd)) {
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(formState.newPwd !== formState.confirmPwd) {
|
||||
return Promise.reject('新密码与确认新密码不一致')
|
||||
} else return Promise.resolve()
|
||||
}
|
||||
}
|
||||
],
|
||||
confirmPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.passwordRules.test(formState.confirmPwd)) {
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(formState.newPwd !== formState.confirmPwd) {
|
||||
return Promise.reject('新密码与确认新密码不一致')
|
||||
} else return Promise.resolve()
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
onMounted(()=>{
|
||||
getPasswordRules()
|
||||
refVercode()
|
||||
})
|
||||
|
||||
function getPasswordRules () { // 获取密码规则
|
||||
$getPasswordRules().then(res => {
|
||||
vdata.passwordRules = new RegExp(res.regexpRules)
|
||||
vdata.passwordRulesText = res.errTips
|
||||
})
|
||||
}
|
||||
// handler
|
||||
function handleSubmit (){
|
||||
formLogin.value.validate().then(valid =>{
|
||||
let params = {
|
||||
phone: formState.phone,
|
||||
code: formState.code,
|
||||
newPwd: formState.newPwd,
|
||||
vercode: formState.vercode,
|
||||
vercodeToken: vercodeToken.value,
|
||||
}
|
||||
retrieve(params).then((res) => {
|
||||
message.success('修改成功')
|
||||
router.push({ path: '/user/login' }) // 校验成功,返回登录页
|
||||
}).catch(err => {
|
||||
showLoginErrorInfo = (err.msg || JSON.stringify(err))
|
||||
loginBtnLoadingFlag = false
|
||||
})
|
||||
}).catch(valid =>{})
|
||||
}
|
||||
|
||||
function sendSMS () { // 发送短信验证
|
||||
if (!formState.phone) {
|
||||
return message.error('请输入手机号!')
|
||||
}
|
||||
// 校验手机号
|
||||
const reg = /^[1][0-9]{10}$/
|
||||
if (!reg.test(formState.phone)) {
|
||||
return message.error('请输入正确的手机号!')
|
||||
}
|
||||
|
||||
if (!vercodeToken.value) {
|
||||
return message.error('请输入验证码!')
|
||||
}
|
||||
if (!formState.vercode) {
|
||||
return message.error('请输入验证码!')
|
||||
}
|
||||
|
||||
vdata.isDisabled = true
|
||||
|
||||
sendSmsCode({ phone: formState.phone, smsType: 'retrieve', vercode: formState.vercode, vercodeToken: vercodeToken.value})
|
||||
.then(res => { return message.success('发送成功!')
|
||||
}).catch(err => {
|
||||
showLoginErrorInfo = (err.msg || JSON.stringify(err))
|
||||
loginBtnLoadingFlag = false
|
||||
// 出错后三秒停止计时
|
||||
setTimeout(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
vdata.isDisabled = false
|
||||
vdata.codeBtnText = '发送短信验证码'
|
||||
}, 500)
|
||||
})
|
||||
|
||||
let time = 60 // 重发验证码时间
|
||||
vdata.codeBtnText = `${time}秒后重新发送`
|
||||
const timer = setInterval(() => {
|
||||
time -= 1
|
||||
vdata.codeBtnText = `${time}秒后重新发送`
|
||||
if (time === 0) {
|
||||
clearInterval(timer)
|
||||
vdata.isDisabled = false
|
||||
vdata.codeBtnText = '发送短信验证码'
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 忘记密码跳转页面
|
||||
function toLogin () {
|
||||
router.push({ name: 'login', path: '/user/login' })
|
||||
}
|
||||
function refVercode() {
|
||||
// 刷新图片验证码
|
||||
// 获取图形验证码
|
||||
vercode().then((res) => {
|
||||
vercodeImgSrc.value = res.imageBase64Data
|
||||
vercodeToken.value = res.vercodeToken
|
||||
|
||||
isOverdue.value = false
|
||||
|
||||
if (timer) clearInterval(timer) // 如果多次点击则清除已有的定时器
|
||||
// 超过60秒提示过期刷新
|
||||
timer = window.setInterval(() => {
|
||||
res.expireTime--
|
||||
if (res.expireTime <= 0) {
|
||||
isOverdue.value = true
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
function sendSMSCode(){
|
||||
vdata.visibleCode = true;
|
||||
refVercode()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#userLayout.user-layout-wrapper {
|
||||
height: 100%;
|
||||
.top {
|
||||
height: 80px;
|
||||
padding: 0 35px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.header {
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
}
|
||||
.mch-url {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
span{
|
||||
margin-right: 10px;
|
||||
}
|
||||
&:hover{
|
||||
color: steelblue;
|
||||
.bi{
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
}
|
||||
.bi{
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center; //修改这一项来决定登录对话框的水平位置,flex-start == left; center == center; flex-end == right
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: calc(100vh - 80px);
|
||||
background: #f0f2f5 url(/src/assets/svg/background.svg) no-repeat 50%;
|
||||
background-size: cover;
|
||||
//padding: 50px 0 84px;
|
||||
position: relative;
|
||||
transition: 0.3s ease;
|
||||
|
||||
.user-layout-lang {
|
||||
width: 100%;
|
||||
// height: 40px;
|
||||
// line-height: 44px;
|
||||
height: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-layout-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: 0.3s ease;
|
||||
input {
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 50px 30px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
background: #fff;
|
||||
border-top: 1px solid #e7eaf3;
|
||||
align-items: center;
|
||||
transition: all 0.3s , border 0s ease;
|
||||
.ant-form{
|
||||
max-width: 300px;
|
||||
}
|
||||
.desc {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
letter-spacing: 0.04em;
|
||||
color: #2691ff;
|
||||
margin-bottom: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
.input-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
// position: absolute;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
padding: 0 16px;
|
||||
margin: 48px 0 24px;
|
||||
text-align: center;
|
||||
|
||||
.links {
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
transition: all 0.3s;
|
||||
&:not(:last-child) {
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//登录页响应式的调整
|
||||
@media screen and (min-width:769px) and (max-width:1024px){
|
||||
.container {
|
||||
padding: 0 100px;
|
||||
min-height: 700px;
|
||||
height: calc(100vh - 80px);
|
||||
align-items: @login-align;
|
||||
.user-layout-content {
|
||||
width: 360px;
|
||||
height: auto;
|
||||
.main{
|
||||
width: 360px;
|
||||
box-shadow: 0 6px 12px rgb(140 152 164 / 8%);
|
||||
border: 0.0625rem solid #E7EAF3 ;
|
||||
height: auto;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (min-width:1025px) and (max-width:1366px){
|
||||
.container {
|
||||
padding: 0 150px;
|
||||
min-height: 700px;
|
||||
height: calc(100vh - 80px);
|
||||
align-items: @login-align;
|
||||
.user-layout-content {
|
||||
width: 360px;
|
||||
height: auto;
|
||||
.main{
|
||||
width: 360px;
|
||||
box-shadow: 0 6px 12px rgb(140 152 164 / 8%);
|
||||
border: 0.0625rem solid #E7EAF3 ;
|
||||
height: auto;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (min-width:1367px) and (max-width:1600px){
|
||||
.container {
|
||||
padding: 0 250px;
|
||||
min-height: 700px;
|
||||
height: calc(100vh - 80px);
|
||||
align-items: @login-align;
|
||||
.user-layout-content {
|
||||
width: 360px;
|
||||
height: auto;
|
||||
.main{
|
||||
width: 360px;
|
||||
box-shadow: 0 6px 12px rgb(140 152 164 / 8%);
|
||||
border: 0.0625rem solid #E7EAF3 ;
|
||||
height: auto;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (min-width:1601px){
|
||||
.container {
|
||||
padding: 0 300px;
|
||||
min-height: 700px;
|
||||
height: calc(100vh - 80px);
|
||||
align-items: @login-align;
|
||||
.user-layout-content {
|
||||
width: 360px;
|
||||
height: auto;
|
||||
.main{
|
||||
width: 360px;
|
||||
box-shadow: 0 6px 12px rgb(140 152 164 / 8%);
|
||||
border: 0.0625rem solid #E7EAF3 ;
|
||||
height: auto;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.user-layout-login {
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.forge-password {
|
||||
font-size: 14px;
|
||||
color: @jee-theme;
|
||||
}
|
||||
|
||||
button.login-button {
|
||||
padding: 0 15px;
|
||||
font-size: 16px;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.user-login-other {
|
||||
text-align: left;
|
||||
margin-top: 24px;
|
||||
line-height: 22px;
|
||||
|
||||
.item-icon {
|
||||
font-size: 24px;
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
margin-left: 16px;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.register {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.code {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.code-input {
|
||||
width: 216px;
|
||||
}
|
||||
.code-img {
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
margin-left: 10px;
|
||||
|
||||
}
|
||||
}
|
||||
.submit {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.container_bg{
|
||||
position: fixed;
|
||||
background: transparent;
|
||||
width: 20%;
|
||||
height: 20%;
|
||||
top: 2%;
|
||||
left: 5%;
|
||||
}
|
||||
.code-body {
|
||||
// padding-bottom: 20px;
|
||||
padding-left: 1px;
|
||||
width: 314px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user