diff --git a/src/app.config.ts b/src/app.config.ts index 5eaf0c9..1fbc021 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -25,6 +25,7 @@ export default defineAppConfig({ 'orderDetail/index', // 订单详情 'unsettledOrders/index', // 未结算账单 'goodsCons/index', // 商品消费 + 'goodsOrderDetail/index', // 商品消费详情 (已支付,未支付) 'helpCenter/index', // 帮助中心 'agreement/index', // 协议 'editProfile/index', // 编辑资料 diff --git a/src/pagesUser/goodsCons/index.scss b/src/pagesUser/goodsCons/index.scss index b858ef2..b56f485 100644 --- a/src/pagesUser/goodsCons/index.scss +++ b/src/pagesUser/goodsCons/index.scss @@ -152,6 +152,113 @@ } } + // 退款订单卡片特殊样式 + .refund_card { + // 商品行 + .goods_row { + display: flex; + align-items: flex-start; + margin-bottom: 20px; + + .goods_img { + width: 208px; + height: 208px; + border-radius: 8px; + flex-shrink: 0; + + &.placeholder { + background-color: #F7F8FA; + display: flex; + align-items: center; + justify-content: center; + border: 1PX dashed #DCDEE0; + + .placeholder_icon { + width: 80px; + height: 80px; + background-color: #DCDEE0; + border-radius: 4px; + } + } + } + + .goods_info_box { + flex: 1; + margin-left: 30px; + display: flex; + flex-direction: column; + + .goods_name { + font-size: 30px; + color: #000000; + font-weight: 600; + line-height: 1.4; + margin-bottom: 10px; + } + + .refund_amount { + font-size: 30px; + color: #000000; + margin-top: auto; + padding-top: 66px; + } + } + } + + // 退款状态栏 + .refund_status_bar { + display: flex; + align-items: center; + height: 88px; + background-color: #F7F8FA; + border-radius: 8px; + padding: 0 30px; + gap: 20px; + + .refund_status_text { + font-size: 28px; + font-weight: 500; + } + + .payment_method { + font-size: 28px; + color: #646566; + } + + .refund_amount_text { + font-size: 28px; + color: #FF8A19; + margin-left: auto; + } + + .detail_btn_box { + display: flex; + align-items: center; + gap: 5px; + margin-left: 20px; + + .detail_text { + font-size: 28px; + color: #646566; + } + } + + // 退款成功状态 + &.refund_success { + .refund_status_text { + color: #07C160; + } + } + + // 退款失败状态 + &.refund_failed { + .refund_status_text { + color: #EE0A24; + } + } + } + } + // 到底了提示 .list-end { text-align: center; diff --git a/src/pagesUser/goodsCons/index.tsx b/src/pagesUser/goodsCons/index.tsx index 82799b1..9de0b4f 100644 --- a/src/pagesUser/goodsCons/index.tsx +++ b/src/pagesUser/goodsCons/index.tsx @@ -1,10 +1,10 @@ /** * 商品消费页 */ -import { View, Text, Button } from '@tarojs/components' +import { View, Text, Button, } from '@tarojs/components' import { useState } from 'react' import Taro, { useLoad } from '@tarojs/taro' -import { Tabs, Divider } from '@taroify/core' +import { Tabs, Divider,Image } from '@taroify/core' import { ArrowDown, Arrow } from '@taroify/icons' import EmptyData from '@/components/EmptyData' import FilterPopup from '../orderList/components/FilterPopup' @@ -20,6 +20,19 @@ interface GoodsOrderItem { 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 = () => { @@ -61,7 +74,33 @@ const GoodsCons = () => { orderNo: 'wjekwejrwkjsf1321445256', amount: 20.00, goodsCount: 1, - status: 'refund' + 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: '微信' + } + ] } ]) @@ -122,7 +161,7 @@ const GoodsCons = () => { const handleOrderClick = (orderId: string) => { console.log('订单详情', orderId) Taro.navigateTo({ - url: `/pagesUser/orderDetail/index?orderId=${orderId}` + url: `/pagesUser/goodsOrderDetail/index?orderId=${orderId}&status=${statusTab === 0 ? 'unpaid' : 'paid'}` }) } @@ -152,6 +191,16 @@ const GoodsCons = () => { return '' } + // 获取退款状态文本 + const getRefundStatusText = (status: 'success' | 'failed') => { + return status === 'success' ? '退款成功' : '退款失败' + } + + // 获取退款状态样式类 + const getRefundStatusClass = (status: 'success' | 'failed') => { + return status === 'success' ? 'refund_success' : 'refund_failed' + } + return ( {/* 状态 Tab:未支付/已支付/退款 + 筛选 */} @@ -174,58 +223,105 @@ const GoodsCons = () => { ) : ( <> - {filteredOrders.map(order => ( - handleOrderClick(order.id)} - > - {/* 标题行:时间 + 状态 */} - - {order.time} - - - {getStatusText(order.status)} - - - - + {filteredOrders.map(order => { + // 退款订单:每个退款商品显示为独立卡片 + if (order.status === 'refund' && order.refundGoods) { + return order.refundGoods.map((goods) => ( + handleOrderClick(order.id)} + > + {/* 商品信息 */} + + {/* 商品图片 */} + + + + + {/* 商品名称和退款金额 */} + + {goods.name} + 退款: ¥ {goods.refundAmount.toFixed(2)} + + - {/* 虚线分隔 */} - - - {/* 订单信息 */} - - - 消费门店 - {order.storeName} - - - 地址 - {order.address} - - - 订单号 - {order.orderNo} + {/* 退款状态栏 */} + + {getRefundStatusText(goods.refundStatus)} + {goods.paymentMethod} + ¥ {goods.refundAmount.toFixed(2)} + + 详情 + + + - - 消费金额 - {order.amount.toFixed(2)}元 + )) + } + + // 普通订单:未支付/已支付,每个订单显示为一个卡片 + return ( + handleOrderClick(order.id)} + > + {/* 标题行:时间 + 状态 */} + + {order.time} + + + {getStatusText(order.status)} + + + - - 商品数量 - {order.goodsCount} + + {/* 虚线分隔 */} + + + {/* 订单信息 */} + + + 消费门店 + {order.storeName} + + + 地址 + {order.address} + + + 订单号 + {order.orderNo} + + + 消费金额 + {order.amount.toFixed(2)}元 + + + 商品数量 + {order.goodsCount} + - - {/* 未支付订单显示立即支付按钮 */} - {order.status === 'unpaid' && ( - - )} - - ))} + {/* 未支付订单显示立即支付按钮 */} + {order.status === 'unpaid' && ( + + )} + + ) + })} {/* 到底了提示 */} diff --git a/src/pagesUser/goodsOrderDetail/index.config.ts b/src/pagesUser/goodsOrderDetail/index.config.ts new file mode 100644 index 0000000..fdd773c --- /dev/null +++ b/src/pagesUser/goodsOrderDetail/index.config.ts @@ -0,0 +1,6 @@ +export default definePageConfig({ + navigationBarTitleText: '商品消费', + navigationBarBackgroundColor: '#fff', + navigationBarTextStyle: 'black', + backgroundColor: '#F2F3F5', +}) diff --git a/src/pagesUser/goodsOrderDetail/index.scss b/src/pagesUser/goodsOrderDetail/index.scss new file mode 100644 index 0000000..c59862c --- /dev/null +++ b/src/pagesUser/goodsOrderDetail/index.scss @@ -0,0 +1,138 @@ +.order_detail_page { + min-height: 100vh; + background-color: #F2F3F5; + padding: 30px; + padding-bottom: 150px; // 为底部按钮留出空间 + + // 商品卡片 + .goods_card { + background-color: #FFFFFF; + border-radius: 12px; + padding: 30px; + margin-bottom: 30px; + + .goods_item { + display: flex; + align-items: flex-start; + + .goods_image { + width: 208px; + height: 208px; + border-radius: 8px; + flex-shrink: 0; + } + + .goods_info { + flex: 1; + margin-left: 30px; + display: flex; + flex-direction: column; + + .goods_name { + font-size: 30px; + color: #000000; + line-height: 1.4; + margin-bottom: 10px; + } + + .price_container { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 66px; + + .goods_price { + font-size: 30px; + color: #FF3A24; + font-weight: 500; + } + + .refund_btn { + padding: 10px 30px; + background: #F2F3F5; + border-radius: 25px; + + .refund_text { + font-size: 25px; + color: #666666; + } + } + } + } + } + } + + // 订单信息卡片 + .order_info_card { + background-color: #FFFFFF; + border-radius: 12px; + padding: 30px; + + .info_list { + display: flex; + flex-direction: column; + gap: 20px; + + .info_row { + display: flex; + align-items: flex-start; + + .info_label { + width: 180px; + font-size: 28px; + color: #333333; + flex-shrink: 0; + } + + .info_value { + flex: 1; + margin-left: 30px; + font-size: 28px; + color: #595959; + text-align: left; + word-break: break-all; + } + } + } + + // 虚线分隔 + .divider { + height: 1PX; + border-bottom: 1PX dashed #D3D8DE; + margin: 30px 0; + } + + // 联系商家 + .merchant_contact { + .contact_text { + font-size: 28px; + color: #333333; + } + } + } + + // 页脚支付按钮(仅未支付订单) + .footer { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background-color: #FFFFFF; + padding: 30px; + box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05); + + .pay_btn { + width: 100%; + height: 88px; + background: #03C175; + border-radius: 44px; + border: none; + font-weight: 500; + font-size: 33px; + color: #FFFFFF; + display: flex; + align-items: center; + justify-content: center; + } + } +} diff --git a/src/pagesUser/goodsOrderDetail/index.tsx b/src/pagesUser/goodsOrderDetail/index.tsx new file mode 100644 index 0000000..55c35a3 --- /dev/null +++ b/src/pagesUser/goodsOrderDetail/index.tsx @@ -0,0 +1,199 @@ +/** + * 订单详情页(商品消费详情) + */ +import { View, Text, Button } from '@tarojs/components' +import { useState } from 'react' +import Taro, { useLoad } from '@tarojs/taro' +import { Image } from '@taroify/core' +import './index.scss' + +// 商品信息接口 +interface GoodsItem { + id: string + image: string // 商品图片 + name: string // 商品名称 + price: number // 商品价格 + canRefund?: boolean // 是否可退款(仅已支付订单) +} + +// 订单详情接口 +interface OrderDetail { + id: string + status: 'unpaid' | 'paid' // 未支付 | 已支付 + goods: GoodsItem[] // 商品列表 + storeName: string // 消费门店 + address: string // 地址 + orderNo: string // 订单号 + amount: number // 消费金额 + goodsCount: number // 商品数量 + merchantPhone: string // 联系商家电话 + + // 已支付订单额外字段 + paymentTime?: string // 支付时间 + paymentMethod?: string // 支付方式 +} + +const OrderDetail = () => { + const [pageType, setPageType] = useState<'unpaid' | 'paid'>('unpaid') + + // 模拟订单详情数据 + const [orderDetail] = useState({ + id: '1', + status: 'unpaid', + goods: [ + { + id: '1', + image: 'https://img01.yzcdn.cn/vant/cat.jpeg', + name: '美汁源Minute Maid果粒橙 橙汁饮料 1.25l/瓶', + price: 12.50 + }, + { + id: '2', + image: 'https://img01.yzcdn.cn/vant/cat.jpeg', + name: '可口可乐 迷你装 200ml/罐', + price: 3.00, + canRefund: true + } + ], + storeName: 'XXX店', + address: 'XXX市XXXXXXXXXXX市XXXXXXXXXXX市XXXXXXXX', + orderNo: 'wjekwejrwkjsf1321445255', + amount: 15.50, + goodsCount: 2, + merchantPhone: '16688889999', + paymentTime: '2025-01-01 10:00:00', + paymentMethod: '微信支付' + }) + + useLoad(() => { + console.log('订单详情页面加载') + + // 从 URL 获取页面类型 + const router = Taro.getCurrentInstance().router + if (router?.params) { + const { status } = router.params + if (status === 'paid' || status === 'unpaid') { + setPageType(status as 'unpaid' | 'paid') + } + } + }) + + // 申请退款 + const handleRefund = (goodsId: string) => { + console.log('申请退款', goodsId) + Taro.showToast({ + title: '申请退款', + icon: 'none' + }) + } + + // 立即支付 + const handlePay = () => { + console.log('立即支付') + Taro.showToast({ + title: '跳转支付', + icon: 'none' + }) + } + + // 联系商家 + const handleCallMerchant = () => { + Taro.makePhoneCall({ + phoneNumber: orderDetail.merchantPhone + }) + } + + return ( + + {/* 商品卡片 */} + + {orderDetail.goods.map((goods, index) => ( + 0 ? '30px' : '0' }}> + + + {goods.name} + + ¥ {goods.price.toFixed(2)} + {/* 已支付订单且商品可退款时显示申请退款按钮 */} + {pageType === 'paid' && goods.canRefund && ( + handleRefund(goods.id)}> + 申请退款 + + )} + + + + ))} + + + {/* 订单信息卡片 */} + + + + 消费门店 + {orderDetail.storeName} + + + 地址 + {orderDetail.address} + + + {/* 已支付订单显示支付时间 */} + {pageType === 'paid' && orderDetail.paymentTime && ( + + 支付时间 + {orderDetail.paymentTime} + + )} + + + 订单号 + {orderDetail.orderNo} + + + 消费金额 + {orderDetail.amount.toFixed(2)}元 + + + {/* 已支付订单显示支付方式 */} + {pageType === 'paid' && orderDetail.paymentMethod && ( + + 支付方式 + {orderDetail.paymentMethod} + + )} + + + 商品数量 + {orderDetail.goodsCount} + + + + {/* 分隔线 */} + + + {/* 联系商家 */} + + 联系商家:{orderDetail.merchantPhone} + + + + {/* 未支付订单显示支付按钮 */} + {pageType === 'unpaid' && ( + + + + )} + + ) +} + +export default OrderDetail