import { useEffect, useMemo, useState } from 'react'; import { Plus, Search } from 'lucide-react'; import { Breadcrumb, Button, DateRangeInput, Input, ManualRechargeDialog, Pagination, Tag, type DateRangeValue } from '@/components/ui'; import { adminApi, type RechargeOrder, type TenantAccount, type TenantOption } from '@/api/adminApi'; import { formatDateTime } from '@/utils/dateTime'; import { formatCents } from '@/utils/currency'; function getDate(value: string) { return value.slice(0, 10); } function RemarkCell({ value }: { value?: string }) { return (
{value || '暂无备注'}
); } export function AdminRechargeRecordsPage() { const [records, setRecords] = useState([]); const [tenants, setTenants] = useState([]); const [accounts, setAccounts] = useState([]); const [enterpriseKeyword, setEnterpriseKeyword] = useState(''); const [dateRange, setDateRange] = useState({}); const [manualOpen, setManualOpen] = useState(false); const [page, setPage] = useState(1); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); async function loadData() { setLoading(true); setError(''); try { const [nextTenants, nextAccounts, nextRecords] = await Promise.all([ adminApi.listTenants(), adminApi.listAccounts(), adminApi.listManualRecharges(), ]); setTenants(nextTenants); setAccounts(nextAccounts); setRecords(nextRecords); } catch (err) { setError(err instanceof Error ? err.message : '充值记录加载失败'); setRecords([]); } finally { setLoading(false); } } useEffect(() => { void loadData(); }, []); const filteredRows = useMemo( () => records.filter((item) => { const rechargeDate = getDate(item.paidAt ?? item.createdAt); const tenantName = item.tenant?.name ?? tenants.find((tenant) => tenant.id === item.tenantId)?.name ?? item.tenantId; const matchesEnterprise = !enterpriseKeyword || tenantName.includes(enterpriseKeyword); const matchesStartDate = !dateRange.start || rechargeDate >= dateRange.start; const matchesEndDate = !dateRange.end || rechargeDate <= dateRange.end; return matchesEnterprise && matchesStartDate && matchesEndDate; }), [dateRange.end, dateRange.start, enterpriseKeyword, records, tenants], ); const pageSize = 10; const totalPages = Math.max(1, Math.ceil(filteredRows.length / pageSize)); const currentPage = Math.min(page, totalPages); const visibleRows = filteredRows.slice((currentPage - 1) * pageSize, currentPage * pageSize); useEffect(() => { setPage(1); }, [dateRange.end, dateRange.start, enterpriseKeyword, records.length]); function resetFilters() { setEnterpriseKeyword(''); setDateRange({}); } return (

充值记录

setEnterpriseKeyword(event.target.value)} value={enterpriseKeyword} />
{error ? ( ) : loading ? ( ) : filteredRows.length === 0 ? ( ) : visibleRows.map((record) => { const tenantName = record.tenant?.name ?? tenants.find((tenant) => tenant.id === record.tenantId)?.name ?? record.tenantId; return ( ); })}
企业名称 充值时间 充值金额 充值后余额 充值类型 备注
{error}
正在加载真实充值记录...
暂无真实充值记录
{tenantName} {formatDateTime(record.paidAt ?? record.createdAt)} ¥{formatCents(record.amountCents)} {record.balanceAfterCents === null || record.balanceAfterCents === undefined ? '-' : `¥${formatCents(record.balanceAfterCents)}`} 人工充值
= totalPages} onNext={() => setPage((value) => Math.min(totalPages, value + 1))} onPrevious={() => setPage((value) => Math.max(1, value - 1))} page={currentPage} totalPages={totalPages} onPageChange={setPage} previousDisabled={currentPage <= 1} total={filteredRows.length} />
tenant.status !== 'deleted')?.id} onClose={() => setManualOpen(false)} onCompleted={loadData} open={manualOpen} targets={tenants.filter((tenant) => tenant.status !== 'deleted').map((tenant) => ({ id: tenant.id, name: tenant.name, code: tenant.code, balanceCents: accounts.find((account) => account.tenantId === tenant.id)?.balanceCents ?? 0, }))} />
); }