You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
11 KiB
344 lines
11 KiB
/** |
|
* 商品消费页 |
|
*/ |
|
import { View, Text, Button, } from '@tarojs/components' |
|
import { useState } from 'react' |
|
import Taro, { useLoad } from '@tarojs/taro' |
|
import { Tabs, Divider,Image } from '@taroify/core' |
|
import { ArrowDown, Arrow } from '@taroify/icons' |
|
import EmptyData from '@/components/EmptyData' |
|
import FilterPopup from '../orderList/components/FilterPopup' |
|
import './index.scss' |
|
|
|
// 商品消费订单数据接口 |
|
interface GoodsOrderItem { |
|
id: string |
|
time: string // 消费时间 |
|
storeName: string // 消费门店 |
|
address: string // 地址 |
|
orderNo: string // 订单号 |
|
amount: number // 消费金额 |
|
goodsCount: number // 商品数量 |
|
status: 'unpaid' | 'paid' | 'refund' // 未支付 | 已支付 | 退款 |
|
|
|
// 退款订单特有字段 |
|
refundGoods?: RefundGoodsItem[] // 退款商品列表 |
|
} |
|
|
|
// 退款商品信息接口 |
|
interface RefundGoodsItem { |
|
id: string |
|
image: string // 商品图片 |
|
name: string // 商品名称 |
|
refundAmount: number // 退款金额 |
|
refundStatus: 'success' | 'failed' // 退款状态:成功 | 失败 |
|
paymentMethod: string // 支付方式 |
|
} |
|
|
|
const GoodsCons = () => { |
|
const [statusTab, setStatusTab] = useState(0) // 0: 未支付, 1: 已支付, 2: 退款 |
|
const [filterPopupOpen, setFilterPopupOpen] = useState(false) // 筛选弹窗 |
|
const [filterData, setFilterData] = useState({ |
|
startDate: '', |
|
endDate: '', |
|
paymentMethods: [] as string[] |
|
}) |
|
|
|
// 模拟商品消费订单数据 |
|
const [orderList] = useState<GoodsOrderItem[]>([ |
|
{ |
|
id: '1', |
|
time: '2025-01-10 16:30:01', |
|
storeName: 'XXX店', |
|
address: 'XXX市XXXXXXXX', |
|
orderNo: 'wjekwejrwkjsf1321445255', |
|
amount: 15.50, |
|
goodsCount: 2, |
|
status: 'unpaid' |
|
}, |
|
{ |
|
id: '2', |
|
time: '2025-01-09 10:30:01', |
|
storeName: 'XXX店', |
|
address: 'XXX市XXX区XXXXXXXXXXXXXXXX街道XXXXXXX大厦201', |
|
orderNo: 'wjekwejrwkjsf1321445255', |
|
amount: 15.00, |
|
goodsCount: 2, |
|
status: 'paid' |
|
}, |
|
{ |
|
id: '3', |
|
time: '2025-01-08 14:20:00', |
|
storeName: 'XXX店', |
|
address: 'XXX市XXXXXXXX', |
|
orderNo: 'wjekwejrwkjsf1321445256', |
|
amount: 20.00, |
|
goodsCount: 1, |
|
status: 'refund', |
|
refundGoods: [ |
|
{ |
|
id: '1', |
|
image: 'https://img01.yzcdn.cn/vant/cat.jpeg', |
|
name: '美汁源Minute Maid果粒橙 橙汁饮料 1.25l/瓶', |
|
refundAmount: 12.50, |
|
refundStatus: 'success', |
|
paymentMethod: '微信' |
|
}, |
|
{ |
|
id: '2', |
|
image: '', // 空图片显示占位图 |
|
name: '美汁源Minute Maid果粒橙 橙汁饮料 1.25l/瓶', |
|
refundAmount: 12.50, |
|
refundStatus: 'success', |
|
paymentMethod: '支付宝' |
|
}, |
|
{ |
|
id: '3', |
|
image: 'https://img01.yzcdn.cn/vant/cat.jpeg', |
|
name: '可口可乐 迷你装 200ml/罐', |
|
refundAmount: 3.00, |
|
refundStatus: 'failed', |
|
paymentMethod: '微信' |
|
} |
|
] |
|
} |
|
]) |
|
|
|
useLoad(() => { |
|
console.log('商品消费页面加载') |
|
}) |
|
|
|
// 筛选按钮点击 |
|
const handleFilter = () => { |
|
setFilterPopupOpen(true) |
|
} |
|
|
|
// 筛选确认 |
|
const handleFilterConfirm = (data: any) => { |
|
setFilterData(data) |
|
|
|
// 计算筛选数量 |
|
let count = 0 |
|
if (data.startDate || data.endDate) count++ |
|
if (data.paymentMethods.length > 0) count += data.paymentMethods.length |
|
|
|
console.log('筛选数据', data, '筛选数量', count) |
|
|
|
Taro.showToast({ |
|
title: '筛选成功', |
|
icon: 'success', |
|
duration: 2000 |
|
}) |
|
} |
|
|
|
// 计算筛选数量 |
|
const getFilterCount = () => { |
|
let count = 0 |
|
if (filterData.startDate || filterData.endDate) count++ |
|
if (filterData.paymentMethods.length > 0) count += filterData.paymentMethods.length |
|
return count |
|
} |
|
|
|
// 根据选中的 Tab 筛选订单 |
|
const getFilteredOrders = () => { |
|
let filtered = orderList |
|
|
|
// 根据状态筛选 |
|
if (statusTab === 0) { |
|
filtered = filtered.filter(order => order.status === 'unpaid') |
|
} else if (statusTab === 1) { |
|
filtered = filtered.filter(order => order.status === 'paid') |
|
} else if (statusTab === 2) { |
|
filtered = filtered.filter(order => order.status === 'refund') |
|
} |
|
|
|
return filtered |
|
} |
|
|
|
const filteredOrders = getFilteredOrders() |
|
|
|
// 订单卡片点击 |
|
const handleOrderClick = (orderId: string) => { |
|
console.log('订单详情', orderId) |
|
Taro.navigateTo({ |
|
url: `/pagesUser/goodsOrderDetail/index?orderId=${orderId}&status=${statusTab === 0 ? 'unpaid' : 'paid'}` |
|
}) |
|
} |
|
|
|
// 立即支付 |
|
const handlePay = (orderId: string, e: any) => { |
|
e.stopPropagation() // 阻止冒泡到卡片点击事件 |
|
console.log('立即支付', orderId) |
|
Taro.showToast({ |
|
title: '跳转支付', |
|
icon: 'none' |
|
}) |
|
} |
|
|
|
// 获取状态文本 |
|
const getStatusText = (status: string) => { |
|
if (status === 'unpaid') return '未支付' |
|
if (status === 'paid') return '已支付' |
|
if (status === 'refund') return '退款' |
|
return '' |
|
} |
|
|
|
// 获取状态样式类 |
|
const getStatusClass = (status: string) => { |
|
if (status === 'unpaid') return 'unpaid' |
|
if (status === 'paid') return 'paid' |
|
if (status === 'refund') return 'refund' |
|
return '' |
|
} |
|
|
|
// 获取退款状态文本 |
|
const getRefundStatusText = (status: 'success' | 'failed') => { |
|
return status === 'success' ? '退款成功' : '退款失败' |
|
} |
|
|
|
// 获取退款状态样式类 |
|
const getRefundStatusClass = (status: 'success' | 'failed') => { |
|
return status === 'success' ? 'refund_success' : 'refund_failed' |
|
} |
|
|
|
return ( |
|
<View className="goods-cons-page"> |
|
{/* 状态 Tab:未支付/已支付/退款 + 筛选 */} |
|
<View className="status-tab-container"> |
|
<Tabs value={statusTab} onChange={setStatusTab} className="status-tabs"> |
|
<Tabs.TabPane title="未支付" /> |
|
<Tabs.TabPane title="已支付" /> |
|
<Tabs.TabPane title="退款" /> |
|
</Tabs> |
|
|
|
<View className="filter-btn" onClick={handleFilter}> |
|
<Text className="filter-text">筛选{getFilterCount() > 0 ? ` ${getFilterCount()}` : ''}</Text> |
|
<ArrowDown size="16px" color="#8B8B8B" /> |
|
</View> |
|
</View> |
|
|
|
{/* 订单列表 */} |
|
<View className="order-list"> |
|
{filteredOrders.length === 0 ? ( |
|
<EmptyData /> |
|
) : ( |
|
<> |
|
{filteredOrders.map(order => { |
|
// 退款订单:每个退款商品显示为独立卡片 |
|
if (order.status === 'refund' && order.refundGoods) { |
|
return order.refundGoods.map((goods) => ( |
|
<View |
|
key={`${order.id}-${goods.id}`} |
|
className="order-card refund_card" |
|
onClick={() => handleOrderClick(order.id)} |
|
> |
|
{/* 商品信息 */} |
|
<View className="goods_row"> |
|
{/* 商品图片 */} |
|
|
|
<Image |
|
width="208rpx" |
|
height="208rpx" |
|
className="goods_img" |
|
src={goods.image} |
|
mode="aspectFill" |
|
placeholder="加载中..." |
|
fallback="加载失败" |
|
/> |
|
|
|
|
|
{/* 商品名称和退款金额 */} |
|
<View className="goods_info_box"> |
|
<Text className="goods_name">{goods.name}</Text> |
|
<Text className="refund_amount">退款: ¥ {goods.refundAmount.toFixed(2)}</Text> |
|
</View> |
|
</View> |
|
|
|
{/* 退款状态栏 */} |
|
<View className={`refund_status_bar ${getRefundStatusClass(goods.refundStatus)}`}> |
|
<Text className="refund_status_text">{getRefundStatusText(goods.refundStatus)}</Text> |
|
<Text className="payment_method">{goods.paymentMethod}</Text> |
|
<Text className="refund_amount_text">¥ {goods.refundAmount.toFixed(2)}</Text> |
|
<View className="detail_btn_box"> |
|
<Text className="detail_text">详情</Text> |
|
<Arrow size="16px" color="#646566" /> |
|
</View> |
|
</View> |
|
</View> |
|
)) |
|
} |
|
|
|
// 普通订单:未支付/已支付,每个订单显示为一个卡片 |
|
return ( |
|
<View |
|
key={order.id} |
|
className="order-card" |
|
onClick={() => handleOrderClick(order.id)} |
|
> |
|
{/* 标题行:时间 + 状态 */} |
|
<View className="card-header"> |
|
<Text className="time">{order.time}</Text> |
|
<View className="status-with-arrow"> |
|
<Text className={`status ${getStatusClass(order.status)}`}> |
|
{getStatusText(order.status)} |
|
</Text> |
|
<Arrow size="16px" color={order.status === 'unpaid' ? '#FF3B30' : '#8B8B8B'} /> |
|
</View> |
|
</View> |
|
|
|
{/* 虚线分隔 */} |
|
<Divider dashed={true} /> |
|
|
|
{/* 订单信息 */} |
|
<View className="card-info"> |
|
<View className="info-row"> |
|
<Text className="info-label">消费门店</Text> |
|
<Text className="info-value">{order.storeName}</Text> |
|
</View> |
|
<View className="info-row"> |
|
<Text className="info-label">地址</Text> |
|
<Text className="info-value">{order.address}</Text> |
|
</View> |
|
<View className="info-row"> |
|
<Text className="info-label">订单号</Text> |
|
<Text className="info-value">{order.orderNo}</Text> |
|
</View> |
|
<View className="info-row"> |
|
<Text className="info-label">消费金额</Text> |
|
<Text className="info-value">{order.amount.toFixed(2)}元</Text> |
|
</View> |
|
<View className="info-row"> |
|
<Text className="info-label">商品数量</Text> |
|
<Text className="info-value">{order.goodsCount}</Text> |
|
</View> |
|
</View> |
|
|
|
{/* 未支付订单显示立即支付按钮 */} |
|
{order.status === 'unpaid' && ( |
|
<Button className="pay-btn" onClick={(e) => handlePay(order.id, e)}> |
|
立即支付 |
|
</Button> |
|
)} |
|
</View> |
|
) |
|
})} |
|
|
|
{/* 到底了提示 */} |
|
<View className="list-end"> |
|
<Text className="end-text">到底了~</Text> |
|
</View> |
|
</> |
|
)} |
|
</View> |
|
|
|
{/* 筛选弹窗 */} |
|
<FilterPopup |
|
open={filterPopupOpen} |
|
onClose={() => setFilterPopupOpen(false)} |
|
onConfirm={handleFilterConfirm} |
|
/> |
|
</View> |
|
) |
|
} |
|
|
|
export default GoodsCons
|
|
|