import { useState } from 'react'; import { Button, Field, Input, Textarea } from '../components/ui.jsx'; import { Icon, PageTitle, Toolbar, Panel, ApiNotice, Modal, ConfirmDialog, SimpleTable, KeyValue } from '../components/layout.jsx'; import { gateways } from '../fixtures/devFixtures.js'; import { explainApiError } from '../api.js'; export function VendorsPage({ vendorRows, setVendorRows, addRechargeRecord, apiLoading, apiError, refreshApi, can = () => true, onCreateVendor, onUpdateVendor, onDeleteVendor, onRechargeVendor }) { const [showCreateVendor, setShowCreateVendor] = useState(false); const [editingVendor, setEditingVendor] = useState(null); const [rechargeVendor, setRechargeVendor] = useState(null); const [deleteVendorTarget, setDeleteVendorTarget] = useState(null); const [newVendor, setNewVendor] = useState({ name: '' }); const [editVendorForm, setEditVendorForm] = useState({ name: '' }); const [rechargeForm, setRechargeForm] = useState({ amount: '', remark: '' }); const [actionError, setActionError] = useState(''); const canManageVendors = can('vendors.manage'); const canManageRecharges = can('recharges.manage'); const parseMoney = (value) => Number(String(value).replace(/[^\d.-]/g, '')) || 0; const formatMoney = (value) => `¥${value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; const openEditVendor = (vendor) => { setEditingVendor(vendor); setEditVendorForm({ name: vendor.name || '' }); }; const closeEditVendor = () => { setEditingVendor(null); setEditVendorForm({ name: '' }); }; const openRechargeVendor = (vendor) => { setRechargeVendor(vendor); setRechargeForm({ amount: '', remark: '' }); }; const closeRechargeVendor = () => { setRechargeVendor(null); setRechargeForm({ amount: '', remark: '' }); }; const submitVendor = async (event) => { event.preventDefault(); if (!newVendor.name.trim()) return; setActionError(''); try { if (onCreateVendor) { await onCreateVendor({ name: newVendor.name.trim(), creditLimit: '0.000000' }); } else { const nextIndex = vendorRows.length + 1; setVendorRows((rows) => [...rows, { id: `V${String(2000 + nextIndex)}`, name: newVendor.name.trim(), balance: '¥0.00', credit: '¥0', gateways: 0, status: '启用', cycle: '待配置', ratePlan: '待配置', contact: '-', createdAt: '2026-06-19' }]); } setNewVendor({ name: '' }); setShowCreateVendor(false); } catch (error) { setActionError(explainApiError(error)); } }; const submitEditVendor = async (event) => { event.preventDefault(); if (!editVendorForm.name.trim() || !editingVendor) return; setActionError(''); try { if (onUpdateVendor) { await onUpdateVendor(editingVendor.id, { name: editVendorForm.name.trim() }); } else { setVendorRows((rows) => rows.map((vendor) => ( vendor.id === editingVendor.id ? { ...vendor, name: editVendorForm.name.trim() } : vendor ))); } closeEditVendor(); } catch (error) { setActionError(explainApiError(error)); } }; const submitRecharge = async (event) => { event.preventDefault(); const amount = Number(rechargeForm.amount); if (!rechargeVendor || !Number.isFinite(amount) || amount <= 0) return; setActionError(''); try { if (onRechargeVendor) { await onRechargeVendor(rechargeVendor.id, { amount: amount.toFixed(2), remark: rechargeForm.remark.trim() || undefined }); } else { const beforeBalance = parseMoney(rechargeVendor.balance); const afterBalance = beforeBalance + amount; setVendorRows((rows) => rows.map((vendor) => ( vendor.id === rechargeVendor.id ? { ...vendor, balance: formatMoney(afterBalance) } : vendor ))); addRechargeRecord({ id: `RCG-V-${Date.now()}`, type: 'vendor', owner: rechargeVendor.name, amount: formatMoney(amount), beforeBalance: formatMoney(beforeBalance), afterBalance: formatMoney(afterBalance), remark: rechargeForm.remark.trim() || '-', operator: '运营管理员', time: new Date().toLocaleString('zh-CN', { hour12: false }), status: '成功' }); } closeRechargeVendor(); } catch (error) { setActionError(explainApiError(error)); } }; const deleteVendor = async (vendor) => { setActionError(''); try { if (onDeleteVendor) { await onDeleteVendor(vendor.id); } else { if ((vendor.gateways ?? 0) > 0) { throw new Error('该供应商仍有关联落地网关,不能删除。'); } setVendorRows((rows) => rows.filter((item) => item.id !== vendor.id)); } setDeleteVendorTarget(null); } catch (error) { setActionError(explainApiError(error)); } }; return ( <> } onClick={() => setShowCreateVendor(true)}>新增供应商 : null} /> }>查询 ( {canManageVendors ? openEditVendor(row)}>编辑 : null} {canManageRecharges ? openRechargeVendor(row)}>充值 : null} {canManageVendors ? setDeleteVendorTarget(row)}>删除 : null} {!canManageVendors && !canManageRecharges ? '-' : null} ), }, ]} /> {showCreateVendor ? ( setShowCreateVendor(false)} size="sm"> 供应商名称 *}> setNewVendor({ ...newVendor, name: event.target.value })} placeholder="请输入供应商名称" required /> setShowCreateVendor(false)}>取消 保存供应商 ) : null} {editingVendor ? ( 供应商名称 *}> setEditVendorForm({ ...editVendorForm, name: event.target.value })} placeholder="请输入供应商名称" required /> 取消 保存修改 ) : null} {rechargeVendor ? ( 充值金额 *}> setRechargeForm({ ...rechargeForm, amount: event.target.value })} placeholder="请输入充值金额" required /> setRechargeForm({ ...rechargeForm, remark: event.target.value })} placeholder="请输入备注" /> 取消 确认充值 ) : null} {deleteVendorTarget ? ( setDeleteVendorTarget(null)} onConfirm={() => void deleteVendor(deleteVendorTarget)} > 确认删除供应商「{deleteVendorTarget.name}」吗?删除后该供应商将不再出现在供应商列表中。 ) : null} > ); }
确认删除供应商「{deleteVendorTarget.name}」吗?删除后该供应商将不再出现在供应商列表中。