- 移除 useGameBoardVm 数据层实施说明文档 - 移除核心玩法与前端规则摘要文档 - 移除游戏模块数据与界面分层第一阶段实施稿文档 - 清理与数据层重构相关的技术方案说明 - 删除关于 PC 和 Mobile 界面分离的设计规划 - 移除 view-model hooks 架构设计相关内容
122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
import { useInfiniteQuery } from '@tanstack/react-query'
|
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { getDepositOrderList, getWithdrawOrderList } from '@/api'
|
|
import { DEFAULT_LIST_PAGE_SIZE } from '@/constants'
|
|
import type { FinanceRecordType } from '@/type'
|
|
|
|
const FINANCE_RECORD_TYPE_OPTIONS: Array<{
|
|
key: FinanceRecordType
|
|
labelKey: string
|
|
}> = [
|
|
{
|
|
key: 'deposit',
|
|
labelKey: 'game.modals.userInfo.financeRecords.deposit',
|
|
},
|
|
{
|
|
key: 'withdraw',
|
|
labelKey: 'game.modals.userInfo.financeRecords.withdraw',
|
|
},
|
|
]
|
|
|
|
function formatFinanceAmount(value: string, locale: string) {
|
|
const numberValue = Number(value)
|
|
|
|
if (!Number.isFinite(numberValue)) {
|
|
return value || '--'
|
|
}
|
|
|
|
return new Intl.NumberFormat(locale, {
|
|
maximumFractionDigits: 4,
|
|
}).format(numberValue)
|
|
}
|
|
|
|
export function useFinanceRecordsVm({ enabled }: { enabled: boolean }) {
|
|
const { i18n, t } = useTranslation()
|
|
const locale = i18n.resolvedLanguage ?? i18n.language ?? 'en-US'
|
|
const [recordType, setRecordType] = useState<FinanceRecordType>('deposit')
|
|
|
|
const query = useInfiniteQuery({
|
|
queryKey: ['finance', 'user-info-order-list', recordType],
|
|
initialPageParam: 1,
|
|
queryFn: ({ pageParam }) =>
|
|
recordType === 'deposit'
|
|
? getDepositOrderList({
|
|
page: pageParam,
|
|
pageSize: DEFAULT_LIST_PAGE_SIZE,
|
|
})
|
|
: getWithdrawOrderList({
|
|
page: pageParam,
|
|
pageSize: DEFAULT_LIST_PAGE_SIZE,
|
|
}),
|
|
enabled,
|
|
getNextPageParam: (lastPage) => {
|
|
const nextPage = lastPage.pagination.page + 1
|
|
const loadedCount =
|
|
lastPage.pagination.page * lastPage.pagination.page_size
|
|
|
|
return loadedCount < lastPage.pagination.total ? nextPage : undefined
|
|
},
|
|
})
|
|
|
|
const lastPage = query.data?.pages.at(-1)
|
|
const total = lastPage?.pagination.total ?? 0
|
|
const loadedPage = lastPage?.pagination.page ?? 1
|
|
|
|
const recordTypes = useMemo(
|
|
() =>
|
|
FINANCE_RECORD_TYPE_OPTIONS.map((option) => ({
|
|
key: option.key,
|
|
label: t(option.labelKey),
|
|
})),
|
|
[t],
|
|
)
|
|
|
|
const items = useMemo(
|
|
() =>
|
|
(query.data?.pages ?? []).flatMap((page) =>
|
|
page.list.map((item, index) => ({
|
|
amountLabel: formatFinanceAmount(item.amount, locale),
|
|
bonusAmountLabel: formatFinanceAmount(item.bonusAmount, locale),
|
|
id: item.orderNo || `${page.pagination.page}-${index}`,
|
|
orderNoLabel: item.orderNo || '--',
|
|
})),
|
|
),
|
|
[locale, query.data?.pages],
|
|
)
|
|
|
|
const selectRecordType = useCallback((type: FinanceRecordType) => {
|
|
setRecordType(type)
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (!enabled) {
|
|
setRecordType('deposit')
|
|
}
|
|
}, [enabled])
|
|
|
|
return {
|
|
emptyText: t('game.modals.userInfo.financeRecords.empty'),
|
|
fetchNextPage: query.fetchNextPage,
|
|
hasNextPage: query.hasNextPage,
|
|
headers: {
|
|
amount: t('game.modals.userInfo.financeRecords.amount'),
|
|
bonusAmount: t('game.modals.userInfo.financeRecords.bonusAmount'),
|
|
orderNo: t('game.modals.userInfo.financeRecords.orderNo'),
|
|
},
|
|
isError: query.isError,
|
|
isFetchingNextPage: query.isFetchingNextPage,
|
|
isLoading: query.isLoading,
|
|
items,
|
|
loadFailedText: t('game.modals.userInfo.financeRecords.loadFailed'),
|
|
loadingText: t('game.modals.userInfo.financeRecords.loading'),
|
|
pageLabel: t('game.modals.userInfo.financeRecords.page', {
|
|
page: loadedPage,
|
|
total,
|
|
}),
|
|
recordType,
|
|
recordTypes,
|
|
selectRecordType,
|
|
}
|
|
}
|