import { ref, reactive } from 'vue' import { useRouter } from 'vue-router' import { showToast, showSuccessToast } from 'vant' import { getStatusApi, submitInvoiceApplyApi } from '@/services/modules/invoiceInformation' import { getFaceAuthResultApi } from '@/services/modules/faceRecognition' import type { PushRecordIdRequest } from '@/services/modules/invoiceInformation/type' import { useUserStore } from '@/stores/modules/user' /* ========================== 类型定义 ========================== */ interface ToStatus { eventStatus?: string invoiceStatus?: string isIdImgReady?: boolean [key: string]: any } type FaceAuthRzzt = 'REQUIRED_AUTHENTICATION' | 'NO_REQUIRED_AUTHENTICATION' interface FaceAuthResultData { success?: boolean rzzt?: FaceAuthRzzt msg?: string lowCertLevel?: boolean } /* ========================== 主 Hook ========================== */ export function useInvoice() { const userStore = useUserStore() const router = useRouter() /* ------------------ 基础状态 ------------------ */ const isLoading = ref(false) const statusMap = ref({}) /** * 是否需要跳转人脸认证页 * REQUIRED_AUTHENTICATION => true */ const needFaceAuth = ref(false) /** * 人脸认证是否已完成 / 无需认证 * NO_REQUIRED_AUTHENTICATION => true * REQUIRED_AUTHENTICATION => false */ const faceAuthResult = ref(false) /* ------------------ 请求参数 ------------------ */ const params = reactive({ pushRecordId: userStore.pushRecordId, }) /* ============================================================ * 状态获取层 * ============================================================ */ const getStatus = async (): Promise => { if (!params.pushRecordId) return false isLoading.value = true try { const res = await getStatusApi(params) if (res.code !== 0 || !res.data) return false statusMap.value = res.data as ToStatus return true } catch (err) { console.error('获取状态失败', err) showToast('获取开票状态失败,请稍后重试') return false } finally { isLoading.value = false } } /* ============================================================ * 人脸认证状态层 * ============================================================ */ const getFaceAuthResult = async (): Promise => { if (!params.pushRecordId) return false try { const res = await getFaceAuthResultApi(params) // data.success 表示认证任务结果;接口返回成功时仍需根据 rzzt 决定下一步 if (res.code !== 0 || !res.data) return false const data = res.data as FaceAuthResultData const rzzt = data.rzzt // 需要做人脸:按钮可点,但点击后应跳人脸页 needFaceAuth.value = rzzt === 'REQUIRED_AUTHENTICATION' // 无需认证:视为人脸流程已通过,可以直接提交 faceAuthResult.value = rzzt === 'NO_REQUIRED_AUTHENTICATION' return true } catch (err: any) { console.error('获取认证结果失败', err) showToast(err?.message || '获取认证结果失败,请稍后重试') return false } } /* ============================================================ * 核心提交逻辑 * ============================================================ */ const doSubmitInvoice = async (): Promise => { if (!params.pushRecordId) { showToast('参数异常') return false } try { const res = await submitInvoiceApplyApi(params) if (res.code === 0 && res.data) { showSuccessToast('提交成功') setTimeout(() => { userStore.LogOut() router.replace({ path: '/success' }) }, 800) return true } showToast(res.msg || '提交失败') return false } catch (err: any) { console.error('提交失败', err) showToast(err?.message || '提交失败') return false } } /* ============================================================ * 流程场景提交 * ============================================================ */ const submitInvoiceForce = async () => { return await doSubmitInvoice() } /* ========================== 暴露 API ========================== */ return { /* 状态 */ statusMap, isLoading, /** * 是否需要去人脸页 */ needFaceAuth, /** * 人脸是否完成 / 无需认证 */ faceAuthResult, /* 状态获取 */ getStatus, getFaceAuthResult, /* 提交 */ submitInvoiceForce, } }