Merge branch 'qb' of https://gitea-inner.fontree.cn/scout666/liveh5-nuxt
This commit is contained in:
commit
8b144a270c
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
export const useAppFooterRouteNames= ['index', 'profile']
|
export const useAppFooterRouteNames= ['home', 'profile']
|
||||||
export const useAppHeaderRouteNames= ['index', 'profile','login']
|
export const useAppHeaderRouteNames= ['home', 'profile','login','collectCode-login','collectCode-mine']
|
||||||
|
211
app/pages/collectCode/login/index.vue
Normal file
211
app/pages/collectCode/login/index.vue
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<script setup>
|
||||||
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { senCode, userLogin } from "@/api/auth/index.js";
|
||||||
|
import { authStore } from "~/stores/auth/index.js";
|
||||||
|
import { message } from '@/components/x-message/useMessage.js'
|
||||||
|
// ... 现有导入 ...
|
||||||
|
import FingerprintJS from '@fingerprintjs/fingerprintjs'
|
||||||
|
const { userInfo, token,fingerprint } = authStore()
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const { locale } = useI18n()
|
||||||
|
definePageMeta({
|
||||||
|
title: '登录',
|
||||||
|
i18n: 'login.title',
|
||||||
|
})
|
||||||
|
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 senCode({
|
||||||
|
telNum: phoneNum.value,
|
||||||
|
zone: '86'
|
||||||
|
})
|
||||||
|
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 userLogin({
|
||||||
|
telNum: phoneNum.value,
|
||||||
|
zone: '86',
|
||||||
|
code: 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
|
||||||
|
}
|
||||||
|
|
||||||
|
</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('login.phonePlaceholder')">
|
||||||
|
<template #label>
|
||||||
|
<div class="text-[16px] text-[#1A1A1A] flex align-center justify-start">
|
||||||
|
手机号
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="border-b-[1.7px] mt-[8px]" v-show="loginType === 1">
|
||||||
|
<van-field v-model="password" clearable :placeholder="$t('login.passwordPlaceholder')">
|
||||||
|
<template #label>
|
||||||
|
<div class="text-[16px] text-[#1A1A1A] flex align-center justify-start">
|
||||||
|
密码
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end mt-[10px]" @click="changeToPwd">
|
||||||
|
<div class="text-[14px] text-[#2B53AC]">
|
||||||
|
{{ loginType === 0 ? '密码登录' : '验证码登录' }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
|
<div class="mt-[55px]">
|
||||||
|
<div v-if="loginType === 0">
|
||||||
|
<van-button :loading="loadingRef.loading1" v-if="phoneNum" :loading-text="$t('login.getCode')"
|
||||||
|
type="primary" block style="height: 48px" @click="getCode">{{ $t('login.getCode')
|
||||||
|
}}</van-button>
|
||||||
|
<van-button v-else type="primary" color="#D3D3D3" block style="height: 48px">{{
|
||||||
|
$t('login.getCode')
|
||||||
|
}}</van-button>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<van-button type="primary" v-if="password" block :loading="loadingRef.loading2" :loading-text="$t('login.login')"
|
||||||
|
style="height: 48px;margin-top:10px" @click="goLogin">{{
|
||||||
|
$t('login.login')
|
||||||
|
}}</van-button>
|
||||||
|
<van-button v-else type="primary" color="#D3D3D3" block style="height: 48px">{{
|
||||||
|
$t('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('login.hasSendTo') }}</div>
|
||||||
|
<div class="text-[16px] text-[#000]">+{{ selectedZone }} {{ phoneNum }}</div>
|
||||||
|
</div>
|
||||||
|
<van-password-input :value="code" :gutter="10" :mask="false" focused @focus="showKeyboard = true" />
|
||||||
|
<div :class="`${countdown > 0 ? 'text-#BDBDBD' : 'text-#2B53AC'} text-14px`">
|
||||||
|
{{ $t('login.reSend') }}<span v-if="countdown > 0">({{ countdown }})</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-[17px]">
|
||||||
|
|
||||||
|
<van-button v-if="code.length === 6" type="primary" block :loading="loadingRef.loading2"
|
||||||
|
:loading-text="$t('login.login')" style="height: 48px" @click="goLogin">{{
|
||||||
|
$t('login.login')
|
||||||
|
}}</van-button>
|
||||||
|
<van-button v-else type="primary" color="#D3D3D3" block style="height: 48px">{{
|
||||||
|
$t('login.login')
|
||||||
|
}}</van-button>
|
||||||
|
</div>
|
||||||
|
<div class="mt-[17px]">
|
||||||
|
<van-button type="primary" @click="goBack" block style="height: 48px">{{ $t('login.back')
|
||||||
|
}}</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>
|
55
app/pages/collectCode/mine/index.vue
Normal file
55
app/pages/collectCode/mine/index.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<script setup>
|
||||||
|
import { userArtworks } from "~/api/goods/index.js";
|
||||||
|
import { authStore } from "~/stores/auth/index.js";
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'default',
|
||||||
|
title: '收款二维码',
|
||||||
|
i18n: 'menu.profile',
|
||||||
|
})
|
||||||
|
const { userInfo } = authStore()
|
||||||
|
const initData = async () => {
|
||||||
|
const res = await userArtworks({})
|
||||||
|
if (res.status === 0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initData()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-[100vw] bg-[url('@/static/images/3532@2x.png')] bg-cover pt-43px flex-grow-1 flex flex-col">
|
||||||
|
<div class="flex items-center px-16px mb-43px">
|
||||||
|
<div class="mr-23px">
|
||||||
|
<img class="w-57px h-57px" src="@/static/images/5514@2x.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="text-18px text-#181818">{{ userInfo.realName }}</div>
|
||||||
|
<div class="text-#575757 text-14px">{{ userInfo.telNum }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1 flex justify-end">
|
||||||
|
<img class="w-40px h-40px" src="@/static/images/logout.png" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div class="border-b-1px border-b-#D3D3D3 px-16px flex">
|
||||||
|
<div class="text-#000 text-16px border-b-3 border-b-#2B53AC h-36px">线下付款二维码 </div>
|
||||||
|
</div>
|
||||||
|
<van-pull-refresh>
|
||||||
|
<van-list finished-text="没有更多了">
|
||||||
|
<van-swipe-cell>
|
||||||
|
|
||||||
|
<van-cell :border="false" title="单元格" value="内容" />
|
||||||
|
<template #right>
|
||||||
|
<van-button square type="danger" text="删除" />
|
||||||
|
<van-button square type="primary" text="收藏" />
|
||||||
|
</template>
|
||||||
|
</van-swipe-cell>
|
||||||
|
</van-list>
|
||||||
|
</van-pull-refresh>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
BIN
app/static/images/logout.png
Normal file
BIN
app/static/images/logout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
app/static/images/qrcodetext.png
Normal file
BIN
app/static/images/qrcodetext.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
@ -3,9 +3,11 @@ export const authStore = createGlobalState(() => {
|
|||||||
const token=useLocalStorage('token','')
|
const token=useLocalStorage('token','')
|
||||||
const RefreshToken=useLocalStorage('RefreshToken','')
|
const RefreshToken=useLocalStorage('RefreshToken','')
|
||||||
const userInfo=useLocalStorage('userInfo',{})
|
const userInfo=useLocalStorage('userInfo',{})
|
||||||
|
const fingerprint=useLocalStorage('fingerprint','')
|
||||||
return{
|
return{
|
||||||
userInfo,
|
userInfo,
|
||||||
RefreshToken,
|
RefreshToken,
|
||||||
token
|
token,
|
||||||
|
fingerprint
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -17,6 +17,8 @@
|
|||||||
"start": "cross-env ENV_FILE=.env.prod nuxt start"
|
"start": "cross-env ENV_FILE=.env.prod nuxt start"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fingerprintjs/fingerprintjs": "^4.5.1",
|
||||||
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@nuxtjs/i18n": "^9.1.1",
|
"@nuxtjs/i18n": "^9.1.1",
|
||||||
"@vueuse/core": "^12.4.0",
|
"@vueuse/core": "^12.4.0",
|
||||||
"@yeger/vue-masonry-wall": "^5.0.17",
|
"@yeger/vue-masonry-wall": "^5.0.17",
|
||||||
|
@ -11,6 +11,12 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@fingerprintjs/fingerprintjs':
|
||||||
|
specifier: ^4.5.1
|
||||||
|
version: 4.5.1
|
||||||
|
'@nuxtjs/color-mode':
|
||||||
|
specifier: ^3.5.2
|
||||||
|
version: 3.5.2(magicast@0.3.5)(rollup@4.29.1)
|
||||||
'@nuxtjs/i18n':
|
'@nuxtjs/i18n':
|
||||||
specifier: ^9.1.1
|
specifier: ^9.1.1
|
||||||
version: 9.1.1(@vue/compiler-dom@3.5.13)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))
|
version: 9.1.1(@vue/compiler-dom@3.5.13)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))
|
||||||
@ -720,6 +726,8 @@ packages:
|
|||||||
'@fastify/accept-negotiator@1.1.0':
|
'@fastify/accept-negotiator@1.1.0':
|
||||||
resolution: {integrity: sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ==}
|
resolution: {integrity: sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
'@fingerprintjs/fingerprintjs@4.5.1':
|
||||||
|
resolution: {integrity: sha512-hKJaRoLHNeUUPhb+Md3pTlY/Js2YR4aXjroaDHpxrjoM8kGnEFyZVZxXo6l3gRyKnQN52Uoqsycd3M73eCdMzw==}
|
||||||
|
|
||||||
'@humanfs/core@0.19.1':
|
'@humanfs/core@0.19.1':
|
||||||
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
||||||
@ -3979,6 +3987,9 @@ packages:
|
|||||||
ts-interface-checker@0.1.13:
|
ts-interface-checker@0.1.13:
|
||||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||||
|
|
||||||
|
tslib@2.8.1:
|
||||||
|
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||||
|
|
||||||
tsx@4.19.2:
|
tsx@4.19.2:
|
||||||
resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
|
resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
@ -4923,6 +4934,9 @@ snapshots:
|
|||||||
|
|
||||||
'@fastify/accept-negotiator@1.1.0':
|
'@fastify/accept-negotiator@1.1.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
'@fingerprintjs/fingerprintjs@4.5.1':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@humanfs/core@0.19.1': {}
|
'@humanfs/core@0.19.1': {}
|
||||||
|
|
||||||
@ -8922,6 +8936,8 @@ snapshots:
|
|||||||
|
|
||||||
ts-interface-checker@0.1.13: {}
|
ts-interface-checker@0.1.13: {}
|
||||||
|
|
||||||
|
tslib@2.8.1: {}
|
||||||
|
|
||||||
tsx@4.19.2:
|
tsx@4.19.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.23.1
|
esbuild: 0.23.1
|
||||||
|
Loading…
Reference in New Issue
Block a user