usePaybackResultPopup.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { computed, reactive, readonly, ref } from 'vue'
  2. export type PaybackScene
  3. = | 'payment-success'
  4. | 'payment-failed'
  5. | 'topup-success'
  6. | 'topup-failed'
  7. export interface PaybackResultState {
  8. visible: boolean
  9. scene: PaybackScene
  10. coins: number | null
  11. }
  12. export interface PaybackResultOptions {
  13. scene: PaybackScene
  14. coins?: number
  15. onPrimary?: () => void
  16. onSecondary?: () => void
  17. }
  18. const state = reactive<PaybackResultState>({
  19. visible: false,
  20. scene: 'payment-success',
  21. coins: null,
  22. })
  23. const primaryHandler = ref<(() => void) | null>(null)
  24. const secondaryHandler = ref<(() => void) | null>(null)
  25. const isSuccess = computed(
  26. () =>
  27. state.scene === 'payment-success' || state.scene === 'topup-success',
  28. )
  29. const isPayment = computed(
  30. () =>
  31. state.scene === 'payment-success' || state.scene === 'payment-failed',
  32. )
  33. const open = (options: PaybackResultOptions) => {
  34. state.scene = options.scene
  35. state.coins = options.coins ?? null
  36. primaryHandler.value = options.onPrimary ?? null
  37. secondaryHandler.value = options.onSecondary ?? null
  38. state.visible = true
  39. }
  40. const close = () => {
  41. state.visible = false
  42. }
  43. const handlePrimary = () => {
  44. const handler = primaryHandler.value
  45. if (handler) {
  46. handler()
  47. }
  48. state.visible = false
  49. }
  50. const handleSecondary = () => {
  51. const handler = secondaryHandler.value
  52. if (handler) {
  53. handler()
  54. }
  55. state.visible = false
  56. }
  57. const handlePaymentSuccessOpen = ({ coins, orderId }: { coins: number, orderId: string }) => {
  58. const router = useRouter()
  59. const route = useRoute()
  60. open({
  61. scene: 'payment-success',
  62. coins,
  63. onPrimary: async () => {
  64. if (route.query.code) {
  65. const query = { ...route.query }
  66. delete query.code
  67. await router.replace({
  68. path: route.path,
  69. query,
  70. })
  71. }
  72. router.push(`/order/detail?id=${orderId}`)
  73. },
  74. })
  75. }
  76. const handleTopupOpen = ({ status, coins }: { status: boolean, coins: number }) => {
  77. if (status) {
  78. open({
  79. scene: 'topup-success',
  80. coins,
  81. onPrimary: () => {
  82. state.visible = false
  83. },
  84. })
  85. }
  86. else {
  87. open({
  88. scene: 'topup-failed',
  89. onPrimary: () => {
  90. state.visible = false
  91. },
  92. })
  93. }
  94. }
  95. export const usePaybackResultPopup = () => {
  96. return {
  97. state: readonly(state),
  98. isSuccess,
  99. isPayment,
  100. open,
  101. close,
  102. handlePrimary,
  103. handleSecondary,
  104. handlePaymentSuccessOpen,
  105. handleTopupOpen,
  106. }
  107. }