feat(trade): v4.0.13 收货禁全市与小飞侠拒单可感知
CI / verify (push) Has been cancelled

拦截伪区县写入与下单;推单失败挂 fulfillmentHold,HQ 可见超区/推单失败。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-02 17:20:40 +08:00
parent 63fcf33416
commit c6b01def4c
18 changed files with 613 additions and 76 deletions
+59 -38
View File
@@ -9,6 +9,7 @@ import {
buildOrderConfirmUrl,
readCheckoutContext,
} from '../../lib/checkout-nav';
import { isDirtyShippingAddress } from '../../lib/shipping-address';
import { request, toast } from '../../lib/api';
type Address = {
@@ -51,6 +52,11 @@ export default function AddressesPage() {
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,
@@ -76,6 +82,12 @@ export default function AddressesPage() {
}
}
const sorted = [...list].sort((a, b) => {
const da = isDirtyShippingAddress(a) ? 0 : 1;
const db = isDirtyShippingAddress(b) ? 0 : 1;
return da - db;
});
return (
<PageShell variant="sub" className="address-page" hasFixedFooter>
<SubPageHeader title={selectMode ? '选择收货地址' : '地址管理'} />
@@ -84,46 +96,55 @@ export default function AddressesPage() {
{!loading && list.length === 0 ? (
<View className="u-empty">暂无收货地址</View>
) : null}
{list.map((a) => (
<View
key={a.id}
className="address-item"
onClick={() => selectAddress(a)}
>
<View className="address-item-head">
<Text className="address-item-name">{a.receiverName}</Text>
<Text className="address-item-phone">{a.phone}</Text>
{a.isDefault === 1 || a.isDefault === true ? (
<Text className="address-default-tag">默认</Text>
{sorted.map((a) => {
const dirty = isDirtyShippingAddress(a);
return (
<View
key={a.id}
className={`address-item${dirty ? ' address-item--dirty' : ''}`}
onClick={() => selectAddress(a)}
>
<View className="address-item-head">
<Text className="address-item-name">{a.receiverName}</Text>
<Text className="address-item-phone">{a.phone}</Text>
{dirty ? <Text className="address-need-fix-tag">需完善</Text> : null}
{a.isDefault === 1 || a.isDefault === true ? (
<Text className="address-default-tag">默认</Text>
) : null}
</View>
<Text className="address-item-detail">{formatAddress(a)}</Text>
{dirty ? (
<Text className="address-item-warn">缺少具体区县,同城配送可能失败,请编辑完善</Text>
) : null}
{!selectMode || dirty ? (
<View className="address-item-actions">
<Text
className="address-action"
onClick={(e) => {
e.stopPropagation();
Taro.navigateTo({ url: buildAddressEditUrl(a.id, checkoutCtx) }).catch((err) => {
toast(err instanceof Error ? err.message : '无法打开编辑页');
});
}}
>
{dirty ? '去完善' : '编辑'}
</Text>
{!selectMode ? (
<Text
className="address-action"
onClick={(e) => {
e.stopPropagation();
void removeAddress(a.id);
}}
>
删除
</Text>
) : null}
</View>
) : null}
</View>
<Text className="address-item-detail">{formatAddress(a)}</Text>
{!selectMode ? (
<View className="address-item-actions">
<Text
className="address-action"
onClick={(e) => {
e.stopPropagation();
Taro.navigateTo({ url: buildAddressEditUrl(a.id, checkoutCtx) }).catch((err) => {
toast(err instanceof Error ? err.message : '无法打开编辑页');
});
}}
>
编辑
</Text>
<Text
className="address-action"
onClick={(e) => {
e.stopPropagation();
void removeAddress(a.id);
}}
>
删除
</Text>
</View>
) : null}
</View>
))}
);
})}
</View>
<View
className="address-fab"