Files
happy-export/frontend/src/pages/PiContractManagement.jsx
T

97 lines
3.5 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect, useMemo } from 'react'
import axios from 'axios'
/**
* PI 合同管理(Proforma Invoice)
* 数据来源:happy 后端 /api/pi-contracts(P1 后端合并阶段开放)
*/
function PiContractManagement() {
const [contracts, setContracts] = useState([])
const [loading, setLoading] = useState(true)
const [keyword, setKeyword] = useState('')
useEffect(() => {
let alive = true
axios.get('/api/pi-contracts')
.then(res => { if (alive) setContracts(Array.isArray(res.data) ? res.data : res.data?.items || []) })
.catch(() => { if (alive) setContracts([]) })
.finally(() => { if (alive) setLoading(false) })
return () => { alive = false }
}, [])
const rows = useMemo(() => {
const kw = keyword.trim().toLowerCase()
if (!kw) return contracts
return contracts.filter(c => [c.pi_no, c.customer_name, c.customer_company].filter(Boolean).join(' ').toLowerCase().includes(kw))
}, [contracts, keyword])
const statusText = (s) => ({ draft: '草稿', signed: '已签署', deposited: '已收定金', producing: '生产中', shipped: '已出运', closed: '已结案' }[s] || s || '—')
return (
<div className="page-container">
<div className="page-header">
<h1 className="page-title">PI 合同管理</h1>
<button className="btn btn-primary">+ 新建 PI</button>
</div>
<div className="toolbar">
<input
type="text"
className="toolbar-search"
placeholder="搜索 PI 编号 / 客户"
value={keyword}
onChange={e => setKeyword(e.target.value)}
/>
<div className="toolbar-actions">
<span className="secondary">{rows.length} 条</span>
</div>
</div>
<div className="table-container">
<table className="data-table">
<thead>
<tr>
<th>PI 编号</th>
<th>客户</th>
<th>签订日期</th>
<th>金额</th>
<th>收款条件</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{loading ? (
<tr><td colSpan="7" className="empty-state">加载中...</td></tr>
) : rows.length === 0 ? (
<tr>
<td colSpan="7" className="empty-state">
<div className="empty-state-title">暂无 PI 合同</div>
<div className="empty-state-hint">PI 合同接口待接入(P1 后端合并阶段开放)</div>
</td>
</tr>
) : (
rows.map(c => (
<tr key={c.id}>
<td><strong>{c.pi_no}</strong></td>
<td>{c.customer_name || c.customer_company || '—'}</td>
<td>{c.signed_date ? new Date(c.signed_date).toLocaleDateString('zh-CN') : '—'}</td>
<td>{c.total_amount ? `${c.currency || 'USD'} ${Number(c.total_amount).toFixed(2)}` : '—'}</td>
<td>{c.payment_terms || '—'}</td>
<td><span className={`status-badge status-${c.status}`}>{statusText(c.status)}</span></td>
<td>
<button className="btn-link">查看</button>
<button className="btn-link">生成单据</button>
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
)
}
export default PiContractManagement