登录页面

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,130 @@
import { useEffect, useMemo, useState } from 'react';
import { View, Text, Image } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import SubPageHeader from '../../components/SubPageHeader';
import { request, toast } from '../../lib/api';
import { getProductMainImage } from '../../lib/product-images';
type Product = {
id: string;
name: string;
price: number;
mainImageUrl?: string | null;
carouselUrls?: string[] | null;
benefitDisplay?: number;
};
export default function OrderConfirmPage() {
const router = useRouter();
const productId = router.params.productId ?? '';
const initialQty = Math.max(2, Number(router.params.qty || 2));
const [product, setProduct] = useState<Product | null>(null);
const [qty, setQty] = useState(initialQty);
useEffect(() => {
if (!productId) return;
request<Product>(`/catalog/products/${productId}`)
.then(setProduct)
.catch((e) => toast(e instanceof Error ? e.message : '加载失败'));
}, [productId]);
const total = useMemo(() => {
if (!product) return 0;
return Number(product.price) * qty;
}, [product, qty]);
const benefit = useMemo(() => {
if (!product) return 0;
return Number(product.benefitDisplay ?? product.price) * qty;
}, [product, qty]);
function changeQty(delta: number) {
setQty((q) => Math.max(2, q + delta));
}
function submit() {
if (!productId) return;
Taro.navigateTo({
url: `/pages/pay/index?productId=${productId}&qty=${qty}&amount=${total.toFixed(2)}`,
});
}
return (
<PageShell variant="sub" className="order-confirm-page" hasFixedFooter>
<SubPageHeader title="确认订单" />
<View className="sub-page-body">
<View
className="order-card"
onClick={() => Taro.navigateTo({ url: '/pages/addresses/index' })}
>
<Text className="order-card-title"></Text>
<Text className="u-muted"> 2 </Text>
</View>
<View className="order-card">
<Text className="order-card-title"></Text>
{product ? (
<View>
<View className="order-product-row">
<View className="order-product-thumb">
{getProductMainImage(product) ? (
<Image
className="order-product-thumb-img"
src={getProductMainImage(product)}
mode="aspectFill"
/>
) : null}
</View>
<View style={{ flex: 1 }}>
<Text className="order-product-name">{product.name}</Text>
<Text className="order-product-price">¥{Number(product.price).toFixed(2)}</Text>
</View>
</View>
<View className="order-qty-row">
<Text></Text>
<View className="order-qty-controls">
<View className="order-qty-btn" onClick={() => changeQty(-1)}>
<Text></Text>
</View>
<Text className="order-qty-value">{qty}</Text>
<View className="order-qty-btn" onClick={() => changeQty(1)}>
<Text></Text>
</View>
</View>
</View>
</View>
) : (
<View className="u-empty"></View>
)}
</View>
<View className="order-card">
<Text className="order-card-title"></Text>
<View className="order-row">
<Text className="order-row-label"></Text>
<Text className="order-row-value">¥{total.toFixed(2)}</Text>
</View>
<View className="order-row">
<Text className="order-row-label"></Text>
<Text className="order-row-value--price">¥{benefit.toFixed(2)}</Text>
</View>
<View className="order-row">
<Text className="order-row-label"></Text>
<Text className="order-row-value"></Text>
</View>
</View>
</View>
<View className="order-confirm-bar">
<View className="order-confirm-total">
<Text className="order-confirm-total-label"></Text>
<Text className="order-confirm-total-value">¥{total.toFixed(2)}</Text>
</View>
<View className="order-confirm-submit" onClick={submit}>
<Text></Text>
</View>
</View>
</PageShell>
);
}