修改促销、优化页面布局

Change-Id: Iae813b5b6557efa7059fe6d94bc32e96c984e4ea
diff --git a/src/pages/UserCenter/UserLevelExperience.jsx b/src/pages/UserCenter/UserLevelExperience.jsx
index 60dcd55..81135c1 100644
--- a/src/pages/UserCenter/UserLevelExperience.jsx
+++ b/src/pages/UserCenter/UserLevelExperience.jsx
@@ -7,6 +7,9 @@
 //   const [isLoading, setIsLoading] = useState(false);
 //   const [upgradeResult, setUpgradeResult] = useState(null);
 //   const [hasCheckedIn, setHasCheckedIn] = useState(false);
+//   const [isUpgrading, setIsUpgrading] = useState(false);
+//   const [lastUpgradeTime, setLastUpgradeTime] = useState(null);
+//   const [justUpgraded, setJustUpgraded] = useState(false); // 新增
 
 //   useEffect(() => {
 //     if (!userId) return;
@@ -14,14 +17,16 @@
 //   }, [userId]);
 
 //   useEffect(() => {
-//     // 自动触发升级判断
 //     if (
 //       experienceInfo &&
-//       experienceInfo.current_experience >= experienceInfo.next_level_experience
+//       experienceInfo.current_experience >= experienceInfo.next_level_experience &&
+//       !isUpgrading &&
+//       !justUpgraded &&
+//       (!lastUpgradeTime || Date.now() - lastUpgradeTime > 2000)
 //     ) {
 //       checkUpgrade();
 //     }
-//   }, [experienceInfo]);
+//   }, [experienceInfo, isUpgrading, lastUpgradeTime, justUpgraded]);
 
 //   const fetchAllLevelData = async () => {
 //     try {
@@ -81,8 +86,11 @@
 //   };
 
 //   const checkUpgrade = async () => {
+//     if (isUpgrading) return;
+
 //     try {
 //       setIsLoading(true);
+//       setIsUpgrading(true);
 //       setError(null);
 
 //       const { data } = await axios.get('/echo/level/upgrade-check', {
@@ -90,46 +98,66 @@
 //       });
 
 //       if (data.can_upgrade) {
-//         await performUpgrade(); // 自动触发
+//         if (window.confirm('您已满足升级条件,是否要升级?')) {
+//           await performUpgrade();
+//         }
+//       } else {
+//         if (data.is_max_level) {
+//           alert('您已达到最高等级!');
+//         } else {
+//           alert(`还不能升级,还需要${data.next_level_experience - data.current_experience}点经验值`);
+//         }
 //       }
 //     } catch (err) {
 //       console.error('检查升级失败:', err);
 //       setError(err.response?.data?.message || '检查升级失败');
 //     } finally {
 //       setIsLoading(false);
+//       setIsUpgrading(false);
 //     }
 //   };
 
+//   const performUpgrade = async () => {
+//     try {
+//       setIsUpgrading(true);
+//       setIsLoading(true);
+//       setError(null);
 
-// const performUpgrade = async () => {
-//   try {
-//     setIsLoading(true);
-//     setError(null);
+//       const { data } = await axios.post('/echo/level/upgrades', {
+//         user_id: userId,
+//         can_upgrade: true,
+//       });
 
-//     const { data } = await axios.post('/echo/level/upgrades', {
-//       user_id: userId,
-//       can_upgrade: true,
-//     });
+//       console.log('升级响应数据:', data);
 
-//     console.log('升级响应数据:', data); // 保留调试日志
+//       if (data.status === 'success') {
+//         setExperienceInfo((prev) => ({
+//           ...prev,
+//           current_level: data.new_level,
+//           current_experience: data.current_experience || 0,
+//           next_level_experience: data.next_level_experience || prev.next_level_experience * 2,
+//         }));
 
-//     setExperienceInfo((prev) => ({
-//       ...prev,
-//       current_level: data.new_level, // 修复:使用正确的字段名
-//       current_experience: 0,
-//       next_level_experience: prev.next_level_experience * 2,
-//     }));
+//         setUpgradeResult(data);
+//         setLastUpgradeTime(Date.now());
+//         setJustUpgraded(true); // 标记为刚升级过
+//         setTimeout(() => setJustUpgraded(false), 3000); // 3 秒冷却期
+//         alert(`恭喜!您已升级到等级 ${data.new_level}!`);
 
