124 lines
6.7 KiB
TypeScript
124 lines
6.7 KiB
TypeScript
import type { HydrogenCustomerRow, HydrogenStationFull } from '../../types';
|
|
import { formatKg as fmtKg, formatYuan as fmtYuan } from '../model';
|
|
|
|
export function StationSummaryTable({ stations }: { stations: HydrogenStationFull[] }) {
|
|
return (
|
|
<>
|
|
{stations.length > 0 && (
|
|
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-3 md:p-4">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<span className="text-sm font-bold text-slate-700">加氢站加氢汇总</span>
|
|
<span className="text-[11px] text-slate-400 font-bold">共 {stations.length} 站</span>
|
|
</div>
|
|
<div className="overflow-x-auto -mx-1 px-1">
|
|
<table className="w-full text-[11px]">
|
|
<thead>
|
|
<tr className="text-slate-400 font-bold border-b border-slate-100">
|
|
<th className="text-left py-1.5 pl-1 w-8">#</th>
|
|
<th className="text-left py-1.5">加氢站</th>
|
|
<th className="text-right py-1.5 w-20">加氢量</th>
|
|
<th className="text-right py-1.5 pl-2 hidden sm:table-cell">占比</th>
|
|
<th className="text-right py-1.5 pl-2 w-24">氢费收入</th>
|
|
<th className="text-right py-1.5 pr-1 hidden md:table-cell">收入占比</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{stations.map((s, i) => {
|
|
const kgFmt = fmtKg(s.kg);
|
|
const revFmt = fmtYuan(s.revenue);
|
|
return (
|
|
<tr key={s.name + i} className="border-b border-slate-50 hover:bg-slate-50/60">
|
|
<td className="py-1.5 pl-1 text-slate-400 tabular-nums">{i + 1}</td>
|
|
<td className="py-1.5 text-slate-700 truncate max-w-[180px]">{s.name}</td>
|
|
<td className="py-1.5 text-right tabular-nums font-bold text-slate-700">
|
|
{kgFmt.value}<span className="text-slate-400 font-normal ml-0.5">{kgFmt.unit}</span>
|
|
</td>
|
|
<td className="py-1.5 pl-2 text-right hidden sm:table-cell">
|
|
<div className="inline-flex items-center gap-1.5">
|
|
<div className="w-12 h-1 bg-slate-100 rounded-full overflow-hidden">
|
|
<div className="h-full bg-gradient-to-r from-cyan-400 to-blue-500" style={{ width: `${Math.min(100, s.share * 100)}%` }} />
|
|
</div>
|
|
<span className="text-slate-500 tabular-nums">{(s.share * 100).toFixed(1)}%</span>
|
|
</div>
|
|
</td>
|
|
<td className="py-1.5 pl-2 text-right tabular-nums font-bold text-emerald-600">
|
|
¥{revFmt.value}<span className="text-slate-400 font-normal ml-0.5">{revFmt.unit}</span>
|
|
</td>
|
|
<td className="py-1.5 pr-1 text-right hidden md:table-cell">
|
|
<div className="inline-flex items-center gap-1.5">
|
|
<div className="w-12 h-1 bg-slate-100 rounded-full overflow-hidden">
|
|
<div className="h-full bg-gradient-to-r from-emerald-400 to-emerald-600" style={{ width: `${Math.min(100, s.revenueShare * 100)}%` }} />
|
|
</div>
|
|
<span className="text-slate-500 tabular-nums">{(s.revenueShare * 100).toFixed(1)}%</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function CustomerSummaryTable({ customers }: { customers: HydrogenCustomerRow[] }) {
|
|
return (
|
|
<>
|
|
{customers.length > 0 && (
|
|
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-3 md:p-4">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<span className="text-sm font-bold text-slate-700">客户账单汇总</span>
|
|
<span className="text-[11px] text-slate-400 font-bold">Top {customers.length}</span>
|
|
</div>
|
|
<div className="overflow-x-auto -mx-1 px-1">
|
|
<table className="w-full text-[11px]">
|
|
<thead>
|
|
<tr className="text-slate-400 font-bold border-b border-slate-100">
|
|
<th className="text-left py-1.5 pl-1 w-8">#</th>
|
|
<th className="text-left py-1.5">客户</th>
|
|
<th className="text-center py-1.5 w-14 hidden sm:table-cell">承担方</th>
|
|
<th className="text-right py-1.5 w-20">加氢量</th>
|
|
<th className="text-right py-1.5 pl-2 w-24">成本支出</th>
|
|
<th className="text-right py-1.5 pr-1 w-24 hidden md:table-cell">应收</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{customers.map((c2, i) => {
|
|
const kgFmt = fmtKg(c2.kg);
|
|
const costFmt = fmtYuan(c2.cost);
|
|
const revFmt = fmtYuan(c2.revenue);
|
|
return (
|
|
<tr key={c2.name + i} className="border-b border-slate-50 hover:bg-slate-50/60">
|
|
<td className="py-1.5 pl-1 text-slate-400 tabular-nums">{i + 1}</td>
|
|
<td className="py-1.5 text-slate-700 truncate max-w-[200px]">{c2.name}</td>
|
|
<td className="py-1.5 text-center hidden sm:table-cell">
|
|
{c2.payer === 'lingniu' ? (
|
|
<span className="px-1.5 py-0.5 rounded bg-blue-50 text-blue-600 text-[10px] font-bold">羚牛</span>
|
|
) : (
|
|
<span className="px-1.5 py-0.5 rounded bg-amber-50 text-amber-600 text-[10px] font-bold">客户</span>
|
|
)}
|
|
</td>
|
|
<td className="py-1.5 text-right tabular-nums font-bold text-slate-700">
|
|
{kgFmt.value}<span className="text-slate-400 font-normal ml-0.5">{kgFmt.unit}</span>
|
|
</td>
|
|
<td className="py-1.5 pl-2 text-right tabular-nums text-amber-600 font-bold">
|
|
¥{costFmt.value}<span className="text-slate-400 font-normal ml-0.5">{costFmt.unit}</span>
|
|
</td>
|
|
<td className="py-1.5 pr-1 text-right tabular-nums text-emerald-600 font-bold hidden md:table-cell">
|
|
¥{revFmt.value}<span className="text-slate-400 font-normal ml-0.5">{revFmt.unit}</span>
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|