227 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <script setup>
 | |
| import {useRouter, useRoute} from 'vue-router';
 | |
| import {useI18n} from 'vue-i18n'
 | |
| import {senCode, userLogin} from "@/api/auth/index.js";
 | |
| import {codeAuthStore} from "@/stores-collect-code/auth/index.js";
 | |
| import {message} from '@/components/x-message/useMessage.js'
 | |
| // ... 现有导入 ...
 | |
| import FingerprintJS from '@fingerprintjs/fingerprintjs'
 | |
| import {checkPhone, mobileLogin, userSend} from "@/api-collect-code/auth/index.js";
 | |
| 
 | |
| const {userInfo, token, fingerprint} = codeAuthStore()
 | |
| const router = useRouter();
 | |
| const route = useRoute();
 | |
| const {locale} = useI18n()
 | |
| const loadingRef = ref({
 | |
|   loading1: false,
 | |
|   loading2: false,
 | |
| })
 | |
| const password = ref('')
 | |
| const loginType = ref(0)
 | |
| const interval = ref(null)
 | |
| const startCountdown = () => {
 | |
|   if (interval.value) {
 | |
|     clearInterval(interval.value);
 | |
|   }
 | |
|   countdown.value = 60;
 | |
|   interval.value = setInterval(() => {
 | |
|     if (countdown.value > 0) {
 | |
|       countdown.value--;
 | |
|     } else {
 | |
|       clearInterval(interval.value);
 | |
|     }
 | |
|   }, 1000);
 | |
| }
 | |
| const countdown = ref(0);
 | |
| const phoneNum = ref('17630920520')
 | |
| const code = ref('123789')
 | |
| const pane = ref(0)
 | |
| const showKeyboard = ref(false);
 | |
| const getFingerprint = async () => {
 | |
|   const fp = await FingerprintJS.load()
 | |
|   const result = await fp.get()
 | |
|   return result.visitorId // 稳定的指纹哈希值
 | |
| }
 | |
| 
 | |
| // 如果指纹存在,且指纹和指纹库中的指纹一致,则直接登录
 | |
| const checkFingerprint = async () => {
 | |
|   const tempFingerprint = await getFingerprint()
 | |
|   if (fingerprint && fingerprint === tempFingerprint) {
 | |
|     await router.push('/collectCode/mine')
 | |
|   }
 | |
| }
 | |
| checkFingerprint()
 | |
| const vanSwipeRef = ref(null)
 | |
| const getCode = async () => {
 | |
|   loadingRef.value.loading1 = true
 | |
|   const res = await checkPhone({
 | |
|     tel: phoneNum.value,
 | |
|   })
 | |
|   loadingRef.value.loading1 = false
 | |
|   if (res.status === 0) {
 | |
|     const res = await userSend({telNum: phoneNum.value, zone: '+86'})
 | |
|     if (res.status === 0) {
 | |
|       pane.value = 1
 | |
|       vanSwipeRef.value?.swipeTo(pane.value)
 | |
|       showKeyboard.value = true
 | |
|     }
 | |
|   }
 | |
|   /*  loadingRef.value.loading1 = false
 | |
|     if (res.status === 0) {
 | |
| 
 | |
| 
 | |
|     }
 | |
|     pane.value = 1
 | |
|     vanSwipeRef.value?.swipeTo(pane.value)
 | |
|     showKeyboard.value = true
 | |
|     startCountdown();*/
 | |
|   /*  pane.value = 1
 | |
|     vanSwipeRef.value?.swipeTo(pane.value)
 | |
|     showKeyboard.value=true
 | |
|     startCountdown();*/
 | |
| 
 | |
| }
 | |
| const changeToPwd = async () => {
 | |
|   loginType.value = loginType.value === 0 ? 1 : 0
 | |
| }
 | |
| const goBack = () => {
 | |
|   code.value = ''
 | |
|   pane.value = 0
 | |
|   vanSwipeRef.value?.swipeTo(pane.value)
 | |
| }
 | |
| const goLogin = async () => {
 | |
|   loadingRef.value.loading2 = true
 | |
|   const res = await mobileLogin({
 | |
|     TelNum: phoneNum.value,
 | |
|     Password: loginType.value === 1 ? password.value : '',
 | |
|     Code: loginType.value === 0 ? code.value : ''
 | |
|   })
 | |
|   if (res.status === 0) {
 | |
|     userInfo.value = res.data.accountInfo
 | |
|     token.value = res.data.token
 | |
|     fingerprint.value = await getFingerprint()
 | |
| 
 | |
|     await router.push('/collectCode/mine');
 | |
| 
 | |
|   }
 | |
|   loadingRef.value.loading2 = false
 | |
| }
 | |
| const showPassword = ref(false)
 | |
| 
 | |
