- 新增地址类型定义,增强前端地址数据结构 - 新增地址编辑页面,支持地址智能识别和定位选点功能 - 地址编辑支持省市区选择及默认地址设置 - 新增地址列表页面,支持地址展示、删除、编辑和选择功能 - 实现售后申请页面,支持选择售后类型和退款原因 - 售后申请支持商品选择、退款金额计算和凭证上传 - 新增售后详情页面,支持售后状态展示及申请取消 - 优化页面加载和用户交互体验,增加错误提示和权限处理
124 lines
3.9 KiB
TypeScript
124 lines
3.9 KiB
TypeScript
import React, { useState, useEffect } from 'react'
|
||
import { View, Text } from '@tarojs/components'
|
||
import Price from '@/components/common/Price'
|
||
|
||
interface PayModalProps {
|
||
visible: boolean
|
||
amount: string
|
||
onClose: () => void
|
||
onConfirm: (payType: number) => void
|
||
}
|
||
|
||
const PAY_TYPES = [
|
||
{ id: 1, name: '微信支付', desc: '推荐使用', icon: 'pay-wechat' },
|
||
{ id: 0, name: '货到付款', desc: '使用账户余额', icon: 'pay-balance' },
|
||
]
|
||
|
||
const PayModal: React.FC<PayModalProps> = ({ visible, amount, onClose, onConfirm }) => {
|
||
const [selected, setSelected] = useState<number>(1)
|
||
const [showOverlay, setShowOverlay] = useState(false)
|
||
const [slideUp, setSlideUp] = useState(false)
|
||
|
||
// 控制动画
|
||
useEffect(() => {
|
||
if (visible) {
|
||
setShowOverlay(true)
|
||
setTimeout(() => setSlideUp(true), 10)
|
||
} else {
|
||
setSlideUp(false)
|
||
setTimeout(() => setShowOverlay(false), 300)
|
||
}
|
||
}, [visible])
|
||
|
||
const handleClose = () => {
|
||
setSlideUp(false)
|
||
setTimeout(() => {
|
||
setShowOverlay(false)
|
||
onClose()
|
||
}, 300)
|
||
}
|
||
|
||
const handleConfirm = () => {
|
||
handleClose()
|
||
onConfirm(selected)
|
||
}
|
||
|
||
if (!showOverlay) return null
|
||
|
||
return (
|
||
<View className='pay-modal-overlay'>
|
||
{/* 遮罩层 */}
|
||
<View
|
||
className={`absolute inset-0 bg-black/50 z-50 ${slideUp ? 'opacity-100' : 'opacity-0'}`}
|
||
onClick={handleClose}
|
||
/>
|
||
|
||
{/* 弹窗内容 */}
|
||
<View
|
||
className={`absolute bottom-0 left-0 right-0 bg-white rounded-t-2xl z-50 ${slideUp ? '' : 'hidden'}`}
|
||
>
|
||
<View className='p-4'>
|
||
{/* 关闭按钮 */}
|
||
<View className='flex justify-end mb-2'>
|
||
<View
|
||
className='w-6 h-6 rounded-full bg-gray-100 flex items-center justify-center'
|
||
onClick={handleClose}
|
||
>
|
||
<Text className='text-gray-400 text-sm'>×</Text>
|
||
</View>
|
||
</View>
|
||
|
||
<View className='text-center py-3 border-b border-gray-100'>
|
||
<Text className='text-base font-medium'>选择支付方式</Text>
|
||
<View className='mt-2'>
|
||
<Price price={amount} size='large' />
|
||
</View>
|
||
</View>
|
||
|
||
<View className='py-3'>
|
||
{PAY_TYPES.map((item) => (
|
||
<View
|
||
key={item.id}
|
||
className='flex items-center justify-between py-3 px-2 rounded-lg mb-1'
|
||
style={{ backgroundColor: selected === item.id ? '#f0fdf4' : 'transparent' }}
|
||
onClick={() => setSelected(item.id)}
|
||
>
|
||
<View className='flex items-center gap-3'>
|
||
<View className='w-8 h-8 rounded-full bg-green-50 flex items-center justify-center'>
|
||
<Text className='text-sm'>
|
||
{item.id === 1 ? '微' : '余'}
|
||
</Text>
|
||
</View>
|
||
<View>
|
||
<Text className='text-sm text-gray-800'>{item.name}</Text>
|
||
<Text className='text-xs text-gray-400'>{item.desc}</Text>
|
||
</View>
|
||
</View>
|
||
<View
|
||
className={`w-5 h-5 rounded-full border-2 flex items-center justify-center ${
|
||
selected === item.id ? 'border-green-500' : 'border-gray-300'
|
||
}`}
|
||
>
|
||
{selected === item.id && (
|
||
<View className='w-2 h-2 rounded-full bg-green-500' />
|
||
)}
|
||
</View>
|
||
</View>
|
||
))}
|
||
</View>
|
||
|
||
<View
|
||
className='w-full py-3 rounded-full text-center text-white text-sm font-medium mt-2'
|
||
style={{ backgroundColor: '#0e932e' }}
|
||
onClick={handleConfirm}
|
||
>
|
||
<Text className='text-white'>确认支付</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|
||
|
||
export default PayModal
|