1
0

2 Коммитууд 57df9709b9 ... 919bb87e2e

Эзэн SHA1 Мессеж Огноо
  yuanmingze 919bb87e2e Merge branch 'feature/faceid-risk/20260206' into pre 1 сар өмнө
  yuanmingze ab480c592a 优化提交逻辑 1 сар өмнө

+ 99 - 43
src/hooks/useInvoice.ts

@@ -1,10 +1,12 @@
 import { ref, reactive, computed } from 'vue'
-import { useRouter, useRoute } from 'vue-router'
+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'
-import { getFaceAuthResultApi } from '@/services/modules/faceRecognition'
+
+/* ========================== 类型定义 ========================== */
 
 interface ToStatus {
   eventStatus?: string
@@ -13,26 +15,43 @@ interface ToStatus {
   [key: string]: any
 }
 
+/* ========================== 主 Hook ========================== */
+
 export function useInvoice() {
   const userStore = useUserStore()
   const router = useRouter()
-  const route = useRoute()
+
+  /* ------------------ 基础状态 ------------------ */
 
   const isLoading = ref(false)
   const statusMap = ref<ToStatus>({})
 
-  // 是否允许继续流程(状态层面)
+  // 状态层面是否允许继续流程
   const statusReady = ref(false)
 
-  // 人脸认证是否通过 / 不需要
+  // 人脸认证接口是否已经返回成功
   const faceAuthReady = ref(false)
 
-  // 默认 true(不可点)
+  // 人脸是否“通过或无需认证”
+  const faceAuthResult = ref(false)
+
+  /* ------------------ UI 控制层 ------------------ */
+
+  /**
+   * 仅用于按钮禁用控制
+   * 不参与真实业务逻辑
+   */
   const btnDisabled = computed(() => {
     return !(statusReady.value && faceAuthReady.value)
   })
 
-  /** ===================== 常量 ===================== */
+  /* ------------------ 请求参数 ------------------ */
+
+  const params = reactive<PushRecordIdRequest>({
+    pushRecordId: userStore.pushRecordId,
+  })
+
+  /* ------------------ 常量映射 ------------------ */
 
   const isSubmitStatusMap = ['PENDING', 'FINISHED', 'RED_INK_ENTRY', 'NOT_APPROVED', 'DISCARD']
 
@@ -46,31 +65,13 @@ export function useInvoice() {
     'INVOICE_DOWNLOADABLE',
   ]
 
-  const params = reactive<PushRecordIdRequest>({
-    pushRecordId: userStore.pushRecordId,
-  })
-
-  const faceAuthResult = ref(false)
-
-  const getFaceAuthResult = async () => {
-    try {
-      const res = await getFaceAuthResultApi(params)
-
-      if (res.code !== 0 || !res.data?.success) return
-
-      const rzzt = res.data.rzzt
-      faceAuthReady.value = true
-
-      if (rzzt === 'NO_REQUIRED_AUTHENTICATION') {
-        faceAuthResult.value = true
-      }
-    } catch (err: any) {
-      console.error('获取认证结果失败', err)
-      showToast(err?.message || '获取认证结果失败,请稍后重试')
-    }
-  }
+  /* ============================================================
+   * 状态获取层
+   * ============================================================ */
 
   const getStatus = async () => {
+    if (!params.pushRecordId) return
+
     isLoading.value = true
     try {
       const res = await getStatusApi(params)
@@ -81,9 +82,10 @@ export function useInvoice() {
       const { invoiceStatus, eventStatus } = res.data
 
       const isInvoiceSubmitted = !!invoiceStatus && isSubmitStatusMap.includes(invoiceStatus)
+
       const isEventSubmitted = !!eventStatus && isSubmitEventStatusMap.includes(eventStatus)
 
-      // 只有「未提交」才允许继续
+      // 只有未提交状态才允许继续
       statusReady.value = !(isInvoiceSubmitted && isEventSubmitted)
     } catch (err) {
       console.error('获取状态失败', err)
@@ -93,41 +95,95 @@ export function useInvoice() {
     }
   }
 
-  const submitInvoiceApply = async () => {
-    if (btnDisabled.value) return
+  /* ============================================================
+   * 人脸认证状态层
+   * ============================================================ */
+
+  const getFaceAuthResult = async () => {
+    if (!params.pushRecordId) return
+
+    try {
+      const res = await getFaceAuthResultApi(params)
+
+      if (res.code !== 0 || !res.data?.success) return
+
+      faceAuthReady.value = true
+
+      if (res.data.rzzt === 'NO_REQUIRED_AUTHENTICATION') {
+        faceAuthResult.value = true
+      }
+    } catch (err: any) {
+      console.error('获取认证结果失败', err)
+      showToast(err?.message || '获取认证结果失败,请稍后重试')
+    }
+  }
+
+  /* ============================================================
+   * 核心提交逻辑(纯业务)
+   * ⚠ 不依赖任何 UI 计算属性
+   * ============================================================ */
+
+  const doSubmitInvoice = async (): Promise<boolean> => {
+    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
+
+        return true
       }
-      showToast(res.msg)
+
+      showToast(res.msg || '提交失败')
+      return false
     } catch (err: any) {
       console.error('提交失败', err)
       showToast(err?.message || '提交失败')
+      return false
     }
+  }
 
-    if (route.path !== '/h5/invoice-information/index') {
-      setTimeout(() => {
-        router.replace({ path: '/invoice-information' })
-      }, 1800)
-    }
+  /* ============================================================
+   * UI 场景提交(按钮点击)
+   * ============================================================ */
+
+  const submitInvoiceWithGuard = async () => {
+    if (btnDisabled.value) return false
+    return await doSubmitInvoice()
+  }
+
+  /* ============================================================
+   * 流程场景提交(loading页/自动流程)
+   * ============================================================ */
+
+  const submitInvoiceForce = async () => {
+    return await doSubmitInvoice()
   }
 
+  /* ========================== 暴露 API ========================== */
+
   return {
-    params,
+    /* 状态 */
     statusMap,
     isLoading,
-
     faceAuthResult,
     btnDisabled,
 
+    /* 状态获取 */
     getStatus,
     getFaceAuthResult,
-    submitInvoiceApply,
+
+    /* 提交 */
+    submitInvoiceWithGuard, // 按钮用
+    submitInvoiceForce, // 流程自动用
   }
 }

+ 2 - 1
src/stores/modules/user.ts

@@ -31,9 +31,10 @@ export const useUserStore = defineStore('user', {
       this.needFaceId = false
     },
   },
+
   persist: {
     key: 'user-store',
-    storage: localStorage,
+    storage: sessionStorage,
     pick: ['access_token', 'needFaceId', 'tenant_id', 'pushRecordId'],
   },
 })

