cxmo před 1 rokem
rodič
revize
7fb241393c

+ 12 - 2
src/views/Login.vue

@@ -8,12 +8,17 @@ import { useRouter } from 'vue-router';
 import MobileModel from './login/MobileModel.vue';
 import OrdinaryModel from './login/OrdinaryModel.vue';
 import EmailModel from './login/EmailModel.vue';
+import ForgetPassModel from './login/ForgetPassModel.vue';
 
 const router=useRouter()
 
 //登陆模式 ordinaryModel账号密码 mobileModel手机号 emailModel邮箱
 let activeModel = ref('ordinaryModel')
+let autoAccount = ref('')
 function changeModel(model){
+    if(model==='forgetPassModel'){
+        autoAccount.value = loginForm.value.getValues().username
+    }
     activeModel.value = model
 }
 
@@ -125,14 +130,14 @@ function userLogin(params,values){
 
 <template>
     <div class="login-page">
-        <van-form class="form-box" ref="loginForm">
+        <van-form class="form-box" ref="loginForm" v-if="activeModel!=='forgetPassModel'">
             <div class="logo-wrap">
                 <img class="logo" src="@/assets/imgs/logo_icon.png" alt="">
                 <div class="title">Bind on account,</div>
                 <div class="sub-title">sign in to continue</div>
             </div>
             <div class="ordinaryModel" v-show="activeModel==='ordinaryModel'">
-                <ordinary-model :activeModel="activeModel"/>
+                <ordinary-model :activeModel="activeModel" @change-model="changeModel('forgetPassModel')"/>
             </div>
             <div class="mobileModel" v-show="activeModel==='mobileModel'">
                 <mobile-model ref="mobileModel"
@@ -176,6 +181,11 @@ function userLogin(params,values){
                 </div>
             </div>
         </van-form>
+        <div class="form-box" v-else>
+            <forget-pass-model ref="forgetPassModel"
+                :autoAccount="autoAccount"
+                @change-model="changeModel('ordinaryModel')"/>
+        </div>
         <img class="pad-img" src="https://hzstatic.hzinsights.com/static/ETA_mobile/login_img.png" alt="">
         <div class="mobile-bot-text">Long time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;More profit</div>
     </div>

+ 2 - 2
src/views/login/EmailModel.vue

@@ -13,7 +13,7 @@ const { picSrc,picId,getPicCode,
       } = useLogin()
 watch(()=>props.activeModel,()=>{
     if(props.activeModel==='emailModel'){
-        if(!timer.value){
+        if(!timer){
             getPicCode()
             codeStr.value = '获取验证码'
         }
@@ -74,7 +74,7 @@ function checkForm(){
     <van-field
         class="form-input-box form-mobile-box"
         v-model="emailPicCode"
-        name="picCode"
+        name="emailPicCode"
         placeholder="请输入图形验证码"
         :rules="[{ required: true, message: '请输入图形验证码' }]"
     >

+ 335 - 3
src/views/login/ForgetPassModel.vue

@@ -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>

+ 1 - 1
src/views/login/MobileModel.vue

@@ -19,7 +19,7 @@ const { picSrc,picId,getPicCode,
 
 watch(()=>props.activeModel,()=>{
     if(props.activeModel==='mobileModel'){
-        if(!timer.value){
+        if(!timer){
             getPicCode()
             codeStr.value = '获取验证码'
         }

+ 9 - 1
src/views/login/OrdinaryModel.vue

@@ -12,6 +12,10 @@ const props = defineProps({
 let username=ref(localStorage.getItem('account')?Base64.decode(localStorage.getItem('account')):'')
 let password=ref(localStorage.getItem('checkPass')?Base64.decode(localStorage.getItem('checkPass')):'')
 
+const emit = defineEmits(['changeModel'])
+function changeModel(){
+    emit('changeModel')
+}
 </script>
 
 <template>
@@ -29,7 +33,11 @@ let password=ref(localStorage.getItem('checkPass')?Base64.decode(localStorage.ge
         name="password"
         placeholder="请输入密码"
         :rules="[{ required: true, message: '请填写密码' }]"
-    />
+    >
+        <template #button>
+            <span class="btn-text" style="color:#0052D9;" @click="changeModel">忘记密码</span>
+        </template>
+    </van-field>
 </template>
 
 <style scoped lang="scss">

+ 1 - 1
src/views/login/hooks/useLogin.js

@@ -34,7 +34,7 @@ export function useLogin(){
             countDown()
         },1000)
     }
-    let timer = ref(0)
+    let timer = 0
     let codeStr = ref('获取验证码')
     let codeCountDown = ref(60)
     function countDown(){