Commit 89130ab2 authored by 罗超's avatar 罗超

完成密码找回流程

parent ed357085
......@@ -144,5 +144,5 @@ textarea {
--el-color-primary-light-9: #dedcff !important;
--el-color-primary-dark-2: #281ae6 !important;
--el-border-color:#e8eaec !important;
--el-border-radius-base: 8px !important;
--el-border-radius-base: 6px !important;
}
\ No newline at end of file
......@@ -9,7 +9,7 @@ const router = createRouter({
})
const whiteList = ['/autoLogin','/login','/notfound','/regist','/']
const whiteList = ['/autoLogin','/login','/notfound','/regist','/','/forgot']
const managerMenu = ['/market','/editor_admin']
let loadingInstance:any = null
......
......@@ -53,6 +53,13 @@ const routes: RouteRecordRaw[] = [
title:'注册 Travel Design'
}
},
{
path: '/forgot',
component: () => import('@/views/Auth/Forgot.vue'),
meta:{
title:'忘记密码 Travel Design'
}
},
{
path: '/notfound',
component: () => import('@/views/ErrorNotFound.vue'),
......
......@@ -81,5 +81,19 @@ class UserServices{
let msg = {}
return Api.Post("travel_login_verify",msg)
}
static async SendResetPassCodeAsync(mail:string):Promise<HttpResponse>{
let msg = {mail}
return Api.Post("travel_forgot_pass",msg)
}
static async VerifyResetPassCodeAsync(mail:string,code:string,v_token:string):Promise<HttpResponse>{
let msg:any = {code}
if(mail!='') msg.mail = mail
if(v_token!='') msg.v_token = v_token
return Api.Post("travel_verify_forgotcode",msg)
}
static async ResetPasswordAsync(pw:string,v_token:string):Promise<HttpResponse>{
let msg:any = {pw,v_token}
return Api.Post("travel_reset_password",msg)
}
}
export default UserServices;
\ No newline at end of file
<template>
<div class="full-width window-height row" style="background-color: #F1F2F4;">
<div class="col">
<div class=" full-height column" style="padding: 50px 0; width:435px;margin:0 auto">
<div>
<img src="https://imgfile.oytour.com/static/pptdefault1.png" style="height: 25px;width: auto;">
</div>
<div class="col column items-center flex-center full-width">
<div class="text-center full-width" v-if="!resetToken">
<div class="text-weight-bold text-dark" style="font-size: 23px;">忘记密码?</div>
<div class="text-info q-mt-md q-mb-xl" style="font-size: 14px; font-weight: 500;">输入你的注册邮箱,重置你的密码。</div>
<el-input v-model="email" placeholder="邮箱" size="large" clearable class="pingfangr full-width" :readonly="isSend" style="height:50px !important;">
<template #suffix>
<el-button link :loading="sending" v-if="!isCountdown && isSend" @click="sendVerifyCode">重新发送</el-button>
<template v-if="isCountdown">
<el-countdown title="" format="ss" :value="countValue" value-style="font-size:14px;color:#f89c53;" class="inline q-mx-sm" @finish="()=>isCountdown=false" />s
</template>
</template>
</el-input>
<div class="q-mt-lg" v-if="isSend">
<div class="text-small text-info text-left q-mb-md">请输入邮件验证码:</div>
<VerifyCode v-model="code" :digit="6"></VerifyCode>
</div>
<el-button type="primary" size="large" class="q-mt-lg ppt-button" :disabled="!mailRegex.test(email)" @click="sendVerifyCode" :loading="sending" v-if="!isSend">发送验证码</el-button>
<el-button type="primary" size="large" class="q-mt-lg ppt-button" :disabled="code.length!=6" :loading="sending" v-if="isSend && !sending" @click="verifyHandler">提交验证码</el-button>
</div>
<div class="full-width" v-if="resetToken">
<div class="text-weight-bold text-dark" style="font-size: 16px;">重新设置你的密码</div>
<div class="text-weight-bold text-dark q-mt-md" style="font-size: 24px;">{{ resetToken.mail }}</div>
<div class="text-info q-mt-md q-mb-xl" style="font-size: 14px; font-weight: 500;">我们建议你的密码包含大写+小写+数字+特殊字符进行组合</div>
<el-input v-model="resetModel.newPassword" type="password" placeholder="新密码" size="large" show-password class="pingfangr full-width" style="height:50px !important;" />
<el-input v-model="resetModel.confirmPassword" type="password" placeholder="确认密码" size="large" show-password class="pingfangr full-width q-mt-lg" style="height:50px !important;" />
<div>
<el-button type="primary" size="large" class="q-mt-lg ppt-button" @click="resetPassword" :loading="loading">确认密码</el-button>
</div>
</div>
</div>
<div>
<el-button link icon="Back" size="large" class="ppt-button text-weight-bolder" @click="forwardHandler('/login')"> 返回登录</el-button>
</div>
</div>
</div>
<div class="col forgot-right-panel column flex-center items-center">
<img src="https://viitto-1301420277.cos.ap-chengdu.myqcloud.com/Upload/Goods/638521566644129630.png" style="width:400px;user-select: none">
</div>
</div>
</template>
<script lang="ts" setup>
import { ApiResult } from "@/configs/axios";
import UserServices from "@/services/UserService";
import { ElMessage } from "element-plus";
import { reactive, ref } from "vue";
import VerifyCode from "@/views/components/element/Verify/VerifyCode.vue";
import { useRouter } from "vue-router";
const email = ref('')
const mailRegex = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/
const loading = ref(false)
const sending = ref(false)
const code = ref('')
const isSend = ref(false)
const isCountdown = ref(false)
const countValue = ref<number>(0)
const resetToken = ref<any>()
const resetModel = reactive({
newPassword:'',
confirmPassword:''
})
const router = useRouter()
const sendVerifyCode = async()=>{
if(!mailRegex.test(email.value) || sending.value) return
sending.value= true
const response = await UserServices.SendResetPassCodeAsync(email.value)
if(response.data.resultCode == ApiResult.SUCCESS){
ElMessage.success({message:'验证码已发送,请前往邮箱查看'})
isCountdown.value = true
countValue.value = Date.now() + 1000 * 60
isSend.value = true
} else {
ElMessage.error({message:response.data.message})
}
sending.value= false
}
const verifyHandler = async ()=>{
if(code.value.length!=6 || !mailRegex.test(email.value) || sending.value || loading.value) return
loading.value=true
const response = await UserServices.VerifyResetPassCodeAsync(email.value,code.value,'')
if(response.data.resultCode == ApiResult.SUCCESS){
resetToken.value = response.data.data
ElMessage.success({message:'验证成功,请重新设置你的密码'})
}else{
ElMessage.error({message:response.data.message})
}
loading.value=false
}
const resetPassword = async()=>{
if(resetModel.newPassword.length<6||resetModel.newPassword.length>20){
ElMessage.error({message:'新密码长度应为6-20位'})
return
}
if(resetModel.newPassword!=resetModel.confirmPassword){
ElMessage.error({message:'两次输入的密码不一致, 请重新输入'})
return
}
if(loading.value) return
loading.value=true
const response = await UserServices.ResetPasswordAsync(resetModel.newPassword,resetToken.value.r_token)
if(response.data.resultCode == ApiResult.SUCCESS){
ElMessage.success({message:'密码更新成功,正在前往登录页面'})
setTimeout(() => {
forwardHandler('/login')
}, 1000);
return
}
ElMessage.error({message:response.data.message})
loading.value=false
}
const forwardHandler=(path:string)=>{
router.push({path})
}
</script>
<style>
.forgot-right-panel{
background-image: url('https://viitto-1301420277.cos.ap-chengdu.myqcloud.com/Upload/Goods/638521440349462315.png');
background-position: center;
background-size: cover;
}
</style>
\ No newline at end of file
......@@ -50,7 +50,7 @@
<div class="col">
<vue-hcaptcha ref="invisibleHcaptcha" sitekey="46e00e53-ddb2-4e7b-9c51-621534c2f1f5" @verify="verifyHandler" v-if="needVerify"></vue-hcaptcha>
</div>
<el-button link type="primary">忘记密码?</el-button>
<el-button link type="primary" @click="redicetToForgot">忘记密码?</el-button>
</div>
</el-form-item>
<el-form-item>
......@@ -190,6 +190,9 @@ const forwardWorkspaceHandler = ()=>{
const redicetToRegist = ()=>{
location.href='/regist'
}
const redicetToForgot = ()=>{
location.href='/forgot'
}
const clearCompanyChoosenHandler = ()=>{
multipleUsers.value=[]
model.value.tid=''
......
......@@ -171,9 +171,12 @@ const sendVerifyCode = async () => {
const response = await UserServices.SendRegistCodeAsync(model.value.mail)
if(response.data.resultCode == ApiResult.SUCCESS){
ElMessage.success({message:'验证码已发送,请前往邮箱查看'})
isCountdown.value = true
countValue.value = Date.now() + 1000 * 60
isSend.value = true
} else {
ElMessage.error({message:response.data.message})
}
sending.value= false
......
<template>
<form autocorrect="off" autocapitalize="off" autocomplete="off" spellcheck="false">
<div class="row flex-between">
<div v-for="(x, i) in formatStyle.col" :key="i" class="override-verfity-ipt" style="width: 60px">
<el-input style="height: 60px" v-model="formatStyle.col[i]" @focus="codeFocus($event)" :ref="setRef" @keyup="changFocus($event, i)" maxlength="1" />
</div>
<div class="q-my-md negative f12" v-if="hasError">{{ errorMsg }}</div>
</div>
</form>
</template>
<script>
import { reactive, ref } from 'vue'
export default {
props: {
/**
* @description 请传入能够被12整除的整数
*/
digit: Number,
/**
* @description 提示语
*/
hint: String,
/**
* @description 绑定值
*/
modelValue: [String, Number]
},
setup(props, context) {
const cols = reactive([])
const hasError = ref(false)
const errorMsg = ref('')
for (let i = 0; i < props.digit; i++) {
cols.push('')
}
const formatStyle = reactive({
col: reactive(cols),
colStyle: ref(`col-${12 / props.digit}`)
})
const myRef = ref([])
const setRef = el => {
myRef.value.push(el)
}
const changFocus = (event, index) => {
if (event.key == 'Backspace') {
if (index != 0) {
myRef.value[index - 1].focus()
}
} else if (index < props.digit) {
if (formatStyle.col[index] != '') {
myRef.value[index + 1].focus()
}
}
updateValue()
}
const updateValue = () => {
let tempValue = ref('')
formatStyle.col.forEach(x => {
tempValue.value += x.toString()
})
context.emit('update:modelValue', tempValue.value)
}
const codeFocus = e => {
e.target.select()
}
const validate = () => {
if (props.modelValue.length != formatStyle.col.length) {
errorMsg.value = '请输入正确的验证码'
hasError.value = true
} else {
errorMsg.value = ''
hasError.value = false
}
}
return { formatStyle, changFocus, setRef, codeFocus, validate, hasError, errorMsg }
}
}
</script>
<style>
/* .override-verfity-ipt .q-field--dense .q-field__control,
.override-verfity-ipt .q-field--dense .q-field__marginal {
} */
.override-verfity-ipt .el-input__inner{
text-align: center;
height: 50px !important;
text-align: center;
font-family: pingfangr;
font-weight: bold;
font-size: 32px;
}
</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