import { useCallback, useEffect, useMemo, useState } from 'react'; import { Link } from 'react-router-dom'; import type { PartnerBillDto } from '@dukang/shared-types'; import { isWxAuthorizeEnabled } from '@dukang/shared-types'; import PullToRefresh from '@dukang/shared-ui/PullToRefresh'; import { request } from '../lib/api'; import { usePartnerSession } from '../contexts/PartnerSessionContext'; import { contactSupport } from '../lib/contact'; import { isPrimaryAccount } from '../lib/partnerAccess'; import { listPartnerStaff } from '../lib/staff'; import { toastError, toastSuccess } from '../lib/toast'; import { authorizePartnerWechat, fetchClientConfig, handlePartnerWechatLoginResult, } from '../lib/wechat-auth'; import { isWechatEnv } from '../lib/weixin'; type CenterPageProps = { /** 子账号个人中心复用 */ variant?: 'primary' | 'sub'; roleLabel?: string; }; function fmtMoney(n: number) { return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } export default function CenterPage({ variant = 'primary', roleLabel }: CenterPageProps) { const { account, logout, refresh, applySession } = usePartnerSession(); const isPrimary = variant === 'primary' && isPrimaryAccount(account); const [authorizing, setAuthorizing] = useState(false); const [bills, setBills] = useState([]); const [staffCount, setStaffCount] = useState(0); useEffect(() => { document.title = isPrimary ? '合伙人中心' : '个人中心'; }, [isPrimary]); const loadCenter = useCallback(() => { const tasks: Promise[] = [Promise.resolve(refresh())]; if (isPrimary) { tasks.push( request('PARTNER_H5', '/partner/settlement/bills') .then(setBills) .catch(() => setBills([])), listPartnerStaff() .then((list) => setStaffCount(list.length)) .catch(() => setStaffCount(0)), ); } return Promise.all(tasks).then(() => undefined); }, [isPrimary, refresh]); useEffect(() => { void loadCenter(); }, [loadCenter]); const finance = useMemo(() => { const pending = bills.filter((b) => b.status === 'AWAITING_CONFIRM'); const settled = bills.filter((b) => b.status === 'PAID'); const paidCount = settled.length; const rejectedCount = bills.filter((b) => b.status === 'REJECTED').length; return { pendingBillCount: pending.length, rejectedCount, pendingTotal: bills .filter((b) => b.status === 'AWAITING_CONFIRM' || b.status === 'UNPAID' || b.status === 'REJECTED') .reduce((s, b) => s + Number(b.totalAmount || 0), 0), settledTotal: settled.reduce((s, b) => s + Number(b.totalAmount || 0), 0), balance: settled.reduce((s, b) => s + Number(b.totalAmount || 0), 0), paidCount, }; }, [bills]); function handleContactPartner() { if (isPrimary) { if (!contactSupport()) toastError('暂无客服电话'); return; } if (!account?.primaryPhone) { toastError('暂无合伙人联系方式'); return; } window.location.href = `tel:${account.primaryPhone}`; } async function handleAvatarAuth() { if (authorizing) return; if (!isWechatEnv()) { toastError('请在微信内打开以授权头像昵称'); return; } setAuthorizing(true); try { const config = await fetchClientConfig(); if (!isWxAuthorizeEnabled(config)) { toastError('微信授权暂未开启'); return; } const result = await authorizePartnerWechat(); if (result) { const session = handlePartnerWechatLoginResult(result); if (session) applySession(session); await refresh(); toastSuccess('微信授权成功'); } // result 为空表示已跳转 OAuth,无需额外处理 } catch (e) { toastError(e instanceof Error ? e.message : '微信授权失败'); } finally { setAuthorizing(false); } } const locationLabel = [account?.companyName].filter(Boolean).join(' · ') || '—'; const displayName = account?.wxNickname?.trim() || account?.name || '合伙人'; const avatarUrl = account?.wxAvatarUrl?.trim() || ''; const badgeLabel = roleLabel || (isPrimary ? '城市合伙人' : '拓店员'); return (

{displayName}

{badgeLabel}
location_on {locationLabel}
{!isPrimary && (

{account?.phone || ''}

)}
{isPrimary && ( <>

资产概览

明细 chevron_right
{finance.pendingBillCount > 0 && (
receipt_long

{finance.rejectedCount > 0 ? '待处理账单' : '待确认账单'}

{finance.rejectedCount > 0 ? `您有 ${finance.pendingBillCount} 笔账单待处理(含 ${finance.rejectedCount} 笔已驳回)` : `您有 ${finance.pendingBillCount} 笔账单待确认`}

chevron_right )}

账户余额 (元)

{fmtMoney(finance.balance)}

待结算

¥ {fmtMoney(finance.pendingTotal)}

提现记录 history

{finance.paidCount} 笔

运营管理

badge
我的员工
{staffCount > 0 && {staffCount}人} chevron_right
receipt_long
代下单列表
chevron_right
storefront
门店审核记录
chevron_right
description
合同管理
待续约 chevron_right
)} {!isPrimary && (
emoji_events
团队贡献榜
chevron_right
)}

传承千年 · 杜康好客

); }