import { DeleteOutlined, PlusOutlined } from '@ant-design/icons'; import { Button, Card, Col, Form, Input, Row, Select, Space, Table, Typography, message } from 'antd'; import { useEffect, useState } from 'react'; import { history } from '@umijs/max'; import { createPurchaseOrder, listProducts, listSuppliers } from '@/services/api'; import type { Product, Supplier } from '@/types/api'; const { Title } = Typography; interface DetailRow { key: number; productId?: string; productName?: string; spec?: string; color?: string; quantity?: string; unitPrice?: string; } let rowKey = 0; const NewOrderPage: React.FC = () => { const [form] = Form.useForm(); const [suppliers, setSuppliers] = useState([]); const [products, setProducts] = useState([]); const [details, setDetails] = useState([{ key: rowKey++ }]); const [submitting, setSubmitting] = useState(false); useEffect(() => { listSuppliers({ page: 1, pageSize: 200, status: 1 }).then((res) => { if (res?.code === 0) setSuppliers(res.data?.list || []); }); listProducts({ page: 1, pageSize: 500 }).then((res) => { if (res?.code === 0) setProducts(res.data?.list || []); }); }, []); const productMap = Object.fromEntries(products.map((p) => [p.productId, p])); const handleProductChange = (rowIdx: number, productId: string) => { const p = productMap[productId]; if (!p) return; setDetails((prev) => prev.map((r, i) => i === rowIdx ? { ...r, productId, productName: p.productName, spec: p.spec || '', color: p.color || '' } : r, ), ); }; const handleFieldChange = (rowIdx: number, field: keyof DetailRow, value: string) => { setDetails((prev) => prev.map((r, i) => (i === rowIdx ? { ...r, [field]: value } : r))); }; const addRow = () => setDetails((prev) => [...prev, { key: rowKey++ }]); const removeRow = (rowIdx: number) => { setDetails((prev) => prev.filter((_, i) => i !== rowIdx)); }; const calcAmount = (row: DetailRow) => { const q = parseFloat(row.quantity || '0'); const p = parseFloat(row.unitPrice || '0'); return isNaN(q) || isNaN(p) ? '' : (q * p).toFixed(2); }; const handleSubmit = async () => { let headerValues: { supplierId: string; orderDate: string; purchaseBy?: string; remark?: string }; try { headerValues = await form.validateFields(); } catch { return; } const validDetails = details.filter((r) => r.productId && r.quantity && r.unitPrice); if (validDetails.length === 0) { message.error('请至少添加一条采购明细'); return; } setSubmitting(true); try { const res = await createPurchaseOrder({ ...headerValues, details: validDetails.map((r) => ({ productId: r.productId!, productName: r.productName!, spec: r.spec, color: r.color, quantity: r.quantity!, unitPrice: r.unitPrice!, })), }); if (res?.code !== 0) { message.error(res?.msg || '创建失败'); return; } message.success('采购订单已创建'); history.push(`/purchase/orders/${res.data.id}`); } catch { message.error('创建失败'); } finally { setSubmitting(false); } }; const columns = [ { title: '产品', width: 220, render: (_: unknown, _row: DetailRow, idx: number) => ( handleFieldChange(idx, 'spec', e.target.value)} /> ), }, { title: '颜色', width: 120, render: (_: unknown, _row: DetailRow, idx: number) => ( handleFieldChange(idx, 'color', e.target.value)} /> ), }, { title: '采购数量', width: 120, render: (_: unknown, _row: DetailRow, idx: number) => ( handleFieldChange(idx, 'quantity', e.target.value)} /> ), }, { title: '单价', width: 120, render: (_: unknown, _row: DetailRow, idx: number) => ( handleFieldChange(idx, 'unitPrice', e.target.value)} /> ), }, { title: '小计', width: 100, render: (_: unknown, _row: DetailRow, idx: number) => calcAmount(details[idx]), }, { title: '', width: 48, render: (_: unknown, _row: DetailRow, idx: number) => ( 新建采购订单
} onClick={addRow}>添加明细} > ); }; export default NewOrderPage;