Krishya | dbfadaa | 2025-06-09 20:33:15 +0800 | [diff] [blame^] | 1 | import React, { useState } from 'react'; |
| 2 | import './PromotionCarousel.css'; |
| 3 | |
| 4 | const PromotionCarousel = ({ |
| 5 | promotions, |
| 6 | isAdmin, |
| 7 | openCreateDialog, |
| 8 | openCategoryDialog, |
| 9 | fetchColdTorrents, |
| 10 | handleDeletePromotion, |
| 11 | fetchPromotionDetail |
| 12 | }) => { |
| 13 | // 1. 新增状态:跟踪当前轮播项的索引 |
| 14 | const [currentIndex, setCurrentIndex] = useState(0); |
| 15 | |
| 16 | // 2. 上一个/下一个轮播的逻辑 |
| 17 | const prevPromo = () => { |
| 18 | if (promotions.length === 0) return; |
| 19 | setCurrentIndex(prev => |
| 20 | prev === 0 ? promotions.length - 1 : prev - 1 |
| 21 | ); |
| 22 | }; |
| 23 | |
| 24 | const nextPromo = () => { |
| 25 | if (promotions.length === 0) return; |
| 26 | setCurrentIndex(prev => |
| 27 | prev === promotions.length - 1 ? 0 : prev + 1 |
| 28 | ); |
| 29 | }; |
| 30 | |
| 31 | // 3. 当前显示的促销项(从数组中取) |
| 32 | const currentPromo = promotions[currentIndex]; |
| 33 | |
| 34 | // 原有工具函数保持不变 |
| 35 | const formatDateTime = (dateTime) => { |
| 36 | if (!dateTime) return '未知'; |
| 37 | // dateTime [2025,1,3,12,10] |
| 38 | return new Date(...dateTime).toLocaleString(); |
| 39 | |
| 40 | }; |
| 41 | |
| 42 | // 修改为一个统一的处理函数,避免混淆 |
| 43 | const getUploadBonusDisplay = (promo) => { |
| 44 | if (!promo || typeof promo.discountPercentage !== 'number') return '无'; |
| 45 | const bonus = promo.discountPercentage; |
| 46 | return bonus > 0 ? `${(bonus * 100).toFixed(0)}%` : '无'; |
| 47 | }; |
| 48 | |
| 49 | const getDownloadDiscountDisplay = (promo) => { |
| 50 | if (!promo || typeof promo.discountPercentage !== 'number') return '无'; |
| 51 | const discount = promo.discountPercentage; |
| 52 | return discount < 0 ? `${Math.abs(discount * 100).toFixed(0)}%` : '无'; |
| 53 | }; |
| 54 | |
| 55 | |
| 56 | if (!Array.isArray(promotions) || promotions.length === 0 || !promotions[currentIndex]) { |
| 57 | return ( |
| 58 | <section className="carousel-section"> |
| 59 | <h2 style={{ marginLeft: '1.6rem' }}>当前促销活动</h2> |
| 60 | {isAdmin && ( |
| 61 | <div style={{ display: 'flex', gap: '0px', marginBottom: '10px' }}> |
| 62 | <button className="create-btn" onClick={openCreateDialog}> |
| 63 | +创建冷门资源促销 |
| 64 | </button> |
| 65 | <button className="create-btn" onClick={openCategoryDialog}> |
| 66 | +创建特定分类促销 |
| 67 | </button> |
| 68 | </div> |
| 69 | )} |
| 70 | <div className="empty-state">暂无促销活动</div> |
| 71 | </section> |
| 72 | ); |
| 73 | } |
| 74 | |
| 75 | |
| 76 | return ( |
| 77 | <section className="carousel-section"> |
| 78 | <h2 style={{ marginLeft: '1.6rem' }}>当前促销活动</h2> |
| 79 | |
| 80 | {isAdmin && ( |
| 81 | <div style={{ display: 'flex', gap: '0px', marginBottom: '10px' }}> |
| 82 | <button className="create-btn" onClick={openCreateDialog}> |
| 83 | +创建冷门资源促销 |
| 84 | </button> |
| 85 | <button className="create-btn" onClick={openCategoryDialog}> |
| 86 | +创建特定分类促销 |
| 87 | </button> |
| 88 | </div> |
| 89 | )} |
| 90 | |
| 91 | <div |
| 92 | className="carousel" |
| 93 | onMouseEnter={() => {}} |
| 94 | onMouseLeave={() => {}} |
| 95 | > |
| 96 | |
| 97 | <button className="arrow left" onClick={prevPromo}><</button> |
| 98 | <div className="slide"> |
| 99 | <div className='promotion-name'><strong>{currentPromo?.name ?? '未知'}</strong></div> |
| 100 | <div style={{ color: '#135c69' }}><strong>促销时间:</strong> |
| 101 | {currentPromo?.startTime && currentPromo?.endTime |
| 102 | ? `${formatDateTime(currentPromo.startTime)} ~ ${formatDateTime(currentPromo.endTime)}` |
| 103 | : '未知'} |
| 104 | </div> |
| 105 | <div style={{ color: '#135c69' }}><strong>上传奖励:</strong>{getUploadBonusDisplay(currentPromo)}</div> |
| 106 | <div style={{ color: '#135c69' }}><strong>下载折扣:</strong>{getDownloadDiscountDisplay(currentPromo)}</div> |
| 107 | {currentPromo?.description && ( |
| 108 | <div><strong>描述:</strong>{currentPromo.description}</div> |
| 109 | )} |
| 110 | |
| 111 | <div className="action-buttons" style={{ display: 'flex', gap: '10px' }}> |
| 112 | {isAdmin && ( |
| 113 | <button className="delete-btn" onClick={() => handleDeletePromotion(currentPromo.id)}> |
| 114 | 删除活动 |
| 115 | </button> |
| 116 | )} |
| 117 | <button |
| 118 | className="view-btn" |
| 119 | onClick={() => fetchPromotionDetail(currentPromo.id)} |
| 120 | aria-label={`查看${currentPromo.name}的详情`} |
| 121 | > |
| 122 | 查看详情 |
| 123 | </button> |
| 124 | </div> |
| 125 | </div> |
| 126 | <button className="arrow right" onClick={nextPromo}>></button> |
| 127 | |
| 128 | {/* 4. 新增:底部指示器 */} |
| 129 | <div className="carousel-indicators"> |
| 130 | {promotions.map((_, index) => ( |
| 131 | <div |
| 132 | key={index} |
| 133 | className={`indicator ${currentIndex === index ? 'active' : ''}`} |
| 134 | onClick={() => setCurrentIndex(index)} // 点击切换轮播项 |
| 135 | /> |
| 136 | ))} |
| 137 | </div> |
| 138 | </div> |
| 139 | </section> |
| 140 | ); |
| 141 | }; |
| 142 | |
| 143 | export default PromotionCarousel; |