登录页面

This commit is contained in:
2026-07-12 15:17:54 +08:00
parent becf91da52
commit bfac6c6663
63 changed files with 4662 additions and 431 deletions
@@ -0,0 +1,128 @@
import { useEffect, useState } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { usePageScroll, useRouter } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import PageNavBar from '../../components/PageNavBar';
import ProductCarousel from '../../components/ProductCarousel';
import { request, toast } from '../../lib/api';
type Store = {
id: string;
name: string;
address?: string;
district?: string;
phone?: string;
coverUrl?: string | null;
carouselUrls?: string[] | null;
openTime?: string | null;
closeTime?: string | null;
category?: { name: string } | null;
};
export default function StoreDetailPage() {
const router = useRouter();
const storeId = router.params.id ?? '';
const [store, setStore] = useState<Store | null>(null);
const [headerSolid, setHeaderSolid] = useState(false);
usePageScroll(({ scrollTop }) => {
setHeaderSolid(scrollTop > 100);
});
useEffect(() => {
if (!storeId) return;
request<Store>(`/stores/${storeId}`)
.then(setStore)
.catch(() => {
request<Store[]>('/stores')
.then((list) => {
const found = (Array.isArray(list) ? list : []).find((s) => s.id === storeId);
if (found) setStore(found);
else toast('门店不存在');
})
.catch((e) => toast(e instanceof Error ? e.message : '加载失败'));
});
}, [storeId]);
function goBack() {
const pages = Taro.getCurrentPages();
if (pages.length > 1) Taro.navigateBack();
else Taro.switchTab({ url: '/pages/stores/index' });
}
if (!store) {
return (
<PageShell variant="scroll" className="store-detail-page">
<PageNavBar title="门店详情" solid onBack={goBack} />
<View className="page-with-nav-bar u-empty"></View>
</PageShell>
);
}
const images =
(store.carouselUrls && store.carouselUrls.length > 0
? store.carouselUrls
: store.coverUrl
? [store.coverUrl]
: []) as string[];
return (
<PageShell variant="scroll" className="store-detail-page" hasFixedFooter>
<PageNavBar
title={store.name}
solid={headerSolid}
titleVisible={headerSolid}
onBack={goBack}
/>
<View className="store-detail-hero full-bleed">
<ProductCarousel images={images} alt={store.name} variant="store" />
</View>
<View className="store-detail-info-card">
<Text className="store-detail-name">{store.name}</Text>
<Text className="store-detail-meta">
{store.district ? `${store.district} · ` : ''}
{store.address || '地址待完善'}
</Text>
<Text className="store-detail-meta">
: {store.openTime && store.closeTime ? `${store.openTime}-${store.closeTime}` : '10:00-22:00'}
</Text>
{store.phone ? <Text className="store-detail-meta">: {store.phone}</Text> : null}
<View className="store-detail-tags">
{store.category?.name ? (
<Text className="store-detail-tag">{store.category.name}</Text>
) : null}
<Text className="store-detail-tag"></Text>
<Text className="store-detail-tag"></Text>
</View>
</View>
<View className="store-detail-section">
<Text className="store-detail-section-title"></Text>
<Text className="store-detail-meta"></Text>
</View>
<View className="store-detail-bar">
<View
className="store-detail-bar-btn store-detail-bar-btn--ghost"
onClick={() => {
if (store.phone) {
Taro.makePhoneCall({ phoneNumber: store.phone }).catch(() => toast('无法拨打'));
} else {
toast('暂无联系电话');
}
}}
>
<Text></Text>
</View>
<View
className="store-detail-bar-btn store-detail-bar-btn--primary"
onClick={() => Taro.navigateTo({ url: '/pages/redeem/index' })}
>
<Text></Text>
</View>
</View>
</PageShell>
);
}