feat: refresh product and customization flows

This commit is contained in:
2026-08-07 16:52:13 +08:00
parent 3af43f6e82
commit 6dd9e15ea5
10 changed files with 180 additions and 190 deletions
+14 -27
View File
@@ -19,7 +19,7 @@
position: relative;
overflow: hidden;
background: rgba(0,0,0,0.03);
border: 2px dashed var(--line-star);
border: 1rpx solid var(--border-strong);
max-width: 100%;
box-sizing: border-box;
}
@@ -42,7 +42,7 @@
align-items: center;
justify-content: space-between;
padding: 20px 0;
border-bottom: 1px dashed rgba(0,0,0,0.06);
border-bottom: 1rpx solid var(--border);
}
.info-row:last-child {
@@ -68,7 +68,7 @@
.info-total {
font-size: 40px;
font-weight: 800;
color: var(--accent-pink);
color: var(--accent-primary);
}
/* 地址卡片 */
@@ -86,12 +86,12 @@
.address-change {
padding: 6px 16px;
border-radius: 8px;
background: rgba(91, 140, 255, 0.08);
background: var(--accent-secondary-soft);
}
.change-text {
font-size: 24px;
color: var(--accent-blue);
color: var(--accent-secondary);
}
.checkout-address-body {
@@ -160,11 +160,11 @@
.addr-picker-item {
padding: 20px 16px;
border-bottom: 1px dashed rgba(0, 0, 0, 0.05);
border-bottom: 1rpx solid var(--border);
}
.addr-picker-item.active {
background: rgba(91, 140, 255, 0.06);
background: var(--accent-secondary-soft);
border-radius: 12px;
}
@@ -188,8 +188,8 @@
.addr-picker-default {
font-size: 22px;
color: var(--accent-pink);
border: 1px solid var(--accent-pink);
color: var(--accent-primary);
border: 1px solid var(--accent-primary);
padding: 2px 8px;
border-radius: 6px;
}
@@ -210,31 +210,18 @@
margin-top: 16px;
padding: 20px;
text-align: center;
border: 2px dashed var(--accent-blue);
border: 1rpx solid var(--border-strong);
border-radius: 12px;
}
.addr-picker-add-text {
font-size: 28px;
color: var(--accent-blue);
color: var(--accent-secondary);
}
/* 底部操作 */
.checkout-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--bg-card);
border-top: var(--line-card);
padding: 20px 32px calc(20px + env(safe-area-inset-bottom));
display: flex;
gap: 24px;
z-index: 500;
}
.checkout-actions .btn-outline,
.checkout-actions .btn-gradient {
/* 底部操作 — 毛玻璃规则由全局 .action-bar 提供 */
.action-bar .btn-secondary,
.action-bar .btn-primary {
flex: 1;
text-align: center;
}
+21 -24
View File
@@ -18,8 +18,9 @@ export default function CheckoutPage() {
const [addrList, setAddrList] = useState<AddressItem[]>([])
useEffect(() => {
const params = Taro.getCurrentInstance().router?.params
const dId = params?.designId
const router = Taro.getCurrentInstance().router
const params = router ? router.params : undefined
const dId = params ? params.designId : undefined
if (!dId) return
const list = getDesignList()
const d = list.find(x => x.id === dId)
@@ -35,7 +36,7 @@ export default function CheckoutPage() {
}
Taro.showModal({
title: '确认下单',
content: `确认后将从设计清单生成订单,并寄送至:\n${address.region?.join(' ')} ${address.detail}`,
content: `确认后将从设计清单生成订单,并寄送至:\n${address.region ? address.region.join(' ') : ''} ${address.detail}`,
success: (res) => {
if (res.confirm) {
designToOrder(design.id)
@@ -54,15 +55,15 @@ export default function CheckoutPage() {
Taro.showToast({ title: '地址已更改', icon: 'success' })
}
const hasStickers = design?.designData?.stickers && design.designData.stickers.length > 0
const hasLegacyImage = design?.designData?.imageSrc
const hasStickers = design && design.designData && design.designData.stickers && design.designData.stickers.length > 0
const hasLegacyImage = design && design.designData ? design.designData.imageSrc : undefined
if (!design) {
return (
<View className={`theme-${resolvedTheme}`}>
<ThemedPageMeta />
<View className='checkout-page'>
<View className='page-header dashed-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
<Text className='page-title'></Text>
</View>
</View>
@@ -71,7 +72,7 @@ export default function CheckoutPage() {
}
const maskStyle: any = { width: 300, height: 420 }
if (design.designData?.category?.mask) {
if (design.designData && design.designData.category && design.designData.category.mask) {
const m = design.designData.category.mask
maskStyle.width = m.width
maskStyle.height = m.height
@@ -84,8 +85,7 @@ export default function CheckoutPage() {
<ThemedPageMeta />
<View className='checkout-page'>
<View className='page-header dashed-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
<View className='star-badge' />
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
<View className='flex-between' style={{ width: '100%' }}>
<Text className='back-btn' onTap={() => Taro.navigateBack()}></Text>
<Text className='page-title'></Text>
@@ -94,8 +94,7 @@ export default function CheckoutPage() {
</View>
{/* 效果展示区 */}
<View className='checkout-canvas dashed-card mt-20'>
<View className='star-badge' />
<View className='checkout-canvas surface-card mt-20'>
<View className='canvas-area' style={maskStyle}>
{hasStickers ? (
design.designData.stickers.map((s: any) => (
@@ -116,7 +115,7 @@ export default function CheckoutPage() {
className='checkout-image'
src={design.designData.imageSrc}
style={{
transform: `translate(${design.designData.imagePos?.x || 0}px, ${design.designData.imagePos?.y || 0}px) scale(${design.designData.imagePos?.scale || 1})`
transform: `translate(${design.designData.imagePos ? design.designData.imagePos.x || 0 : 0}px, ${design.designData.imagePos ? design.designData.imagePos.y || 0 : 0}px) scale(${design.designData.imagePos ? design.designData.imagePos.scale || 1 : 1})`
}}
mode='aspectFit'
/>
@@ -125,8 +124,7 @@ export default function CheckoutPage() {
</View>
{/* 商品信息 */}
<View className='checkout-info dashed-card mt-20'>
<View className='star-badge' />
<View className='checkout-info surface-card mt-20'>
<View className='info-row'>
<Text className='info-label'></Text>
<Text className='info-value'>{design.productName}</Text>
@@ -146,8 +144,7 @@ export default function CheckoutPage() {
</View>
{/* 收货地址 */}
<View className='checkout-address-card dashed-card mt-20'>
<View className='star-badge' />
<View className='checkout-address-card surface-card mt-20'>
<View className='checkout-address-header'>
<Text className='info-label'></Text>
<View className='address-change' onTap={() => setShowAddrPicker(true)}>
@@ -161,7 +158,7 @@ export default function CheckoutPage() {
<Text className='addr-phone'>{address.phone}</Text>
</View>
<Text className='addr-detail'>
{address.region?.join(' ')} {address.detail}
{address.region ? address.region.join(' ') : ''} {address.detail}
</Text>
</View>
) : (
@@ -172,21 +169,21 @@ export default function CheckoutPage() {
</View>
{/* 底部操作 */}
<View className='checkout-actions'>
<View className='btn-outline' onTap={() => Taro.navigateBack()}>
<View className='action-bar'>
<View className='btn-secondary' onTap={() => Taro.navigateBack()}>
<Text></Text>
</View>
<View className='btn-gradient' onTap={handleConfirm}>
<View className='btn-primary' onTap={handleConfirm}>
<Text></Text>
</View>
</View>
<View style={{ height: '40px' }} />
<View className='safe-bottom-placeholder' />
{/* 地址选择底部弹窗 */}
{showAddrPicker && (
<View className='modal-overlay' style={{ alignItems: 'flex-end', justifyContent: 'flex-end' }}>
<View className='addr-picker-sheet dashed-card'>
<View className='addr-picker-sheet surface-card'>
<View className='addr-picker-header'>
<Text className='addr-picker-title'></Text>
<Text className='addr-picker-close' onTap={() => setShowAddrPicker(false)}></Text>
@@ -195,7 +192,7 @@ export default function CheckoutPage() {
{addrList.map((addr) => (
<View
key={addr.id}
className={`addr-picker-item ${address?.id === addr.id ? 'active' : ''}`}
className={`addr-picker-item ${address && address.id === addr.id ? 'active' : ''}`}
onTap={() => handlePickAddress(addr)}
>
<View className='addr-picker-row'>
@@ -204,7 +201,7 @@ export default function CheckoutPage() {
{addr.isDefault && <Text className='addr-picker-default'></Text>}
</View>
<Text className='addr-picker-detail'>
{addr.region?.join(' ')} {addr.detail}
{addr.region ? addr.region.join(' ') : ''} {addr.detail}
</Text>
</View>
))}