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 WechatShareReady from '../../components/WechatShareReady'; import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../components/UserTabBar'; import BenefitFigure from '../../components/BenefitFigure'; import { goLogin } from '../../lib/auth-nav'; import { isLoggedIn, request, toast } from '../../lib/api'; import { navBarStyle, tabNavContentStyle, useNavBarMetrics } from '../../lib/nav-bar'; import { buildSceneSharePayload, toWeappShareMessage, toWeappShareTimeline, } from '../../lib/wechat-share'; import { formatMoney } from '../../lib/money'; 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; }; type RedeemHistoryItem = { id: string; redeemNo: string; amount: number; storeName: string; createdAt: string; }; 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 [redeemHistory, setRedeemHistory] = useState([]); const [tab, setTab] = useState<'available' | 'history'>('available'); const resetGuestState = useCallback(() => { setSummary(null); setCoupons([]); setRedeemHistory([]); }, []); const loadBenefit = useCallback(() => { if (!isLoggedIn()) return Promise.resolve(); return Promise.all([ request('/benefit/summary'), request('/benefit/coupons'), request<{ list?: RedeemHistoryItem[] } | RedeemHistoryItem[]>('/redeem/records?page=1&pageSize=50'), ]) .then(([s, list, records]) => { setSummary(s); setCoupons(Array.isArray(list) ? list : []); const hist = Array.isArray(records) ? records : Array.isArray(records?.list) ? records.list : []; setRedeemHistory(hist); }) .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 sharePayload = useMemo( () => buildSceneSharePayload('benefit', { path: '/pages/benefit/index', }), [], ); useShareAppMessage(() => toWeappShareMessage(sharePayload)); useShareTimeline(() => toWeappShareTimeline(sharePayload)); return ( {process.env.TARO_ENV !== 'h5' ? ( 好客权益 ) : null} 郑州市 {!loggedIn ? ( 登录后查看好客权益余额 goLogin('/pages/benefit/index')} > 去登录 ) : ( 当前好客权益余额 Taro.navigateTo({ url: '/pages/redeem/index' })} > 去使用 setTab('available')} > 可用权益 setTab('history')} > 历史记录 {tab === 'available' ? ( available.length === 0 ? ( 暂无可用权益 ) : ( available.map((c) => ( {c.sourceProduct || '好客权益'} NO. {c.couponNo} 已用 / 总额 Taro.navigateTo({ url: `/pages/redeem/index?couponId=${c.id}&amount=${c.balance}`, }) } > 立即核销 )) ) ) : redeemHistory.length === 0 ? ( 暂无核销记录 ) : ( redeemHistory.map((r) => ( {r.storeName || '门店核销'} NO. {r.redeemNo} {r.createdAt ? String(r.createdAt).slice(0, 19).replace('T', ' ') : '-'} )) )} )} {shouldRenderPageTabBar() ? : null} ); }