useInvoice.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { ref, reactive } from 'vue'
  2. import { useRouter } from 'vue-router'
  3. import { showToast, showSuccessToast } from 'vant'
  4. import { getStatusApi, submitInvoiceApplyApi } from '@/services/modules/invoiceInformation'
  5. import { getFaceAuthResultApi } from '@/services/modules/faceRecognition'
  6. import type { PushRecordIdRequest } from '@/services/modules/invoiceInformation/type'
  7. import { useUserStore } from '@/stores/modules/user'
  8. /* ========================== 类型定义 ========================== */
  9. interface ToStatus {
  10. eventStatus?: string
  11. invoiceStatus?: string
  12. isIdImgReady?: boolean
  13. [key: string]: any
  14. }
  15. type FaceAuthRzzt = 'REQUIRED_AUTHENTICATION' | 'NO_REQUIRED_AUTHENTICATION'
  16. interface FaceAuthResultData {
  17. success?: boolean
  18. rzzt?: FaceAuthRzzt
  19. msg?: string
  20. lowCertLevel?: boolean
  21. }
  22. /* ========================== 主 Hook ========================== */
  23. export function useInvoice() {
  24. const userStore = useUserStore()
  25. const router = useRouter()
  26. /* ------------------ 基础状态 ------------------ */
  27. const isLoading = ref(false)
  28. const statusMap = ref<ToStatus>({})
  29. /**
  30. * 是否需要跳转人脸认证页
  31. * REQUIRED_AUTHENTICATION => true
  32. */
  33. const needFaceAuth = ref(false)
  34. /**
  35. * 人脸认证是否已完成 / 无需认证
  36. * NO_REQUIRED_AUTHENTICATION => true
  37. * REQUIRED_AUTHENTICATION => false
  38. */
  39. const faceAuthResult = ref(false)
  40. /* ------------------ 请求参数 ------------------ */
  41. const params = reactive<PushRecordIdRequest>({
  42. pushRecordId: userStore.pushRecordId,
  43. })
  44. /* ============================================================
  45. * 状态获取层
  46. * ============================================================ */
  47. const getStatus = async (): Promise<boolean> => {
  48. if (!params.pushRecordId) return false
  49. isLoading.value = true
  50. try {
  51. const res = await getStatusApi(params)
  52. if (res.code !== 0 || !res.data) return false
  53. statusMap.value = res.data as ToStatus
  54. return true
  55. } catch (err) {
  56. console.error('获取状态失败', err)
  57. showToast('获取开票状态失败,请稍后重试')
  58. return false
  59. } finally {
  60. isLoading.value = false
  61. }
  62. }
  63. /* ============================================================
  64. * 人脸认证状态层
  65. * ============================================================ */
  66. const getFaceAuthResult = async (): Promise<boolean> => {
  67. if (!params.pushRecordId) return false
  68. try {
  69. const res = await getFaceAuthResultApi(params)
  70. // data.success 表示认证任务结果;接口返回成功时仍需根据 rzzt 决定下一步
  71. if (res.code !== 0 || !res.data) return false
  72. const data = res.data as FaceAuthResultData
  73. const rzzt = data.rzzt
  74. // 需要做人脸:按钮可点,但点击后应跳人脸页
  75. needFaceAuth.value = rzzt === 'REQUIRED_AUTHENTICATION'
  76. // 无需认证:视为人脸流程已通过,可以直接提交
  77. faceAuthResult.value = rzzt === 'NO_REQUIRED_AUTHENTICATION'
  78. return true
  79. } catch (err: any) {
  80. console.error('获取认证结果失败', err)
  81. showToast(err?.message || '获取认证结果失败,请稍后重试')
  82. return false
  83. }
  84. }
  85. /* ============================================================
  86. * 核心提交逻辑
  87. * ============================================================ */
  88. const doSubmitInvoice = async (): Promise<boolean> => {
  89. if (!params.pushRecordId) {
  90. showToast('参数异常')
  91. return false
  92. }
  93. try {
  94. const res = await submitInvoiceApplyApi(params)
  95. if (res.code === 0 && res.data) {
  96. showSuccessToast('提交成功')
  97. setTimeout(() => {
  98. userStore.LogOut()
  99. router.replace({ path: '/success' })
  100. }, 800)
  101. return true
  102. }
  103. showToast(res.msg || '提交失败')
  104. return false
  105. } catch (err: any) {
  106. console.error('提交失败', err)
  107. showToast(err?.message || '提交失败')
  108. return false
  109. }
  110. }
  111. /* ============================================================
  112. * 流程场景提交
  113. * ============================================================ */
  114. const submitInvoiceForce = async () => {
  115. return await doSubmitInvoice()
  116. }
  117. /* ========================== 暴露 API ========================== */
  118. return {
  119. /* 状态 */
  120. statusMap,
  121. isLoading,
  122. /**
  123. * 是否需要去人脸页
  124. */
  125. needFaceAuth,
  126. /**
  127. * 人脸是否完成 / 无需认证
  128. */
  129. faceAuthResult,
  130. /* 状态获取 */
  131. getStatus,
  132. getFaceAuthResult,
  133. /* 提交 */
  134. submitInvoiceForce,
  135. }
  136. }