feat(user): 新增收货地址管理及售后申请页面

- 新增地址类型定义,增强前端地址数据结构
- 新增地址编辑页面,支持地址智能识别和定位选点功能
- 地址编辑支持省市区选择及默认地址设置
- 新增地址列表页面,支持地址展示、删除、编辑和选择功能
- 实现售后申请页面,支持选择售后类型和退款原因
- 售后申请支持商品选择、退款金额计算和凭证上传
- 新增售后详情页面,支持售后状态展示及申请取消
- 优化页面加载和用户交互体验,增加错误提示和权限处理
This commit is contained in:
2026-07-01 12:11:56 +08:00
parent bf6ed504cc
commit 1fa58040f3
636 changed files with 58878 additions and 716 deletions

View File

@@ -0,0 +1,158 @@
import React, { useState } from 'react'
import { View, Text, ScrollView, Picker } from '@tarojs/components'
import Taro from '@tarojs/taro'
definePageConfig({
navigationBarTitleText: '改签预约',
})
const BookingReschedulePage: React.FC = () => {
const [orderId, setOrderId] = useState('BK202605120001')
const [oldDate, setOldDate] = useState('2026-05-15')
const [oldTime, setOldTime] = useState('14:00-16:00')
const [newDate, setNewDate] = useState('')
const [newTime, setNewTime] = useState('')
// 可选日期未来7天
const availableDates = []
for (let i = 1; i <= 7; i++) {
const date = new Date()
date.setDate(date.getDate() + i)
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
availableDates.push(`${year}-${month}-${day}`)
}
// 可选时段
const availableTimes = ['09:00-11:00', '10:00-12:00', '14:00-16:00', '15:00-17:00']
// 提交改签
const handleSubmit = () => {
if (!newDate) {
Taro.showToast({ title: '请选择新日期', icon: 'none' })
return
}
if (!newTime) {
Taro.showToast({ title: '请选择新时段', icon: 'none' })
return
}
Taro.showModal({
title: '确认改签',
content: `确定将预约从\n${oldDate} ${oldTime}\n改签至\n${newDate} ${newTime}吗?`,
confirmText: '确认改签',
confirmColor: '#0e932e',
success: (res) => {
if (res.confirm) {
Taro.showLoading({ title: '改签中...' })
// 这里应该调用改签API
setTimeout(() => {
Taro.hideLoading()
Taro.showToast({ title: '改签成功', icon: 'success' })
setTimeout(() => {
Taro.navigateBack()
}, 1500)
}, 2000)
}
}
})
}
return (
<View className='min-h-screen bg-gray-50 flex flex-col'>
<ScrollView scrollY className='flex-1'>
{/* 原预约信息 */}
<View className='bg-white mx-3 mt-3 rounded-xl p-4'>
<Text className='text-base font-medium text-gray-800 mb-3 block'></Text>
<View className='bg-gray-50 rounded-lg p-3'>
<View className='flex justify-between items-center mb-2'>
<Text className='text-sm text-gray-500'></Text>
<Text className='text-sm text-gray-800'>{orderId}</Text>
</View>
<View className='flex justify-between items-center mb-2'>
<Text className='text-sm text-gray-500'></Text>
<Text className='text-sm text-gray-800'>{oldDate}</Text>
</View>
<View className='flex justify-between items-center'>
<Text className='text-sm text-gray-500'></Text>
<Text className='text-sm text-gray-800'>{oldTime}</Text>
</View>
</View>
</View>
{/* 选择新日期 */}
<View className='bg-white mx-3 mt-3 rounded-xl p-4'>
<Text className='text-base font-medium text-gray-800 mb-3 block'></Text>
<Picker
mode='selector'
range={availableDates}
onChange={(e) => setNewDate(availableDates[e.detail.value])}
>
<View className='bg-gray-50 rounded-lg p-3 flex justify-between items-center'>
<Text className={`text-sm ${newDate ? 'text-gray-800' : 'text-gray-400'}`}>
{newDate || '请选择日期'}
</Text>
<Text className='text-gray-400'></Text>
</View>
</Picker>
</View>
{/* 选择新时段 */}
<View className='bg-white mx-3 mt-3 rounded-xl p-4'>
<Text className='text-base font-medium text-gray-800 mb-3 block'></Text>
<View className='flex flex-wrap gap-2'>
{availableTimes.map(time => (
<View
key={time}
className={`px-4 py-2 rounded-full border ${
newTime === time
? 'border-orange-500 bg-orange-50'
: 'border-gray-200'
}`}
onClick={() => setNewTime(time)}
>
<Text
className={`text-sm ${
newTime === time ? 'text-orange-500' : 'text-gray-700'
}`}
>
{time}
</Text>
</View>
))}
</View>
</View>
{/* 改签说明 */}
<View className='bg-white mx-3 mt-3 rounded-xl p-4'>
<Text className='text-base font-medium text-gray-800 mb-3 block'></Text>
<View className='text-xs text-gray-500 leading-6'>
<Text className='block'>1. </Text>
<Text className='block'>2. 2</Text>
<Text className='block'>3. </Text>
<Text className='block'>4. </Text>
</View>
</View>
</ScrollView>
{/* 提交按钮 */}
<View className='bg-white p-3 shadow-lg' style={{ paddingBottom: '20px' }}>
<View
className={`text-center py-3 rounded-full ${
newDate && newTime ? 'bg-orange-500' : 'bg-gray-300'
}`}
onClick={newDate && newTime ? handleSubmit : undefined}
>
<Text className='text-white font-bold'></Text>
</View>
</View>
</View>
)
}
export default BookingReschedulePage