import { useEffect, useState, useCallback } from 'react' import { Card, Table, Typography, Space, Select, Tag, DatePicker, Button, message, Modal, Alert, Descriptions, Divider, Statistic, Row, Col, Empty, } from 'antd' import { DollarCircleOutlined, FileTextOutlined, CheckCircleOutlined, ClockCircleOutlined, PlusOutlined, } from '@ant-design/icons' import { createSettlementBatch, formatMoney, listSettlementBatches, listSettlementItems, listSites, settleBatch, cancelSettlementBatch, getMe, type SettlementBatch, type SettlementItem, type Site, } from '../api' import { useMember } from '../MemberContext' import type { Dayjs } from 'dayjs' const STATUS_LABELS: Record = { settled: { label: '已释放入账', color: 'success' }, draft: { label: '待释放入账', color: 'warning' }, pending: { label: '待释放入账', color: 'warning' }, processing: { label: '结算处理中', color: 'processing' }, cancelled: { label: '已作废', color: 'default' }, } const PARTY_ROLE_LABELS: Record = { seller: '渠道代销分润 (40%)', distributor_sell: '渠道代销分润 (40%)', distributor_b: '渠道代销分润 (40%)', receiver: '号源出租分润 (35%)', distributor_receive: '号源出租分润 (35%)', distributor_a: '号源出租分润 (35%)', two_party_distributor: '分销商分润', platform: '平台服务费', } export default function Settlements() { const member = useMember() const [sites, setSites] = useState([]) const [siteID, setSiteID] = useState(member?.site_id) const [batches, setBatches] = useState([]) const [loading, setLoading] = useState(false) const [range, setRange] = useState<[Dayjs | null, Dayjs | null] | null>(null) const [itemsFor, setItemsFor] = useState(null) const [items, setItems] = useState([]) const [itemsLoading, setItemsLoading] = useState(false) const [creating, setCreating] = useState(false) const load = useCallback(async (id: number) => { setLoading(true) try { setBatches(await listSettlementBatches(id)) } catch { message.error('结算账单加载失败') } finally { setLoading(false) } }, []) useEffect(() => { async function init() { let currentMember = member if (!currentMember) { try { currentMember = await getMe() } catch { // ignore } } const activeSiteID = currentMember?.site_id if (activeSiteID) { setSiteID(activeSiteID) void load(activeSiteID) } if (currentMember?.is_superadmin) { try { const rows = await listSites() setSites(rows) if (!activeSiteID && rows.length > 0) { setSiteID(rows[0].id) void load(rows[0].id) } } catch { // ignore } } } void init() }, [member, load]) async function handleCreate() { if (!siteID || !range?.[0] || !range?.[1]) { message.warning('请选择站点和结算周期') return } setCreating(true) try { const batch = await createSettlementBatch(siteID, range[0].toISOString(), range[1].toISOString()) message.success(`结算批次 ${batch.batch_no} 已创建,合计金额 ${formatMoney(batch.total_amount_cent)}`) void load(siteID) } catch (error: unknown) { const respMessage = (error as { response?: { data?: { message?: string } } })?.response?.data?.message message.error(respMessage ?? '批次创建失败') } finally { setCreating(false) } } async function handleSettle(batch: SettlementBatch) { Modal.confirm({ title: '立即释放入账?', content: `即将把批次【${batch.batch_no}】的 ${formatMoney(batch.total_amount_cent)} 转入商户可提现余额,人工批次会绕过冷却期。`, onOk: async () => { try { await settleBatch(batch.id) message.success(`批次 ${batch.batch_no} 已释放入账`) if (siteID) void load(siteID) } catch (error: unknown) { const respMessage = (error as { response?: { data?: { message?: string } } })?.response?.data?.message message.error(respMessage ?? '释放失败') } }, }) } async function handleCancel(batch: SettlementBatch) { Modal.confirm({ title: '作废未入账批次?', content: `作废【${batch.batch_no}】后,其中订单可重新进入自动释放或新的人工批次。`, okButtonProps: { danger: true }, onOk: async () => { try { await cancelSettlementBatch(batch.id) message.success(`批次 ${batch.batch_no} 已作废`) if (siteID) void load(siteID) } catch (error: unknown) { const respMessage = (error as { response?: { data?: { message?: string } } })?.response?.data?.message message.error(respMessage ?? '作废失败') } }, }) } async function showItems(batch: SettlementBatch) { setItemsFor(batch) setItemsLoading(true) try { setItems(await listSettlementItems(batch.id)) } catch { message.error('结算对账明细加载失败') } finally { setItemsLoading(false) } } const isSuperadmin = member?.is_superadmin return (
{isSuperadmin ? '结算管理与批次对账' : '结算对账单与财务对账'} {isSuperadmin ? '冷却期满后系统按站点按天自动释放入账;也可手工创建批次立即入账,或作废未入账草稿以免挡住自动释放' : '订单完成冷却期结束后系统自动释放入账,此处查看对账批次与入账明细'}
{isSuperadmin && sites.length > 1 && (