import React, { useEffect, useRef, useState } from 'react'; import { Button, Descriptions, Drawer, Table, Tag, Typography, } from 'antd'; import type { TableProps } from 'antd'; import XinTable from '@/components/XinTable'; import type { XinTableColumn, XinTableInstance, XinTableProps, } from '@/components/XinTable/typings.ts'; import type IStatement from '@/domain/iStatement.ts'; import type { IStatementItem } from '@/domain/iStatement.ts'; import { STATEMENT_STATUS_MAP } from '@/domain/iStatement.ts'; import { RECONCILED_MAP } from '@/domain/iReconciliation.ts'; import { getStoreOptions } from '@/api/customer/store.ts'; import type IStore from '@/domain/iStore.ts'; import { Get } from '@/api/common/table.ts'; const { Title, Text } = Typography; /** * 门店对账单(后台只读视角;生成/导出在小程序端) */ const StatementPage: React.FC = () => { const tableRef = useRef>(null); const [stores, setStores] = useState([]); const [detailOpen, setDetailOpen] = useState(false); const [detail, setDetail] = useState(null); const [detailLoading, setDetailLoading] = useState(false); useEffect(() => { getStoreOptions().then((res) => setStores(res.data.data ?? [])); }, []); const openDetail = async (id: number) => { setDetailOpen(true); setDetailLoading(true); try { const res = await Get('/recon/statement', id); setDetail(res.data.data ?? null); } finally { setDetailLoading(false); } }; const itemColumns: TableProps['columns'] = [ { title: '品名', dataIndex: 'product_name' }, { title: '单价', dataIndex: 'price', align: 'right', render: (v) => `¥${v}` }, { title: '数量', dataIndex: 'quantity', align: 'right' }, { title: '重量', dataIndex: 'weight', align: 'right' }, { title: '金额', dataIndex: 'amount', align: 'right', render: (v) => `¥${v}` }, { title: '对账状态', dataIndex: 'is_reconciled', align: 'center', render: (v) => { const item = RECONCILED_MAP[Number(v ?? 0)]; return {item?.text}; }, }, { title: '备注', dataIndex: 'store_remark', render: (v) => v || '-' }, ]; const columns: XinTableColumn[] = [ { title: '对账单号', dataIndex: 'statement_no', valueType: 'text', hideInForm: true, render: (_, record) => {record.statement_no}, }, { title: '门店', dataIndex: 'store_id', valueType: 'select', hideInForm: true, fieldProps: { options: stores.map((s) => ({ label: s.name, value: s.id })), showSearch: true, optionFilterProp: 'label', }, render: (_, record) => record.store?.name ?? '-', }, { title: '对账周期', dataIndex: 'period_start', valueType: 'dateRange', hideInForm: true, render: (_, record) => `${record.period_start} ~ ${record.period_end}`, }, { title: '总金额', dataIndex: 'total_amount', hideInForm: true, hideInSearch: true, align: 'right', render: (_, record) => ¥{record.total_amount}, }, { title: '回款周期', dataIndex: 'payment_cycle_days', hideInForm: true, hideInSearch: true, align: 'center', render: (_, record) => `${record.payment_cycle_days} 天`, }, { title: '应结算日期', dataIndex: 'settlement_date', hideInForm: true, hideInSearch: true, align: 'center', render: (_, record) => { const overdue = record.status !== 2 && record.settlement_date ? new Date(record.settlement_date).getTime() < Date.now() : false; return ( {record.settlement_date} {overdue ? '(逾期)' : ''} ); }, }, { title: '状态', dataIndex: 'status', valueType: 'select', hideInForm: true, fieldProps: { options: Object.entries(STATEMENT_STATUS_MAP).map(([value, item]) => ({ value: Number(value), label: item.text, })), }, render: (_, record) => { const item = STATEMENT_STATUS_MAP[record.status ?? 0]; return {item?.text}; }, align: 'center', }, ]; const operateRender: XinTableProps['operateRender'] = (record) => [ , ]; const tableProps: XinTableProps = { api: '/recon/statement', columns, rowKey: 'id', accessName: 'recon.statement', tableRef, operateRender, formProps: false, actionBarRender: (dom) => [dom.search, dom.keywordSearch], }; return ( <>
门店对账单 门店在小程序端自助生成;应结算日期 = 对账周期结束日 + 门店回款周期(生成时快照),逾期高亮提示。
{...tableProps} /> setDetailOpen(false)} width={860} loading={detailLoading} > {detail ? ( <> {detail.store?.name} {STATEMENT_STATUS_MAP[detail.status ?? 0]?.text} {detail.period_start} ~ {detail.period_end} {detail.payment_cycle_days} 天 {detail.settlement_date} ¥{detail.total_amount} {detail.remark ? ( {detail.remark} ) : null} 对账明细({detail.items?.length ?? 0}) rowKey="id" size="small" columns={itemColumns} dataSource={detail.items ?? []} pagination={false} summary={() => ( 合计 ¥{detail.total_amount} )} /> ) : null} ); }; export default StatementPage;