import React, { useState, useEffect } from 'react' import { View, Text, Input, Image, ScrollView } from '@tarojs/components' import Taro from '@tarojs/taro' import { Button, Uploader } from '@nutui/nutui-react-taro' import { getShopOrder } from '@/api/shop/shopOrder' import type { ShopOrder } from '@/api/shop/shopOrder/model' import Price from '@/components/common/Price' definePageConfig({ navigationBarTitleText: '申请售后', }) // 售后类型 const AFTER_SALE_TYPES = [ { value: 'refund', label: '退款', desc: '仅退款,商品无需退回' }, { value: 'return', label: '退货退款', desc: '退款并退货,商品需退回' }, ] // 退款原因选项 const REASON_OPTIONS = [ '商品损坏/有瑕疵', '商品与描述不符', '收到错误商品', '商品少发/漏发', '不想要了', '其他原因', ] const AfterSaleApplyPage: React.FC = () => { const { orderId, type } = Taro.getCurrentInstance().router?.params || {} const [order, setOrder] = useState(null) const [loading, setLoading] = useState(false) // 售后类型 const [afterSaleType, setAfterSaleType] = useState<'refund' | 'return'>( (type as 'refund' | 'return') || 'refund' ) // 退款原因 const [selectedReason, setSelectedReason] = useState('') const [reasonDesc, setReasonDesc] = useState('') // 图片上传 const [images, setImages] = useState([]) // 选中的商品 const [selectedItems, setSelectedItems] = useState([]) // 可退金额 const [refundAmount, setRefundAmount] = useState('0.00') useEffect(() => { if (orderId) { loadOrder() } }, [orderId]) const loadOrder = async () => { try { const res = await getShopOrder(Number(orderId)) if (res) { setOrder(res) // 默认选中所有商品 const allItemIndices = (res.orderGoods || []).map((_, idx) => idx) setSelectedItems(allItemIndices) // 计算可退金额 const amount = calculateRefundAmount(res, allItemIndices) setRefundAmount(amount) } } catch (err) { console.error('加载订单失败', err) Taro.showToast({ title: '加载失败', icon: 'none' }) } } // 计算可退金额 const calculateRefundAmount = (orderData: ShopOrder, selectedIdx: number[]): string => { if (!orderData.orderGoods || selectedIdx.length === 0) return '0.00' let total = 0 orderData.orderGoods.forEach((item, idx) => { if (selectedIdx.includes(idx)) { total += Number(item.price || 0) * (item.num || item.quantity || 1) } }) // 按比例计算优惠分摊 const totalPrice = Number(orderData.totalPrice || 0) if (totalPrice > 0) { const payPrice = Number(orderData.payPrice || 0) const ratio = payPrice / totalPrice total = total * ratio } return total.toFixed(2) } // 切换商品选中 const toggleItem = (idx: number) => { const newSelected = selectedItems.includes(idx) ? selectedItems.filter(i => i !== idx) : [...selectedItems, idx] setSelectedItems(newSelected) if (order) { setRefundAmount(calculateRefundAmount(order, newSelected)) } } // 全选/取消全选 const toggleAll = () => { if (!order?.orderGoods) return if (selectedItems.length === order.orderGoods.length) { setSelectedItems([]) setRefundAmount('0.00') } else { const allIdx = order.orderGoods.map((_, idx) => idx) setSelectedItems(allIdx) setRefundAmount(calculateRefundAmount(order, allIdx)) } } // 提交申请 const handleSubmit = async () => { if (selectedItems.length === 0) { Taro.showToast({ title: '请选择要售后的商品', icon: 'none' }) return } if (!selectedReason) { Taro.showToast({ title: '请选择退款原因', icon: 'none' }) return } Taro.showModal({ title: '确认提交', content: `确认提交${afterSaleType === 'refund' ? '退款' : '退货退款'}申请?`, success: async (res) => { if (res.confirm) { await submitApply() } }, }) } const submitApply = async () => { if (!selectedReason) { Taro.showToast({ title: '请选择退款原因', icon: 'none' }) return } setLoading(true) try { const res = await applyAfterSale({ orderId: orderId || '', type: afterSaleType, reason: selectedReason, description: reasonDesc, amount: parseFloat(refundAmount), evidenceImages: images }) if (res.success) { Taro.showToast({ title: '申请提交成功', icon: 'success' }) setTimeout(() => { Taro.redirectTo({ url: '/pages/order/after-sale-list' }) }, 1500) } else { Taro.showToast({ title: res.message || '提交失败', icon: 'none' }) } } catch (err) { console.error('申请售后失败:', err) Taro.showToast({ title: '提交失败', icon: 'none' }) } finally { setLoading(false) } } if (!order) { return ( 加载中... ) } return ( {/* 售后类型选择 */} 售后类型 {AFTER_SALE_TYPES.map(item => ( setAfterSaleType(item.value as 'refund' | 'return')} > {item.label} {item.desc} ))} {/* 商品选择 */} 选择商品 {selectedItems.length === order.orderGoods?.length ? '取消全选' : '全选'} {order.orderGoods?.map((item, idx) => ( toggleItem(idx)} > {/* 选中状态 */} {selectedItems.includes(idx) && ( )} {/* 商品图片 */} {/* 商品信息 */} {item.goodsName} x{item.num || item.quantity || 1} ))} {/* 退款原因 */} 退款原因 {REASON_OPTIONS.map(reason => ( setSelectedReason(reason)} > {reason} ))} {/* 补充说明 */} 补充说明(选填) setReasonDesc(e.detail.value)} style={{ minHeight: '80px' }} /> {/* 上传凭证 */} 上传凭证(选填) ({ id: String(idx), url }))} onChange={(files) => { setImages(files.map(f => f.url || '')) }} maxCount={3} /> {/* 退款金额 */} 预计退款金额 {'\u00A5'}{refundAmount} {afterSaleType === 'return' && ( 退货时请将商品寄回,商家收货后退款将原路返回 )} {/* 提交按钮 */} ) } export default AfterSaleApplyPage