316 lines
9.7 KiB
TypeScript
316 lines
9.7 KiB
TypeScript
import { computed, inject, onMounted, provide, ref, type ComponentPublicInstance, type InjectionKey } from 'vue'
|
|
import OtpInput from 'vue3-otp-input'
|
|
import { usePrice, usePriceWithoutType } from '@/utils/usePrice'
|
|
import { loading, loadingMore } from '@/utils'
|
|
import router from '@/router'
|
|
import { useWalletStore } from '@/store/walletStore'
|
|
import type { Transaction } from '@/models/transaction'
|
|
import { createCard, getActivatedCards, withdraw, confirmCode } from '@/api/wallet'
|
|
import { useInfiniteScroll } from '@vueuse/core'
|
|
import { message } from 'ant-design-vue'
|
|
import type { Card } from '@/models/wallet'
|
|
import { useUserStore } from '@/store/userStore'
|
|
import { useSettingsStore } from '@/store/settingsStore'
|
|
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
|
import type { TableEngineInput, TableOutput } from '@/models/table'
|
|
import { getTransactionTable, getTransactionTable2 } from '@/api/transaction'
|
|
import { formatWalletMinHint, parseWalletMinRial } from '@/utils/walletMinAmount'
|
|
|
|
export interface WalletPageContext {
|
|
isDeposit: ReturnType<typeof ref<boolean>>
|
|
walletStore: ReturnType<typeof useWalletStore>
|
|
showAddCard: ReturnType<typeof ref<boolean>>
|
|
chargeAccountModal: ReturnType<typeof ref<boolean>>
|
|
showConfirmCode: ReturnType<typeof ref<boolean>>
|
|
infoVisible: ReturnType<typeof ref<boolean>>
|
|
refOtpInput: ReturnType<typeof ref<InstanceType<typeof OtpInput> | null>>
|
|
form: ReturnType<typeof ref<Transaction>>
|
|
cardForm: ReturnType<typeof ref<Card>>
|
|
disableButton: ReturnType<typeof computed<boolean>>
|
|
cardItems: ReturnType<typeof ref<Card[]>>
|
|
depositItems: ReturnType<typeof ref<Transaction[]>>
|
|
withdrawItems: ReturnType<typeof ref<Transaction[]>>
|
|
mobileDepositScrollEl: ReturnType<typeof ref<HTMLElement | null>>
|
|
desktopDepositScrollEl: ReturnType<typeof ref<HTMLElement | null>>
|
|
minWithdrawHint: ReturnType<typeof computed<string>>
|
|
minDepositHint: ReturnType<typeof computed<string>>
|
|
usePriceWithoutType: typeof usePriceWithoutType
|
|
usePrice: typeof usePrice
|
|
setIsDeposit: (val: boolean) => void
|
|
useStyle: () => string
|
|
formatter: (value: number) => string
|
|
percentChange: (val: number) => void
|
|
ok: () => Promise<void>
|
|
addCard: () => Promise<void>
|
|
getCards: () => Promise<void>
|
|
handleOnComplete: (value: string) => Promise<void>
|
|
}
|
|
|
|
export const WALLET_PAGE_CONTEXT_KEY: InjectionKey<WalletPageContext> = Symbol('walletPageContext')
|
|
|
|
export function useWalletPage() {
|
|
const isDeposit = ref(true)
|
|
const walletStore = useWalletStore()
|
|
const userStore = useUserStore()
|
|
const settingsStore = useSettingsStore()
|
|
const isDesktop = useDesktopBreakpoint()
|
|
const showAddCard = ref(false)
|
|
const chargeAccountModal = ref(false)
|
|
const showConfirmCode = ref(false)
|
|
const infoVisible = ref(false)
|
|
const refOtpInput = ref<InstanceType<typeof OtpInput> | null>(null)
|
|
const mobileDepositScrollEl = ref<HTMLElement | null>(null)
|
|
const desktopDepositScrollEl = ref<HTMLElement | null>(null)
|
|
|
|
const form = ref<Transaction>({
|
|
value: undefined,
|
|
percentWallet: 0,
|
|
card_id: undefined,
|
|
})
|
|
|
|
const cardForm = ref<Card>({
|
|
birth_date: 0,
|
|
shaba_number: '',
|
|
})
|
|
|
|
const cardItems = ref<Card[]>([])
|
|
const depositItems = ref<Transaction[]>([])
|
|
const withdrawItems = ref<Transaction[]>([])
|
|
const depositTableOutput = ref<TableOutput<Transaction> | null>(null)
|
|
const withdrawTableOutput = ref<TableOutput<Transaction> | null>(null)
|
|
|
|
const depositPagination = ref<TableEngineInput>({ filters: [], limit: 6, page: 0 })
|
|
const withdrawPagination = ref<TableEngineInput>({
|
|
filters: [{ field: 'type', cr: 'and', type: 'number', op: 'eq', value: 4 }],
|
|
limit: 6,
|
|
page: 0,
|
|
})
|
|
|
|
const activeDepositScrollEl = computed(() =>
|
|
isDesktop.value ? desktopDepositScrollEl.value : mobileDepositScrollEl.value
|
|
)
|
|
|
|
const unitCalculator = computed(() => (walletStore?.walletInfo?.cash ?? 0) / 100)
|
|
|
|
const minWithdrawAmount = computed(() =>
|
|
parseWalletMinRial(settingsStore.getSettingByKey('min_withdraw')),
|
|
)
|
|
const minDepositAmount = computed(() =>
|
|
parseWalletMinRial(settingsStore.getSettingByKey('min_deposit')),
|
|
)
|
|
const minWithdrawHint = computed(() =>
|
|
formatWalletMinHint('withdraw', minWithdrawAmount.value),
|
|
)
|
|
const minDepositHint = computed(() =>
|
|
formatWalletMinHint('deposit', minDepositAmount.value),
|
|
)
|
|
|
|
const disableButton = computed(() => {
|
|
if (loading.value) return true
|
|
if (walletStore?.walletInfo?.cash && !isDeposit.value) {
|
|
if (cardItems.value.length > 0) {
|
|
return (
|
|
walletStore?.walletInfo?.cash <= 0 ||
|
|
walletStore?.walletInfo?.cash < parseInt(String(form.value?.value)) ||
|
|
isNaN(parseInt(String(form.value?.value))) ||
|
|
parseInt(String(form.value?.value)) < minWithdrawAmount.value
|
|
)
|
|
}
|
|
return true
|
|
}
|
|
if (isDeposit.value) {
|
|
return (
|
|
isNaN(parseInt(String(form.value?.value))) ||
|
|
parseInt(String(form.value?.value)) < minDepositAmount.value
|
|
)
|
|
}
|
|
return false
|
|
})
|
|
|
|
function setIsDeposit(val: boolean) {
|
|
isDeposit.value = val
|
|
form.value.value = undefined
|
|
form.value.percentWallet = 0
|
|
}
|
|
|
|
function useStyle() {
|
|
if (isDeposit.value) return 'right: 2%;'
|
|
return ' right: 98%; transform: translate(100%, 0);'
|
|
}
|
|
|
|
const formatter = (value: number) => `${value}%`
|
|
|
|
function percentChange(val: number) {
|
|
if (val !== 0) form.value.value = parseInt((unitCalculator.value * val).toFixed())
|
|
else form.value.value = undefined
|
|
}
|
|
|
|
function resetData() {
|
|
form.value.value = undefined
|
|
form.value.percentWallet = 0
|
|
}
|
|
|
|
async function addCard() {
|
|
try {
|
|
loading.value = true
|
|
await createCard(cardForm.value)
|
|
await getCards()
|
|
showAddCard.value = false
|
|
cardForm.value = { birth_date: 0, shaba_number: '' }
|
|
message.success('کارت وارد شده با موفقیت افزوده شد و پس از تایید نمایش داده خواهد شد.')
|
|
} catch (e) {
|
|
console.log(e)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function getCards() {
|
|
try {
|
|
cardItems.value = (await getActivatedCards()) ?? []
|
|
form.value.card_id = cardItems.value.length ? cardItems.value[0].id : undefined
|
|
} catch (e) {
|
|
console.log(e)
|
|
}
|
|
}
|
|
|
|
async function ok() {
|
|
try {
|
|
if (form.value.value !== undefined) {
|
|
loading.value = true
|
|
if (!isDeposit.value) {
|
|
await confirmCode({ value: form.value.value })
|
|
showConfirmCode.value = true
|
|
} else {
|
|
chargeAccountModal.value = true
|
|
}
|
|
} else {
|
|
message.error('ابتدا مبلغ را وارد کنید')
|
|
}
|
|
} catch (e) {
|
|
console.log(e)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function initDepositTable() {
|
|
try {
|
|
depositPagination.value.page === 0 ? (loading.value = true) : (loadingMore.value = true)
|
|
depositTableOutput.value = await getTransactionTable2(depositPagination.value)
|
|
depositItems.value.push(...depositTableOutput.value.rows)
|
|
} catch (e) {
|
|
console.log(e)
|
|
} finally {
|
|
loading.value = false
|
|
loadingMore.value = false
|
|
}
|
|
}
|
|
|
|
async function initWithdrawTable() {
|
|
try {
|
|
withdrawPagination.value.page === 0 ? (loading.value = true) : (loadingMore.value = true)
|
|
withdrawTableOutput.value = await getTransactionTable(withdrawPagination.value)
|
|
withdrawItems.value.push(...withdrawTableOutput.value.rows)
|
|
} catch (e) {
|
|
console.log(e)
|
|
} finally {
|
|
loading.value = false
|
|
loadingMore.value = false
|
|
}
|
|
}
|
|
|
|
async function handleOnComplete(value: string) {
|
|
try {
|
|
infoVisible.value = true
|
|
showConfirmCode.value = false
|
|
await withdraw({ ...form.value, otp: value })
|
|
await walletStore.getMyWallet()
|
|
await message.success('عملیات با موفقیت انجام شد')
|
|
resetData()
|
|
} catch (e) {
|
|
console.log(e)
|
|
}
|
|
infoVisible.value = false
|
|
refOtpInput.value?.clearInput()
|
|
}
|
|
|
|
onMounted(async () => {
|
|
if (router.currentRoute.value.query.state === 'deposit') {
|
|
isDeposit.value = true
|
|
}
|
|
cardForm.value.birth_date = userStore.userInfo?.birth_date
|
|
await walletStore.getMyWallet()
|
|
await initWithdrawTable()
|
|
await initDepositTable()
|
|
await getCards()
|
|
})
|
|
|
|
if (!userStore.isSingle) {
|
|
useInfiniteScroll(
|
|
activeDepositScrollEl,
|
|
async () => {
|
|
if (isDeposit.value) {
|
|
if (
|
|
depositTableOutput.value &&
|
|
(depositPagination.value.page + 1) * depositPagination.value.limit <
|
|
depositTableOutput.value.query.total
|
|
) {
|
|
depositPagination.value.page++
|
|
await initDepositTable()
|
|
}
|
|
} else if (
|
|
withdrawTableOutput.value &&
|
|
(withdrawPagination.value.page + 1) * withdrawPagination.value.limit <
|
|
withdrawTableOutput.value.query.total
|
|
) {
|
|
withdrawPagination.value.page++
|
|
await initWithdrawTable()
|
|
}
|
|
},
|
|
{ distance: 12 }
|
|
)
|
|
}
|
|
|
|
const context: WalletPageContext = {
|
|
isDeposit,
|
|
walletStore,
|
|
showAddCard,
|
|
chargeAccountModal,
|
|
showConfirmCode,
|
|
infoVisible,
|
|
refOtpInput,
|
|
form,
|
|
cardForm,
|
|
disableButton,
|
|
cardItems,
|
|
depositItems,
|
|
withdrawItems,
|
|
mobileDepositScrollEl,
|
|
desktopDepositScrollEl,
|
|
minWithdrawHint,
|
|
minDepositHint,
|
|
usePriceWithoutType,
|
|
usePrice,
|
|
setIsDeposit,
|
|
useStyle,
|
|
formatter,
|
|
percentChange,
|
|
ok,
|
|
addCard,
|
|
getCards,
|
|
handleOnComplete,
|
|
}
|
|
|
|
provide(WALLET_PAGE_CONTEXT_KEY, context)
|
|
return context
|
|
}
|
|
|
|
export function useWalletPageContext() {
|
|
const context = inject(WALLET_PAGE_CONTEXT_KEY)
|
|
if (!context) {
|
|
throw new Error('useWalletPageContext must be used within useWalletPage')
|
|
}
|
|
return context
|
|
}
|