Explorar el Código

优化开票流程状态判断与按钮禁用逻辑

调整状态判断方式,提升流程准确性,避免重复提交
重构按钮禁用为计算属性,增强交互体验
删除多余日志,简化界面代码
yuanmingze hace 1 mes
padre
commit
e7ed10933e

+ 48 - 50
src/hooks/useInvoice.ts

@@ -1,38 +1,41 @@
-import { ref, reactive } from 'vue'
+import { ref, reactive, computed } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
 import { showToast, showSuccessToast } from 'vant'
 import { getStatusApi, submitInvoiceApplyApi } from '@/services/modules/invoiceInformation'
-import type { PushRecordIdRequest } from '@/services/modules/invoiceInformation/type.d.ts'
+import type { PushRecordIdRequest } from '@/services/modules/invoiceInformation/type'
 import { useUserStore } from '@/stores/modules/user'
 import { getFaceAuthResultApi } from '@/services/modules/faceRecognition'
 
 interface ToStatus {
-  /** 待处理事件 */
   eventStatus?: string
-  /** 开票状态 */
   invoiceStatus?: string
-  /** 是否上传身份证图片 */
   isIdImgReady?: boolean
-  [property: string]: any
+  [key: string]: any
 }
 
-/**
- * 发票状态 Hook
- * 用于复用:状态查询 + 提交开票申请
- */
 export function useInvoice() {
   const userStore = useUserStore()
   const router = useRouter()
-
   const route = useRoute()
 
-  // state
-  const btnDisabled = ref(false)
-  const statusMap = ref<ToStatus>({})
   const isLoading = ref(false)
+  const statusMap = ref<ToStatus>({})
+
+  // 是否允许继续流程(状态层面)
+  const statusReady = ref(false)
+
+  // 人脸认证是否通过 / 不需要
+  const faceAuthReady = ref(false)
+
+  // 默认 true(不可点)
+  const btnDisabled = computed(() => {
+    return !(statusReady.value && faceAuthReady.value)
+  })
+
+  /** ===================== 常量 ===================== */
 
-  // 已提交状态映射
   const isSubmitStatusMap = ['PENDING', 'FINISHED', 'RED_INK_ENTRY', 'NOT_APPROVED', 'DISCARD']
+
   const isSubmitEventStatusMap = [
     'SUBMITTED',
     'PENDING_PAYMENT',
@@ -43,46 +46,45 @@ 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) {
-        const rzzt = res.data.rzzt
-        // 已认证或无需认证提交跳转
-        if (rzzt === 'NO_REQUIRED_AUTHENTICATION') {
-          faceAuthResult.value = true
-        }
+
+      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 || '获取认证结果失败,请稍后重试')
-      btnDisabled.value = true
+      showToast(err?.message || '获取认证结果失败,请稍后重试')
     }
   }
 
-  /**
-   * 获取开票状态
-   */
   const getStatus = async () => {
     isLoading.value = true
     try {
       const res = await getStatusApi(params)
-      if (res.code === 0) {
-        statusMap.value = res.data as ToStatus
-        //  判断当前是否已提交
-        const { invoiceStatus, eventStatus } = res.data
-        const isInvoiceSubmitted = invoiceStatus && isSubmitStatusMap.includes(invoiceStatus)
-        const isEventSubmitted = eventStatus && isSubmitEventStatusMap.includes(eventStatus)
-        btnDisabled.value = isInvoiceSubmitted && isEventSubmitted
-      }
+      if (res.code !== 0) return
+
+      statusMap.value = res.data as ToStatus
+
+      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)
       showToast('获取开票状态失败,请稍后重试')
@@ -91,14 +93,12 @@ export function useInvoice() {
     }
   }
 
-  /**
-   * 提交开票申请
-   */
   const submitInvoiceApply = async () => {
+    if (btnDisabled.value) return
+
     try {
-      // 1. 提交流程
       const res = await submitInvoiceApplyApi(params)
-      // 2. 成功逻辑
+
       if (res.code === 0 && res.data) {
         showSuccessToast('提交成功')
         setTimeout(() => {
@@ -107,20 +107,16 @@ export function useInvoice() {
         }, 800)
         return
       }
-      // 3. 失败逻辑(接口返回的错误)
+
       showToast(res.msg)
     } catch (err: any) {
-      // 4. 异常逻辑
       console.error('提交失败', err)
-      showToast(err.message)
+      showToast(err?.message || '提交失败')
     }
 
-    // 5. 失败后统一处理 —— 判断当前页面是否需要跳转
     if (route.path !== '/h5/invoice-information/index') {
       setTimeout(() => {
-        router.replace({
-          path: '/invoice-information',
-        })
+        router.replace({ path: '/invoice-information' })
       }, 1800)
     }
   }
@@ -128,11 +124,13 @@ export function useInvoice() {
   return {
     params,
     statusMap,
-    btnDisabled,
     isLoading,
+
     faceAuthResult,
+    btnDisabled,
+
     getStatus,
-    submitInvoiceApply,
     getFaceAuthResult,
+    submitInvoiceApply,
   }
 }

+ 0 - 1
src/views/face-recognition/index.vue

@@ -41,7 +41,6 @@ const getConfirmInvoiceInfo = async () => {
 
   const res = await getFaceAuthInfoApi(params)
   if (res.code === 0 && res.data?.faceAuthUrl) {
-    console.log('faceAuthUrl:', res.data.faceAuthUrl)
     // 直接跳转进行人脸识别
     window.location.href = res.data.faceAuthUrl
   } else {

+ 1 - 0
src/views/invoice-information/index.vue

@@ -188,6 +188,7 @@ const getConfirmInvoiceInfo = async () => {
  * 使用 hooks 提供的状态进行判断
  */
 const handleNext = async () => {
+  if (btnDisabled.value) return
   // 未上传身份证,跳转上传页
   if (!statusMap.value.isIdImgReady) {
     return router.push({ path: '/identity-upload' })

+ 1 - 0
src/views/pedding-face-recognition/index.vue

@@ -76,6 +76,7 @@ const lowCertLevelDialog = ref(false)
 const getFaceAuthResult = async () => {
   try {
     const res = await getFaceAuthResultApi(params)
+
     if (res.code === 0 && res.data.lowCertLevel) {
       lowCertLevelDialog.value = true
       return