import React, { useState, useEffect } from 'react' import { View, Text, ScrollView } from '@tarojs/components' import Taro from '@tarojs/taro' import { useRequest } from '@/hooks/useRequest' import { pageUserPointsLog, getUserPointsInfo, type UserPointsInfo } from '@/api/system/user/points' definePageConfig({ navigationBarTitleText: '积分明细', enablePullDownRefresh: true, }) // 积分类型映射 const TYPE_MAP: Record = { 1: { label: '获得', icon: '📈', color: 'text-green-600', bgColor: 'bg-green-50' }, 2: { label: '消费', icon: '📉', color: 'text-red-500', bgColor: 'bg-red-50' }, 3: { label: '过期', icon: '⏰', color: 'text-gray-500', bgColor: 'bg-gray-50' }, 4: { label: '调整', icon: '🔧', color: 'text-blue-500', bgColor: 'bg-blue-50' }, } const tabs = [ { label: '全部', value: -1 }, { label: '获得', value: 1 }, { label: '消费', value: 2 }, { label: '过期', value: 3 }, ] const PointsRecordPage: React.FC = () => { const [activeTab, setActiveTab] = useState(-1) const [page, setPage] = useState(1) const [logs, setLogs] = useState([]) const [hasMore, setHasMore] = useState(true) const [pointsInfo, setPointsInfo] = useState({ points: 0, totalEarned: 0, totalUsed: 0, expiringSoon: 0 }) // 获取积分统计信息 const { run: fetchPointsInfo, loading: infoLoading } = useRequest(getUserPointsInfo, { manual: true, onSuccess: (data) => { setPointsInfo(data) }, onError: (err) => { console.error('获取积分信息失败:', err) } }) // 获取积分记录 const { run: fetchLogs, loading } = useRequest(pageUserPointsLog, { manual: true, onSuccess: (data) => { if (data?.list) { if (page === 1) { setLogs(data.list) } else { setLogs(prev => [...prev, ...data.list]) } setHasMore(data.list.length >= 20) } Taro.stopPullDownRefresh() }, onError: (err) => { Taro.showToast({ title: err.message || '加载失败', icon: 'none' }) Taro.stopPullDownRefresh() } }) // 加载数据 const loadData = (pageNum: number = 1) => { const params: any = { page: pageNum, limit: 20 } if (activeTab !== -1) { params.type = activeTab } fetchLogs(params) } // 初始化加载 useEffect(() => { setPage(1) loadData(1) fetchPointsInfo() // 加载积分统计信息 }, [activeTab]) // 下拉刷新(Taro 自动识别此函数) function onPullDownRefresh() { setPage(1) loadData(1) } // 加载更多 const loadMore = () => { if (loading || !hasMore) return const nextPage = page + 1 setPage(nextPage) loadData(nextPage) } // 格式化积分 const formatPoints = (points?: number) => { if (!points && points !== 0) return '0' return points > 0 ? `+${points}` : String(points) } // 获取类型信息 const getTypeInfo = (type?: number) => { return TYPE_MAP[type || 0] || { label: '未知', icon: '❓', color: 'text-gray-500', bgColor: 'bg-gray-50' } } // 格式化时间 const formatTime = (timeStr?: string) => { if (!timeStr) return '' const date = new Date(timeStr) const month = (date.getMonth() + 1).toString().padStart(2, '0') const day = date.getDate().toString().padStart(2, '0') const hour = date.getHours().toString().padStart(2, '0') const minute = date.getMinutes().toString().padStart(2, '0') return `${month}-${day} ${hour}:${minute}` } // 按日期分组 const groupLogsByDate = () => { const groups: { date: string; logs: UserPointsLog[] }[] = [] let currentDate = '' let currentGroup: UserPointsLog[] = [] logs.forEach(log => { const date = log.createTime ? log.createTime.split(' ')[0] : '' if (date !== currentDate) { if (currentGroup.length > 0) { groups.push({ date: currentDate, logs: currentGroup }) } currentDate = date currentGroup = [log] } else { currentGroup.push(log) } }) if (currentGroup.length > 0) { groups.push({ date: currentDate, logs: currentGroup }) } return groups } const groupedLogs = groupLogsByDate() return ( {/* 顶部统计卡片 */} {infoLoading ? '-' : pointsInfo.points.toLocaleString()} 当前积分 {infoLoading ? '-' : `+${pointsInfo.totalEarned.toLocaleString()}`} 累计获得 {infoLoading ? '-' : `-${pointsInfo.totalUsed.toLocaleString()}`} 累计使用 {/* Tab 栏 */} {tabs.map(tab => ( setActiveTab(tab.value)} > {tab.label} {activeTab === tab.value && ( )} ))} {/* 日志列表 */} {logs.length === 0 && !loading ? ( 📊 暂无积分记录 快去购物、签到获取积分吧 ) : ( {groupedLogs.map(group => ( {/* 日期分隔 */} {group.date} {/* 当日记录 */} {group.logs.map(log => { const typeInfo = getTypeInfo(log.type) return ( {typeInfo.icon} {log.reason || typeInfo.label} {formatTime(log.createTime)} {log.orderId && ( 订单: {log.orderId} )} {formatPoints(log.points)} ) })} ))} {/* 加载更多 */} {hasMore && ( {loading ? '加载中...' : '上拉加载更多'} )} {!hasMore && logs.length > 0 && ( — 已经到底了 — )} )} ) } export default PointsRecordPage