fix:提交修复6个问题

This commit is contained in:
ljy
2026-07-08 23:01:18 +08:00
parent 99be8e0237
commit ab9654564e
43 changed files with 3671 additions and 277 deletions
+115 -22
View File
@@ -1,36 +1,129 @@
import { useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import type { PartnerLeaderboardPeriod, PartnerLeaderboardResponse } from '@dukang/shared-types';
import PageHeader from '@dukang/shared-ui/PageHeader';
import { LEADERBOARD_MOCK } from '../lib/leaderboard';
import { fetchPartnerLeaderboard } from '../lib/leaderboard';
import { usePartnerSession } from '../contexts/PartnerSessionContext';
import { isPrimaryAccount } from '../lib/partnerAccess';
const PERIOD_TABS: { key: PartnerLeaderboardPeriod; label: string }[] = [
{ key: 'month', label: '本月' },
{ key: 'lastMonth', label: '上月' },
{ key: 'total', label: '累计' },
];
function periodStatLabel(period: PartnerLeaderboardPeriod): string {
if (period === 'month') return '本月拓店';
if (period === 'lastMonth') return '上月拓店';
return '累计拓店';
}
function periodSubLabel(period: PartnerLeaderboardPeriod): string {
if (period === 'total') return '累计';
if (period === 'month') return '本月新增';
return '上月新增';
}
export default function LeaderboardPage() {
const navigate = useNavigate();
const { account } = usePartnerSession();
const showStaffFab = isPrimaryAccount(account);
const [period, setPeriod] = useState<PartnerLeaderboardPeriod>('month');
const [data, setData] = useState<PartnerLeaderboardResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
setLoading(true);
setError('');
fetchPartnerLeaderboard(period)
.then(setData)
.catch((e) => {
setData(null);
setError(e instanceof Error ? e.message : '加载失败');
})
.finally(() => setLoading(false));
}, [period]);
return (
<div className="page-no-tab">
<PageHeader title="合伙人贡献榜" onBack={() => navigate('/')} />
<p className="label-md text-muted" style={{ padding: '0 20px 12px' }}>
</p>
<div style={{ padding: '0 20px 24px' }}>
{LEADERBOARD_MOCK.map((entry) => (
<div key={entry.rank} className="partner-leaderboard-row">
<div className="partner-leaderboard-rank">{entry.rank}</div>
<div className="partner-leaderboard-info">
<p className="headline-md">
{entry.name}
<span className="label-md text-muted" style={{ marginLeft: 6, fontWeight: 400 }}>({entry.role})</span>
</p>
<p className="label-md text-muted"> {entry.totalStores} </p>
</div>
<div className="partner-leaderboard-stat">
<p className="headline-md text-primary">{entry.monthStores} </p>
<p className="label-md text-muted"></p>
</div>
</div>
<div className="partner-leaderboard-tabs">
{PERIOD_TABS.map((tab) => (
<button
key={tab.key}
type="button"
className={`partner-leaderboard-tab${period === tab.key ? ' active' : ''}`}
onClick={() => setPeriod(tab.key)}
>
{tab.label}
</button>
))}
</div>
<p className="label-md text-muted" style={{ padding: '0 20px 12px' }}>
</p>
{loading && <div className="empty">...</div>}
{!loading && error && <div className="empty">{error}</div>}
{!loading && !error && data && (
<div style={{ padding: '0 20px 96px' }}>
{data.self && (
<section className="partner-leaderboard-self-card">
<div className="partner-leaderboard-self-main">
<div className="partner-leaderboard-self-rank"> {data.self.rank} </div>
<div>
<p className="headline-md" style={{ color: '#fff' }}>
{data.self.name}
{data.self.isSelf ? ' (我)' : ''}
</p>
<p className="label-md" style={{ color: 'rgba(255,255,255,0.8)' }}>{data.self.roleLabel}</p>
</div>
</div>
<div className="partner-leaderboard-self-stats">
<span>{periodStatLabel(period)}: {data.self.periodStores} </span>
{data.self.beatPercent != null && (
<span> {data.self.beatPercent}% </span>
)}
</div>
</section>
)}
<h2 className="headline-md" style={{ margin: '16px 0 12px' }}></h2>
{data.list.length === 0 ? (
<div className="empty"></div>
) : (
data.list.map((entry) => (
<div key={entry.accountId} className="partner-leaderboard-row">
<div className="partner-leaderboard-rank">{entry.rank}</div>
<div className="partner-leaderboard-info">
<p className="headline-md">
{entry.name}
<span className="label-md text-muted" style={{ marginLeft: 6, fontWeight: 400 }}>
({entry.roleLabel})
</span>
</p>
<p className="label-md text-muted"> {entry.totalStores} </p>
</div>
<div className="partner-leaderboard-stat">
<p className="headline-md text-primary">{entry.periodStores} </p>
<p className="label-md text-muted">{periodSubLabel(period)}</p>
</div>
</div>
))
)}
</div>
)}
{showStaffFab && (
<Link to="/center/staff" className="partner-fab-round" aria-label="子账号管理">
<span className="material-symbols-outlined">add</span>
</Link>
)}
</div>
);
}