import React, { useState, useEffect } from 'react'; | |
import { useNavigate, useLocation } from 'react-router-dom'; | |
import { generateInviteCode, getUserInviteCodes, exchangeUpload, getUserInfo } from '../../api/personal'; | |
import './personalSubpage.css'; | |
const Exchange = () => { | |
const navigate = useNavigate(); | |
const location = useLocation(); | |
const [inviteCodes, setInviteCodes] = useState([]); | |
const [userInfo, setUserInfo] = useState(null); | |
const [magicPoints, setMagicPoints] = useState('0'); | |
const [loading, setLoading] = useState(false); | |
const [error, setError] = useState(null); | |
// 获取用户信息和邀请码列表 | |
useEffect(() => { | |
const fetchData = async () => { | |
try { | |
setLoading(true); | |
const [userData, codes] = await Promise.all([ | |
getUserInfo(), | |
getUserInviteCodes() | |
]); | |
setUserInfo(userData); | |
setInviteCodes(codes); | |
} catch (err) { | |
setError(err.message); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
fetchData(); | |
}, []); | |
// 生成邀请码 | |
const handleGenerateInviteCode = async () => { | |
try { | |
setLoading(true); | |
const newCode = await generateInviteCode(); | |
setInviteCodes([...inviteCodes, newCode]); | |
// 刷新用户信息 | |
const updatedUser = await getUserInfo(); | |
setUserInfo(updatedUser); | |
} catch (err) { | |
setError(err.message); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
const handleExchangeUpload = async () => { | |
const points = Number(magicPoints); | |
if (!points || points <= 0) { | |
setError('请输入有效的魔力值'); | |
return; | |
} | |
try { | |
setLoading(true); | |
await exchangeUpload(points); | |
// 刷新用户信息 | |
const updatedUser = await getUserInfo(); | |
setUserInfo(updatedUser); | |
setMagicPoints('0'); | |
setError(null); | |
} catch (err) { | |
setError(err.message); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
const handleBack = () => { | |
// 返回个人中心,并携带来源标记 | |
navigate('/personal', { | |
state: { | |
fromSubpage: true, // 标记来自子页面 | |
dashboardTab: location.state?.dashboardTab // 保留Dashboard的标签页状态 | |
}, | |
replace: true // 替换当前历史记录 | |
}); | |
}; | |
if (loading) { | |
return <div className="subpage-container">加载中...</div>; | |
} | |
if (error) { | |
return ( | |
<div className="subpage-container"> | |
<button className="back-button" onClick={handleBack}> | |
返回个人中心 | |
</button> | |
<div className="error">错误: {error}</div> | |
</div> | |
); | |
} | |
return ( | |
<div className="subpage-container"> | |
<button className="back-button" onClick={handleBack}> | |
返回个人中心 | |
</button> | |
<h2 className="page-title">兑换区</h2> | |
<div className="exchange-section"> | |
<h3>当前魔力值: {userInfo?.magicPoints || 0}</h3> | |
<div className="exchange-card"> | |
<h4>兑换邀请码</h4> | |
<p>消耗10魔力值兑换一个邀请码</p> | |
<button | |
className="exchange-btn" | |
onClick={handleGenerateInviteCode} | |
disabled={!userInfo || userInfo.magicPoints < 10} | |
> | |
兑换邀请码 | |
</button> | |
</div> | |
<div className="exchange-card"> | |
<h4>兑换上传量</h4> | |
<p>1魔力值 = 1GB上传量</p> | |
<div className="exchange-input-group"> | |
<input | |
type="number" | |
value={magicPoints} | |
onChange={(e) => { | |
// 允许空字符串或有效数字 | |
const value = e.target.value; | |
if (value === '' || !isNaN(value)) { | |
setMagicPoints(value); | |
} | |
}} | |
min="1" | |
max={userInfo?.magicPoints || 0} | |
placeholder="输入要兑换的魔力值" | |
/> | |
<button | |
className="exchange-btn" | |
onClick={handleExchangeUpload} | |
disabled={ | |
!magicPoints || | |
Number(magicPoints) <= 0 || | |
!userInfo || | |
Number(magicPoints) > userInfo.magicPoints | |
} | |
> | |
兑换上传量 | |
</button> | |
</div> | |
</div> | |
{inviteCodes.length > 0 && ( | |
<div className="invite-code-list"> | |
<h4>我的邀请码</h4> | |
<ul> | |
{inviteCodes.map((code, index) => ( | |
<li key={index}> | |
<span className="code">{code.code}</span> | |
<span className={`status ${code.isUsed ? 'used' : 'available'}`}> | |
{code.isUsed ? '已使用' : '可用'} | |
</span> | |
</li> | |
))} | |
</ul> | |
</div> | |
)} | |
</div> | |
</div> | |
); | |
}; | |
export default Exchange; |