import { useCallback, useState } from 'react'; import { View, Text } from '@tarojs/components'; import '../../styles/address.css'; import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'; import PageShell from '../../components/PageShell'; import SubPageHeader from '../../components/SubPageHeader'; import { buildAddressEditUrl, buildOrderConfirmUrl, readCheckoutContext, } from '../../lib/checkout-nav'; import { isDirtyShippingAddress } from '../../lib/shipping-address'; import { request, toast } from '../../lib/api'; type Address = { id: string; receiverName: string; phone: string; province: string; city: string; district: string; detail: string; isDefault?: number | boolean; }; function formatAddress(a: Address) { return `${a.province}${a.city}${a.district}${a.detail}`; } export default function AddressesPage() { const router = useRouter(); const checkoutCtx = readCheckoutContext(router.params); const selectMode = checkoutCtx.select === true; const [list, setList] = useState([]); const [loading, setLoading] = useState(true); const loadList = useCallback(() => { setLoading(true); request('/user/addresses') .then((data) => setList(Array.isArray(data) ? data : [])) .catch(() => setList([])) .finally(() => setLoading(false)); }, []); useDidShow(() => { loadList(); }); usePullDownRefresh(() => { void Promise.resolve(loadList()).finally(() => Taro.stopPullDownRefresh()); }); function selectAddress(addr: Address) { if (!selectMode) return; if (isDirtyShippingAddress(addr)) { toast('该地址缺少具体区县,请先完善'); Taro.navigateTo({ url: buildAddressEditUrl(addr.id, checkoutCtx) }).catch(() => {}); return; } Taro.redirectTo({ url: buildOrderConfirmUrl({ productId: checkoutCtx.productId, qty: checkoutCtx.qty, addressId: addr.id, cross: checkoutCtx.cross, }), }); } async function removeAddress(id: string) { const res = await Taro.showModal({ title: '删除地址', content: '确定删除该收货地址吗?', }); if (!res.confirm) return; try { await request(`/user/addresses/${id}`, { method: 'DELETE' }); toast('已删除', 'success'); loadList(); } catch (e) { toast(e instanceof Error ? e.message : '删除失败'); } } const sorted = [...list].sort((a, b) => { const da = isDirtyShippingAddress(a) ? 0 : 1; const db = isDirtyShippingAddress(b) ? 0 : 1; return da - db; }); return ( {loading ? 加载中… : null} {!loading && list.length === 0 ? ( 暂无收货地址 ) : null} {sorted.map((a) => { const dirty = isDirtyShippingAddress(a); return ( selectAddress(a)} > {a.receiverName} {a.phone} {dirty ? 需完善 : null} {a.isDefault === 1 || a.isDefault === true ? ( 默认 ) : null} {formatAddress(a)} {dirty ? ( 缺少具体区县,同城配送可能失败,请编辑完善 ) : null} {!selectMode || dirty ? ( { e.stopPropagation(); Taro.navigateTo({ url: buildAddressEditUrl(a.id, checkoutCtx) }).catch((err) => { toast(err instanceof Error ? err.message : '无法打开编辑页'); }); }} > {dirty ? '去完善' : '编辑'} {!selectMode ? ( { e.stopPropagation(); void removeAddress(a.id); }} > 删除 ) : null} ) : null} ); })} { Taro.navigateTo({ url: buildAddressEditUrl(undefined, checkoutCtx) }).catch((e) => { toast(e instanceof Error ? e.message : '无法打开新增地址页'); }); }} > 新增地址 ); }