Files
36-character-flower/src/features/game/hooks/use-wallet-records-vm.ts
JiaJun 901ad1c30b refactor(constants): 提取常量并优化国际化配置
- 创建API相关常量文件,包括响应码、HTTP状态码、请求头等
- 将认证相关常量从auth模块提取到独立的常量文件
- 在API客户端中使用新定义的常量替换硬编码值
- 更新认证API和服务中对常量的引用
- 在国际化配置中创建统一的文案常量以减少重复
- 将认证表单验证规则改为使用常量配置
2026-06-02 12:03:29 +08:00

107 lines
3.4 KiB
TypeScript

import { useInfiniteQuery } from '@tanstack/react-query'
import dayjs from 'dayjs'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { DEFAULT_LIST_PAGE_SIZE } from '@/constants'
import { getWalletRecordList } from '@/features/game/api'
const WALLET_RECORD_TYPE = 'payout'
function formatWalletAmount(value: string, locale: string) {
const numberValue = Number(value)
if (!Number.isFinite(numberValue)) {
return value || '--'
}
return new Intl.NumberFormat(locale, {
maximumFractionDigits: 4,
}).format(numberValue)
}
function formatWalletRecordTime(value: number | string | null) {
if (value === null || value === '') {
return '--'
}
const numericValue = Number(value)
const timestamp =
Number.isFinite(numericValue) && numericValue > 0
? numericValue < 10_000_000_000
? numericValue * 1000
: numericValue
: value
const formatted = dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')
return formatted === 'Invalid Date' ? String(value) : formatted
}
export function useWalletRecordsVm({ enabled }: { enabled: boolean }) {
const { i18n, t } = useTranslation()
const locale = i18n.resolvedLanguage ?? i18n.language ?? 'en-US'
const query = useInfiniteQuery({
queryKey: ['finance', 'wallet-record-list', WALLET_RECORD_TYPE],
initialPageParam: 1,
queryFn: ({ pageParam }) =>
getWalletRecordList({
page: pageParam,
pageSize: DEFAULT_LIST_PAGE_SIZE,
type: WALLET_RECORD_TYPE,
}),
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 items = useMemo(
() =>
(query.data?.pages ?? []).flatMap((page) =>
page.list.map((item, index) => ({
amountLabel: formatWalletAmount(item.amount, locale),
balanceAfterLabel: formatWalletAmount(item.balanceAfter, locale),
balanceBeforeLabel: formatWalletAmount(item.balanceBefore, locale),
id: item.id || `${page.pagination.page}-${index}`,
remarkLabel: item.remark || '--',
timeLabel: formatWalletRecordTime(item.createdAt),
typeLabel: item.type || WALLET_RECORD_TYPE,
})),
),
[locale, query.data?.pages],
)
return {
emptyText: t('game.modals.userInfo.walletRecords.empty'),
fetchNextPage: query.fetchNextPage,
hasNextPage: query.hasNextPage,
headers: {
amount: t('game.modals.userInfo.walletRecords.amount'),
balanceAfter: t('game.modals.userInfo.walletRecords.balanceAfter'),
balanceBefore: t('game.modals.userInfo.walletRecords.balanceBefore'),
remark: t('game.modals.userInfo.walletRecords.remark'),
time: t('game.modals.userInfo.walletRecords.time'),
type: t('game.modals.userInfo.walletRecords.type'),
},
isError: query.isError,
isFetchingNextPage: query.isFetchingNextPage,
isLoading: query.isLoading,
items,
loadFailedText: t('game.modals.userInfo.walletRecords.loadFailed'),
loadingText: t('game.modals.userInfo.walletRecords.loading'),
pageLabel: t('game.modals.userInfo.walletRecords.page', {
page: loadedPage,
total,
}),
}
}