import { useCallback, useMemo, useState } from 'react'; import { View, Text, Image } from '@tarojs/components'; import Taro, { useDidShow, usePullDownRefresh, useShareAppMessage, useShareTimeline } from '@tarojs/taro'; import PageShell from '../../components/PageShell'; import ShareNavButton from '../../components/ShareNavButton'; import WechatShareReady from '../../components/WechatShareReady'; import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../components/UserTabBar'; import { goLogin } from '../../lib/auth-nav'; import { isLoggedIn, request, toast } from '../../lib/api'; import { navBarStyle, tabNavContentStyle, useNavBarMetrics } from '../../lib/nav-bar'; import { DEFAULT_SHARE_DESC, DEFAULT_SHARE_TITLE, toWeappShareMessage, } from '../../lib/wechat-share'; import iconBenefit from '../../assets/tabbar/benefit-active.png'; type BenefitSummary = { totalBalance: number; maxRedeemAmount: number; activeCouponCount: number; }; type CouponItem = { id: string; couponNo: string; totalAmount: number; usedAmount: number; balance: number; status: string; sourceProduct: string; }; function formatMoney(amount: number) { return amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } function usagePercent(coupon: CouponItem) { const total = Number(coupon.totalAmount); if (total <= 0) return 0; return Math.min(100, Math.round((Number(coupon.usedAmount) / total) * 100)); } export default function BenefitPage() { const metrics = useNavBarMetrics(); const [loggedIn, setLoggedIn] = useState(() => isLoggedIn()); const [summary, setSummary] = useState(null); const [coupons, setCoupons] = useState([]); const [tab, setTab] = useState<'available' | 'history'>('available'); const resetGuestState = useCallback(() => { setSummary(null); setCoupons([]); }, []); const loadBenefit = useCallback(() => { if (!isLoggedIn()) return Promise.resolve(); return Promise.all([ request('/benefit/summary'), request('/benefit/coupons'), ]) .then(([s, list]) => { setSummary(s); setCoupons(Array.isArray(list) ? list : []); }) .catch((e) => toast(e instanceof Error ? e.message : '加载失败')); }, []); useDidShow(() => { syncTabBarSelected(2); const loggedInNow = isLoggedIn(); setLoggedIn(loggedInNow); if (loggedInNow) { void loadBenefit(); } else { resetGuestState(); } }); usePullDownRefresh(() => { const loggedInNow = isLoggedIn(); setLoggedIn(loggedInNow); if (!loggedInNow) { resetGuestState(); Taro.stopPullDownRefresh(); return; } void loadBenefit().finally(() => Taro.stopPullDownRefresh()); }); const available = coupons.filter((c) => c.status === 'ACTIVE' && c.balance > 0); const history = coupons.filter((c) => c.status === 'USED_UP' || c.status === 'VOID'); const visible = tab === 'available' ? available : history; const sharePayload = useMemo( () => ({ title: '好客权益 · 杜康好客', desc: DEFAULT_SHARE_DESC, path: '/pages/benefit/index', }), [], ); useShareAppMessage(() => toWeappShareMessage(sharePayload)); useShareTimeline(() => ({ title: sharePayload.title || DEFAULT_SHARE_TITLE, query: '', imageUrl: sharePayload.imgUrl, })); return ( {process.env.TARO_ENV !== 'h5' ? ( 好客权益 ) : null} 郑州市 {!loggedIn ? ( 登录后查看好客权益余额 goLogin('/pages/benefit/index')} > 去登录 ) : ( 当前好客权益余额 ¥ {summary ? formatMoney(summary.totalBalance) : '--'} Taro.navigateTo({ url: '/pages/redeem/index' })} > 去使用 setTab('available')} > 可用权益 setTab('history')} > 历史记录 {visible.length === 0 ? ( {tab === 'available' ? '暂无可用权益' : '暂无历史记录'} ) : ( visible.map((c) => ( {c.sourceProduct || '好客权益'} ¥{formatMoney(c.balance)} NO. {c.couponNo} 已用 ¥{formatMoney(c.usedAmount)} / 总额 ¥{formatMoney(c.totalAmount)} {tab === 'available' ? ( Taro.navigateTo({ url: `/pages/redeem/index?couponId=${c.id}&amount=${c.balance}`, }) } > 立即核销 ) : null} )) )} )} {shouldRenderPageTabBar() ? : null} ); }