-//     setUpgradeResult(data);
-//     alert(`恭喜!您已升级到等级 ${data.new_level}!`); // 修复:使用正确的字段名
-//   } catch (err) {
-//     console.error('升级失败:', err);
-//     setError(err.response?.data?.message || '升级失败');
-//   } finally {
-//     setIsLoading(false);
-//   }
-// };
-
+//         // 再次拉取最新经验数据,避免经验值仍然满足升级条件
+//         await fetchAllLevelData();
+//       } else {
+//         throw new Error(data.message || '升级失败');
+//       }
+//     } catch (err) {
+//       console.error('升级失败:', err);
+//       setError(err.message || '升级失败');
+//       alert(err.message || '升级失败,请稍后再试');
+//     } finally {
+//       setIsLoading(false);
+//       setIsUpgrading(false);
+//     }
+//   };
 
 //   if (error) return <p className="error">{error}</p>;
 //   if (isLoading) return <p>加载中...</p>;
@@ -141,11 +169,11 @@
 //     (current_experience / (next_level_experience || 1)) * 100
 //   ).toFixed(2);
 
-//   const expToNextLevel = Math.max(0, next_level_experience - current_experience); // 防止负数
+//   const expToNextLevel = Math.max(0, next_level_experience - current_experience);
 
 //   return (
 //     <div className="level-experience-section">
-//       {/* <h3>等级与经验</h3> */}
+//       <h3>等级与经验</h3>
 //       <p><strong>当前等级:</strong>{current_level || '未知'}</p>
 //       <p><strong>当前经验:</strong>{current_experience}</p>
 //       <p><strong>距离下一等级还需:</strong>{expToNextLevel} 经验值</p>
@@ -155,14 +183,17 @@
 //       </div>
 //       <p className="exp-progress-text">{progressPercent}%</p>
 
-
 //       {upgradeResult && (
 //         <div className="upgrade-success">
-//             {/* 使用与状态一致的字段名 */}
-//             <p>恭喜!您已成功升级到等级 {upgradeResult.new_level}!</p>
+//           <p>恭喜!您已成功升级到等级 {upgradeResult.new_level}!</p>
 //         </div>
-//         )}
-      
+//       )}
+
+//       {error && (
+//         <div className="upgrade-error">
+//           <p>{error}</p>
+//         </div>
+//       )}
 
 //       <div className="level-actions">
 //         <button onClick={() => updateExperience('check-in', 15)} disabled={hasCheckedIn}>
@@ -170,7 +201,9 @@
 //         </button>
 //         <button onClick={() => updateExperience('task', 30)}>完成任务 (+30经验)</button>
 //         <button onClick={() => updateExperience('upload', 50)}>上传种子 (+50经验)</button>
-//         {/* <button onClick={checkUpgrade}>检查升级</button> */}
+//         <button onClick={checkUpgrade} disabled={isUpgrading}>
+//           {isUpgrading ? '升级中...' : '检查升级'}
+//         </button>
 //       </div>
 //     </div>
 //   );
@@ -178,198 +211,3 @@
 
 // export default UserLevelExperience;
 
