个人中心全部,模糊乱序搜索,类型筛选
Change-Id: Id635654fccccaea80bfbf4d1480abd55f7d12046
diff --git a/src/components/Personal/Exchange.jsx b/src/components/Personal/Exchange.jsx
new file mode 100644
index 0000000..1e5b2e8
--- /dev/null
+++ b/src/components/Personal/Exchange.jsx
@@ -0,0 +1,175 @@
+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;
\ No newline at end of file