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('')
|
|
const code = ref('')
|
|
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>
|