|
@@ -1,12 +1,344 @@
|
|
|
<script setup>
|
|
|
+import {ref,onMounted} from 'vue'
|
|
|
+import { showToast } from 'vant'
|
|
|
+import {_apiLogin} from '@/api/user'
|
|
|
+import {useLogin} from './hooks/useLogin'
|
|
|
+import {Base64} from 'js-base64'
|
|
|
+const props = defineProps({
|
|
|
+ autoAccount:{//自动填入账号,如果有
|
|
|
+ type:String,
|
|
|
+ default:''
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const { picSrc,picId,getPicCode} = useLogin()
|
|
|
+
|
|
|
+const stepTitle = [
|
|
|
+ '忘记密码',
|
|
|
+ '安全验证',
|
|
|
+ '请输入验证码',
|
|
|
+ '设置密码'
|
|
|
+]
|
|
|
+let currentStep = ref(0)
|
|
|
+let account = ref('')
|
|
|
+let accountCode = ref('') //账号的图形验证码
|
|
|
+
|
|
|
+let userMobile = ref('')
|
|
|
+let areaCode = ref('')
|
|
|
+let userEmail = ref('')
|
|
|
+let choosedWay = ref('')
|
|
|
+
|
|
|
+let captInput = ref('')
|
|
|
+let showKeyboard = ref(false)
|
|
|
+function getUserInfo(values){
|
|
|
+ _apiLogin.apiAccountCheck({
|
|
|
+ CaptchaId:picId.value,
|
|
|
+ CaptchaCode:accountCode.value,
|
|
|
+ UserName:account.value
|
|
|
+ }).then(res=>{
|
|
|
+ if(res.Ret!==200){
|
|
|
+ //刷新图形验证码
|
|
|
+ getPicCode()
|
|
|
+ accountCode.value = ''
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if(res.Data){
|
|
|
+ const {Mobile,Email,TelAreaCode} = res.Data
|
|
|
+ userMobile.value = Mobile
|
|
|
+ userEmail.value = Email
|
|
|
+ areaCode.value = TelAreaCode
|
|
|
+ goNextStep()
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+//获取手机/邮箱验证码
|
|
|
+async function getVerifyCode(){
|
|
|
+ if(!choosedWay.value){
|
|
|
+ showToast('请选择验证方式')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const res = await _apiLogin.apiGetVerifyCode({
|
|
|
+ VerifyType:choosedWay.value==='mobile'?1:2,
|
|
|
+ CaptchaId:picId.value,
|
|
|
+ CaptchaCode:accountCode.value,
|
|
|
+ Mobile:choosedWay.value==='mobile'?userMobile.value:'',
|
|
|
+ Email:choosedWay.value==='email'?userEmail.value:'',
|
|
|
+ TelAreaCode:choosedWay.value==='mobile'?areaCode.value+'':'',
|
|
|
+ Source:3
|
|
|
+ })
|
|
|
+ if(res.Ret!==200) return
|
|
|
+ showToast('验证码已发送')
|
|
|
+ goNextStep()
|
|
|
+}
|
|
|
+//检查输入的验证码
|
|
|
+function checkInput(){
|
|
|
+ if(captInput.value.length!==6){
|
|
|
+ showToast('请输入完整的验证码')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ _apiLogin.apiCheckCodeVerify({
|
|
|
+ FindType:choosedWay.value==='mobile'?1:2,
|
|
|
+ VerifyCode:captInput.value,
|
|
|
+ UserName:account.value,
|
|
|
+ Mobile:choosedWay.value==='mobile'?userMobile.value:'',
|
|
|
+ Email:choosedWay.value==='email'?userEmail.value:''
|
|
|
+ }).then(res=>{
|
|
|
+ if(res.Ret!==200) return
|
|
|
+ goNextStep()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+//重置密码
|
|
|
+let checkPassStr = ref('确定')
|
|
|
+let resetPassTimer = 0
|
|
|
+let countDownNum = ref(5)
|
|
|
+let password = ref('')
|
|
|
+let checkPassword = ref('')
|
|
|
+
|
|
|
+function resetPass(values){
|
|
|
+ if(checkPassStr.value.includes('去登陆')){
|
|
|
+ $emit('changeModel')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ _apiLogin.resetPass({
|
|
|
+ UserName:account.value,
|
|
|
+ Password:Base64.encode(values.password),
|
|
|
+ RePassword:Base64.encode(values.checkPassword)
|
|
|
+ }).then(res=>{
|
|
|
+ if(res.Ret!==200) return
|
|
|
+ showToast('重置密码成功,请登陆')
|
|
|
+ resetPassCountDown()
|
|
|
+ })
|
|
|
+}
|
|
|
+function resetPassCountDown(){
|
|
|
+ countDownNum.value--
|
|
|
+ checkPassStr.value = `去登陆(${countDownNum.value}s)`
|
|
|
+ if(countDownNum.value<=0){
|
|
|
+ clearInterval(resetPassTimer)
|
|
|
+ emit('changeModel')
|
|
|
+ return
|
|
|
+ }
|
|
|
+}
|
|
|
+function goNextStep(){
|
|
|
+ currentStep.value++
|
|
|
+}
|
|
|
+
|
|
|
+const emit = defineEmits(['changeModel'])
|
|
|
+function changeModel(){
|
|
|
+ if(currentStep.value > 0){
|
|
|
+ currentStep.value--
|
|
|
+ }else{
|
|
|
+ emit('changeModel')
|
|
|
+ }
|
|
|
+}
|
|
|
+onMounted(()=>{
|
|
|
+ account.value = props.autoAccount
|
|
|
+ getPicCode()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div>
|
|
|
-
|
|
|
+ <div class="forget-pass-model-wrap">
|
|
|
+ <div class="header-nav" @click="changeModel">
|
|
|
+ <span><van-icon name="arrow-left" /></span>
|
|
|
+ <span>{{stepTitle[currentStep]}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="step-container" v-show="currentStep===0">
|
|
|
+ <van-form @submit="getUserInfo">
|
|
|
+ <van-field
|
|
|
+ class="form-input-box form-mobile-box"
|
|
|
+ v-model="account"
|
|
|
+ name="account"
|
|
|
+ placeholder="请输入账号"
|
|
|
+ :rules="[{ required: true, message: '请输入账号' },]"
|
|
|
+ />
|
|
|
+ <van-field
|
|
|
+ class="form-input-box form-mobile-box"
|
|
|
+ v-model="accountCode"
|
|
|
+ name="accountCode"
|
|
|
+ placeholder="请输入图形验证码"
|
|
|
+ :rules="[{ required: true, message: '请输入图形验证码' }]"
|
|
|
+ >
|
|
|
+ <template #button>
|
|
|
+ <div class="pic-filed" @click="getPicCode">
|
|
|
+ <img :src="picSrc" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ <div class="btn-box">
|
|
|
+ <van-button
|
|
|
+ round
|
|
|
+ block
|
|
|
+ type="primary"
|
|
|
+ native-type="submit"
|
|
|
+ >下一步</van-button>
|
|
|
+ </div>
|
|
|
+ </van-form>
|
|
|
+ </div>
|
|
|
+ <div class="step-container" v-show="currentStep>0">
|
|
|
+ <div class="container-inner" v-show="currentStep===1">
|
|
|
+ <div class="verification-item"
|
|
|
+ :class="{'active':choosedWay==='mobile','disabled':!userMobile.length}" @click="choosedWay = 'mobile'">
|
|
|
+ <div class="icon">
|
|
|
+ <img src="@/assets/imgs/login/phone-icon.png" />
|
|
|
+ </div>
|
|
|
+ <div class="text">{{userMobile||'暂未绑定'}}</div>
|
|
|
+ </div>
|
|
|
+ <div class="verification-item"
|
|
|
+ :class="{'active':choosedWay==='email','disabled':!userEmail.length}" @click="choosedWay = 'email'">
|
|
|
+ <div class="icon">
|
|
|
+ <img src="@/assets/imgs/login/email-icon.png" />
|
|
|
+ </div>
|
|
|
+ <div class="text">{{userEmail||'暂未绑定'}}</div>
|
|
|
+ </div>
|
|
|
+ <van-button round block type="primary"
|
|
|
+ @click="getVerifyCode"
|
|
|
+ >获取验证码</van-button>
|
|
|
+ </div>
|
|
|
+ <div class="container-inner" v-show="currentStep===2">
|
|
|
+ <van-password-input
|
|
|
+ :value="captInput"
|
|
|
+ :length="6"
|
|
|
+ :gutter="10"
|
|
|
+ :mask="false"
|
|
|
+ :focused="showKeyboard"
|
|
|
+ @focus="showKeyboard = true"
|
|
|
+ />
|
|
|
+ <van-number-keyboard
|
|
|
+ v-model="captInput"
|
|
|
+ :show="showKeyboard"
|
|
|
+ @blur="showKeyboard = false"
|
|
|
+ />
|
|
|
+ <van-button round block type="primary"
|
|
|
+ @click="checkInput"
|
|
|
+ >下一步</van-button>
|
|
|
+ </div>
|
|
|
+ <div class="container-inner" v-show="currentStep===3">
|
|
|
+ <van-form @submit="resetPass">
|
|
|
+ <van-field
|
|
|
+ class="form-input-box form-mobile-box"
|
|
|
+ v-model="password"
|
|
|
+ name="password"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ :rules="[{ required: true, message: '请输入密码' },]"
|
|
|
+ />
|
|
|
+ <van-field
|
|
|
+ class="form-input-box form-mobile-box"
|
|
|
+ v-model="checkPassword"
|
|
|
+ name="checkPassword"
|
|
|
+ placeholder="请输入确认密码"
|
|
|
+ :rules="[{ required: true, message: '请输入确认密码' },]"
|
|
|
+ />
|
|
|
+ <van-button round block type="primary"
|
|
|
+ native-type="submit"
|
|
|
+ >{{checkPassStr}}</van-button>
|
|
|
+ </van-form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-
|
|
|
+@import "./style/common.scss";
|
|
|
+.forget-pass-model-wrap{
|
|
|
+ .header-nav{
|
|
|
+ margin-top:160px;
|
|
|
+ font-size: 48px;
|
|
|
+ }
|
|
|
+ .step-container{
|
|
|
+ margin-top: 70px;
|
|
|
+ .container-inner{
|
|
|
+ .verification-item{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width:100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding:20px 30px;
|
|
|
+ margin-bottom: 60px;
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ border-radius: 16px;
|
|
|
+ background-color: #fff;
|
|
|
+ &.active{
|
|
|
+ border: 1px solid #0052D9;
|
|
|
+ background-color: #F2F3FF;
|
|
|
+ }
|
|
|
+ &.disabled{
|
|
|
+ user-select: none;
|
|
|
+ pointer-events: none;
|
|
|
+ }
|
|
|
+ .icon{
|
|
|
+ width:80px;
|
|
|
+ height: 80px;
|
|
|
+ padding:16px;
|
|
|
+ border-radius: 50%;
|
|
|
+ box-shadow: 0px 2px 12px 0px #0000001A;
|
|
|
+ margin-right:20px;
|
|
|
+ img{
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .van-password-input{
|
|
|
+ margin-bottom: 60px;
|
|
|
+ :deep(.van-password-input__security){
|
|
|
+ li{
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ border-radius: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ @media screen and (min-width:$media-width) {
|
|
|
+ .header-nav{
|
|
|
+ margin-top:0;
|
|
|
+ font-size: 36px;
|
|
|
+ }
|
|
|
+ .step-container{
|
|
|
+ margin-top: 70px;
|
|
|
+ .container-inner{
|
|
|
+ .verification-item{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width:100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding:10px 15px;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ border-radius: 8px;
|
|
|
+ background-color: #fff;
|
|
|
+ &.active{
|
|
|
+ border: 1px solid #0052D9;
|
|
|
+ background-color: #F2F3FF;
|
|
|
+ }
|
|
|
+ &.disabled{
|
|
|
+ user-select: none;
|
|
|
+ pointer-events: none;
|
|
|
+ }
|
|
|
+ .icon{
|
|
|
+ width:40px;
|
|
|
+ height: 40px;
|
|
|
+ padding:8px;
|
|
|
+ border-radius: 50%;
|
|
|
+ box-shadow: 0px 2px 12px 0px #0000001A;
|
|
|
+ margin-right:20px;
|
|
|
+ img{
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .van-password-input{
|
|
|
+ margin-bottom: 60px;
|
|
|
+ :deep(.van-password-input__security){
|
|
|
+ li{
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ border-radius: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|