blob: ff01ef33b28ace7d93545b610caca06676d8f27d [file] [log] [blame]
Krishya6bf199c2025-06-06 21:14:23 +08001// import React, { useState, useEffect } from 'react';
2// import './PromotionsPage.css';
Krishya57cc17b2025-05-26 16:43:34 +08003
Krishya2283d882025-05-27 22:25:19 +08004
Krishya6bf199c2025-06-06 21:14:23 +08005// function PromotionsPage() {
6// const [promotions, setPromotions] = useState([]);
7// const [currentPromotion, setCurrentPromotion] = useState(null);
8// const [isAdmin, setIsAdmin] = useState(false);
9// const [isLoading, setIsLoading] = useState(false);
10// const [error, setError] = useState(null);
11// const [formData, setFormData] = useState({
12// name: '',
13// uploadCoeff: 1,
14// downloadCoeff: 1,
15// timeRange: 0,
16// criteria: 1,
17// pStartTime: '',
18// pEndTime: ''
19// });
20// const [isCreating, setIsCreating] = useState(false);
21// const [currentPage, setCurrentPage] = useState(1);
22// const [perPage] = useState(10);
23// const [totalPromotions, setTotalPromotions] = useState(0);
Krishya57cc17b2025-05-26 16:43:34 +080024
Krishya6bf199c2025-06-06 21:14:23 +080025// const getAuthHeaders = () => {
26// const token = localStorage.getItem('token');
27// return {
28// 'Authorization': token ? `Bearer ${token}` : '',
29// 'Content-Type': 'application/json'
30// };
31// };
Krishya57cc17b2025-05-26 16:43:34 +080032
Krishya6bf199c2025-06-06 21:14:23 +080033// const fetchPromotions = async (page = 1) => {
34// setIsLoading(true);
35// try {
36// const response = await fetch(`/promotions/list?page=${page}&per_page=${perPage}`, {
37// headers: getAuthHeaders()
38// });
Krishya57cc17b2025-05-26 16:43:34 +080039
Krishya6bf199c2025-06-06 21:14:23 +080040// if (!response.ok) {
41// throw new Error('获取促销活动失败');
42// }
Krishya57cc17b2025-05-26 16:43:34 +080043
Krishya6bf199c2025-06-06 21:14:23 +080044// const data = await response.json();
45// if (data.code === 0 && data.result) {
46// setPromotions(data.rows || []);
47// setTotalPromotions(data.total || 0);
48// } else {
49// throw new Error(data.msg || '获取促销活动失败');
50// }
51// } catch (err) {
52// console.error('获取促销活动错误:', err);
53// setError(err.message);
54// } finally {
55// setIsLoading(false);
56// }
57// };
Krishya57cc17b2025-05-26 16:43:34 +080058
Krishya6bf199c2025-06-06 21:14:23 +080059// const fetchPromotionDetails = async (promoId) => {
60// setIsLoading(true);
61// try {
62// const response = await fetch(`/promotions/${promoId}`, {
63// headers: getAuthHeaders()
64// });
Krishya57cc17b2025-05-26 16:43:34 +080065
Krishya6bf199c2025-06-06 21:14:23 +080066// if (!response.ok) {
67// throw new Error('获取促销详情失败');
68// }
Krishya57cc17b2025-05-26 16:43:34 +080069
Krishya6bf199c2025-06-06 21:14:23 +080070// const data = await response.json();
71// if (data.code === 0 && data.result) {
72// setCurrentPromotion(data.rows);
73// } else {
74// throw new Error(data.msg || '获取促销详情失败');
75// }
76// } catch (err) {
77// console.error('获取促销详情错误:', err);
78// setError(err.message);
79// } finally {
80// setIsLoading(false);
81// }
82// };
Krishya57cc17b2025-05-26 16:43:34 +080083
Krishya6bf199c2025-06-06 21:14:23 +080084// const createPromotion = async () => {
85// if (!formData.name || !formData.pStartTime || !formData.pEndTime) {
86// alert('请填写完整活动信息');
87// return;
88// }
Krishya57cc17b2025-05-26 16:43:34 +080089
Krishya6bf199c2025-06-06 21:14:23 +080090// if (new Date(formData.pStartTime) >= new Date(formData.pEndTime)) {
91// alert('活动时间设置不正确,请重新设定');
92// return;
93// }
Krishya57cc17b2025-05-26 16:43:34 +080094
Krishya6bf199c2025-06-06 21:14:23 +080095// setIsLoading(true);
96// try {
97// const response = await fetch('/promotions/add', {
98// method: 'POST',
99// headers: getAuthHeaders(),
100// body: JSON.stringify(formData)
101// });
Krishya57cc17b2025-05-26 16:43:34 +0800102
Krishya6bf199c2025-06-06 21:14:23 +0800103// if (!response.ok) {
104// throw new Error('创建促销活动失败');
105// }
Krishya57cc17b2025-05-26 16:43:34 +0800106
Krishya6bf199c2025-06-06 21:14:23 +0800107// const data = await response.json();
108// if (data.code === 0 && data.result) {
109// alert(`活动创建成功!活动ID: ${data.msg}`);
110// setIsCreating(false);
111// setFormData({
112// name: '',
113// uploadCoeff: 1,
114// downloadCoeff: 1,
115// timeRange: 0,
116// criteria: 1,
117// pStartTime: '',
118// pEndTime: ''
119// });
120// fetchPromotions();
121// } else {
122// throw new Error(data.msg || '创建促销活动失败');
123// }
124// } catch (err) {
125// console.error('创建促销活动错误:', err);
126// alert(err.message);
127// } finally {
128// setIsLoading(false);
129// }
130// };
Krishya57cc17b2025-05-26 16:43:34 +0800131
Krishya6bf199c2025-06-06 21:14:23 +0800132// const deletePromotion = async (promoId) => {
133// if (!window.confirm('确定要删除这个促销活动吗?')) {
134// return;
135// }
Krishya57cc17b2025-05-26 16:43:34 +0800136
Krishya6bf199c2025-06-06 21:14:23 +0800137// setIsLoading(true);
138// try {
139// const response = await fetch(`/promotions/delete/${promoId}`, {
140// method: 'DELETE',
141// headers: getAuthHeaders()
142// });
Krishya57cc17b2025-05-26 16:43:34 +0800143
Krishya6bf199c2025-06-06 21:14:23 +0800144// if (!response.ok) {
145// throw new Error('删除促销活动失败');
146// }
Krishya57cc17b2025-05-26 16:43:34 +0800147
Krishya6bf199c2025-06-06 21:14:23 +0800148// const data = await response.json();
149// if (data.code === 0 && data.result) {
150// alert('促销活动删除成功');
151// fetchPromotions();
152// if (currentPromotion && currentPromotion.promoId === promoId) {
153// setCurrentPromotion(null);
154// }
155// } else {
156// throw new Error(data.msg || '删除促销活动失败');
157// }
158// } catch (err) {
159// console.error('删除促销活动错误:', err);
160// alert(err.message);
161// } finally {
162// setIsLoading(false);
163// }
164// };
Krishya57cc17b2025-05-26 16:43:34 +0800165
Krishya6bf199c2025-06-06 21:14:23 +0800166// const checkAdminStatus = () => {
167// const role = localStorage.getItem('role');
168// setIsAdmin(role === 'admin');
169// };
Krishya57cc17b2025-05-26 16:43:34 +0800170
Krishya6bf199c2025-06-06 21:14:23 +0800171// useEffect(() => {
172// checkAdminStatus();
173// fetchPromotions();
174// }, []);
Krishya57cc17b2025-05-26 16:43:34 +0800175
Krishya6bf199c2025-06-06 21:14:23 +0800176// const handleInputChange = (e) => {
177// const { name, value } = e.target;
178// setFormData(prev => ({
179// ...prev,
180// [name]: name === 'uploadCoeff' || name === 'downloadCoeff' || name === 'timeRange' || name === 'criteria'
181// ? parseFloat(value)
182// : value
183// }));
184// };
Krishya57cc17b2025-05-26 16:43:34 +0800185
Krishya6bf199c2025-06-06 21:14:23 +0800186// const handlePageChange = (newPage) => {
187// setCurrentPage(newPage);
188// fetchPromotions(newPage);
189// };
Krishya57cc17b2025-05-26 16:43:34 +0800190
Krishya6bf199c2025-06-06 21:14:23 +0800191// const getPromotionType = (promo) => {
192// if (promo.downloadCoeff === 0 && promo.uploadCoeff > 1) {
193// return '免费';
194// } else if (promo.downloadCoeff < 1 && promo.uploadCoeff > 1) {
195// return '折扣+上传奖励';
196// } else if (promo.downloadCoeff < 1) {
197// return '折扣';
198// } else if (promo.uploadCoeff > 1) {
199// return '上传奖励';
200// }
201// return '普通';
202// };
Krishya57cc17b2025-05-26 16:43:34 +0800203
Krishya6bf199c2025-06-06 21:14:23 +0800204// return (
205// <div className="promotions-page">
206// <div className="promotions-container">
207// <h1>促销活动</h1>
Krishya57cc17b2025-05-26 16:43:34 +0800208
Krishya6bf199c2025-06-06 21:14:23 +0800209// {isAdmin && (
210// <div className="admin-actions">
211// <button
212// className="create-button"
213// onClick={() => setIsCreating(!isCreating)}
214// >
215// {isCreating ? '取消创建' : '创建新活动'}
216// </button>
217// </div>
218// )}
Krishya57cc17b2025-05-26 16:43:34 +0800219
Krishya6bf199c2025-06-06 21:14:23 +0800220// {isCreating && isAdmin && (
221// <div className="create-promotion-form">
222// <h2>创建新促销活动</h2>
223// <div className="form-group">
224// <label>活动名称</label>
225// <input
226// type="text"
227// name="name"
228// value={formData.name}
229// onChange={handleInputChange}
230// placeholder="例如: 春节特惠"
231// />
232// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800233
Krishya6bf199c2025-06-06 21:14:23 +0800234// <div className="form-row">
235// <div className="form-group">
236// <label>上传量系数</label>
237// <input
238// type="number"
239// name="uploadCoeff"
240// min="0"
241// step="0.1"
242// value={formData.uploadCoeff}
243// onChange={handleInputChange}
244// />
245// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800246
Krishya6bf199c2025-06-06 21:14:23 +0800247// <div className="form-group">
248// <label>下载量系数</label>
249// <input
250// type="number"
251// name="downloadCoeff"
252// min="0"
253// step="0.1"
254// value={formData.downloadCoeff}
255// onChange={handleInputChange}
256// />
257// </div>
258// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800259
Krishya6bf199c2025-06-06 21:14:23 +0800260// <div className="form-row">
261// <div className="form-group">
262// <label>资源时间范围</label>
263// <select
264// name="timeRange"
265// value={formData.timeRange}
266// onChange={handleInputChange}
267// >
268// <option value="0">全站资源</option>
269// <option value="1">当天上传</option>
270// <option value="2">最近两天</option>
271// <option value="7">最近一周</option>
272// <option value="30">最近一个月</option>
273// </select>
274// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800275
Krishya6bf199c2025-06-06 21:14:23 +0800276// <div className="form-group">
277// <label>最低用户等级</label>
278// <input
279// type="number"
280// name="criteria"
281// min="1"
282// value={formData.criteria}
283// onChange={handleInputChange}
284// />
285// </div>
286// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800287
Krishya6bf199c2025-06-06 21:14:23 +0800288// <div className="form-row">
289// <div className="form-group">
290// <label>开始时间</label>
291// <input
292// type="datetime-local"
293// name="pStartTime"
294// value={formData.pStartTime}
295// onChange={handleInputChange}
296// />
297// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800298
Krishya6bf199c2025-06-06 21:14:23 +0800299// <div className="form-group">
300// <label>结束时间</label>
301// <input
302// type="datetime-local"
303// name="pEndTime"
304// value={formData.pEndTime}
305// onChange={handleInputChange}
306// />
307// </div>
308// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800309
Krishya6bf199c2025-06-06 21:14:23 +0800310// <button
311// className="submit-button"
312// onClick={createPromotion}
313// disabled={isLoading}
314// >
315// {isLoading ? '创建中...' : '提交创建'}
316// </button>
317// </div>
318// )}
Krishya57cc17b2025-05-26 16:43:34 +0800319
Krishya6bf199c2025-06-06 21:14:23 +0800320// {error && <div className="error-message">{error}</div>}
Krishya57cc17b2025-05-26 16:43:34 +0800321
Krishya6bf199c2025-06-06 21:14:23 +0800322// <div className="promotions-grid">
323// {/* 促销活动列表 */}
324// <div className="promotions-list">
325// <h2>当前促销活动</h2>
326// {isLoading && promotions.length === 0 ? (
327// <div className="loading">加载中...</div>
328// ) : promotions.length === 0 ? (
329// <div className="no-promotions">暂无促销活动</div>
330// ) : (
331// <div className="promotion-items">
332// {promotions.map(promo => (
333// <div
334// key={promo.promoId}
335// className={`promotion-item ${currentPromotion && currentPromotion.promoId === promo.promoId ? 'active' : ''}`}
336// onClick={() => fetchPromotionDetails(promo.promoId)}
337// >
338// <div className="promotion-header">
339// <h3>{promo.name}</h3>
340// <span className="promotion-type">{getPromotionType(promo)}</span>
341// </div>
342// <div className="promotion-dates">
343// {new Date(promo.pStartTime).toLocaleString()} - {new Date(promo.pEndTime).toLocaleString()}
344// </div>
345// <div className="promotion-coeffs">
346// <span>上传: {promo.uploadCoeff}x</span>
347// <span>下载: {promo.downloadCoeff}x</span>
348// </div>
349// {isAdmin && (
350// <button
351// className="delete-button"
352// onClick={(e) => {
353// e.stopPropagation();
354// deletePromotion(promo.promoId);
355// }}
356// disabled={isLoading}
357// >
358// 删除
359// </button>
360// )}
361// </div>
362// ))}
363// </div>
364// )}
Krishya57cc17b2025-05-26 16:43:34 +0800365
Krishya6bf199c2025-06-06 21:14:23 +0800366// {totalPromotions > perPage && (
367// <div className="pagination">
368// <button
369// disabled={currentPage === 1}
370// onClick={() => handlePageChange(currentPage - 1)}
371// >
372// 上一页
373// </button>
374// <span>第 {currentPage} 页</span>
375// <button
376// disabled={currentPage * perPage >= totalPromotions}
377// onClick={() => handlePageChange(currentPage + 1)}
378// >
379// 下一页
380// </button>
381// </div>
382// )}
383// </div>
Krishya57cc17b2025-05-26 16:43:34 +0800384
Krishya6bf199c2025-06-06 21:14:23 +0800385// {/* 促销活动详情 */}
386// <div className="promotion-details">
387// {currentPromotion ? (
388// <>
389// <h2>{currentPromotion.name}</h2>
390// <div className="detail-item">
391// <label>活动ID:</label>
392// <span>{currentPromotion.promoId}</span>
393// </div>
394// <div className="detail-item">
395// <label>活动时间:</label>
396// <span>
397// {new Date(currentPromotion.pStartTime).toLocaleString()} - {new Date(currentPromotion.pEndTime).toLocaleString()}
398// </span>
399// </div>
400// <div className="detail-item">
401// <label>促销类型:</label>
402// <span>{getPromotionType(currentPromotion)}</span>
403// </div>
404// <div className="detail-item">
405// <label>上传量系数:</label>
406// <span>{currentPromotion.uploadCoeff}x</span>
407// </div>
408// <div className="detail-item">
409// <label>下载量系数:</label>
410// <span>{currentPromotion.downloadCoeff}x</span>
411// </div>
412// <div className="detail-item">
413// <label>适用资源:</label>
414// <span>
415// {currentPromotion.timeRange === 0
416// ? '全站资源'
417// : `最近${currentPromotion.timeRange}天内上传的资源`}
418// </span>
419// </div>
420// <div className="detail-item">
421// <label>参与条件:</label>
422// <span>用户等级 ≥ {currentPromotion.criteria}</span>
423// </div>
424// </>
425// ) : (
426// <div className="no-selection">请从左侧选择一个促销活动查看详情</div>
427// )}
428// </div>
429// </div>
430// </div>
431// </div>
432// );
433// }
Krishya57cc17b2025-05-26 16:43:34 +0800434
Krishya6bf199c2025-06-06 21:14:23 +0800435// export default PromotionsPage;