import React, { useState, useCallback } from 'react'; import { View, Text } from '@tarojs/components'; import Taro, { useReachBottom } from '@tarojs/taro'; import { usePageData } from '@/hooks/usePageData'; import { listMyOrders } from '../../../services/points'; import type { PointsOrder } from '../../../services/points'; import EmptyState from '../../../components/EmptyState'; import Loading from '../../../components/Loading'; import { useElderClass } from '../../../hooks/useElderClass'; import './index.scss'; const STATUS_TABS = [ { key: '', label: '全部' }, { key: 'pending', label: '待核销' }, { key: 'verified', label: '已核销' }, { key: 'expired', label: '已过期' }, ]; const STATUS_CONFIG: Record = { pending: { label: '待核销', cls: 'order-status-tag--pending' }, verified: { label: '已核销', cls: 'order-status-tag--verified' }, cancelled: { label: '已取消', cls: 'order-status-tag--cancelled' }, expired: { label: '已过期', cls: 'order-status-tag--expired' }, }; export default function MallOrders() { const modeClass = useElderClass(); const [orders, setOrders] = useState([]); const [activeTab, setActiveTab] = useState(''); const [page, setPage] = useState(1); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); const fetchOrders = useCallback( async (pageNum: number, status: string, isRefresh = false) => { setLoading(true); try { const res = await listMyOrders({ page: pageNum, page_size: 10, }); let list = res.data || []; if (status) { list = list.filter((o) => o.status === status); } if (isRefresh) { setOrders(list); } else { setOrders((prev) => [...prev, ...list]); } setTotal(res.total); setPage(pageNum); } catch { Taro.showToast({ title: '加载失败', icon: 'none' }); } finally { setLoading(false); } }, [], ); const loadAll = useCallback( async (status?: string) => { const s = status !== undefined ? status : activeTab; await fetchOrders(1, s, true); }, [fetchOrders, activeTab], ); usePageData( useCallback(async () => { Taro.setNavigationBarTitle({ title: '我的订单' }); await loadAll(); }, [loadAll]), { throttleMs: 10000, enablePullDown: true }, ); useReachBottom(() => { if (!loading && orders.length < total) { fetchOrders(page + 1, activeTab); } }); const handleTabChange = (key: string) => { setActiveTab(key); fetchOrders(1, key, true); }; const handleShowQrCode = (qrCode: string) => { Taro.showModal({ title: '核销码', content: qrCode, showCancel: false, confirmText: '知道了', }); }; const getStatusConfig = (status: string) => { return STATUS_CONFIG[status] || { label: status, cls: 'order-status-tag--expired' }; }; const formatDate = (dateStr: string) => { if (!dateStr) return ''; const d = new Date(dateStr); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`; }; return ( {/* 状态筛选标签 */} {STATUS_TABS.map((tab) => ( handleTabChange(tab.key)} > {tab.label} ))} {/* 订单列表 */} {orders.length === 0 && !loading ? ( Taro.switchTab({ url: '/pages/mall/index' })} /> ) : ( {orders.map((order) => { const statusCfg = getStatusConfig(order.status); return ( 商品 {order.product_id.slice(0, 8)} {statusCfg.label} 消耗积分 {order.points_cost.toLocaleString()} 兑换时间 {formatDate(order.created_at)} {order.status === 'pending' && ( handleShowQrCode(order.qr_code)}> 核销码 {order.qr_code} 查看 )} ); })} {loading && } {!loading && orders.length >= total && total > 0 && ( )} )} ); }