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