193 lines
7.8 KiB
TypeScript
193 lines
7.8 KiB
TypeScript
import { View, Text, ScrollView, Image } from '@tarojs/components'
|
|
import Taro from '@tarojs/taro'
|
|
import { useState, useEffect } from 'react'
|
|
import './index.scss'
|
|
import { getOrderList, type OrderItem } from '../../utils/store'
|
|
import { PRODUCT_ICON_MAP } from '../../utils/productConfig'
|
|
import { assetUrl } from '../../utils/asset'
|
|
import { useThemeContext } from '../../context/ThemeContext'
|
|
import { useSafeArea } from '../../hooks/useSafeArea'
|
|
import { useStatusBar } from '../../hooks/useStatusBar'
|
|
import LoginGuard from '../../components/LoginGuard'
|
|
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
|
|
|
const STATUS_TABS = [
|
|
{ code: 'all', label: '全部' },
|
|
{ code: 'pending', label: '待付款' },
|
|
{ code: 'paid', label: '待发货' },
|
|
{ code: 'shipping', label: '待收货' },
|
|
{ code: 'done', label: '已完成' }
|
|
]
|
|
|
|
const STATUS_MAP: Record<string, { label: string; badge: string }> = {
|
|
pending: { label: '待付款', badge: 'badge-pink' },
|
|
paid: { label: '待发货', badge: 'badge-blue' },
|
|
shipping: { label: '待收货', badge: 'badge-blue' },
|
|
done: { label: '已完成', badge: 'badge-green' },
|
|
cancelled: { label: '已取消', badge: 'badge-gray' }
|
|
}
|
|
|
|
export default function OrdersPage() {
|
|
const { theme, resolvedTheme } = useThemeContext()
|
|
const safe = useSafeArea()
|
|
useStatusBar(resolvedTheme)
|
|
const [activeTab, setActiveTab] = useState('all')
|
|
const [orders, setOrders] = useState<OrderItem[]>([])
|
|
|
|
const load = () => setOrders(getOrderList())
|
|
|
|
useEffect(load, [])
|
|
|
|
// 读取从 profile 跳转过来的筛选状态
|
|
useEffect(() => {
|
|
const init = () => {
|
|
const filter = Taro.getStorageSync('orders:filter')
|
|
if (filter && STATUS_TABS.some(t => t.code === filter)) {
|
|
setActiveTab(filter)
|
|
Taro.removeStorageSync('orders:filter')
|
|
}
|
|
load()
|
|
}
|
|
init()
|
|
// 页面每次显示时刷新
|
|
const page = Taro.getCurrentInstance().page
|
|
if (page) {
|
|
const orig = page.onShow
|
|
page.onShow = function () {
|
|
init()
|
|
if (orig) orig.apply(this)
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
// 页面每次显示时刷新(处理下单后同步)
|
|
useEffect(() => {
|
|
Taro.eventCenter?.once?.('orders:refresh', load)
|
|
load()
|
|
return () => { Taro.eventCenter?.off?.('orders:refresh', load) }
|
|
}, [])
|
|
|
|
const filteredOrders = activeTab === 'all'
|
|
? orders
|
|
: orders.filter(o => o.statusCode === activeTab)
|
|
|
|
const goDetail = (order: OrderItem) => {
|
|
Taro.navigateTo({ url: `/pages/orderDetail/index?orderId=${order.id}` })
|
|
}
|
|
|
|
return (
|
|
<View className={`theme-${resolvedTheme}`}>
|
|
<ThemedPageMeta />
|
|
<LoginGuard>
|
|
<View className='orders-page'>
|
|
|
|
<View className='page-header dashed-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
|
<View className='star-badge' />
|
|
<Text className='page-title'>我的订单</Text>
|
|
</View>
|
|
|
|
{/* 状态筛选Tab */}
|
|
<View className='status-tabs'>
|
|
<ScrollView className='tabs-scroll' scrollX>
|
|
{STATUS_TABS.map((tab) => (
|
|
<View
|
|
key={tab.code}
|
|
className={`tab-item ${activeTab === tab.code ? 'active' : ''}`}
|
|
onTap={() => setActiveTab(tab.code)}
|
|
>
|
|
<Text className='tab-label'>{tab.label}</Text>
|
|
{activeTab === tab.code && <View className='tab-underline' />}
|
|
</View>
|
|
))}
|
|
</ScrollView>
|
|
</View>
|
|
|
|
{/* 订单列表 */}
|
|
<ScrollView className='orders-list' scrollY>
|
|
{filteredOrders.map((order) => {
|
|
const status = STATUS_MAP[order.statusCode] || STATUS_MAP.pending
|
|
const rawIcon = order.productIcon?.startsWith('/icon/') || /^https?:/i.test(order.productIcon || '')
|
|
? order.productIcon
|
|
: '/icon/四角星.svg'
|
|
const iconSrc = assetUrl(rawIcon)
|
|
return (
|
|
<View key={order.id} className='order-card dashed-card' onTap={() => goDetail(order)}>
|
|
<View className='star-badge' />
|
|
<View className='order-header'>
|
|
<Text className='order-date'>{order.date}</Text>
|
|
<Text className={`badge ${status.badge}`}>{status.label}</Text>
|
|
</View>
|
|
<View className='order-body'>
|
|
<View className='order-icon-wrapper'>
|
|
<Image className='order-icon-img' src={iconSrc} mode='aspectFit' />
|
|
</View>
|
|
<View className='order-info'>
|
|
<Text className='order-product'>{order.productName}</Text>
|
|
<Text className='order-sku'>{order.sku}</Text>
|
|
<Text className='order-meta'>数量: {order.count} 件 | {order.id}</Text>
|
|
</View>
|
|
</View>
|
|
<View className='order-footer'>
|
|
<View className='order-price-bar'>
|
|
<Text className='price-label'>实付款</Text>
|
|
<Text className='price-value'>{order.price}</Text>
|
|
</View>
|
|
<View className='order-actions'>
|
|
{order.statusCode === 'pending' && (
|
|
<View className='btn-gradient order-btn'>
|
|
<Text>立即付款</Text>
|
|
</View>
|
|
)}
|
|
{order.statusCode === 'paid' && (
|
|
<View className='btn-outline order-btn'>
|
|
<Text>催发货</Text>
|
|
</View>
|
|
)}
|
|
{order.statusCode === 'shipping' && (
|
|
<>
|
|
<View className='btn-outline order-btn' onTap={(e) => { e.stopPropagation(); Taro.showToast({ title: '查看物流', icon: 'none' }) }}>
|
|
<Text>查看物流</Text>
|
|
</View>
|
|
<View className='btn-gradient order-btn' onTap={(e) => { e.stopPropagation(); Taro.showToast({ title: '确认收货', icon: 'none' }) }}>
|
|
<Text>确认收货</Text>
|
|
</View>
|
|
</>
|
|
)}
|
|
{order.statusCode === 'done' && (
|
|
<>
|
|
<View className='btn-outline order-btn' onTap={(e) => { e.stopPropagation(); Taro.showToast({ title: '申请售后', icon: 'none' }) }}>
|
|
<Text>申请售后</Text>
|
|
</View>
|
|
<View className='btn-gradient order-btn' onTap={(e) => { e.stopPropagation(); Taro.showToast({ title: '再来一单', icon: 'none' }) }}>
|
|
<Text>再来一单</Text>
|
|
</View>
|
|
</>
|
|
)}
|
|
<View className='btn-outline order-btn' onTap={(e) => { e.stopPropagation(); goDetail(order) }}>
|
|
<Text>详情</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
)
|
|
})}
|
|
|
|
{filteredOrders.length === 0 && (
|
|
<View className='empty-state'>
|
|
<Image className='empty-icon-img' src={assetUrl('/icon/包裹.png')} mode='aspectFit' />
|
|
<Text className='empty-text'>暂无订单</Text>
|
|
<Text className='empty-sub'>去首页开始定制吧</Text>
|
|
<View className='btn-gradient' onTap={() => Taro.switchTab({ url: '/pages/index/index' })}>
|
|
<Text>去定制</Text>
|
|
</View>
|
|
</View>
|
|
)}
|
|
</ScrollView>
|
|
|
|
<View style={{ height: '40px' }} />
|
|
</View>
|
|
</LoginGuard>
|
|
</View>
|
|
)
|
|
}
|