import { useCallback, useEffect, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { STORE_WITHDRAW_STATUS_LABELS, type StoreWithdrawRequestDto, type StoreWithdrawStatus, type StoreWithdrawSummaryDto, } from '@dukang/shared-types'; import PullToRefresh from '@dukang/shared-ui/PullToRefresh'; import { request } from '../lib/api'; import { formatMoney, toMoneyNumber } from '../lib/money'; import { useStorePageView } from '../lib/usePageView'; import { useRedeemSuccessListener } from '../lib/useRedeemSuccessBus'; type StatusFilter = 'all' | StoreWithdrawStatus; export default function WithdrawPage() { useStorePageView('store_withdraw_view'); const navigate = useNavigate(); const [summary, setSummary] = useState(null); const [items, setItems] = useState([]); const [statusFilter, setStatusFilter] = useState('all'); const [submitting, setSubmitting] = useState(false); const [msg, setMsg] = useState(''); const load = useCallback(async () => { try { const [summaryRes, listRes] = await Promise.all([ request('SHOP_H5', '/shop/withdraw/summary'), request<{ items: StoreWithdrawRequestDto[] }>('SHOP_H5', '/shop/withdraw/requests?pageSize=50'), ]); setSummary(summaryRes); setItems(listRes.items || []); } catch (e) { setMsg(e instanceof Error ? e.message : '加载失败'); } }, []); useEffect(() => { void load(); }, [load]); // v3.5.1 #2:核销成功后即时刷新可提余额与提现按钮状态 useRedeemSuccessListener(() => { void load(); }, [load]); const filtered = useMemo(() => { if (statusFilter === 'all') return items; return items.filter((r) => r.status === statusFilter); }, [items, statusFilter]); async function applyWithdraw() { if (!summary || submitting) return; if (!summary.isPrimary) { setMsg('仅主账号可申请提现'); return; } if (!(summary.availableAmount > 0)) { setMsg('暂无可提未出账余额'); return; } const ok = window.confirm( `确认申请提现 ¥${formatMoney(summary.availableAmount)}?\n审核通过后将打款至入驻收款账户。`, ); if (!ok) return; setSubmitting(true); setMsg(''); try { await request('SHOP_H5', '/shop/withdraw', { method: 'POST', body: JSON.stringify({}), }); setMsg('提现申请已提交,请等待总部审核'); await load(); } catch (e) { setMsg(e instanceof Error ? e.message : '提现申请失败'); } finally { setSubmitting(false); } } const canApply = !!summary?.isPrimary && summary.availableAmount > 0 && summary.hasBankAccount && !submitting; return (

结算提现

可提未出账余额

¥ {formatMoney(toMoneyNumber(summary?.availableAmount))}

今日剩余额度

¥ {formatMoney(toMoneyNumber(summary?.remainingDailyLimit))}

info 单日上限 ¥{formatMoney(summary?.dailyLimit ?? 5000)} {!summary?.hasBankAccount ? ' · 请先完善收款账户' : ''}

{summary && !summary.isPrimary ? (

仅主账号可申请提现,店员可查看记录

) : ( )} {msg ?

{msg}

: null}

提现记录

共 {filtered.length} 笔
{filtered.length === 0 ? (

暂无提现记录

) : (
{filtered.map((r) => { const status = r.status as StoreWithdrawStatus; const badgeClass = status === 'PAID' ? 'paid' : status === 'REJECTED' ? 'rejected' : 'pending'; return (
单号 {r.withdrawNo}

申请时间:{' '} {new Date(r.appliedAt) .toLocaleString('zh-CN', { hour12: false }) .slice(0, 16)}

{STORE_WITHDRAW_STATUS_LABELS[status] ?? status}

提现金额

¥{formatMoney(toMoneyNumber(r.amount))}

明细笔数

{r.payoutCount} 笔

{status === 'REJECTED' && r.rejectReason ? (

驳回原因: {r.rejectReason}

) : null} {status === 'PAID' && r.paidAt ? (

结算时间:{' '} {new Date(r.paidAt).toLocaleString('zh-CN', { hour12: false }).slice(0, 16)}

) : null}
); })}
)}
); }