c6b01def4c
CI / verify (push) Has been cancelled
拦截伪区县写入与下单;推单失败挂 fulfillmentHold,HQ 可见超区/推单失败。 Co-authored-by: Cursor <cursoragent@cursor.com>
62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import {
|
|
REGION_ALL,
|
|
isShippingRegionComplete,
|
|
normalizeShippingRegionSelection,
|
|
type RegionSelection,
|
|
} from './region-data';
|
|
|
|
export const SHIPPING_DETAIL_MIN_LEN = 8;
|
|
export const SHIPPING_REGION_REQUIRED_MSG = '请选择具体区县';
|
|
export const SHIPPING_DETAIL_REQUIRED_MSG = '请填写详细地址';
|
|
export const SHIPPING_DETAIL_TOO_SHORT_MSG = '请填写更详细的收货地址(含街道门牌)';
|
|
|
|
export type ShippingAddressLike = {
|
|
province?: string | null;
|
|
city?: string | null;
|
|
district?: string | null;
|
|
detail?: string | null;
|
|
};
|
|
|
|
export function isDirtyShippingAddress(addr: ShippingAddressLike): boolean {
|
|
return !validateClientShippingAddress(addr).ok;
|
|
}
|
|
|
|
export function validateClientShippingAddress(addr: ShippingAddressLike): {
|
|
ok: boolean;
|
|
message?: string;
|
|
} {
|
|
const province = String(addr.province ?? '').trim();
|
|
const city = String(addr.city ?? '').trim();
|
|
const district = String(addr.district ?? '').trim();
|
|
const detail = String(addr.detail ?? '').trim();
|
|
|
|
if (!province || !city) return { ok: false, message: '请选择所在地区' };
|
|
if (!district || district === REGION_ALL || district === '全部') {
|
|
return { ok: false, message: SHIPPING_REGION_REQUIRED_MSG };
|
|
}
|
|
const regionOk = isShippingRegionComplete({ province, city, district });
|
|
if (!regionOk) {
|
|
return { ok: false, message: SHIPPING_REGION_REQUIRED_MSG };
|
|
}
|
|
if (!detail) return { ok: false, message: SHIPPING_DETAIL_REQUIRED_MSG };
|
|
if (detail.length < SHIPPING_DETAIL_MIN_LEN) {
|
|
return { ok: false, message: SHIPPING_DETAIL_TOO_SHORT_MSG };
|
|
}
|
|
return { ok: true };
|
|
}
|
|
|
|
export function shippingDetailCityWideHint(detail: string | null | undefined): string | null {
|
|
const d = String(detail ?? '').trim();
|
|
if (!d.includes('全市')) return null;
|
|
if (/路|街|巷|号|大厦|广场|小区|村|镇|乡/.test(d)) return null;
|
|
return '详细地址含「全市」,建议改为具体街道门牌,以免配送拒单';
|
|
}
|
|
|
|
export function toShippingRegion(addr: ShippingAddressLike): RegionSelection {
|
|
return normalizeShippingRegionSelection({
|
|
province: String(addr.province ?? ''),
|
|
city: String(addr.city ?? ''),
|
|
district: String(addr.district ?? ''),
|
|
});
|
|
}
|