| const togglePasswordVisibility = () => {
 | |
|   showPassword.value = !showPassword.value
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <template>
 | |
|   <div class="h-[100vh] w-[100vw] bg-[url('@/static/images/asdfsdd.png')] bg-cover px-[31px] pt-[86px]">
 | |
|     <div class="w-full flex justify-center mb-[100px] flex-col items-center">
 | |
|       <img class="h-[105px] w-[189px]" src="@/static/images/ghfggff.png" alt="">
 | |
|       <img class="h-[29px] w-[108px]" src="@/static/images/qrcodetext.png" alt="">
 | |
|     </div>
 | |
|     <van-swipe ref="vanSwipeRef" :show-indicators="false" :touchable="false" :lazy-render="true" :loop="false">
 | |
|       <van-swipe-item>
 | |
|         <div v-show="pane === 0">
 | |
|           <div class="">
 | |
|             <div class="border-b-[1.7px] mt-[8px]">
 | |
|               <van-field v-model="phoneNum" clearable :placeholder="$t('collectCode.login.phoneNumberPlaceholder')">
 | |
|                 <template #label>
 | |
|                   <div class="text-[16px] text-[#1A1A1A] flex align-center justify-start">
 | |
|                     {{ $t('collectCode.login.phoneNumber') }}
 | |
|                   </div>
 | |
|                 </template>
 | |
|               </van-field>
 | |
|             </div>
 | |
|             <div class="border-b-[1.7px] mt-[8px]" v-show="loginType === 1">
 | |
|               <van-field
 | |
|                   v-model="password"
 | |
|                   :type="showPassword ? 'text' : 'password'"
 | |
|                   clearable
 | |
|                   :placeholder="$t('collectCode.login.passwordPlaceholder')"
 | |
|               >
 | |
|                 <template #label>
 | |
|                   <div class="text-[16px] text-[#1A1A1A] flex align-center justify-start">
 | |
|                     {{ $t('collectCode.login.password') }}
 | |
|                   </div>
 | |
|                 </template>
 | |
|                 <template #button>
 | |
|                   <div class="flex justify-center items-center">
 | |
|                     <van-icon
 | |
|                         size="20"
 | |
|                         :name="showPassword ? 'eye-o' : 'closed-eye'"
 | |
|                         @click="togglePasswordVisibility"
 | |
|                     />
 | |
|                   </div>
 | |
|                 </template>
 | |
|               </van-field>
 | |
|             </div>
 | |
|             <div class="flex justify-end mt-[10px]">
 | |
|               <div class="text-[14px] text-[#2B53AC]" @click="changeToPwd">
 | |
|                 {{ loginType === 0 ? $t('collectCode.login.passwordLogin') : $t('collectCode.login.codeLogin') }}
 | |
|               </div>
 | |
|             </div>
 | |
|             <div/>
 | |
|           </div>
 | |
|           <div class="mt-[55px]">
 | |
|             <div v-if="loginType === 0">
 | |
|               <van-button :loading="loadingRef.loading1" v-if="phoneNum" :loading-text="$t('collectCode.login.getCode')"
 | |
|                           type="primary" block style="height: 48px" @click="getCode">{{ $t('collectCode.login.getCode') }}
 | |
|               </van-button>
 | |
|               <van-button v-else type="primary" color="#D3D3D3" block style="height: 48px">{{ $t('collectCode.login.getCode') }}</van-button>
 | |
|             </div>
 | |
|             <div v-else>
 | |
|               <van-button type="primary" v-if="password" block :loading="loadingRef.loading2" :loading-text="$t('collectCode.login.login')"
 | |
|                           style="height: 48px;margin-top:10px" @click="goLogin">{{ $t('collectCode.login.login') }}
 | |
|               </van-button>
 | |
|               <van-button v-else type="primary" color="#D3D3D3" block style="height: 48px">{{ $t('collectCode.login.login') }}</van-button>
 | |
|             </div>
 | |
|           </div>
 | |
|         </div>
 | |
|       </van-swipe-item>
 | |
|       <van-swipe-item>
 | |
|         <div v-show="pane === 1">
 | |
|           <div class="flex mb-[16px]">
 | |
|             <div class="text-[16px] text-[#BDBDBD] mr-[10px]">{{ $t('collectCode.login.hasSendTo') }}</div>
 | |
|             <div class="text-[16px] text-[#000]">+86 {{ phoneNum }}</div>
 | |
|           </div>
 | |
|           <van-password-input :value="code" :gutter="10" :mask="false" focused @focus="showKeyboard = true"/>
 | |
|           <div class="flex justify-between">
 | |
|             <div :class="`${countdown>0?'text-#BDBDBD':'text-#2B53AC'}  text-14px`">
 | |
|               {{ $t('collectCode.login.reSend') }}<span v-if="countdown>0">({{ countdown }})</span>
 | |
|             </div>
 | |
|             <div @click="goBack" class="text-#2B53AC text-14px">
 | |
|               {{ $t('collectCode.login.back') }}
 | |
|             </div>
 | |
|           </div>
 | |
|           <div class="mt-[17px]">
 | |
|             <van-button v-if="code.length === 6" type="primary" block :loading="loadingRef.loading2"
 | |
|                         :loading-text="$t('collectCode.login.login')" style="height: 48px" @click="goLogin">
 | |
|               {{ $t('collectCode.login.login') }}
 | |
|             </van-button>
 | |
|             <van-button v-else type="primary" color="#D3D3D3" block style="height: 48px">
 | |
|               {{ $t('collectCode.login.login') }}
 | |
|             </van-button>
 | |
|           </div>
 | |
|         </div>
 | |
|       </van-swipe-item>
 | |
|     </van-swipe>
 | |
|     <van-number-keyboard v-model="code" :show="showKeyboard" @blur="showKeyboard = false"/>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <style scoped lang="scss">
 | |
| :deep(.van-cell.van-field) {
 | |
|   padding-left: 0;
 | |
| }
 | |
| 
 | |
| :deep(.van-password-input) {
 | |
|   margin: 0;
 | |
| }
 | |
| 
 | |
| :deep(.van-password-input__item) {
 | |
|   border: 1px solid #E5E5E5;
 | |
|   width: 41px;
 | |
|   height: 41px;
 | |
| }
 | |
| </style>
 |