修改促销、优化页面布局
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;