import React, { useState, useEffect, useCallback } from 'react'; import { Table, Button, Space, Typography, message, Card, DatePicker, Select } from 'antd'; import { BankOutlined, SearchOutlined } from '@ant-design/icons'; import { queryBankTransactions, listBankAccounts } from '../api'; import { formatDate } from '../utils/formatDate'; import type { BankAccount } from '../types'; const { RangePicker } = DatePicker; interface TransactionRecord { counterAcctNo?: string; cnterName?: string; cnterBankName?: string; acctNo?: string; transAmt?: number | string; dcFlag?: number; dcFlagLabel?: string; transTimeStr?: string; digestCode?: string; remark?: string; balance?: number | string; tellerSeqno?: string; transferId?: string; } const AdminBankTransactions: React.FC = () => { const [data, setData] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(20); // 银行账户 const [accounts, setAccounts] = useState([]); const [selectedAccountId, setSelectedAccountId] = useState(undefined); // 搜索条件 const [dateRange, setDateRange] = useState<[string | null, string | null]>([null, null]); const [dcFlag, setDcFlag] = useState(undefined); useEffect(() => { loadAccounts(); }, []); const loadAccounts = async () => { try { const res = await listBankAccounts(); setAccounts(res.items || []); } catch (err: any) { message.error(err?.message || '加载银行账户失败'); } }; const fetchData = useCallback(async () => { if (!selectedAccountId || !dateRange[0] || !dateRange[1]) return; setLoading(true); try { const res = await queryBankTransactions({ accountId: selectedAccountId, startDate: dateRange[0], endDate: dateRange[1], dcFlag, page, pageSize, }); setData(res.items || []); setTotal(res.total || 0); } catch (err: any) { message.error(err?.message || '查询失败'); } finally { setLoading(false); } }, [selectedAccountId, dateRange, dcFlag, page, pageSize]); useEffect(() => { if (selectedAccountId && dateRange[0] && dateRange[1]) { fetchData(); } }, [fetchData]); const handleSearch = () => { if (!selectedAccountId) { message.warning('请选择银行账户'); return; } if (!dateRange[0] || !dateRange[1]) { message.warning('请选择交易时间区间'); return; } setPage(1); fetchData(); }; const selectedAccount = accounts.find(a => a.id === selectedAccountId); const columns = [ { title: '收款账号', dataIndex: 'counterAcctNo', width: 180, render: (v: string) => v || '-', }, { title: '收款户名', dataIndex: 'cnterName', width: 120, render: (v: string) => v || '-', }, { title: '收款开户行', dataIndex: 'cnterBankName', width: 150, render: (v: string) => v || '-', }, { title: '我方付款账号', dataIndex: 'acctNo', width: 180, render: (v: string) => v || '-', }, { title: '打款金额', dataIndex: 'transAmt', width: 120, align: 'right' as const, render: (v: number | string) => v != null ? Number(v).toFixed(2) : '-', }, { title: '借贷方向', dataIndex: 'dcFlagLabel', width: 100, render: (v: string, r: TransactionRecord) => v || (r.dcFlag === 0 ? '借/出金' : r.dcFlag === 1 ? '贷/入金' : '-'), }, { title: '打款时间', dataIndex: 'transTimeStr', width: 160, render: (v: string) => v ? formatDate(v) : '-', }, { title: '摘要', dataIndex: 'digestCode', width: 100, render: (v: string) => v || '-', }, { title: '用途/备注', dataIndex: 'remark', width: 150, render: (v: string) => v || '-', }, { title: '账户余额', dataIndex: 'balance', width: 120, align: 'right' as const, render: (v: number | string) => v != null ? Number(v).toFixed(2) : '-', }, { title: '流水号', dataIndex: 'tellerSeqno', width: 150, render: (v: string) => v || '-', }, ]; return (
银行交易查询 查询银行账户交易流水记录
借/出金 贷/入金 {selectedAccount && (
当前查询账户:{selectedAccount.bankName} | {selectedAccount.accountNo} | {selectedAccount.accountName}
)}
`${r.tellerSeqno || ''}-${r.transferId || ''}-${i}`} columns={columns} dataSource={data} loading={loading} scroll={{ x: 1400 }} pagination={{ current: page, pageSize, total, showSizeChanger: true, showTotal: (t) => `共 ${t} 条`, onChange: (p, ps) => { setPage(p); setPageSize(ps); }, }} /> ); }; export default AdminBankTransactions;