This commit is contained in:
2026-06-30 10:33:56 +08:00
commit 6e047dc0a5
607 changed files with 65966 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
import { useEffect, useMemo, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import PageHeader from '@dukang/shared-ui/PageHeader';
import { isLoggedIn, request } from '../lib/api';
type DateFilter = 'today' | '7d' | '30d';
type StatusFilter = 'ALL' | 'PENDING_SHIP' | 'SHIPPING' | 'COMPLETED' | 'ABNORMAL';
function orderStatusLabel(status: string) {
const s = String(status).toUpperCase();
if (s.includes('SHIP') || s === 'OUT_WAREHOUSE') return { label: '运输中', color: 'var(--color-status-blue)' };
if (s === 'COMPLETED') return { label: '已完成', color: 'var(--color-success-green)' };
if (s.includes('PENDING') || s === 'PAID') return { label: '待发货', color: 'var(--color-secondary)' };
if (s.includes('ERROR') || s.includes('ABNORMAL')) return { label: '异常', color: 'var(--color-error)' };
return { label: status, color: 'var(--color-subtle-gray)' };
}
const DATE_FILTERS: { key: DateFilter; label: string }[] = [
{ key: 'today', label: '今日' },
{ key: '7d', label: '近7天' },
{ key: '30d', label: '近30天' },
];
const STATUS_FILTERS: { key: StatusFilter; label: string }[] = [
{ key: 'ALL', label: '全部' },
{ key: 'PENDING_SHIP', label: '待发货' },
{ key: 'SHIPPING', label: '运输中' },
{ key: 'COMPLETED', label: '已完成' },
{ key: 'ABNORMAL', label: '异常' },
];
export default function OrderListPage() {
const navigate = useNavigate();
const [data, setData] = useState<{ list: Array<Record<string, unknown>> }>({ list: [] });
const [tab, setTab] = useState<'orders' | 'coupons'>('orders');
const [dateFilter, setDateFilter] = useState<DateFilter>('today');
const [statusFilter, setStatusFilter] = useState<StatusFilter>('ALL');
useEffect(() => {
if (!isLoggedIn()) { navigate('/login'); return; }
request('PARTNER_H5', '/partner/orders').then(setData);
}, [navigate]);
const filtered = useMemo(() => data.list.filter((o) => {
if (statusFilter === 'ALL') return true;
const s = String(o.status).toUpperCase();
if (statusFilter === 'PENDING_SHIP') return s.includes('PENDING') || s === 'PAID';
if (statusFilter === 'SHIPPING') return s.includes('SHIP') || s === 'OUT_WAREHOUSE';
if (statusFilter === 'COMPLETED') return s === 'COMPLETED';
if (statusFilter === 'ABNORMAL') return s.includes('ERROR') || s.includes('ABNORMAL');
return true;
}), [data.list, statusFilter]);
return (
<div className="page-no-tab partner-orders-page">
<PageHeader title="订单中心" onBack={() => navigate('/')} />
<div className="partner-segment">
<button type="button" className={tab === 'orders' ? 'active' : ''} onClick={() => setTab('orders')}></button>
<button type="button" className={tab === 'coupons' ? 'active' : ''} onClick={() => setTab('coupons')}></button>
</div>
{tab === 'orders' && (
<>
<div className="partner-filter-row" style={{ marginBottom: 8 }}>
{DATE_FILTERS.map((f) => (
<button key={f.key} type="button" className={`partner-chip${dateFilter === f.key ? ' active' : ''}`} style={{ border: dateFilter === f.key ? 'none' : '1px solid var(--color-outline-variant)', background: dateFilter === f.key ? undefined : '#fff' }} onClick={() => setDateFilter(f.key)}>
{f.label}
</button>
))}
</div>
<div className="partner-filter-row" style={{ borderBottom: '1px solid var(--color-surface-container-high)', paddingBottom: 8, marginBottom: 16 }}>
{STATUS_FILTERS.map((f) => (
<button key={f.key} type="button" className={`partner-filter-tab${statusFilter === f.key ? ' active' : ''}`} onClick={() => setStatusFilter(f.key)}>
{f.label}
</button>
))}
</div>
{filtered.length === 0 && <div className="empty"></div>}
{filtered.map((o) => {
const st = orderStatusLabel(String(o.status));
const payAmount = Number(o.payAmount || 0);
return (
<Link key={String(o.id)} to={`/orders/${o.id}`} className="partner-order-card">
<div className="partner-order-card-top">
<span className="label-md text-muted">NO. {String(o.orderNo)}</span>
<span className="label-md" style={{ color: st.color, fontWeight: 600 }}>{st.label}</span>
</div>
<div className="partner-order-product">
<div className="partner-order-product-img" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<span className="material-symbols-outlined text-muted">liquor</span>
</div>
<div style={{ flex: 1, minWidth: 0 }}>
<h3 className="headline-md line-2-clamp">{String(o.productName || '杜康好酒')}</h3>
<p className="text-variant body-md" style={{ marginTop: 4 }}>¥{payAmount.toFixed(2)}</p>
<span className="partner-benefit-tag">
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>confirmation_number</span>
¥{Math.round(payAmount * 0.2)}
</span>
</div>
</div>
<div className="partner-order-address">
<span className="material-symbols-outlined" style={{ fontSize: 18 }}>location_on</span>
<p className="line-2-clamp">{String(o.receiverAddress || '收货地址')}</p>
</div>
<div className="partner-order-commission">
<div>
<p className="label-md text-muted"></p>
<p className="headline-md text-primary" style={{ marginTop: 4 }}>¥{(payAmount * 0.04).toFixed(2)}</p>
</div>
<div>
<p className="label-md text-muted"></p>
<p className="headline-md text-primary" style={{ marginTop: 4 }}>¥0.00</p>
</div>
<div>
<p className="label-md text-muted"></p>
<p className="headline-md" style={{ marginTop: 4, color: 'var(--color-aged-amber)' }}>¥{Math.round(payAmount * 0.2)}</p>
</div>
</div>
</Link>
);
})}
</>
)}
{tab === 'coupons' && (
<div style={{ padding: '0 20px' }}>
<div className="partner-revenue-card" style={{ marginBottom: 16 }}>
<p className="partner-revenue-label"></p>
<div className="partner-revenue-amount" style={{ fontSize: 28 }}>42,800.00</div>
</div>
<p className="text-muted body-md text-center"> preV1 </p>
</div>
)}
</div>
);
}