import { useEffect, useMemo, useState } from 'react'; import { ChevronLeft, ChevronRight, Plus, Search } from 'lucide-react'; import { Breadcrumb, Button, DateRangeInput, Input, Modal, Select, Textarea, Tag, type DateRangeValue } from '@/components/ui'; import { adminApi, type AccountTransaction, type RechargeOrder, type TenantAccount, type TenantOption } from '@/api/adminApi'; type ManualRechargeForm = { tenantId: string; amount: string; smsUnits: string; operator: string; remark: string; }; function getDate(value: string) { return value.slice(0, 10); } function formatAmount(value?: number) { if (value === undefined) { return ''; } return value.toLocaleString('zh-CN', { maximumFractionDigits: 2, minimumFractionDigits: Number.isInteger(value) ? 0 : 2, }); } function RemarkCell({ value }: { value?: string }) { return (
{value || '暂无备注'}
); } export function AdminRechargeRecordsPage() { const [records, setRecords] = useState([]); const [accounts, setAccounts] = useState([]); const [transactions, setTransactions] = useState([]); const [tenants, setTenants] = useState([]); const [enterpriseKeyword, setEnterpriseKeyword] = useState(''); const [dateRange, setDateRange] = useState({}); const [manualOpen, setManualOpen] = useState(false); const [form, setForm] = useState({ tenantId: '', amount: '', smsUnits: '0', operator: '运营', remark: '' }); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); async function loadData() { setLoading(true); setError(''); try { const [nextTenants, nextRecords, nextAccounts, nextTransactions] = await Promise.all([ adminApi.listTenants(), adminApi.listManualRecharges(), adminApi.listAccounts(), adminApi.listTransactions(), ]); setTenants(nextTenants); setRecords(nextRecords); setAccounts(nextAccounts); setTransactions(nextTransactions); setForm((current) => ({ ...current, tenantId: current.tenantId || nextTenants[0]?.id || '' })); } 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], ); function resetFilters() { setEnterpriseKeyword(''); setDateRange({}); } function updateForm(key: K, value: ManualRechargeForm[K]) { setForm((current) => ({ ...current, [key]: value })); } async function submitManualRecharge() { const amount = Number(form.amount); const smsUnits = Number(form.smsUnits || 0); if (!form.tenantId || !Number.isFinite(amount) || amount <= 0 || !Number.isFinite(smsUnits) || smsUnits < 0) { return; } await adminApi.createManualRecharge({ tenantId: form.tenantId, amountCents: Math.round(amount * 100), smsUnits, remark: [form.operator, form.remark].filter(Boolean).join(' / '), }); await loadData(); setManualOpen(false); setForm({ tenantId: tenants[0]?.id ?? '', amount: '', smsUnits: '0', operator: '运营', remark: '' }); } return (

充值记录

setEnterpriseKeyword(event.target.value)} value={enterpriseKeyword} />
{error ? ( ) : loading ? ( ) : filteredRows.length === 0 ? ( ) : filteredRows.map((record) => { const account = accounts.find((item) => item.tenantId === record.tenantId); const transaction = transactions.find((item) => item.relatedId === record.id); const tenantName = record.tenant?.name ?? tenants.find((tenant) => tenant.id === record.tenantId)?.name ?? record.tenantId; return ( ); })}
企业名称 充值时间 充值金额 充值后余额 充值类型 操作人 备注
{error}
正在加载真实充值记录...
暂无真实充值记录
{tenantName} {new Date(record.paidAt ?? record.createdAt).toLocaleString('zh-CN')} {formatAmount(record.amountCents / 100)} {formatAmount((transaction?.balanceAfter ?? account?.balanceCents ?? 0) / 100)} 人工充值 {record.operatorId || '运营'}
updateForm('tenantId', event.target.value)} options={tenants.map((tenant) => ({ label: tenant.name, value: tenant.id }))} value={form.tenantId} /> updateForm('amount', event.target.value)} prefix="¥" type="number" value={form.amount} /> updateForm('smsUnits', event.target.value)} type="number" value={form.smsUnits} /> updateForm('operator', event.target.value)} value={form.operator} />