import React, { useState, useEffect } from 'react' import Taro, { useRouter } from '@tarojs/taro' import { View, Text, Image } from '@tarojs/components' import { Cell, CellGroup, Radio, RadioGroup, TextArea, Button, Uploader, Loading, Empty, InputNumber } from '@nutui/nutui-react-taro' import { applyAfterSale } from '@/api/afterSale' import { updateShopOrder } from '@/api/shop/shopOrder' import './index.scss' // 订单商品信息 interface OrderGoods { goodsId: string goodsName: string goodsImage: string goodsPrice: number goodsNum: number skuInfo?: string canRefundNum: number // 可退款数量 } // 退款原因选项 const REFUND_REASONS = [ '不想要了', '商品质量问题', '商品与描述不符', '收到商品破损', '发错商品', '商品缺件', '其他原因' ] // 退款申请信息 interface RefundApplication { refundType: 'full' | 'partial' // 退款类型:全额退款 | 部分退款 refundReason: string // 退款原因 refundDescription: string // 退款说明 refundAmount: number // 退款金额 refundGoods: Array<{ goodsId: string refundNum: number }> // 退款商品 evidenceImages: string[] // 凭证图片 contactPhone?: string // 联系电话 isUrgent: boolean // 是否加急处理 } const RefundPage: React.FC = () => { const router = useRouter() const { orderId, orderNo } = router.params const [loading, setLoading] = useState(true) const [submitting, setSubmitting] = useState(false) const [orderGoods, setOrderGoods] = useState([]) const [orderAmount, setOrderAmount] = useState(0) const [refundApp, setRefundApp] = useState({ refundType: 'full', refundReason: '', refundDescription: '', refundAmount: 0, refundGoods: [], evidenceImages: [], contactPhone: '', isUrgent: false }) useEffect(() => { if (orderId) { loadOrderInfo() } }, [orderId]) // 加载订单信息 const loadOrderInfo = async () => { try { setLoading(true) // 模拟API调用 const mockOrderGoods: OrderGoods[] = [ { goodsId: '1', goodsName: 'iPhone 15 Pro Max 256GB 深空黑色', goodsImage: 'https://via.placeholder.com/100x100', goodsPrice: 9999, goodsNum: 1, canRefundNum: 1, skuInfo: '颜色:深空黑色,容量:256GB' }, { goodsId: '2', goodsName: 'AirPods Pro 第三代', goodsImage: 'https://via.placeholder.com/100x100', goodsPrice: 1999, goodsNum: 2, canRefundNum: 2, skuInfo: '颜色:白色' } ] const totalAmount = mockOrderGoods.reduce((sum, goods) => sum + goods.goodsPrice * goods.goodsNum, 0 ) await new Promise(resolve => setTimeout(resolve, 1000)) setOrderGoods(mockOrderGoods) setOrderAmount(totalAmount) // 初始化退款申请信息 setRefundApp(prev => ({ ...prev, refundAmount: totalAmount, refundGoods: mockOrderGoods.map(goods => ({ goodsId: goods.goodsId, refundNum: goods.goodsNum })) })) } catch (error) { console.error('加载订单信息失败:', error) Taro.showToast({ title: '加载失败,请重试', icon: 'none' }) } finally { setLoading(false) } } // 更新退款申请信息 const updateRefundApp = (field: keyof RefundApplication, value: any) => { setRefundApp(prev => ({ ...prev, [field]: value })) } // 切换退款类型 // const handleRefundTypeChange = (type: 'full' | 'partial') => { // updateRefundApp('refundType', type) // // if (type === 'full') { // // 全额退款 // updateRefundApp('refundAmount', orderAmount) // updateRefundApp('refundGoods', orderGoods.map(goods => ({ // goodsId: goods.goodsId, // refundNum: goods.goodsNum // }))) // } else { // // 部分退款 // updateRefundApp('refundAmount', 0) // updateRefundApp('refundGoods', orderGoods.map(goods => ({ // goodsId: goods.goodsId, // refundNum: 0 // }))) // } // } // 更新商品退款数量 const updateGoodsRefundNum = (goodsId: string, refundNum: number) => { const newRefundGoods = refundApp.refundGoods.map(item => item.goodsId === goodsId ? { ...item, refundNum } : item ) updateRefundApp('refundGoods', newRefundGoods) // 重新计算退款金额 const newRefundAmount = newRefundGoods.reduce((sum, item) => { const goods = orderGoods.find(g => g.goodsId === item.goodsId) return sum + (goods ? goods.goodsPrice * item.refundNum : 0) }, 0) updateRefundApp('refundAmount', newRefundAmount) } // 处理图片上传 const handleImageUpload = async (files: any) => { try { const uploadedImages: string[] = [] for (const file of files) { if (file.url) { uploadedImages.push(file.url) } } updateRefundApp('evidenceImages', uploadedImages) } catch (error) { console.error('图片上传失败:', error) Taro.showToast({ title: '图片上传失败', icon: 'none' }) } } // 提交退款申请 const submitRefund = async () => { try { // 验证必填信息 if (!refundApp.refundReason) { Taro.showToast({ title: '请选择退款原因', icon: 'none' }) return } if (refundApp.refundAmount <= 0) { Taro.showToast({ title: '退款金额必须大于0', icon: 'none' }) return } if (refundApp.refundType === 'partial') { const hasRefundGoods = refundApp.refundGoods.some(item => item.refundNum > 0) if (!hasRefundGoods) { Taro.showToast({ title: '请选择要退款的商品', icon: 'none' }) return } } setSubmitting(true) // 构造请求参数 const params = { orderId: orderId || '', type: 'refund' as const, reason: refundApp.refundReason, description: refundApp.refundDescription, amount: refundApp.refundAmount, contactPhone: refundApp.contactPhone, evidenceImages: refundApp.evidenceImages, goodsItems: refundApp.refundGoods.filter(item => item.refundNum > 0).map(item => ({ goodsId: item.goodsId, quantity: item.refundNum })) } // 调用API提交退款申请 const result = await applyAfterSale(params) if (result.success) { // 更新订单状态为"退款申请中" if (orderId) { try { await updateShopOrder({ orderId: parseInt(orderId), orderStatus: 4 // 退款申请中 }) } catch (updateError) { console.error('更新订单状态失败:', updateError) // 即使更新订单状态失败,也继续执行后续操作 } } Taro.showToast({ title: '退款申请提交成功', icon: 'success' }) // 延迟返回上一页 setTimeout(() => { Taro.navigateBack() }, 1500) } else { throw new Error(result.message || '提交失败') } } catch (error) { console.error('提交退款申请失败:', error) Taro.showToast({ title: error instanceof Error ? error.message : '提交失败,请重试', icon: 'none' }) } finally { setSubmitting(false) } } if (loading) { return ( 正在加载订单信息... ) } if (orderGoods.length === 0) { return ( ) } return ( {/* 订单信息 */} 订单号:{orderNo} 订单金额:¥{orderAmount} {/* 退款类型选择 */} {/**/} {/* handleRefundTypeChange(value as 'full' | 'partial')}*/} {/* >*/} {/* */} {/* 全额退款*/} {/* */} {/* */} {/* 部分退款*/} {/* */} {/* */} {/**/} {/* 商品列表 */} {refundApp.refundType === 'partial' && ( 选择退款商品 {orderGoods.map(goods => { const refundGoods = refundApp.refundGoods.find(item => item.goodsId === goods.goodsId) const refundNum = refundGoods?.refundNum || 0 return ( {goods.goodsName} {goods.skuInfo && ( {goods.skuInfo} )} ¥{goods.goodsPrice} 退款数量 updateGoodsRefundNum(goods.goodsId, value)} /> 最多{goods.canRefundNum}件 ) })} )} {/* 退款金额 */} ¥{refundApp.refundAmount} {/* 退款原因 */} updateRefundApp('refundReason', value)} > {REFUND_REASONS.map(reason => ( {reason} ))} {/* 退款说明 */} 退款说明