商品只支持现场提货的功能修改
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
/** 商品履约能力(与 HQ / 交易硬闸一致) */
|
||||
|
||||
export type FulfillmentFlags = {
|
||||
allowOnlinePurchase?: boolean | null;
|
||||
allowOnSitePickup?: boolean | null;
|
||||
allowCrossCityDelivery?: boolean | null;
|
||||
};
|
||||
|
||||
/** 未返回时默认允许线上(存量商品) */
|
||||
export function canBuyOnline(p: FulfillmentFlags): boolean {
|
||||
return p.allowOnlinePurchase !== false;
|
||||
}
|
||||
|
||||
/** 仅显式开启才展示现场取货 */
|
||||
export function canPickupOnSite(p: FulfillmentFlags): boolean {
|
||||
return p.allowOnSitePickup === true;
|
||||
}
|
||||
|
||||
export function canCrossCity(p: FulfillmentFlags): boolean {
|
||||
return p.allowCrossCityDelivery !== false;
|
||||
}
|
||||
|
||||
export function normalizeFulfillmentFlags<T extends FulfillmentFlags>(p: T): T {
|
||||
return {
|
||||
...p,
|
||||
allowOnlinePurchase: canBuyOnline(p),
|
||||
allowOnSitePickup: canPickupOnSite(p),
|
||||
allowCrossCityDelivery: canCrossCity(p),
|
||||
};
|
||||
}
|
||||
@@ -17,6 +17,12 @@ import { isLoggedIn, request, toast } from '../../lib/api';
|
||||
import { ensurePayReady } from '../../lib/pay-ready';
|
||||
import { capturePromoSceneAndTouchScan } from '../../lib/promo';
|
||||
import { getProductMainImage } from '../../lib/product-images';
|
||||
import {
|
||||
canBuyOnline,
|
||||
canCrossCity,
|
||||
canPickupOnSite,
|
||||
normalizeFulfillmentFlags,
|
||||
} from '../../lib/product-fulfillment';
|
||||
import { getCityCodeForCatalog, resolveUserCity } from '../../lib/user-location';
|
||||
import {
|
||||
DEFAULT_SHARE_DESC,
|
||||
@@ -50,9 +56,9 @@ const FULFILLMENT_FILTERS: Array<{ key: FulfillmentFilter; label: string }> = [
|
||||
|
||||
function matchFulfillmentFilter(p: Product, filter: FulfillmentFilter): boolean {
|
||||
if (filter === 'ALL') return true;
|
||||
if (filter === 'ONLINE') return p.allowOnlinePurchase !== false;
|
||||
if (filter === 'CROSS_CITY') return p.allowCrossCityDelivery !== false;
|
||||
return !!p.allowOnSitePickup;
|
||||
if (filter === 'ONLINE') return canBuyOnline(p);
|
||||
if (filter === 'CROSS_CITY') return canCrossCity(p);
|
||||
return canPickupOnSite(p);
|
||||
}
|
||||
|
||||
type MiniHomeConfig = {
|
||||
@@ -117,7 +123,9 @@ export default function HomePage() {
|
||||
const loadProducts = useCallback(() => {
|
||||
setLoading(true);
|
||||
return request<Product[]>(`/catalog/products?cityCode=${encodeURIComponent(cityCode)}`)
|
||||
.then((list) => setProducts(Array.isArray(list) ? list : []))
|
||||
.then((list) =>
|
||||
setProducts(Array.isArray(list) ? list.map((p) => normalizeFulfillmentFlags(p)) : []),
|
||||
)
|
||||
.catch((e) => toast(e instanceof Error ? e.message : '加载失败'))
|
||||
.finally(() => setLoading(false));
|
||||
}, [cityCode]);
|
||||
@@ -138,7 +146,7 @@ export default function HomePage() {
|
||||
request<Product[]>(`/catalog/products?cityCode=${encodeURIComponent(nextCode)}`),
|
||||
loadMiniHome(),
|
||||
]);
|
||||
setProducts(Array.isArray(list) ? list : []);
|
||||
setProducts(Array.isArray(list) ? list.map((p) => normalizeFulfillmentFlags(p)) : []);
|
||||
} catch (e) {
|
||||
toast(e instanceof Error ? e.message : '加载失败');
|
||||
} finally {
|
||||
@@ -268,7 +276,7 @@ export default function HomePage() {
|
||||
<CouponBadge amount={p.benefitDisplay ?? p.price} label="好客权益" />
|
||||
</View>
|
||||
<View className="home-product-actions">
|
||||
{p.allowOnSitePickup ? (
|
||||
{canPickupOnSite(p) ? (
|
||||
<Text
|
||||
className="home-pickup-btn"
|
||||
onClick={(e) => {
|
||||
@@ -279,7 +287,7 @@ export default function HomePage() {
|
||||
现场取货
|
||||
</Text>
|
||||
) : null}
|
||||
{p.allowOnlinePurchase !== false ? (
|
||||
{canBuyOnline(p) ? (
|
||||
<Text
|
||||
className="home-buy-btn"
|
||||
onClick={(e) => {
|
||||
|
||||
@@ -16,6 +16,11 @@ import {
|
||||
getProductMainImage,
|
||||
type ProductImageSource,
|
||||
} from '../../lib/product-images';
|
||||
import {
|
||||
canBuyOnline,
|
||||
canPickupOnSite,
|
||||
normalizeFulfillmentFlags,
|
||||
} from '../../lib/product-fulfillment';
|
||||
import {
|
||||
DEFAULT_SHARE_DESC,
|
||||
DEFAULT_SHARE_TITLE,
|
||||
@@ -49,7 +54,7 @@ export default function ProductDetailPage() {
|
||||
useEffect(() => {
|
||||
if (!productId) return;
|
||||
request<Product>(`/catalog/products/${productId}`)
|
||||
.then(setProduct)
|
||||
.then((p) => setProduct(normalizeFulfillmentFlags(p)))
|
||||
.catch((e) => toast(e instanceof Error ? e.message : '加载失败'));
|
||||
}, [productId]);
|
||||
|
||||
@@ -107,9 +112,6 @@ export default function ProductDetailPage() {
|
||||
Taro.navigateTo({ url: returnPath });
|
||||
}
|
||||
|
||||
const allowOnline = product?.allowOnlinePurchase !== false;
|
||||
const allowOnSite = !!product?.allowOnSitePickup;
|
||||
|
||||
if (!product) {
|
||||
return (
|
||||
<PageShell variant="scroll" className="product-detail-page">
|
||||
@@ -119,6 +121,8 @@ export default function ProductDetailPage() {
|
||||
);
|
||||
}
|
||||
|
||||
const allowOnline = canBuyOnline(product);
|
||||
const allowOnSite = canPickupOnSite(product);
|
||||
const benefit = Number(product.benefitDisplay ?? product.benefitAmount ?? product.price);
|
||||
const carouselImages = getProductCarouselImages(product);
|
||||
const detailImages = getProductDetailImages(product);
|
||||
|
||||
Reference in New Issue
Block a user