import React, { useState, useEffect, useMemo } from 'react' import axios from 'axios' /** * 客户报价单管理 * 数据来源:happy 后端 /api/quotes(P1 后端合并阶段开放) * 未接入前保持可用的空态,不做假数据。 */ function QuoteManagement() { const [quotes, setQuotes] = useState([]) const [loading, setLoading] = useState(true) const [keyword, setKeyword] = useState('') useEffect(() => { let alive = true axios.get('/api/quotes') .then(res => { if (alive) setQuotes(Array.isArray(res.data) ? res.data : res.data?.items || []) }) .catch(() => { if (alive) setQuotes([]) }) .finally(() => { if (alive) setLoading(false) }) return () => { alive = false } }, []) const rows = useMemo(() => { const kw = keyword.trim().toLowerCase() if (!kw) return quotes return quotes.filter(q => [q.quote_no, q.customer_name, q.customer_company].filter(Boolean).join(' ').toLowerCase().includes(kw)) }, [quotes, keyword]) const statusText = (s) => ({ draft: '草稿', sent: '已发送', accepted: '已接受', rejected: '已拒绝', expired: '已过期' }[s] || s || '—') return (

客户报价单管理

setKeyword(e.target.value)} />
{rows.length} 条
{loading ? ( ) : rows.length === 0 ? ( ) : ( rows.map(q => ( )) )}
报价单号 客户 报价日期 有效期至 金额 状态 操作
加载中...
暂无报价单
报价单接口待接入(P1 后端合并阶段开放)
{q.quote_no} {q.customer_name || q.customer_company || '—'} {q.quote_date ? new Date(q.quote_date).toLocaleDateString('zh-CN') : '—'} {q.valid_until ? new Date(q.valid_until).toLocaleDateString('zh-CN') : '—'} {q.total_amount ? `${q.currency || 'USD'} ${Number(q.total_amount).toFixed(2)}` : '—'} {statusText(q.status)}
) } export default QuoteManagement