import { useCallback, useEffect, useMemo, useState } from 'react'; import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import PullToRefresh from '@dukang/shared-ui/PullToRefresh'; import { isLoggedIn, request } from '../lib/api'; import { toastSuccess } from '../lib/toast'; import { usePartnerSession } from '../contexts/PartnerSessionContext'; import { canCreatePartnerStore, canManagePartnerStore } from '../lib/partnerAccess'; import { canPartnerOpenStore, storeAuditLabel, storeAuditPillClass, storeStatusLabel, storeStatusPillClass, type StoreStatusValue, } from '../lib/storeStatus'; type StatusFilter = 'ALL' | StoreStatusValue | 'PENDING_AUDIT' | 'REJECTED'; const FILTERS: { key: StatusFilter; label: string }[] = [ { key: 'ALL', label: '全部' }, { key: 'OPEN', label: '营业中' }, { key: 'PAUSED', label: '暂时闭店' }, { key: 'PENDING_AUDIT', label: '待审核' }, { key: 'REJECTED', label: '已驳回' }, { key: 'CLOSED', label: '关闭' }, ]; export default function StoreListPage() { const navigate = useNavigate(); const [searchParams] = useSearchParams(); const { account } = usePartnerSession(); const canMutate = canManagePartnerStore(account); const canCreate = canCreatePartnerStore(account); const [stores, setStores] = useState>>([]); const [q, setQ] = useState(''); const initialFilter = (searchParams.get('audit') === 'pending' ? 'PENDING_AUDIT' : 'ALL') as StatusFilter; const [filter, setFilter] = useState(initialFilter); const [updatingId, setUpdatingId] = useState(null); const [error, setError] = useState(''); const [closeTarget, setCloseTarget] = useState(null); const loadStores = useCallback(() => { return request>>('PARTNER_H5', '/partner/stores').then(setStores); }, []); useEffect(() => { if (!isLoggedIn()) { navigate('/login'); return; } void loadStores(); }, [navigate, loadStores]); useEffect(() => { document.title = canMutate ? '门店管理' : '我的门店'; }, [canMutate]); const filtered = useMemo(() => stores.filter((s) => { const matchQ = !q || String(s.name).includes(q) || String(s.address).includes(q); const audit = String(s.auditStatus || 'APPROVED').toUpperCase(); const status = String(s.status).toUpperCase(); let matchStatus = true; if (filter === 'PENDING_AUDIT') matchStatus = audit === 'PENDING'; else if (filter === 'REJECTED') matchStatus = audit === 'REJECTED'; else if (filter !== 'ALL') matchStatus = status === filter; return matchQ && matchStatus; }), [stores, q, filter]); async function updateStatus(storeId: string, next: StoreStatusValue, auditStatus?: string) { if (next === 'OPEN' && !canPartnerOpenStore(auditStatus)) { setError(auditStatus === 'REJECTED' ? '门店审核未通过,请查看驳回原因并修改后重新提交' : '门店尚在总部审核中,通过后方可开门'); return; } if (next === 'CLOSED') { setCloseTarget(storeId); return; } setUpdatingId(storeId); setError(''); try { await request('PARTNER_H5', `/partner/stores/${storeId}/status`, { method: 'PUT', body: JSON.stringify({ status: next }), }); await loadStores(); if (next === 'OPEN') toastSuccess('开店成功'); } catch { /* request 已 toast */ } finally { setUpdatingId(null); } } async function confirmCloseStore() { if (!closeTarget) return; const storeId = closeTarget; setCloseTarget(null); setUpdatingId(storeId); setError(''); try { await request('PARTNER_H5', `/partner/stores/${storeId}/status`, { method: 'PUT', body: JSON.stringify({ status: 'CLOSED' }), }); await loadStores(); } catch { /* request 已 toast */ } finally { setUpdatingId(null); } } return ( {error &&

{error}

}
search setQ(e.target.value)} />
{FILTERS.map((f) => ( ))}
{canCreate && ( )} {filtered.length === 0 &&
暂无门店
} {filtered.map((s) => { const storeId = String(s.id); const currentStatus = String(s.status).toUpperCase() as StoreStatusValue; const auditStatus = String(s.auditStatus || 'APPROVED').toUpperCase(); const dim = currentStatus === 'CLOSED'; const storeName = String(s.name || '未命名门店'); const busy = updatingId === storeId; const canOpen = canPartnerOpenStore(auditStatus); return (

门店名称

{storeName}

{String(s.address || s.district || '')}

{auditStatus !== 'APPROVED' && (

{storeAuditLabel(auditStatus)} {auditStatus === 'REJECTED' && s.rejectReason ? `:${String(s.rejectReason)}` : ''}

)}
{auditStatus !== 'APPROVED' ? ( {storeAuditLabel(auditStatus)} ) : ( {storeStatusLabel(currentStatus)} )}
{canMutate && (
{currentStatus === 'PAUSED' && ( )} edit
)}
); })} {closeTarget && (
setCloseTarget(null)}>
e.stopPropagation()}>

确认关闭门店?

关闭后不可恢复营业,确认关闭该门店?

)}
); }