用户中心 商城 登陆注册前端

Change-Id: I4165f66073210b296608a5cfa0e8329e3d9bc8e3
diff --git a/src/pages/ShopPage.jsx b/src/pages/ShopPage.jsx
new file mode 100644
index 0000000..bb7d989
--- /dev/null
+++ b/src/pages/ShopPage.jsx
@@ -0,0 +1,187 @@
+import React, { useState, useEffect } from 'react';
+import axios from 'axios';
+import { message, Button } from 'antd';
+import { ArrowLeftOutlined } from '@ant-design/icons';
+import { useNavigate } from 'react-router-dom';
+
+const ShopPage = () => {
+  const navigate = useNavigate();
+  const [user, setUser] = useState(null);
+  const [loading, setLoading] = useState(false);
+  const [shopItems, setShopItems] = useState([
+    {
+      id: 1,
+      type: 'decoration',
+      name: '头像框',
+      description: '好看的头像框可以让别人更好地记住你',
+      price: 100,
+      image: 'https://img.icons8.com/?size=100&id=11730&format=png&color=000000'
+    },
+    {
+      id: 2,
+      type: 'decoration',
+      name: '对话框',
+      description: '闪亮的对话框,让您的消息更醒目',
+      price: 150,
+      image: 'https://img.icons8.com/?size=100&id=143&format=png&color=000000'
+    },
+    {
+      id: 3,
+      type: 'upload',
+      name: '上传量+100MB',
+      description: '增加100MB的上传量',
+      price: 50,
+      image: 'https://img.icons8.com/?size=100&id=368&format=png&color=000000'
+    },
+    {
+      id: 4,
+      type: 'invite',
+      name: '邀请码',
+      description: '一个邀请码,用于邀请好友加入',
+      price: 200,
+      image: 'https://img.icons8.com/?size=100&id=5465&format=png&color=000000'
+    }
+  ]);
+
+  useEffect(() => {
+    // 从localStorage获取用户信息
+    const userData = localStorage.getItem('user');
+    if (userData) {
+      setUser(JSON.parse(userData));
+    }
+  }, []);
+
+  const handlePurchase = async (item) => {
+    if (!user) {
+      message.error('请先登录');
+      return;
+    }
+
+    setLoading(true);
+    try {
+      let response;
+      const username = user.username;
+
+      switch (item.type) {
+        case 'decoration':
+          response = await axios.post('http://localhost:8080/shop/soldDecoration', null, {
+            params: {
+              buyername: username,
+              decoration: item.name,
+              price: item.price
+            }
+          });
+          break;
+        case 'upload':
+          response = await axios.post('http://localhost:8080/shop/soldUpload', null, {
+            params: {
+              buyername: username,
+              price: item.price,
+              upload: 100 // 假设每次购买增加100MB
+            }
+          });
+          break;
+        case 'invite':
+          response = await axios.post('http://localhost:8080/shop/soldInvite', null, {
+            params: {
+              buyername: username,
+              price: item.price
+            }
+          });
+          break;
+        default:
+          throw new Error('未知的商品类型');
+      }
+
+      if (response.data && response.data.success) {
+        message.success('购买成功!');
+        // 更新用户信息
+        user.credit -= item.price;
+        if(item.type=='decoration'){
+            user.decoration= user.decoration+" "+item.name;
+        }
+        localStorage.setItem('user', JSON.stringify(user));
+        setUser(user);
+      } else {
+        message.error(response.data.message || '购买失败');
+      }
+    } catch (error) {
+      console.error('购买出错:', error);
+      message.error(error.response?.data?.message || '购买过程中出错');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  if (!user) {
+    return (
+      <div style={{ padding: '20px', textAlign: 'center' }}>
+        <h2>请先登录后再访问商城</h2>
+      </div>
+    );
+  }
+
+  return (
+    <div className="shop-container" style={{ padding: '20px', maxWidth: '1200px', margin: '0 auto' }}>
+      {/* 添加返回按钮 */}
+      <Button 
+        type="text" 
+        icon={<ArrowLeftOutlined />} 
+        onClick={() => navigate(-1)}
+        style={{ marginBottom: '20px', paddingLeft: 0 }}
+      >
+        返回
+      </Button>
+
+      <h1 style={{ textAlign: 'center', marginBottom: '30px' }}>商城</h1>
+      <div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
+        <div>
+          <h3>当前用户: {user.username}</h3>
+          <p>余额: {user.credit || 0} 积分</p>
+        </div>
+      </div>
+
+      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '20px' }}>
+        {shopItems.map((item) => (
+          <div key={item.id} style={{
+            border: '1px solid #ddd',
+            borderRadius: '8px',
+            padding: '15px',
+            display: 'flex',
+            flexDirection: 'column',
+            boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
+          }}>
+            <div style={{ height: '150px', backgroundColor: '#f5f5f5', display: 'flex', justifyContent: 'center', alignItems: 'center', marginBottom: '15px' }}>
+              {item.image ? (
+                <img src={item.image} alt={item.name} style={{ maxWidth: '100%', maxHeight: '100%' }} />
+              ) : (
+                <span>商品图片</span>
+              )}
+            </div>
+            <h3 style={{ margin: '0 0 10px 0' }}>{item.name}</h3>
+            <p style={{ color: '#666', flexGrow: 1 }}>{item.description}</p>
+            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '15px' }}>
+              <span style={{ fontSize: '18px', fontWeight: 'bold', color: '#f56c6c' }}>{item.price} 积分</span>
+              <button
+                onClick={() => handlePurchase(item)}
+                disabled={loading || (user.credit < item.price)}
+                style={{
+                  padding: '8px 16px',
+                  backgroundColor: user.credit >= item.price ? '#1890ff' : '#ccc',
+                  color: 'white',
+                  border: 'none',
+                  borderRadius: '4px',
+                  cursor: user.credit >= item.price ? 'pointer' : 'not-allowed'
+                }}
+              >
+                {loading ? '处理中...' : '购买'}
+              </button>
+            </div>
+          </div>
+        ))}
+      </div>
+    </div>
+  );
+};
+
+export default ShopPage;
\ No newline at end of file