Files
xinlong-shop-taro/src_bak/pages/list.tsx
赵忠林 1fa58040f3 feat(user): 新增收货地址管理及售后申请页面
- 新增地址类型定义,增强前端地址数据结构
- 新增地址编辑页面,支持地址智能识别和定位选点功能
- 地址编辑支持省市区选择及默认地址设置
- 新增地址列表页面,支持地址展示、删除、编辑和选择功能
- 实现售后申请页面,支持选择售后类型和退款原因
- 售后申请支持商品选择、退款金额计算和凭证上传
- 新增售后详情页面,支持售后状态展示及申请取消
- 优化页面加载和用户交互体验,增加错误提示和权限处理
2026-07-01 12:11:56 +08:00

132 lines
4.4 KiB
TypeScript

import React, { useState, useEffect } from 'react'
import { View, Text, ScrollView, Image } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { listShopStore } from '@/api/shop/shopStore'
import type { ShopStore } from '@/api/shop/shopStore/model'
import EmptyState from '@/components/common/EmptyState'
import { useScrollHeight } from '@/hooks/useScrollHeight'
definePageConfig({
navigationBarTitleText: '门店列表',
})
const StoreListPage: React.FC = () => {
const [stores, setStores] = useState<ShopStore[]>([])
const [loading, setLoading] = useState(true)
const scrollHeight = useScrollHeight(44)
useEffect(() => {
fetchStores()
}, [])
const fetchStores = async () => {
try {
const data = await listShopStore({ status: 1 })
setStores(data || [])
} catch (e) {
console.error('获取门店列表失败:', e)
} finally {
setLoading(false)
}
}
const handleCallStore = (phone: string) => {
Taro.makePhoneCall({
phoneNumber: phone,
fail: () => {
Taro.showToast({ title: '拨打失败', icon: 'none' })
},
})
}
const handleOpenMap = (store: ShopStore) => {
if (store.latitude && store.longitude) {
Taro.openLocation({
latitude: parseFloat(store.latitude),
longitude: parseFloat(store.longitude),
name: store.name || '',
address: store.address || '',
})
} else {
Taro.showToast({ title: '暂无位置信息', icon: 'none' })
}
}
const handleBooking = (storeId: number) => {
Taro.navigateTo({ url: `/pages/store/booking?storeId=${storeId}` })
}
return (
<View className='min-h-screen bg-gray-50'>
<ScrollView scrollY style={{ height: scrollHeight }}>
{loading ? (
<View className='flex items-center justify-center py-10'>
<Text className='text-gray-400'>...</Text>
</View>
) : stores.length === 0 ? (
<EmptyState text='暂无门店' />
) : (
<View className='p-3'>
{stores.map(store => (
<View key={store.id} className='bg-white rounded-lg p-3 mb-3'>
<View className='flex justify-between items-start mb-2'>
<Text className='text-base font-medium text-gray-800 flex-1'>
{store.name}
</Text>
{store.distance && (
<Text className='text-xs text-gray-400 ml-2'>
{store.distance < 1
? `${Math.round(store.distance * 1000)}m`
: `${store.distance.toFixed(1)}km`}
</Text>
)}
</View>
<View className='flex items-center mb-1'>
<Text className='text-xs text-gray-400 mr-2'>📍</Text>
<Text className='text-xs text-gray-600 flex-1'>
{store.address}
</Text>
</View>
{store.businessHours && (
<View className='flex items-center mb-2'>
<Text className='text-xs text-gray-400 mr-2'>🕐</Text>
<Text className='text-xs text-gray-600'>
{store.businessHours}
</Text>
</View>
)}
<View className='flex gap-2 mt-2'>
<View
className='flex-1 py-2 bg-blue-50 rounded-lg text-center'
onClick={() => handleCallStore(store.phone || '')}
>
<Text className='text-xs text-blue-500'>📞 </Text>
</View>
<View
className='flex-1 py-2 bg-green-50 rounded-lg text-center'
onClick={() => handleOpenMap(store)}
>
<Text className='text-xs text-green-500'>📍 </Text>
</View>
{/*<View*/}
{/* className='flex-1 py-2 bg-orange-50 rounded-lg text-center'*/}
{/* onClick={() => handleBooking(store.id!)}*/}
{/*>*/}
{/* <Text className='text-xs text-orange-500'>📅 立即预约</Text>*/}
{/*</View>*/}
</View>
</View>
))}
</View>
)}
</ScrollView>
</View>
)
}
export default StoreListPage