+ 2 - 2
src/views/identity-upload/index.vue

@@ -81,7 +81,7 @@ import { useInvoice } from '@/hooks/useInvoice'
 import type { UpdateH5IdcardInfoRequest } from '@/services/modules/identityUpload/type.d'
 
 // --- 初始化 Hooks ---
-const { getStatus, submitInvoiceApply, getFaceAuthResult, faceAuthResult } = useInvoice()
+const { getStatus, submitInvoiceForce, getFaceAuthResult, faceAuthResult } = useInvoice()
 const userStore = useUserStore()
 /** 上传项类型 */
 interface UploadFileItem {
@@ -200,7 +200,7 @@ const handleNext = async () => {
         return router.push({ path: '/face-recognition' })
       }
       // 其他情况,直接提交
-      await submitInvoiceApply()
+      await submitInvoiceForce()
     }
   } catch (err: any) {
     const { message } = err

+ 9 - 3
src/views/invoice-information/index.vue

@@ -152,8 +152,14 @@ import ModernDialog from '@/components/ModernDialog.vue'
 // ✅ 使用封装好的 Hook
 import { useInvoice } from '@/hooks/useInvoice'
 // --- 初始化 Hooks ---
-const { getStatus, submitInvoiceApply, getFaceAuthResult, btnDisabled, statusMap, faceAuthResult } =
-  useInvoice()
+const {
+  getStatus,
+  submitInvoiceWithGuard,
+  getFaceAuthResult,
+  btnDisabled,
+  statusMap,
+  faceAuthResult,
+} = useInvoice()
 
 // --- 其余本页面独有逻辑 ---
 const userStore = useUserStore()
@@ -200,7 +206,7 @@ const handleNext = async () => {
   }
 
   // 其他情况,直接提交
-  await submitInvoiceApply()
+  await submitInvoiceWithGuard()
 }
 
 const rejectAndReturnDialog = ref(false)

+ 2 - 2
src/views/pedding-face-recognition/index.vue

@@ -62,7 +62,7 @@ const userStore = useUserStore()
 const router = useRouter()
 
 // --- 初始化 Hooks ---
-const { submitInvoiceApply } = useInvoice()
+const { submitInvoiceForce } = useInvoice()
 
 const loadingSize = '10vw'
 const loadingColor = '#1677ff'
@@ -86,7 +86,7 @@ const getFaceAuthResult = async () => {
       const rzzt = res.data.rzzt
       // 已认证或无需认证提交跳转
       if (rzzt === 'NO_REQUIRED_AUTHENTICATION') {
-        submitInvoiceApply()
+        submitInvoiceForce()
         return
       }
     } else {