import type { RouteLocationNormalizedLoaded, Router } from 'vue-router' import { runLogic } from '@af-mobile-client-vue3/services/api/common' import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting' import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user' import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil' import { showFailToast, showSuccessToast } from 'vant' import { ref } from 'vue' export function useFaceLogin() { const setting = useSettingStore() const userState = useUserStore() const loading = ref(false) async function isFaceRecognition() { return await new Promise<{ success: boolean, embedding: number[] }>((resolve) => { mobileUtil.execute({ param: { scene: '面部识别认证', liveness: 'nod', }, funcName: 'verifyFace', callbackFunc: async (result: any) => { if (result.status === 'success' && result.data?.embedding) { resolve({ success: true, embedding: result.data.embedding }) return } resolve({ success: false, embedding: null }) }, }) }) } function startIntervalFaceRecognition() { mobileUtil.execute({ param: { scene: '面部识别认证', liveness: 'nod', intervalMinutes: setting.getSetting()?.faceIntervalMinutes || 1, retryCount: setting.getSetting()?.faceRetryCount || 3, }, funcName: 'startPeriodicFaceVerify', callbackFunc: async (result: any) => { if (result.status === 'success' && result.data.success && !result.data.success) { showSuccessToast('认证成功') } else if (result.status === 'success' && !result.data.success) { showFailToast('面部识别认证失败, 请重新登录') mobileUtil.execute({ param: {}, funcName: 'stopPeriodicFaceVerify', callbackFunc: async () => {}, }) userState.logout() } }, }) } async function matchFaceEmbedding(userId: string, embedding: number[]) { const matchRes = await runLogic('matchFaceEmbedding', { userId, embedding, }, 'af-system') as any return matchRes } function isFaceRecognitionEnabled(): boolean { return setting.getSetting()?.isFaceRecognition ?? false } async function handleLoginSuccess(userId: string, route: RouteLocationNormalizedLoaded, router: Router) { const faceRes = await isFaceRecognition() if (!faceRes.success) { showFailToast('面部识别认证失败') return false } const matchRes = await matchFaceEmbedding(userId, faceRes.embedding) if (!matchRes.isMatch) { showFailToast(matchRes.msg || '面部识别认证失败') return false } const toPath = decodeURIComponent((route.query?.redirect || '/') as string) if (route.name === '/login') await router.replace('/') else await router.replace(toPath) if (setting.getSetting()?.intervalFaceRecognition) { startIntervalFaceRecognition() } return true } return { loading, isFaceRecognition, startIntervalFaceRecognition, matchFaceEmbedding, isFaceRecognitionEnabled, handleLoginSuccess, } }