-import React, { useState, useEffect } from 'react';
-import axios from 'axios';
-
-const UserLevelExperience = ({ userId }) => {
-  const [experienceInfo, setExperienceInfo] = useState(null);
-  const [error, setError] = useState(null);
-  const [isLoading, setIsLoading] = useState(false);
-  const [upgradeResult, setUpgradeResult] = useState(null);
-  const [hasCheckedIn, setHasCheckedIn] = useState(false);
-
-  useEffect(() => {
-    if (!userId) return;
-    fetchAllLevelData();
-  }, [userId]);
-
-  useEffect(() => {
-    // 自动触发升级判断
-    if (
-      experienceInfo &&
-      experienceInfo.current_experience >= experienceInfo.next_level_experience
-    ) {
-      checkUpgrade();
-    }
-  }, [experienceInfo]);
-
-  const fetchAllLevelData = async () => {
-    try {
-      setIsLoading(true);
-      setError(null);
-
-      const { data } = await axios.get('/echo/level/getExperience', {
-        params: { user_id: userId },
-      });
-
-      const normalizedData = {
-        ...data,
-        current_level: data.current_level || data.level,
-      };
-
-      setExperienceInfo(normalizedData);
-
-      const today = new Date().toDateString();
-      const lastCheckIn = localStorage.getItem('lastCheckIn');
-      setHasCheckedIn(lastCheckIn === today);
-    } catch (err) {
-      console.error('经验信息获取失败:', err);
-      setError('获取经验信息失败');
-    } finally {
-      setIsLoading(false);
-    }
-  };
-
-  const updateExperience = async (source, amount = 10) => {
-    try {
-      setIsLoading(true);
-      setError(null);
-
-      const { data } = await axios.post('/echo/level/updateExperience', {
-        user_id: userId,
-        experience: amount,
-        source: source,
-      });
-
-      setExperienceInfo((prev) => ({
-        ...prev,
-        current_experience: data.current_experience,
-      }));
-
-      alert(`获得${amount}点经验值!来源:${source}`);
-
-      if (source === 'check-in') {
-        localStorage.setItem('lastCheckIn', new Date().toDateString());
-        setHasCheckedIn(true);
-      }
-    } catch (err) {
-      console.error('更新经验失败:', err);
-      setError(err.response?.data?.message || '更新经验失败');
-    } finally {
-      setIsLoading(false);
-    }
-  };
-
-  const checkUpgrade = async () => {
-    try {
-      setIsLoading(true);
-      setError(null);
-
-      const { data } = await axios.get('/echo/level/upgrade-check', {
-        params: { user_id: userId },
-      });
-
-      if (data.can_upgrade) {
-        if (window.confirm('您已满足升级条件,是否要升级?')) {
-          await performUpgrade();
-        }
-      } else {
-        // 区分是经验不足还是已达最高等级
-        if (data.is_max_level) {
-          alert('您已达到最高等级!');
-        } else {
-          alert(`还不能升级,还需要${data.next_level_experience - data.current_experience}点经验值`);
-        }
-      }
-    } catch (err) {
-      console.error('检查升级失败:', err);
-      setError(err.response?.data?.message || '检查升级失败');
-    } finally {
-      setIsLoading(false);
-    }
-  };
-
-  const performUpgrade = async () => {
-    try {
-      setIsLoading(true);
-      setError(null);
-
-      const { data } = await axios.post('/echo/level/upgrades', {
-        user_id: userId,
-        can_upgrade: true,
-      });
-
-      console.log('升级响应数据:', data);
-
-      // 正确处理升级结果
-      if (data.status === 'success') {
-        setExperienceInfo((prev) => ({
-          ...prev,
-          current_level: data.new_level,
-          current_experience: 0,
-          next_level_experience: prev.next_level_experience * 2,
-        }));
-
-        setUpgradeResult(data);
-        alert(`恭喜!您已升级到等级 ${data.new_level}!`);
-      } else {
-        throw new Error(data.message || '升级失败');
-      }
-    } catch (err) {
-      console.error('升级失败:', err);
-      setError(err.message || '升级失败');
-      alert(err.message || '升级失败,请稍后再试');
-    } finally {
-      setIsLoading(false);
-    }
-  };
-
-  if (error) return <p className="error">{error}</p>;
-  if (isLoading) return <p>加载中...</p>;
-  if (!experienceInfo) return <p>加载经验信息中...</p>;
-
-  const { current_experience, next_level_experience, current_level } = experienceInfo;
-  const progressPercent = Math.min(
-    100,
-    (current_experience / (next_level_experience || 1)) * 100
-  ).toFixed(2);
-
-  const expToNextLevel = Math.max(0, next_level_experience - current_experience);
-
-  return (
-    <div className="level-experience-section">
-      <h3>等级与经验</h3>
-      <p><strong>当前等级:</strong>{current_level || '未知'}</p>
-      <p><strong>当前经验:</strong>{current_experience}</p>
-      <p><strong>距离下一等级还需:</strong>{expToNextLevel} 经验值</p>
-
-      <div className="exp-bar-wrapper">
-        <div className="exp-bar" style={{ width: `${progressPercent}%` }} />
-      </div>
-      <p className="exp-progress-text">{progressPercent}%</p>
-
-      {upgradeResult && (
-        <div className="upgrade-success">
-          <p>恭喜!您已成功升级到等级 {upgradeResult.new_level}!</p>
-        </div>
-      )}
-
-      {error && (
-        <div className="upgrade-error">
-          <p>{error}</p>
-        </div>
-      )}
-
-      <div className="level-actions">
-        <button onClick={() => updateExperience('check-in', 15)} disabled={hasCheckedIn}>
-          {hasCheckedIn ? '今日已签到' : '每日签到 (+15经验)'}
-        </button>
-        <button onClick={() => updateExperience('task', 30)}>完成任务 (+30经验)</button>
-        <button onClick={() => updateExperience('upload', 50)}>上传种子 (+50经验)</button>
-        <button onClick={checkUpgrade}>检查升级</button>
-      </div>
-    </div>
-  );
-};
-
-export default UserLevelExperience;