diff --git a/src/user/ticket/use.tsx b/src/user/ticket/use.tsx index d02e892..4ea2a4d 100644 --- a/src/user/ticket/use.tsx +++ b/src/user/ticket/use.tsx @@ -81,6 +81,8 @@ const OrderConfirm = () => { const [deliveryRangeChecking, setDeliveryRangeChecking] = useState(false) const deliveryRangeCheckingRef = useRef(false) const [inDeliveryRange, setInDeliveryRange] = useState(undefined) + // Prevent using stale `inDeliveryRange` from a previous address when user switches addresses. + const [deliveryRangeCheckedAddressId, setDeliveryRangeCheckedAddressId] = useState(undefined) const router = Taro.getCurrentInstance().router; const goodsId = router?.params?.goodsId; @@ -264,6 +266,7 @@ const OrderConfirm = () => { const p = await getCheckPoint() const ok = await isPointInFence(p) setInDeliveryRange(ok) + setDeliveryRangeCheckedAddressId(address?.id) if (!ok) { Taro.showToast({ title: '不在配送范围内,暂不支持下单', icon: 'none' }) } @@ -271,6 +274,7 @@ const OrderConfirm = () => { } catch (e: any) { console.error('配送范围校验失败:', e) setInDeliveryRange(undefined) + setDeliveryRangeCheckedAddressId(undefined) // Note: we validate by address coords only; no GPS permission prompt here. Taro.showToast({ title: e?.message || '配送范围校验失败,请稍后重试', icon: 'none' }) @@ -654,26 +658,33 @@ const OrderConfirm = () => { ;(async () => { if (!address?.id) { setInDeliveryRange(undefined) + setDeliveryRangeCheckedAddressId(undefined) return } const p = parseLngLatFromText(`${address?.lng || ''},${address?.lat || ''}`) if (!p) { // Cannot validate without address coords -> treat as out of range to block ordering. setInDeliveryRange(false) + setDeliveryRangeCheckedAddressId(address.id) return } // Avoid keeping stale state from previous address while we validate this one. setInDeliveryRange(undefined) + setDeliveryRangeCheckedAddressId(undefined) let ok = true try { ok = await isPointInFence(p) } catch (_e) { // Pre-check is best-effort; don't block UI here. - if (!cancelled) setInDeliveryRange(undefined) + if (!cancelled) { + setInDeliveryRange(undefined) + setDeliveryRangeCheckedAddressId(undefined) + } return } if (cancelled) return setInDeliveryRange(ok) + setDeliveryRangeCheckedAddressId(address.id) })() return () => { cancelled = true @@ -686,11 +697,12 @@ const OrderConfirm = () => { useEffect(() => { const id = address?.id if (!id) return + if (deliveryRangeCheckedAddressId !== id) return if (inDeliveryRange !== false) return if (outOfRangePromptedAddressIdRef.current === id) return outOfRangePromptedAddressIdRef.current = id Taro.showToast({ title: addressHasCoords ? '该地址不在配送范围,请更换围栏内地址' : '该地址缺少定位,请在地址里选择地图定位后重试', icon: 'none' }) - }, [address?.id, addressHasCoords, inDeliveryRange]) + }, [address?.id, addressHasCoords, deliveryRangeCheckedAddressId, inDeliveryRange]) // When tickets/stock change, clamp quantity into [0..maxQuantity]. useEffect(() => { @@ -1049,7 +1061,7 @@ const OrderConfirm = () => { deliveryRangeChecking || !address?.id || !addressHasCoords || - inDeliveryRange === false || + (deliveryRangeCheckedAddressId === address?.id && inDeliveryRange === false) || availableTicketTotal <= 0 || !canStartOrder } @@ -1057,7 +1069,16 @@ const OrderConfirm = () => { > {deliveryRangeChecking ? '校验配送范围...' - : (!address?.id ? '请选择地址' : (!addressHasCoords ? '地址缺少定位' : (inDeliveryRange === false ? '不在配送范围' : (submitLoading ? '提交中...' : '立即提交')))) + : (!address?.id + ? '请选择地址' + : (!addressHasCoords + ? '地址缺少定位' + : ((deliveryRangeCheckedAddressId === address?.id && inDeliveryRange === false) + ? '不在配送范围' + : (submitLoading ? '提交中...' : '立即提交') + ) + ) + ) } )}