# PaymentCountdown 支付倒计时组件 基于订单创建时间的支付倒计时组件,支持静态显示和实时更新两种模式。 ## 功能特性 - ✅ **双模式支持**:静态显示(列表页)和实时更新(详情页) - ✅ **智能状态判断**:自动判断紧急程度并应用不同样式 - ✅ **过期自动处理**:倒计时结束后触发回调 - ✅ **灵活样式**:支持徽章模式和纯文本模式 - ✅ **性能优化**:避免不必要的重渲染 ## 使用方法 ### 基础用法 ```tsx import PaymentCountdown from '@/components/PaymentCountdown'; // 订单列表页 - 静态显示 // 订单详情页 - 实时更新 { console.log('支付已过期'); }} /> ``` ### 高级用法 ```tsx // 自定义超时时间(12小时) // 纯文本模式 ``` ## API 参数 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | createTime | string | - | 订单创建时间 | | payStatus | boolean | false | 支付状态 | | realTime | boolean | false | 是否实时更新 | | timeoutHours | number | 24 | 超时小时数 | | showSeconds | boolean | false | 是否显示秒数 | | className | string | '' | 自定义样式类名 | | onExpired | function | - | 过期回调函数 | | mode | 'badge' \| 'text' | 'badge' | 显示模式 | ## 样式状态 ### 正常状态 - 红色渐变背景 - 白色文字 - 轻微阴影效果 ### 紧急状态(< 1小时) - 更深的红色背景 - 脉冲动画效果 ### 非常紧急状态(< 10分钟) - 最深的红色背景 - 快速闪烁动画 ### 过期状态 - 灰色背景 - 无动画效果 ## Hook 使用 如果需要单独使用倒计时逻辑,可以直接使用 Hook: ```tsx import { usePaymentCountdown, formatCountdownText } from '@/hooks/usePaymentCountdown'; const MyComponent = ({ order }) => { const timeLeft = usePaymentCountdown( order.createTime, order.payStatus, true, // 实时更新 24 // 24小时超时 ); const countdownText = formatCountdownText(timeLeft, true); return (
剩余时间:{countdownText}
); }; ``` ## 工具函数 ```tsx import { formatCountdownText, isUrgentCountdown, isCriticalCountdown } from '@/hooks/usePaymentCountdown'; // 格式化倒计时文本 const text = formatCountdownText(timeLeft, true); // "2小时30分15秒" // 判断是否紧急 const isUrgent = isUrgentCountdown(timeLeft); // < 1小时 // 判断是否非常紧急 const isCritical = isCriticalCountdown(timeLeft); // < 10分钟 ``` ## 注意事项 1. **性能考虑**:列表页建议使用 `realTime={false}` 避免过多定时器 2. **内存泄漏**:组件会自动清理定时器,无需手动处理 3. **时区问题**:确保 `createTime` 格式正确,建议使用 ISO 格式 4. **过期处理**:`onExpired` 回调只在实时模式下触发 ## 样式定制 可以通过 CSS 变量或覆盖样式类来自定义外观: ```scss .custom-countdown { .payment-countdown-badge { background: linear-gradient(135deg, #your-color-1, #your-color-2); border-radius: 8px; &.urgent { animation: customPulse 1.5s infinite; } } } @keyframes customPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.8; } } ```