import { useState } from 'react'; import { Alert, Button, Form, Input, InputNumber, Modal, Space, Tabs, message } from 'antd'; import { ProCard } from '@ant-design/pro-components'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { ColDef } from '@ag-grid-community/core'; import dayjs from 'dayjs'; import PageContainer from '@/components/common/PageContainer'; import SearchForm from '@/components/common/SearchForm'; import DataGrid from '@/components/common/DataGrid'; import PermissionButton from '@/components/common/PermissionButton'; import { commissionApi, CollectionRuleRow, CollectionLedgerRow, CommissionSearchParam, } from '@/api/commission'; import { GRAY, RADIUS, SHADOW } from '@/theme/tokens'; const fmt = (v: unknown) => (v as number)?.toLocaleString() ?? '-'; const RULE_COLS: ColDef[] = [ { field: 'carrierName', headerName: '보험사', width: 140 }, { field: 'productType', headerName: '상품유형', width: 120 }, { field: 'paymentCycle', headerName: '납입주기', width: 100 }, { field: 'ratePercent', headerName: '수수료율(%)', width: 120, type: 'numericColumn' }, { field: 'effectiveFrom', headerName: '적용시작', width: 120 }, { field: 'effectiveTo', headerName: '적용종료', width: 120 }, { field: 'status', headerName: '상태', width: 90 }, ]; const LEDGER_COLS: ColDef[] = [ { field: 'settleMonth', headerName: '정산월', width: 110, pinned: 'left' }, { field: 'agentName', headerName: '설계사', width: 120 }, { field: 'contractNo', headerName: '계약번호', width: 140 }, { field: 'collectionAmount', headerName: '수납금액', flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) }, { field: 'ratePercent', headerName: '수수료율(%)', width: 110, type: 'numericColumn' }, { field: 'commissionAmount', headerName: '수수료', flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) }, { field: 'status', headerName: '상태', width: 90 }, ]; export default function CollectionCommission() { const qc = useQueryClient(); const [ledgerParams, setLedgerParams] = useState({ settleMonth: dayjs().format('YYYYMM'), pageSize: 200, }); const [ruleModalOpen, setRuleModalOpen] = useState(false); const [editingRule, setEditingRule] = useState(null); const [form] = Form.useForm(); const { data: rulesData, isLoading: rulesLoading, isError: rulesError } = useQuery({ queryKey: ['collection', 'rules'], queryFn: () => commissionApi.collectionRules(), retry: false, }); const { data: ledgersData, isLoading: ledgersLoading } = useQuery({ queryKey: ['collection', 'ledgers', ledgerParams], queryFn: () => commissionApi.collectionLedgers(ledgerParams), retry: false, }); const rules = rulesData?.list ?? []; const ledgers = ledgersData?.list ?? []; const openCreate = () => { setEditingRule(null); form.resetFields(); setRuleModalOpen(true); }; const openEdit = (row: CollectionRuleRow) => { setEditingRule(row); form.setFieldsValue(row); setRuleModalOpen(true); }; const handleSave = async () => { const values = await form.validateFields(); try { if (editingRule) { await commissionApi.collectionRuleUpdate(editingRule.ruleId, values); message.success('수정 완료'); } else { await commissionApi.collectionRuleCreate(values); message.success('등록 완료'); } qc.invalidateQueries({ queryKey: ['collection', 'rules'] }); setRuleModalOpen(false); } catch { /* request.ts 처리 */ } }; const handleDelete = (id: number) => Modal.confirm({ title: '룰 삭제', content: '삭제하시겠습니까?', onOk: async () => { await commissionApi.collectionRuleDelete(id); message.success('삭제 완료'); qc.invalidateQueries({ queryKey: ['collection', 'rules'] }); }, }); const pinnedLedger = ledgers.length > 0 ? { agentName: '합계', collectionAmount: ledgers.reduce((s, r) => s + (r.collectionAmount ?? 0), 0), commissionAmount: ledgers.reduce((s, r) => s + (r.commissionAmount ?? 0), 0), } as Partial : undefined; const cardStyle = { background: '#fff', borderRadius: RADIUS.lg, border: `1px solid ${GRAY[100]}`, boxShadow: SHADOW.sm }; return ( {rulesError && ( )}
+ 룰 등록
rows={rules} columns={[ ...RULE_COLS, { headerName: '액션', width: 160, pinned: 'right', cellRenderer: (p: { data: CollectionRuleRow }) => ( openEdit(p.data)}>수정 handleDelete(p.data.ruleId)}>삭제 ), }, ]} loading={rulesLoading} height={520} rowKey="ruleId" /> ), }, { key: 'ledgers', label: '수금 원장', children: ( <> setLedgerParams({ ...v as CommissionSearchParam, pageSize: 200 })} onReset={() => setLedgerParams({ settleMonth: dayjs().format('YYYYMM'), pageSize: 200 })} /> rows={ledgers} columns={LEDGER_COLS} loading={ledgersLoading} height={520} rowKey="ledgerId" pinnedBottomRow={pinnedLedger} /> ), }, ]} /> setRuleModalOpen(false)} okText="저장" cancelText="취소" >
); }