import type { ProductDetailContentDto } from '@dukang/shared-types'; import { Link, useNavigate, useParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; import AppImage from '@dukang/shared-ui/AppImage'; import ProductCarousel from '../components/ProductCarousel'; import AppToast from '../components/AppToast'; import { request } from '../lib/api'; import { track } from '../lib/analytics'; import { handleShareButtonClick } from '../lib/wechat-share'; import { getProductCarouselImages, getProductDetailImages } from '../lib/product-images'; import type { ProductImageSource } from '../lib/product-images'; type Product = ProductImageSource & { name: string; subtitle?: string; price: number; benefitAmount?: number; detailContent?: ProductDetailContentDto | null; }; export default function ProductDetailPage() { const { id } = useParams(); const navigate = useNavigate(); const [product, setProduct] = useState(null); const [headerSolid, setHeaderSolid] = useState(false); const [toast, setToast] = useState(''); useEffect(() => { if (id) request('USER_H5', `/catalog/products/${id}`).then(setProduct); }, [id]); useEffect(() => { if (id) { track('product_detail_view', { refType: 'PRODUCT', refId: id, productId: id }); } }, [id]); useEffect(() => { function onScroll() { setHeaderSolid(window.scrollY > 100); } window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); if (!product) return
加载中...
; const benefit = Number(product.benefitAmount ?? product.price); const carouselImages = getProductCarouselImages(product); const detailImages = getProductDetailImages(product); const detail = product.detailContent ?? {}; const features = detail.features ?? []; return (

{product.name}

¥ {product.price}

{product.name}

{product.subtitle && (

{product.subtitle}

)}
confirmation_number

买杜康美酒 · 享全城好客礼遇 ¥{benefit}

购酒即享本城专属好客权益,为您安排一场地道饭局。权益金可直接用于本地签约门店消费,到店享用,醇香美酒配佳肴。

restaurant

商品详情

{detailImages.map((src, index) => ( ))} {(detail.storyTitle || detail.storyText || features.length > 0) && (
{(detail.storyTitle || detail.storyText) && (
{detail.storyTitle &&

{detail.storyTitle}

} {detail.storyText &&

{detail.storyText}

}
)} {features.length > 0 && (
{features.map((f) => (
{f.icon}
{f.title}
{f.desc}
))}
)}
)}
); }