feat(orderConfirm): 优化订单确认页面功能和样式

- 添加优惠券选择功能
- 增加商品数量选择
- 完善订单信息展示
- 优化支付流程
- 添加错误状态和加载状态处理
- 新增 OrderConfirmSkeleton 组件用于加载骨架屏
This commit is contained in:
2025-08-11 17:27:00 +08:00
parent c6fcf9c2e5
commit bcaf8203e4
10 changed files with 1314 additions and 86 deletions

View File

@@ -0,0 +1,168 @@
import React from 'react'
import { View, Text } from '@tarojs/components'
import { Button } from '@nutui/nutui-react-taro'
import './CouponCard.scss'
export interface CouponCardProps {
/** 优惠券金额 */
amount: number
/** 最低消费金额 */
minAmount?: number
/** 优惠券类型1-满减券 2-折扣券 3-免费券 */
type?: 1 | 2 | 3
/** 优惠券状态0-未使用 1-已使用 2-已过期 */
status?: 0 | 1 | 2
/** 优惠券标题 */
title?: string
/** 有效期开始时间 */
startTime?: string
/** 有效期结束时间 */
endTime?: string
/** 是否显示领取按钮 */
showReceiveBtn?: boolean
/** 是否显示使用按钮 */
showUseBtn?: boolean
/** 领取按钮点击事件 */
onReceive?: () => void
/** 使用按钮点击事件 */
onUse?: () => void
/** 优惠券样式主题red | orange | blue | purple | green */
theme?: 'red' | 'orange' | 'blue' | 'purple' | 'green'
}
const CouponCard: React.FC<CouponCardProps> = ({
amount,
minAmount,
type = 1,
status = 0,
title,
startTime,
endTime,
showReceiveBtn = false,
showUseBtn = false,
onReceive,
onUse,
theme = 'red'
}) => {
// 格式化优惠券金额显示
const formatAmount = () => {
switch (type) {
case 1: // 满减券
return `¥${amount}`
case 2: // 折扣券
return `${amount}`
case 3: // 免费券
return '免费'
default:
return `¥${amount}`
}
}
// 获取优惠券状态文本
const getStatusText = () => {
switch (status) {
case 0:
return '未使用'
case 1:
return '已使用'
case 2:
return '已过期'
default:
return '未使用'
}
}
// 获取使用条件文本
const getConditionText = () => {
if (type === 3) return '无门槛'
if (minAmount && minAmount > 0) {
return `${minAmount}可用`
}
return '无门槛'
}
// 格式化日期
const formatDate = (dateStr?: string) => {
if (!dateStr) return ''
const date = new Date(dateStr)
return `${date.getMonth() + 1}.${date.getDate()}`
}
// 获取有效期文本
const getValidityText = () => {
if (startTime && endTime) {
return `${formatDate(startTime)}-${formatDate(endTime)}`
}
return ''
}
return (
<View className={`coupon-card coupon-card--${theme} ${status !== 0 ? 'coupon-card--disabled' : ''}`}>
{/* 左侧金额区域 */}
<View className="coupon-card__left">
<View className="coupon-card__amount">
<Text className="coupon-card__currency">¥</Text>
<Text className="coupon-card__value">{amount}</Text>
</View>
<View className="coupon-card__condition">
{getConditionText()}
</View>
</View>
{/* 中间分割线 */}
<View className="coupon-card__divider">
<View className="coupon-card__divider-line"></View>
<View className="coupon-card__circle coupon-card__circle--top"></View>
<View className="coupon-card__circle coupon-card__circle--bottom"></View>
</View>
{/* 右侧信息区域 */}
<View className="coupon-card__right">
<View className="coupon-card__info">
<View className="coupon-card__title">
{title || (type === 1 ? '满减券' : type === 2 ? '折扣券' : '免费券')}
</View>
<View className="coupon-card__validity">
{getValidityText()}
</View>
</View>
{/* 按钮区域 */}
<View className="coupon-card__action">
{showReceiveBtn && status === 0 && (
<Button
className="coupon-card__btn coupon-card__btn--receive"
size="small"
onClick={onReceive}
>
</Button>
)}
{showUseBtn && status === 0 && (
<Button
className="coupon-card__btn coupon-card__btn--use"
size="small"
onClick={onUse}
>
使
</Button>
)}
{status !== 0 && (
<View className="coupon-card__status">
{getStatusText()}
</View>
)}
</View>
</View>
{/* 状态遮罩 */}
{status !== 0 && (
<View className="coupon-card__mask">
<Text className="coupon-card__mask-text">{getStatusText()}</Text>
</View>
)}
</View>
)
}
export default CouponCard