blob: fd79cec0ae1939957ef2caad489254956dafc74c [file] [log] [blame]
Krishya2283d882025-05-27 22:25:19 +08001// import React, { useEffect, useState, useRef } from 'react';
2// import './Promotion.css';
3
4
5
6// const Promotion = () => {
7// const [promotions, setPromotions] = useState([]);
8// const [coldResources, setColdResources] = useState([]);
9// const [loading, setLoading] = useState(true);
10
11// // 轮播索引
12// const [promoIndex, setPromoIndex] = useState(0);
13// const [coldIndex, setColdIndex] = useState(0);
14
15// // 计时器引用,用于清理
16// const promoTimerRef = useRef(null);
17// const coldTimerRef = useRef(null);
18
19// useEffect(() => {
20// fetchData();
21// }, []);
22
23// // 自动轮播:促销活动
24// useEffect(() => {
25// if (promotions.length === 0) return;
26// // 清理旧的计时器
27// clearInterval(promoTimerRef.current);
28// promoTimerRef.current = setInterval(() => {
29// setPromoIndex(prev => (prev + 1) % promotions.length);
30// }, 5000);
31// return () => clearInterval(promoTimerRef.current);
32// }, [promotions]);
33
34// // 自动轮播:冷门资源
35// useEffect(() => {
36// if (coldResources.length === 0) return;
37// clearInterval(coldTimerRef.current);
38// coldTimerRef.current = setInterval(() => {
39// setColdIndex(prev => (prev + 1) % coldResources.length);
40// }, 5000);
41// return () => clearInterval(coldTimerRef.current);
42// }, [coldResources]);
43
44// const fetchData = async () => {
45// try {
46// const promoResponse = await fetch(`/echo/promotions/active`);
47// const promoData = await promoResponse.json();
48// setPromotions(promoData);
49
50// const coldResponse = await fetch(`/echo/resources/cold`);
51// const coldData = await coldResponse.json();
52// setColdResources(coldData);
53// } catch (error) {
54// console.error('获取数据失败:', error);
55// } finally {
56// setLoading(false);
57// }
58// };
59
60// if (loading) {
61// return <div className="promotion-container">加载中...</div>;
62// }
63
64// // 手动切换
65// const prevPromo = () => setPromoIndex((promoIndex - 1 + promotions.length) % promotions.length);
66// const nextPromo = () => setPromoIndex((promoIndex + 1) % promotions.length);
67// const prevCold = () => setColdIndex((coldIndex - 1 + coldResources.length) % coldResources.length);
68// const nextCold = () => setColdIndex((coldIndex + 1) % coldResources.length);
69
70// const currentPromo = promotions[promoIndex];
71// const currentCold = coldResources[coldIndex];
72
73// return (
74// <div className="promotion-container carousel-container">
75// {/* 促销活动轮播 */}
76// <section className="carousel-section">
77// <h2>当前促销活动</h2>
78// {promotions.length === 0 ? (
79// <div className="empty-state">暂无促销活动</div>
80// ) : (
81// <div
82// className="carousel"
83// onMouseEnter={() => clearInterval(promoTimerRef.current)}
84// onMouseLeave={() => {
85// promoTimerRef.current = setInterval(() => {
86// setPromoIndex(prev => (prev + 1) % promotions.length);
87// }, 3000);
88// }}
89// >
90// <button className="arrow left" onClick={prevPromo}>&lt;</button>
91// <div className="slide">
92// <div><strong>种子类型:</strong>{currentPromo.category}</div>
93// <div><strong>促销时间:</strong>
94// {new Date(currentPromo.promotion_start_time).toLocaleString()} ~{' '}
95// {new Date(currentPromo.promotion_end_time).toLocaleString()}
96// </div>
97// <div><strong>下载折扣:</strong>{currentPromo.download_discount ?? '无'}</div>
98// <div><strong>上传奖励:</strong>{currentPromo.upload_reward ?? '无'}</div>
99// {currentPromo.description && (
100// <div><strong>详细描述:</strong>{currentPromo.description}</div>
101// )}
102// </div>
103// <button className="arrow right" onClick={nextPromo}>&gt;</button>
104// </div>
105// )}
106// </section>
107
108// {/* 冷门资源轮播 */}
109// <section className="carousel-section">
110// <h2>冷门资源推荐</h2>
111// {coldResources.length === 0 ? (
112// <div className="empty-state">暂无冷门资源推荐</div>
113// ) : (
114// <div
115// className="carousel"
116// onMouseEnter={() => clearInterval(coldTimerRef.current)}
117// onMouseLeave={() => {
118// coldTimerRef.current = setInterval(() => {
119// setColdIndex(prev => (prev + 1) % coldResources.length);
120// }, 3000);
121// }}
122// >
123// <button className="arrow left" onClick={prevCold}>&lt;</button>
124// <div className="slide cold-slide">
125// <img src={currentCold.poster} alt={currentCold.title} className="resource-poster" />
126// <div className="resource-info">
127// <div><strong>标题:</strong>{currentCold.title}</div>
128// <div><strong>下载量:</strong>{currentCold.download_count} | <strong>种子数:</strong>{currentCold.seed_count}</div>
129// <div><strong>激励:</strong>
130// {currentCold.incentives?.download_exempt && <span className="incentive-badge">免下载量</span>}
131// {currentCold.incentives?.extra_seed_bonus && <span className="incentive-badge">做种加成</span>}
132// {!(currentCold.incentives?.download_exempt || currentCold.incentives?.extra_seed_bonus) && '无'}
133// </div>
134// </div>
135// </div>
136// <button className="arrow right" onClick={nextCold}>&gt;</button>
137// </div>
138// )}
139// </section>
140// </div>
141// );
142// };
143
144// export default Promotion;
145
Krishyaf1d0ea82025-05-03 17:01:58 +0800146import React, { useEffect, useState, useRef } from 'react';
147import './Promotion.css';
148
Krishyaf1d0ea82025-05-03 17:01:58 +0800149const Promotion = () => {
150 const [promotions, setPromotions] = useState([]);
151 const [coldResources, setColdResources] = useState([]);
152 const [loading, setLoading] = useState(true);
153
Krishyaf1d0ea82025-05-03 17:01:58 +0800154 const [promoIndex, setPromoIndex] = useState(0);
155 const [coldIndex, setColdIndex] = useState(0);
156
Krishyaf1d0ea82025-05-03 17:01:58 +0800157 const promoTimerRef = useRef(null);
158 const coldTimerRef = useRef(null);
159
160 useEffect(() => {
161 fetchData();
162 }, []);
163
Krishyaf1d0ea82025-05-03 17:01:58 +0800164 useEffect(() => {
165 if (promotions.length === 0) return;
Krishyaf1d0ea82025-05-03 17:01:58 +0800166 clearInterval(promoTimerRef.current);
167 promoTimerRef.current = setInterval(() => {
168 setPromoIndex(prev => (prev + 1) % promotions.length);
169 }, 5000);
170 return () => clearInterval(promoTimerRef.current);
171 }, [promotions]);
172
Krishyaf1d0ea82025-05-03 17:01:58 +0800173 useEffect(() => {
174 if (coldResources.length === 0) return;
175 clearInterval(coldTimerRef.current);
176 coldTimerRef.current = setInterval(() => {
177 setColdIndex(prev => (prev + 1) % coldResources.length);
178 }, 5000);
179 return () => clearInterval(coldTimerRef.current);
180 }, [coldResources]);
181
182 const fetchData = async () => {
183 try {
Krishya2283d882025-05-27 22:25:19 +0800184 const promoResponse = await fetch(`/echo/promotions/active`);
Krishyaf1d0ea82025-05-03 17:01:58 +0800185 const promoData = await promoResponse.json();
186 setPromotions(promoData);
187
Krishya2283d882025-05-27 22:25:19 +0800188 const coldResponse = await fetch(`/echo/resources/cold`);
Krishyaf1d0ea82025-05-03 17:01:58 +0800189 const coldData = await coldResponse.json();
190 setColdResources(coldData);
191 } catch (error) {
192 console.error('获取数据失败:', error);
193 } finally {
194 setLoading(false);
195 }
196 };
197
198 if (loading) {
199 return <div className="promotion-container">加载中...</div>;
200 }
201
Krishyaf1d0ea82025-05-03 17:01:58 +0800202 const prevPromo = () => setPromoIndex((promoIndex - 1 + promotions.length) % promotions.length);
203 const nextPromo = () => setPromoIndex((promoIndex + 1) % promotions.length);
204 const prevCold = () => setColdIndex((coldIndex - 1 + coldResources.length) % coldResources.length);
205 const nextCold = () => setColdIndex((coldIndex + 1) % coldResources.length);
206
207 const currentPromo = promotions[promoIndex];
208 const currentCold = coldResources[coldIndex];
209
210 return (
211 <div className="promotion-container carousel-container">
212 {/* 促销活动轮播 */}
213 <section className="carousel-section">
214 <h2>当前促销活动</h2>
Krishya2283d882025-05-27 22:25:19 +0800215 {promotions.length === 0 || !currentPromo ? (
Krishyaf1d0ea82025-05-03 17:01:58 +0800216 <div className="empty-state">暂无促销活动</div>
217 ) : (
218 <div
219 className="carousel"
220 onMouseEnter={() => clearInterval(promoTimerRef.current)}
221 onMouseLeave={() => {
222 promoTimerRef.current = setInterval(() => {
223 setPromoIndex(prev => (prev + 1) % promotions.length);
224 }, 3000);
225 }}
226 >
227 <button className="arrow left" onClick={prevPromo}>&lt;</button>
228 <div className="slide">
Krishya2283d882025-05-27 22:25:19 +0800229 <div><strong>种子类型:</strong>{currentPromo?.category ?? '未知'}</div>
Krishyaf1d0ea82025-05-03 17:01:58 +0800230 <div><strong>促销时间:</strong>
Krishya2283d882025-05-27 22:25:19 +0800231 {currentPromo?.promotion_start_time && currentPromo?.promotion_end_time
232 ? `${new Date(currentPromo.promotion_start_time).toLocaleString()} ~ ${new Date(currentPromo.promotion_end_time).toLocaleString()}`
233 : '未知'}
Krishyaf1d0ea82025-05-03 17:01:58 +0800234 </div>
Krishya2283d882025-05-27 22:25:19 +0800235 <div><strong>下载折扣:</strong>{currentPromo?.download_discount ?? '无'}</div>
236 <div><strong>上传奖励:</strong>{currentPromo?.upload_reward ?? '无'}</div>
237 {currentPromo?.description && (
Krishyaf1d0ea82025-05-03 17:01:58 +0800238 <div><strong>详细描述:</strong>{currentPromo.description}</div>
239 )}
240 </div>
241 <button className="arrow right" onClick={nextPromo}>&gt;</button>
242 </div>
243 )}
244 </section>
245
246 {/* 冷门资源轮播 */}
247 <section className="carousel-section">
248 <h2>冷门资源推荐</h2>
Krishya2283d882025-05-27 22:25:19 +0800249 {coldResources.length === 0 || !currentCold ? (
Krishyaf1d0ea82025-05-03 17:01:58 +0800250 <div className="empty-state">暂无冷门资源推荐</div>
251 ) : (
252 <div
253 className="carousel"
254 onMouseEnter={() => clearInterval(coldTimerRef.current)}
255 onMouseLeave={() => {
256 coldTimerRef.current = setInterval(() => {
257 setColdIndex(prev => (prev + 1) % coldResources.length);
258 }, 3000);
259 }}
260 >
261 <button className="arrow left" onClick={prevCold}>&lt;</button>
262 <div className="slide cold-slide">
263 <img src={currentCold.poster} alt={currentCold.title} className="resource-poster" />
264 <div className="resource-info">
265 <div><strong>标题:</strong>{currentCold.title}</div>
Krishya2283d882025-05-27 22:25:19 +0800266 <div><strong>下载量:</strong>{currentCold.download_count ?? 0} | <strong>种子数:</strong>{currentCold.seed_count ?? 0}</div>
Krishyaf1d0ea82025-05-03 17:01:58 +0800267 <div><strong>激励:</strong>
268 {currentCold.incentives?.download_exempt && <span className="incentive-badge">免下载量</span>}
269 {currentCold.incentives?.extra_seed_bonus && <span className="incentive-badge">做种加成</span>}
Krishya2283d882025-05-27 22:25:19 +0800270 {!currentCold.incentives?.download_exempt && !currentCold.incentives?.extra_seed_bonus && '无'}
Krishyaf1d0ea82025-05-03 17:01:58 +0800271 </div>
272 </div>
273 </div>
274 <button className="arrow right" onClick={nextCold}>&gt;</button>
275 </div>
276 )}
277 </section>
278 </div>
279 );
280};
281
282export default Promotion;
Krishya2283d882025-05-27 22:25:19 +0800283