@tplc/business
Version:
79 lines (75 loc) • 1.83 kB
text/typescript
import { commitOrder, queryOrderPaymentStatus, type CommitPageDetailParams } from '../api/pay'
import { onPageHide } from '@dcloudio/uni-app'
import { IResData } from '../action'
import { onUnmounted, ref } from 'vue'
const usePay = (
fun?: (data: unknown) => Promise<IResData<any>>,
queryStatusFun?: (orderNo: string) => Promise<any>,
) => {
const successFun = ref()
let pollingTimer: NodeJS.Timeout | null = null
const runAsync = async (orderNo: string) => {
try {
const { data, status } = await (queryStatusFun || queryOrderPaymentStatus)(orderNo)
if (status === 1 || data?.status === 1) {
uni.hideLoading()
cancel()
successFun.value?.()
} else {
// 继续轮询
pollingTimer = setTimeout(() => {
runAsync(orderNo)
}, 1000)
}
} catch (error) {
// 出错时停止轮询
cancel()
}
}
const cancel = () => {
if (pollingTimer) {
clearTimeout(pollingTimer)
pollingTimer = null
}
}
const pay = async (
data: CommitPageDetailParams,
options?: {
onSuccess?: () => void
onError?: () => void
},
) => {
const {
data: { orderNo, paymentParams, wakePayment },
} = await (fun || commitOrder)(data)
if (!wakePayment) {
options?.onSuccess?.()
runAsync(orderNo)
return
}
uni.showLoading({
title: 'loading...',
mask: true,
})
successFun.value = options?.onSuccess
uni.requestPayment({
provider: 'wxpay',
...paymentParams,
success: () => {
runAsync(orderNo)
},
fail: () => {
options?.onError?.()
uni.hideLoading()
},
})
}
onPageHide(() => {
cancel?.()
})
onUnmounted(() => {
cancel?.()
})
return [pay]
}
export default usePay