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
+64 -36
View File
@@ -1,26 +1,34 @@
import { useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import type { PartnerLeaderboardEntry } from '@dukang/shared-types';
import { isLoggedIn, request } from '../lib/api';
import { LEADERBOARD_MOCK } from '../lib/leaderboard';
import { storeStatusLabel } from '../lib/storeStatus';
import { fetchPartnerLeaderboard } from '../lib/leaderboard';
import { storeStatusLabel, storeStatusPillClass } from '../lib/storeStatus';
function fmtMoney(n: number) {
return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
const HOME_STORE_PREVIEW_LIMIT = 6;
export default function HomePage() {
const navigate = useNavigate();
const [dash, setDash] = useState<Record<string, unknown> | null>(null);
const [stores, setStores] = useState<Array<Record<string, unknown>>>([]);
const [leaderboardPreview, setLeaderboardPreview] = useState<PartnerLeaderboardEntry[]>([]);
useEffect(() => {
if (!isLoggedIn()) { navigate('/login'); return; }
request<Record<string, unknown>>('PARTNER_H5', '/partner/dashboard').then(setDash);
request<Array<Record<string, unknown>>>('PARTNER_H5', '/partner/stores').then(setStores);
fetchPartnerLeaderboard('month')
.then((data) => setLeaderboardPreview(data.list.slice(0, 2)))
.catch(() => setLeaderboardPreview([]));
}, [navigate]);
const storeCount = Number(dash?.storeCount || stores.length || 0);
const orderCount = Number(dash?.orderCount || 0);
const pendingAuditCount = Number(dash?.pendingAuditCount || 0);
const activeStores = stores.filter((s) => String(s.status).toUpperCase() === 'OPEN').length;
const abnormalStores = Math.max(0, storeCount - activeStores);
const revenue = orderCount * 128.45;
@@ -34,9 +42,7 @@ export default function HomePage() {
return created.getMonth() === now.getMonth() && created.getFullYear() === now.getFullYear();
}).length;
const recentFromDash = (dash?.recentStores as Array<Record<string, unknown>> | undefined) ?? [];
const displayStores = stores.length > 0 ? stores : recentFromDash;
const previewLeaderboard = LEADERBOARD_MOCK.slice(0, 2);
const previewStores = stores.slice(0, HOME_STORE_PREVIEW_LIMIT);
return (
<div className="page partner-home">
@@ -107,7 +113,7 @@ export default function HomePage() {
</div>
<span className="partner-quick-action-label"></span>
</Link>
<Link to="/center/bills" className="partner-quick-action">
<Link to="/center/settlement" className="partner-quick-action">
<div className="partner-quick-action-icon partner-quick-action-icon--green">
<span className="material-symbols-outlined">account_balance</span>
</div>
@@ -146,6 +152,35 @@ export default function HomePage() {
</div>
</section>
<section className="partner-home-store-section">
<div className="partner-home-store-header">
<h2 className="headline-md"></h2>
<Link to="/stores" className="label-md text-primary"></Link>
</div>
{previewStores.length === 0 ? (
<div className="partner-home-store-empty">
<p className="label-md text-muted"></p>
<Link to="/stores/new" className="label-md text-primary"></Link>
</div>
) : (
previewStores.map((s) => {
const storeId = String(s.id);
const status = String(s.status || 'PAUSED').toUpperCase();
return (
<Link key={storeId} to={`/stores/${storeId}`} className="partner-home-store-row">
<div className="partner-home-store-info">
<p className="headline-md">{String(s.name || '未命名门店')}</p>
<p className="label-md text-muted">{String(s.address || s.district || '')}</p>
</div>
<span className={`partner-status-pill ${storeStatusPillClass(status)}`}>
{storeStatusLabel(status)}
</span>
</Link>
);
})
)}
</section>
<section className="partner-expansion-card">
<h2 className="headline-md" style={{ marginBottom: 16 }}></h2>
<div className="partner-expansion-split">
@@ -155,23 +190,12 @@ export default function HomePage() {
<span className="headline-lg" style={{ fontSize: 24 }}>{monthNew}</span>
</div>
</div>
<div>
<p className="label-md text-muted" style={{ marginBottom: 4 }}></p>
<span className="headline-lg" style={{ fontSize: 24 }}>{pendingAuditCount}</span>
</div>
</div>
{displayStores.length > 0 && (
<ul className="partner-store-name-list">
<li className="partner-store-name-list-header">
<span className="label-md text-muted"></span>
<span className="label-md text-muted"></span>
</li>
{displayStores.slice(0, 5).map((s) => (
<li key={String(s.id)}>
<span className="headline-md">{String(s.name || '未命名门店')}</span>
<span className="label-md text-muted">{storeStatusLabel(String(s.status))}</span>
</li>
))}
</ul>
)}
<div className="partner-leaderboard-section">
<div className="partner-leaderboard-header">
<h3 className="headline-md" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
@@ -180,22 +204,26 @@ export default function HomePage() {
</h3>
<Link to="/leaderboard" className="label-md text-primary"></Link>
</div>
{previewLeaderboard.map((entry) => (
<div key={entry.rank} className="partner-leaderboard-row partner-leaderboard-row--compact">
<div className="partner-leaderboard-rank">{entry.rank}</div>
<div className="partner-leaderboard-info">
<p className="body-md" style={{ fontWeight: 600 }}>
{entry.name}
<span className="label-md text-muted" style={{ marginLeft: 4 }}>({entry.role})</span>
</p>
<p className="label-md text-muted"> {entry.totalStores} </p>
{leaderboardPreview.length === 0 ? (
<p className="label-md text-muted"></p>
) : (
leaderboardPreview.map((entry) => (
<div key={entry.accountId} className="partner-leaderboard-row partner-leaderboard-row--compact">
<div className="partner-leaderboard-rank">{entry.rank}</div>
<div className="partner-leaderboard-info">
<p className="body-md" style={{ fontWeight: 600 }}>
{entry.name}
<span className="label-md text-muted" style={{ marginLeft: 4 }}>({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"></p>
</div>
</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>
<p className="label-md text-muted" style={{ paddingTop: 16, borderTop: '1px solid rgba(226,190,188,0.1)' }}>